summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/train_cmd.cpp88
1 files changed, 47 insertions, 41 deletions
diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp
index f04121db6..0aca1b08d 100644
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -2659,28 +2659,6 @@ static void TrainMovedChangeSignals(TileIndex tile, DiagDirection dir)
}
-struct TrainCollideChecker {
- const Vehicle *v;
- const Vehicle *v_skip;
-};
-
-static void *FindTrainCollideEnum(Vehicle *v, void *data)
-{
- const TrainCollideChecker* tcc = (TrainCollideChecker*)data;
-
- if (v != tcc->v &&
- v != tcc->v_skip &&
- v->type == VEH_TRAIN &&
- v->u.rail.track != TRACK_BIT_DEPOT &&
- myabs(v->z_pos - tcc->v->z_pos) < 6 &&
- myabs(v->x_pos - tcc->v->x_pos) < 6 &&
- myabs(v->y_pos - tcc->v->y_pos) < 6) {
- return v;
- } else {
- return NULL;
- }
-}
-
static void SetVehicleCrashed(Vehicle *v)
{
if (v->u.rail.crash_anim_pos != 0) return;
@@ -2704,6 +2682,47 @@ static uint CountPassengersInTrain(const Vehicle* v)
return num;
}
+struct TrainCollideChecker {
+ Vehicle *v;
+ const Vehicle *v_skip;
+ uint num;
+};
+
+static void *FindTrainCollideEnum(Vehicle *v, void *data)
+{
+ TrainCollideChecker* tcc = (TrainCollideChecker*)data;
+
+ if (v != tcc->v &&
+ v != tcc->v_skip &&
+ v->type == VEH_TRAIN &&
+ v->u.rail.track != TRACK_BIT_DEPOT &&
+ myabs(v->z_pos - tcc->v->z_pos) < 6 &&
+ myabs(v->x_pos - tcc->v->x_pos) < 6 &&
+ myabs(v->y_pos - tcc->v->y_pos) < 6 ) {
+
+ Vehicle *coll = GetFirstVehicleInChain(v);
+
+ /* it can't collide with its own wagons */
+ if (tcc->v == coll ||
+ (tcc->v->u.rail.track == TRACK_BIT_WORMHOLE && (tcc->v->direction & 2) != (v->direction & 2)))
+ return NULL;
+
+ /* two drivers + passengers killed in train tcc->v (if it was not crashed already) */
+ if (!(tcc->v->vehstatus & VS_CRASHED)) {
+ tcc->num += 2 + CountPassengersInTrain(tcc->v);
+ SetVehicleCrashed(tcc->v);
+ }
+
+ if (!(coll->vehstatus & VS_CRASHED)) {
+ /* two drivers + passengers killed in train coll (if it was not crashed already) */
+ tcc->num += 2 + CountPassengersInTrain(coll);
+ SetVehicleCrashed(coll);
+ }
+ }
+
+ return NULL;
+}
+
/**
* Checks whether the specified train has a collision with another vehicle. If
* so, destroys this vehicle, and the other vehicle if its subtype has TS_Front.
@@ -2720,28 +2739,15 @@ static void CheckTrainCollision(Vehicle *v)
TrainCollideChecker tcc;
tcc.v = v;
tcc.v_skip = v->next;
+ tcc.num = 0;
- /* find colliding vehicle */
- Vehicle *realcoll = (Vehicle*)VehicleFromPosXY(v->x_pos, v->y_pos, &tcc, FindTrainCollideEnum);
- if (realcoll == NULL) return;
-
- Vehicle *coll = GetFirstVehicleInChain(realcoll);
-
- /* it can't collide with its own wagons */
- if (v == coll ||
- (v->u.rail.track == TRACK_BIT_WORMHOLE && (v->direction & 2) != (realcoll->direction & 2)))
- return;
-
- /* two drivers + passengers killed in train v */
- uint num = 2 + CountPassengersInTrain(v);
- if (!(coll->vehstatus & VS_CRASHED))
- /* two drivers + passengers killed in train coll (if it was not crashed already) */
- num += 2 + CountPassengersInTrain(coll);
+ /* find colliding vehicles */
+ VehicleFromPosXY(v->x_pos, v->y_pos, &tcc, FindTrainCollideEnum);
- SetVehicleCrashed(v);
- if (IsFrontEngine(coll)) SetVehicleCrashed(coll);
+ /* any dead -> no crash */
+ if (tcc.num == 0) return;
- SetDParam(0, num);
+ SetDParam(0, tcc.num);
AddNewsItem(STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL,
NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_VEHICLE, NT_ACCIDENT, 0),
v->index,