changeset 7861:6986bc3b90e4 draft

(svn r11411) -Codechange: implement random triggers for houses.
author rubidium <rubidium@openttd.org>
date Sun, 11 Nov 2007 17:58:05 +0000
parents 9676dc785085
children f5474c8b9b6f
files src/newgrf_engine.cpp src/newgrf_house.cpp src/newgrf_house.h src/town_map.h
diffstat 4 files changed, 71 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/newgrf_engine.cpp
+++ b/src/newgrf_engine.cpp
@@ -1011,6 +1011,7 @@
 	object.trigger = trigger;
 
 	group = Resolve(GetVehicleSpriteGroup(v->engine_type, v), &object);
+	if (group == NULL) return;
 
 	new_random_bits = Random();
 	v->random_bits &= ~object.reseed;
--- a/src/newgrf_house.cpp
+++ b/src/newgrf_house.cpp
@@ -490,11 +490,8 @@
 		return true;
 	}
 
-	/* @todo: Magic with triggers goes here.  Got to implement that, one day. ..
-	 * Process randomizing of tiles following specs.
-	 * Once done, redraw the house
-	 * MarkTileDirtyByTile(tile);
-	 */
+	TriggerHouse(tile, HOUSE_TRIGGER_TILE_LOOP);
+	TriggerHouse(tile, HOUSE_TRIGGER_TILE_LOOP_TOP);
 
 	if (HASBIT(hs->callback_mask, CBM_HOUSE_ANIMATION_START_STOP)) {
 		/* If this house is marked as having a synchronised callback, all the
@@ -525,3 +522,47 @@
 	SetHouseProcessingTime(tile, hs->processing_time);
 	return true;
 }
+
+static void DoTriggerHouse(TileIndex tile, HouseTrigger trigger, byte base_random, bool first)
+{
+	ResolverObject object;
+
+	/* We can't trigger a non-existent building... */
+	assert(IsTileType(tile, MP_HOUSE));
+
+	HouseID hid = GetHouseType(tile);
+	HouseSpec *hs = GetHouseSpecs(hid);
+
+	NewHouseResolver(&object, hid, tile, GetTownByTile(tile));
+
+	object.callback = CBID_RANDOM_TRIGGER;
+	object.trigger = trigger;
+
+	const SpriteGroup *group = Resolve(hs->spritegroup, &object);
+	if (group == NULL) return;
+
+	byte new_random_bits = Random();
+	byte random_bits = GetHouseRandomBits(tile);
+	random_bits &= ~object.reseed;
+	random_bits |= (first ? new_random_bits : base_random) & object.reseed;
+	SetHouseRandomBits(tile, random_bits);
+
+	switch (trigger) {
+		case HOUSE_TRIGGER_TILE_LOOP:
+			/* Random value already set. */
+			break;
+
+		case HOUSE_TRIGGER_TILE_LOOP_TOP:
+			if (!first) break;
+			/* Random value of first tile already set. */
+			if (hs->building_flags & BUILDING_2_TILES_Y)   DoTriggerHouse(TILE_ADDXY(tile, 0, 1), trigger, false, random_bits);
+			if (hs->building_flags & BUILDING_2_TILES_X)   DoTriggerHouse(TILE_ADDXY(tile, 1, 0), trigger, false, random_bits);
+			if (hs->building_flags & BUILDING_HAS_4_TILES) DoTriggerHouse(TILE_ADDXY(tile, 1, 1), trigger, false, random_bits);
+			break;
+	}
+}
+
+void TriggerHouse(TileIndex t, HouseTrigger trigger)
+{
+	DoTriggerHouse(t, trigger, true, 0);
+}
--- a/src/newgrf_house.h
+++ b/src/newgrf_house.h
@@ -45,4 +45,15 @@
 
 bool NewHouseTileLoop(TileIndex tile);
 
+enum HouseTrigger {
+	/* The tile of the house has been triggered during the tileloop. */
+	HOUSE_TRIGGER_TILE_LOOP     = 0x01,
+	/*
+	 * The top tile of a (multitile) building has been triggered during and all
+	 * the tileloop other tiles of the same building get the same random value.
+	 */
+	HOUSE_TRIGGER_TILE_LOOP_TOP = 0x02,
+};
+void TriggerHouse(TileIndex t, HouseTrigger trigger);
+
 #endif /* NEWGRF_HOUSE_H */
--- a/src/town_map.h
+++ b/src/town_map.h
@@ -300,6 +300,19 @@
 }
 
 /**
+ * Set the random bits for this house.
+ * This is required for newgrf house
+ * @param t      the tile of this house
+ * @param random the new random bits
+ * @pre IsTileType(t, MP_HOUSE)
+ */
+static inline void SetHouseRandomBits(TileIndex t, byte random)
+{
+	assert(IsTileType(t, MP_HOUSE));
+	_m[t].m1 = random;
+}
+
+/**
  * Get the random bits for this house.
  * This is required for newgrf house
  * @param t the tile of this house