# newgrf_cargo.cpp

Go to the documentation of this file.

    00001 /* $Id: newgrf_cargo.cpp 18809 2010-01-15 16:41:15Z rubidium $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    00008  */
    00009
    00012 #include "stdafx.h"
    00013 #include "debug.h"
    00014 #include "newgrf.h"
    00015 #include "newgrf_spritegroup.h"
    00016 #include "core/bitmath_func.hpp"
    00017
    00018 static uint32 CargoGetRandomBits(const ResolverObject *object)
    00019 {
    00020   return 0;
    00021 }
    00022
    00023
    00024 static uint32 CargoGetTriggers(const ResolverObject *object)
    00025 {
    00026   return 0;
    00027 }
    00028
    00029
    00030 static void CargoSetTriggers(const ResolverObject *object, int triggers)
    00031 {
    00032   return;
    00033 }
    00034
    00035
    00036 static uint32 CargoGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
    00037 {
    00038   DEBUG(grf, 1, "Unhandled cargo property 0x%X", variable);
    00039
    00040   *available = false;
    00041   return UINT_MAX;
    00042 }
    00043
    00044
    00045 static const SpriteGroup *CargoResolveReal(const ResolverObject *object, const RealSpriteGroup *group)
    00046 {
    00047   /* Cargo action 2s should always have only 1 "loaded" state, but some
    00048    * times things don't follow the spec... */
    00049   if (group->num_loaded > 0) return group->loaded[0];
    00050   if (group->num_loading > 0) return group->loading[0];
    00051
    00052   return NULL;
    00053 }
    00054
    00055
    00056 static void NewCargoResolver(ResolverObject *res, const CargoSpec *cs)
    00057 {
    00058   res->GetRandomBits = &CargoGetRandomBits;
    00059   res->GetTriggers   = &CargoGetTriggers;
    00060   res->SetTriggers   = &CargoSetTriggers;
    00061   res->GetVariable   = &CargoGetVariable;
    00062   res->ResolveReal   = &CargoResolveReal;
    00063
    00064   res->u.cargo.cs = cs;
    00065
    00066   res->callback        = CBID_NO_CALLBACK;
    00067   res->callback_param1 = 0;
    00068   res->callback_param2 = 0;
    00069   res->last_value      = 0;
    00070   res->trigger         = 0;
    00071   res->reseed          = 0;
    00072   res->count           = 0;
    00073   res->grffile         = cs->grffile;
    00074 }
    00075
    00076
    00077 SpriteID GetCustomCargoSprite(const CargoSpec *cs)
    00078 {
    00079   const SpriteGroup *group;
    00080   ResolverObject object;
    00081
    00082   NewCargoResolver(&object, cs);
    00083
    00084   group = SpriteGroup::Resolve(cs->group, &object);
    00085   if (group == NULL) return 0;
    00086
    00087   return group->GetResult();
    00088 }
    00089
    00090
    00091 uint16 GetCargoCallback(CallbackID callback, uint32 param1, uint32 param2, const CargoSpec *cs)
    00092 {
    00093   ResolverObject object;
    00094   const SpriteGroup *group;
    00095
    00096   NewCargoResolver(&object, cs);
    00097   object.callback = callback;
    00098   object.callback_param1 = param1;
    00099   object.callback_param2 = param2;
    00100
    00101   group = SpriteGroup::Resolve(cs->group, &object);
    00102   if (group == NULL) return CALLBACK_FAILED;
    00103
    00104   return group->GetCallbackResult();
    00105 }
    00106
    00107
    00108 CargoID GetCargoTranslation(uint8 cargo, const GRFFile *grffile, bool usebit)
    00109 {
    00110   /* Pre-version 7 uses the 'climate dependent' ID, i.e. cargo is the cargo ID */
    00111   if (grffile->grf_version < 7) {
    00112     if (!usebit) return cargo;
    00113     /* Else the cargo value is a 'climate independent' 'bitnum' */
    00114     if (HasBit(_cargo_mask, cargo)) return GetCargoIDByBitnum(cargo);
    00115   } else {
    00116     /* If the GRF contains a translation table... */
    00117     if (grffile->cargo_max > 0) {
    00118       /* ...and the cargo is in bounds, then get the cargo ID for
    00119        * the label */
    00120       if (cargo < grffile->cargo_max) return GetCargoIDByLabel(grffile->cargo_list[cargo]);
    00121     } else {
    00122       /* Else the cargo value is a 'climate independent' 'bitnum' */
    00123       if (HasBit(_cargo_mask, cargo)) return GetCargoIDByBitnum(cargo);
    00124     }
    00125   }
    00126   return CT_INVALID;
    00127 }
    00128
    00129 uint8 GetReverseCargoTranslation(CargoID cargo, const GRFFile *grffile)
    00130 {
    00131   /* Note: All grf versions use CargoBit here. Pre-version 7 do NOT use the 'climate dependent' ID. */
    00132   const CargoSpec *cs = CargoSpec::Get(cargo);
    00133
    00134   /* If the GRF contains a translation table (and the cargo is in the table)
    00135    * then get the cargo ID for the label */
    00136   for (uint i = 0; i < grffile->cargo_max; i++) {
    00137     if (cs->label == grffile->cargo_list[i]) return i;
    00138   }
    00139
    00140   /* No matching label was found, so we return the 'climate independent' 'bitnum' */
    00141   return cs->bitnum;;
    00142 }