changeset 7860:9676dc785085 draft

(svn r11410) -Codechange: implement random triggers for industries.
author rubidium <rubidium@openttd.org>
date Sun, 11 Nov 2007 17:56:37 +0000
parents 51d89ad22764
children 6986bc3b90e4
files src/economy.cpp src/industry.h src/industry_cmd.cpp src/newgrf_industries.cpp src/newgrf_industrytiles.cpp src/newgrf_industrytiles.h src/newgrf_spritegroup.cpp src/saveload.cpp
diffstat 8 files changed, 88 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/economy.cpp
+++ b/src/economy.cpp
@@ -1256,6 +1256,7 @@
 			best->produced_cargo_waiting[1] = min(best->produced_cargo_waiting[1] + (num_pieces * indspec->input_cargo_multiplier[accepted_cargo_index][1] / 256), 0xFFFF);
 		}
 
+		TriggerIndustry(best, INDUSTRY_TRIGGER_RECEIVED_CARGO);
 		StartStopIndustryTileAnimation(best, IAT_INDUSTRY_RECEIVED_CARGO);
 	}
 }
--- a/src/industry.h
+++ b/src/industry.h
@@ -130,6 +130,9 @@
 	Date last_cargo_accepted_at;        ///< Last day cargo was accepted by this industry
 	byte selected_layout;               ///< Which tile layout was used when creating the industry
 
+	byte random_triggers;               ///< Triggers for the random
+	uint16 random;                      ///< Random value used for randomisation of all kinds of things
+
 	PersistentStorage psa;              ///< Persistent storage for NewGRF industries.
 
 	Industry(TileIndex tile = 0) : xy(tile) {}
--- a/src/industry_cmd.cpp
+++ b/src/industry_cmd.cpp
@@ -701,6 +701,8 @@
 	IndustryGfx newgfx;
 	IndustryGfx gfx;
 
+	TriggerIndustryTile(tile, INDTILE_TRIGGER_TILE_LOOP);
+
 	if (!IsIndustryCompleted(tile)) {
 		MakeIndustryTileBigger(tile);
 		return;
@@ -1042,6 +1044,7 @@
 	if (_game_mode == GM_EDITOR) return;
 
 	FOR_ALL_INDUSTRIES(i) {
+		TriggerIndustry(i, INDUSTRY_TRIGGER_INDUSTRY_TICK);
 		StartStopIndustryTileAnimation(i, IAT_INDUSTRY_TICK);
 		ProduceIndustryGoods(i);
 	}
@@ -2137,6 +2140,9 @@
 
 	SLE_CONDARRX(cpp_offsetof(Industry, psa) + cpp_offsetof(Industry::PersistentStorage, storage), SLE_UINT32, 16, 76, SL_MAX_VERSION),
 
+	SLE_CONDVAR(Industry, random_triggers,            SLE_UINT8,                 82, SL_MAX_VERSION),
+	SLE_CONDVAR(Industry, random,                     SLE_UINT16,                82, SL_MAX_VERSION),
+
 	/* reserve extra space in savegame here. (currently 32 bytes) */
 	SLE_CONDNULL(32, 2, SL_MAX_VERSION),
 
--- a/src/newgrf_industries.cpp
+++ b/src/newgrf_industries.cpp
@@ -16,6 +16,7 @@
 #include "newgrf_callbacks.h"
 #include "newgrf_spritegroup.h"
 #include "newgrf_industries.h"
+#include "newgrf_industrytiles.h"
 #include "newgrf_commons.h"
 #include "newgrf_text.h"
 #include "newgrf_town.h"
@@ -338,18 +339,18 @@
 
 static uint32 IndustryGetRandomBits(const ResolverObject *object)
 {
-	return object->u.industry.ind == NULL ? 0 : 0; //object->u.industry.ind->random_bits;
+	return object->u.industry.ind == NULL ? 0 : object->u.industry.ind->random;
 }
 
 static uint32 IndustryGetTriggers(const ResolverObject *object)
 {
-	return object->u.industry.ind == NULL ? 0 : 0; //object->u.industry.ind->triggers;
+	return object->u.industry.ind == NULL ? 0 : object->u.industry.ind->random_triggers;
 }
 
 static void IndustrySetTriggers(const ResolverObject *object, int triggers)
 {
 	if (object->u.industry.ind == NULL) return;
-	//object->u.industry.ind->triggers = triggers;
+	object->u.industry.ind->random_triggers = triggers;
 }
 
 static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *indus)
@@ -528,3 +529,19 @@
 
 	InvalidateWindow(WC_INDUSTRY_VIEW, ind->index);
 }
+
+void DoTriggerIndustry(Industry *ind, IndustryTileTrigger trigger)
+{
+	ResolverObject object;
+
+	NewIndustryResolver(&object, ind->xy, ind);
+	object.callback = CBID_RANDOM_TRIGGER;
+	object.trigger = trigger;
+
+	const SpriteGroup *group = Resolve(GetIndustrySpec(ind->type)->grf_prop.spritegroup, &object);
+	if (group == NULL) return;
+
+	byte new_random_bits = Random();
+	ind->random &= ~object.reseed;
+	ind->random |= new_random_bits & object.reseed;
+}
--- a/src/newgrf_industrytiles.cpp
+++ b/src/newgrf_industrytiles.cpp
@@ -119,14 +119,14 @@
 {
 	const TileIndex tile = object->u.industry.tile;
 	if (tile == INVALID_TILE || !IsTileType(tile, MP_INDUSTRY)) return 0;
-	return (object->scope == VSG_SCOPE_SELF) ? GetIndustryRandomBits(tile) : 0; //GetIndustryByTile(tile)->random_bits;
+	return (object->scope == VSG_SCOPE_SELF) ? GetIndustryRandomBits(tile) : GetIndustryByTile(tile)->random;
 }
 
 static uint32 IndustryTileGetTriggers(const ResolverObject *object)
 {
 	const TileIndex tile = object->u.industry.tile;
 	if (tile == INVALID_TILE || !IsTileType(tile, MP_INDUSTRY)) return 0;
-	return (object->scope == VSG_SCOPE_SELF) ? GetIndustryTriggers(tile) : 0; //GetIndustryByTile(tile)->triggers;
+	return (object->scope == VSG_SCOPE_SELF) ? GetIndustryTriggers(tile) : GetIndustryByTile(tile)->random_triggers;
 }
 
 static void IndustryTileSetTriggers(const ResolverObject *object, int triggers)
@@ -134,10 +134,10 @@
 	const TileIndex tile = object->u.industry.tile;
 	if (tile == INVALID_TILE || !IsTileType(tile, MP_INDUSTRY)) return;
 
-	if (object->scope != VSG_SCOPE_SELF) {
+	if (object->scope == VSG_SCOPE_SELF) {
 		SetIndustryTriggers(tile, triggers);
 	} else {
-		//GetIndustryByTile(tile)->triggers = triggers;
+		GetIndustryByTile(tile)->random_triggers = triggers;
 	}
 }
 
@@ -385,3 +385,43 @@
 
 	return ret;
 }
+
+static void DoTriggerIndustryTile(TileIndex tile, IndustryTileTrigger trigger, Industry *ind)
+{
+	ResolverObject object;
+
+	IndustryGfx gfx = GetIndustryGfx(tile);
+	const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
+
+	NewIndustryTileResolver(&object, gfx, tile, ind);
+
+	object.callback = CBID_RANDOM_TRIGGER;
+	object.trigger = trigger;
+
+	const SpriteGroup *group = Resolve(itspec->grf_prop.spritegroup, &object);
+	if (group == NULL) return;
+
+	byte new_random_bits = Random();
+	byte random_bits = GetIndustryRandomBits(tile);
+	random_bits &= ~object.reseed;
+	random_bits |= new_random_bits & object.reseed;
+	SetIndustryRandomBits(tile, random_bits);
+}
+
+void TriggerIndustryTile(TileIndex tile, IndustryTileTrigger trigger)
+{
+	DoTriggerIndustryTile(tile, trigger, GetIndustryByTile(tile));
+}
+
+extern void DoTriggerIndustry(Industry *ind, IndustryTileTrigger trigger);
+
+void TriggerIndustry(Industry *ind, IndustryTileTrigger trigger)
+{
+	BEGIN_TILE_LOOP(tile, ind->width, ind->height, ind->xy)
+		if (IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == ind->index) {
+			DoTriggerIndustryTile(tile, trigger, ind);
+		}
+	END_TILE_LOOP(tile, ind->width, ind->height, ind->xy)
+
+	DoTriggerIndustry(ind, trigger);
+}
--- a/src/newgrf_industrytiles.h
+++ b/src/newgrf_industrytiles.h
@@ -21,4 +21,16 @@
 bool StartStopIndustryTileAnimation(TileIndex tile, IndustryAnimationTrigger iat, uint32 random = Random());
 bool StartStopIndustryTileAnimation(const Industry *ind, IndustryAnimationTrigger iat);
 
+
+enum IndustryTileTrigger {
+	/* The tile of the industry has been triggered during the tileloop. */
+	INDTILE_TRIGGER_TILE_LOOP       = 0x01,
+	/* The industry has been triggered via it's tick. */
+	INDUSTRY_TRIGGER_INDUSTRY_TICK  = 0x02,
+	/* Cargo has been delivered. */
+	INDUSTRY_TRIGGER_RECEIVED_CARGO = 0x04,
+};
+void TriggerIndustryTile(TileIndex t, IndustryTileTrigger trigger);
+void TriggerIndustry(Industry *ind, IndustryTileTrigger trigger);
+
 #endif /* NEWGRF_INDUSTRYTILES_H */
--- a/src/newgrf_spritegroup.cpp
+++ b/src/newgrf_spritegroup.cpp
@@ -252,7 +252,7 @@
 		/* Handle triggers */
 		/* Magic code that may or may not do the right things... */
 		byte waiting_triggers = object->GetTriggers(object);
-		byte match = group->g.random.triggers & (waiting_triggers | object->trigger);
+		byte match = group->g.random.triggers & (waiting_triggers | object->trigger) || group->g.random.triggers == 0;
 		bool res;
 
 		res = (group->g.random.cmp_mode == RSG_CMP_ANY) ?
--- a/src/saveload.cpp
+++ b/src/saveload.cpp
@@ -29,7 +29,7 @@
 #include "strings.h"
 #include <list>
 
-extern const uint16 SAVEGAME_VERSION = 81;
+extern const uint16 SAVEGAME_VERSION = 82;
 uint16 _sl_version;       ///< the major savegame version identifier
 byte   _sl_minor_version; ///< the minor savegame version, DO NOT USE!