Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013 #include "debug.h"
00014 #include "newgrf.h"
00015 #include "newgrf_spritegroup.h"
00016 #include "industrytype.h"
00017 #include "core/bitmath_func.hpp"
00018 #include <list>
00019
00020
00021 struct GenericCallback {
00022 const GRFFile *file;
00023 const SpriteGroup *group;
00024
00025 GenericCallback(const GRFFile *file, const SpriteGroup *group) :
00026 file(file),
00027 group(group)
00028 { }
00029 };
00030
00031 typedef std::list<GenericCallback> GenericCallbackList;
00032
00033 static GenericCallbackList _gcl[GSF_END];
00034
00035
00039 void ResetGenericCallbacks()
00040 {
00041 for (uint8 feature = 0; feature < lengthof(_gcl); feature++) {
00042 _gcl[feature].clear();
00043 }
00044 }
00045
00046
00053 void AddGenericCallback(uint8 feature, const GRFFile *file, const SpriteGroup *group)
00054 {
00055 if (feature >= lengthof(_gcl)) {
00056 grfmsg(5, "AddGenericCallback: Unsupported feature 0x%02X", feature);
00057 return;
00058 }
00059
00060
00061
00062
00063 _gcl[feature].push_front(GenericCallback(file, group));
00064 }
00065
00066
00067 static uint32 GenericCallbackGetRandomBits(const ResolverObject *object)
00068 {
00069 return 0;
00070 }
00071
00072
00073 static uint32 GenericCallbackGetTriggers(const ResolverObject *object)
00074 {
00075 return 0;
00076 }
00077
00078
00079 static void GenericCallbackSetTriggers(const ResolverObject *object, int triggers)
00080 {
00081 return;
00082 }
00083
00084
00085 static uint32 GenericCallbackGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
00086 {
00087 switch (variable) {
00088 case 0x40: return object->grffile->cargo_map[object->u.generic.cargo_type];
00089
00090 case 0x80: return object->u.generic.cargo_type;
00091 case 0x81: return CargoSpec::Get(object->u.generic.cargo_type)->bitnum;
00092 case 0x82: return object->u.generic.default_selection;
00093 case 0x83: return object->u.generic.src_industry;
00094 case 0x84: return object->u.generic.dst_industry;
00095 case 0x85: return object->u.generic.distance;
00096 case 0x86: return object->u.generic.event;
00097 case 0x87: return object->u.generic.count;
00098 case 0x88: return object->u.generic.station_size;
00099
00100 default: break;
00101 }
00102
00103 DEBUG(grf, 1, "Unhandled generic feature variable 0x%02X", variable);
00104
00105 *available = false;
00106 return UINT_MAX;
00107 }
00108
00109
00110 static const SpriteGroup *GenericCallbackResolveReal(const ResolverObject *object, const RealSpriteGroup *group)
00111 {
00112 if (group->num_loaded == 0) return NULL;
00113
00114 return group->loaded[0];
00115 }
00116
00117
00118 static inline void NewGenericResolver(ResolverObject *res)
00119 {
00120 res->GetRandomBits = &GenericCallbackGetRandomBits;
00121 res->GetTriggers = &GenericCallbackGetTriggers;
00122 res->SetTriggers = &GenericCallbackSetTriggers;
00123 res->GetVariable = &GenericCallbackGetVariable;
00124 res->ResolveReal = &GenericCallbackResolveReal;
00125
00126 res->callback = CBID_NO_CALLBACK;
00127 res->callback_param1 = 0;
00128 res->callback_param2 = 0;
00129 res->ResetState();
00130 }
00131
00132
00142 static uint16 GetGenericCallbackResult(uint8 feature, ResolverObject *object, const GRFFile **file)
00143 {
00144 assert(feature < lengthof(_gcl));
00145
00146
00147 for (GenericCallbackList::const_iterator it = _gcl[feature].begin(); it != _gcl[feature].end(); ++it) {
00148 const SpriteGroup *group = it->group;
00149 object->grffile = it->file;
00150 group = SpriteGroup::Resolve(group, object);
00151 if (group == NULL || group->GetCallbackResult() == CALLBACK_FAILED) continue;
00152
00153
00154 if (file != NULL) *file = it->file;
00155
00156 return group->GetCallbackResult();
00157 }
00158
00159
00160 return CALLBACK_FAILED;
00161 }
00162
00163
00180 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)
00181 {
00182 ResolverObject object;
00183
00184 NewGenericResolver(&object);
00185
00186 if (src_industry != IT_AI_UNKNOWN && src_industry != IT_AI_TOWN) {
00187 const IndustrySpec *is = GetIndustrySpec(src_industry);
00188
00189 if (is->grf_prop.subst_id != INVALID_INDUSTRYTYPE) src_industry = is->grf_prop.subst_id;
00190 }
00191
00192 if (dst_industry != IT_AI_UNKNOWN && dst_industry != IT_AI_TOWN) {
00193 const IndustrySpec *is = GetIndustrySpec(dst_industry);
00194
00195 if (is->grf_prop.subst_id != INVALID_INDUSTRYTYPE) dst_industry = is->grf_prop.subst_id;
00196 }
00197
00198 object.callback = CBID_GENERIC_AI_PURCHASE_SELECTION;
00199 object.u.generic.cargo_type = cargo_type;
00200 object.u.generic.default_selection = default_selection;
00201 object.u.generic.src_industry = src_industry;
00202 object.u.generic.dst_industry = dst_industry;
00203 object.u.generic.distance = distance;
00204 object.u.generic.event = event;
00205 object.u.generic.count = count;
00206 object.u.generic.station_size = station_size;
00207
00208 uint16 callback = GetGenericCallbackResult(feature, &object, file);
00209 if (callback != CALLBACK_FAILED) callback = GB(callback, 0, 8);
00210 return callback;
00211 }