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->u.generic.cargo_type;
00089
00090 case 0x80: return object->u.generic.cargo_type;
00091 case 0x81: return object->u.generic.cargo_type;
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, const GRFFile *grffile)
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->last_value = 0;
00130 res->trigger = 0;
00131 res->reseed = 0;
00132 res->count = 0;
00133 res->grffile = grffile;
00134 }
00135
00136
00145 static uint16 GetGenericCallbackResult(uint8 feature, ResolverObject *object, const GRFFile **file)
00146 {
00147 assert(feature < lengthof(_gcl));
00148
00149
00150 for (GenericCallbackList::const_iterator it = _gcl[feature].begin(); it != _gcl[feature].end(); ++it) {
00151 const SpriteGroup *group = it->group;
00152 group = SpriteGroup::Resolve(group, object);
00153 if (group == NULL) continue;
00154
00155
00156 if (file != NULL) *file = it->file;
00157
00158 return group->GetCallbackResult();
00159 }
00160
00161
00162 return CALLBACK_FAILED;
00163 }
00164
00165
00169 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)
00170 {
00171 ResolverObject object;
00172
00173 NewGenericResolver(&object, *file);
00174
00175 if (src_industry != IT_AI_UNKNOWN && src_industry != IT_AI_TOWN) {
00176 const IndustrySpec *is = GetIndustrySpec(src_industry);
00177
00178 if (is->grf_prop.subst_id != INVALID_INDUSTRYTYPE) src_industry = is->grf_prop.subst_id;
00179 }
00180
00181 if (dst_industry != IT_AI_UNKNOWN && dst_industry != IT_AI_TOWN) {
00182 const IndustrySpec *is = GetIndustrySpec(dst_industry);
00183
00184 if (is->grf_prop.subst_id != INVALID_INDUSTRYTYPE) dst_industry = is->grf_prop.subst_id;
00185 }
00186
00187 object.callback = CBID_GENERIC_AI_PURCHASE_SELECTION;
00188 object.u.generic.cargo_type = cargo_type;
00189 object.u.generic.default_selection = default_selection;
00190 object.u.generic.src_industry = src_industry;
00191 object.u.generic.dst_industry = dst_industry;
00192 object.u.generic.distance = distance;
00193 object.u.generic.event = event;
00194 object.u.generic.count = count;
00195 object.u.generic.station_size = station_size;
00196
00197 uint16 callback = GetGenericCallbackResult(feature, &object, file);
00198 if (callback != CALLBACK_FAILED) callback = GB(callback, 0, 8);
00199 return callback;
00200 }