Changeset - r8544:31b3976529d7
[Not reviewed]
master
0 5 2
peter1138 - 17 years ago 2008-02-12 13:23:57
peter1138@openttd.org
(svn r12122) -Codechange: Add framework for generic feature callbacks, along with some parts for AI use.
7 files changed with 257 insertions and 6 deletions:
0 comments (0 inline, 0 general)
projects/openttd_vs80.vcproj
Show inline comments
 
@@ -1069,12 +1069,16 @@
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_engine.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_generic.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_house.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_industries.h"
 
				>
 
@@ -1945,12 +1949,16 @@
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_engine.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_generic.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_house.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_industries.cpp"
 
				>
projects/openttd_vs90.vcproj
Show inline comments
 
@@ -1066,12 +1066,16 @@
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_engine.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_generic.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_house.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_industries.h"
 
				>
 
@@ -1942,12 +1946,16 @@
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_engine.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_generic.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_house.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\newgrf_industries.cpp"
 
				>
source.list
Show inline comments
 
@@ -173,12 +173,13 @@ newgrf.h
 
newgrf_callbacks.h
 
newgrf_canal.h
 
newgrf_cargo.h
 
newgrf_commons.h
 
newgrf_config.h
 
newgrf_engine.h
 
newgrf_generic.h
 
newgrf_house.h
 
newgrf_industries.h
 
newgrf_industrytiles.h
 
newgrf_sound.h
 
newgrf_spritegroup.h
 
newgrf_station.h
 
@@ -402,12 +403,13 @@ spriteloader/spriteloader.hpp
 
newgrf.cpp
 
newgrf_canal.cpp
 
newgrf_cargo.cpp
 
newgrf_commons.cpp
 
newgrf_config.cpp
 
newgrf_engine.cpp
 
newgrf_generic.cpp
 
newgrf_house.cpp
 
newgrf_industries.cpp
 
newgrf_industrytiles.cpp
 
newgrf_sound.cpp
 
newgrf_spritegroup.cpp
 
newgrf_station.cpp
src/newgrf.cpp
Show inline comments
 
@@ -3086,37 +3086,42 @@ static void FeatureMapSpriteGroup(byte *
 
	 * B num-cid       number of cargo IDs (sprite group IDs) in this definition
 
	 *                 can be zero, in that case the def-cid is used always
 
	 * B cargo-type    type of this cargo type (e.g. mail=2, wood=7, see below)
 
	 * W cid           cargo ID (sprite group ID) for this type of cargo
 
	 * W def-cid       default cargo ID (sprite group ID) */
 

	
 
	if (_cur_grffile->spritegroups == 0) {
 
		grfmsg(1, "FeatureMapSpriteGroup: No sprite groups to work on! Skipping");
 
		return;
 
	}
 

	
 
	if (!check_length(len, 6, "FeatureMapSpriteGroup")) return;
 

	
 
	uint8 feature = buf[1];
 
	uint8 idcount = buf[2] & 0x7F;
 
	bool wagover = (buf[2] & 0x80) == 0x80;
 

	
 
	if (!check_length(len, 3 + idcount, "FeatureMapSpriteGroup")) return;
 

	
 
	/* If idcount is zero, this is a feature callback */
 
	if (idcount == 0) {
 
		grfmsg(2, "FeatureMapSpriteGroup: Feature callbacks not implemented yet");
 
		byte *bp = &buf[4];
 
		uint16 groupid = grf_load_word(&bp);
 

	
 
		grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
 

	
 
		AddGenericCallback(feature, _cur_grffile, _cur_grffile->spritegroups[groupid]);
 
		return;
 
	}
 

	
 
	uint8 cidcount = buf[3 + idcount];
 
	if (!check_length(len, 4 + idcount + cidcount * 3, "FeatureMapSpriteGroup")) return;
 

	
 
	grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids, %d cids, wagon override %d",
 
			feature, idcount, cidcount, wagover);
 

	
 
	if (_cur_grffile->spritegroups == 0) {
 
		grfmsg(1, "FeatureMapSpriteGroup: No sprite groups to work on! Skipping");
 
		return;
 
	}
 

	
 
	switch (feature) {
 
		case GSF_TRAIN:
 
		case GSF_ROAD:
 
		case GSF_SHIP:
 
		case GSF_AIRCRAFT:
 
			VehicleMapSpriteGroup(buf, feature, idcount, cidcount, wagover);
 
@@ -5098,12 +5103,15 @@ static void ResetNewGRFData()
 

	
 
	/* Unload sprite group data */
 
	UnloadWagonOverrides();
 
	UnloadCustomEngineSprites();
 
	ResetEngineListOrder();
 

	
 
	/* Reset generic feature callback lists */
 
	ResetGenericCallbacks();
 

	
 
	/* Reset price base data */
 
	ResetPriceBaseMultipliers();
 

	
 
	/* Reset the curencies array */
 
	ResetCurrencies();
 

	
src/newgrf_generic.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "variables.h"
 
#include "landscape.h"
 
#include "debug.h"
 
#include "newgrf.h"
 
#include "newgrf_callbacks.h"
 
#include "newgrf_commons.h"
 
#include "newgrf_spritegroup.h"
 
#include "newgrf_generic.h"
 
#include "tile_map.h"
 
#include <list>
 

	
 

	
 
struct GenericCallback {
 
	const GRFFile *file;
 
	const SpriteGroup *group;
 

	
 
	GenericCallback(const GRFFile *file, const SpriteGroup *group) :
 
		file(file),
 
		group(group)
 
	{ }
 
};
 

	
 
typedef std::list<GenericCallback> GenericCallbackList;
 

	
 
static GenericCallbackList _gcl[GSF_END];
 

	
 

	
 
/**
 
 * Reset all generic feature callback sprite groups.
 
 */
 
void ResetGenericCallbacks()
 
{
 
	for (uint8 feature = 0; feature < lengthof(_gcl); feature++) {
 
		_gcl[feature].clear();
 
	}
 
}
 

	
 

	
 
/**
 
 * Add a generic feature callback sprite group to the appropriate feature list.
 
 * @param feature
 
 * @param file
 
 * @param group
 
 */
 
void AddGenericCallback(uint8 feature, const GRFFile *file, const SpriteGroup *group)
 
{
 
	if (feature >= lengthof(_gcl)) {
 
		grfmsg(5, "AddGenericCallback: Unsupported feature 0x%02X", feature);
 
		return;
 
	}
 

	
 
	/* Generic feature callbacks are evaluated in reverse (i.e. the last group
 
	 * to be added is evaluated first, etc) thus we push the group to the
 
	 * beginning of the list so a standard iterator will do the right thing. */
 
	_gcl[feature].push_front(GenericCallback(file, group));
 
}
 

	
 

	
 
static uint32 GenericCallbackGetRandomBits(const ResolverObject *object)
 
{
 
	return 0;
 
}
 

	
 

	
 
static uint32 GenericCallbackGetTriggers(const ResolverObject *object)
 
{
 
	return 0;
 
}
 

	
 

	
 
static void GenericCallbackSetTriggers(const ResolverObject *object, int triggers)
 
{
 
	return;
 
}
 

	
 

	
 
static uint32 GenericCallbackGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
 
{
 
	switch (variable) {
 
		case 0x40: return object->u.generic.cargo_type;
 

	
 
		case 0x80: return object->u.generic.cargo_type;
 
		case 0x81: return object->u.generic.cargo_type;
 
		case 0x82: return object->u.generic.default_selection;
 
		case 0x83: return object->u.generic.src_industry;
 
		case 0x84: return object->u.generic.dst_industry;
 
		case 0x85: return object->u.generic.distance;
 
		case 0x86: return object->u.generic.event;
 
		case 0x87: return object->u.generic.count;
 
		case 0x88: return object->u.generic.station_size;
 

	
 
		default: break;
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled generic feature property 0x%02X", variable);
 

	
 
	*available = false;
 
	return 0;
 
}
 

	
 

	
 
static const SpriteGroup *GenericCallbackResolveReal(const ResolverObject *object, const SpriteGroup *group)
 
{
 
	if (group->g.real.num_loaded == 0) return NULL;
 

	
 
	return group->g.real.loaded[0];
 
}
 

	
 

	
 
static inline void NewGenericResolver(ResolverObject *res)
 
{
 
	res->GetRandomBits = &GenericCallbackGetRandomBits;
 
	res->GetTriggers   = &GenericCallbackGetTriggers;
 
	res->SetTriggers   = &GenericCallbackSetTriggers;
 
	res->GetVariable   = &GenericCallbackGetVariable;
 
	res->ResolveReal   = &GenericCallbackResolveReal;
 

	
 
	res->callback        = CBID_NO_CALLBACK;
 
	res->callback_param1 = 0;
 
	res->callback_param2 = 0;
 
	res->last_value      = 0;
 
	res->trigger         = 0;
 
	res->reseed          = 0;
 
}
 

	
 

	
 
/** Follow a generic feature callback list and return the first successful
 
 * answer
 
 * @param feature GRF Feature of callback
 
 * @param object  pre-populated resolver object
 
 * @param file    address of GRFFile object if file reference is needed, NULL is valid
 
 * @return callback value if successful or CALLBACK_FAILED
 
 */
 
static uint16 GetGenericCallbackResult(uint8 feature, ResolverObject *object, const GRFFile **file)
 
{
 
	assert(feature < lengthof(_gcl));
 

	
 
	/* Test each feature callback sprite group. */
 
	for (GenericCallbackList::const_iterator it = _gcl[feature].begin(); it != _gcl[feature].end(); ++it) {
 
		const SpriteGroup *group = it->group;
 
		group = Resolve(group, object);
 
		if (group == NULL || group->type != SGT_CALLBACK) continue;
 

	
 
		/* Return NewGRF file if necessary */
 
		if (file != NULL) *file = it->file;
 

	
 
		return group->g.callback.result;
 
	}
 

	
 
	/* No callback returned a valid result, so we've failed. */
 
	return CALLBACK_FAILED;
 
}
 

	
 

	
 
/**
 
 * 'Execute' an AI purchase selection callback
 
 */
 
uint16 GetAiPurchaseCallbackResult(uint8 feature, CargoID cargo_type, uint8 default_selection, IndustryType src_industry, IndustryType dst_industry, uint8 distance, AIConstructionEvent event, uint8 count, uint8 station_size, const GRFFile **file)
 
{
 
	ResolverObject object;
 

	
 
	NewGenericResolver(&object);
 

	
 
	object.callback = CBID_GENERIC_AI_PURCHASE_SELECTION;
 
	object.u.generic.cargo_type        = cargo_type;
 
	object.u.generic.default_selection = default_selection;
 
	object.u.generic.src_industry      = src_industry;
 
	object.u.generic.dst_industry      = dst_industry;
 
	object.u.generic.distance          = distance;
 
	object.u.generic.event             = event;
 
	object.u.generic.count             = count;
 
	object.u.generic.station_size      = station_size;
 

	
 
	return GetGenericCallbackResult(feature, &object, file);
 
}
src/newgrf_generic.h
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
#ifndef NEWGRF_GENERIC_H
 
#define NEWGRF_GENERIC_H
 

	
 
enum AIConstructionEvent {
 
	AICE_TRAIN_CHECK_RAIL_ENGINE     = 0x00, ///< Check if we should build an engine
 
	AICE_TRAIN_CHECK_ELRAIL_ENGINE   = 0x01,
 
	AICE_TRAIN_CHECK_MONORAIL_ENGINE = 0x02,
 
	AICE_TRAIN_CHECK_MAGLEV_ENGINE   = 0x03,
 
	AICE_TRAIN_GET_RAIL_WAGON        = 0x08,
 
	AICE_TRAIN_GET_ELRAIL_WAGON      = 0x09,
 
	AICE_TRAIN_GET_MONORAIL_WAGON    = 0x0A,
 
	AICE_TRAIN_GET_MAGLEV_WAGON      = 0x0B,
 
	AICE_TRAIN_GET_RAILTYPE          = 0x0F,
 

	
 
	AICE_ROAD_CHECK_ENGINE           = 0x00, ///< Check if we should build an engine
 
	AICE_ROAD_GET_FIRST_ENGINE       = 0x01, ///< Unused, we check all
 
	AICE_ROAD_GET_NUMBER_ENGINES     = 0x02, ///< Unused, we check all
 

	
 
	AICE_SHIP_CHECK_ENGINE           = 0x00, ///< Check if we should build an engine
 
	AICE_SHIP_GET_FIRST_ENGINE       = 0x01, ///< Unused, we check all
 
	AICE_SHIP_GET_NUMBER_ENGINES     = 0x02, ///< Unused, we check all
 

	
 
	AICE_AIRCRAFT_CHECK_ENGINE       = 0x00, ///< Check if we should build an engine
 

	
 
	AICE_STATION_GET_STATION_ID      = 0x00, ///< Get a station ID to build
 
};
 

	
 
void ResetGenericCallbacks();
 
void AddGenericCallback(uint8 feature, const struct GRFFile *file, const struct SpriteGroup *group);
 

	
 
uint16 GetAiPurchaseCallbackResult(uint8 feature, CargoID cargo_type, uint8 default_selection, IndustryType src_industry, IndustryType dst_industry, uint8 distance, AIConstructionEvent event, uint8 count, uint8 station_size, const struct GRFFile **file);
 

	
 
#endif /* NEWGRF_GENERIC_H */
src/newgrf_spritegroup.h
Show inline comments
 
@@ -7,12 +7,13 @@
 

	
 
#include "town_type.h"
 
#include "industry_type.h"
 
#include "newgrf_storage.h"
 
#include "core/bitmath_func.hpp"
 
#include "gfx_type.h"
 
#include "newgrf_generic.h"
 

	
 
/**
 
 * Gets the value of a so-called newgrf "register".
 
 * @param i index of the register
 
 * @pre i < 0x110
 
 * @return the value of the register
 
@@ -233,12 +234,22 @@ struct ResolverObject {
 
			IndustryGfx gfx;
 
			IndustryType type;
 
		} industry;
 
		struct {
 
			const struct CargoSpec *cs;
 
		} cargo;
 
		struct {
 
			CargoID cargo_type;
 
			uint8 default_selection;
 
			IndustryType src_industry;
 
			IndustryType dst_industry;
 
			uint8 distance;
 
			AIConstructionEvent event;
 
			uint8 count;
 
			uint8 station_size;
 
		} generic;
 
	} u;
 

	
 
	uint32 (*GetRandomBits)(const struct ResolverObject*);
 
	uint32 (*GetTriggers)(const struct ResolverObject*);
 
	void (*SetTriggers)(const struct ResolverObject*, int);
 
	uint32 (*GetVariable)(const struct ResolverObject*, byte, byte, bool*);
0 comments (0 inline, 0 general)