2913 UpdateSignalsOnSegment(tile, _otherside_signal_directions[i]); |
2913 UpdateSignalsOnSegment(tile, _otherside_signal_directions[i]); |
2914 } |
2914 } |
2915 } |
2915 } |
2916 |
2916 |
2917 |
2917 |
2918 typedef struct TrainCollideChecker { |
|
2919 const Vehicle *v; |
|
2920 const Vehicle *v_skip; |
|
2921 } TrainCollideChecker; |
|
2922 |
|
2923 static void *FindTrainCollideEnum(Vehicle *v, void *data) |
|
2924 { |
|
2925 const TrainCollideChecker* tcc = data; |
|
2926 |
|
2927 if (v != tcc->v && |
|
2928 v != tcc->v_skip && |
|
2929 v->type == VEH_Train && |
|
2930 v->u.rail.track != 0x80 && |
|
2931 myabs(v->z_pos - tcc->v->z_pos) <= 6 && |
|
2932 myabs(v->x_pos - tcc->v->x_pos) < 6 && |
|
2933 myabs(v->y_pos - tcc->v->y_pos) < 6) { |
|
2934 return v; |
|
2935 } else { |
|
2936 return NULL; |
|
2937 } |
|
2938 } |
|
2939 |
|
2940 static void SetVehicleCrashed(Vehicle *v) |
2918 static void SetVehicleCrashed(Vehicle *v) |
2941 { |
2919 { |
2942 Vehicle *u; |
2920 Vehicle *u; |
2943 |
2921 |
2944 if (v->u.rail.crash_anim_pos != 0) return; |
2922 if (v->u.rail.crash_anim_pos != 0) return; |
2958 uint num = 0; |
2936 uint num = 0; |
2959 BEGIN_ENUM_WAGONS(v) |
2937 BEGIN_ENUM_WAGONS(v) |
2960 if (v->cargo_type == CT_PASSENGERS) num += v->cargo_count; |
2938 if (v->cargo_type == CT_PASSENGERS) num += v->cargo_count; |
2961 END_ENUM_WAGONS(v) |
2939 END_ENUM_WAGONS(v) |
2962 return num; |
2940 return num; |
|
2941 } |
|
2942 |
|
2943 typedef struct TrainCollideChecker { |
|
2944 Vehicle *v; |
|
2945 const Vehicle *v_skip; |
|
2946 uint num; |
|
2947 } TrainCollideChecker; |
|
2948 |
|
2949 static void *FindTrainCollideEnum(Vehicle *v, void *data) |
|
2950 { |
|
2951 TrainCollideChecker* tcc = (TrainCollideChecker*)data; |
|
2952 |
|
2953 if (v != tcc->v && |
|
2954 v != tcc->v_skip && |
|
2955 v->type == VEH_Train && |
|
2956 v->u.rail.track != 0x80 && |
|
2957 myabs(v->z_pos - tcc->v->z_pos) < 6 && |
|
2958 myabs(v->x_pos - tcc->v->x_pos) < 6 && |
|
2959 myabs(v->y_pos - tcc->v->y_pos) < 6 ) { |
|
2960 |
|
2961 Vehicle *coll = GetFirstVehicleInChain(v); |
|
2962 |
|
2963 /* it can't collide with its own wagons */ |
|
2964 if (tcc->v == coll || |
|
2965 (tcc->v->u.rail.track == 0x40 && (tcc->v->direction & 2) != (v->direction & 2))) |
|
2966 return NULL; |
|
2967 |
|
2968 /* two drivers + passengers killed in train tcc->v (if it was not crashed already) */ |
|
2969 if (!(tcc->v->vehstatus & VS_CRASHED)) { |
|
2970 tcc->num += 2 + CountPassengersInTrain(tcc->v); |
|
2971 SetVehicleCrashed(tcc->v); |
|
2972 } |
|
2973 |
|
2974 if (!(coll->vehstatus & VS_CRASHED)) { |
|
2975 /* two drivers + passengers killed in train coll (if it was not crashed already) */ |
|
2976 tcc->num += 2 + CountPassengersInTrain(coll); |
|
2977 SetVehicleCrashed(coll); |
|
2978 } |
|
2979 } |
|
2980 |
|
2981 return NULL; |
2963 } |
2982 } |
2964 |
2983 |
2965 /* |
2984 /* |
2966 * Checks whether the specified train has a collision with another vehicle. If |
2985 * Checks whether the specified train has a collision with another vehicle. If |
2967 * so, destroys this vehicle, and the other vehicle if its subtype has TS_Front. |
2986 * so, destroys this vehicle, and the other vehicle if its subtype has TS_Front. |
2969 * plays a sound. |
2988 * plays a sound. |
2970 */ |
2989 */ |
2971 static void CheckTrainCollision(Vehicle *v) |
2990 static void CheckTrainCollision(Vehicle *v) |
2972 { |
2991 { |
2973 TrainCollideChecker tcc; |
2992 TrainCollideChecker tcc; |
2974 Vehicle *coll; |
|
2975 Vehicle *realcoll; |
|
2976 uint num; |
|
2977 |
2993 |
2978 /* can't collide in depot */ |
2994 /* can't collide in depot */ |
2979 if (v->u.rail.track == 0x80) return; |
2995 if (v->u.rail.track == 0x80) return; |
2980 |
2996 |
2981 assert(v->u.rail.track == 0x40 || TileVirtXY(v->x_pos, v->y_pos) == v->tile); |
2997 assert(v->u.rail.track == 0x40 || TileVirtXY(v->x_pos, v->y_pos) == v->tile); |
2982 |
2998 |
2983 tcc.v = v; |
2999 tcc.v = v; |
2984 tcc.v_skip = v->next; |
3000 tcc.v_skip = v->next; |
2985 |
3001 tcc.num = 0; |
2986 /* find colliding vehicle */ |
3002 |
2987 realcoll = VehicleFromPos(TileVirtXY(v->x_pos, v->y_pos), &tcc, FindTrainCollideEnum); |
3003 /* find colliding vehicles */ |
2988 if (realcoll == NULL) return; |
3004 VehicleFromPos(v->tile, &tcc, FindTrainCollideEnum); |
2989 |
3005 |
2990 coll = GetFirstVehicleInChain(realcoll); |
3006 /* any dead -> no crash */ |
2991 |
3007 if (tcc.num == 0) return; |
2992 /* it can't collide with its own wagons */ |
3008 |
2993 if (v == coll || |
3009 SetDParam(0, tcc.num); |
2994 (v->u.rail.track & 0x40 && (v->direction & 2) != (realcoll->direction & 2))) |
|
2995 return; |
|
2996 |
|
2997 //two drivers + passangers killed in train v |
|
2998 num = 2 + CountPassengersInTrain(v); |
|
2999 if (!(coll->vehstatus & VS_CRASHED)) |
|
3000 //two drivers + passangers killed in train coll (if it was not crashed already) |
|
3001 num += 2 + CountPassengersInTrain(coll); |
|
3002 |
|
3003 SetVehicleCrashed(v); |
|
3004 if (IsFrontEngine(coll)) SetVehicleCrashed(coll); |
|
3005 |
|
3006 SetDParam(0, num); |
|
3007 AddNewsItem(STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL, |
3010 AddNewsItem(STR_8868_TRAIN_CRASH_DIE_IN_FIREBALL, |
3008 NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_VEHICLE, NT_ACCIDENT, 0), |
3011 NEWS_FLAGS(NM_THIN, NF_VIEWPORT | NF_VEHICLE, NT_ACCIDENT, 0), |
3009 v->index, |
3012 v->index, |
3010 0 |
3013 0 |
3011 ); |
3014 ); |