23 #include "sound.h" |
23 #include "sound.h" |
24 #include "depot.h" |
24 #include "depot.h" |
25 #include "waypoint.h" |
25 #include "waypoint.h" |
26 #include "vehicle_gui.h" |
26 #include "vehicle_gui.h" |
27 #include "train.h" |
27 #include "train.h" |
28 #include "bridge.h" |
|
29 #include "newgrf_callbacks.h" |
28 #include "newgrf_callbacks.h" |
30 #include "newgrf_engine.h" |
29 #include "newgrf_engine.h" |
31 #include "newgrf_text.h" |
30 #include "newgrf_text.h" |
32 #include "direction.h" |
31 #include "direction.h" |
33 #include "yapf/yapf.h" |
32 #include "yapf/yapf.h" |
90 bool wagon_has_power = true; |
89 bool wagon_has_power = true; |
91 |
90 |
92 /* Power is not added for articulated parts */ |
91 /* Power is not added for articulated parts */ |
93 if (IsArticulatedPart(u)) continue; |
92 if (IsArticulatedPart(u)) continue; |
94 |
93 |
95 if (IsLevelCrossingTile(u->tile)) { |
94 if (IsBridgeTile(u->tile) && IsBridgeMiddle(u->tile) && DiagDirToAxis(DirToDiagDir(u->direction)) == GetBridgeAxis(u->tile)) { |
|
95 if (!HasPowerOnRail(u->u.rail.railtype, GetRailTypeOnBridge(u->tile))) engine_has_power = false; |
|
96 if (!HasPowerOnRail(v->u.rail.railtype, GetRailTypeOnBridge(u->tile))) wagon_has_power = false; |
|
97 } else if (IsLevelCrossingTile(u->tile)) { |
96 if (!HasPowerOnRail(u->u.rail.railtype, GetRailTypeCrossing(u->tile))) engine_has_power = false; |
98 if (!HasPowerOnRail(u->u.rail.railtype, GetRailTypeCrossing(u->tile))) engine_has_power = false; |
97 if (!HasPowerOnRail(v->u.rail.railtype, GetRailTypeCrossing(u->tile))) wagon_has_power = false; |
99 if (!HasPowerOnRail(v->u.rail.railtype, GetRailTypeCrossing(u->tile))) wagon_has_power = false; |
98 } else { |
100 } else { |
99 if (!HasPowerOnRail(u->u.rail.railtype, GetRailType(u->tile))) engine_has_power = false; |
101 if (!HasPowerOnRail(u->u.rail.railtype, GetRailType(u->tile))) engine_has_power = false; |
100 if (!HasPowerOnRail(v->u.rail.railtype, GetRailType(u->tile))) wagon_has_power = false; |
102 if (!HasPowerOnRail(v->u.rail.railtype, GetRailType(u->tile))) wagon_has_power = false; |
1523 |
1525 |
1524 /* update other vars */ |
1526 /* update other vars */ |
1525 UpdateVarsAfterSwap(a); |
1527 UpdateVarsAfterSwap(a); |
1526 UpdateVarsAfterSwap(b); |
1528 UpdateVarsAfterSwap(b); |
1527 |
1529 |
1528 /* call the proper EnterTile function unless we are in a wormhole */ |
1530 VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos); |
1529 if (!(a->u.rail.track & 0x40)) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos); |
1531 VehicleEnterTile(b, b->tile, b->x_pos, b->y_pos); |
1530 if (!(b->u.rail.track & 0x40)) VehicleEnterTile(b, b->tile, b->x_pos, b->y_pos); |
|
1531 } else { |
1532 } else { |
1532 if (!(a->u.rail.track & 0x80)) a->direction = ReverseDir(a->direction); |
1533 if (!(a->u.rail.track & 0x80)) a->direction = ReverseDir(a->direction); |
1533 UpdateVarsAfterSwap(a); |
1534 UpdateVarsAfterSwap(a); |
1534 |
1535 |
1535 if (!(a->u.rail.track & 0x40)) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos); |
1536 VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos); |
1536 } |
1537 } |
1537 |
1538 |
1538 /* Update train's power incase tiles were different rail type */ |
1539 /* Update train's power incase tiles were different rail type */ |
1539 TrainPowerChanged(v); |
1540 TrainPowerChanged(v); |
1540 } |
1541 } |
1848 tfdd.tile = tile; |
1849 tfdd.tile = tile; |
1849 tfdd.best_length = 0; |
1850 tfdd.best_length = 0; |
1850 return tfdd; |
1851 return tfdd; |
1851 } |
1852 } |
1852 |
1853 |
|
1854 if (v->u.rail.track == 0x40) tile = GetVehicleOutOfTunnelTile(v); |
|
1855 |
1853 if (_patches.yapf.rail_use_yapf) { |
1856 if (_patches.yapf.rail_use_yapf) { |
1854 bool found = YapfFindNearestRailDepotTwoWay(v, max_distance, NPF_INFINITE_PENALTY, &tfdd.tile, &tfdd.reverse); |
1857 bool found = YapfFindNearestRailDepotTwoWay(v, max_distance, NPF_INFINITE_PENALTY, &tfdd.tile, &tfdd.reverse); |
1855 tfdd.best_length = found ? max_distance / 2 : -1; // some fake distance or NOT_FOUND |
1858 tfdd.best_length = found ? max_distance / 2 : -1; // some fake distance or NOT_FOUND |
1856 } else if (_patches.new_pathfinding_all) { |
1859 } else if (_patches.new_pathfinding_all) { |
1857 NPFFoundTargetData ftd; |
1860 NPFFoundTargetData ftd; |
2639 { |
2644 { |
2640 switch (GetTileType(tile)) { |
2645 switch (GetTileType(tile)) { |
2641 case MP_RAILWAY: |
2646 case MP_RAILWAY: |
2642 case MP_STATION: |
2647 case MP_STATION: |
2643 // normal tracks, jump to owner check |
2648 // normal tracks, jump to owner check |
|
2649 break; |
|
2650 |
|
2651 case MP_TUNNELBRIDGE: |
|
2652 if (IsBridge(tile) && IsBridgeMiddle(tile)) { |
|
2653 // is train going over the bridge? |
|
2654 if (v->z_pos > GetTileMaxZ(tile)) return true; |
|
2655 } |
2644 break; |
2656 break; |
2645 |
2657 |
2646 case MP_STREET: |
2658 case MP_STREET: |
2647 // tracks over roads, do owner check of tracks |
2659 // tracks over roads, do owner check of tracks |
2648 return |
2660 return |
2981 if (prev == NULL) AffectSpeedByDirChange(v, chosen_dir); |
2993 if (prev == NULL) AffectSpeedByDirChange(v, chosen_dir); |
2982 |
2994 |
2983 v->direction = chosen_dir; |
2995 v->direction = chosen_dir; |
2984 } |
2996 } |
2985 } else { |
2997 } else { |
2986 /* in tunnel on on a bridge */ |
2998 /* in tunnel */ |
2987 GetNewVehiclePos(v, &gp); |
2999 GetNewVehiclePos(v, &gp); |
2988 |
3000 |
2989 SetSpeedLimitOnBridge(v); |
3001 // Check if to exit the tunnel... |
2990 |
3002 if (!IsTunnelTile(gp.new_tile) || |
2991 if (!(IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) || !(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y) & 0x4)) { |
3003 !(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y)&0x4) ) { |
2992 v->x_pos = gp.x; |
3004 v->x_pos = gp.x; |
2993 v->y_pos = gp.y; |
3005 v->y_pos = gp.y; |
2994 VehiclePositionChanged(v); |
3006 VehiclePositionChanged(v); |
2995 if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v); |
|
2996 continue; |
3007 continue; |
2997 } |
3008 } |
2998 } |
3009 } |
2999 |
3010 |
3000 /* update image of train, as well as delta XY */ |
3011 /* update image of train, as well as delta XY */ |
3087 |
3098 |
3088 /* Check if the wagon was on a road/rail-crossing and disable it if no |
3099 /* Check if the wagon was on a road/rail-crossing and disable it if no |
3089 * others are on it */ |
3100 * others are on it */ |
3090 DisableTrainCrossing(v->tile); |
3101 DisableTrainCrossing(v->tile); |
3091 |
3102 |
3092 if ( (v->u.rail.track == 0x40 && v->vehstatus & VS_HIDDEN) ) { // inside a tunnel |
3103 if (v->u.rail.track == 0x40) { // inside a tunnel |
3093 TileIndex endtile = CheckTunnelBusy(v->tile, NULL); |
3104 TileIndex endtile = CheckTunnelBusy(v->tile, NULL); |
3094 |
3105 |
3095 if (endtile == INVALID_TILE) return; // tunnel is busy (error returned) |
3106 if (endtile == INVALID_TILE) return; // tunnel is busy (error returned) |
3096 |
3107 |
3097 switch (v->direction) { |
3108 switch (v->direction) { |
3118 static const DirDiff delta[] = { |
3129 static const DirDiff delta[] = { |
3119 DIRDIFF_45LEFT, DIRDIFF_SAME, DIRDIFF_SAME, DIRDIFF_45RIGHT |
3130 DIRDIFF_45LEFT, DIRDIFF_SAME, DIRDIFF_SAME, DIRDIFF_45RIGHT |
3120 }; |
3131 }; |
3121 |
3132 |
3122 do { |
3133 do { |
3123 /* We don't need to twist around vehicles if they're not visible */ |
3134 //I need to buffer the train direction |
|
3135 if (!(v->u.rail.track & 0x40)) { |
|
3136 v->direction = ChangeDir(v->direction, delta[GB(Random(), 0, 2)]); |
|
3137 } |
3124 if (!(v->vehstatus & VS_HIDDEN)) { |
3138 if (!(v->vehstatus & VS_HIDDEN)) { |
3125 v->direction = ChangeDir(v->direction, delta[GB(Random(), 0, 2)]); |
|
3126 BeginVehicleMove(v); |
3139 BeginVehicleMove(v); |
3127 UpdateTrainDeltaXY(v, v->direction); |
3140 UpdateTrainDeltaXY(v, v->direction); |
3128 v->cur_image = GetTrainImage(v, v->direction); |
3141 v->cur_image = GetTrainImage(v, v->direction); |
3129 /* Refrain from updating the z position of the vehicle when on |
3142 AfterSetTrainPos(v, false); |
3130 a bridge, because AfterSetTrainPos will put the vehicle under |
|
3131 the bridge in that case */ |
|
3132 if (!(v->u.rail.track & 0x40)) AfterSetTrainPos(v, false); |
|
3133 } |
3143 } |
3134 } while ((v = v->next) != NULL); |
3144 } while ((v = v->next) != NULL); |
3135 } |
3145 } |
3136 |
3146 |
3137 static void HandleCrashedTrain(Vehicle *v) |
3147 static void HandleCrashedTrain(Vehicle *v) |
3138 { |
3148 { |
3139 int state = ++v->u.rail.crash_anim_pos; |
3149 int state = ++v->u.rail.crash_anim_pos; |
3140 uint32 r; |
3150 uint32 r; |
3141 Vehicle *u; |
3151 Vehicle *u; |
3142 |
3152 |
3143 if (state == 4 && !(v->u.rail.track & VS_HIDDEN)) { |
3153 if (state == 4 && v->u.rail.track != 0x40) { |
3144 CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE); |
3154 CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE); |
3145 } |
3155 } |
3146 |
3156 |
3147 if (state <= 200 && CHANCE16R(1, 7, r)) { |
3157 if (state <= 200 && CHANCE16R(1, 7, r)) { |
3148 int index = (r * 10 >> 16); |
3158 int index = (r * 10 >> 16); |
3225 if (v->u.rail.track & 0x40) return true; // exit if inside a tunnel |
3235 if (v->u.rail.track & 0x40) return true; // exit if inside a tunnel |
3226 if (v->u.rail.track & 0x80) return true; // exit if inside a depot |
3236 if (v->u.rail.track & 0x80) return true; // exit if inside a depot |
3227 |
3237 |
3228 tile = v->tile; |
3238 tile = v->tile; |
3229 |
3239 |
3230 if (IsTileType(tile, MP_TUNNELBRIDGE)) { |
3240 // tunnel entrance? |
3231 DiagDirection dir; |
3241 if (IsTunnelTile(tile) && |
3232 |
3242 DiagDirToDir(GetTunnelDirection(tile)) == v->direction) { |
3233 if (IsTunnel(tile)) { |
3243 return true; |
3234 dir = GetTunnelDirection(tile); |
|
3235 } else { |
|
3236 dir = GetBridgeRampDirection(tile); |
|
3237 } |
|
3238 if (DiagDirToDir(dir) == v->direction) return true; |
|
3239 } |
3244 } |
3240 |
3245 |
3241 // depot? |
3246 // depot? |
3242 /* XXX -- When enabled, this makes it possible to crash trains of others |
3247 /* XXX -- When enabled, this makes it possible to crash trains of others |
3243 (by building a depot right against a station) */ |
3248 (by building a depot right against a station) */ |