mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r955) Replace uint16 for orders with struct Order
This adds no functionality, but is a stepping stone for future improvement (like 16bit order indices) and is easier to read. This changes preserves binary compatibility wrt savegames.
This commit is contained in:
parent
1de8e294d8
commit
7c2448ecea
33
ai.c
33
ai.c
|
@ -248,7 +248,7 @@ static int AiChooseShipToReplaceWith(Player *p, Vehicle *v)
|
||||||
|
|
||||||
static void AiHandleGotoDepot(Player *p, int cmd)
|
static void AiHandleGotoDepot(Player *p, int cmd)
|
||||||
{
|
{
|
||||||
if ((p->ai.cur_veh->next_order & OT_MASK) != OT_GOTO_DEPOT)
|
if (p->ai.cur_veh->current_order.type != OT_GOTO_DEPOT)
|
||||||
DoCommandByTile(0, p->ai.cur_veh->index, 0, DC_EXEC, cmd);
|
DoCommandByTile(0, p->ai.cur_veh->index, 0, DC_EXEC, cmd);
|
||||||
|
|
||||||
if (++p->ai.state_counter <= 1387) {
|
if (++p->ai.state_counter <= 1387) {
|
||||||
|
@ -256,18 +256,20 @@ static void AiHandleGotoDepot(Player *p, int cmd)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((p->ai.cur_veh->next_order&OT_MASK) == OT_GOTO_DEPOT) {
|
if (p->ai.cur_veh->current_order.type == OT_GOTO_DEPOT) {
|
||||||
p->ai.cur_veh->next_order = OT_DUMMY;
|
p->ai.cur_veh->current_order.type = OT_DUMMY;
|
||||||
|
p->ai.cur_veh->current_order.flags = 0;
|
||||||
InvalidateWindow(WC_VEHICLE_VIEW, p->ai.cur_veh->index);
|
InvalidateWindow(WC_VEHICLE_VIEW, p->ai.cur_veh->index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AiRestoreVehicleOrders(Vehicle *v, BackuppedOrders *bak)
|
static void AiRestoreVehicleOrders(Vehicle *v, BackuppedOrders *bak)
|
||||||
{
|
{
|
||||||
uint16 *os = bak->order, ord;
|
const Order *os = bak->order;
|
||||||
int ind = 0;
|
int ind = 0;
|
||||||
while ((ord = *os++) != 0) {
|
|
||||||
if (DoCommandByTile(0, v->index + (ind << 16), ord, DC_EXEC, CMD_INSERT_ORDER) == CMD_ERROR)
|
while (os++->type != OT_NOTHING) {
|
||||||
|
if (DoCommandByTile(0, v->index + (ind << 16), PackOrder(os), DC_EXEC, CMD_INSERT_ORDER) == CMD_ERROR)
|
||||||
break;
|
break;
|
||||||
ind++;
|
ind++;
|
||||||
}
|
}
|
||||||
|
@ -3519,7 +3521,7 @@ static void AiStateSellVeh(Player *p)
|
||||||
if (v->type == VEH_Train) {
|
if (v->type == VEH_Train) {
|
||||||
|
|
||||||
if (!IsTrainDepotTile(v->tile) || v->u.rail.track != 0x80 || !(v->vehstatus&VS_STOPPED)) {
|
if (!IsTrainDepotTile(v->tile) || v->u.rail.track != 0x80 || !(v->vehstatus&VS_STOPPED)) {
|
||||||
if ((v->next_order & OT_MASK) != OT_GOTO_DEPOT)
|
if (v->current_order.type != OT_GOTO_DEPOT)
|
||||||
DoCommandByTile(0, v->index, 0, DC_EXEC, CMD_TRAIN_GOTO_DEPOT);
|
DoCommandByTile(0, v->index, 0, DC_EXEC, CMD_TRAIN_GOTO_DEPOT);
|
||||||
goto going_to_depot;
|
goto going_to_depot;
|
||||||
}
|
}
|
||||||
|
@ -3529,7 +3531,7 @@ static void AiStateSellVeh(Player *p)
|
||||||
|
|
||||||
} else if (v->type == VEH_Road) {
|
} else if (v->type == VEH_Road) {
|
||||||
if (!IsRoadDepotTile(v->tile) || v->u.road.state != 254 || !(v->vehstatus&VS_STOPPED)) {
|
if (!IsRoadDepotTile(v->tile) || v->u.road.state != 254 || !(v->vehstatus&VS_STOPPED)) {
|
||||||
if ((v->next_order & OT_MASK) != OT_GOTO_DEPOT)
|
if (v->current_order.type != OT_GOTO_DEPOT)
|
||||||
DoCommandByTile(0, v->index, 0, DC_EXEC, CMD_SEND_ROADVEH_TO_DEPOT);
|
DoCommandByTile(0, v->index, 0, DC_EXEC, CMD_SEND_ROADVEH_TO_DEPOT);
|
||||||
goto going_to_depot;
|
goto going_to_depot;
|
||||||
}
|
}
|
||||||
|
@ -3537,7 +3539,7 @@ static void AiStateSellVeh(Player *p)
|
||||||
DoCommandByTile(0, v->index, 0, DC_EXEC, CMD_SELL_ROAD_VEH);
|
DoCommandByTile(0, v->index, 0, DC_EXEC, CMD_SELL_ROAD_VEH);
|
||||||
} else if (v->type == VEH_Aircraft) {
|
} else if (v->type == VEH_Aircraft) {
|
||||||
if (!IsAircraftHangarTile(v->tile) && !(v->vehstatus&VS_STOPPED)) {
|
if (!IsAircraftHangarTile(v->tile) && !(v->vehstatus&VS_STOPPED)) {
|
||||||
if ((v->next_order & OT_MASK) != OT_GOTO_DEPOT)
|
if (v->current_order.type != OT_GOTO_DEPOT)
|
||||||
DoCommandByTile(0, v->index, 0, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR);
|
DoCommandByTile(0, v->index, 0, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR);
|
||||||
goto going_to_depot;
|
goto going_to_depot;
|
||||||
}
|
}
|
||||||
|
@ -3554,8 +3556,9 @@ going_to_depot:;
|
||||||
if (++p->ai.state_counter <= 832)
|
if (++p->ai.state_counter <= 832)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT) {
|
if (v->current_order.type == OT_GOTO_DEPOT) {
|
||||||
v->next_order = OT_DUMMY;
|
v->current_order.type = OT_DUMMY;
|
||||||
|
v->current_order.flags = 0;
|
||||||
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
||||||
}
|
}
|
||||||
return_to_loop:;
|
return_to_loop:;
|
||||||
|
@ -3566,7 +3569,7 @@ static void AiStateRemoveStation(Player *p)
|
||||||
{
|
{
|
||||||
// Remove stations that aren't in use by any vehicle
|
// Remove stations that aren't in use by any vehicle
|
||||||
byte in_use[256], *used;
|
byte in_use[256], *used;
|
||||||
uint16 *ord;
|
Order *ord;
|
||||||
Station *st;
|
Station *st;
|
||||||
uint tile;
|
uint tile;
|
||||||
|
|
||||||
|
@ -3575,9 +3578,9 @@ static void AiStateRemoveStation(Player *p)
|
||||||
|
|
||||||
// Get a list of all stations that are in use by a vehicle
|
// Get a list of all stations that are in use by a vehicle
|
||||||
memset(in_use, 0, sizeof(in_use));
|
memset(in_use, 0, sizeof(in_use));
|
||||||
for(ord=_order_array; ord != _ptr_to_next_order; ord++) {
|
for (ord = _order_array; ord != _ptr_to_next_order; ++ord) {
|
||||||
if ((*ord & OT_MASK) == OT_GOTO_STATION)
|
if (ord->type == OT_GOTO_STATION)
|
||||||
in_use[*ord >> 8] = 1;
|
in_use[ord->station] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go through all stations and delete those that aren't in use
|
// Go through all stations and delete those that aren't in use
|
||||||
|
|
11
ai_new.c
11
ai_new.c
|
@ -497,21 +497,22 @@ static void AiNew_State_LocateRoute(Player *p) {
|
||||||
static bool AiNew_CheckVehicleStation(Player *p, Station *st) {
|
static bool AiNew_CheckVehicleStation(Player *p, Station *st) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
Vehicle *v;
|
Vehicle *v;
|
||||||
uint16 *sched;
|
|
||||||
uint16 ord;
|
|
||||||
|
|
||||||
// Also check if we don't have already a lot of busses to this city...
|
// Also check if we don't have already a lot of busses to this city...
|
||||||
FOR_ALL_VEHICLES(v) {
|
FOR_ALL_VEHICLES(v) {
|
||||||
if (v->owner == _current_player) {
|
if (v->owner == _current_player) {
|
||||||
sched = v->schedule_ptr;
|
const Order *sched = v->schedule_ptr;
|
||||||
while (sched != NULL && (ord=*sched++) != 0) {
|
if (sched != NULL) {
|
||||||
if ((ord & OT_MASK) == OT_GOTO_STATION && DEREF_STATION(ord >> 8) == st) {
|
for (; sched->type != OT_NOTHING; ++sched) {
|
||||||
|
if (sched->type == OT_GOTO_STATION &&
|
||||||
|
DEREF_STATION(sched->station) == st) {
|
||||||
// This vehicle has this city in his list
|
// This vehicle has this city in his list
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (count > AI_CHECK_MAX_VEHICLE_PER_STATION) return false;
|
if (count > AI_CHECK_MAX_VEHICLE_PER_STATION) return false;
|
||||||
return true;
|
return true;
|
||||||
|
|
138
aircraft_cmd.c
138
aircraft_cmd.c
|
@ -198,7 +198,9 @@ int32 CmdBuildAircraft(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
|
|
||||||
_new_aircraft_id = v->index;
|
_new_aircraft_id = v->index;
|
||||||
|
|
||||||
*(v->schedule_ptr = _ptr_to_next_order++) = 0;
|
_ptr_to_next_order->type = OT_NOTHING;
|
||||||
|
_ptr_to_next_order->flags = 0;
|
||||||
|
v->schedule_ptr = _ptr_to_next_order++;
|
||||||
// the AI doesn't click on a tile to build airplanes, so the below code will
|
// the AI doesn't click on a tile to build airplanes, so the below code will
|
||||||
// never work. Therefore just assume the AI's planes always come from Hangar0
|
// never work. Therefore just assume the AI's planes always come from Hangar0
|
||||||
// On hold for NewAI
|
// On hold for NewAI
|
||||||
|
@ -361,11 +363,11 @@ int32 CmdSendAircraftToHangar(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
if (!CheckOwnership(v->owner))
|
if (!CheckOwnership(v->owner))
|
||||||
return CMD_ERROR;
|
return CMD_ERROR;
|
||||||
|
|
||||||
if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT) {
|
if (v->current_order.type == OT_GOTO_DEPOT) {
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
if (v->next_order&OF_UNLOAD)
|
if (v->current_order.flags & OF_UNLOAD) v->cur_order_index++;
|
||||||
{ v->cur_order_index++; }
|
v->current_order.type = OT_DUMMY;
|
||||||
v->next_order = OT_DUMMY;
|
v->current_order.flags = 0;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -376,8 +378,9 @@ int32 CmdSendAircraftToHangar(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
return CMD_ERROR;
|
return CMD_ERROR;
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
v->next_order = OF_NON_STOP | OF_FULL_LOAD | OT_GOTO_DEPOT;
|
v->current_order.type = OT_GOTO_DEPOT;
|
||||||
v->next_order_param = v->u.air.targetairport;
|
v->current_order.flags = OF_NON_STOP | OF_FULL_LOAD;
|
||||||
|
v->current_order.station = v->u.air.targetairport;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,21 +469,24 @@ static void CheckIfAircraftNeedsService(Vehicle *v)
|
||||||
if (v->vehstatus & VS_STOPPED)
|
if (v->vehstatus & VS_STOPPED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((v->next_order & (OT_MASK | OF_FULL_LOAD)) == (OT_GOTO_DEPOT | OF_FULL_LOAD))
|
if (v->current_order.type == OT_GOTO_DEPOT &&
|
||||||
|
v->current_order.flags & OF_FULL_LOAD)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_patches.gotodepot && ScheduleHasDepotOrders(v->schedule_ptr))
|
if (_patches.gotodepot && ScheduleHasDepotOrders(v->schedule_ptr))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
st = DEREF_STATION(v->next_order_param);
|
st = DEREF_STATION(v->current_order.station);
|
||||||
// only goto depot if the target airport has terminals (eg. it is airport)
|
// only goto depot if the target airport has terminals (eg. it is airport)
|
||||||
if (st->xy != 0 && st->airport_tile != 0 && GetAirport(st->airport_type)->nofterminals != 0) {
|
if (st->xy != 0 && st->airport_tile != 0 && GetAirport(st->airport_type)->nofterminals != 0) {
|
||||||
// printf("targetairport = %d, st->index = %d\n", v->u.air.targetairport, st->index);
|
// printf("targetairport = %d, st->index = %d\n", v->u.air.targetairport, st->index);
|
||||||
// v->u.air.targetairport = st->index;
|
// v->u.air.targetairport = st->index;
|
||||||
v->next_order = OF_NON_STOP | OT_GOTO_DEPOT;
|
v->current_order.type = OT_GOTO_DEPOT;
|
||||||
|
v->current_order.flags = OF_NON_STOP;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
} else if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
|
} else if (v->current_order.type == OT_GOTO_DEPOT) {
|
||||||
v->next_order = OT_DUMMY;
|
v->current_order.type = OT_DUMMY;
|
||||||
|
v->current_order.flags = 0;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -552,7 +558,7 @@ static void HelicopterTickHandler(Vehicle *v)
|
||||||
|
|
||||||
// if true, helicopter rotors do not rotate. This should only be the case if a helicopter is
|
// if true, helicopter rotors do not rotate. This should only be the case if a helicopter is
|
||||||
// loading/unloading at a terminal or stopped
|
// loading/unloading at a terminal or stopped
|
||||||
if ((v->next_order&OT_MASK) == OT_LOADING || (v->vehstatus&VS_STOPPED)) {
|
if (v->current_order.type == OT_LOADING || (v->vehstatus & VS_STOPPED)) {
|
||||||
if (u->cur_speed != 0) {
|
if (u->cur_speed != 0) {
|
||||||
u->cur_speed++;
|
u->cur_speed++;
|
||||||
if (u->cur_speed >= 0x80 && u->cur_image == 0xF40) {
|
if (u->cur_speed >= 0x80 && u->cur_image == 0xF40) {
|
||||||
|
@ -983,15 +989,18 @@ static void HandleAircraftSmoke(Vehicle *v)
|
||||||
|
|
||||||
static void ProcessAircraftOrder(Vehicle *v)
|
static void ProcessAircraftOrder(Vehicle *v)
|
||||||
{
|
{
|
||||||
uint order;
|
Order order;
|
||||||
|
|
||||||
// OT_GOTO_DEPOT, OT_LOADING
|
// OT_GOTO_DEPOT, OT_LOADING
|
||||||
if ((v->next_order & OT_MASK) >= OT_GOTO_DEPOT && (v->next_order & OT_MASK) <= OT_LOADING) {
|
if (v->current_order.type >= OT_GOTO_DEPOT &&
|
||||||
if ((v->next_order & (OT_MASK|OF_UNLOAD)) != (OT_GOTO_DEPOT|OF_UNLOAD))
|
v->current_order.type <= OT_LOADING) {
|
||||||
|
if (v->current_order.type != OT_GOTO_DEPOT ||
|
||||||
|
!(v->current_order.flags & OF_UNLOAD))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((v->next_order & (OT_MASK|OF_UNLOAD|OF_FULL_LOAD)) == (OT_GOTO_DEPOT|OF_UNLOAD|OF_FULL_LOAD) &&
|
if (v->current_order.type == OT_GOTO_DEPOT &&
|
||||||
|
(v->current_order.flags & (OF_UNLOAD | OF_FULL_LOAD)) == (OF_UNLOAD | OF_FULL_LOAD) &&
|
||||||
SERVICE_INTERVAL) {
|
SERVICE_INTERVAL) {
|
||||||
v->cur_order_index++;
|
v->cur_order_index++;
|
||||||
}
|
}
|
||||||
|
@ -1001,21 +1010,23 @@ static void ProcessAircraftOrder(Vehicle *v)
|
||||||
|
|
||||||
order = v->schedule_ptr[v->cur_order_index];
|
order = v->schedule_ptr[v->cur_order_index];
|
||||||
|
|
||||||
if (order == 0) {
|
if (order.type == OT_NOTHING) {
|
||||||
v->next_order = OT_NOTHING;
|
v->current_order.type = OT_NOTHING;
|
||||||
|
v->current_order.flags = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (order == (uint)((v->next_order | (v->next_order_param<<8))))
|
if (order.type == v->current_order.type &&
|
||||||
|
order.flags == v->current_order.flags &&
|
||||||
|
order.station == v->current_order.station)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
v->next_order = (byte)order;
|
v->current_order = order;
|
||||||
v->next_order_param = (byte)(order >> 8);
|
|
||||||
|
|
||||||
// orders are changed in flight, ensure going to the right station
|
// orders are changed in flight, ensure going to the right station
|
||||||
if ((order & OT_MASK) == OT_GOTO_STATION && v->u.air.state == FLYING) {
|
if (order.type == OT_GOTO_STATION && v->u.air.state == FLYING) {
|
||||||
AircraftNextAirportPos_and_Order(v);
|
AircraftNextAirportPos_and_Order(v);
|
||||||
v->u.air.targetairport = order >> 8;
|
v->u.air.targetairport = order.station;
|
||||||
}
|
}
|
||||||
|
|
||||||
InvalidateVehicleOrderWidget(v);
|
InvalidateVehicleOrderWidget(v);
|
||||||
|
@ -1023,11 +1034,11 @@ static void ProcessAircraftOrder(Vehicle *v)
|
||||||
|
|
||||||
static void HandleAircraftLoading(Vehicle *v, int mode)
|
static void HandleAircraftLoading(Vehicle *v, int mode)
|
||||||
{
|
{
|
||||||
if (v->next_order == OT_NOTHING)
|
if (v->current_order.type == OT_NOTHING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (v->next_order != OT_DUMMY) {
|
if (v->current_order.type != OT_DUMMY) {
|
||||||
if ((v->next_order&OT_MASK) != OT_LOADING)
|
if (v->current_order.type != OT_LOADING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (mode != 0)
|
if (mode != 0)
|
||||||
|
@ -1036,16 +1047,17 @@ static void HandleAircraftLoading(Vehicle *v, int mode)
|
||||||
if (--v->load_unload_time_rem)
|
if (--v->load_unload_time_rem)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (v->next_order&OF_FULL_LOAD && CanFillVehicle(v)) {
|
if (v->current_order.flags & OF_FULL_LOAD && CanFillVehicle(v)) {
|
||||||
SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_INC);
|
SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_INC);
|
||||||
LoadUnloadVehicle(v);
|
LoadUnloadVehicle(v);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
byte b = v->next_order;
|
Order b = v->current_order;
|
||||||
v->next_order = OT_NOTHING;
|
v->current_order.type = OT_NOTHING;
|
||||||
if (!(b & OF_NON_STOP))
|
v->current_order.flags = 0;
|
||||||
|
if (!(b.flags & OF_NON_STOP))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1105,9 +1117,9 @@ static void MaybeCrashAirplane(Vehicle *v)
|
||||||
static void AircraftEntersTerminal(Vehicle *v)
|
static void AircraftEntersTerminal(Vehicle *v)
|
||||||
{
|
{
|
||||||
Station *st;
|
Station *st;
|
||||||
byte old_order;
|
Order old_order;
|
||||||
|
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT)
|
if (v->current_order.type == OT_GOTO_DEPOT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
st = DEREF_STATION(v->u.air.targetairport);
|
st = DEREF_STATION(v->u.air.targetairport);
|
||||||
|
@ -1128,12 +1140,14 @@ static void AircraftEntersTerminal(Vehicle *v)
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
old_order = v->next_order;
|
old_order = v->current_order;
|
||||||
v->next_order = OT_LOADING;
|
v->current_order.type = OT_LOADING;
|
||||||
|
v->current_order.flags = 0;
|
||||||
|
|
||||||
if ((old_order & OT_MASK) == OT_GOTO_STATION &&
|
if (old_order.type == OT_GOTO_STATION &&
|
||||||
v->next_order_param == v->last_station_visited) {
|
v->current_order.station == v->last_station_visited) {
|
||||||
v->next_order = OT_LOADING | (old_order & (OF_UNLOAD|OF_FULL_LOAD)) | OF_NON_STOP;
|
v->current_order.flags =
|
||||||
|
(old_order.flags & (OF_FULL_LOAD | OF_UNLOAD)) | OF_NON_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_INC);
|
SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_INC);
|
||||||
|
@ -1143,7 +1157,7 @@ static void AircraftEntersTerminal(Vehicle *v)
|
||||||
|
|
||||||
static void AircraftEnterHangar(Vehicle *v)
|
static void AircraftEnterHangar(Vehicle *v)
|
||||||
{
|
{
|
||||||
byte old_order;
|
Order old_order;
|
||||||
|
|
||||||
ServiceAircraft(v);
|
ServiceAircraft(v);
|
||||||
|
|
||||||
|
@ -1151,15 +1165,16 @@ static void AircraftEnterHangar(Vehicle *v)
|
||||||
|
|
||||||
TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
|
TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
|
||||||
|
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
|
if (v->current_order.type == OT_GOTO_DEPOT) {
|
||||||
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
||||||
|
|
||||||
old_order = v->next_order;
|
old_order = v->current_order;
|
||||||
v->next_order = OT_NOTHING;
|
v->current_order.type = OT_NOTHING;
|
||||||
|
v->current_order.flags = 0;
|
||||||
|
|
||||||
if (old_order & OF_UNLOAD) { v->cur_order_index++; }
|
if (old_order.flags & OF_UNLOAD) {
|
||||||
|
v->cur_order_index++;
|
||||||
else if (old_order & OF_FULL_LOAD) { // force depot visit
|
} else if (old_order.flags & OF_FULL_LOAD) { // force depot visit
|
||||||
v->vehstatus |= VS_STOPPED;
|
v->vehstatus |= VS_STOPPED;
|
||||||
|
|
||||||
if (v->owner == _local_player) {
|
if (v->owner == _local_player) {
|
||||||
|
@ -1192,9 +1207,9 @@ static void AircraftNextAirportPos_and_Order(Vehicle *v)
|
||||||
Station *st;
|
Station *st;
|
||||||
const AirportFTAClass *Airport;
|
const AirportFTAClass *Airport;
|
||||||
|
|
||||||
if ((v->next_order&OT_MASK) == OT_GOTO_STATION ||
|
if (v->current_order.type == OT_GOTO_STATION ||
|
||||||
(v->next_order&OT_MASK) == OT_GOTO_DEPOT)
|
v->current_order.type == OT_GOTO_DEPOT)
|
||||||
v->u.air.targetairport = v->next_order_param;
|
v->u.air.targetairport = v->current_order.station;
|
||||||
|
|
||||||
st = DEREF_STATION(v->u.air.targetairport);
|
st = DEREF_STATION(v->u.air.targetairport);
|
||||||
Airport = GetAirport(st->airport_type);
|
Airport = GetAirport(st->airport_type);
|
||||||
|
@ -1248,19 +1263,22 @@ static void AircraftEventHandler_InHangar(Vehicle *v, const AirportFTAClass *Air
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT && (v->vehstatus&VS_STOPPED)) { // if we were sent to the depot, stay there
|
// if we were sent to the depot, stay there
|
||||||
v->next_order = OT_NOTHING;
|
if (v->current_order.type == OT_GOTO_DEPOT && (v->vehstatus & VS_STOPPED)) {
|
||||||
|
v->current_order.type = OT_NOTHING;
|
||||||
|
v->current_order.flags = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((v->next_order&OT_MASK) != OT_GOTO_STATION && (v->next_order&OT_MASK) != OT_GOTO_DEPOT)
|
if (v->current_order.type != OT_GOTO_STATION &&
|
||||||
|
v->current_order.type != OT_GOTO_DEPOT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// if the block of the next position is busy, stay put
|
// if the block of the next position is busy, stay put
|
||||||
if (AirportHasBlock(v, &Airport->layout[v->u.air.pos], Airport)) {return;}
|
if (AirportHasBlock(v, &Airport->layout[v->u.air.pos], Airport)) {return;}
|
||||||
|
|
||||||
// We are already at the target airport, we need to find a terminal
|
// We are already at the target airport, we need to find a terminal
|
||||||
if (v->next_order_param == v->u.air.targetairport) {
|
if (v->current_order.station == v->u.air.targetairport) {
|
||||||
// FindFreeTerminal:
|
// FindFreeTerminal:
|
||||||
// 1. Find a free terminal, 2. Occupy it, 3. Set the vehicle's state to that terminal
|
// 1. Find a free terminal, 2. Occupy it, 3. Set the vehicle's state to that terminal
|
||||||
if (v->subtype != 0) {if(!AirportFindFreeTerminal(v, Airport)) {return;}} // airplane
|
if (v->subtype != 0) {if(!AirportFindFreeTerminal(v, Airport)) {return;}} // airplane
|
||||||
|
@ -1294,8 +1312,7 @@ static void AircraftEventHandler_AtTerminal(Vehicle *v, const AirportFTAClass *A
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// removed &0x1F
|
if (v->current_order.type == OT_NOTHING) return;
|
||||||
if (v->next_order == OT_NOTHING) {return;}
|
|
||||||
|
|
||||||
// if the block of the next position is busy, stay put
|
// if the block of the next position is busy, stay put
|
||||||
if (AirportHasBlock(v, &Airport->layout[v->u.air.pos], Airport)) {
|
if (AirportHasBlock(v, &Airport->layout[v->u.air.pos], Airport)) {
|
||||||
|
@ -1305,19 +1322,20 @@ static void AircraftEventHandler_AtTerminal(Vehicle *v, const AirportFTAClass *A
|
||||||
// airport-road is free. We either have to go to another airport, or to the hangar
|
// airport-road is free. We either have to go to another airport, or to the hangar
|
||||||
// ---> start moving
|
// ---> start moving
|
||||||
|
|
||||||
switch (v->next_order&OT_MASK) {
|
switch (v->current_order.type) {
|
||||||
case OT_GOTO_STATION: // ready to fly to another airport
|
case OT_GOTO_STATION: // ready to fly to another airport
|
||||||
// airplane goto state takeoff, helicopter to helitakeoff
|
// airplane goto state takeoff, helicopter to helitakeoff
|
||||||
v->u.air.state = (v->subtype != 0) ? TAKEOFF : HELITAKEOFF;
|
v->u.air.state = (v->subtype != 0) ? TAKEOFF : HELITAKEOFF;
|
||||||
break;
|
break;
|
||||||
case OT_GOTO_DEPOT: // visit hangar for serivicing, sale, etc.
|
case OT_GOTO_DEPOT: // visit hangar for serivicing, sale, etc.
|
||||||
if (v->next_order_param == v->u.air.targetairport)
|
if (v->current_order.station == v->u.air.targetairport)
|
||||||
v->u.air.state = HANGAR;
|
v->u.air.state = HANGAR;
|
||||||
else
|
else
|
||||||
v->u.air.state = (v->subtype != 0) ? TAKEOFF : HELITAKEOFF;
|
v->u.air.state = (v->subtype != 0) ? TAKEOFF : HELITAKEOFF;
|
||||||
break;
|
break;
|
||||||
default: // orders have been deleted (no orders), goto depot and don't bother us
|
default: // orders have been deleted (no orders), goto depot and don't bother us
|
||||||
v->next_order = OT_NOTHING;
|
v->current_order.type = OT_NOTHING;
|
||||||
|
v->current_order.flags = 0;
|
||||||
v->u.air.state = HANGAR;
|
v->u.air.state = HANGAR;
|
||||||
}
|
}
|
||||||
AirportMove(v, Airport);
|
AirportMove(v, Airport);
|
||||||
|
@ -1423,7 +1441,7 @@ static void AircraftEventHandler_EndLanding(Vehicle *v, const AirportFTAClass *A
|
||||||
// 1. in case all terminals are busy AirportFindFreeTerminal() returns false or
|
// 1. in case all terminals are busy AirportFindFreeTerminal() returns false or
|
||||||
// 2. not going for terminal (but depot, no order),
|
// 2. not going for terminal (but depot, no order),
|
||||||
// --> get out of the way to the hangar.
|
// --> get out of the way to the hangar.
|
||||||
if ((v->next_order&OT_MASK) == OT_GOTO_STATION) {
|
if (v->current_order.type == OT_GOTO_STATION) {
|
||||||
if (AirportFindFreeTerminal(v, Airport)) {return;}
|
if (AirportFindFreeTerminal(v, Airport)) {return;}
|
||||||
}
|
}
|
||||||
v->u.air.state = HANGAR;
|
v->u.air.state = HANGAR;
|
||||||
|
@ -1442,7 +1460,7 @@ static void AircraftEventHandler_HeliEndLanding(Vehicle *v, const AirportFTAClas
|
||||||
// --> else TAKEOFF
|
// --> else TAKEOFF
|
||||||
// the reason behind this is that if an airport has a terminal, it also has a hangar. Airplanes
|
// the reason behind this is that if an airport has a terminal, it also has a hangar. Airplanes
|
||||||
// must go to a hangar.
|
// must go to a hangar.
|
||||||
if ((v->next_order&OT_MASK) == OT_GOTO_STATION) {
|
if (v->current_order.type == OT_GOTO_STATION) {
|
||||||
if (AirportFindFreeHelipad(v, Airport)) {return;}
|
if (AirportFindFreeHelipad(v, Airport)) {return;}
|
||||||
}
|
}
|
||||||
v->u.air.state = (Airport->nofterminals != 0) ? HANGAR : HELITAKEOFF;
|
v->u.air.state = (Airport->nofterminals != 0) ? HANGAR : HELITAKEOFF;
|
||||||
|
@ -1720,7 +1738,7 @@ static void AircraftEventHandler(Vehicle *v, int loop)
|
||||||
ProcessAircraftOrder(v);
|
ProcessAircraftOrder(v);
|
||||||
HandleAircraftLoading(v, loop);
|
HandleAircraftLoading(v, loop);
|
||||||
|
|
||||||
if ((v->next_order&OT_MASK) >= OT_LOADING)
|
if (v->current_order.type >= OT_LOADING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// pass the right airport structure to the functions
|
// pass the right airport structure to the functions
|
||||||
|
|
|
@ -547,15 +547,15 @@ static void AircraftViewWndProc(Window *w, WindowEvent *e)
|
||||||
} else if (v->vehstatus & VS_STOPPED) {
|
} else if (v->vehstatus & VS_STOPPED) {
|
||||||
str = STR_8861_STOPPED;
|
str = STR_8861_STOPPED;
|
||||||
} else {
|
} else {
|
||||||
switch(v->next_order & OT_MASK) {
|
switch (v->current_order.type) {
|
||||||
case OT_GOTO_STATION: {
|
case OT_GOTO_STATION: {
|
||||||
SetDParam(0, v->next_order_param);
|
SetDParam(0, v->current_order.station);
|
||||||
SetDParam(1, v->cur_speed * 8);
|
SetDParam(1, v->cur_speed * 8);
|
||||||
str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
|
str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case OT_GOTO_DEPOT: {
|
case OT_GOTO_DEPOT: {
|
||||||
SetDParam(0, v->next_order_param);
|
SetDParam(0, v->current_order.station);
|
||||||
SetDParam(1, v->cur_speed * 8);
|
SetDParam(1, v->cur_speed * 8);
|
||||||
str = STR_HEADING_FOR_HANGAR + _patches.vehicle_speed;
|
str = STR_HEADING_FOR_HANGAR + _patches.vehicle_speed;
|
||||||
} break;
|
} break;
|
||||||
|
@ -857,15 +857,15 @@ void ShowAircraftDepotWindow(uint tile)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawSmallSchedule(Vehicle *v, int x, int y) {
|
static void DrawSmallSchedule(Vehicle *v, int x, int y) {
|
||||||
uint16 *sched;
|
const Order *sched;
|
||||||
int sel;
|
int sel;
|
||||||
uint ord;
|
Order ord;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
sched = v->schedule_ptr;
|
sched = v->schedule_ptr;
|
||||||
sel = v->cur_order_index;
|
sel = v->cur_order_index;
|
||||||
|
|
||||||
while ((ord=*sched++) != 0) {
|
while ((ord = *sched++).type != OT_NOTHING) {
|
||||||
if (sel == 0) {
|
if (sel == 0) {
|
||||||
_stringwidth_base = 0xE0;
|
_stringwidth_base = 0xE0;
|
||||||
DoDrawString( "\xAF", x-6, y, 16);
|
DoDrawString( "\xAF", x-6, y, 16);
|
||||||
|
@ -873,8 +873,8 @@ static void DrawSmallSchedule(Vehicle *v, int x, int y) {
|
||||||
}
|
}
|
||||||
sel--;
|
sel--;
|
||||||
|
|
||||||
if ((ord & OT_MASK) == OT_GOTO_STATION) {
|
if (ord.type == OT_GOTO_STATION) {
|
||||||
SetDParam(0, ord >> 8);
|
SetDParam(0, ord.station);
|
||||||
DrawString(x, y, STR_A036, 0);
|
DrawString(x, y, STR_A036, 0);
|
||||||
|
|
||||||
y += 6;
|
y += 6;
|
||||||
|
|
|
@ -79,7 +79,9 @@ static void InitializeDisasterVehicle(Vehicle *v, int x, int y, byte z, byte dir
|
||||||
v->owner = OWNER_NONE;
|
v->owner = OWNER_NONE;
|
||||||
v->vehstatus = VS_UNCLICKABLE;
|
v->vehstatus = VS_UNCLICKABLE;
|
||||||
v->u.disaster.image_override = 0;
|
v->u.disaster.image_override = 0;
|
||||||
v->next_order = 0;
|
v->current_order.type = OT_NOTHING;
|
||||||
|
v->current_order.flags = 0;
|
||||||
|
v->current_order.station = 0;
|
||||||
|
|
||||||
DisasterVehicleUpdateImage(v);
|
DisasterVehicleUpdateImage(v);
|
||||||
VehiclePositionChanged(v);
|
VehiclePositionChanged(v);
|
||||||
|
@ -141,7 +143,7 @@ static void DisasterTick_Zeppeliner(Vehicle *v)
|
||||||
|
|
||||||
++v->tick_counter;
|
++v->tick_counter;
|
||||||
|
|
||||||
if (v->next_order < 2) {
|
if (v->current_order.station < 2) {
|
||||||
if (v->tick_counter&1)
|
if (v->tick_counter&1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -149,23 +151,23 @@ static void DisasterTick_Zeppeliner(Vehicle *v)
|
||||||
|
|
||||||
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
||||||
|
|
||||||
if (v->next_order == 1) {
|
if (v->current_order.station == 1) {
|
||||||
if (++v->age == 38) {
|
if (++v->age == 38) {
|
||||||
v->next_order = 2;
|
v->current_order.station = 2;
|
||||||
v->age = 0;
|
v->age = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((v->tick_counter&7)==0) {
|
if ((v->tick_counter&7)==0) {
|
||||||
CreateEffectVehicleRel(v, 0, -17, 2, EV_SMOKE_3);
|
CreateEffectVehicleRel(v, 0, -17, 2, EV_SMOKE_3);
|
||||||
}
|
}
|
||||||
} else if (v->next_order == 0) {
|
} else if (v->current_order.station == 0) {
|
||||||
tile = v->tile; /**/
|
tile = v->tile; /**/
|
||||||
|
|
||||||
if (IS_TILETYPE(tile, MP_STATION) &&
|
if (IS_TILETYPE(tile, MP_STATION) &&
|
||||||
IS_BYTE_INSIDE(_map5[tile], 8, 0x43) &&
|
IS_BYTE_INSIDE(_map5[tile], 8, 0x43) &&
|
||||||
IS_HUMAN_PLAYER(_map_owner[tile])) {
|
IS_HUMAN_PLAYER(_map_owner[tile])) {
|
||||||
|
|
||||||
v->next_order = 1;
|
v->current_order.station = 1;
|
||||||
v->age = 0;
|
v->age = 0;
|
||||||
|
|
||||||
SetDParam(0, _map2[tile]);
|
SetDParam(0, _map2[tile]);
|
||||||
|
@ -180,7 +182,7 @@ static void DisasterTick_Zeppeliner(Vehicle *v)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v->next_order > 2) {
|
if (v->current_order.station > 2) {
|
||||||
if (++v->age <= 13320)
|
if (++v->age <= 13320)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -223,7 +225,7 @@ static void DisasterTick_Zeppeliner(Vehicle *v)
|
||||||
EV_DEMOLISH);
|
EV_DEMOLISH);
|
||||||
}
|
}
|
||||||
} else if (v->age == 350) {
|
} else if (v->age == 350) {
|
||||||
v->next_order = 3;
|
v->current_order.station = 3;
|
||||||
v->age = 0;
|
v->age = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +250,7 @@ static void DisasterTick_UFO(Vehicle *v)
|
||||||
|
|
||||||
v->u.disaster.image_override = (++v->tick_counter & 8) ? 0xF45 : 0xF44;
|
v->u.disaster.image_override = (++v->tick_counter & 8) ? 0xF45 : 0xF44;
|
||||||
|
|
||||||
if (v->next_order == 0) {
|
if (v->current_order.station == 0) {
|
||||||
// fly around randomly
|
// fly around randomly
|
||||||
int x = GET_TILE_X(v->dest_tile)*16;
|
int x = GET_TILE_X(v->dest_tile)*16;
|
||||||
int y = GET_TILE_Y(v->dest_tile)*16;
|
int y = GET_TILE_Y(v->dest_tile)*16;
|
||||||
|
@ -262,7 +264,7 @@ static void DisasterTick_UFO(Vehicle *v)
|
||||||
v->dest_tile = TILE_MASK(Random());
|
v->dest_tile = TILE_MASK(Random());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
v->next_order = 1;
|
v->current_order.station = 1;
|
||||||
|
|
||||||
FOR_ALL_VEHICLES(u) {
|
FOR_ALL_VEHICLES(u) {
|
||||||
if (u->type == VEH_Road && IS_HUMAN_PLAYER(u->owner)) {
|
if (u->type == VEH_Road && IS_HUMAN_PLAYER(u->owner)) {
|
||||||
|
@ -336,7 +338,8 @@ static void DisasterTick_2(Vehicle *v)
|
||||||
GetNewVehiclePosResult gp;
|
GetNewVehiclePosResult gp;
|
||||||
|
|
||||||
v->tick_counter++;
|
v->tick_counter++;
|
||||||
v->u.disaster.image_override = (v->next_order == 1 && v->tick_counter&4) ? 0xF4F : 0;
|
v->u.disaster.image_override =
|
||||||
|
(v->current_order.station == 1 && v->tick_counter&4) ? 0xF4F : 0;
|
||||||
|
|
||||||
GetNewVehiclePos(v, &gp);
|
GetNewVehiclePos(v, &gp);
|
||||||
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
||||||
|
@ -346,7 +349,7 @@ static void DisasterTick_2(Vehicle *v)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v->next_order == 2) {
|
if (v->current_order.station == 2) {
|
||||||
if (!(v->tick_counter&3)) {
|
if (!(v->tick_counter&3)) {
|
||||||
Industry *i = DEREF_INDUSTRY(v->dest_tile);
|
Industry *i = DEREF_INDUSTRY(v->dest_tile);
|
||||||
int x = GET_TILE_X(i->xy)*16;
|
int x = GET_TILE_X(i->xy)*16;
|
||||||
|
@ -360,13 +363,13 @@ static void DisasterTick_2(Vehicle *v)
|
||||||
EV_DEMOLISH);
|
EV_DEMOLISH);
|
||||||
|
|
||||||
if (++v->age >= 55)
|
if (++v->age >= 55)
|
||||||
v->next_order = 3;
|
v->current_order.station = 3;
|
||||||
}
|
}
|
||||||
} else if (v->next_order == 1) {
|
} else if (v->current_order.station == 1) {
|
||||||
if (++v->age == 112) {
|
if (++v->age == 112) {
|
||||||
Industry *i;
|
Industry *i;
|
||||||
|
|
||||||
v->next_order = 2;
|
v->current_order.station = 2;
|
||||||
v->age = 0;
|
v->age = 0;
|
||||||
|
|
||||||
i = DEREF_INDUSTRY(v->dest_tile);
|
i = DEREF_INDUSTRY(v->dest_tile);
|
||||||
|
@ -376,7 +379,7 @@ static void DisasterTick_2(Vehicle *v)
|
||||||
AddNewsItem(STR_B002_OIL_REFINERY_EXPLOSION, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0);
|
AddNewsItem(STR_B002_OIL_REFINERY_EXPLOSION, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0);
|
||||||
SndPlayTileFx(SND_12_EXPLOSION, i->xy);
|
SndPlayTileFx(SND_12_EXPLOSION, i->xy);
|
||||||
}
|
}
|
||||||
} else if (v->next_order == 0) {
|
} else if (v->current_order.station == 0) {
|
||||||
int x,y;
|
int x,y;
|
||||||
uint tile;
|
uint tile;
|
||||||
int ind;
|
int ind;
|
||||||
|
@ -394,7 +397,7 @@ static void DisasterTick_2(Vehicle *v)
|
||||||
v->dest_tile = ind = _map2[tile];
|
v->dest_tile = ind = _map2[tile];
|
||||||
|
|
||||||
if (DEREF_INDUSTRY(ind)->type == IT_OIL_REFINERY) {
|
if (DEREF_INDUSTRY(ind)->type == IT_OIL_REFINERY) {
|
||||||
v->next_order = 1;
|
v->current_order.station = 1;
|
||||||
v->age = 0;
|
v->age = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -406,7 +409,8 @@ static void DisasterTick_3(Vehicle *v)
|
||||||
GetNewVehiclePosResult gp;
|
GetNewVehiclePosResult gp;
|
||||||
|
|
||||||
v->tick_counter++;
|
v->tick_counter++;
|
||||||
v->u.disaster.image_override = (v->next_order == 1 && v->tick_counter&4) ? 0xF53 : 0;
|
v->u.disaster.image_override =
|
||||||
|
(v->current_order.station == 1 && v->tick_counter&4) ? 0xF53 : 0;
|
||||||
|
|
||||||
GetNewVehiclePos(v, &gp);
|
GetNewVehiclePos(v, &gp);
|
||||||
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
|
||||||
|
@ -416,7 +420,7 @@ static void DisasterTick_3(Vehicle *v)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v->next_order == 2) {
|
if (v->current_order.station == 2) {
|
||||||
if (!(v->tick_counter&3)) {
|
if (!(v->tick_counter&3)) {
|
||||||
Industry *i = DEREF_INDUSTRY(v->dest_tile);
|
Industry *i = DEREF_INDUSTRY(v->dest_tile);
|
||||||
int x = GET_TILE_X(i->xy)*16;
|
int x = GET_TILE_X(i->xy)*16;
|
||||||
|
@ -430,13 +434,13 @@ static void DisasterTick_3(Vehicle *v)
|
||||||
EV_DEMOLISH);
|
EV_DEMOLISH);
|
||||||
|
|
||||||
if (++v->age >= 55)
|
if (++v->age >= 55)
|
||||||
v->next_order = 3;
|
v->current_order.station = 3;
|
||||||
}
|
}
|
||||||
} else if (v->next_order == 1) {
|
} else if (v->current_order.station == 1) {
|
||||||
if (++v->age == 112) {
|
if (++v->age == 112) {
|
||||||
Industry *i;
|
Industry *i;
|
||||||
|
|
||||||
v->next_order = 2;
|
v->current_order.station = 2;
|
||||||
v->age = 0;
|
v->age = 0;
|
||||||
|
|
||||||
i = DEREF_INDUSTRY(v->dest_tile);
|
i = DEREF_INDUSTRY(v->dest_tile);
|
||||||
|
@ -446,7 +450,7 @@ static void DisasterTick_3(Vehicle *v)
|
||||||
AddNewsItem(STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0);
|
AddNewsItem(STR_B003_FACTORY_DESTROYED_IN_SUSPICIOUS, NEWS_FLAGS(NM_THIN,NF_VIEWPORT|NF_TILE,NT_ACCIDENT,0), i->xy, 0);
|
||||||
SndPlayTileFx(SND_12_EXPLOSION, i->xy);
|
SndPlayTileFx(SND_12_EXPLOSION, i->xy);
|
||||||
}
|
}
|
||||||
} else if (v->next_order == 0) {
|
} else if (v->current_order.station == 0) {
|
||||||
int x,y;
|
int x,y;
|
||||||
uint tile;
|
uint tile;
|
||||||
int ind;
|
int ind;
|
||||||
|
@ -464,7 +468,7 @@ static void DisasterTick_3(Vehicle *v)
|
||||||
v->dest_tile = ind = _map2[tile];
|
v->dest_tile = ind = _map2[tile];
|
||||||
|
|
||||||
if (DEREF_INDUSTRY(ind)->type == IT_FACTORY) {
|
if (DEREF_INDUSTRY(ind)->type == IT_FACTORY) {
|
||||||
v->next_order = 1;
|
v->current_order.station = 1;
|
||||||
v->age = 0;
|
v->age = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -496,7 +500,7 @@ static void DisasterTick_4(Vehicle *v)
|
||||||
|
|
||||||
v->tick_counter++;
|
v->tick_counter++;
|
||||||
|
|
||||||
if (v->next_order == 1) {
|
if (v->current_order.station == 1) {
|
||||||
int x = GET_TILE_X(v->dest_tile)*16 + 8;
|
int x = GET_TILE_X(v->dest_tile)*16 + 8;
|
||||||
int y = GET_TILE_Y(v->dest_tile)*16 + 8;
|
int y = GET_TILE_Y(v->dest_tile)*16 + 8;
|
||||||
if (abs(v->x_pos - x) + abs(v->y_pos - y) >= 8) {
|
if (abs(v->x_pos - x) + abs(v->y_pos - y) >= 8) {
|
||||||
|
@ -513,7 +517,7 @@ static void DisasterTick_4(Vehicle *v)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
v->next_order = 2;
|
v->current_order.station = 2;
|
||||||
|
|
||||||
FOR_ALL_VEHICLES(u) {
|
FOR_ALL_VEHICLES(u) {
|
||||||
if (u->type == VEH_Train || u->type == VEH_Road) {
|
if (u->type == VEH_Train || u->type == VEH_Road) {
|
||||||
|
@ -547,7 +551,7 @@ static void DisasterTick_4(Vehicle *v)
|
||||||
u->next = w;
|
u->next = w;
|
||||||
InitializeDisasterVehicle(w, -6*16, v->y_pos, 0, 5, 12);
|
InitializeDisasterVehicle(w, -6*16, v->y_pos, 0, 5, 12);
|
||||||
w->vehstatus |= VS_DISASTER;
|
w->vehstatus |= VS_DISASTER;
|
||||||
} else if (v->next_order < 1) {
|
} else if (v->current_order.station < 1) {
|
||||||
|
|
||||||
int x = GET_TILE_X(v->dest_tile)*16;
|
int x = GET_TILE_X(v->dest_tile)*16;
|
||||||
int y = GET_TILE_Y(v->dest_tile)*16;
|
int y = GET_TILE_Y(v->dest_tile)*16;
|
||||||
|
@ -562,7 +566,7 @@ static void DisasterTick_4(Vehicle *v)
|
||||||
v->dest_tile = TILE_MASK(Random());
|
v->dest_tile = TILE_MASK(Random());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
v->next_order = 1;
|
v->current_order.station = 1;
|
||||||
|
|
||||||
tile_org = tile = TILE_MASK(Random());
|
tile_org = tile = TILE_MASK(Random());
|
||||||
do {
|
do {
|
||||||
|
@ -594,11 +598,11 @@ static void DisasterTick_4b(Vehicle *v)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v->next_order == 0) {
|
if (v->current_order.station == 0) {
|
||||||
u = &_vehicles[v->u.disaster.unk2];
|
u = &_vehicles[v->u.disaster.unk2];
|
||||||
if (abs(v->x_pos - u->x_pos) > 16)
|
if (abs(v->x_pos - u->x_pos) > 16)
|
||||||
return;
|
return;
|
||||||
v->next_order = 1;
|
v->current_order.station = 1;
|
||||||
|
|
||||||
CreateEffectVehicleRel(u, 0, 7, 8, EV_CRASHED_SMOKE);
|
CreateEffectVehicleRel(u, 0, 7, 8, EV_CRASHED_SMOKE);
|
||||||
SndPlayVehicleFx(SND_12_EXPLOSION, u);
|
SndPlayVehicleFx(SND_12_EXPLOSION, u);
|
||||||
|
|
10
economy.c
10
economy.c
|
@ -1231,7 +1231,7 @@ static bool LoadWait(const Vehicle *v, const Vehicle *u) {
|
||||||
const Vehicle *x;
|
const Vehicle *x;
|
||||||
bool has_any_cargo = false;
|
bool has_any_cargo = false;
|
||||||
|
|
||||||
if (!(u->next_order & OF_FULL_LOAD)) return false;
|
if (!(u->current_order.flags & OF_FULL_LOAD)) return false;
|
||||||
|
|
||||||
for (w = u; w != NULL; w = w->next) {
|
for (w = u; w != NULL; w = w->next) {
|
||||||
if (w->cargo_count != 0) {
|
if (w->cargo_count != 0) {
|
||||||
|
@ -1246,7 +1246,7 @@ static bool LoadWait(const Vehicle *v, const Vehicle *u) {
|
||||||
if ((x->type != VEH_Train || x->subtype == 0) && // for all locs
|
if ((x->type != VEH_Train || x->subtype == 0) && // for all locs
|
||||||
u->last_station_visited == x->last_station_visited && // at the same station
|
u->last_station_visited == x->last_station_visited && // at the same station
|
||||||
!(x->vehstatus & VS_STOPPED) && // not stopped
|
!(x->vehstatus & VS_STOPPED) && // not stopped
|
||||||
(x->next_order & OT_MASK) == OT_LOADING && // loading
|
x->current_order.type == OT_LOADING && // loading
|
||||||
u != x) { // not itself
|
u != x) { // not itself
|
||||||
bool other_has_any_cargo = false;
|
bool other_has_any_cargo = false;
|
||||||
bool has_space_for_same_type = false;
|
bool has_space_for_same_type = false;
|
||||||
|
@ -1288,7 +1288,7 @@ int LoadUnloadVehicle(Vehicle *v)
|
||||||
byte old_player;
|
byte old_player;
|
||||||
bool completely_empty = true;
|
bool completely_empty = true;
|
||||||
|
|
||||||
assert((v->next_order&0x1F) == OT_LOADING);
|
assert(v->current_order.type == OT_LOADING);
|
||||||
|
|
||||||
v->cur_speed = 0;
|
v->cur_speed = 0;
|
||||||
old_player = _current_player;
|
old_player = _current_player;
|
||||||
|
@ -1309,7 +1309,7 @@ int LoadUnloadVehicle(Vehicle *v)
|
||||||
profit += DeliverGoods(v->cargo_count, v->cargo_type, v->cargo_source, last_visited, v->cargo_days);
|
profit += DeliverGoods(v->cargo_count, v->cargo_type, v->cargo_source, last_visited, v->cargo_days);
|
||||||
result |= 1;
|
result |= 1;
|
||||||
v->cargo_count = 0;
|
v->cargo_count = 0;
|
||||||
} else if (u->next_order & OF_UNLOAD) {
|
} else if (u->current_order.flags & OF_UNLOAD) {
|
||||||
/* unload goods and let it wait at the station */
|
/* unload goods and let it wait at the station */
|
||||||
st->time_since_unload = 0;
|
st->time_since_unload = 0;
|
||||||
|
|
||||||
|
@ -1335,7 +1335,7 @@ int LoadUnloadVehicle(Vehicle *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* don't pick up goods that we unloaded */
|
/* don't pick up goods that we unloaded */
|
||||||
if (u->next_order & OF_UNLOAD) continue;
|
if (u->current_order.flags & OF_UNLOAD) continue;
|
||||||
|
|
||||||
/* update stats */
|
/* update stats */
|
||||||
ge->days_since_pickup = 0;
|
ge->days_since_pickup = 0;
|
||||||
|
|
6
engine.c
6
engine.c
|
@ -314,14 +314,14 @@ ResolveVehicleSpriteGroup(struct SpriteGroup *spritegroup, struct Vehicle *veh,
|
||||||
// TTDPatch runs on little-endian arch;
|
// TTDPatch runs on little-endian arch;
|
||||||
// Variable is 0x80 + offset in TTD's vehicle structure
|
// Variable is 0x80 + offset in TTD's vehicle structure
|
||||||
switch (dsg->variable - 0x80) {
|
switch (dsg->variable - 0x80) {
|
||||||
#define veh_prop(id_, value_) case id_: value = value_; break
|
#define veh_prop(id_, value_) case (id_): value = (value_); break
|
||||||
veh_prop(0x00, veh->type);
|
veh_prop(0x00, veh->type);
|
||||||
veh_prop(0x01, veh->subtype);
|
veh_prop(0x01, veh->subtype);
|
||||||
veh_prop(0x04, veh->index);
|
veh_prop(0x04, veh->index);
|
||||||
veh_prop(0x05, veh->index & 0xFF);
|
veh_prop(0x05, veh->index & 0xFF);
|
||||||
/* XXX? Is THIS right? */
|
/* XXX? Is THIS right? */
|
||||||
veh_prop(0x0A, veh->next_order_param << 8 | veh->next_order);
|
veh_prop(0x0A, PackOrder(&veh->current_order));
|
||||||
veh_prop(0x0B, veh->next_order);
|
veh_prop(0x0B, PackOrder(&veh->current_order) & 0xff);
|
||||||
veh_prop(0x0C, veh->num_orders);
|
veh_prop(0x0C, veh->num_orders);
|
||||||
veh_prop(0x0D, veh->cur_order_index);
|
veh_prop(0x0D, veh->cur_order_index);
|
||||||
veh_prop(0x10, veh->load_unload_time_rem);
|
veh_prop(0x10, veh->load_unload_time_rem);
|
||||||
|
|
|
@ -736,8 +736,9 @@ static void FixVehicle(Vehicle *n, OldVehicle *o, int num)
|
||||||
assert(n->schedule_ptr >= _order_array && n->schedule_ptr < _ptr_to_next_order);
|
assert(n->schedule_ptr >= _order_array && n->schedule_ptr < _ptr_to_next_order);
|
||||||
}
|
}
|
||||||
|
|
||||||
n->next_order = o->next_order;
|
n->current_order.type = o->next_order & 0x0f;
|
||||||
n->next_order_param = o->next_order_param;
|
n->current_order.flags = o->next_order >> 4;
|
||||||
|
n->current_order.station = o->next_order_param;
|
||||||
n->num_orders = o->num_orders;
|
n->num_orders = o->num_orders;
|
||||||
n->cur_order_index = o->cur_order_index;
|
n->cur_order_index = o->cur_order_index;
|
||||||
n->dest_tile = o->dest_tile;
|
n->dest_tile = o->dest_tile;
|
||||||
|
|
122
order_cmd.c
122
order_cmd.c
|
@ -15,7 +15,7 @@ int32 CmdInsertOrder(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
{
|
{
|
||||||
Vehicle *v = &_vehicles[p1 & 0xFFFF];
|
Vehicle *v = &_vehicles[p1 & 0xFFFF];
|
||||||
int sel = p1 >> 16;
|
int sel = p1 >> 16;
|
||||||
int t;
|
Order new_order = UnpackOrder(p2);
|
||||||
|
|
||||||
if (sel > v->num_orders) return_cmd_error(STR_EMPTY);
|
if (sel > v->num_orders) return_cmd_error(STR_EMPTY);
|
||||||
if (_ptr_to_next_order == endof(_order_array)) return_cmd_error(STR_8831_NO_MORE_SPACE_FOR_ORDERS);
|
if (_ptr_to_next_order == endof(_order_array)) return_cmd_error(STR_8831_NO_MORE_SPACE_FOR_ORDERS);
|
||||||
|
@ -23,21 +23,25 @@ int32 CmdInsertOrder(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
|
|
||||||
// for ships, make sure that the station is not too far away from the previous destination.
|
// for ships, make sure that the station is not too far away from the previous destination.
|
||||||
if (v->type == VEH_Ship && IS_HUMAN_PLAYER(v->owner) &&
|
if (v->type == VEH_Ship && IS_HUMAN_PLAYER(v->owner) &&
|
||||||
sel != 0 && ((t=v->schedule_ptr[sel-1])&OT_MASK) == OT_GOTO_STATION) {
|
sel != 0 && v->schedule_ptr[sel - 1].type == OT_GOTO_STATION) {
|
||||||
|
|
||||||
int dist = GetTileDist(DEREF_STATION(t >> 8)->xy, DEREF_STATION(p2 >> 8)->xy);
|
int dist = GetTileDist(
|
||||||
|
DEREF_STATION(v->schedule_ptr[sel - 1].station)->xy,
|
||||||
|
DEREF_STATION(new_order.station)->xy
|
||||||
|
);
|
||||||
if (dist >= 130)
|
if (dist >= 130)
|
||||||
return_cmd_error(STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO);
|
return_cmd_error(STR_0210_TOO_FAR_FROM_PREVIOUS_DESTINATIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
uint16 *s1, *s2;
|
Order *s1;
|
||||||
|
Order *s2;
|
||||||
Vehicle *u;
|
Vehicle *u;
|
||||||
|
|
||||||
s1 = &v->schedule_ptr[sel];
|
s1 = &v->schedule_ptr[sel];
|
||||||
s2 = _ptr_to_next_order++;
|
s2 = _ptr_to_next_order++;
|
||||||
do s2[1] = s2[0]; while (--s2 >= s1);
|
do s2[1] = s2[0]; while (--s2 >= s1);
|
||||||
s1[0] = (uint16)p2;
|
*s1 = new_order;
|
||||||
|
|
||||||
s1 = v->schedule_ptr;
|
s1 = v->schedule_ptr;
|
||||||
|
|
||||||
|
@ -72,7 +76,9 @@ static int32 DecloneOrder(Vehicle *dst, uint32 flags)
|
||||||
DeleteVehicleSchedule(dst);
|
DeleteVehicleSchedule(dst);
|
||||||
|
|
||||||
dst->num_orders = 0;
|
dst->num_orders = 0;
|
||||||
*(dst->schedule_ptr = _ptr_to_next_order++) = 0;
|
_ptr_to_next_order->type = OT_NOTHING;
|
||||||
|
_ptr_to_next_order->flags = 0;
|
||||||
|
dst->schedule_ptr = _ptr_to_next_order++;
|
||||||
|
|
||||||
InvalidateWindow(WC_VEHICLE_ORDERS, dst->index);
|
InvalidateWindow(WC_VEHICLE_ORDERS, dst->index);
|
||||||
}
|
}
|
||||||
|
@ -92,9 +98,7 @@ int32 CmdDeleteOrder(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
return DecloneOrder(v, flags);
|
return DecloneOrder(v, flags);
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
uint16 *s1;
|
Order *s1 = &v->schedule_ptr[sel];
|
||||||
|
|
||||||
s1 = &v->schedule_ptr[sel];
|
|
||||||
|
|
||||||
// copy all orders to get rid of the hole
|
// copy all orders to get rid of the hole
|
||||||
do s1[0] = s1[1]; while (++s1 != _ptr_to_next_order);
|
do s1[0] = s1[1]; while (++s1 != _ptr_to_next_order);
|
||||||
|
@ -111,8 +115,11 @@ int32 CmdDeleteOrder(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
if ((byte)sel < u->cur_order_index)
|
if ((byte)sel < u->cur_order_index)
|
||||||
u->cur_order_index--;
|
u->cur_order_index--;
|
||||||
|
|
||||||
if ((byte)sel == u->cur_order_index && (u->next_order&(OT_MASK|OF_NON_STOP)) == (OT_LOADING|OF_NON_STOP))
|
if ((byte)sel == u->cur_order_index &&
|
||||||
u->next_order = OT_LOADING;
|
u->current_order.type == OT_LOADING &&
|
||||||
|
u->current_order.flags & OF_NON_STOP) {
|
||||||
|
u->current_order.flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
InvalidateWindow(WC_VEHICLE_VIEW, u->index);
|
InvalidateWindow(WC_VEHICLE_VIEW, u->index);
|
||||||
InvalidateWindow(WC_VEHICLE_ORDERS, u->index);
|
InvalidateWindow(WC_VEHICLE_ORDERS, u->index);
|
||||||
|
@ -139,8 +146,10 @@ int32 CmdSkipOrder(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
v->u.rail.days_since_order_progr = 0;
|
v->u.rail.days_since_order_progr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((v->next_order&(OT_MASK|OF_NON_STOP)) == (OT_LOADING|OF_NON_STOP))
|
if (v->current_order.type == OT_LOADING &&
|
||||||
v->next_order = OT_LOADING;
|
v->current_order.flags & OF_NON_STOP) {
|
||||||
|
v->current_order.flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
InvalidateWindow(WC_VEHICLE_ORDERS, v->index);
|
InvalidateWindow(WC_VEHICLE_ORDERS, v->index);
|
||||||
}
|
}
|
||||||
|
@ -155,29 +164,28 @@ int32 CmdModifyOrder(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
{
|
{
|
||||||
Vehicle *v = &_vehicles[p1];
|
Vehicle *v = &_vehicles[p1];
|
||||||
byte sel = (byte)p2;
|
byte sel = (byte)p2;
|
||||||
uint16 *sched;
|
Order *sched;
|
||||||
|
|
||||||
if (sel >= v->num_orders)
|
if (sel >= v->num_orders)
|
||||||
return CMD_ERROR;
|
return CMD_ERROR;
|
||||||
|
|
||||||
sched = &v->schedule_ptr[sel];
|
sched = &v->schedule_ptr[sel];
|
||||||
if (!((*sched & OT_MASK) == OT_GOTO_STATION ||
|
if (sched->type != OT_GOTO_STATION &&
|
||||||
((*sched & OT_MASK) == OT_GOTO_DEPOT && (p2>>8) != 1)))
|
(sched->type != OT_GOTO_DEPOT || (p2 >> 8) == 1))
|
||||||
return CMD_ERROR;
|
return CMD_ERROR;
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
switch (p2 >> 8) {
|
switch (p2 >> 8) {
|
||||||
case 0: // full load
|
case 0: // full load
|
||||||
*sched ^= OF_FULL_LOAD;
|
sched->flags ^= OF_FULL_LOAD;
|
||||||
if ((*sched & OT_MASK) != OT_GOTO_DEPOT)
|
if (sched->type != OT_GOTO_DEPOT) sched->flags &= ~OF_UNLOAD;
|
||||||
*sched &= ~OF_UNLOAD;
|
|
||||||
break;
|
break;
|
||||||
case 1: // unload
|
case 1: // unload
|
||||||
*sched ^= OF_UNLOAD;
|
sched->flags ^= OF_UNLOAD;
|
||||||
*sched &= ~OF_FULL_LOAD;
|
sched->flags &= ~OF_FULL_LOAD;
|
||||||
break;
|
break;
|
||||||
case 2: // non stop
|
case 2: // non stop
|
||||||
*sched ^= OF_NON_STOP;
|
sched->flags ^= OF_NON_STOP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sched = v->schedule_ptr;
|
sched = v->schedule_ptr;
|
||||||
|
@ -247,14 +255,12 @@ int32 CmdCloneOrder(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
|
|
||||||
// let's see what happens with road vehicles
|
// let's see what happens with road vehicles
|
||||||
if (src->type == VEH_Road) {
|
if (src->type == VEH_Road) {
|
||||||
uint16 ord;
|
const Order *i;
|
||||||
int i;
|
|
||||||
Station *st;
|
|
||||||
TileIndex required_dst;
|
TileIndex required_dst;
|
||||||
|
|
||||||
for (i=0; (ord = src->schedule_ptr[i]) != 0; i++) {
|
for (i = src->schedule_ptr; i->type != OT_NOTHING; ++i) {
|
||||||
if ( ( ord & OT_MASK ) == OT_GOTO_STATION ) {
|
if (i->type == OT_GOTO_STATION) {
|
||||||
st = DEREF_STATION(ord >> 8);
|
const Station *st = DEREF_STATION(i->station);
|
||||||
required_dst = (dst->cargo_type == CT_PASSENGERS) ? st->bus_tile : st->lorry_tile;
|
required_dst = (dst->cargo_type == CT_PASSENGERS) ? st->bus_tile : st->lorry_tile;
|
||||||
if ( !required_dst )
|
if ( !required_dst )
|
||||||
return CMD_ERROR;
|
return CMD_ERROR;
|
||||||
|
@ -289,7 +295,6 @@ int32 CmdCloneOrder(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
void BackupVehicleOrders(Vehicle *v, BackuppedOrders *bak)
|
void BackupVehicleOrders(Vehicle *v, BackuppedOrders *bak)
|
||||||
{
|
{
|
||||||
Vehicle *u = IsScheduleShared(v);
|
Vehicle *u = IsScheduleShared(v);
|
||||||
uint16 *sched, ord, *os;
|
|
||||||
|
|
||||||
bak->orderindex = v->cur_order_index;
|
bak->orderindex = v->cur_order_index;
|
||||||
bak->service_interval = v->service_interval;
|
bak->service_interval = v->service_interval;
|
||||||
|
@ -300,25 +305,24 @@ void BackupVehicleOrders(Vehicle *v, BackuppedOrders *bak)
|
||||||
GetName(v->string_id & 0x7FF, bak->name);
|
GetName(v->string_id & 0x7FF, bak->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
os = bak->order;
|
|
||||||
// stored shared orders in this special way?
|
// stored shared orders in this special way?
|
||||||
if (u) {
|
if (u != NULL) {
|
||||||
os[0] = 0xFFFF;
|
bak->clone = u->index;
|
||||||
os[1] = u->index;
|
} else {
|
||||||
return;
|
Order *sched = v->schedule_ptr;
|
||||||
}
|
Order *os = bak->order;
|
||||||
|
|
||||||
|
bak->clone = INVALID_VEHICLE;
|
||||||
|
|
||||||
sched = v->schedule_ptr;
|
|
||||||
do {
|
do {
|
||||||
ord = *sched++;
|
*os++ = *sched++;
|
||||||
*os++ = ord;
|
} while (sched->type != OT_NOTHING);
|
||||||
} while (ord != 0);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RestoreVehicleOrders(Vehicle *v, BackuppedOrders *bak)
|
void RestoreVehicleOrders(Vehicle *v, BackuppedOrders *bak)
|
||||||
{
|
{
|
||||||
uint16 ord, *os;
|
int i;
|
||||||
int ind;
|
|
||||||
|
|
||||||
if (bak->name[0]) {
|
if (bak->name[0]) {
|
||||||
strcpy((char*)_decode_parameters, bak->name);
|
strcpy((char*)_decode_parameters, bak->name);
|
||||||
|
@ -327,9 +331,8 @@ void RestoreVehicleOrders(Vehicle *v, BackuppedOrders *bak)
|
||||||
|
|
||||||
DoCommandP(0, v->index, bak->orderindex|(bak->service_interval<<16) , NULL, CMD_RESTORE_ORDER_INDEX);
|
DoCommandP(0, v->index, bak->orderindex|(bak->service_interval<<16) , NULL, CMD_RESTORE_ORDER_INDEX);
|
||||||
|
|
||||||
os = bak->order;
|
if (bak->clone != INVALID_VEHICLE) {
|
||||||
if (os[0] == 0xFFFF) {
|
DoCommandP(0, v->index | bak->clone << 16, 0, NULL, CMD_CLONE_ORDER);
|
||||||
DoCommandP(0, v->index | os[1]<<16, 0, NULL, CMD_CLONE_ORDER);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,12 +340,9 @@ void RestoreVehicleOrders(Vehicle *v, BackuppedOrders *bak)
|
||||||
// order number is one more then the current amount of orders, and because
|
// order number is one more then the current amount of orders, and because
|
||||||
// in network the commands are queued before send, the second insert always
|
// in network the commands are queued before send, the second insert always
|
||||||
// fails in test mode. By bypassing the test-mode, that no longer is a problem.
|
// fails in test mode. By bypassing the test-mode, that no longer is a problem.
|
||||||
ind = 0;
|
for (i = 0; bak->order[i].type != OT_NOTHING; ++i)
|
||||||
while ((ord = *os++) != 0) {
|
if (!DoCommandP(0, v->index + (i << 16), PackOrder(&bak->order[i]), NULL, CMD_INSERT_ORDER | CMD_NO_TEST_IF_IN_NETWORK))
|
||||||
if (!DoCommandP(0, v->index + (ind << 16), ord, NULL, CMD_INSERT_ORDER | CMD_NO_TEST_IF_IN_NETWORK))
|
|
||||||
break;
|
break;
|
||||||
ind++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* p1 = vehicle
|
/* p1 = vehicle
|
||||||
|
@ -370,8 +370,8 @@ int CheckOrders(Vehicle *v)
|
||||||
|
|
||||||
/* only check every 20 days, so that we don't flood the message log */
|
/* only check every 20 days, so that we don't flood the message log */
|
||||||
if ( ( ( v->day_counter % 20) == 0 ) && (v->owner == _local_player) ) {
|
if ( ( ( v->day_counter % 20) == 0 ) && (v->owner == _local_player) ) {
|
||||||
|
Order order;
|
||||||
uint16 order, old_order;
|
Order old_order;
|
||||||
int i, n_st, problem_type = -1;
|
int i, n_st, problem_type = -1;
|
||||||
Station *st;
|
Station *st;
|
||||||
int message=0;
|
int message=0;
|
||||||
|
@ -381,21 +381,25 @@ int CheckOrders(Vehicle *v)
|
||||||
order = v->schedule_ptr[0];
|
order = v->schedule_ptr[0];
|
||||||
n_st = 0;
|
n_st = 0;
|
||||||
|
|
||||||
for (old_order = i = 0; order!=0; i++ ) {
|
old_order.type = OT_NOTHING;
|
||||||
|
old_order.flags = 0;
|
||||||
|
for (i = 0; order.type != OT_NOTHING; i++) {
|
||||||
order = v->schedule_ptr[i];
|
order = v->schedule_ptr[i];
|
||||||
if (order == old_order) {
|
if (order.type == old_order.type &&
|
||||||
|
order.flags == old_order.flags &&
|
||||||
|
order.station == old_order.station) {
|
||||||
problem_type = 2;
|
problem_type = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( (order & OT_MASK) == OT_DUMMY ) {
|
if (order.type == OT_DUMMY) {
|
||||||
problem_type = 1;
|
problem_type = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( ( (order & OT_MASK) == OT_GOTO_STATION ) /*&& (order != old_order) */) {
|
if (order.type == OT_GOTO_STATION /*&& (order != old_order) */) {
|
||||||
//I uncommented this in order not to get two error messages
|
//I uncommented this in order not to get two error messages
|
||||||
//when two identical entries are in the list
|
//when two identical entries are in the list
|
||||||
n_st++;
|
n_st++;
|
||||||
st = DEREF_STATION(order >> 8);
|
st = DEREF_STATION(order.station);
|
||||||
required_tile = GetStationTileForVehicle(v,st);
|
required_tile = GetStationTileForVehicle(v,st);
|
||||||
if (!required_tile) problem_type = 3;
|
if (!required_tile) problem_type = 3;
|
||||||
}
|
}
|
||||||
|
@ -404,9 +408,11 @@ int CheckOrders(Vehicle *v)
|
||||||
|
|
||||||
//Now, check the last and the first order
|
//Now, check the last and the first order
|
||||||
//as the last order is the end of order marker, jump back 2
|
//as the last order is the end of order marker, jump back 2
|
||||||
if ( (v->schedule_ptr[0] == v->schedule_ptr[i-2]) && ( i-2 != 0 ) ) {
|
if (i > 2 &&
|
||||||
|
v->schedule_ptr[0].type == v->schedule_ptr[i - 2].type &&
|
||||||
|
v->schedule_ptr[0].flags == v->schedule_ptr[i - 2].flags &&
|
||||||
|
v->schedule_ptr[0].station == v->schedule_ptr[i - 2].station)
|
||||||
problem_type = 2;
|
problem_type = 2;
|
||||||
}
|
|
||||||
|
|
||||||
if ( (n_st < 2) && (problem_type == -1) ) problem_type = 0;
|
if ( (n_st < 2) && (problem_type == -1) ) problem_type = 0;
|
||||||
|
|
||||||
|
|
57
order_gui.c
57
order_gui.c
|
@ -13,14 +13,14 @@
|
||||||
static int OrderGetSel(Window *w)
|
static int OrderGetSel(Window *w)
|
||||||
{
|
{
|
||||||
Vehicle *v = &_vehicles[w->window_number];
|
Vehicle *v = &_vehicles[w->window_number];
|
||||||
uint16 *sched = v->schedule_ptr;
|
const Order *sched = v->schedule_ptr;
|
||||||
int num = WP(w,order_d).sel;
|
int num = WP(w,order_d).sel;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
if (num == 0)
|
if (num == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while (*sched != 0) {
|
while (sched->type != OT_NOTHING) {
|
||||||
sched++;
|
sched++;
|
||||||
count++;
|
count++;
|
||||||
if (--num == 0)
|
if (--num == 0)
|
||||||
|
@ -34,7 +34,8 @@ static void DrawOrdersWindow(Window *w)
|
||||||
{
|
{
|
||||||
Vehicle *v;
|
Vehicle *v;
|
||||||
int num, sel;
|
int num, sel;
|
||||||
uint16 *sched, ord;
|
const Order *sched;
|
||||||
|
Order ord;
|
||||||
int y, i;
|
int y, i;
|
||||||
StringID str;
|
StringID str;
|
||||||
bool shared_schedule;
|
bool shared_schedule;
|
||||||
|
@ -47,8 +48,10 @@ static void DrawOrdersWindow(Window *w)
|
||||||
|
|
||||||
sched = v->schedule_ptr;
|
sched = v->schedule_ptr;
|
||||||
num=0;
|
num=0;
|
||||||
while (*sched != 0)
|
while (sched->type != OT_NOTHING) {
|
||||||
sched++,num++;
|
sched++;
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
|
||||||
if ((uint)num + shared_schedule <= (uint)WP(w,order_d).sel)
|
if ((uint)num + shared_schedule <= (uint)WP(w,order_d).sel)
|
||||||
SETBIT(w->disabled_state, 5); /* delete */
|
SETBIT(w->disabled_state, 5); /* delete */
|
||||||
|
@ -61,7 +64,7 @@ static void DrawOrdersWindow(Window *w)
|
||||||
sel = OrderGetSel(w);
|
sel = OrderGetSel(w);
|
||||||
|
|
||||||
SetDParam(2,STR_8827_FULL_LOAD);
|
SetDParam(2,STR_8827_FULL_LOAD);
|
||||||
switch(v->schedule_ptr[sel] & 0x1F) {
|
switch (v->schedule_ptr[sel].type) {
|
||||||
case OT_GOTO_STATION:
|
case OT_GOTO_STATION:
|
||||||
break;
|
break;
|
||||||
case OT_GOTO_DEPOT:
|
case OT_GOTO_DEPOT:
|
||||||
|
@ -88,43 +91,43 @@ static void DrawOrdersWindow(Window *w)
|
||||||
|
|
||||||
if ( (uint)(i - w->vscroll.pos) < 6) {
|
if ( (uint)(i - w->vscroll.pos) < 6) {
|
||||||
|
|
||||||
if (ord == 0) {
|
if (ord.type == OT_NOTHING) {
|
||||||
str = shared_schedule ? STR_END_OF_SHARED_ORDERS : STR_882A_END_OF_ORDERS;
|
str = shared_schedule ? STR_END_OF_SHARED_ORDERS : STR_882A_END_OF_ORDERS;
|
||||||
} else {
|
} else {
|
||||||
SetDParam(1, 6);
|
SetDParam(1, 6);
|
||||||
|
|
||||||
if ( (ord & OT_MASK) == OT_GOTO_STATION) {
|
if (ord.type == OT_GOTO_STATION) {
|
||||||
SetDParam(1, STR_8806_GO_TO + ((ord >> 5) & 7));
|
SetDParam(1, STR_8806_GO_TO + (ord.flags >> 1));
|
||||||
SetDParam(2, ord >> 8);
|
SetDParam(2, ord.station);
|
||||||
} else if ((ord & OT_MASK) == OT_GOTO_DEPOT) {
|
} else if (ord.type == OT_GOTO_DEPOT) {
|
||||||
StringID s = STR_NULL;
|
StringID s = STR_NULL;
|
||||||
if (v->type == VEH_Aircraft) {
|
if (v->type == VEH_Aircraft) {
|
||||||
s = STR_GO_TO_AIRPORT_HANGAR;
|
s = STR_GO_TO_AIRPORT_HANGAR;
|
||||||
SetDParam(2, ord>>8);
|
SetDParam(2, ord.station);
|
||||||
} else {
|
} else {
|
||||||
SetDParam(2, _depots[ord >> 8].town_index);
|
SetDParam(2, _depots[ord.station].town_index);
|
||||||
switch (v->type) {
|
switch (v->type) {
|
||||||
case VEH_Train: s = STR_880E_GO_TO_TRAIN_DEPOT; break;
|
case VEH_Train: s = STR_880E_GO_TO_TRAIN_DEPOT; break;
|
||||||
case VEH_Road: s = STR_9038_GO_TO_ROADVEH_DEPOT; break;
|
case VEH_Road: s = STR_9038_GO_TO_ROADVEH_DEPOT; break;
|
||||||
case VEH_Ship: s = STR_GO_TO_SHIP_DEPOT; break;
|
case VEH_Ship: s = STR_GO_TO_SHIP_DEPOT; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (v->type == VEH_Train)
|
if (v->type == VEH_Train && ord.flags & OF_NON_STOP) s += 2;
|
||||||
s += (ord>>6)&2;
|
if (ord.flags & OF_FULL_LOAD) ++s; /* XXX service */
|
||||||
SetDParam(1, s + ((ord>>6)&1) );
|
SetDParam(1, s);
|
||||||
} else if ((ord & OT_MASK) == OT_GOTO_WAYPOINT) {
|
} else if (ord.type == OT_GOTO_WAYPOINT) {
|
||||||
SetDParam(2, ord >> 8);
|
SetDParam(2, ord.station);
|
||||||
SetDParam(1, STR_GO_TO_WAYPOINT);
|
SetDParam(1, STR_GO_TO_WAYPOINT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
byte color = (i == WP(w,order_d).sel) ? 0xC : 0x10;
|
byte color = (i == WP(w,order_d).sel) ? 0xC : 0x10;
|
||||||
SetDParam(0, i+1);
|
SetDParam(0, i+1);
|
||||||
if ((ord & OT_MASK) != OT_DUMMY) {
|
if (ord.type != OT_DUMMY) {
|
||||||
DrawString(2, y, str, color);
|
DrawString(2, y, str, color);
|
||||||
} else {
|
} else {
|
||||||
SetDParam(1, STR_INVALID_ORDER);
|
SetDParam(1, STR_INVALID_ORDER);
|
||||||
SetDParam(2, ord >> 8);
|
SetDParam(2, ord.station);
|
||||||
DrawString(2, y, str, color);
|
DrawString(2, y, str, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,7 +136,7 @@ static void DrawOrdersWindow(Window *w)
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (ord == 0)
|
if (ord.type == OT_NOTHING)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -288,17 +291,17 @@ static void OrdersWndProc(Window *w, WindowEvent *e)
|
||||||
sel += w->vscroll.pos;
|
sel += w->vscroll.pos;
|
||||||
|
|
||||||
if (_ctrl_pressed && sel < v->num_orders) { // watch out for schedule_ptr overflow
|
if (_ctrl_pressed && sel < v->num_orders) { // watch out for schedule_ptr overflow
|
||||||
int ord = v->schedule_ptr[sel];
|
Order ord = v->schedule_ptr[sel];
|
||||||
int xy = 0;
|
int xy = 0;
|
||||||
switch (ord & OT_MASK) {
|
switch (ord.type) {
|
||||||
case OT_GOTO_STATION: /* station order */
|
case OT_GOTO_STATION: /* station order */
|
||||||
xy = _stations[ord >> 8].xy ;
|
xy = _stations[ord.station].xy ;
|
||||||
break;
|
break;
|
||||||
case OT_GOTO_DEPOT: /* goto depot order */
|
case OT_GOTO_DEPOT: /* goto depot order */
|
||||||
xy = _depots[ord >> 8].xy;
|
xy = _depots[ord.station].xy;
|
||||||
break;
|
break;
|
||||||
case OT_GOTO_WAYPOINT: /* goto waypoint order */
|
case OT_GOTO_WAYPOINT: /* goto waypoint order */
|
||||||
xy = _waypoints[ord >> 8].xy;
|
xy = _waypoints[ord.station].xy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xy)
|
if (xy)
|
||||||
|
@ -352,7 +355,7 @@ static void OrdersWndProc(Window *w, WindowEvent *e)
|
||||||
case WE_RCLICK: {
|
case WE_RCLICK: {
|
||||||
Vehicle *v = &_vehicles[w->window_number];
|
Vehicle *v = &_vehicles[w->window_number];
|
||||||
if (e->click.widget != 8) break;
|
if (e->click.widget != 8) break;
|
||||||
if ((v->schedule_ptr[OrderGetSel(w)] & OT_MASK) == OT_GOTO_DEPOT)
|
if (v->schedule_ptr[OrderGetSel(w)].type == OT_GOTO_DEPOT)
|
||||||
GuiShowTooltips(STR_SERVICE_HINT);
|
GuiShowTooltips(STR_SERVICE_HINT);
|
||||||
else
|
else
|
||||||
GuiShowTooltips(STR_8857_MAKE_THE_HIGHLIGHTED_ORDER);
|
GuiShowTooltips(STR_8857_MAKE_THE_HIGHLIGHTED_ORDER);
|
||||||
|
|
|
@ -760,8 +760,12 @@ int32 CmdBuildTrainWaypoint(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
|
|
||||||
static void DoDeleteWaypoint(Waypoint *cp)
|
static void DoDeleteWaypoint(Waypoint *cp)
|
||||||
{
|
{
|
||||||
|
Order order;
|
||||||
cp->xy = 0;
|
cp->xy = 0;
|
||||||
DeleteCommandFromVehicleSchedule(((cp-_waypoints) << 8) + OT_GOTO_WAYPOINT);
|
order.type = OT_GOTO_WAYPOINT;
|
||||||
|
order.flags = 0;
|
||||||
|
order.station = cp - _waypoints;
|
||||||
|
DeleteCommandFromVehicleSchedule(order);
|
||||||
if (~cp->town_or_string & 0xC000) DeleteName(cp->town_or_string);
|
if (~cp->town_or_string & 0xC000) DeleteName(cp->town_or_string);
|
||||||
RedrawWaypointSign(cp);
|
RedrawWaypointSign(cp);
|
||||||
}
|
}
|
||||||
|
|
128
roadveh_cmd.c
128
roadveh_cmd.c
|
@ -169,7 +169,9 @@ int32 CmdBuildRoadVeh(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
_new_roadveh_id = v->index;
|
_new_roadveh_id = v->index;
|
||||||
|
|
||||||
v->string_id = STR_SV_ROADVEH_NAME;
|
v->string_id = STR_SV_ROADVEH_NAME;
|
||||||
*(v->schedule_ptr = _ptr_to_next_order++) = 0;
|
_ptr_to_next_order->type = OT_NOTHING;
|
||||||
|
_ptr_to_next_order->flags = 0;
|
||||||
|
v->schedule_ptr = _ptr_to_next_order++;
|
||||||
|
|
||||||
v->service_interval = _patches.servint_roadveh;
|
v->service_interval = _patches.servint_roadveh;
|
||||||
|
|
||||||
|
@ -300,11 +302,12 @@ int32 CmdSendRoadVehToDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
if (v->type != VEH_Road || !CheckOwnership(v->owner))
|
if (v->type != VEH_Road || !CheckOwnership(v->owner))
|
||||||
return CMD_ERROR;
|
return CMD_ERROR;
|
||||||
|
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
|
if (v->current_order.type == OT_GOTO_DEPOT) {
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
if (v->next_order & OF_UNLOAD)
|
if (v->current_order.flags & OF_UNLOAD)
|
||||||
v->cur_order_index++;
|
v->cur_order_index++;
|
||||||
v->next_order = OT_DUMMY;
|
v->current_order.type = OT_DUMMY;
|
||||||
|
v->current_order.flags = 0;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -315,8 +318,9 @@ int32 CmdSendRoadVehToDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
return_cmd_error(STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT);
|
return_cmd_error(STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT);
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
v->next_order = OF_NON_STOP | OF_FULL_LOAD | OT_GOTO_DEPOT;
|
v->current_order.type = OT_GOTO_DEPOT;
|
||||||
v->next_order_param = (byte)depot;
|
v->current_order.flags = OF_NON_STOP | OF_FULL_LOAD;
|
||||||
|
v->current_order.station = (byte)depot;
|
||||||
v->dest_tile = _depots[depot].xy;
|
v->dest_tile = _depots[depot].xy;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
|
@ -556,16 +560,18 @@ static void HandleBrokenRoadVeh(Vehicle *v)
|
||||||
|
|
||||||
static void ProcessRoadVehOrder(Vehicle *v)
|
static void ProcessRoadVehOrder(Vehicle *v)
|
||||||
{
|
{
|
||||||
uint order;
|
Order order;
|
||||||
Station *st;
|
Station *st;
|
||||||
|
|
||||||
if ((v->next_order & OT_MASK) >= OT_GOTO_DEPOT && (v->next_order & OT_MASK) <= OT_LEAVESTATION) {
|
if (v->current_order.type >= OT_GOTO_DEPOT && v->current_order.type <= OT_LEAVESTATION) {
|
||||||
// Let a depot order in the schedule interrupt.
|
// Let a depot order in the schedule interrupt.
|
||||||
if ((v->next_order & (OT_MASK|OF_UNLOAD)) != (OT_GOTO_DEPOT|OF_UNLOAD))
|
if (v->current_order.type != OT_GOTO_DEPOT ||
|
||||||
|
!(v->current_order.flags & OF_UNLOAD))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((v->next_order & (OT_MASK|OF_UNLOAD|OF_FULL_LOAD)) == (OT_GOTO_DEPOT|OF_UNLOAD|OF_FULL_LOAD) &&
|
if (v->current_order.type == OT_GOTO_DEPOT &&
|
||||||
|
(v->current_order.flags & (OF_UNLOAD | OF_FULL_LOAD)) == (OF_UNLOAD | OF_FULL_LOAD) &&
|
||||||
SERVICE_INTERVAL ) {
|
SERVICE_INTERVAL ) {
|
||||||
v->cur_order_index++;
|
v->cur_order_index++;
|
||||||
}
|
}
|
||||||
|
@ -575,27 +581,29 @@ static void ProcessRoadVehOrder(Vehicle *v)
|
||||||
|
|
||||||
order = v->schedule_ptr[v->cur_order_index];
|
order = v->schedule_ptr[v->cur_order_index];
|
||||||
|
|
||||||
if (order == 0) {
|
if (order.type == OT_NOTHING) {
|
||||||
v->next_order = OT_NOTHING;
|
v->current_order.type = OT_NOTHING;
|
||||||
|
v->current_order.flags = 0;
|
||||||
v->dest_tile = 0;
|
v->dest_tile = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (order == (uint)((v->next_order | (v->next_order_param<<8))))
|
if (order.type == v->current_order.type &&
|
||||||
|
order.flags == v->current_order.flags &&
|
||||||
|
order.station == v->current_order.station)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
v->next_order = (byte)order;
|
v->current_order = order;
|
||||||
v->next_order_param = (byte)(order >> 8);
|
|
||||||
|
|
||||||
v->dest_tile = 0;
|
v->dest_tile = 0;
|
||||||
|
|
||||||
if ((order & OT_MASK) == OT_GOTO_STATION) {
|
if (order.type == OT_GOTO_STATION) {
|
||||||
if ( (byte)(order >> 8) == v->last_station_visited)
|
if (order.station == v->last_station_visited)
|
||||||
v->last_station_visited = 0xFF;
|
v->last_station_visited = 0xFF;
|
||||||
st = DEREF_STATION(order >> 8);
|
st = DEREF_STATION(order.station);
|
||||||
v->dest_tile = v->cargo_type==CT_PASSENGERS ? st->bus_tile : st->lorry_tile;
|
v->dest_tile = v->cargo_type==CT_PASSENGERS ? st->bus_tile : st->lorry_tile;
|
||||||
} else if ((order & OT_MASK) == OT_GOTO_DEPOT) {
|
} else if (order.type == OT_GOTO_DEPOT) {
|
||||||
v->dest_tile = _depots[order >> 8].xy;
|
v->dest_tile = _depots[order.station].xy;
|
||||||
}
|
}
|
||||||
|
|
||||||
InvalidateVehicleOrderWidget(v);
|
InvalidateVehicleOrderWidget(v);
|
||||||
|
@ -603,17 +611,17 @@ static void ProcessRoadVehOrder(Vehicle *v)
|
||||||
|
|
||||||
static void HandleRoadVehLoading(Vehicle *v)
|
static void HandleRoadVehLoading(Vehicle *v)
|
||||||
{
|
{
|
||||||
if (v->next_order == OT_NOTHING)
|
if (v->current_order.type == OT_NOTHING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (v->next_order != OT_DUMMY) {
|
if (v->current_order.type != OT_DUMMY) {
|
||||||
if ((v->next_order&OT_MASK) != OT_LOADING)
|
if (v->current_order.type != OT_LOADING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (--v->load_unload_time_rem)
|
if (--v->load_unload_time_rem)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (v->next_order&OF_FULL_LOAD && CanFillVehicle(v)) {
|
if (v->current_order.flags & OF_FULL_LOAD && CanFillVehicle(v)) {
|
||||||
SET_EXPENSES_TYPE(EXPENSES_ROADVEH_INC);
|
SET_EXPENSES_TYPE(EXPENSES_ROADVEH_INC);
|
||||||
if (LoadUnloadVehicle(v)) {
|
if (LoadUnloadVehicle(v)) {
|
||||||
InvalidateWindow(WC_ROADVEH_LIST, v->owner);
|
InvalidateWindow(WC_ROADVEH_LIST, v->owner);
|
||||||
|
@ -623,9 +631,10 @@ static void HandleRoadVehLoading(Vehicle *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
byte b = v->next_order;
|
Order b = v->current_order;
|
||||||
v->next_order = OT_LEAVESTATION;
|
v->current_order.type = OT_LEAVESTATION;
|
||||||
if (!(b & OF_NON_STOP))
|
v->current_order.flags = 0;
|
||||||
|
if (!(b.flags & OF_NON_STOP))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1052,7 +1061,7 @@ static const byte _roadveh_data_2[4] = { 0,1,8,9 };
|
||||||
static void RoadVehEventHandler(Vehicle *v)
|
static void RoadVehEventHandler(Vehicle *v)
|
||||||
{
|
{
|
||||||
GetNewVehiclePosResult gp;
|
GetNewVehiclePosResult gp;
|
||||||
byte new_dir,old_dir,old_order;
|
byte new_dir, old_dir;
|
||||||
RoadDriveEntry rd;
|
RoadDriveEntry rd;
|
||||||
int x,y;
|
int x,y;
|
||||||
Station *st;
|
Station *st;
|
||||||
|
@ -1088,7 +1097,7 @@ static void RoadVehEventHandler(Vehicle *v)
|
||||||
ProcessRoadVehOrder(v);
|
ProcessRoadVehOrder(v);
|
||||||
HandleRoadVehLoading(v);
|
HandleRoadVehLoading(v);
|
||||||
|
|
||||||
if ((v->next_order & OT_MASK) == OT_LOADING)
|
if (v->current_order.type == OT_LOADING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (v->u.road.state == 254) {
|
if (v->u.road.state == 254) {
|
||||||
|
@ -1305,8 +1314,9 @@ again:
|
||||||
st = DEREF_STATION(_map2[v->tile]);
|
st = DEREF_STATION(_map2[v->tile]);
|
||||||
b = IS_BYTE_INSIDE(_map5[v->tile], 0x43, 0x47) ? &st->truck_stop_status : &st->bus_stop_status;
|
b = IS_BYTE_INSIDE(_map5[v->tile], 0x43, 0x47) ? &st->truck_stop_status : &st->bus_stop_status;
|
||||||
|
|
||||||
if ( (v->next_order&OT_MASK) != OT_LEAVESTATION &&
|
if (v->current_order.type != OT_LEAVESTATION &&
|
||||||
(v->next_order&OT_MASK) != OT_GOTO_DEPOT) {
|
v->current_order.type != OT_GOTO_DEPOT) {
|
||||||
|
Order old_order;
|
||||||
|
|
||||||
*b &= ~0x80;
|
*b &= ~0x80;
|
||||||
|
|
||||||
|
@ -1314,12 +1324,14 @@ again:
|
||||||
|
|
||||||
RoadVehArrivesAt(v, st);
|
RoadVehArrivesAt(v, st);
|
||||||
|
|
||||||
old_order = v->next_order;
|
old_order = v->current_order;
|
||||||
v->next_order = OT_LOADING;
|
v->current_order.type = OT_LOADING;
|
||||||
|
v->current_order.flags = 0;
|
||||||
|
|
||||||
if ((old_order & OT_MASK) == OT_GOTO_STATION &&
|
if (old_order.type == OT_GOTO_STATION &&
|
||||||
v->next_order_param == v->last_station_visited) {
|
v->current_order.station == v->last_station_visited) {
|
||||||
v->next_order = OT_LOADING | OF_NON_STOP | (old_order & (OF_FULL_LOAD|OF_UNLOAD));
|
v->current_order.flags =
|
||||||
|
(old_order.flags & (OF_FULL_LOAD | OF_UNLOAD)) | OF_NON_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_EXPENSES_TYPE(EXPENSES_ROADVEH_INC);
|
SET_EXPENSES_TYPE(EXPENSES_ROADVEH_INC);
|
||||||
|
@ -1331,12 +1343,13 @@ again:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((v->next_order & OT_MASK) != OT_GOTO_DEPOT) {
|
if (v->current_order.type != OT_GOTO_DEPOT) {
|
||||||
if (*b&0x80) {
|
if (*b&0x80) {
|
||||||
v->cur_speed = 0;
|
v->cur_speed = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
v->next_order = 0;
|
v->current_order.type = OT_NOTHING;
|
||||||
|
v->current_order.flags = 0;
|
||||||
}
|
}
|
||||||
*b |= 0x80;
|
*b |= 0x80;
|
||||||
|
|
||||||
|
@ -1361,8 +1374,6 @@ again:
|
||||||
|
|
||||||
void RoadVehEnterDepot(Vehicle *v)
|
void RoadVehEnterDepot(Vehicle *v)
|
||||||
{
|
{
|
||||||
byte t;
|
|
||||||
|
|
||||||
v->u.road.state = 254;
|
v->u.road.state = 254;
|
||||||
v->vehstatus |= VS_HIDDEN;
|
v->vehstatus |= VS_HIDDEN;
|
||||||
|
|
||||||
|
@ -1375,16 +1386,19 @@ void RoadVehEnterDepot(Vehicle *v)
|
||||||
|
|
||||||
TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
|
TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
|
||||||
|
|
||||||
if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT) {
|
if (v->current_order.type == OT_GOTO_DEPOT) {
|
||||||
|
Order t;
|
||||||
|
|
||||||
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
||||||
|
|
||||||
t = v->next_order;
|
t = v->current_order;
|
||||||
v->next_order = OT_DUMMY;
|
v->current_order.type = OT_DUMMY;
|
||||||
|
v->current_order.flags = 0;
|
||||||
|
|
||||||
// Part of the schedule?
|
// Part of the schedule?
|
||||||
if (t & OF_UNLOAD) { v->cur_order_index++; }
|
if (t.flags & OF_UNLOAD) {
|
||||||
|
v->cur_order_index++;
|
||||||
else if (t & OF_FULL_LOAD) {
|
} else if (t.flags & OF_FULL_LOAD) {
|
||||||
v->vehstatus |= VS_STOPPED;
|
v->vehstatus |= VS_STOPPED;
|
||||||
if (v->owner == _local_player) {
|
if (v->owner == _local_player) {
|
||||||
SetDParam(0, v->unitnumber);
|
SetDParam(0, v->unitnumber);
|
||||||
|
@ -1432,25 +1446,29 @@ static void CheckIfRoadVehNeedsService(Vehicle *v)
|
||||||
|
|
||||||
// Don't interfere with a depot visit scheduled by the user, or a
|
// Don't interfere with a depot visit scheduled by the user, or a
|
||||||
// depot visit by the order list.
|
// depot visit by the order list.
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT &&
|
if (v->current_order.type == OT_GOTO_DEPOT &&
|
||||||
(v->next_order & (OF_FULL_LOAD|OF_UNLOAD)) != 0)
|
(v->current_order.flags & (OF_FULL_LOAD | OF_UNLOAD)) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
i = FindClosestRoadDepot(v);
|
i = FindClosestRoadDepot(v);
|
||||||
|
|
||||||
if (i < 0 || GetTileDist(v->tile, (&_depots[i])->xy) > 12) {
|
if (i < 0 || GetTileDist(v->tile, (&_depots[i])->xy) > 12) {
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
|
if (v->current_order.type == OT_GOTO_DEPOT) {
|
||||||
v->next_order = OT_DUMMY;
|
v->current_order.type = OT_DUMMY;
|
||||||
|
v->current_order.flags = 0;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v->next_order == (OT_GOTO_DEPOT | OF_NON_STOP) && !CHANCE16(1,20))
|
if (v->current_order.type == OT_GOTO_DEPOT &&
|
||||||
|
v->current_order.flags & OF_NON_STOP &&
|
||||||
|
!CHANCE16(1,20))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
v->next_order = OT_GOTO_DEPOT | OF_NON_STOP;
|
v->current_order.type = OT_GOTO_DEPOT;
|
||||||
v->next_order_param = (byte)i;
|
v->current_order.flags = OF_NON_STOP;
|
||||||
|
v->current_order.station = (byte)i;
|
||||||
v->dest_tile = (&_depots[i])->xy;
|
v->dest_tile = (&_depots[i])->xy;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
|
@ -1473,8 +1491,8 @@ void OnNewDay_RoadVeh(Vehicle *v)
|
||||||
CheckOrders(v);
|
CheckOrders(v);
|
||||||
|
|
||||||
/* update destination */
|
/* update destination */
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_STATION) {
|
if (v->current_order.type == OT_GOTO_STATION) {
|
||||||
st = DEREF_STATION(v->next_order_param);
|
st = DEREF_STATION(v->current_order.station);
|
||||||
if ((tile=(v->cargo_type==CT_PASSENGERS ? st->bus_tile : st->lorry_tile)) != 0)
|
if ((tile=(v->cargo_type==CT_PASSENGERS ? st->bus_tile : st->lorry_tile)) != 0)
|
||||||
v->dest_tile = tile;
|
v->dest_tile = tile;
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,15 +204,15 @@ static void RoadVehViewWndProc(Window *w, WindowEvent *e)
|
||||||
} else if (v->vehstatus & VS_STOPPED) {
|
} else if (v->vehstatus & VS_STOPPED) {
|
||||||
str = STR_8861_STOPPED;
|
str = STR_8861_STOPPED;
|
||||||
} else {
|
} else {
|
||||||
switch(v->next_order & OT_MASK) {
|
switch (v->current_order.type) {
|
||||||
case OT_GOTO_STATION: {
|
case OT_GOTO_STATION: {
|
||||||
SetDParam(0, v->next_order_param);
|
SetDParam(0, v->current_order.station);
|
||||||
SetDParam(1, v->cur_speed * 10 >> 5);
|
SetDParam(1, v->cur_speed * 10 >> 5);
|
||||||
str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
|
str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case OT_GOTO_DEPOT: {
|
case OT_GOTO_DEPOT: {
|
||||||
Depot *dep = &_depots[v->next_order_param];
|
Depot *dep = &_depots[v->current_order.station];
|
||||||
SetDParam(0, dep->town_index);
|
SetDParam(0, dep->town_index);
|
||||||
SetDParam(1, v->cur_speed * 10 >> 5);
|
SetDParam(1, v->cur_speed * 10 >> 5);
|
||||||
str = STR_HEADING_FOR_ROAD_DEPOT + _patches.vehicle_speed;
|
str = STR_HEADING_FOR_ROAD_DEPOT + _patches.vehicle_speed;
|
||||||
|
|
116
ship_cmd.c
116
ship_cmd.c
|
@ -95,7 +95,8 @@ static void CheckIfShipNeedsService(Vehicle *v)
|
||||||
if (v->vehstatus & VS_STOPPED)
|
if (v->vehstatus & VS_STOPPED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((v->next_order & (OT_MASK | OF_FULL_LOAD)) == (OT_GOTO_DEPOT | OF_FULL_LOAD))
|
if (v->current_order.type == OT_GOTO_DEPOT &&
|
||||||
|
v->current_order.flags & OF_FULL_LOAD)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_patches.gotodepot && ScheduleHasDepotOrders(v->schedule_ptr))
|
if (_patches.gotodepot && ScheduleHasDepotOrders(v->schedule_ptr))
|
||||||
|
@ -104,15 +105,17 @@ static void CheckIfShipNeedsService(Vehicle *v)
|
||||||
i = FindClosestShipDepot(v);
|
i = FindClosestShipDepot(v);
|
||||||
|
|
||||||
if (i < 0 || GetTileDist(v->tile, (&_depots[i])->xy) > 12) {
|
if (i < 0 || GetTileDist(v->tile, (&_depots[i])->xy) > 12) {
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
|
if (v->current_order.type == OT_GOTO_DEPOT) {
|
||||||
v->next_order = OT_DUMMY;
|
v->current_order.type = OT_DUMMY;
|
||||||
|
v->current_order.flags = 0;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
v->next_order = OT_GOTO_DEPOT | OF_NON_STOP;
|
v->current_order.type = OT_GOTO_DEPOT;
|
||||||
v->next_order_param = (byte)i;
|
v->current_order.flags = OF_NON_STOP;
|
||||||
|
v->current_order.station = (byte)i;
|
||||||
v->dest_tile = (&_depots[i])->xy;
|
v->dest_tile = (&_depots[i])->xy;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
|
@ -199,15 +202,18 @@ static const TileIndexDiff _dock_offs[] = {
|
||||||
|
|
||||||
static void ProcessShipOrder(Vehicle *v)
|
static void ProcessShipOrder(Vehicle *v)
|
||||||
{
|
{
|
||||||
uint order;
|
Order order;
|
||||||
Station *st;
|
Station *st;
|
||||||
|
|
||||||
if ((v->next_order & OT_MASK) >= OT_GOTO_DEPOT && (v->next_order & OT_MASK) <= OT_LEAVESTATION) {
|
if (v->current_order.type >= OT_GOTO_DEPOT &&
|
||||||
if ((v->next_order & (OT_MASK|OF_UNLOAD)) != (OT_GOTO_DEPOT|OF_UNLOAD))
|
v->current_order.type <= OT_LEAVESTATION) {
|
||||||
|
if (v->current_order.type != OT_GOTO_DEPOT ||
|
||||||
|
!(v->current_order.flags & OF_UNLOAD))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((v->next_order & (OT_MASK|OF_UNLOAD|OF_FULL_LOAD)) == (OT_GOTO_DEPOT|OF_UNLOAD|OF_FULL_LOAD) &&
|
if (v->current_order.type == OT_GOTO_DEPOT &&
|
||||||
|
(v->current_order.flags & (OF_UNLOAD | OF_FULL_LOAD)) == (OF_UNLOAD | OF_FULL_LOAD) &&
|
||||||
SERVICE_INTERVAL) {
|
SERVICE_INTERVAL) {
|
||||||
v->cur_order_index++;
|
v->cur_order_index++;
|
||||||
}
|
}
|
||||||
|
@ -218,28 +224,30 @@ static void ProcessShipOrder(Vehicle *v)
|
||||||
|
|
||||||
order = v->schedule_ptr[v->cur_order_index];
|
order = v->schedule_ptr[v->cur_order_index];
|
||||||
|
|
||||||
if (order == 0) {
|
if (order.type == OT_NOTHING) {
|
||||||
v->next_order = OT_NOTHING;
|
v->current_order.type = OT_NOTHING;
|
||||||
|
v->current_order.flags = 0;
|
||||||
v->dest_tile = 0;
|
v->dest_tile = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (order == (uint)((v->next_order | (v->next_order_param<<8))))
|
if (order.type == v->current_order.type &&
|
||||||
|
order.flags == v->current_order.flags &&
|
||||||
|
order.station == v->current_order.station)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
v->next_order = (byte)order;
|
v->current_order = order;
|
||||||
v->next_order_param = (byte)(order >> 8);
|
|
||||||
|
|
||||||
if ((order & OT_MASK) == OT_GOTO_STATION) {
|
if (order.type == OT_GOTO_STATION) {
|
||||||
if ( (byte)(order >> 8) == v->last_station_visited)
|
if (order.station == v->last_station_visited)
|
||||||
v->last_station_visited = 0xFF;
|
v->last_station_visited = 0xFF;
|
||||||
|
|
||||||
st = DEREF_STATION(order >> 8);
|
st = DEREF_STATION(order.station);
|
||||||
if (st->dock_tile != 0) {
|
if (st->dock_tile != 0) {
|
||||||
v->dest_tile = TILE_ADD(st->dock_tile, _dock_offs[_map5[st->dock_tile]-0x4B]);
|
v->dest_tile = TILE_ADD(st->dock_tile, _dock_offs[_map5[st->dock_tile]-0x4B]);
|
||||||
}
|
}
|
||||||
} else if ((order & OT_MASK) == OT_GOTO_DEPOT) {
|
} else if (order.type == OT_GOTO_DEPOT) {
|
||||||
v->dest_tile = _depots[order >> 8].xy;
|
v->dest_tile = _depots[order.station].xy;
|
||||||
} else {
|
} else {
|
||||||
v->dest_tile = 0;
|
v->dest_tile = 0;
|
||||||
}
|
}
|
||||||
|
@ -248,17 +256,17 @@ static void ProcessShipOrder(Vehicle *v)
|
||||||
|
|
||||||
static void HandleShipLoading(Vehicle *v)
|
static void HandleShipLoading(Vehicle *v)
|
||||||
{
|
{
|
||||||
if (v->next_order == OT_NOTHING)
|
if (v->current_order.type == OT_NOTHING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (v->next_order != OT_DUMMY) {
|
if (v->current_order.type != OT_DUMMY) {
|
||||||
if ((v->next_order&OT_MASK) != OT_LOADING)
|
if (v->current_order.type != OT_LOADING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (--v->load_unload_time_rem)
|
if (--v->load_unload_time_rem)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (v->next_order&OF_FULL_LOAD && CanFillVehicle(v)) {
|
if (v->current_order.flags & OF_FULL_LOAD && CanFillVehicle(v)) {
|
||||||
SET_EXPENSES_TYPE(EXPENSES_SHIP_INC);
|
SET_EXPENSES_TYPE(EXPENSES_SHIP_INC);
|
||||||
if (LoadUnloadVehicle(v)) {
|
if (LoadUnloadVehicle(v)) {
|
||||||
InvalidateWindow(WC_SHIPS_LIST, v->owner);
|
InvalidateWindow(WC_SHIPS_LIST, v->owner);
|
||||||
|
@ -269,9 +277,10 @@ static void HandleShipLoading(Vehicle *v)
|
||||||
PlayShipSound(v);
|
PlayShipSound(v);
|
||||||
|
|
||||||
{
|
{
|
||||||
byte b = v->next_order;
|
Order b = v->current_order;
|
||||||
v->next_order = OT_LEAVESTATION;
|
v->current_order.type = OT_LEAVESTATION;
|
||||||
if (!(b & OF_NON_STOP))
|
v->current_order.flags = 0;
|
||||||
|
if (!(b.flags & OF_NON_STOP))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -380,8 +389,6 @@ static int32 EstimateShipCost(uint16 engine_type);
|
||||||
|
|
||||||
static void ShipEnterDepot(Vehicle *v)
|
static void ShipEnterDepot(Vehicle *v)
|
||||||
{
|
{
|
||||||
byte t;
|
|
||||||
|
|
||||||
v->u.ship.state = 0x80;
|
v->u.ship.state = 0x80;
|
||||||
v->vehstatus |= VS_HIDDEN;
|
v->vehstatus |= VS_HIDDEN;
|
||||||
v->cur_speed = 0;
|
v->cur_speed = 0;
|
||||||
|
@ -396,15 +403,18 @@ static void ShipEnterDepot(Vehicle *v)
|
||||||
|
|
||||||
TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
|
TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
|
||||||
|
|
||||||
if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT) {
|
if (v->current_order.type == OT_GOTO_DEPOT) {
|
||||||
|
Order t;
|
||||||
|
|
||||||
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
||||||
|
|
||||||
t = v->next_order;
|
t = v->current_order;
|
||||||
v->next_order = OT_DUMMY;
|
v->current_order.type = OT_DUMMY;
|
||||||
|
v->current_order.flags = 0;
|
||||||
|
|
||||||
if (t&OF_UNLOAD) { v->cur_order_index++; }
|
if (t.flags & OF_UNLOAD) {
|
||||||
|
v->cur_order_index++;
|
||||||
else if (t & 0x40) {
|
} else if (t.flags & OF_FULL_LOAD) {
|
||||||
v->vehstatus |= VS_STOPPED;
|
v->vehstatus |= VS_STOPPED;
|
||||||
if (v->owner == _local_player) {
|
if (v->owner == _local_player) {
|
||||||
SetDParam(0, v->unitnumber);
|
SetDParam(0, v->unitnumber);
|
||||||
|
@ -636,7 +646,7 @@ static void ShipController(Vehicle *v)
|
||||||
ProcessShipOrder(v);
|
ProcessShipOrder(v);
|
||||||
HandleShipLoading(v);
|
HandleShipLoading(v);
|
||||||
|
|
||||||
if ((v->next_order & OT_MASK) == OT_LOADING)
|
if (v->current_order.type == OT_LOADING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CheckShipLeaveDepot(v);
|
CheckShipLeaveDepot(v);
|
||||||
|
@ -657,21 +667,23 @@ static void ShipController(Vehicle *v)
|
||||||
if (r & 0x8) goto reverse_direction;
|
if (r & 0x8) goto reverse_direction;
|
||||||
|
|
||||||
if (v->dest_tile != 0 && v->dest_tile == gp.new_tile) {
|
if (v->dest_tile != 0 && v->dest_tile == gp.new_tile) {
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
|
if (v->current_order.type == OT_GOTO_DEPOT) {
|
||||||
if ((gp.x&0xF)==8 && (gp.y&0xF)==8) {
|
if ((gp.x&0xF)==8 && (gp.y&0xF)==8) {
|
||||||
ShipEnterDepot(v);
|
ShipEnterDepot(v);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if ((v->next_order & OT_MASK) == OT_GOTO_STATION) {
|
} else if (v->current_order.type == OT_GOTO_STATION) {
|
||||||
Station *st;
|
Station *st;
|
||||||
|
|
||||||
v->last_station_visited = v->next_order_param;
|
v->last_station_visited = v->current_order.station;
|
||||||
|
|
||||||
/* Process station in the schedule. Don't do that for buoys (HVOT_BUOY) */
|
/* Process station in the schedule. Don't do that for buoys (HVOT_BUOY) */
|
||||||
st = DEREF_STATION(v->next_order_param);
|
st = DEREF_STATION(v->current_order.station);
|
||||||
if (!(st->had_vehicle_of_type & HVOT_BUOY)
|
if (!(st->had_vehicle_of_type & HVOT_BUOY)
|
||||||
&& (st->facilities & FACIL_DOCK)) { /* ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations */
|
&& (st->facilities & FACIL_DOCK)) { /* ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations */
|
||||||
v->next_order = (v->next_order & (OF_FULL_LOAD|OF_UNLOAD)) | OF_NON_STOP | OT_LOADING;
|
v->current_order.type = OT_LOADING;
|
||||||
|
v->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD;
|
||||||
|
v->current_order.flags |= OF_NON_STOP;
|
||||||
ShipArrivesAt(v, st);
|
ShipArrivesAt(v, st);
|
||||||
|
|
||||||
SET_EXPENSES_TYPE(EXPENSES_SHIP_INC);
|
SET_EXPENSES_TYPE(EXPENSES_SHIP_INC);
|
||||||
|
@ -681,7 +693,8 @@ static void ShipController(Vehicle *v)
|
||||||
}
|
}
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
} else { /* leave buoys right aways */
|
} else { /* leave buoys right aways */
|
||||||
v->next_order = OT_LEAVESTATION;
|
v->current_order.type = OT_LEAVESTATION;
|
||||||
|
v->current_order.flags = 0;
|
||||||
v->cur_order_index++;
|
v->cur_order_index++;
|
||||||
InvalidateVehicleOrderWidget(v);
|
InvalidateVehicleOrderWidget(v);
|
||||||
}
|
}
|
||||||
|
@ -689,8 +702,9 @@ static void ShipController(Vehicle *v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v->next_order == OT_LEAVESTATION) {
|
if (v->current_order.type == OT_LEAVESTATION) {
|
||||||
v->next_order = OT_NOTHING;
|
v->current_order.type = OT_NOTHING;
|
||||||
|
v->current_order.flags = 0;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -843,7 +857,9 @@ int32 CmdBuildShip(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
|
|
||||||
v->string_id = STR_SV_SHIP_NAME;
|
v->string_id = STR_SV_SHIP_NAME;
|
||||||
v->u.ship.state = 0x80;
|
v->u.ship.state = 0x80;
|
||||||
*(v->schedule_ptr = _ptr_to_next_order++) = 0;
|
_ptr_to_next_order->type = OT_NOTHING;
|
||||||
|
_ptr_to_next_order->flags = 0;
|
||||||
|
v->schedule_ptr = _ptr_to_next_order++;
|
||||||
|
|
||||||
v->service_interval = _patches.servint_ships;
|
v->service_interval = _patches.servint_ships;
|
||||||
v->date_of_last_service = _date;
|
v->date_of_last_service = _date;
|
||||||
|
@ -917,10 +933,11 @@ int32 CmdSendShipToDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
if (!CheckOwnership(v->owner))
|
if (!CheckOwnership(v->owner))
|
||||||
return CMD_ERROR;
|
return CMD_ERROR;
|
||||||
|
|
||||||
if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT) {
|
if (v->current_order.type == OT_GOTO_DEPOT) {
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
if (v->next_order&OF_UNLOAD) {v->cur_order_index++;}
|
if (v->current_order.flags & OF_UNLOAD) v->cur_order_index++;
|
||||||
v->next_order = OT_DUMMY;
|
v->current_order.type = OT_DUMMY;
|
||||||
|
v->current_order.flags = 0;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -930,8 +947,9 @@ int32 CmdSendShipToDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
v->dest_tile = _depots[depot].xy;
|
v->dest_tile = _depots[depot].xy;
|
||||||
v->next_order = OF_NON_STOP | OF_FULL_LOAD | OT_GOTO_DEPOT;
|
v->current_order.type = OT_GOTO_DEPOT;
|
||||||
v->next_order_param = depot;
|
v->current_order.flags = OF_NON_STOP | OF_FULL_LOAD;
|
||||||
|
v->current_order.station = depot;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
18
ship_gui.c
18
ship_gui.c
|
@ -498,15 +498,15 @@ static void ShipViewWndProc(Window *w, WindowEvent *e) {
|
||||||
} else if (v->vehstatus & VS_STOPPED) {
|
} else if (v->vehstatus & VS_STOPPED) {
|
||||||
str = STR_8861_STOPPED;
|
str = STR_8861_STOPPED;
|
||||||
} else {
|
} else {
|
||||||
switch(v->next_order & OT_MASK) {
|
switch (v->current_order.type) {
|
||||||
case OT_GOTO_STATION: {
|
case OT_GOTO_STATION: {
|
||||||
SetDParam(0, v->next_order_param);
|
SetDParam(0, v->current_order.station);
|
||||||
SetDParam(1, v->cur_speed * 10 >> 5);
|
SetDParam(1, v->cur_speed * 10 >> 5);
|
||||||
str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
|
str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case OT_GOTO_DEPOT: {
|
case OT_GOTO_DEPOT: {
|
||||||
Depot *dep = &_depots[v->next_order_param];
|
Depot *dep = &_depots[v->current_order.station];
|
||||||
SetDParam(0, dep->town_index);
|
SetDParam(0, dep->town_index);
|
||||||
SetDParam(1, v->cur_speed * 10 >> 5);
|
SetDParam(1, v->cur_speed * 10 >> 5);
|
||||||
str = STR_HEADING_FOR_SHIP_DEPOT + _patches.vehicle_speed;
|
str = STR_HEADING_FOR_SHIP_DEPOT + _patches.vehicle_speed;
|
||||||
|
@ -836,16 +836,14 @@ void ShowShipDepotWindow(uint tile)
|
||||||
|
|
||||||
|
|
||||||
static void DrawSmallShipSchedule(Vehicle *v, int x, int y) {
|
static void DrawSmallShipSchedule(Vehicle *v, int x, int y) {
|
||||||
uint16 *sched;
|
Order *sched;
|
||||||
int sel;
|
int sel;
|
||||||
uint ord;
|
|
||||||
Station *st;
|
Station *st;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
sched = v->schedule_ptr;
|
|
||||||
sel = v->cur_order_index;
|
sel = v->cur_order_index;
|
||||||
|
|
||||||
while ((ord=*sched++) != 0) {
|
for (sched = v->schedule_ptr; sched->type != OT_NOTHING; ++sched) {
|
||||||
if (sel == 0) {
|
if (sel == 0) {
|
||||||
_stringwidth_base = 0xE0;
|
_stringwidth_base = 0xE0;
|
||||||
DoDrawString( "\xAF", x-6, y, 16);
|
DoDrawString( "\xAF", x-6, y, 16);
|
||||||
|
@ -853,11 +851,11 @@ static void DrawSmallShipSchedule(Vehicle *v, int x, int y) {
|
||||||
}
|
}
|
||||||
sel--;
|
sel--;
|
||||||
|
|
||||||
if ((ord & OT_MASK) == OT_GOTO_STATION) {
|
if (sched->type == OT_GOTO_STATION) {
|
||||||
st = DEREF_STATION(ord >> 8);
|
st = DEREF_STATION(sched->station);
|
||||||
|
|
||||||
if (!(st->had_vehicle_of_type & HVOT_BUOY)) {
|
if (!(st->had_vehicle_of_type & HVOT_BUOY)) {
|
||||||
SetDParam(0, ord >> 8);
|
SetDParam(0, sched->station);
|
||||||
DrawString(x, y, STR_A036, 0);
|
DrawString(x, y, STR_A036, 0);
|
||||||
|
|
||||||
y += 6;
|
y += 6;
|
||||||
|
|
|
@ -2139,10 +2139,12 @@ static uint32 VehicleEnter_Station(Vehicle *v, uint tile, int x, int y)
|
||||||
!IsTrainStationTile(tile + _tileoffs_by_dir[v->direction >> 1])) {
|
!IsTrainStationTile(tile + _tileoffs_by_dir[v->direction >> 1])) {
|
||||||
|
|
||||||
station_id = _map2[tile];
|
station_id = _map2[tile];
|
||||||
if ((!(v->next_order & OF_NON_STOP) && !_patches.new_nonstop) ||
|
if ((!(v->current_order.flags & OF_NON_STOP) && !_patches.new_nonstop) ||
|
||||||
(((v->next_order & OT_MASK) == OT_GOTO_STATION && v->next_order_param == station_id))) {
|
(v->current_order.type == OT_GOTO_STATION && v->current_order.station == station_id)) {
|
||||||
|
|
||||||
if (!(_patches.new_nonstop && (v->next_order & OF_NON_STOP)) && v->next_order != OT_LEAVESTATION && v->last_station_visited != station_id) {
|
if (!(_patches.new_nonstop && v->current_order.flags & OF_NON_STOP) &&
|
||||||
|
v->current_order.type != OT_LEAVESTATION &&
|
||||||
|
v->last_station_visited != station_id) {
|
||||||
x &= 0xF;
|
x &= 0xF;
|
||||||
y &= 0xF;
|
y &= 0xF;
|
||||||
|
|
||||||
|
@ -2199,6 +2201,7 @@ static uint32 VehicleEnter_Station(Vehicle *v, uint tile, int x, int y)
|
||||||
|
|
||||||
static void DeleteStation(Station *st)
|
static void DeleteStation(Station *st)
|
||||||
{
|
{
|
||||||
|
Order order;
|
||||||
int index;
|
int index;
|
||||||
st->xy = 0;
|
st->xy = 0;
|
||||||
|
|
||||||
|
@ -2209,7 +2212,10 @@ static void DeleteStation(Station *st)
|
||||||
|
|
||||||
index = st->index;
|
index = st->index;
|
||||||
DeleteWindowById(WC_STATION_VIEW, index);
|
DeleteWindowById(WC_STATION_VIEW, index);
|
||||||
DeleteCommandFromVehicleSchedule((index << 8) + OT_GOTO_STATION);
|
order.type = OT_GOTO_STATION;
|
||||||
|
order.flags = 0;
|
||||||
|
order.station = index;
|
||||||
|
DeleteCommandFromVehicleSchedule(order);
|
||||||
DeleteSubsidyWithStation(index);
|
DeleteSubsidyWithStation(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
153
train_cmd.c
153
train_cmd.c
|
@ -425,7 +425,7 @@ int32 CmdBuildRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
// v->cargo_count = 0;
|
// v->cargo_count = 0;
|
||||||
v->value = value;
|
v->value = value;
|
||||||
// v->day_counter = 0;
|
// v->day_counter = 0;
|
||||||
// v->next_order = 0;
|
// v->current_order = 0;
|
||||||
// v->next_station = 0;
|
// v->next_station = 0;
|
||||||
// v->load_unload_time_rem = 0;
|
// v->load_unload_time_rem = 0;
|
||||||
// v->progress = 0;
|
// v->progress = 0;
|
||||||
|
@ -451,7 +451,9 @@ int32 CmdBuildRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
// v->cur_order_index = 0;
|
// v->cur_order_index = 0;
|
||||||
// v->num_orders = 0;
|
// v->num_orders = 0;
|
||||||
|
|
||||||
*(v->schedule_ptr = _ptr_to_next_order++) = 0;
|
_ptr_to_next_order->type = OT_NOTHING;
|
||||||
|
_ptr_to_next_order->flags = 0;
|
||||||
|
v->schedule_ptr = _ptr_to_next_order++;
|
||||||
// v->next_in_chain = 0xffff;
|
// v->next_in_chain = 0xffff;
|
||||||
// v->next = NULL;
|
// v->next = NULL;
|
||||||
|
|
||||||
|
@ -682,7 +684,9 @@ int32 CmdMoveRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
// setting the type to 0 also involves setting up the schedule_ptr field.
|
// setting the type to 0 also involves setting up the schedule_ptr field.
|
||||||
src->subtype = 0;
|
src->subtype = 0;
|
||||||
assert(src->schedule_ptr == NULL);
|
assert(src->schedule_ptr == NULL);
|
||||||
*(src->schedule_ptr = _ptr_to_next_order++) = 0;
|
_ptr_to_next_order->type = OT_NOTHING;
|
||||||
|
_ptr_to_next_order->flags = 0;
|
||||||
|
src->schedule_ptr = _ptr_to_next_order++;
|
||||||
src->num_orders = 0;
|
src->num_orders = 0;
|
||||||
}
|
}
|
||||||
dst_head = src;
|
dst_head = src;
|
||||||
|
@ -1138,14 +1142,15 @@ int32 CmdTrainGotoDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
Vehicle *v = &_vehicles[p1];
|
Vehicle *v = &_vehicles[p1];
|
||||||
TrainFindDepotData tfdd;
|
TrainFindDepotData tfdd;
|
||||||
|
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
|
if (v->current_order.type == OT_GOTO_DEPOT) {
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
if (v->next_order & OF_UNLOAD) {
|
if (v->current_order.flags & OF_UNLOAD) {
|
||||||
v->u.rail.days_since_order_progr = 0;
|
v->u.rail.days_since_order_progr = 0;
|
||||||
v->cur_order_index++;
|
v->cur_order_index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
v->next_order = OT_DUMMY;
|
v->current_order.type = OT_DUMMY;
|
||||||
|
v->current_order.flags = 0;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1157,8 +1162,9 @@ int32 CmdTrainGotoDepot(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
v->dest_tile = tfdd.tile;
|
v->dest_tile = tfdd.tile;
|
||||||
v->next_order = OF_NON_STOP | OF_FULL_LOAD | OT_GOTO_DEPOT;
|
v->current_order.type = OT_GOTO_DEPOT;
|
||||||
v->next_order_param = GetDepotByTile(tfdd.tile);
|
v->current_order.flags = OF_NON_STOP | OF_FULL_LOAD;
|
||||||
|
v->current_order.station = GetDepotByTile(tfdd.tile);
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1364,8 +1370,8 @@ static bool TrainTrackFollower(uint tile, TrainTrackFollowerData *ttfd, int trac
|
||||||
static void FillWithStationData(TrainTrackFollowerData *fd, Vehicle *v)
|
static void FillWithStationData(TrainTrackFollowerData *fd, Vehicle *v)
|
||||||
{
|
{
|
||||||
fd->dest_coords = v->dest_tile;
|
fd->dest_coords = v->dest_tile;
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_STATION)
|
if (v->current_order.type == OT_GOTO_STATION)
|
||||||
fd->station_index = v->next_order_param;
|
fd->station_index = v->current_order.station;
|
||||||
else
|
else
|
||||||
fd->station_index = -1;
|
fd->station_index = -1;
|
||||||
|
|
||||||
|
@ -1570,29 +1576,32 @@ bad:;
|
||||||
|
|
||||||
static bool ProcessTrainOrder(Vehicle *v)
|
static bool ProcessTrainOrder(Vehicle *v)
|
||||||
{
|
{
|
||||||
uint order;
|
Order order;
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
// These are un-interruptible
|
// These are un-interruptible
|
||||||
if ((v->next_order & OT_MASK) >= OT_GOTO_DEPOT && (v->next_order & OT_MASK) <= OT_LEAVESTATION) {
|
if (v->current_order.type >= OT_GOTO_DEPOT &&
|
||||||
|
v->current_order.type <= OT_LEAVESTATION) {
|
||||||
// Let a depot order in the schedule interrupt.
|
// Let a depot order in the schedule interrupt.
|
||||||
if ((v->next_order & (OT_MASK|OF_UNLOAD)) != (OT_GOTO_DEPOT|OF_UNLOAD))
|
if (v->current_order.type != OT_GOTO_DEPOT ||
|
||||||
|
!(v->current_order.flags & OF_UNLOAD))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((v->next_order & (OT_MASK|OF_UNLOAD|OF_FULL_LOAD)) == (OT_GOTO_DEPOT|OF_UNLOAD|OF_FULL_LOAD) &&
|
if (v->current_order.type == OT_GOTO_DEPOT &&
|
||||||
|
(v->current_order.flags & (OF_UNLOAD | OF_FULL_LOAD)) == (OF_UNLOAD | OF_FULL_LOAD) &&
|
||||||
SERVICE_INTERVAL) {
|
SERVICE_INTERVAL) {
|
||||||
v->cur_order_index++;
|
v->cur_order_index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we've reached the waypoint?
|
// check if we've reached the waypoint?
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_WAYPOINT && v->tile == v->dest_tile) {
|
if (v->current_order.type == OT_GOTO_WAYPOINT && v->tile == v->dest_tile) {
|
||||||
v->cur_order_index++;
|
v->cur_order_index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we've reached a non-stop station while TTDPatch nonstop is enabled..
|
// check if we've reached a non-stop station while TTDPatch nonstop is enabled..
|
||||||
if (_patches.new_nonstop && (v->next_order & OF_NON_STOP) && v->next_order_param == _map2[v->tile]) {
|
if (_patches.new_nonstop && v->current_order.flags & OF_NON_STOP &&
|
||||||
|
v->current_order.station == _map2[v->tile]) {
|
||||||
v->cur_order_index++;
|
v->cur_order_index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1602,33 +1611,35 @@ static bool ProcessTrainOrder(Vehicle *v)
|
||||||
order = v->schedule_ptr[v->cur_order_index];
|
order = v->schedule_ptr[v->cur_order_index];
|
||||||
|
|
||||||
// If no order, do nothing.
|
// If no order, do nothing.
|
||||||
if (order == 0) {
|
if (order.type == OT_NOTHING) {
|
||||||
v->next_order = OT_NOTHING;
|
v->current_order.type = OT_NOTHING;
|
||||||
|
v->current_order.flags = 0;
|
||||||
v->dest_tile = 0;
|
v->dest_tile = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it is unchanged, keep it.
|
// If it is unchanged, keep it.
|
||||||
if (order == (uint)((v->next_order | (v->next_order_param<<8))))
|
if (order.type == v->current_order.type &&
|
||||||
|
order.flags == v->current_order.flags &&
|
||||||
|
order.station == v->current_order.station)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Otherwise set it, and determine the destination tile.
|
// Otherwise set it, and determine the destination tile.
|
||||||
v->next_order = (byte)order;
|
v->current_order = order;
|
||||||
v->next_order_param = (byte)(order >> 8);
|
|
||||||
|
|
||||||
v->dest_tile = 0;
|
v->dest_tile = 0;
|
||||||
|
|
||||||
result = false;
|
result = false;
|
||||||
if ((order & OT_MASK) == OT_GOTO_STATION) {
|
if (order.type == OT_GOTO_STATION) {
|
||||||
if ( (byte)(order >> 8) == v->last_station_visited)
|
if (order.station == v->last_station_visited)
|
||||||
v->last_station_visited = 0xFF;
|
v->last_station_visited = 0xFF;
|
||||||
v->dest_tile = DEREF_STATION(order >> 8)->xy;
|
v->dest_tile = DEREF_STATION(order.station)->xy;
|
||||||
result = CheckReverseTrain(v);
|
result = CheckReverseTrain(v);
|
||||||
} else if ((order & OT_MASK) == OT_GOTO_DEPOT) {
|
} else if (order.type == OT_GOTO_DEPOT) {
|
||||||
v->dest_tile = _depots[order >> 8].xy;
|
v->dest_tile = _depots[order.station].xy;
|
||||||
result = CheckReverseTrain(v);
|
result = CheckReverseTrain(v);
|
||||||
} else if ((order & OT_MASK) == OT_GOTO_WAYPOINT) {
|
} else if (order.type == OT_GOTO_WAYPOINT) {
|
||||||
v->dest_tile = _waypoints[order >> 8].xy;
|
v->dest_tile = _waypoints[order.station].xy;
|
||||||
result = CheckReverseTrain(v);
|
result = CheckReverseTrain(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1647,24 +1658,24 @@ static void MarkTrainDirty(Vehicle *v)
|
||||||
|
|
||||||
static void HandleTrainLoading(Vehicle *v, bool mode)
|
static void HandleTrainLoading(Vehicle *v, bool mode)
|
||||||
{
|
{
|
||||||
if (v->next_order == OT_NOTHING)
|
if (v->current_order.type == OT_NOTHING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (v->next_order != OT_DUMMY) {
|
if (v->current_order.type != OT_DUMMY) {
|
||||||
if ((v->next_order&OT_MASK) != OT_LOADING)
|
if (v->current_order.type != OT_LOADING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (mode)
|
if (mode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// don't mark the train as lost if we're loading on the final station.
|
// don't mark the train as lost if we're loading on the final station.
|
||||||
if (v->next_order & OF_NON_STOP)
|
if (v->current_order.flags & OF_NON_STOP)
|
||||||
v->u.rail.days_since_order_progr = 0;
|
v->u.rail.days_since_order_progr = 0;
|
||||||
|
|
||||||
if (--v->load_unload_time_rem)
|
if (--v->load_unload_time_rem)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (v->next_order&OF_FULL_LOAD && CanFillVehicle(v)) {
|
if (v->current_order.flags & OF_FULL_LOAD && CanFillVehicle(v)) {
|
||||||
SET_EXPENSES_TYPE(EXPENSES_TRAIN_INC);
|
SET_EXPENSES_TYPE(EXPENSES_TRAIN_INC);
|
||||||
if (LoadUnloadVehicle(v)) {
|
if (LoadUnloadVehicle(v)) {
|
||||||
InvalidateWindow(WC_TRAINS_LIST, v->owner);
|
InvalidateWindow(WC_TRAINS_LIST, v->owner);
|
||||||
|
@ -1679,11 +1690,12 @@ static void HandleTrainLoading(Vehicle *v, bool mode)
|
||||||
TrainPlayLeaveStationSound(v);
|
TrainPlayLeaveStationSound(v);
|
||||||
|
|
||||||
{
|
{
|
||||||
byte b = v->next_order;
|
Order b = v->current_order;
|
||||||
v->next_order = OT_LEAVESTATION;
|
v->current_order.type = OT_LEAVESTATION;
|
||||||
|
v->current_order.flags = 0;
|
||||||
|
|
||||||
// If this was not the final order, don't remove it from the list.
|
// If this was not the final order, don't remove it from the list.
|
||||||
if (!(b & OF_NON_STOP))
|
if (!(b.flags & OF_NON_STOP))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1739,15 +1751,19 @@ static void TrainEnterStation(Vehicle *v, int station)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Did we reach the final destination?
|
// Did we reach the final destination?
|
||||||
if ((v->next_order&OT_MASK) == OT_GOTO_STATION && v->next_order_param == (byte)station) {
|
if (v->current_order.type == OT_GOTO_STATION &&
|
||||||
|
v->current_order.station == (byte)station) {
|
||||||
// Yeah, keep the load/unload flags
|
// Yeah, keep the load/unload flags
|
||||||
// Non Stop now means if the order should be increased.
|
// Non Stop now means if the order should be increased.
|
||||||
v->next_order = (v->next_order & (OF_FULL_LOAD|OF_UNLOAD)) | OF_NON_STOP | OT_LOADING;
|
v->current_order.type = OT_LOADING;
|
||||||
|
v->current_order.flags &= OF_FULL_LOAD | OF_UNLOAD;
|
||||||
|
v->current_order.flags |= OF_NON_STOP;
|
||||||
} else {
|
} else {
|
||||||
// No, just do a simple load
|
// No, just do a simple load
|
||||||
v->next_order = OT_LOADING;
|
v->current_order.type = OT_LOADING;
|
||||||
|
v->current_order.flags = 0;
|
||||||
}
|
}
|
||||||
v->next_order_param = 0;
|
v->current_order.station = 0;
|
||||||
|
|
||||||
SET_EXPENSES_TYPE(EXPENSES_TRAIN_INC);
|
SET_EXPENSES_TYPE(EXPENSES_TRAIN_INC);
|
||||||
if (LoadUnloadVehicle(v) != 0) {
|
if (LoadUnloadVehicle(v) != 0) {
|
||||||
|
@ -2059,8 +2075,9 @@ static void TrainController(Vehicle *v)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v->next_order == OT_LEAVESTATION) {
|
if (v->current_order.type == OT_LEAVESTATION) {
|
||||||
v->next_order = OT_NOTHING;
|
v->current_order.type = OT_NOTHING;
|
||||||
|
v->current_order.flags = 0;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2484,7 +2501,7 @@ static void TrainLocoHandler(Vehicle *v, bool mode)
|
||||||
|
|
||||||
HandleTrainLoading(v, mode);
|
HandleTrainLoading(v, mode);
|
||||||
|
|
||||||
if ((v->next_order & OT_MASK) == OT_LOADING)
|
if (v->current_order.type == OT_LOADING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (CheckTrainStayInDepot(v))
|
if (CheckTrainStayInDepot(v))
|
||||||
|
@ -2532,8 +2549,6 @@ static const byte _depot_track_ind[4] = {0,1,0,1};
|
||||||
|
|
||||||
void TrainEnterDepot(Vehicle *v, uint tile)
|
void TrainEnterDepot(Vehicle *v, uint tile)
|
||||||
{
|
{
|
||||||
byte t;
|
|
||||||
|
|
||||||
SetSignalsOnBothDir(tile, _depot_track_ind[_map5[tile]&3]);
|
SetSignalsOnBothDir(tile, _depot_track_ind[_map5[tile]&3]);
|
||||||
|
|
||||||
if (v->subtype != 0)
|
if (v->subtype != 0)
|
||||||
|
@ -2551,17 +2566,19 @@ void TrainEnterDepot(Vehicle *v, uint tile)
|
||||||
|
|
||||||
TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
|
TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
|
||||||
|
|
||||||
if ((v->next_order&OT_MASK) == OT_GOTO_DEPOT) {
|
if (v->current_order.type == OT_GOTO_DEPOT) {
|
||||||
|
Order t;
|
||||||
|
|
||||||
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
||||||
|
|
||||||
t = v->next_order;
|
t = v->current_order;
|
||||||
v->next_order = OT_DUMMY;
|
v->current_order.type = OT_DUMMY;
|
||||||
|
v->current_order.flags = 0;
|
||||||
|
|
||||||
// Part of the schedule?
|
if (t.flags & OF_UNLOAD) { // Part of the schedule?
|
||||||
if (t & OF_UNLOAD) { v->u.rail.days_since_order_progr = 0; v->cur_order_index++; }
|
v->u.rail.days_since_order_progr = 0;
|
||||||
|
v->cur_order_index++;
|
||||||
// User initiated?
|
} else if (t.flags & OF_FULL_LOAD) { // User initiated?
|
||||||
else if (t & OF_FULL_LOAD) {
|
|
||||||
v->vehstatus |= VS_STOPPED;
|
v->vehstatus |= VS_STOPPED;
|
||||||
if (v->owner == _local_player) {
|
if (v->owner == _local_player) {
|
||||||
SetDParam(0, v->unitnumber);
|
SetDParam(0, v->unitnumber);
|
||||||
|
@ -2594,18 +2611,19 @@ static void CheckIfTrainNeedsService(Vehicle *v)
|
||||||
|
|
||||||
// Don't interfere with a depot visit scheduled by the user, or a
|
// Don't interfere with a depot visit scheduled by the user, or a
|
||||||
// depot visit by the order list.
|
// depot visit by the order list.
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT &&
|
if (v->current_order.type == OT_GOTO_DEPOT &&
|
||||||
(v->next_order & (OF_FULL_LOAD|OF_UNLOAD)) != 0)
|
(v->current_order.flags & (OF_FULL_LOAD | OF_UNLOAD)) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tfdd = FindClosestTrainDepot(v);
|
tfdd = FindClosestTrainDepot(v);
|
||||||
/* Only go to the depot if it is not too far out of our way. */
|
/* Only go to the depot if it is not too far out of our way. */
|
||||||
if (tfdd.best_length == (uint)-1 || tfdd.best_length > 16 ) {
|
if (tfdd.best_length == (uint)-1 || tfdd.best_length > 16 ) {
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT) {
|
if (v->current_order.type == OT_GOTO_DEPOT) {
|
||||||
/* If we were already heading for a depot but it has
|
/* If we were already heading for a depot but it has
|
||||||
* suddenly moved farther away, we continue our normal
|
* suddenly moved farther away, we continue our normal
|
||||||
* schedule? */
|
* schedule? */
|
||||||
v->next_order = OT_DUMMY;
|
v->current_order.type = OT_DUMMY;
|
||||||
|
v->current_order.flags = 0;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -2613,11 +2631,14 @@ static void CheckIfTrainNeedsService(Vehicle *v)
|
||||||
|
|
||||||
depot = GetDepotByTile(tfdd.tile);
|
depot = GetDepotByTile(tfdd.tile);
|
||||||
|
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_DEPOT && v->next_order_param != depot && !CHANCE16(3,16))
|
if (v->current_order.type == OT_GOTO_DEPOT &&
|
||||||
|
v->current_order.station != depot &&
|
||||||
|
!CHANCE16(3,16))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
v->next_order = OT_GOTO_DEPOT | OF_NON_STOP;
|
v->current_order.type = OT_GOTO_DEPOT;
|
||||||
v->next_order_param = depot;
|
v->current_order.flags = OF_NON_STOP;
|
||||||
|
v->current_order.station = depot;
|
||||||
v->dest_tile = tfdd.tile;
|
v->dest_tile = tfdd.tile;
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, 4);
|
||||||
}
|
}
|
||||||
|
@ -2662,8 +2683,8 @@ void OnNewDay_Train(Vehicle *v)
|
||||||
CheckOrders(v);
|
CheckOrders(v);
|
||||||
|
|
||||||
/* update destination */
|
/* update destination */
|
||||||
if ((v->next_order & OT_MASK) == OT_GOTO_STATION &&
|
if (v->current_order.type == OT_GOTO_STATION &&
|
||||||
(tile=DEREF_STATION(v->next_order_param)->train_tile) != 0)
|
(tile = DEREF_STATION(v->current_order.station)->train_tile) != 0)
|
||||||
v->dest_tile = tile;
|
v->dest_tile = tile;
|
||||||
|
|
||||||
if ((v->vehstatus & VS_STOPPED) == 0) {
|
if ((v->vehstatus & VS_STOPPED) == 0) {
|
||||||
|
@ -2719,10 +2740,10 @@ void InitializeTrains()
|
||||||
_age_cargo_skip_counter = 1;
|
_age_cargo_skip_counter = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ScheduleHasDepotOrders(uint16 *schedule)
|
int ScheduleHasDepotOrders(const Order *schedule)
|
||||||
{
|
{
|
||||||
for (;*schedule!=0;schedule++)
|
for (; schedule->type != OT_NOTHING; schedule++)
|
||||||
if ((*schedule&OT_MASK) == OT_GOTO_DEPOT)
|
if (schedule->type == OT_GOTO_DEPOT)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -778,15 +778,15 @@ static void TrainViewWndProc(Window *w, WindowEvent *e)
|
||||||
str = STR_TRAIN_STOPPING + _patches.vehicle_speed;
|
str = STR_TRAIN_STOPPING + _patches.vehicle_speed;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch(v->next_order & OT_MASK) {
|
switch (v->current_order.type) {
|
||||||
case OT_GOTO_STATION: {
|
case OT_GOTO_STATION: {
|
||||||
str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
|
str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
|
||||||
SetDParam(0, v->next_order_param);
|
SetDParam(0, v->current_order.station);
|
||||||
SetDParam(1, v->u.rail.last_speed * 10 >> 4);
|
SetDParam(1, v->u.rail.last_speed * 10 >> 4);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case OT_GOTO_DEPOT: {
|
case OT_GOTO_DEPOT: {
|
||||||
Depot *dep = &_depots[v->next_order_param];
|
Depot *dep = &_depots[v->current_order.station];
|
||||||
SetDParam(0, dep->town_index);
|
SetDParam(0, dep->town_index);
|
||||||
str = STR_HEADING_FOR_TRAIN_DEPOT + _patches.vehicle_speed;
|
str = STR_HEADING_FOR_TRAIN_DEPOT + _patches.vehicle_speed;
|
||||||
SetDParam(1, v->u.rail.last_speed * 10 >> 4);
|
SetDParam(1, v->u.rail.last_speed * 10 >> 4);
|
||||||
|
@ -798,7 +798,7 @@ static void TrainViewWndProc(Window *w, WindowEvent *e)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OT_GOTO_WAYPOINT: {
|
case OT_GOTO_WAYPOINT: {
|
||||||
SetDParam(0, v->next_order_param);
|
SetDParam(0, v->current_order.station);
|
||||||
str = STR_HEADING_FOR_WAYPOINT + _patches.vehicle_speed;
|
str = STR_HEADING_FOR_WAYPOINT + _patches.vehicle_speed;
|
||||||
SetDParam(1, v->u.rail.last_speed * 10 >> 4);
|
SetDParam(1, v->u.rail.last_speed * 10 >> 4);
|
||||||
break;
|
break;
|
||||||
|
|
58
vehicle.c
58
vehicle.c
|
@ -402,7 +402,7 @@ uint GetWaypointByTile(uint tile)
|
||||||
|
|
||||||
Vehicle *IsScheduleShared(Vehicle *u)
|
Vehicle *IsScheduleShared(Vehicle *u)
|
||||||
{
|
{
|
||||||
uint16 *sched = u->schedule_ptr;
|
const Order *sched = u->schedule_ptr;
|
||||||
Vehicle *v;
|
Vehicle *v;
|
||||||
|
|
||||||
FOR_ALL_VEHICLES(v) {
|
FOR_ALL_VEHICLES(v) {
|
||||||
|
@ -414,7 +414,8 @@ Vehicle *IsScheduleShared(Vehicle *u)
|
||||||
|
|
||||||
void DeleteVehicleSchedule(Vehicle *v)
|
void DeleteVehicleSchedule(Vehicle *v)
|
||||||
{
|
{
|
||||||
uint16 *sched, *cur;
|
Order *sched;
|
||||||
|
Order *cur;
|
||||||
int num;
|
int num;
|
||||||
Vehicle *u;
|
Vehicle *u;
|
||||||
|
|
||||||
|
@ -446,32 +447,33 @@ void DeleteVehicleSchedule(Vehicle *v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteCommandFromVehicleSchedule(uint cmd)
|
void DeleteCommandFromVehicleSchedule(Order cmd)
|
||||||
{
|
{
|
||||||
Vehicle *v;
|
Vehicle *v;
|
||||||
uint16 *sched;
|
|
||||||
uint order;
|
|
||||||
bool need_invalidate;
|
bool need_invalidate;
|
||||||
|
|
||||||
FOR_ALL_VEHICLES(v) {
|
FOR_ALL_VEHICLES(v) {
|
||||||
if (v->type != 0 && v->schedule_ptr != NULL) {
|
if (v->type != 0 && v->schedule_ptr != NULL) {
|
||||||
|
Order *sched;
|
||||||
|
|
||||||
// clear last station visited
|
// clear last station visited
|
||||||
if (v->last_station_visited == (cmd>>8) && (cmd & OT_MASK) == OT_GOTO_STATION)
|
if (v->last_station_visited == cmd.station && cmd.type == OT_GOTO_STATION)
|
||||||
v->last_station_visited = 0xFF;
|
v->last_station_visited = 0xFF;
|
||||||
|
|
||||||
// check the next order
|
// check the next order
|
||||||
if ( (uint)((v->next_order&OT_MASK) | (v->next_order_param<<8)) == cmd) {
|
if (v->current_order.type == cmd.type &&
|
||||||
v->next_order = OT_DUMMY;
|
v->current_order.station == cmd.station) {
|
||||||
|
v->current_order.type = OT_DUMMY;
|
||||||
|
v->current_order.flags = 0;
|
||||||
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear the order list
|
// clear the order list
|
||||||
need_invalidate = false;
|
need_invalidate = false;
|
||||||
sched = v->schedule_ptr;
|
for (sched = v->schedule_ptr; sched->type != OT_NOTHING; ++sched) {
|
||||||
while ((order=*sched++) != 0) {
|
if (sched->type == cmd.type && sched->station == cmd.station) {
|
||||||
if ( (order & (OT_MASK|0xFF00)) == cmd) {
|
sched->type = OT_DUMMY;
|
||||||
sched[-1] = OT_DUMMY;
|
sched->flags = 0;
|
||||||
need_invalidate = true;
|
need_invalidate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -484,6 +486,7 @@ void DeleteCommandFromVehicleSchedule(uint cmd)
|
||||||
|
|
||||||
void DoDeleteDepot(uint tile)
|
void DoDeleteDepot(uint tile)
|
||||||
{
|
{
|
||||||
|
Order order;
|
||||||
byte dep_index;
|
byte dep_index;
|
||||||
Depot *d;
|
Depot *d;
|
||||||
|
|
||||||
|
@ -494,7 +497,10 @@ void DoDeleteDepot(uint tile)
|
||||||
for(d=_depots,dep_index=0; d->xy != (TileIndex)tile; d++) {dep_index++;}
|
for(d=_depots,dep_index=0; d->xy != (TileIndex)tile; d++) {dep_index++;}
|
||||||
d->xy = 0;
|
d->xy = 0;
|
||||||
|
|
||||||
DeleteCommandFromVehicleSchedule((dep_index << 8) + OT_GOTO_DEPOT);
|
order.type = OT_GOTO_DEPOT;
|
||||||
|
order.flags = 0;
|
||||||
|
order.station = dep_index;
|
||||||
|
DeleteCommandFromVehicleSchedule(order);
|
||||||
|
|
||||||
// Delete the depot
|
// Delete the depot
|
||||||
DeleteWindowById(WC_VEHICLE_DEPOT, tile);
|
DeleteWindowById(WC_VEHICLE_DEPOT, tile);
|
||||||
|
@ -1586,8 +1592,8 @@ const byte _common_veh_desc[] = {
|
||||||
|
|
||||||
SLE_VAR(Vehicle,cur_order_index, SLE_UINT8),
|
SLE_VAR(Vehicle,cur_order_index, SLE_UINT8),
|
||||||
SLE_VAR(Vehicle,num_orders, SLE_UINT8),
|
SLE_VAR(Vehicle,num_orders, SLE_UINT8),
|
||||||
SLE_VAR(Vehicle,next_order, SLE_UINT8),
|
SLE_VAR(Vehicle,current_order, SLE_UINT8), /* XXX hack to avoid version bump */
|
||||||
SLE_VAR(Vehicle,next_order_param, SLE_UINT8),
|
SLE_VAR(Vehicle,current_order.station, SLE_UINT8),
|
||||||
SLE_REF(Vehicle,schedule_ptr, REF_SCHEDULE),
|
SLE_REF(Vehicle,schedule_ptr, REF_SCHEDULE),
|
||||||
|
|
||||||
SLE_VAR(Vehicle,age, SLE_UINT16),
|
SLE_VAR(Vehicle,age, SLE_UINT16),
|
||||||
|
@ -1731,7 +1737,7 @@ static const byte _disaster_desc[] = {
|
||||||
SLE_VAR(Vehicle,z_height, SLE_UINT8),
|
SLE_VAR(Vehicle,z_height, SLE_UINT8),
|
||||||
SLE_VAR(Vehicle,owner, SLE_UINT8),
|
SLE_VAR(Vehicle,owner, SLE_UINT8),
|
||||||
SLE_VAR(Vehicle,vehstatus, SLE_UINT8),
|
SLE_VAR(Vehicle,vehstatus, SLE_UINT8),
|
||||||
SLE_VAR(Vehicle,next_order, SLE_UINT8),
|
SLE_VAR(Vehicle,current_order.station, SLE_UINT8),
|
||||||
|
|
||||||
SLE_VAR(Vehicle,cur_image, SLE_UINT16),
|
SLE_VAR(Vehicle,cur_image, SLE_UINT16),
|
||||||
SLE_VAR(Vehicle,age, SLE_UINT16),
|
SLE_VAR(Vehicle,age, SLE_UINT16),
|
||||||
|
@ -1858,15 +1864,31 @@ static void Load_CHKP()
|
||||||
|
|
||||||
static void Save_ORDR()
|
static void Save_ORDR()
|
||||||
{
|
{
|
||||||
|
uint16 orders[lengthof(_order_array)];
|
||||||
uint len = _ptr_to_next_order - _order_array;
|
uint len = _ptr_to_next_order - _order_array;
|
||||||
SlArray(_order_array, len, SLE_UINT16);
|
uint i;
|
||||||
|
|
||||||
|
assert (len <= lengthof(orders));
|
||||||
|
|
||||||
|
for (i = 0; i < len; ++i)
|
||||||
|
orders[i] = PackOrder(&_order_array[i]);
|
||||||
|
|
||||||
|
SlArray(orders, len, SLE_UINT16);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_ORDR()
|
static void Load_ORDR()
|
||||||
{
|
{
|
||||||
|
uint16 orders[lengthof(_order_array)];
|
||||||
uint len = SlGetFieldLength() >> 1;
|
uint len = SlGetFieldLength() >> 1;
|
||||||
|
uint i;
|
||||||
|
|
||||||
|
assert (len <= lengthof(orders));
|
||||||
|
|
||||||
_ptr_to_next_order = _order_array + len;
|
_ptr_to_next_order = _order_array + len;
|
||||||
SlArray(_order_array, len, SLE_UINT16);
|
SlArray(orders, len, SLE_UINT16);
|
||||||
|
|
||||||
|
for (i = 0; i < len; ++i)
|
||||||
|
_order_array[i] = UnpackOrder(orders[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ChunkHandler _veh_chunk_handlers[] = {
|
const ChunkHandler _veh_chunk_handlers[] = {
|
||||||
|
|
46
vehicle.h
46
vehicle.h
|
@ -3,6 +3,27 @@
|
||||||
|
|
||||||
#include "vehicle_gui.h"
|
#include "vehicle_gui.h"
|
||||||
|
|
||||||
|
typedef struct Order {
|
||||||
|
uint8 type:4;
|
||||||
|
uint8 flags:4;
|
||||||
|
uint8 station;
|
||||||
|
} Order;
|
||||||
|
|
||||||
|
static inline uint16 PackOrder(const Order *order)
|
||||||
|
{
|
||||||
|
return order->station << 8 | order->flags << 4 | order->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Order UnpackOrder(uint16 packed)
|
||||||
|
{
|
||||||
|
Order order = {
|
||||||
|
(packed & 0x000f),
|
||||||
|
(packed & 0x00f0) >> 4,
|
||||||
|
(packed & 0xff00) >> 8
|
||||||
|
};
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct VehicleRail {
|
typedef struct VehicleRail {
|
||||||
uint16 last_speed; // NOSAVE: only used in UI
|
uint16 last_speed; // NOSAVE: only used in UI
|
||||||
uint16 crash_anim_pos;
|
uint16 crash_anim_pos;
|
||||||
|
@ -145,9 +166,8 @@ struct Vehicle {
|
||||||
// related to the current order
|
// related to the current order
|
||||||
byte cur_order_index;
|
byte cur_order_index;
|
||||||
byte num_orders;
|
byte num_orders;
|
||||||
byte next_order;
|
Order current_order;
|
||||||
byte next_order_param;
|
Order *schedule_ptr;
|
||||||
uint16 *schedule_ptr;
|
|
||||||
|
|
||||||
// Boundaries for the current position in the world and a next hash link.
|
// Boundaries for the current position in the world and a next hash link.
|
||||||
// NOSAVE: All of those can be updated with VehiclePositionChanged()
|
// NOSAVE: All of those can be updated with VehiclePositionChanged()
|
||||||
|
@ -220,16 +240,13 @@ enum {
|
||||||
OT_LEAVESTATION = 4,
|
OT_LEAVESTATION = 4,
|
||||||
OT_DUMMY = 5,
|
OT_DUMMY = 5,
|
||||||
OT_GOTO_WAYPOINT = 6,
|
OT_GOTO_WAYPOINT = 6,
|
||||||
|
|
||||||
OT_MASK = 0x1F,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Order flags */
|
/* Order flags */
|
||||||
enum {
|
enum {
|
||||||
OF_UNLOAD = 0x20,
|
OF_UNLOAD = 0x2,
|
||||||
OF_FULL_LOAD = 0x40, // Also used when to force an aircraft into a depot.
|
OF_FULL_LOAD = 0x4, // Also used when to force an aircraft into a depot
|
||||||
OF_NON_STOP = 0x80,
|
OF_NON_STOP = 0x8
|
||||||
OF_MASK = 0xE0,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -269,8 +286,9 @@ typedef void VehicleTickProc(Vehicle *v);
|
||||||
typedef void *VehicleFromPosProc(Vehicle *v, void *data);
|
typedef void *VehicleFromPosProc(Vehicle *v, void *data);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
VehicleID clone;
|
||||||
byte orderindex;
|
byte orderindex;
|
||||||
uint16 order[41];
|
Order order[41];
|
||||||
uint16 service_interval;
|
uint16 service_interval;
|
||||||
char name[32];
|
char name[32];
|
||||||
} BackuppedOrders;
|
} BackuppedOrders;
|
||||||
|
@ -337,7 +355,7 @@ void CheckVehicleBreakdown(Vehicle *v);
|
||||||
void AgeVehicle(Vehicle *v);
|
void AgeVehicle(Vehicle *v);
|
||||||
void MaybeRenewVehicle(Vehicle *v, int32 build_cost);
|
void MaybeRenewVehicle(Vehicle *v, int32 build_cost);
|
||||||
|
|
||||||
void DeleteCommandFromVehicleSchedule(uint cmd);
|
void DeleteCommandFromVehicleSchedule(Order cmd);
|
||||||
|
|
||||||
void BeginVehicleMove(Vehicle *v);
|
void BeginVehicleMove(Vehicle *v);
|
||||||
void EndVehicleMove(Vehicle *v);
|
void EndVehicleMove(Vehicle *v);
|
||||||
|
@ -361,7 +379,7 @@ int32 GetTrainRunningCost(Vehicle *v);
|
||||||
|
|
||||||
int CheckStoppedInDepot(Vehicle *v);
|
int CheckStoppedInDepot(Vehicle *v);
|
||||||
|
|
||||||
int ScheduleHasDepotOrders(uint16 *schedule);
|
int ScheduleHasDepotOrders(const Order *schedule);
|
||||||
int CheckOrders(Vehicle *v);
|
int CheckOrders(Vehicle *v);
|
||||||
|
|
||||||
typedef struct GetNewVehiclePosResult {
|
typedef struct GetNewVehiclePosResult {
|
||||||
|
@ -389,8 +407,8 @@ enum {
|
||||||
|
|
||||||
VARDEF Vehicle _vehicles[NUM_VEHICLES];
|
VARDEF Vehicle _vehicles[NUM_VEHICLES];
|
||||||
|
|
||||||
VARDEF uint16 _order_array[5000];
|
VARDEF Order _order_array[5000];
|
||||||
VARDEF uint16 *_ptr_to_next_order;
|
VARDEF Order *_ptr_to_next_order;
|
||||||
|
|
||||||
VARDEF Depot _depots[255];
|
VARDEF Depot _depots[255];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue