Changeset - r11582:3a0dfd7221e5
[Not reviewed]
master
0 2 0
frosch - 15 years ago 2009-04-05 12:17:36
frosch@openttd.org
(svn r15958) -Fix [FS#2787]: Abort production callback after 0x10000 iterations and show a messagebox blaming the newgrf. (mizipzor)
2 files changed with 15 insertions and 0 deletions:
0 comments (0 inline, 0 general)
src/lang/english.txt
Show inline comments
 
@@ -3162,24 +3162,25 @@ STR_NEWGRF_COMPATIBLE_LOADED            
 

	
 
STR_NEWGRF_COMPATIBLE_LOAD_WARNING                              :{WHITE}Compatible GRF(s) loaded for missing files
 
STR_NEWGRF_DISABLED_WARNING                                     :{WHITE}Missing GRF file(s) have been disabled
 
STR_NEWGRF_UNPAUSE_WARNING_TITLE                                :{YELLOW}Missing GRF file(s)
 
STR_NEWGRF_UNPAUSE_WARNING                                      :{WHITE}Unpausing can crash OpenTTD. Do not file bug reports for subsequent crashes.{}Do you really want to unpause?
 

	
 
STR_NEWGRF_BROKEN                                               :{WHITE}Behaviour of NewGRF '{0:RAW_STRING}' is likely to cause desyncs and/or crashes.
 
STR_NEWGRF_BROKEN_VEHICLE_LENGTH                                :{WHITE}It changes vehicle length for '{1:ENGINE}' when not inside a depot.
 
STR_BROKEN_VEHICLE_LENGTH                                       :{WHITE}Train '{VEHICLE}' belonging to '{COMPANY}' has invalid length. It is probably caused by problems with NewGRFs. Game may desync or crash.
 

	
 
STR_NEWGRF_BUGGY                                                :{WHITE}NewGRF '{0:RAW_STRING}' provides incorrect information.
 
STR_NEWGRF_BUGGY_ARTICULATED_CARGO                              :{WHITE}Cargo/refit information for '{1:ENGINE}' differs from purchase list after construction. This might cause autorenew/-replace to fail refitting correctly.
 
STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK                    :{WHITE}'{1:STRING}' caused an endless loop in the production callback.
 

	
 
STR_LOADGAME_REMOVED_TRAMS                                      :{WHITE}Game was saved in version without tram support. All trams have been removed.
 

	
 
STR_CURRENCY_WINDOW                                             :{WHITE}Custom currency
 
STR_CURRENCY_EXCHANGE_RATE                                      :{LTBLUE}Exchange rate: {ORANGE}{CURRENCY} = £ {COMMA}
 
STR_CURRENCY_SEPARATOR                                          :{LTBLUE}Separator: {RAW_STRING}
 
STR_CURRENCY_PREFIX                                             :{LTBLUE}Prefix: {RAW_STRING}
 
STR_CURRENCY_SUFFIX                                             :{LTBLUE}Suffix: {RAW_STRING}
 
STR_CURRENCY_SWITCH_TO_EURO                                     :{LTBLUE}Switch to Euro: {ORANGE}{NUM}
 
STR_CURRENCY_SWITCH_TO_EURO_NEVER                               :{LTBLUE}Switch to Euro: {ORANGE}never
 
STR_CURRENCY_PREVIEW                                            :{LTBLUE}Preview: {ORANGE}{CURRENCY}
 
STR_CURRENCY_CHANGE_PARAMETER                                   :{BLACK}Change custom currency parameter
src/newgrf_industries.cpp
Show inline comments
 
@@ -8,24 +8,26 @@
 
#include "strings_type.h"
 
#include "company_type.h"
 
#include "industry_map.h"
 
#include "newgrf.h"
 
#include "newgrf_industries.h"
 
#include "newgrf_commons.h"
 
#include "newgrf_text.h"
 
#include "newgrf_town.h"
 
#include "window_func.h"
 
#include "town.h"
 
#include "company_base.h"
 
#include "command_func.h"
 
#include "gui.h"
 
#include "strings_func.h"
 

	
 
#include "table/strings.h"
 

	
 
static uint32 _industry_creation_random_bits;
 

	
 
/* Since the industry IDs defined by the GRF file don't necessarily correlate
 
 * to those used by the game, the IDs used for overriding old industries must be
 
 * translated when the idustry spec is set. */
 
IndustryOverrideManager _industry_mngr(NEW_INDUSTRYOFFSET, NUM_INDUSTRYTYPES, INVALID_INDUSTRYTYPE);
 
IndustryTileOverrideManager _industile_mngr(NEW_INDUSTRYTILEOFFSET, NUM_INDUSTRYTILES, INVALID_INDUSTRYTILE);
 

	
 
IndustryType MapNewGRFIndustryType(IndustryType grf_type, uint32 grf_id)
 
@@ -561,24 +563,36 @@ static int32 DerefIndProd(uint field, bo
 
 */
 
void IndustryProductionCallback(Industry *ind, int reason)
 
{
 
	const IndustrySpec *spec = GetIndustrySpec(ind->type);
 
	ResolverObject object;
 
	NewIndustryResolver(&object, ind->xy, ind, ind->type);
 
	if ((spec->behaviour & INDUSTRYBEH_PRODCALLBACK_RANDOM) != 0) object.callback_param1 = Random();
 
	int multiplier = 1;
 
	if ((spec->behaviour & INDUSTRYBEH_PROD_MULTI_HNDLING) != 0) multiplier = ind->prod_level;
 
	object.callback_param2 = reason;
 

	
 
	for (uint loop = 0;; loop++) {
 
		/* limit the number of calls to break infinite loops.
 
		 * 'loop' is provided as 16 bits to the newgrf, so abort when those are exceeded. */
 
		if (loop >= 0x10000) {
 
			/* display error message */
 
			SetDParamStr(0, spec->grf_prop.grffile->filename);
 
			SetDParam(1, spec->name);
 
			ShowErrorMessage(STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK, STR_NEWGRF_BUGGY, 0, 0);
 

	
 
			/* abort the function early, this error isn't critical and will allow the game to continue to run */
 
			break;
 
		}
 

	
 
		SB(object.callback_param2, 8, 16, loop);
 
		const SpriteGroup *group = Resolve(spec->grf_prop.spritegroup, &object);
 
		if (group == NULL || group->type != SGT_INDUSTRY_PRODUCTION) break;
 

	
 
		bool deref = (group->g.indprod.version == 1);
 

	
 
		for (uint i = 0; i < 3; i++) {
 
			ind->incoming_cargo_waiting[i] = Clamp(ind->incoming_cargo_waiting[i] - DerefIndProd(group->g.indprod.substract_input[i], deref) * multiplier, 0, 0xFFFF);
 
		}
 
		for (uint i = 0; i < 2; i++) {
 
			ind->produced_cargo_waiting[i] = Clamp(ind->produced_cargo_waiting[i] + max(DerefIndProd(group->g.indprod.add_output[i], deref), 0) * multiplier, 0, 0xFFFF);
 
		}
0 comments (0 inline, 0 general)