Changeset - r18226:c04963816211
[Not reviewed]
master
0 8 0
michi_cc - 13 years ago 2011-10-31 22:31:40
michi_cc@openttd.org
(svn r23072) -Feature: [NewGRF] House callback 0x148.
8 files changed with 88 insertions and 9 deletions:
0 comments (0 inline, 0 general)
src/house.h
Show inline comments
 
@@ -117,12 +117,13 @@ struct HouseSpec {
 
	byte probability;                  ///< Relative probability of appearing (16 is the standard value)
 
	HouseExtraFlags extra_flags;       ///< some more flags
 
	HouseClassID class_id;             ///< defines the class this house has (not grf file based)
 
	AnimationInfo animation;           ///< information about the animation.
 
	byte processing_time;              ///< Periodic refresh multiplier
 
	byte minimum_life;                 ///< The minimum number of years this house will survive before the town rebuilds it
 
	uint32 watched_cargoes;            ///< Cargo types watched for acceptance.
 

	
 
	Money GetRemovalCost() const;
 

	
 
	static FORCEINLINE HouseSpec *Get(size_t house_id)
 
	{
 
		assert(house_id < HOUSE_MAX);
src/newgrf.cpp
Show inline comments
 
@@ -2028,13 +2028,12 @@ static ChangeInfoResult IgnoreTownHouseP
 
			for (uint j = 0; j < 4; j++) buf->ReadByte();
 
			break;
 

	
 
		case 0x20: {
 
			byte count = buf->ReadByte();
 
			for (byte j = 0; j < count; j++) buf->ReadByte();
 
			ret = CIR_UNHANDLED;
 
			break;
 
		}
 

	
 
		default:
 
			ret = CIR_UNKNOWN;
 
			break;
 
@@ -2248,16 +2247,18 @@ static ChangeInfoResult TownHouseChangeI
 
			}
 

	
 
			case 0x1F: // Minimum life span
 
				housespec->minimum_life = buf->ReadByte();
 
				break;
 

	
 
			case 0x20: { // @todo Cargo acceptance watch list
 
			case 0x20: { // Cargo acceptance watch list
 
				byte count = buf->ReadByte();
 
				for (byte j = 0; j < count; j++) buf->ReadByte();
 
				ret = CIR_UNHANDLED;
 
				for (byte j = 0; j < count; j++) {
 
					CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
 
					if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
 
				}
 
				break;
 
			}
 

	
 
			case 0x21: // long introduction year
 
				housespec->min_year = buf->ReadWord();
 
				break;
src/newgrf_callbacks.h
Show inline comments
 
@@ -205,13 +205,13 @@ enum CallbackID {
 
	CBID_NEW_SIGNALS_SPRITE_DRAW         = 0x146, // 15 bit callback, not implemented
 

	
 
	/** Add an offset to the default sprite numbers to show another sprite. */
 
	CBID_CANALS_SPRITE_OFFSET            = 0x147, // 15 bit callback
 

	
 
	/** Called when a cargo type specified in property 20 is accepted. */
 
	CBID_HOUSE_WATCHED_CARGO_ACCEPTED    = 0x148, // 15 bit callback, not implemented
 
	CBID_HOUSE_WATCHED_CARGO_ACCEPTED    = 0x148, // 15 bit callback
 

	
 
	/** Callback done for each tile of a station to check the slope. */
 
	CBID_STATION_LAND_SLOPE_CHECK        = 0x149, // 15 bit callback
 

	
 
	/** Called to determine the colour of an industry. */
 
	CBID_INDUSTRY_DECIDE_COLOUR          = 0x14A, // 4 bit callback
src/newgrf_house.cpp
Show inline comments
 
@@ -329,12 +329,15 @@ static uint32 HouseGetVariable(const Res
 
				if (HasBit(st->goods[cid].acceptance_pickup, GoodsEntry::GES_EVER_ACCEPTED))    SetBit(res, 0);
 
				if (HasBit(st->goods[cid].acceptance_pickup, GoodsEntry::GES_LAST_MONTH))       SetBit(res, 1);
 
				if (HasBit(st->goods[cid].acceptance_pickup, GoodsEntry::GES_CURRENT_MONTH))    SetBit(res, 2);
 
				if (HasBit(st->goods[cid].acceptance_pickup, GoodsEntry::GES_ACCEPTED_BIGTICK)) SetBit(res, 3);
 
			}
 

	
 
			/* Cargo triggered CB 148? */
 
			if (HasBit(object->u.house.watched_cargo_triggers, cid)) SetBit(res, 4);
 

	
 
			return res;
 
		}
 

	
 
		/* Distance test for some house types */
 
		case 0x65: return GetDistanceFromNearbyHouse(parameter, tile, object->u.house.house_id);
 

	
 
@@ -424,25 +427,26 @@ static void NewHouseResolver(ResolverObj
 
	res->ResetState();
 

	
 
	const HouseSpec *hs  = HouseSpec::Get(house_id);
 
	res->grffile         = (hs != NULL ? hs->grf_prop.grffile : NULL);
 
}
 

	
 
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile, bool not_yet_constructed, uint8 initial_random_bits)
 
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile, bool not_yet_constructed, uint8 initial_random_bits, uint32 watched_cargo_triggers)
 
{
 
	ResolverObject object;
 
	const SpriteGroup *group;
 

	
 
	assert(IsValidTile(tile) && (not_yet_constructed || IsTileType(tile, MP_HOUSE)));
 

	
 
	NewHouseResolver(&object, house_id, tile, town);
 
	object.callback = callback;
 
	object.callback_param1 = param1;
 
	object.callback_param2 = param2;
 
	object.u.house.not_yet_constructed = not_yet_constructed;
 
	object.u.house.initial_random_bits = initial_random_bits;
 
	object.u.house.watched_cargo_triggers = watched_cargo_triggers;
 

	
 
	group = SpriteGroup::Resolve(HouseSpec::Get(house_id)->grf_prop.spritegroup[0], &object);
 
	if (group == NULL) return CALLBACK_FAILED;
 

	
 
	return group->GetCallbackResult();
 
}
 
@@ -504,13 +508,13 @@ void DrawNewHouseTile(TileInfo *ti, Hous
 
	}
 
}
 

	
 
/* Simple wrapper for GetHouseCallback to keep the animation unified. */
 
uint16 GetSimpleHouseCallback(CallbackID callback, uint32 param1, uint32 param2, const HouseSpec *spec, Town *town, TileIndex tile, uint32 extra_data)
 
{
 
	return GetHouseCallback(callback, param1, param2, spec - HouseSpec::Get(0), town, tile);
 
	return GetHouseCallback(callback, param1, param2, spec - HouseSpec::Get(0), town, tile, false, 0, extra_data);
 
}
 

	
 
/** Helper class for animation control. */
 
struct HouseAnimationBase : public AnimationBase<HouseAnimationBase, HouseSpec, Town, uint32, GetSimpleHouseCallback> {
 
	static const CallbackID cb_animation_speed      = CBID_HOUSE_ANIMATION_SPEED;
 
	static const CallbackID cb_animation_next_frame = CBID_HOUSE_ANIMATION_NEXT_FRAME;
 
@@ -656,12 +660,55 @@ static void DoTriggerHouse(TileIndex til
 
void TriggerHouse(TileIndex t, HouseTrigger trigger)
 
{
 
	DoTriggerHouse(t, trigger, 0, true);
 
}
 

	
 
/**
 
 * Run the watched cargo accepted callback for a single house tile.
 
 * @param tile The house tile.
 
 * @param origin The triggering tile.
 
 * @param trigger_cargoes Cargo types that triggered the callback.
 
 * @param random Random bits.
 
 */
 
void DoWatchedCargoCallback(TileIndex tile, TileIndex origin, uint32 trigger_cargoes, uint16 random)
 
{
 
	TileIndexDiffC diff = TileIndexToTileIndexDiffC(origin, tile);
 
	uint32 cb_info = random << 16 | (uint8)diff.y << 8 | (uint8)diff.x;
 
	HouseAnimationBase::ChangeAnimationFrame(CBID_HOUSE_WATCHED_CARGO_ACCEPTED, HouseSpec::Get(GetHouseType(tile)), Town::GetByTile(tile), tile, 0, cb_info, trigger_cargoes);
 
}
 

	
 
/**
 
 * Run watched cargo accepted callback for a house.
 
 * @param tile House tile.
 
 * @param trigger_cargoes Triggering cargo types.
 
 * @pre IsTileType(t, MP_HOUSE)
 
 */
 
void WatchedCargoCallback(TileIndex tile, uint32 trigger_cargoes)
 
{
 
	assert(IsTileType(tile, MP_HOUSE));
 
	HouseID id = GetHouseType(tile);
 
	const HouseSpec *hs = HouseSpec::Get(id);
 

	
 
	trigger_cargoes &= hs->watched_cargoes;
 
	/* None of the trigger cargoes is watched? */
 
	if (trigger_cargoes == 0) return;
 

	
 
	/* Same random value for all tiles of a multi-tile house. */
 
	uint16 r = Random();
 

	
 
	/* Do the callback, start at northern tile. */
 
	TileIndex north = tile + GetHouseNorthPart(id);
 
	hs = HouseSpec::Get(id);
 

	
 
	DoWatchedCargoCallback(north, tile, trigger_cargoes, r);
 
	if (hs->building_flags & BUILDING_2_TILES_Y)   DoWatchedCargoCallback(TILE_ADDXY(north, 0, 1), tile, trigger_cargoes, r);
 
	if (hs->building_flags & BUILDING_2_TILES_X)   DoWatchedCargoCallback(TILE_ADDXY(north, 1, 0), tile, trigger_cargoes, r);
 
	if (hs->building_flags & BUILDING_HAS_4_TILES) DoWatchedCargoCallback(TILE_ADDXY(north, 1, 1), tile, trigger_cargoes, r);
 
}
 

	
 
/**
 
 * Resolve a house's spec and such so we can get a variable.
 
 * @param ro    The resolver object to fill.
 
 * @param index The house tile to get the data from.
 
 */
 
void GetHouseResolver(ResolverObject *ro, uint index)
 
{
src/newgrf_house.h
Show inline comments
 
@@ -41,13 +41,14 @@ void IncreaseBuildingCount(Town *t, Hous
 
void DecreaseBuildingCount(Town *t, HouseID house_id);
 

	
 
void DrawNewHouseTile(TileInfo *ti, HouseID house_id);
 
void AnimateNewHouseTile(TileIndex tile);
 
void AnimateNewHouseConstruction(TileIndex tile);
 

	
 
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile, bool not_yet_constructed = false, uint8 initial_random_bits = 0);
 
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile, bool not_yet_constructed = false, uint8 initial_random_bits = 0, uint32 watched_cargo_triggers = 0);
 
void WatchedCargoCallback(TileIndex tile, uint32 trigger_cargoes);
 

	
 
bool CanDeleteHouse(TileIndex tile);
 

	
 
bool NewHouseTileLoop(TileIndex tile);
 

	
 
enum HouseTrigger {
src/newgrf_spritegroup.h
Show inline comments
 
@@ -338,12 +338,13 @@ struct ResolverObject {
 
		struct {
 
			TileIndex tile;
 
			Town *town;                    ///< Town of this house
 
			HouseID house_id;
 
			uint16 initial_random_bits;    ///< Random bits during construction checks
 
			bool not_yet_constructed;      ///< True for construction check
 
			uint32 watched_cargo_triggers; ///< Cargo types that triggered the watched cargo callback.
 
		} house;
 
		struct {
 
			TileIndex tile;
 
			Industry *ind;
 
			IndustryGfx gfx;
 
			IndustryType type;
src/station_cmd.cpp
Show inline comments
 
@@ -46,12 +46,13 @@
 
#include "debug.h"
 
#include "core/random_func.hpp"
 
#include "company_base.h"
 
#include "table/airporttile_ids.h"
 
#include "newgrf_airporttiles.h"
 
#include "order_backup.h"
 
#include "newgrf_house.h"
 

	
 
#include "table/strings.h"
 

	
 
/**
 
 * Check whether the given tile is a hangar.
 
 * @param t the tile to of whether it is a hangar.
 
@@ -2984,12 +2985,37 @@ static VehicleEnterTileStatus VehicleEnt
 
	}
 

	
 
	return VETSB_CONTINUE;
 
}
 

	
 
/**
 
 * Run the watched cargo callback for all houses in the catchment area.
 
 * @param st Station.
 
 */
 
void TriggerWatchedCargoCallbacks(Station *st)
 
{
 
	/* Collect cargoes accepted since the last big tick. */
 
	uint cargoes = 0;
 
	for (CargoID cid = 0; cid < NUM_CARGO; cid++) {
 
		if (HasBit(st->goods[cid].acceptance_pickup, GoodsEntry::GES_ACCEPTED_BIGTICK)) SetBit(cargoes, cid);
 
	}
 

	
 
	/* Anything to do? */
 
	if (cargoes == 0) return;
 

	
 
	/* Loop over all houses in the catchment. */
 
	Rect r = st->GetCatchmentRect();
 
	TileArea ta(TileXY(r.left, r.top), TileXY(r.right, r.bottom));
 
	TILE_AREA_LOOP(tile, ta) {
 
		if (IsTileType(tile, MP_HOUSE)) {
 
			WatchedCargoCallback(tile, cargoes);
 
		}
 
	}
 
}
 

	
 
/**
 
 * This function is called for each station once every 250 ticks.
 
 * Not all stations will get the tick at the same time.
 
 * @param st the station receiving the tick.
 
 * @return true if the station is still valid (wasn't deleted)
 
 */
 
static bool StationHandleBigTick(BaseStation *st)
 
@@ -2997,12 +3023,14 @@ static bool StationHandleBigTick(BaseSta
 
	if (!st->IsInUse() && ++st->delete_ctr >= 8) {
 
		delete st;
 
		return false;
 
	}
 

	
 
	if (Station::IsExpected(st)) {
 
		TriggerWatchedCargoCallbacks(Station::From(st));
 

	
 
		for (CargoID i = 0; i < NUM_CARGO; i++) {
 
			ClrBit(Station::From(st)->goods[i].acceptance_pickup, GoodsEntry::GES_ACCEPTED_BIGTICK);
 
		}
 
	}
 

	
 

	
src/table/town_land.h
Show inline comments
 
@@ -1810,13 +1810,13 @@ assert_compile(lengthof(_town_draw_tile_
 
 * @param cg2 2nd CargoID available
 
 * @param cg3 3rd CargoID available
 
 * @see HouseSpec
 
 */
 
#define MS(mnd, mxd, p, rc, bn, rr, mg, ca1, ca2, ca3, bf, ba, cg1, cg2, cg3) \
 
	{mnd, mxd, p, rc, bn, rr, mg, {ca1, ca2, ca3}, {cg1, cg2, cg3}, bf, ba, true, \
 
	 GRFFileProps(INVALID_HOUSE_ID), 0, {0, 0, 0, 0}, 16, NO_EXTRA_FLAG, HOUSE_NO_CLASS, {0, 2, 0, 0}, 0, 0}
 
	 GRFFileProps(INVALID_HOUSE_ID), 0, {0, 0, 0, 0}, 16, NO_EXTRA_FLAG, HOUSE_NO_CLASS, {0, 2, 0, 0}, 0, 0, 0}
 
/** House specifications from original data */
 
static const HouseSpec _original_house_specs[] = {
 
	/**
 
	 *                                                                              remove_rating_decrease
 
	 *                                                                              |    mail_generation
 
	 *     min_year                                                                 |    |    1st CargoID acceptance
0 comments (0 inline, 0 general)