articulated_vehicles.cpp

Go to the documentation of this file.
00001 /* $Id: articulated_vehicles.cpp 13686 2008-07-09 19:13:21Z rubidium $ */
00002 
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "articulated_vehicles.h"
00008 #include "engine.h"
00009 #include "train.h"
00010 #include "roadveh.h"
00011 #include "newgrf_callbacks.h"
00012 #include "newgrf_engine.h"
00013 #include "vehicle_func.h"
00014 
00015 
00016 uint CountArticulatedParts(EngineID engine_type, bool purchase_window)
00017 {
00018   if (!HasBit(EngInfo(engine_type)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) return 0;
00019 
00020   Vehicle *v = NULL;;
00021   if (!purchase_window) {
00022     v = new InvalidVehicle();
00023     v->engine_type = engine_type;
00024   }
00025 
00026   uint i;
00027   for (i = 1; i < MAX_UVALUE(EngineID); i++) {
00028     uint16 callback = GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE, i, 0, engine_type, v);
00029     if (callback == CALLBACK_FAILED || GB(callback, 0, 8) == 0xFF) break;
00030   }
00031 
00032   delete v;
00033 
00034   return i - 1;
00035 }
00036 
00037 
00038 uint16 *GetCapacityOfArticulatedParts(EngineID engine, VehicleType type)
00039 {
00040   static uint16 capacity[NUM_CARGO];
00041   memset(capacity, 0, sizeof(capacity));
00042 
00043   if (type == VEH_TRAIN) {
00044     const RailVehicleInfo *rvi = RailVehInfo(engine);
00045     capacity[rvi->cargo_type] = GetEngineProperty(engine, 0x14, rvi->capacity);
00046     if (rvi->railveh_type == RAILVEH_MULTIHEAD) capacity[rvi->cargo_type] += rvi->capacity;
00047   } else if (type == VEH_ROAD) {
00048     const RoadVehicleInfo *rvi = RoadVehInfo(engine);
00049     capacity[rvi->cargo_type] = GetEngineProperty(engine, 0x0F, rvi->capacity);
00050   }
00051 
00052   if (!HasBit(EngInfo(engine)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) return capacity;
00053 
00054   for (uint i = 1; i < MAX_UVALUE(EngineID); i++) {
00055     uint16 callback = GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE, i, 0, engine, NULL);
00056     if (callback == CALLBACK_FAILED || GB(callback, 0, 8) == 0xFF) break;
00057 
00058     EngineID artic_engine = GetFirstEngineOfType(type) + GB(callback, 0, 7);
00059 
00060     if (type == VEH_TRAIN) {
00061       const RailVehicleInfo *rvi = RailVehInfo(artic_engine);
00062       capacity[rvi->cargo_type] += GetEngineProperty(artic_engine, 0x14, rvi->capacity);
00063     } else if (type == VEH_ROAD) {
00064       const RoadVehicleInfo *rvi = RoadVehInfo(artic_engine);
00065       capacity[rvi->cargo_type] += GetEngineProperty(artic_engine, 0x0F, rvi->capacity);
00066     }
00067   }
00068 
00069   return capacity;
00070 }
00071 
00072 
00073 void AddArticulatedParts(Vehicle **vl, VehicleType type)
00074 {
00075   const Vehicle *v = vl[0];
00076   Vehicle *u = vl[0];
00077 
00078   if (!HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) return;
00079 
00080   for (uint i = 1; i < MAX_UVALUE(EngineID); i++) {
00081     uint16 callback = GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE, i, 0, v->engine_type, v);
00082     if (callback == CALLBACK_FAILED || GB(callback, 0, 8) == 0xFF) return;
00083 
00084     /* Attempt to use pre-allocated vehicles until they run out. This can happen
00085      * if the callback returns different values depending on the cargo type. */
00086     u->SetNext(vl[i]);
00087     if (u->Next() == NULL) return;
00088 
00089     Vehicle *previous = u;
00090     u = u->Next();
00091 
00092     EngineID engine_type = GetFirstEngineOfType(type) + GB(callback, 0, 7);
00093     bool flip_image = HasBit(callback, 7);
00094 
00095     /* get common values from first engine */
00096     u->direction = v->direction;
00097     u->owner = v->owner;
00098     u->tile = v->tile;
00099     u->x_pos = v->x_pos;
00100     u->y_pos = v->y_pos;
00101     u->z_pos = v->z_pos;
00102     u->build_year = v->build_year;
00103     u->vehstatus = v->vehstatus & ~VS_STOPPED;
00104 
00105     u->cargo_subtype = 0;
00106     u->max_speed = 0;
00107     u->max_age = 0;
00108     u->engine_type = engine_type;
00109     u->value = 0;
00110     u->subtype = 0;
00111     u->cur_image = 0xAC2;
00112     u->random_bits = VehicleRandomBits();
00113 
00114     switch (type) {
00115       default: NOT_REACHED();
00116 
00117       case VEH_TRAIN: {
00118         const RailVehicleInfo *rvi_artic = RailVehInfo(engine_type);
00119 
00120         u = new (u) Train();
00121         previous->SetNext(u);
00122         u->u.rail.track = v->u.rail.track;
00123         u->u.rail.railtype = v->u.rail.railtype;
00124         u->u.rail.first_engine = v->engine_type;
00125 
00126         u->spritenum = rvi_artic->image_index;
00127         u->cargo_type = rvi_artic->cargo_type;
00128         u->cargo_cap = rvi_artic->capacity;
00129 
00130         SetArticulatedPart(u);
00131       } break;
00132 
00133       case VEH_ROAD: {
00134         const RoadVehicleInfo *rvi_artic = RoadVehInfo(engine_type);
00135 
00136         u = new (u) RoadVehicle();
00137         previous->SetNext(u);
00138         u->u.road.first_engine = v->engine_type;
00139         u->u.road.cached_veh_length = GetRoadVehLength(u);
00140         u->u.road.state = RVSB_IN_DEPOT;
00141 
00142         u->u.road.roadtype = v->u.road.roadtype;
00143         u->u.road.compatible_roadtypes = v->u.road.compatible_roadtypes;
00144 
00145         u->spritenum = rvi_artic->image_index;
00146         u->cargo_type = rvi_artic->cargo_type;
00147         u->cargo_cap = rvi_artic->capacity;
00148 
00149         SetRoadVehArticPart(u);
00150       } break;
00151     }
00152 
00153     if (flip_image) u->spritenum++;
00154 
00155     VehiclePositionChanged(u);
00156   }
00157 }

Generated on Wed Oct 1 17:03:20 2008 for openttd by  doxygen 1.5.6