summaryrefslogtreecommitdiff
path: root/src/vehicle.cpp
diff options
context:
space:
mode:
authormaedhros <maedhros@openttd.org>2007-06-11 14:00:16 +0000
committermaedhros <maedhros@openttd.org>2007-06-11 14:00:16 +0000
commit3e326085fa69da20e0a81182cbea4466016eb566 (patch)
tree890b370c5bc0ffbb3bd5a9eb55a4b0a3117acd29 /src/vehicle.cpp
parentbe0f5cf877bb2d7a74855f8988e50ca09624aabe (diff)
downloadopenttd-3e326085fa69da20e0a81182cbea4466016eb566.tar.xz
(svn r10097) -Feature: Add support for articulated road vehicles, or callbacks 11 and 17 for
road vehicles for those who prefer the technical explanation.
Diffstat (limited to 'src/vehicle.cpp')
-rw-r--r--src/vehicle.cpp48
1 files changed, 35 insertions, 13 deletions
diff --git a/src/vehicle.cpp b/src/vehicle.cpp
index 47b8b7c5c..025cadd00 100644
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -230,11 +230,15 @@ void AfterLoadVehicles()
v->first = NULL;
if (v->type == VEH_TRAIN) v->u.rail.first_engine = INVALID_ENGINE;
+ if (v->type == VEH_ROAD) v->u.road.first_engine = INVALID_ENGINE;
}
FOR_ALL_VEHICLES(v) {
- if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v)))
+ if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
TrainConsistChanged(v);
+ } else if (v->type == VEH_ROAD && IsRoadVehFront(v)) {
+ RoadVehUpdateCache(v);
+ }
}
FOR_ALL_VEHICLES(v) {
@@ -498,7 +502,7 @@ static Vehicle *GetPrevVehicleInChain_bruteforce(const Vehicle *v)
{
Vehicle *u;
- FOR_ALL_VEHICLES(u) if (u->type == VEH_TRAIN && u->next == v) return u;
+ FOR_ALL_VEHICLES(u) if (u->type == v->type && u->next == v) return u;
return NULL;
}
@@ -531,10 +535,14 @@ Vehicle *GetFirstVehicleInChain(const Vehicle *v)
Vehicle* u;
assert(v != NULL);
- assert(v->type == VEH_TRAIN);
+ assert(v->type == VEH_TRAIN || v->type == VEH_ROAD);
if (v->first != NULL) {
- if (IsFrontEngine(v->first) || IsFreeWagon(v->first)) return v->first;
+ if (v->type == VEH_TRAIN) {
+ if (IsFrontEngine(v->first) || IsFreeWagon(v->first)) return v->first;
+ } else {
+ if (IsRoadVehFront(v->first)) return v->first;
+ }
DEBUG(misc, 0, "v->first cache faulty. We shouldn't be here, rebuilding cache!");
}
@@ -548,8 +556,10 @@ Vehicle *GetFirstVehicleInChain(const Vehicle *v)
while ((u = GetPrevVehicleInChain_bruteforce(v)) != NULL) v = u;
/* Set the first pointer of all vehicles in that chain to the first wagon */
- if (IsFrontEngine(v) || IsFreeWagon(v))
+ if ((v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) ||
+ (v->type == VEH_ROAD && IsRoadVehFront(v))) {
for (u = (Vehicle *)v; u != NULL; u = u->next) u->first = (Vehicle *)v;
+ }
return (Vehicle*)v;
}
@@ -572,9 +582,8 @@ bool IsEngineCountable(const Vehicle *v)
case VEH_TRAIN:
return !IsArticulatedPart(v) && // tenders and other articulated parts
(!IsMultiheaded(v) || IsTrainEngine(v)); // rear parts of multiheaded engines
- case VEH_ROAD:
- case VEH_SHIP:
- return true;
+ case VEH_ROAD: return IsRoadVehFront(v);
+ case VEH_SHIP: return true;
default: return false; // Only count player buildable vehicles
}
}
@@ -609,7 +618,9 @@ void DestroyVehicle(Vehicle *v)
/* Now remove any artic part. This will trigger an other
* destroy vehicle, which on his turn can remove any
* other artic parts. */
- if (v->type == VEH_TRAIN && EngineHasArticPart(v)) DeleteVehicle(v->next);
+ if ((v->type == VEH_TRAIN && EngineHasArticPart(v)) || (v->type == VEH_ROAD && RoadVehHasArticPart(v))) {
+ DeleteVehicle(v->next);
+ }
}
/**
@@ -621,7 +632,7 @@ void DestroyVehicle(Vehicle *v)
*/
void DeleteVehicleChain(Vehicle *v)
{
- assert(v->type != VEH_TRAIN);
+ assert(v->type != VEH_TRAIN && v->type != VEH_ROAD);
do {
Vehicle *u = v;
@@ -705,6 +716,7 @@ void CallVehicleTicks()
case VEH_SHIP:
if (v->type == VEH_TRAIN && IsTrainWagon(v)) continue;
if (v->type == VEH_AIRCRAFT && v->subtype != AIR_HELICOPTER) continue;
+ if (v->type == VEH_ROAD && !IsRoadVehFront(v)) continue;
v->motion_counter += (v->direction & 1) ? (v->cur_speed * 3) / 4 : v->cur_speed;
/* Play a running sound if the motion counter passes 256 (Do we not skip sounds?) */
@@ -1876,6 +1888,8 @@ int32 CmdCloneVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (w->type == VEH_TRAIN && EngineHasArticPart(w)) {
w = GetNextArticPart(w);
+ } else if (w->type == VEH_ROAD && RoadVehHasArticPart(w)) {
+ w = w->next;
} else {
break;
}
@@ -1886,7 +1900,15 @@ int32 CmdCloneVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
total_cost += GetRefitCost(v->engine_type);
}
}
- } while (v->type == VEH_TRAIN && EngineHasArticPart(v) && (v = GetNextArticPart(v)) != NULL);
+
+ if (v->type == VEH_TRAIN && EngineHasArticPart(v)) {
+ v = GetNextArticPart(v);
+ } else if (v->type == VEH_ROAD && RoadVehHasArticPart(v)) {
+ v = v->next;
+ } else {
+ break;
+ }
+ } while (v != NULL);
if ((flags & DC_EXEC) && v->type == VEH_TRAIN) w = GetNextVehicle(w);
} while (v->type == VEH_TRAIN && (v = GetNextVehicle(v)) != NULL);
@@ -1964,7 +1986,7 @@ void BuildDepotVehicleList(VehicleType type, TileIndex tile, Vehicle ***engine_l
case VEH_ROAD:
FOR_ALL_VEHICLES(v) {
- if (v->tile == tile && v->type == VEH_ROAD && IsRoadVehInDepot(v)) {
+ if (v->tile == tile && v->type == VEH_ROAD && IsRoadVehInDepot(v) && IsRoadVehFront(v)) {
if (*engine_count == *engine_list_length) ExtendVehicleListSize((const Vehicle***)engine_list, engine_list_length, 25);
(*engine_list)[(*engine_count)++] = v;
}
@@ -2163,7 +2185,7 @@ void VehicleEnterDepot(Vehicle *v)
case VEH_ROAD:
InvalidateWindowClasses(WC_ROADVEH_LIST);
- v->u.road.state = RVSB_IN_DEPOT;
+ if (!IsRoadVehFront(v)) v = GetFirstVehicleInChain(v);
break;
case VEH_SHIP: