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