peter1138@6365: /* $Id$ */ peter1138@6365: rubidium@9111: /** @file newgrf_cargo.cpp Implementation of NewGRF cargoes. */ rubidium@9111: peter1138@6365: #include "stdafx.h" peter1138@6365: #include "openttd.h" peter1138@6383: #include "debug.h" peter1138@6365: #include "cargotype.h" peter1138@6365: #include "newgrf.h" peter1138@6365: #include "newgrf_callbacks.h" peter1138@6365: #include "newgrf_spritegroup.h" peter1138@6365: #include "newgrf_cargo.h" peter1138@6365: peter1138@6365: peter1138@6365: static uint32 CargoGetRandomBits(const ResolverObject *object) peter1138@6365: { peter1138@6365: return 0; peter1138@6365: } peter1138@6365: peter1138@6365: peter1138@6365: static uint32 CargoGetTriggers(const ResolverObject *object) peter1138@6365: { peter1138@6365: return 0; peter1138@6365: } peter1138@6365: peter1138@6365: peter1138@6365: static void CargoSetTriggers(const ResolverObject *object, int triggers) peter1138@6365: { peter1138@6365: return; peter1138@6365: } peter1138@6365: peter1138@6365: peter1138@6365: static uint32 CargoGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) peter1138@6365: { peter1138@6383: DEBUG(grf, 1, "Unhandled cargo property 0x%X", variable); peter1138@6383: peter1138@6365: *available = false; peter1138@6365: return 0; peter1138@6365: } peter1138@6365: peter1138@6365: peter1138@6365: static const SpriteGroup *CargoResolveReal(const ResolverObject *object, const SpriteGroup *group) peter1138@6365: { peter1138@6657: /* Cargo action 2s should always have only 1 "loaded" state, but some peter1138@6657: * times things don't follow the spec... */ peter1138@6657: if (group->g.real.num_loaded > 0) return group->g.real.loaded[0]; peter1138@6657: if (group->g.real.num_loading > 0) return group->g.real.loading[0]; peter1138@6365: peter1138@6657: return NULL; peter1138@6365: } peter1138@6365: peter1138@6365: peter1138@6365: static void NewCargoResolver(ResolverObject *res, const CargoSpec *cs) peter1138@6365: { peter1138@6365: res->GetRandomBits = &CargoGetRandomBits; peter1138@6365: res->GetTriggers = &CargoGetTriggers; peter1138@6365: res->SetTriggers = &CargoSetTriggers; peter1138@6365: res->GetVariable = &CargoGetVariable; peter1138@6365: res->ResolveReal = &CargoResolveReal; peter1138@6365: peter1138@6365: res->u.cargo.cs = cs; peter1138@6365: rubidium@7327: res->callback = CBID_NO_CALLBACK; peter1138@6365: res->callback_param1 = 0; peter1138@6365: res->callback_param2 = 0; peter1138@6365: res->last_value = 0; peter1138@6365: res->trigger = 0; peter1138@6365: res->reseed = 0; glx@8756: res->count = 0; frosch@9750: res->grffile = cs->grffile; peter1138@6365: } peter1138@6365: peter1138@6365: peter1138@6365: SpriteID GetCustomCargoSprite(const CargoSpec *cs) peter1138@6365: { peter1138@6365: const SpriteGroup *group; peter1138@6365: ResolverObject object; peter1138@6365: peter1138@6365: NewCargoResolver(&object, cs); peter1138@6365: peter1138@6365: group = Resolve(cs->group, &object); peter1138@6365: if (group == NULL || group->type != SGT_RESULT) return 0; peter1138@6365: peter1138@6365: return group->g.result.sprite; peter1138@6365: } peter1138@6365: peter1138@6365: rubidium@7327: uint16 GetCargoCallback(CallbackID callback, uint32 param1, uint32 param2, const CargoSpec *cs) peter1138@6365: { peter1138@6365: ResolverObject object; peter1138@6365: const SpriteGroup *group; peter1138@6365: peter1138@6365: NewCargoResolver(&object, cs); peter1138@6365: object.callback = callback; peter1138@6365: object.callback_param1 = param1; peter1138@6365: object.callback_param2 = param2; peter1138@6365: peter1138@6365: group = Resolve(cs->group, &object); peter1138@6365: if (group == NULL || group->type != SGT_CALLBACK) return CALLBACK_FAILED; peter1138@6365: peter1138@6365: return group->g.callback.result; peter1138@6365: } peter1138@6460: peter1138@6460: glx@7717: CargoID GetCargoTranslation(uint8 cargo, const GRFFile *grffile, bool usebit) peter1138@6460: { peter1138@6460: /* Pre-version 7 uses the 'climate dependent' ID, i.e. cargo is the cargo ID */ glx@7717: if (grffile->grf_version < 7) { glx@7717: if (!usebit) return cargo; glx@7717: /* Else the cargo value is a 'climate independent' 'bitnum' */ skidd13@7928: if (HasBit(_cargo_mask, cargo)) return GetCargoIDByBitnum(cargo); glx@7717: } else { peter1138@9728: /* If the GRF contains a translation table... */ peter1138@9728: if (grffile->cargo_max > 0) { peter1138@9728: /* ...and the cargo is in bounds, then get the cargo ID for peter1138@9728: * the label */ peter1138@9728: if (cargo < grffile->cargo_max) return GetCargoIDByLabel(grffile->cargo_list[cargo]); peter1138@9728: } else { peter1138@9728: /* Else the cargo value is a 'climate independent' 'bitnum' */ peter1138@9728: if (HasBit(_cargo_mask, cargo)) return GetCargoIDByBitnum(cargo); peter1138@9728: } glx@7717: } glx@7717: return CT_INVALID; peter1138@6460: } rubidium@7199: rubidium@7199: uint8 GetReverseCargoTranslation(CargoID cargo, const GRFFile *grffile) rubidium@7199: { frosch@8564: /* Note: All grf versions use CargoBit here. Pre-version 7 do NOT use the 'climate dependent' ID. */ rubidium@7199: const CargoSpec *cs = GetCargo(cargo); rubidium@7199: rubidium@7199: /* If the GRF contains a translation table (and the cargo is in the table) rubidium@7199: * then get the cargo ID for the label */ rubidium@7199: for (uint i = 0; i < grffile->cargo_max; i++) { rubidium@7199: if (cs->label == grffile->cargo_list[i]) return i; rubidium@7199: } rubidium@7199: rubidium@7199: /* No matching label was found, so we return the 'climate independent' 'bitnum' */ rubidium@7199: return cs->bitnum;; rubidium@7199: }