mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r14869) -Feature: Allow road vehicles to move multiple steps in a tick (code based on train movement code) and add support for RV prop 15. This gives RVs a maximum speed of 318mph instead 79mph. This only implements higher speeds, not 'realistic acceleration'.
This commit is contained in:
parent
680175fea0
commit
c0efc759ef
|
@ -96,7 +96,7 @@ struct RoadVehicleInfo {
|
||||||
byte running_cost;
|
byte running_cost;
|
||||||
byte running_cost_class;
|
byte running_cost_class;
|
||||||
SoundFxByte sfx;
|
SoundFxByte sfx;
|
||||||
byte max_speed;
|
uint16 max_speed; ///< Maximum speed in mph/3.2 units
|
||||||
byte capacity;
|
byte capacity;
|
||||||
CargoID cargo_type;
|
CargoID cargo_type;
|
||||||
};
|
};
|
||||||
|
|
|
@ -104,6 +104,7 @@ enum {
|
||||||
struct GRFTempEngineData {
|
struct GRFTempEngineData {
|
||||||
uint16 cargo_allowed;
|
uint16 cargo_allowed;
|
||||||
uint16 cargo_disallowed;
|
uint16 cargo_disallowed;
|
||||||
|
uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
|
||||||
};
|
};
|
||||||
|
|
||||||
static GRFTempEngineData *_gted;
|
static GRFTempEngineData *_gted;
|
||||||
|
@ -790,7 +791,6 @@ static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop
|
||||||
|
|
||||||
case 0x13: // Power in 10hp
|
case 0x13: // Power in 10hp
|
||||||
case 0x14: // Weight in 1/4 tons
|
case 0x14: // Weight in 1/4 tons
|
||||||
case 0x15: // Speed in mph*0.8
|
|
||||||
/** @todo Support for road vehicles realistic power
|
/** @todo Support for road vehicles realistic power
|
||||||
* computations (called rvpower in TTDPatch) is just
|
* computations (called rvpower in TTDPatch) is just
|
||||||
* missing in OTTD yet. --pasky */
|
* missing in OTTD yet. --pasky */
|
||||||
|
@ -798,6 +798,10 @@ static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop
|
||||||
ret = CIR_UNHANDLED;
|
ret = CIR_UNHANDLED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x15: // Speed in mph/0.8
|
||||||
|
_gted[e->index].rv_max_speed = grf_load_byte(&buf);
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x16: // Cargos available for refitting
|
case 0x16: // Cargos available for refitting
|
||||||
ei->refit_mask = grf_load_dword(&buf);
|
ei->refit_mask = grf_load_dword(&buf);
|
||||||
break;
|
break;
|
||||||
|
@ -6027,6 +6031,14 @@ static void AfterLoadGRFs()
|
||||||
/* Load old shore sprites in new position, if they were replaced by ActionA */
|
/* Load old shore sprites in new position, if they were replaced by ActionA */
|
||||||
ActivateOldShore();
|
ActivateOldShore();
|
||||||
|
|
||||||
|
Engine *e;
|
||||||
|
FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
|
||||||
|
if (_gted[e->index].rv_max_speed != 0) {
|
||||||
|
/* Set RV maximum speed from the mph/0.8 unit value */
|
||||||
|
e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Deallocate temporary loading data */
|
/* Deallocate temporary loading data */
|
||||||
free(_gted);
|
free(_gted);
|
||||||
_grm_sprites.clear();
|
_grm_sprites.clear();
|
||||||
|
|
|
@ -625,7 +625,7 @@ static void RoadVehCrash(Vehicle *v)
|
||||||
SndPlayVehicleFx(SND_12_EXPLOSION, v);
|
SndPlayVehicleFx(SND_12_EXPLOSION, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RoadVehCheckTrainCrash(Vehicle *v)
|
static bool RoadVehCheckTrainCrash(Vehicle *v)
|
||||||
{
|
{
|
||||||
for (Vehicle *u = v; u != NULL; u = u->Next()) {
|
for (Vehicle *u = v; u != NULL; u = u->Next()) {
|
||||||
if (u->u.road.state == RVSB_WORMHOLE) continue;
|
if (u->u.road.state == RVSB_WORMHOLE) continue;
|
||||||
|
@ -636,9 +636,11 @@ static void RoadVehCheckTrainCrash(Vehicle *v)
|
||||||
|
|
||||||
if (HasVehicleOnPosXY(v->x_pos, v->y_pos, u, EnumCheckRoadVehCrashTrain)) {
|
if (HasVehicleOnPosXY(v->x_pos, v->y_pos, u, EnumCheckRoadVehCrashTrain)) {
|
||||||
RoadVehCrash(v);
|
RoadVehCrash(v);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleBrokenRoadVeh(Vehicle *v)
|
static void HandleBrokenRoadVeh(Vehicle *v)
|
||||||
|
@ -812,35 +814,39 @@ static void RoadVehArrivesAt(const Vehicle* v, Station* st)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool RoadVehAccelerate(Vehicle *v)
|
static int RoadVehAccelerate(Vehicle *v)
|
||||||
{
|
{
|
||||||
uint spd = v->cur_speed + 1 + (v->u.road.overtaking != 0 ? 1 : 0);
|
uint oldspeed = v->cur_speed;
|
||||||
byte t;
|
uint accel = 256 + (v->u.road.overtaking != 0 ? 256 : 0);
|
||||||
|
uint spd = v->subspeed + accel;
|
||||||
|
|
||||||
/* Clamp */
|
v->subspeed = (uint8)spd;
|
||||||
spd = min(spd, v->max_speed);
|
|
||||||
if (v->u.road.state == RVSB_WORMHOLE && !(v->vehstatus & VS_HIDDEN)) {
|
int tempmax = v->max_speed;
|
||||||
spd = min(spd, GetBridgeSpec(GetBridgeType(v->tile))->speed * 2);
|
if (v->cur_speed > v->max_speed) {
|
||||||
|
tempmax = v->cur_speed - (v->cur_speed / 10) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* updates statusbar only if speed have changed to save CPU time */
|
v->cur_speed = spd = Clamp(v->cur_speed + ((int)spd >> 8), 0, tempmax);
|
||||||
if (spd != v->cur_speed) {
|
|
||||||
v->cur_speed = spd;
|
/* Apply bridge speed limit */
|
||||||
|
if (v->u.road.state == RVSB_WORMHOLE && !(v->vehstatus & VS_HIDDEN)) {
|
||||||
|
v->cur_speed = min(v->cur_speed, GetBridgeSpec(GetBridgeType(v->tile))->speed * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update statusbar only if speed has changed to save CPU time */
|
||||||
|
if (oldspeed != v->cur_speed) {
|
||||||
if (_settings_client.gui.vehicle_speed) {
|
if (_settings_client.gui.vehicle_speed) {
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decrease somewhat when turning */
|
/* Speed is scaled in the same manner as for trains. @see train_cmd.cpp */
|
||||||
if (!(v->direction & 1)) spd = spd * 3 >> 2;
|
int scaled_spd = spd * 3 >> 2;
|
||||||
|
|
||||||
if (spd == 0) return false;
|
scaled_spd += v->progress;
|
||||||
|
v->progress = 0;
|
||||||
if ((byte)++spd == 0) return true;
|
return scaled_spd;
|
||||||
|
|
||||||
v->progress = (t = v->progress) - (byte)spd;
|
|
||||||
|
|
||||||
return (t < v->progress);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Direction RoadVehGetNewDirection(const Vehicle* v, int x, int y)
|
static Direction RoadVehGetNewDirection(const Vehicle* v, int x, int y)
|
||||||
|
@ -1831,12 +1837,26 @@ static void RoadVehController(Vehicle *v)
|
||||||
|
|
||||||
if (v->IsInDepot() && RoadVehLeaveDepot(v, true)) return;
|
if (v->IsInDepot() && RoadVehLeaveDepot(v, true)) return;
|
||||||
|
|
||||||
/* Check if vehicle needs to proceed, return if it doesn't */
|
/* Check how far the vehicle needs to proceed */
|
||||||
if (!RoadVehAccelerate(v)) return;
|
int j = RoadVehAccelerate(v);
|
||||||
|
|
||||||
for (Vehicle *prev = NULL; v != NULL; prev = v, v = v->Next()) {
|
int adv_spd = (v->direction & 1) ? 192 : 256;
|
||||||
if (!IndividualRoadVehicleController(v, prev)) break;
|
while (j >= adv_spd) {
|
||||||
|
j -= adv_spd;
|
||||||
|
|
||||||
|
Vehicle *u = v;
|
||||||
|
for (Vehicle *prev = NULL; u != NULL; prev = u, u = u->Next()) {
|
||||||
|
if (!IndividualRoadVehicleController(u, prev)) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 192 spd used for going straight, 256 for going diagonally. */
|
||||||
|
adv_spd = (v->direction & 1) ? 192 : 256;
|
||||||
|
|
||||||
|
/* Test for a collision, but only if another movement will occur. */
|
||||||
|
if (j >= adv_spd && RoadVehCheckTrainCrash(v)) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (v->progress == 0) v->progress = j;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AgeRoadVehCargo(Vehicle *v)
|
static void AgeRoadVehCargo(Vehicle *v)
|
||||||
|
|
Loading…
Reference in New Issue