--- a/src/newgrf_house.cpp Sat Oct 06 21:16:00 2007 +0000
+++ b/src/newgrf_house.cpp Mon Dec 03 23:39:38 2007 +0000
@@ -25,6 +25,7 @@
#include "newgrf_town.h"
#include "newgrf_sound.h"
#include "newgrf_commons.h"
+#include "transparency.h"
static BuildingCounts _building_counts;
static HouseClassMapping _class_mapping[HOUSE_CLASS_MAX];
@@ -210,7 +211,7 @@
case 0x40: return (IsTileType(tile, MP_HOUSE) ? GetHouseBuildingStage(tile) : 0) | OriginalTileRandomiser(TileX(tile), TileY(tile)) << 2;
/* Building age. */
- case 0x41: return clamp(_cur_year - GetHouseConstructionYear(tile), 0, 0xFF);
+ case 0x41: return Clamp(_cur_year - GetHouseConstructionYear(tile), 0, 0xFF);
/* Town zone */
case 0x42: return GetTownRadiusGroup(town, tile);
@@ -320,14 +321,14 @@
if (IS_CUSTOM_SPRITE(image)) image += stage;
- if ((HASBIT(image, SPRITE_MODIFIER_OPAQUE) || !HASBIT(_transparent_opt, TO_HOUSES)) && HASBIT(image, PALETTE_MODIFIER_COLOR)) {
+ if ((HasBit(image, SPRITE_MODIFIER_OPAQUE) || !IsTransparencySet(TO_HOUSES)) && HasBit(image, PALETTE_MODIFIER_COLOR)) {
if (pal == 0) {
const HouseSpec *hs = GetHouseSpecs(house_id);
- if (HASBIT(hs->callback_mask, CBM_HOUSE_COLOUR)) {
+ if (HasBit(hs->callback_mask, CBM_HOUSE_COLOUR)) {
uint16 callback = GetHouseCallback(CBID_HOUSE_COLOUR, 0, 0, house_id, GetTownByTile(ti->tile), ti->tile);
if (callback != CALLBACK_FAILED) {
/* If bit 14 is set, we should use a 2cc colour map, else use the callback value. */
- pal = HASBIT(callback, 14) ? GB(callback, 0, 8) + SPR_2CCMAP_BASE : callback;
+ pal = HasBit(callback, 14) ? GB(callback, 0, 8) + SPR_2CCMAP_BASE : callback;
}
} else {
pal = hs->random_colour[OriginalTileRandomiser(ti->x, ti->y)] + PALETTE_RECOLOR_START;
@@ -343,10 +344,10 @@
ti->x + dtss->delta_x, ti->y + dtss->delta_y,
dtss->size_x, dtss->size_y,
dtss->size_z, ti->z + dtss->delta_z,
- HASBIT(_transparent_opt, TO_HOUSES)
+ IsTransparencySet(TO_HOUSES)
);
} else {
- AddChildSpriteScreen(image, pal, dtss->delta_x, dtss->delta_y, HASBIT(_transparent_opt, TO_HOUSES));
+ AddChildSpriteScreen(image, pal, (byte)dtss->delta_x, (byte)dtss->delta_y, IsTransparencySet(TO_HOUSES));
}
}
}
@@ -368,7 +369,7 @@
} else {
/* Limit the building stage to the number of stages supplied. */
byte stage = GetHouseBuildingStage(ti->tile);
- stage = clamp(stage - 4 + group->g.layout.num_sprites, 0, group->g.layout.num_sprites - 1);
+ stage = Clamp(stage - 4 + group->g.layout.num_sprites, 0, group->g.layout.num_sprites - 1);
DrawTileLayout(ti, group, stage, house_id);
}
}
@@ -379,9 +380,9 @@
byte animation_speed = hs->animation_speed;
bool frame_set_by_callback = false;
- if (HASBIT(hs->callback_mask, CBM_HOUSE_ANIMATION_SPEED)) {
+ if (HasBit(hs->callback_mask, CBM_HOUSE_ANIMATION_SPEED)) {
uint16 callback_res = GetHouseCallback(CBID_HOUSE_ANIMATION_SPEED, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile);
- if (callback_res != CALLBACK_FAILED) animation_speed = clamp(callback_res & 0xFF, 2, 16);
+ if (callback_res != CALLBACK_FAILED) animation_speed = Clamp(callback_res & 0xFF, 2, 16);
}
/* An animation speed of 2 means the animation frame changes 4 ticks, and
@@ -393,7 +394,7 @@
byte frame = GetHouseAnimationFrame(tile);
byte num_frames = GB(hs->animation_frames, 0, 7);
- if (HASBIT(hs->callback_mask, CBM_HOUSE_ANIMATION_NEXT_FRAME)) {
+ if (HasBit(hs->callback_mask, CBM_HOUSE_ANIMATION_NEXT_FRAME)) {
uint32 param = (hs->extra_flags & CALLBACK_1A_RANDOM_BITS) ? Random() : 0;
uint16 callback_res = GetHouseCallback(CBID_HOUSE_ANIMATION_NEXT_FRAME, param, 0, GetHouseType(tile), GetTownByTile(tile), tile);
@@ -422,7 +423,7 @@
if (!frame_set_by_callback) {
if (frame < num_frames) {
frame++;
- } else if (frame == num_frames && HASBIT(hs->animation_frames, 7)) {
+ } else if (frame == num_frames && HasBit(hs->animation_frames, 7)) {
/* This animation loops, so start again from the beginning */
frame = 0;
} else {
@@ -460,7 +461,7 @@
if ((IsValidPlayer(_current_player) && IsHumanPlayer(_current_player))
|| _current_player == OWNER_WATER || _current_player == OWNER_NONE) return true;
- if (HASBIT(hs->callback_mask, CBM_HOUSE_DENY_DESTRUCTION)) {
+ if (HasBit(hs->callback_mask, CBM_HOUSE_DENY_DESTRUCTION)) {
uint16 callback_res = GetHouseCallback(CBID_HOUSE_DENY_DESTRUCTION, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile);
return (callback_res == CALLBACK_FAILED || callback_res == 0);
} else {
@@ -472,7 +473,7 @@
{
const HouseSpec *hs = GetHouseSpecs(GetHouseType(tile));
- if (HASBIT(hs->callback_mask, CBM_HOUSE_ANIMATION_START_STOP)) {
+ if (HasBit(hs->callback_mask, CBM_HOUSE_ANIMATION_START_STOP)) {
uint32 param = (hs->extra_flags & SYNCHRONISED_CALLBACK_1B) ? (GB(Random(), 0, 16) | random_bits << 16) : Random();
uint16 callback_res = GetHouseCallback(CBID_HOUSE_ANIMATION_START_STOP, param, 0, GetHouseType(tile), GetTownByTile(tile), tile);
@@ -489,13 +490,10 @@
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 (HasBit(hs->callback_mask, CBM_HOUSE_ANIMATION_START_STOP)) {
/* If this house is marked as having a synchronised callback, all the
* tiles will have the callback called at once, rather than when the
* tile loop reaches them. This should only be enabled for the northern
@@ -513,7 +511,7 @@
}
/* Check callback 21, which determines if a house should be destroyed. */
- if (HASBIT(hs->callback_mask, CBM_HOUSE_DESTRUCTION)) {
+ if (HasBit(hs->callback_mask, CBM_HOUSE_DESTRUCTION)) {
uint16 callback_res = GetHouseCallback(CBID_HOUSE_DESTRUCTION, 0, 0, GetHouseType(tile), GetTownByTile(tile), tile);
if (callback_res != CALLBACK_FAILED && callback_res > 0) {
ClearTownHouse(GetTownByTile(tile), tile);
@@ -524,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, random_bits, false);
+ if (hs->building_flags & BUILDING_2_TILES_X) DoTriggerHouse(TILE_ADDXY(tile, 1, 0), trigger, random_bits, false);
+ if (hs->building_flags & BUILDING_HAS_4_TILES) DoTriggerHouse(TILE_ADDXY(tile, 1, 1), trigger, random_bits, false);
+ break;
+ }
+}
+
+void TriggerHouse(TileIndex t, HouseTrigger trigger)
+{
+ DoTriggerHouse(t, trigger, 0, true);
+}