mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r1525) -Codechange: rewrote the _order_array, now it can be made dynamic.
-Codechange: renamed all 'schedule' stuff to 'order(list)' -Codechange: moved all order-stuff to order_cmd.c / order.h -Codechange: vehicles that share orders are now linked to eachother with next_shared/prev_shared in Vehicle Developers: please use AssignOrder to assign data to an order. If not, you _WILL_ make the save-routine to assert!
This commit is contained in:
parent
732c362dea
commit
d275109e79
2
ai.c
2
ai.c
|
@ -3618,7 +3618,7 @@ 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_ALL_ORDERS(ord) {
|
||||||
if (ord->type == OT_GOTO_STATION)
|
if (ord->type == OT_GOTO_STATION)
|
||||||
in_use[ord->station] = 1;
|
in_use[ord->station] = 1;
|
||||||
}
|
}
|
||||||
|
|
14
ai_new.c
14
ai_new.c
|
@ -502,14 +502,12 @@ static bool AiNew_CheckVehicleStation(Player *p, Station *st) {
|
||||||
// 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) {
|
||||||
const Order *sched = v->schedule_ptr;
|
const Order *order;
|
||||||
if (sched != NULL) {
|
|
||||||
for (; sched->type != OT_NOTHING; ++sched) {
|
FOR_VEHICLE_ORDERS(v, order) {
|
||||||
if (sched->type == OT_GOTO_STATION &&
|
if (order->type == OT_GOTO_STATION && GetStation(order->station) == st) {
|
||||||
GetStation(sched->station) == st) {
|
// This vehicle has this city in its list
|
||||||
// This vehicle has this city in his list
|
count++;
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ int32 CmdBuildAircraft(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
|
|
||||||
// allocate 2 or 3 vehicle structs, depending on type
|
// allocate 2 or 3 vehicle structs, depending on type
|
||||||
if (!AllocateVehicles(vl, (avi->subtype & 1) == 0 ? 3 : 2) ||
|
if (!AllocateVehicles(vl, (avi->subtype & 1) == 0 ? 3 : 2) ||
|
||||||
_ptr_to_next_order >= endof(_order_array))
|
IsOrderPoolFull())
|
||||||
return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
|
return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
|
||||||
|
|
||||||
unit_num = GetFreeUnitNumber(VEH_Aircraft);
|
unit_num = GetFreeUnitNumber(VEH_Aircraft);
|
||||||
|
@ -200,9 +200,6 @@ int32 CmdBuildAircraft(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
|
|
||||||
_new_aircraft_id = v->index;
|
_new_aircraft_id = v->index;
|
||||||
|
|
||||||
_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
|
||||||
|
@ -490,7 +487,7 @@ static void CheckIfAircraftNeedsService(Vehicle *v)
|
||||||
v->current_order.flags & OF_FULL_LOAD)
|
v->current_order.flags & OF_FULL_LOAD)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_patches.gotodepot && ScheduleHasDepotOrders(v->schedule_ptr))
|
if (_patches.gotodepot && VehicleHasDepotOrders(v))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
st = GetStation(v->current_order.station);
|
st = GetStation(v->current_order.station);
|
||||||
|
@ -510,13 +507,13 @@ static void CheckIfAircraftNeedsService(Vehicle *v)
|
||||||
|
|
||||||
void InvalidateAircraftWindows(const Vehicle *v)
|
void InvalidateAircraftWindows(const Vehicle *v)
|
||||||
{
|
{
|
||||||
const Order *o;
|
const Order *order;
|
||||||
|
|
||||||
InvalidateWindow(WC_AIRCRAFT_LIST, v->owner);
|
InvalidateWindow(WC_AIRCRAFT_LIST, v->owner);
|
||||||
|
|
||||||
for ( o = v->schedule_ptr; o->type != OT_NOTHING; o++) {
|
FOR_VEHICLE_ORDERS(v, order) {
|
||||||
if (o->type == OT_GOTO_STATION ) {
|
if (order->type == OT_GOTO_STATION ) {
|
||||||
InvalidateWindow(WC_AIRCRAFT_LIST, o->station << 16 | v->owner);
|
InvalidateWindow(WC_AIRCRAFT_LIST, (order->station << 16) | v->owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1024,21 +1021,9 @@ static void HandleAircraftSmoke(Vehicle *v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if the vehicle does have valid orders
|
|
||||||
// false if none are valid
|
|
||||||
static bool CheckForValidOrders(Vehicle *v)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < v->num_orders; i++) {
|
|
||||||
if( v->schedule_ptr[i].type != OT_DUMMY )
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ProcessAircraftOrder(Vehicle *v)
|
static void ProcessAircraftOrder(Vehicle *v)
|
||||||
{
|
{
|
||||||
Order order;
|
Order *order;
|
||||||
|
|
||||||
// OT_GOTO_DEPOT, OT_LOADING
|
// OT_GOTO_DEPOT, OT_LOADING
|
||||||
if (v->current_order.type == OT_GOTO_DEPOT ||
|
if (v->current_order.type == OT_GOTO_DEPOT ||
|
||||||
|
@ -1057,32 +1042,32 @@ static void ProcessAircraftOrder(Vehicle *v)
|
||||||
if (v->cur_order_index >= v->num_orders)
|
if (v->cur_order_index >= v->num_orders)
|
||||||
v->cur_order_index = 0;
|
v->cur_order_index = 0;
|
||||||
|
|
||||||
order = v->schedule_ptr[v->cur_order_index];
|
order = GetVehicleOrder(v, v->cur_order_index);
|
||||||
|
|
||||||
if (order.type == OT_NOTHING) {
|
if (order == NULL) {
|
||||||
v->current_order.type = OT_NOTHING;
|
v->current_order.type = OT_NOTHING;
|
||||||
v->current_order.flags = 0;
|
v->current_order.flags = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( order.type == OT_DUMMY && !CheckForValidOrders(v))
|
if (order->type == OT_DUMMY && !CheckForValidOrders(v))
|
||||||
CrashAirplane(v);
|
CrashAirplane(v);
|
||||||
|
|
||||||
if (order.type == v->current_order.type &&
|
if (order->type == v->current_order.type &&
|
||||||
order.flags == v->current_order.flags &&
|
order->flags == v->current_order.flags &&
|
||||||
order.station == v->current_order.station)
|
order->station == v->current_order.station)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
v->current_order = order;
|
v->current_order = *order;
|
||||||
|
|
||||||
// orders are changed in flight, ensure going to the right station
|
// orders are changed in flight, ensure going to the right station
|
||||||
if (order.type == 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.station;
|
v->u.air.targetairport = order->station;
|
||||||
}
|
}
|
||||||
|
|
||||||
InvalidateVehicleOrderWidget(v);
|
InvalidateVehicleOrder(v);
|
||||||
|
|
||||||
InvalidateAircraftWindows(v);
|
InvalidateAircraftWindows(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1116,7 +1101,7 @@ static void HandleAircraftLoading(Vehicle *v, int mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v->cur_order_index++;
|
v->cur_order_index++;
|
||||||
InvalidateVehicleOrderWidget(v);
|
InvalidateVehicleOrder(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CrashAirplane(Vehicle *v)
|
static void CrashAirplane(Vehicle *v)
|
||||||
|
|
|
@ -920,16 +920,13 @@ void ShowAircraftDepotWindow(uint tile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawSmallSchedule(Vehicle *v, int x, int y) {
|
static void DrawSmallOrderList(Vehicle *v, int x, int y) {
|
||||||
const Order *sched;
|
const Order *order;
|
||||||
int sel;
|
int sel, i = 0;
|
||||||
Order ord;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
sched = v->schedule_ptr;
|
|
||||||
sel = v->cur_order_index;
|
sel = v->cur_order_index;
|
||||||
|
|
||||||
while ((ord = *sched++).type != OT_NOTHING) {
|
FOR_VEHICLE_ORDERS(v, order) {
|
||||||
if (sel == 0) {
|
if (sel == 0) {
|
||||||
_stringwidth_base = 0xE0;
|
_stringwidth_base = 0xE0;
|
||||||
DoDrawString( "\xAF", x-6, y, 16);
|
DoDrawString( "\xAF", x-6, y, 16);
|
||||||
|
@ -937,8 +934,8 @@ static void DrawSmallSchedule(Vehicle *v, int x, int y) {
|
||||||
}
|
}
|
||||||
sel--;
|
sel--;
|
||||||
|
|
||||||
if (ord.type == OT_GOTO_STATION) {
|
if (order->type == OT_GOTO_STATION) {
|
||||||
SetDParam(0, ord.station);
|
SetDParam(0, order->station);
|
||||||
DrawString(x, y, STR_A036, 0);
|
DrawString(x, y, STR_A036, 0);
|
||||||
|
|
||||||
y += 6;
|
y += 6;
|
||||||
|
@ -1052,7 +1049,7 @@ static void PlayerAircraftWndProc(Window *w, WindowEvent *e)
|
||||||
DrawString(x + 19, y, STR_01AB, 0);
|
DrawString(x + 19, y, STR_01AB, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawSmallSchedule(v, x + 136, y);
|
DrawSmallOrderList(v, x + 136, y);
|
||||||
|
|
||||||
y += PLY_WND_PRC__SIZE_OF_ROW_BIG;
|
y += PLY_WND_PRC__SIZE_OF_ROW_BIG;
|
||||||
}
|
}
|
||||||
|
|
4
misc.c
4
misc.c
|
@ -150,6 +150,8 @@ void CSleep(int milliseconds)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InitializeVehicles();
|
||||||
|
void InitializeOrders();
|
||||||
void InitializeClearLand();
|
void InitializeClearLand();
|
||||||
void InitializeRail();
|
void InitializeRail();
|
||||||
void InitializeRailGui();
|
void InitializeRailGui();
|
||||||
|
@ -206,7 +208,7 @@ void InitializeGame()
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeVehicles();
|
InitializeVehicles();
|
||||||
_backup_orders_tile = 0;
|
InitializeOrders();
|
||||||
|
|
||||||
InitNewsItemStructs();
|
InitNewsItemStructs();
|
||||||
InitializeLandscape();
|
InitializeLandscape();
|
||||||
|
|
51
oldloader.c
51
oldloader.c
|
@ -752,6 +752,22 @@ static void FixDepot(Depot *n, OldDepot *o, int num)
|
||||||
} while (n++,o++,--num);
|
} while (n++,o++,--num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void FixOrder(uint16 *o, int num)
|
||||||
|
{
|
||||||
|
Order *order;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < num; ++i) {
|
||||||
|
order = GetOrder(i);
|
||||||
|
AssignOrder(order, UnpackOldOrder(*o));
|
||||||
|
/* Recover the next list */
|
||||||
|
if (i > 0 && order->type != OT_NOTHING)
|
||||||
|
GetOrder(i - 1)->next = order;
|
||||||
|
|
||||||
|
o++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void FixVehicle(OldVehicle *o, int num)
|
static void FixVehicle(OldVehicle *o, int num)
|
||||||
{
|
{
|
||||||
Vehicle *n;
|
Vehicle *n;
|
||||||
|
@ -767,10 +783,9 @@ static void FixVehicle(OldVehicle *o, int num)
|
||||||
n->subtype = o->subtype;
|
n->subtype = o->subtype;
|
||||||
|
|
||||||
if (o->schedule_ptr == 0xFFFFFFFF || o->schedule_ptr == 0) {
|
if (o->schedule_ptr == 0xFFFFFFFF || o->schedule_ptr == 0) {
|
||||||
n->schedule_ptr = NULL;
|
n->orders = NULL;
|
||||||
} else {
|
} else {
|
||||||
n->schedule_ptr = _order_array + REMAP_ORDER_IDX(o->schedule_ptr);
|
n->orders = GetOrder(REMAP_ORDER_IDX(o->schedule_ptr));
|
||||||
assert(n->schedule_ptr >= _order_array && n->schedule_ptr < _ptr_to_next_order);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
n->current_order.type = o->next_order & 0x0f;
|
n->current_order.type = o->next_order & 0x0f;
|
||||||
|
@ -870,6 +885,31 @@ static void FixVehicle(OldVehicle *o, int num)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (i++,o++,--num);
|
} while (i++,o++,--num);
|
||||||
|
|
||||||
|
/* Check for shared orders, and link them correctly */
|
||||||
|
{
|
||||||
|
Vehicle *v;
|
||||||
|
|
||||||
|
FOR_ALL_VEHICLES(v) {
|
||||||
|
Vehicle *u;
|
||||||
|
|
||||||
|
if (v->type == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FOR_ALL_VEHICLES_FROM(u, v->index + 1) {
|
||||||
|
if (u->type == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* If a vehicle has the same orders, add the link to eachother
|
||||||
|
in both vehicles */
|
||||||
|
if (v->orders == u->orders) {
|
||||||
|
v->next_shared = u;
|
||||||
|
u->prev_shared = v;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FixSubsidy(Subsidy *n, OldSubsidy *o, int num)
|
static void FixSubsidy(Subsidy *n, OldSubsidy *o, int num)
|
||||||
|
@ -1447,15 +1487,12 @@ bool LoadOldSaveGame(const char *file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < lengthof(m->order_list); ++i)
|
|
||||||
_order_array[i] = UnpackOldOrder(m->order_list[i]);
|
|
||||||
_ptr_to_next_order = _order_array + REMAP_ORDER_IDX(m->ptr_to_next_order);
|
|
||||||
|
|
||||||
FixTown(m->town_list, lengthof(m->town_list), m->town_name_type);
|
FixTown(m->town_list, lengthof(m->town_list), m->town_name_type);
|
||||||
FixIndustry(m->industries, lengthof(m->industries));
|
FixIndustry(m->industries, lengthof(m->industries));
|
||||||
FixStation(m->stations, lengthof(m->stations));
|
FixStation(m->stations, lengthof(m->stations));
|
||||||
|
|
||||||
FixDepot(_depots, m->depots, lengthof(m->depots));
|
FixDepot(_depots, m->depots, lengthof(m->depots));
|
||||||
|
FixOrder(m->order_list, lengthof(m->order_list));
|
||||||
FixVehicle(m->vehicles, lengthof(m->vehicles));
|
FixVehicle(m->vehicles, lengthof(m->vehicles));
|
||||||
FixSubsidy(_subsidies, m->subsidies, lengthof(m->subsidies));
|
FixSubsidy(_subsidies, m->subsidies, lengthof(m->subsidies));
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
#ifndef ORDER_H
|
||||||
|
#define ORDER_H
|
||||||
|
|
||||||
|
/* Order types */
|
||||||
|
enum {
|
||||||
|
OT_NOTHING = 0,
|
||||||
|
OT_GOTO_STATION = 1,
|
||||||
|
OT_GOTO_DEPOT = 2,
|
||||||
|
OT_LOADING = 3,
|
||||||
|
OT_LEAVESTATION = 4,
|
||||||
|
OT_DUMMY = 5,
|
||||||
|
OT_GOTO_WAYPOINT = 6
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Order flags -- please use OFB instead OF and use HASBIT/SETBIT/CLEARBIT */
|
||||||
|
enum {
|
||||||
|
OF_UNLOAD = 0x2,
|
||||||
|
OF_FULL_LOAD = 0x4, // Also used when to force an aircraft into a depot
|
||||||
|
OF_NON_STOP = 0x8
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Order flags bits */
|
||||||
|
enum {
|
||||||
|
OFB_UNLOAD = 1,
|
||||||
|
OFB_FULL_LOAD = 2,
|
||||||
|
OFB_NON_STOP = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Possible clone options */
|
||||||
|
enum {
|
||||||
|
CO_SHARE = 0,
|
||||||
|
CO_COPY = 1,
|
||||||
|
CO_UNSHARE = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
/* If you change this, keep in mind that it is saved on 3 places:
|
||||||
|
- Load_ORDR, all the global orders
|
||||||
|
- Vehicle -> current_order
|
||||||
|
- REF_SHEDULE (all REFs are currently limited to 16 bits!!) */
|
||||||
|
typedef struct Order {
|
||||||
|
uint8 type;
|
||||||
|
uint8 flags;
|
||||||
|
uint16 station;
|
||||||
|
|
||||||
|
struct Order *next; //! Pointer to next order. If NULL, end of list
|
||||||
|
|
||||||
|
uint16 index; //! Index of the order, is not saved or anything, just for reference
|
||||||
|
} Order;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
VehicleID clone;
|
||||||
|
byte orderindex;
|
||||||
|
Order order[41];
|
||||||
|
uint16 service_interval;
|
||||||
|
char name[32];
|
||||||
|
} BackuppedOrders;
|
||||||
|
|
||||||
|
VARDEF TileIndex _backup_orders_tile;
|
||||||
|
VARDEF BackuppedOrders _backup_orders_data[1];
|
||||||
|
|
||||||
|
VARDEF Order _orders[5000];
|
||||||
|
VARDEF uint32 _orders_size;
|
||||||
|
|
||||||
|
static inline Order *GetOrder(uint index)
|
||||||
|
{
|
||||||
|
assert(index < _orders_size);
|
||||||
|
return &_orders[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FOR_ALL_ORDERS_FROM(o, from) for(o = GetOrder(from); o != &_orders[_orders_size]; o++)
|
||||||
|
#define FOR_ALL_ORDERS(o) FOR_ALL_ORDERS_FROM(o, 0)
|
||||||
|
|
||||||
|
#define FOR_VEHICLE_ORDERS(v, order) for (order = v->orders; order != NULL; order = order->next)
|
||||||
|
|
||||||
|
static inline bool HasOrderPoolFree(uint amount)
|
||||||
|
{
|
||||||
|
Order *order;
|
||||||
|
|
||||||
|
FOR_ALL_ORDERS(order)
|
||||||
|
if (order->type == OT_NOTHING)
|
||||||
|
if (--amount == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool IsOrderPoolFull()
|
||||||
|
{
|
||||||
|
return !HasOrderPoolFree(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pack and unpack routines */
|
||||||
|
|
||||||
|
static inline uint32 PackOrder(const Order *order)
|
||||||
|
{
|
||||||
|
return order->station << 16 | order->flags << 8 | order->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Order UnpackOrder(uint32 packed)
|
||||||
|
{
|
||||||
|
Order order;
|
||||||
|
order.type = (packed & 0x000000FF);
|
||||||
|
order.flags = (packed & 0x0000FF00) >> 8;
|
||||||
|
order.station = (packed & 0xFFFF0000) >> 16;
|
||||||
|
order.next = NULL;
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Functions */
|
||||||
|
void BackupVehicleOrders(Vehicle *v, BackuppedOrders *order);
|
||||||
|
void RestoreVehicleOrders(Vehicle *v, BackuppedOrders *order);
|
||||||
|
void DeleteDestinationFromVehicleOrder(Order dest);
|
||||||
|
void InvalidateVehicleOrder(const Vehicle *v);
|
||||||
|
bool VehicleHasDepotOrders(const Vehicle *v);
|
||||||
|
bool CheckOrders(const Vehicle *v);
|
||||||
|
void DeleteVehicleOrders(Vehicle *v);
|
||||||
|
bool IsOrderListShared(const Vehicle *v);
|
||||||
|
void AssignOrder(Order *order, Order data);
|
||||||
|
bool CheckForValidOrders(Vehicle *v);
|
||||||
|
|
||||||
|
Order UnpackVersion4Order(uint16 packed);
|
||||||
|
Order UnpackOldOrder(uint16 packed);
|
||||||
|
|
||||||
|
#endif /* ORDER_H */
|
1059
order_cmd.c
1059
order_cmd.c
File diff suppressed because it is too large
Load Diff
214
order_gui.c
214
order_gui.c
|
@ -14,32 +14,23 @@
|
||||||
static int OrderGetSel(Window *w)
|
static int OrderGetSel(Window *w)
|
||||||
{
|
{
|
||||||
Vehicle *v = GetVehicle(w->window_number);
|
Vehicle *v = GetVehicle(w->window_number);
|
||||||
const Order *sched = v->schedule_ptr;
|
|
||||||
int num = WP(w,order_d).sel;
|
int num = WP(w,order_d).sel;
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
if (num == 0)
|
if (num < 0 || num > v->num_orders)
|
||||||
return 0;
|
return v->num_orders;
|
||||||
|
|
||||||
while (sched->type != OT_NOTHING) {
|
return num;
|
||||||
sched++;
|
|
||||||
count++;
|
|
||||||
if (--num == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawOrdersWindow(Window *w)
|
static void DrawOrdersWindow(Window *w)
|
||||||
{
|
{
|
||||||
Vehicle *v;
|
const Vehicle *v;
|
||||||
int num, sel;
|
const Order *order;
|
||||||
const Order *sched;
|
|
||||||
Order ord;
|
|
||||||
int y, i;
|
|
||||||
StringID str;
|
StringID str;
|
||||||
bool shared_schedule;
|
int sel;
|
||||||
|
int y, i;
|
||||||
|
bool shared_orders;
|
||||||
|
byte color;
|
||||||
|
|
||||||
v = GetVehicle(w->window_number);
|
v = GetVehicle(w->window_number);
|
||||||
|
|
||||||
|
@ -57,40 +48,41 @@ static void DrawOrdersWindow(Window *w)
|
||||||
w->disabled_state |= 1 << 6;
|
w->disabled_state |= 1 << 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_schedule = IsScheduleShared(v) != NULL;
|
shared_orders = IsOrderListShared(v);
|
||||||
|
|
||||||
sched = v->schedule_ptr;
|
if ((uint)v->num_orders + shared_orders <= (uint)WP(w,order_d).sel)
|
||||||
num=0;
|
|
||||||
while (sched->type != OT_NOTHING) {
|
|
||||||
sched++;
|
|
||||||
num++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((uint)num + shared_schedule <= (uint)WP(w,order_d).sel)
|
|
||||||
SETBIT(w->disabled_state, 5); /* delete */
|
SETBIT(w->disabled_state, 5); /* delete */
|
||||||
|
|
||||||
if (num == 0)
|
if (v->num_orders == 0)
|
||||||
SETBIT(w->disabled_state, 4); /* skip */
|
SETBIT(w->disabled_state, 4); /* skip */
|
||||||
|
|
||||||
SetVScrollCount(w, num+1);
|
SetVScrollCount(w, v->num_orders + 1);
|
||||||
|
|
||||||
sel = OrderGetSel(w);
|
sel = OrderGetSel(w);
|
||||||
|
SetDParam(2, STR_8827_FULL_LOAD);
|
||||||
|
|
||||||
SetDParam(2,STR_8827_FULL_LOAD);
|
order = GetVehicleOrder(v, sel);
|
||||||
switch (v->schedule_ptr[sel].type) {
|
|
||||||
case OT_GOTO_STATION:
|
|
||||||
break;
|
|
||||||
case OT_GOTO_DEPOT:
|
|
||||||
SETBIT(w->disabled_state, 9); /* unload */
|
|
||||||
SetDParam(2,STR_SERVICE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OT_GOTO_WAYPOINT:
|
if (order != NULL) {
|
||||||
SETBIT(w->disabled_state, 8); /* full load */
|
switch (order->type) {
|
||||||
SETBIT(w->disabled_state, 9); /* unload */
|
case OT_GOTO_STATION:
|
||||||
break;
|
break;
|
||||||
|
case OT_GOTO_DEPOT:
|
||||||
|
SETBIT(w->disabled_state, 9); /* unload */
|
||||||
|
SetDParam(2,STR_SERVICE);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
case OT_GOTO_WAYPOINT:
|
||||||
|
SETBIT(w->disabled_state, 8); /* full load */
|
||||||
|
SETBIT(w->disabled_state, 9); /* unload */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SETBIT(w->disabled_state, 6); /* nonstop */
|
||||||
|
SETBIT(w->disabled_state, 8); /* full load */
|
||||||
|
SETBIT(w->disabled_state, 9); /* unload */
|
||||||
|
}
|
||||||
|
} else {
|
||||||
SETBIT(w->disabled_state, 6); /* nonstop */
|
SETBIT(w->disabled_state, 6); /* nonstop */
|
||||||
SETBIT(w->disabled_state, 8); /* full load */
|
SETBIT(w->disabled_state, 8); /* full load */
|
||||||
SETBIT(w->disabled_state, 9); /* unload */
|
SETBIT(w->disabled_state, 9); /* unload */
|
||||||
|
@ -102,61 +94,62 @@ static void DrawOrdersWindow(Window *w)
|
||||||
|
|
||||||
y = 15;
|
y = 15;
|
||||||
|
|
||||||
i = 0;
|
i = w->vscroll.pos;
|
||||||
for(;;) {
|
order = GetVehicleOrder(v, i);
|
||||||
str = ((byte)v->cur_order_index == i) ? STR_8805 : STR_8804;
|
while (order != NULL) {
|
||||||
|
str = (v->cur_order_index == i) ? STR_8805 : STR_8804;
|
||||||
|
|
||||||
ord = v->schedule_ptr[i];
|
if (i - w->vscroll.pos < 6) {
|
||||||
|
SetDParam(1, 6);
|
||||||
|
|
||||||
if ( (uint)(i - w->vscroll.pos) < 6) {
|
if (order->type == OT_GOTO_STATION) {
|
||||||
|
SetDParam(1, STR_8806_GO_TO + (order->flags >> 1));
|
||||||
if (ord.type == OT_NOTHING) {
|
SetDParam(2, order->station);
|
||||||
str = shared_schedule ? STR_END_OF_SHARED_ORDERS : STR_882A_END_OF_ORDERS;
|
} else if (order->type == OT_GOTO_DEPOT) {
|
||||||
} else {
|
StringID s = STR_NULL;
|
||||||
SetDParam(1, 6);
|
if (v->type == VEH_Aircraft) {
|
||||||
|
s = STR_GO_TO_AIRPORT_HANGAR;
|
||||||
if (ord.type == OT_GOTO_STATION) {
|
SetDParam(2, order->station);
|
||||||
SetDParam(1, STR_8806_GO_TO + (ord.flags >> 1));
|
|
||||||
SetDParam(2, ord.station);
|
|
||||||
} else if (ord.type == OT_GOTO_DEPOT) {
|
|
||||||
StringID s = STR_NULL;
|
|
||||||
if (v->type == VEH_Aircraft) {
|
|
||||||
s = STR_GO_TO_AIRPORT_HANGAR;
|
|
||||||
SetDParam(2, ord.station);
|
|
||||||
} else {
|
|
||||||
SetDParam(2, _depots[ord.station].town_index);
|
|
||||||
switch (v->type) {
|
|
||||||
case VEH_Train: s = STR_880E_GO_TO_TRAIN_DEPOT; break;
|
|
||||||
case VEH_Road: s = STR_9038_GO_TO_ROADVEH_DEPOT; break;
|
|
||||||
case VEH_Ship: s = STR_GO_TO_SHIP_DEPOT; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (v->type == VEH_Train && ord.flags & OF_NON_STOP) s += 2;
|
|
||||||
if (ord.flags & OF_FULL_LOAD) ++s; /* XXX service */
|
|
||||||
SetDParam(1, s);
|
|
||||||
} else if (ord.type == OT_GOTO_WAYPOINT) {
|
|
||||||
SetDParam(2, ord.station);
|
|
||||||
SetDParam(1, (ord.flags & OF_NON_STOP) ? STR_GO_NON_STOP_TO_WAYPOINT : STR_GO_TO_WAYPOINT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
byte color = (i == WP(w,order_d).sel) ? 0xC : 0x10;
|
|
||||||
SetDParam(0, i+1);
|
|
||||||
if (ord.type != OT_DUMMY) {
|
|
||||||
DrawString(2, y, str, color);
|
|
||||||
} else {
|
} else {
|
||||||
SetDParam(1, STR_INVALID_ORDER);
|
SetDParam(2, _depots[order->station].town_index);
|
||||||
SetDParam(2, ord.station);
|
switch (v->type) {
|
||||||
DrawString(2, y, str, color);
|
case VEH_Train: s = STR_880E_GO_TO_TRAIN_DEPOT; break;
|
||||||
|
case VEH_Road: s = STR_9038_GO_TO_ROADVEH_DEPOT; break;
|
||||||
|
case VEH_Ship: s = STR_GO_TO_SHIP_DEPOT; break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (v->type == VEH_Train && order->flags & OF_NON_STOP)
|
||||||
|
s += 2;
|
||||||
|
|
||||||
|
if (order->flags & OF_FULL_LOAD)
|
||||||
|
s++; /* XXX service */
|
||||||
|
|
||||||
|
SetDParam(1, s);
|
||||||
|
} else if (order->type == OT_GOTO_WAYPOINT) {
|
||||||
|
SetDParam(1, (order->flags & OF_NON_STOP) ? STR_GO_NON_STOP_TO_WAYPOINT : STR_GO_TO_WAYPOINT);
|
||||||
|
SetDParam(2, order->station);
|
||||||
|
}
|
||||||
|
|
||||||
|
color = (i == WP(w,order_d).sel) ? 0xC : 0x10;
|
||||||
|
SetDParam(0, i + 1);
|
||||||
|
if (order->type != OT_DUMMY) {
|
||||||
|
DrawString(2, y, str, color);
|
||||||
|
} else {
|
||||||
|
SetDParam(1, STR_INVALID_ORDER);
|
||||||
|
SetDParam(2, order->station);
|
||||||
|
DrawString(2, y, str, color);
|
||||||
}
|
}
|
||||||
y += 10;
|
y += 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
order = order->next;
|
||||||
|
}
|
||||||
|
|
||||||
if (ord.type == OT_NOTHING)
|
if (i - w->vscroll.pos < 6) {
|
||||||
break;
|
str = shared_orders ? STR_END_OF_SHARED_ORDERS : STR_882A_END_OF_ORDERS;
|
||||||
|
color = (i == WP(w,order_d).sel) ? 0xC : 0x10;
|
||||||
|
DrawString(2, y, str, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,12 +310,6 @@ static void OrdersPlaceObj(Vehicle *v, uint tile, Window *w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum OrderFlags {
|
|
||||||
FULL_LOAD = 0,
|
|
||||||
UNLOAD = 1,
|
|
||||||
NON_STOP = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
static void OrderClick_Goto(Window *w, Vehicle *v)
|
static void OrderClick_Goto(Window *w, Vehicle *v)
|
||||||
{
|
{
|
||||||
InvalidateWidget(w, 7);
|
InvalidateWidget(w, 7);
|
||||||
|
@ -337,27 +324,27 @@ static void OrderClick_Goto(Window *w, Vehicle *v)
|
||||||
|
|
||||||
static void OrderClick_FullLoad(Window *w, Vehicle *v)
|
static void OrderClick_FullLoad(Window *w, Vehicle *v)
|
||||||
{
|
{
|
||||||
DoCommandP(v->tile, v->index, OrderGetSel(w) | (FULL_LOAD << 8), NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
|
DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), OFB_FULL_LOAD, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OrderClick_Unload(Window *w, Vehicle *v)
|
static void OrderClick_Unload(Window *w, Vehicle *v)
|
||||||
{
|
{
|
||||||
DoCommandP(v->tile, v->index, OrderGetSel(w) | (UNLOAD << 8), NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
|
DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), OFB_UNLOAD, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
|
||||||
}
|
|
||||||
|
|
||||||
static void OrderClick_Skip(Window *w, Vehicle *v)
|
|
||||||
{
|
|
||||||
DoCommandP(v->tile,v->index, 0, NULL, CMD_SKIP_ORDER);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OrderClick_Delete(Window *w, Vehicle *v)
|
|
||||||
{
|
|
||||||
DoCommandP(v->tile,v->index, OrderGetSel(w), NULL, CMD_DELETE_ORDER | CMD_MSG(STR_8834_CAN_T_DELETE_THIS_ORDER));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OrderClick_Nonstop(Window *w, Vehicle *v)
|
static void OrderClick_Nonstop(Window *w, Vehicle *v)
|
||||||
{
|
{
|
||||||
DoCommandP(v->tile, v->index, OrderGetSel(w) | (NON_STOP << 8), NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
|
DoCommandP(v->tile, v->index + (OrderGetSel(w) << 16), OFB_NON_STOP, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void OrderClick_Skip(Window *w, Vehicle *v)
|
||||||
|
{
|
||||||
|
DoCommandP(v->tile, v->index, 0, NULL, CMD_SKIP_ORDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void OrderClick_Delete(Window *w, Vehicle *v)
|
||||||
|
{
|
||||||
|
DoCommandP(v->tile, v->index, OrderGetSel(w), NULL, CMD_DELETE_ORDER | CMD_MSG(STR_8834_CAN_T_DELETE_THIS_ORDER));
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void OnButtonClick(Window *w, Vehicle *v);
|
typedef void OnButtonClick(Window *w, Vehicle *v);
|
||||||
|
@ -399,18 +386,18 @@ 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) {
|
||||||
Order ord = v->schedule_ptr[sel];
|
Order *ord = GetVehicleOrder(v, sel);
|
||||||
int xy = 0;
|
int xy = 0;
|
||||||
switch (ord.type) {
|
switch (ord->type) {
|
||||||
case OT_GOTO_STATION: /* station order */
|
case OT_GOTO_STATION: /* station order */
|
||||||
xy = GetStation(ord.station)->xy ;
|
xy = GetStation(ord->station)->xy ;
|
||||||
break;
|
break;
|
||||||
case OT_GOTO_DEPOT: /* goto depot order */
|
case OT_GOTO_DEPOT: /* goto depot order */
|
||||||
xy = _depots[ord.station].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.station].xy;
|
xy = _waypoints[ord->station].xy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xy)
|
if (xy)
|
||||||
|
@ -447,7 +434,6 @@ static void OrdersWndProc(Window *w, WindowEvent *e)
|
||||||
case 9: /* unload button */
|
case 9: /* unload button */
|
||||||
OrderClick_Unload(w, v);
|
OrderClick_Unload(w, v);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -473,7 +459,7 @@ static void OrdersWndProc(Window *w, WindowEvent *e)
|
||||||
case WE_RCLICK: {
|
case WE_RCLICK: {
|
||||||
Vehicle *v = GetVehicle(w->window_number);
|
Vehicle *v = GetVehicle(w->window_number);
|
||||||
if (e->click.widget != 8) break;
|
if (e->click.widget != 8) break;
|
||||||
if (v->schedule_ptr[OrderGetSel(w)].type == OT_GOTO_DEPOT)
|
if (GetVehicleOrder(v, 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);
|
||||||
|
|
|
@ -768,10 +768,11 @@ static void DoDeleteWaypoint(Waypoint *cp)
|
||||||
{
|
{
|
||||||
Order order;
|
Order order;
|
||||||
cp->xy = 0;
|
cp->xy = 0;
|
||||||
|
|
||||||
order.type = OT_GOTO_WAYPOINT;
|
order.type = OT_GOTO_WAYPOINT;
|
||||||
order.flags = 0;
|
|
||||||
order.station = cp - _waypoints;
|
order.station = cp - _waypoints;
|
||||||
DeleteCommandFromVehicleSchedule(order);
|
DeleteDestinationFromVehicleOrder(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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ int32 CmdBuildRoadVeh(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
return cost;
|
return cost;
|
||||||
|
|
||||||
v = AllocateVehicle();
|
v = AllocateVehicle();
|
||||||
if (v == NULL || _ptr_to_next_order >= endof(_order_array))
|
if (v == NULL || IsOrderPoolFull())
|
||||||
return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
|
return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
|
||||||
|
|
||||||
/* find the first free roadveh id */
|
/* find the first free roadveh id */
|
||||||
|
@ -172,9 +172,6 @@ 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;
|
||||||
_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;
|
||||||
|
|
||||||
|
@ -554,11 +551,11 @@ static void HandleBrokenRoadVeh(Vehicle *v)
|
||||||
|
|
||||||
static void ProcessRoadVehOrder(Vehicle *v)
|
static void ProcessRoadVehOrder(Vehicle *v)
|
||||||
{
|
{
|
||||||
Order order;
|
const Order *order;
|
||||||
Station *st;
|
const Station *st;
|
||||||
|
|
||||||
if (v->current_order.type >= OT_GOTO_DEPOT && v->current_order.type <= 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 orderlist interrupt.
|
||||||
if (v->current_order.type != OT_GOTO_DEPOT ||
|
if (v->current_order.type != OT_GOTO_DEPOT ||
|
||||||
!(v->current_order.flags & OF_UNLOAD))
|
!(v->current_order.flags & OF_UNLOAD))
|
||||||
return;
|
return;
|
||||||
|
@ -573,34 +570,35 @@ static void ProcessRoadVehOrder(Vehicle *v)
|
||||||
if (v->cur_order_index >= v->num_orders)
|
if (v->cur_order_index >= v->num_orders)
|
||||||
v->cur_order_index = 0;
|
v->cur_order_index = 0;
|
||||||
|
|
||||||
order = v->schedule_ptr[v->cur_order_index];
|
order = GetVehicleOrder(v, v->cur_order_index);
|
||||||
|
|
||||||
if (order.type == OT_NOTHING) {
|
if (order == NULL) {
|
||||||
v->current_order.type = OT_NOTHING;
|
v->current_order.type = OT_NOTHING;
|
||||||
v->current_order.flags = 0;
|
v->current_order.flags = 0;
|
||||||
v->dest_tile = 0;
|
v->dest_tile = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (order.type == v->current_order.type &&
|
if (order->type == v->current_order.type &&
|
||||||
order.flags == v->current_order.flags &&
|
order->flags == v->current_order.flags &&
|
||||||
order.station == v->current_order.station)
|
order->station == v->current_order.station)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
v->current_order = order;
|
v->current_order = *order;
|
||||||
|
|
||||||
v->dest_tile = 0;
|
v->dest_tile = 0;
|
||||||
|
|
||||||
if (order.type == OT_GOTO_STATION) {
|
if (order->type == OT_GOTO_STATION) {
|
||||||
if (order.station == v->last_station_visited)
|
if (order->station == v->last_station_visited)
|
||||||
v->last_station_visited = 0xFFFF;
|
v->last_station_visited = 0xFFFF;
|
||||||
st = GetStation(order.station);
|
|
||||||
v->dest_tile = v->cargo_type==CT_PASSENGERS ? st->bus_tile : st->lorry_tile;
|
st = GetStation(order->station);
|
||||||
} else if (order.type == OT_GOTO_DEPOT) {
|
v->dest_tile = v->cargo_type == CT_PASSENGERS ? st->bus_tile : st->lorry_tile;
|
||||||
v->dest_tile = _depots[order.station].xy;
|
} else if (order->type == OT_GOTO_DEPOT) {
|
||||||
|
v->dest_tile = _depots[order->station].xy;
|
||||||
}
|
}
|
||||||
|
|
||||||
InvalidateVehicleOrderWidget(v);
|
InvalidateVehicleOrder(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleRoadVehLoading(Vehicle *v)
|
static void HandleRoadVehLoading(Vehicle *v)
|
||||||
|
@ -634,7 +632,7 @@ static void HandleRoadVehLoading(Vehicle *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
v->cur_order_index++;
|
v->cur_order_index++;
|
||||||
InvalidateVehicleOrderWidget(v);
|
InvalidateVehicleOrder(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StartRoadVehSound(Vehicle *v)
|
static void StartRoadVehSound(Vehicle *v)
|
||||||
|
@ -1390,7 +1388,7 @@ void RoadVehEnterDepot(Vehicle *v)
|
||||||
v->current_order.type = OT_DUMMY;
|
v->current_order.type = OT_DUMMY;
|
||||||
v->current_order.flags = 0;
|
v->current_order.flags = 0;
|
||||||
|
|
||||||
// Part of the schedule?
|
// Part of the orderlist?
|
||||||
if (t.flags & OF_UNLOAD) {
|
if (t.flags & OF_UNLOAD) {
|
||||||
v->cur_order_index++;
|
v->cur_order_index++;
|
||||||
} else if (t.flags & OF_FULL_LOAD) {
|
} else if (t.flags & OF_FULL_LOAD) {
|
||||||
|
@ -1436,7 +1434,7 @@ static void CheckIfRoadVehNeedsService(Vehicle *v)
|
||||||
if (v->vehstatus & VS_STOPPED)
|
if (v->vehstatus & VS_STOPPED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_patches.gotodepot && ScheduleHasDepotOrders(v->schedule_ptr))
|
if (_patches.gotodepot && VehicleHasDepotOrders(v))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// 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
|
||||||
|
|
12
saveload.c
12
saveload.c
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SAVEGAME_MAJOR_VERSION = 5,
|
SAVEGAME_MAJOR_VERSION = 5,
|
||||||
SAVEGAME_MINOR_VERSION = 1,
|
SAVEGAME_MINOR_VERSION = 2,
|
||||||
|
|
||||||
SAVEGAME_LOADABLE_VERSION = (SAVEGAME_MAJOR_VERSION << 8) + SAVEGAME_MINOR_VERSION
|
SAVEGAME_LOADABLE_VERSION = (SAVEGAME_MAJOR_VERSION << 8) + SAVEGAME_MINOR_VERSION
|
||||||
};
|
};
|
||||||
|
@ -869,6 +869,7 @@ static void UninitWriteZlib()
|
||||||
extern const ChunkHandler _misc_chunk_handlers[];
|
extern const ChunkHandler _misc_chunk_handlers[];
|
||||||
extern const ChunkHandler _player_chunk_handlers[];
|
extern const ChunkHandler _player_chunk_handlers[];
|
||||||
extern const ChunkHandler _veh_chunk_handlers[];
|
extern const ChunkHandler _veh_chunk_handlers[];
|
||||||
|
extern const ChunkHandler _order_chunk_handlers[];
|
||||||
extern const ChunkHandler _town_chunk_handlers[];
|
extern const ChunkHandler _town_chunk_handlers[];
|
||||||
extern const ChunkHandler _sign_chunk_handlers[];
|
extern const ChunkHandler _sign_chunk_handlers[];
|
||||||
extern const ChunkHandler _station_chunk_handlers[];
|
extern const ChunkHandler _station_chunk_handlers[];
|
||||||
|
@ -880,6 +881,7 @@ extern const ChunkHandler _animated_tile_chunk_handlers[];
|
||||||
static const ChunkHandler * const _chunk_handlers[] = {
|
static const ChunkHandler * const _chunk_handlers[] = {
|
||||||
_misc_chunk_handlers,
|
_misc_chunk_handlers,
|
||||||
_veh_chunk_handlers,
|
_veh_chunk_handlers,
|
||||||
|
_order_chunk_handlers,
|
||||||
_industry_chunk_handlers,
|
_industry_chunk_handlers,
|
||||||
_economy_chunk_handlers,
|
_economy_chunk_handlers,
|
||||||
_engine_chunk_handlers,
|
_engine_chunk_handlers,
|
||||||
|
@ -912,9 +914,7 @@ static uint ReferenceToInt(void *v, uint t)
|
||||||
case REF_VEHICLE: return ((Vehicle *)v)->index + 1;
|
case REF_VEHICLE: return ((Vehicle *)v)->index + 1;
|
||||||
case REF_STATION: return ((Station *)v)->index + 1;
|
case REF_STATION: return ((Station *)v)->index + 1;
|
||||||
case REF_TOWN: return ((Town *)v)->index + 1;
|
case REF_TOWN: return ((Town *)v)->index + 1;
|
||||||
|
case REF_ORDER: return ((Order *)v)->index + 1;
|
||||||
case REF_SCHEDULE:
|
|
||||||
return ((byte*)v - (byte*)_order_array) / sizeof(_order_array[0]) + 1;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
|
@ -935,13 +935,11 @@ void *IntToReference(uint r, uint t)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
switch (t) {
|
switch (t) {
|
||||||
|
case REF_ORDER: return GetOrder(r - 1);
|
||||||
case REF_VEHICLE: return GetVehicle(r - 1);
|
case REF_VEHICLE: return GetVehicle(r - 1);
|
||||||
case REF_STATION: return GetStation(r - 1);
|
case REF_STATION: return GetStation(r - 1);
|
||||||
case REF_TOWN: return GetTown(r - 1);
|
case REF_TOWN: return GetTown(r - 1);
|
||||||
|
|
||||||
case REF_SCHEDULE:
|
|
||||||
return (byte*)_order_array + (r - 1) * sizeof(_order_array[0]);
|
|
||||||
|
|
||||||
case REF_VEHICLE_OLD: {
|
case REF_VEHICLE_OLD: {
|
||||||
/* Old vehicles were saved differently: invalid vehicle was 0xFFFF,
|
/* Old vehicles were saved differently: invalid vehicle was 0xFFFF,
|
||||||
and the index was not - 1.. correct for this */
|
and the index was not - 1.. correct for this */
|
||||||
|
|
10
saveload.h
10
saveload.h
|
@ -70,11 +70,11 @@ typedef struct {
|
||||||
extern SaverLoader _sl;
|
extern SaverLoader _sl;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
REF_SCHEDULE = 0,
|
REF_ORDER = 0,
|
||||||
REF_VEHICLE = 1,
|
REF_VEHICLE = 1,
|
||||||
REF_STATION = 2,
|
REF_STATION = 2,
|
||||||
REF_TOWN = 3,
|
REF_TOWN = 3,
|
||||||
REF_VEHICLE_OLD = 4,
|
REF_VEHICLE_OLD = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
53
ship_cmd.c
53
ship_cmd.c
|
@ -23,13 +23,13 @@ static byte GetTileShipTrackStatus(uint tile) {
|
||||||
|
|
||||||
void InvalidateShipWindows(const Vehicle *v)
|
void InvalidateShipWindows(const Vehicle *v)
|
||||||
{
|
{
|
||||||
const Order *o;
|
const Order *order;
|
||||||
|
|
||||||
InvalidateWindow(WC_SHIPS_LIST, v->owner);
|
InvalidateWindow(WC_SHIPS_LIST, v->owner);
|
||||||
|
|
||||||
for ( o = v->schedule_ptr; o->type != OT_NOTHING; o++) {
|
FOR_VEHICLE_ORDERS(v, order) {
|
||||||
if (o->type == OT_GOTO_STATION ) {
|
if (order->type == OT_GOTO_STATION ) {
|
||||||
InvalidateWindow(WC_SHIPS_LIST, o->station << 16 | v->owner);
|
InvalidateWindow(WC_SHIPS_LIST, (order->station << 16) | v->owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ static void CheckIfShipNeedsService(Vehicle *v)
|
||||||
v->current_order.flags & OF_FULL_LOAD)
|
v->current_order.flags & OF_FULL_LOAD)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_patches.gotodepot && ScheduleHasDepotOrders(v->schedule_ptr))
|
if (_patches.gotodepot && VehicleHasDepotOrders(v))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
i = FindClosestShipDepot(v);
|
i = FindClosestShipDepot(v);
|
||||||
|
@ -215,8 +215,7 @@ static const TileIndexDiffC _dock_offs[] = {
|
||||||
|
|
||||||
static void ProcessShipOrder(Vehicle *v)
|
static void ProcessShipOrder(Vehicle *v)
|
||||||
{
|
{
|
||||||
Order order;
|
const Order *order;
|
||||||
Station *st;
|
|
||||||
|
|
||||||
if (v->current_order.type >= OT_GOTO_DEPOT &&
|
if (v->current_order.type >= OT_GOTO_DEPOT &&
|
||||||
v->current_order.type <= OT_LEAVESTATION) {
|
v->current_order.type <= OT_LEAVESTATION) {
|
||||||
|
@ -235,36 +234,39 @@ static void ProcessShipOrder(Vehicle *v)
|
||||||
if (v->cur_order_index >= v->num_orders)
|
if (v->cur_order_index >= v->num_orders)
|
||||||
v->cur_order_index = 0;
|
v->cur_order_index = 0;
|
||||||
|
|
||||||
order = v->schedule_ptr[v->cur_order_index];
|
order = GetVehicleOrder(v, v->cur_order_index);
|
||||||
|
|
||||||
if (order.type == OT_NOTHING) {
|
if (order == NULL) {
|
||||||
v->current_order.type = OT_NOTHING;
|
v->current_order.type = OT_NOTHING;
|
||||||
v->current_order.flags = 0;
|
v->current_order.flags = 0;
|
||||||
v->dest_tile = 0;
|
v->dest_tile = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (order.type == v->current_order.type &&
|
if (order->type == v->current_order.type &&
|
||||||
order.flags == v->current_order.flags &&
|
order->flags == v->current_order.flags &&
|
||||||
order.station == v->current_order.station)
|
order->station == v->current_order.station)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
v->current_order = order;
|
v->current_order = *order;
|
||||||
|
|
||||||
if (order.type == OT_GOTO_STATION) {
|
if (order->type == OT_GOTO_STATION) {
|
||||||
if (order.station == v->last_station_visited)
|
const Station *st;
|
||||||
|
|
||||||
|
if (order->station == v->last_station_visited)
|
||||||
v->last_station_visited = 0xFFFF;
|
v->last_station_visited = 0xFFFF;
|
||||||
|
|
||||||
st = GetStation(order.station);
|
st = GetStation(order->station);
|
||||||
if (st->dock_tile != 0) {
|
if (st->dock_tile != 0) {
|
||||||
v->dest_tile = TILE_ADD(st->dock_tile, ToTileIndexDiff(_dock_offs[_map5[st->dock_tile]-0x4B]));
|
v->dest_tile = TILE_ADD(st->dock_tile, ToTileIndexDiff(_dock_offs[_map5[st->dock_tile]-0x4B]));
|
||||||
}
|
}
|
||||||
} else if (order.type == OT_GOTO_DEPOT) {
|
} else if (order->type == OT_GOTO_DEPOT) {
|
||||||
v->dest_tile = _depots[order.station].xy;
|
v->dest_tile = _depots[order->station].xy;
|
||||||
} else {
|
} else {
|
||||||
v->dest_tile = 0;
|
v->dest_tile = 0;
|
||||||
}
|
}
|
||||||
InvalidateVehicleOrderWidget(v);
|
|
||||||
|
InvalidateVehicleOrder(v);
|
||||||
|
|
||||||
InvalidateShipWindows(v);
|
InvalidateShipWindows(v);
|
||||||
}
|
}
|
||||||
|
@ -301,7 +303,7 @@ static void HandleShipLoading(Vehicle *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
v->cur_order_index++;
|
v->cur_order_index++;
|
||||||
InvalidateVehicleOrderWidget(v);
|
InvalidateVehicleOrder(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UpdateShipDeltaXY(Vehicle *v, int dir)
|
static void UpdateShipDeltaXY(Vehicle *v, int dir)
|
||||||
|
@ -692,7 +694,7 @@ static void ShipController(Vehicle *v)
|
||||||
|
|
||||||
v->last_station_visited = v->current_order.station;
|
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 orderlist. Don't do that for buoys (HVOT_BUOY) */
|
||||||
st = GetStation(v->current_order.station);
|
st = GetStation(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 */
|
||||||
|
@ -711,7 +713,7 @@ static void ShipController(Vehicle *v)
|
||||||
v->current_order.type = OT_LEAVESTATION;
|
v->current_order.type = OT_LEAVESTATION;
|
||||||
v->current_order.flags = 0;
|
v->current_order.flags = 0;
|
||||||
v->cur_order_index++;
|
v->cur_order_index++;
|
||||||
InvalidateVehicleOrderWidget(v);
|
InvalidateVehicleOrder(v);
|
||||||
}
|
}
|
||||||
goto else_end;
|
goto else_end;
|
||||||
}
|
}
|
||||||
|
@ -830,7 +832,7 @@ int32 CmdBuildShip(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
v = AllocateVehicle();
|
v = AllocateVehicle();
|
||||||
if (v == NULL || _ptr_to_next_order >= endof(_order_array) ||
|
if (v == NULL || IsOrderPoolFull() ||
|
||||||
(unit_num = GetFreeUnitNumber(VEH_Ship)) > _patches.max_ships)
|
(unit_num = GetFreeUnitNumber(VEH_Ship)) > _patches.max_ships)
|
||||||
return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
|
return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
|
||||||
|
|
||||||
|
@ -871,9 +873,6 @@ 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;
|
||||||
_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;
|
||||||
|
|
23
ship_gui.c
23
ship_gui.c
|
@ -863,15 +863,14 @@ void ShowShipDepotWindow(uint tile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void DrawSmallShipSchedule(Vehicle *v, int x, int y) {
|
static void DrawSmallOrderList(Vehicle *v, int x, int y) {
|
||||||
Order *sched;
|
const Order *order;
|
||||||
int sel;
|
int sel, i = 0;
|
||||||
Station *st;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
sel = v->cur_order_index;
|
sel = v->cur_order_index;
|
||||||
|
order = v->orders;
|
||||||
|
|
||||||
for (sched = v->schedule_ptr; sched->type != OT_NOTHING; ++sched) {
|
while (order != NULL) {
|
||||||
if (sel == 0) {
|
if (sel == 0) {
|
||||||
_stringwidth_base = 0xE0;
|
_stringwidth_base = 0xE0;
|
||||||
DoDrawString( "\xAF", x-6, y, 16);
|
DoDrawString( "\xAF", x-6, y, 16);
|
||||||
|
@ -879,11 +878,9 @@ static void DrawSmallShipSchedule(Vehicle *v, int x, int y) {
|
||||||
}
|
}
|
||||||
sel--;
|
sel--;
|
||||||
|
|
||||||
if (sched->type == OT_GOTO_STATION) {
|
if (order->type == OT_GOTO_STATION) {
|
||||||
st = GetStation(sched->station);
|
if (!(GetStation(order->station)->had_vehicle_of_type & HVOT_BUOY)) {
|
||||||
|
SetDParam(0, order->station);
|
||||||
if (!(st->had_vehicle_of_type & HVOT_BUOY)) {
|
|
||||||
SetDParam(0, sched->station);
|
|
||||||
DrawString(x, y, STR_A036, 0);
|
DrawString(x, y, STR_A036, 0);
|
||||||
|
|
||||||
y += 6;
|
y += 6;
|
||||||
|
@ -891,6 +888,8 @@ static void DrawSmallShipSchedule(Vehicle *v, int x, int y) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
order = order->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -998,7 +997,7 @@ static void PlayerShipsWndProc(Window *w, WindowEvent *e)
|
||||||
DrawString(x + 12, y, STR_01AB, 0);
|
DrawString(x + 12, y, STR_01AB, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawSmallShipSchedule(v, x + 138, y);
|
DrawSmallOrderList(v, x + 138, y);
|
||||||
|
|
||||||
y += PLY_WND_PRC__SIZE_OF_ROW_BIG;
|
y += PLY_WND_PRC__SIZE_OF_ROW_BIG;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ enum {
|
||||||
|
|
||||||
void ModifyStationRatingAround(TileIndex tile, byte owner, int amount, uint radius);
|
void ModifyStationRatingAround(TileIndex tile, byte owner, int amount, uint radius);
|
||||||
|
|
||||||
TileIndex GetStationTileForVehicle(Vehicle *v, Station *st);
|
TileIndex GetStationTileForVehicle(const Vehicle *v, const Station *st);
|
||||||
|
|
||||||
void ShowStationViewWindow(int station);
|
void ShowStationViewWindow(int station);
|
||||||
void UpdateAllStationVirtCoord();
|
void UpdateAllStationVirtCoord();
|
||||||
|
|
|
@ -94,7 +94,7 @@ static Station *GetStationAround(uint tile, int w, int h, int closest_station)
|
||||||
return (closest_station == -1) ? NULL : GetStation(closest_station);
|
return (closest_station == -1) ? NULL : GetStation(closest_station);
|
||||||
}
|
}
|
||||||
|
|
||||||
TileIndex GetStationTileForVehicle(Vehicle *v, Station *st)
|
TileIndex GetStationTileForVehicle(const Vehicle *v, const Station *st)
|
||||||
{
|
{
|
||||||
switch (v->type) {
|
switch (v->type) {
|
||||||
case VEH_Train: return st->train_tile;
|
case VEH_Train: return st->train_tile;
|
||||||
|
@ -2257,10 +2257,11 @@ static void DeleteStation(Station *st)
|
||||||
|
|
||||||
index = st->index;
|
index = st->index;
|
||||||
DeleteWindowById(WC_STATION_VIEW, index);
|
DeleteWindowById(WC_STATION_VIEW, index);
|
||||||
|
|
||||||
order.type = OT_GOTO_STATION;
|
order.type = OT_GOTO_STATION;
|
||||||
order.flags = 0;
|
|
||||||
order.station = index;
|
order.station = index;
|
||||||
DeleteCommandFromVehicleSchedule(order);
|
DeleteDestinationFromVehicleOrder(order);
|
||||||
|
|
||||||
DeleteSubsidyWithStation(index);
|
DeleteSubsidyWithStation(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
98
train_cmd.c
98
train_cmd.c
|
@ -395,7 +395,7 @@ int32 CmdBuildRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
|
|
||||||
if (!(flags & DC_QUERY_COST)) {
|
if (!(flags & DC_QUERY_COST)) {
|
||||||
v = AllocateVehicle();
|
v = AllocateVehicle();
|
||||||
if (v == NULL || _ptr_to_next_order >= endof(_order_array))
|
if (v == NULL || IsOrderPoolFull())
|
||||||
return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
|
return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
|
||||||
|
|
||||||
unit_num = GetFreeUnitNumber(VEH_Train);
|
unit_num = GetFreeUnitNumber(VEH_Train);
|
||||||
|
@ -417,24 +417,13 @@ int32 CmdBuildRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
v->u.rail.track = 0x80;
|
v->u.rail.track = 0x80;
|
||||||
v->u.rail.first_engine = 0xffff;
|
v->u.rail.first_engine = 0xffff;
|
||||||
v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
|
v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
|
||||||
// v->subtype = 0;
|
|
||||||
v->spritenum = rvi->image_index;
|
v->spritenum = rvi->image_index;
|
||||||
v->cargo_type = rvi->cargo_type;
|
v->cargo_type = rvi->cargo_type;
|
||||||
v->cargo_cap = rvi->capacity;
|
v->cargo_cap = rvi->capacity;
|
||||||
v->max_speed = rvi->max_speed;
|
v->max_speed = rvi->max_speed;
|
||||||
// v->cargo_count = 0;
|
|
||||||
v->value = value;
|
v->value = value;
|
||||||
// v->day_counter = 0;
|
|
||||||
// v->current_order = 0;
|
|
||||||
// v->next_station = 0;
|
|
||||||
// v->load_unload_time_rem = 0;
|
|
||||||
// v->progress = 0;
|
|
||||||
// v->targetairport = 0;
|
|
||||||
// v->crash_anim_pos = 0;
|
|
||||||
v->last_station_visited = 0xFFFF;
|
v->last_station_visited = 0xFFFF;
|
||||||
v->dest_tile = 0;
|
v->dest_tile = 0;
|
||||||
// v->profit_last_year = 0;
|
|
||||||
// v->profit_this_year = 0;
|
|
||||||
|
|
||||||
v->engine_type = (byte)p1;
|
v->engine_type = (byte)p1;
|
||||||
e = &_engines[p1];
|
e = &_engines[p1];
|
||||||
|
@ -444,23 +433,10 @@ int32 CmdBuildRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
v->max_age = e->lifelength * 366;
|
v->max_age = e->lifelength * 366;
|
||||||
|
|
||||||
v->string_id = STR_SV_TRAIN_NAME;
|
v->string_id = STR_SV_TRAIN_NAME;
|
||||||
// v->cur_speed = 0;
|
|
||||||
// v->subspeed = 0;
|
|
||||||
v->u.rail.railtype = e->railtype;
|
v->u.rail.railtype = e->railtype;
|
||||||
_new_train_id = v->index;
|
_new_train_id = v->index;
|
||||||
// v->cur_order_index = 0;
|
|
||||||
// v->num_orders = 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 = NULL;
|
|
||||||
|
|
||||||
v->service_interval = _patches.servint_trains;
|
v->service_interval = _patches.servint_trains;
|
||||||
// v->breakdown_ctr = 0;
|
|
||||||
// v->breakdowns_since_last_service = 0;
|
|
||||||
// v->unk4D = 0;
|
|
||||||
v->date_of_last_service = _date;
|
v->date_of_last_service = _date;
|
||||||
v->build_year = _cur_year;
|
v->build_year = _cur_year;
|
||||||
v->type = VEH_Train;
|
v->type = VEH_Train;
|
||||||
|
@ -680,12 +656,9 @@ int32 CmdMoveRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
// move the train to an empty line. for locomotives, we set the type to 0. for wagons, 4.
|
// move the train to an empty line. for locomotives, we set the type to 0. for wagons, 4.
|
||||||
if (is_loco) {
|
if (is_loco) {
|
||||||
if (src->subtype != 0) {
|
if (src->subtype != 0) {
|
||||||
// setting the type to 0 also involves setting up the schedule_ptr field.
|
// setting the type to 0 also involves setting up the orders field.
|
||||||
src->subtype = 0;
|
src->subtype = 0;
|
||||||
assert(src->schedule_ptr == NULL);
|
assert(src->orders == NULL);
|
||||||
_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;
|
||||||
|
@ -695,9 +668,9 @@ int32 CmdMoveRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
src->u.rail.first_engine = 0xffff;
|
src->u.rail.first_engine = 0xffff;
|
||||||
} else {
|
} else {
|
||||||
if (src->subtype == 0) {
|
if (src->subtype == 0) {
|
||||||
// the vehicle was previously a loco. need to free the schedule list and delete vehicle windows etc.
|
// the vehicle was previously a loco. need to free the order list and delete vehicle windows etc.
|
||||||
DeleteWindowById(WC_VEHICLE_VIEW, src->index);
|
DeleteWindowById(WC_VEHICLE_VIEW, src->index);
|
||||||
DeleteVehicleSchedule(src);
|
DeleteVehicleOrders(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
src->subtype = 2;
|
src->subtype = 2;
|
||||||
|
@ -1644,13 +1617,13 @@ bad:;
|
||||||
|
|
||||||
static bool ProcessTrainOrder(Vehicle *v)
|
static bool ProcessTrainOrder(Vehicle *v)
|
||||||
{
|
{
|
||||||
Order order;
|
const Order *order;
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
// These are un-interruptible
|
// These are un-interruptible
|
||||||
if (v->current_order.type >= OT_GOTO_DEPOT &&
|
if (v->current_order.type >= OT_GOTO_DEPOT &&
|
||||||
v->current_order.type <= OT_LEAVESTATION) {
|
v->current_order.type <= OT_LEAVESTATION) {
|
||||||
// Let a depot order in the schedule interrupt.
|
// Let a depot order in the orderlist interrupt.
|
||||||
if (v->current_order.type != OT_GOTO_DEPOT ||
|
if (v->current_order.type != OT_GOTO_DEPOT ||
|
||||||
!(v->current_order.flags & OF_UNLOAD))
|
!(v->current_order.flags & OF_UNLOAD))
|
||||||
return false;
|
return false;
|
||||||
|
@ -1676,10 +1649,11 @@ static bool ProcessTrainOrder(Vehicle *v)
|
||||||
// Get the current order
|
// Get the current order
|
||||||
if (v->cur_order_index >= v->num_orders)
|
if (v->cur_order_index >= v->num_orders)
|
||||||
v->cur_order_index = 0;
|
v->cur_order_index = 0;
|
||||||
order = v->schedule_ptr[v->cur_order_index];
|
|
||||||
|
order = GetVehicleOrder(v, v->cur_order_index);
|
||||||
|
|
||||||
// If no order, do nothing.
|
// If no order, do nothing.
|
||||||
if (order.type == OT_NOTHING) {
|
if (order == NULL) {
|
||||||
v->current_order.type = OT_NOTHING;
|
v->current_order.type = OT_NOTHING;
|
||||||
v->current_order.flags = 0;
|
v->current_order.flags = 0;
|
||||||
v->dest_tile = 0;
|
v->dest_tile = 0;
|
||||||
|
@ -1687,31 +1661,37 @@ static bool ProcessTrainOrder(Vehicle *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it is unchanged, keep it.
|
// If it is unchanged, keep it.
|
||||||
if (order.type == v->current_order.type &&
|
if (order->type == v->current_order.type &&
|
||||||
order.flags == v->current_order.flags &&
|
order->flags == v->current_order.flags &&
|
||||||
order.station == v->current_order.station)
|
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->current_order = order;
|
v->current_order = *order;
|
||||||
|
|
||||||
v->dest_tile = 0;
|
v->dest_tile = 0;
|
||||||
|
|
||||||
result = false;
|
result = false;
|
||||||
if (order.type == OT_GOTO_STATION) {
|
switch (order->type) {
|
||||||
if (order.station == v->last_station_visited)
|
case OT_GOTO_STATION:
|
||||||
v->last_station_visited = 0xFFFF;
|
if (order->station == v->last_station_visited)
|
||||||
v->dest_tile = GetStation(order.station)->xy;
|
v->last_station_visited = 0xFFFF;
|
||||||
result = CheckReverseTrain(v);
|
v->dest_tile = GetStation(order->station)->xy;
|
||||||
} else if (order.type == OT_GOTO_DEPOT) {
|
result = CheckReverseTrain(v);
|
||||||
v->dest_tile = _depots[order.station].xy;
|
break;
|
||||||
result = CheckReverseTrain(v);
|
|
||||||
} else if (order.type == OT_GOTO_WAYPOINT) {
|
case OT_GOTO_DEPOT:
|
||||||
v->dest_tile = _waypoints[order.station].xy;
|
v->dest_tile = _depots[order->station].xy;
|
||||||
result = CheckReverseTrain(v);
|
result = CheckReverseTrain(v);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OT_GOTO_WAYPOINT:
|
||||||
|
v->dest_tile = _waypoints[order->station].xy;
|
||||||
|
result = CheckReverseTrain(v);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
InvalidateVehicleOrderWidget(v);
|
InvalidateVehicleOrder(v);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1771,7 +1751,7 @@ static void HandleTrainLoading(Vehicle *v, bool mode)
|
||||||
|
|
||||||
v->u.rail.days_since_order_progr = 0;
|
v->u.rail.days_since_order_progr = 0;
|
||||||
v->cur_order_index++;
|
v->cur_order_index++;
|
||||||
InvalidateVehicleOrderWidget(v);
|
InvalidateVehicleOrder(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int UpdateTrainSpeed(Vehicle *v)
|
static int UpdateTrainSpeed(Vehicle *v)
|
||||||
|
@ -2669,7 +2649,7 @@ void TrainEnterDepot(Vehicle *v, uint tile)
|
||||||
v->current_order.type = OT_DUMMY;
|
v->current_order.type = OT_DUMMY;
|
||||||
v->current_order.flags = 0;
|
v->current_order.flags = 0;
|
||||||
|
|
||||||
if (t.flags & OF_UNLOAD) { // Part of the schedule?
|
if (t.flags & OF_UNLOAD) { // Part of the orderlist?
|
||||||
v->u.rail.days_since_order_progr = 0;
|
v->u.rail.days_since_order_progr = 0;
|
||||||
v->cur_order_index++;
|
v->cur_order_index++;
|
||||||
} else if (t.flags & OF_FULL_LOAD) { // User initiated?
|
} else if (t.flags & OF_FULL_LOAD) { // User initiated?
|
||||||
|
@ -2701,7 +2681,7 @@ static void CheckIfTrainNeedsService(Vehicle *v)
|
||||||
if (v->vehstatus & VS_STOPPED)
|
if (v->vehstatus & VS_STOPPED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_patches.gotodepot && ScheduleHasDepotOrders(v->schedule_ptr))
|
if (_patches.gotodepot && VehicleHasDepotOrders(v))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -2834,11 +2814,3 @@ void InitializeTrains()
|
||||||
{
|
{
|
||||||
_age_cargo_skip_counter = 1;
|
_age_cargo_skip_counter = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ScheduleHasDepotOrders(const Order *schedule)
|
|
||||||
{
|
|
||||||
for (; schedule->type != OT_NOTHING; schedule++)
|
|
||||||
if (schedule->type == OT_GOTO_DEPOT)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
1
ttd.c
1
ttd.c
|
@ -496,6 +496,7 @@ static void InitializeDynamicVariables(void)
|
||||||
_industry_sort = NULL;
|
_industry_sort = NULL;
|
||||||
|
|
||||||
_sign_size = lengthof(_sign_list);
|
_sign_size = lengthof(_sign_list);
|
||||||
|
_orders_size = lengthof(_orders);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UnInitializeDynamicVariables(void)
|
static void UnInitializeDynamicVariables(void)
|
||||||
|
|
203
vehicle.c
203
vehicle.c
|
@ -33,24 +33,6 @@ bool VehicleNeedsService(const Vehicle *v)
|
||||||
(v->date_of_last_service + v->service_interval < _date);
|
(v->date_of_last_service + v->service_interval < _date);
|
||||||
}
|
}
|
||||||
|
|
||||||
Order UnpackOldOrder(uint16 packed)
|
|
||||||
{
|
|
||||||
Order order;
|
|
||||||
order.type = (packed & 0x000f);
|
|
||||||
order.flags = (packed & 0x00f0) >> 4;
|
|
||||||
order.station = (packed & 0xff00) >> 8;
|
|
||||||
|
|
||||||
// Sanity check
|
|
||||||
// TTD stores invalid orders as OT_NOTHING with non-zero flags/station
|
|
||||||
if (order.type == OT_NOTHING && (order.flags != 0 || order.station != 0)) {
|
|
||||||
order.type = OT_DUMMY;
|
|
||||||
order.flags = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return order;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void VehicleInTheWayErrMsg(Vehicle *v)
|
void VehicleInTheWayErrMsg(Vehicle *v)
|
||||||
{
|
{
|
||||||
StringID id;
|
StringID id;
|
||||||
|
@ -177,11 +159,6 @@ void AfterLoadVehicles()
|
||||||
if (v->subtype == 0)
|
if (v->subtype == 0)
|
||||||
UpdateTrainAcceleration(v);
|
UpdateTrainAcceleration(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_DEBUG)
|
|
||||||
if (!(v->schedule_ptr == NULL || (v->schedule_ptr >= _order_array && v->schedule_ptr < _ptr_to_next_order)))
|
|
||||||
v->schedule_ptr = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +173,7 @@ static Vehicle *InitializeVehicle(Vehicle *v)
|
||||||
memset(v, 0, sizeof(Vehicle));
|
memset(v, 0, sizeof(Vehicle));
|
||||||
v->index = index;
|
v->index = index;
|
||||||
|
|
||||||
assert(v->schedule_ptr == NULL);
|
assert(v->orders == NULL);
|
||||||
|
|
||||||
v->left_coord = INVALID_COORD;
|
v->left_coord = INVALID_COORD;
|
||||||
v->next = NULL;
|
v->next = NULL;
|
||||||
|
@ -353,8 +330,6 @@ void InitializeVehicles()
|
||||||
v->index = i++;
|
v->index = i++;
|
||||||
|
|
||||||
memset(_vehicle_position_hash, -1, sizeof(_vehicle_position_hash));
|
memset(_vehicle_position_hash, -1, sizeof(_vehicle_position_hash));
|
||||||
|
|
||||||
_ptr_to_next_order = _order_array;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vehicle *GetLastVehicleInChain(Vehicle *v)
|
Vehicle *GetLastVehicleInChain(Vehicle *v)
|
||||||
|
@ -439,91 +414,6 @@ uint GetWaypointByTile(uint tile)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Vehicle *IsScheduleShared(Vehicle *u)
|
|
||||||
{
|
|
||||||
const Order *sched = u->schedule_ptr;
|
|
||||||
Vehicle *v;
|
|
||||||
|
|
||||||
FOR_ALL_VEHICLES(v) {
|
|
||||||
if (v->schedule_ptr == sched && u != v && v->type != 0)
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeleteVehicleSchedule(Vehicle *v)
|
|
||||||
{
|
|
||||||
Order *sched;
|
|
||||||
Order *cur;
|
|
||||||
int num;
|
|
||||||
Vehicle *u;
|
|
||||||
|
|
||||||
// if the schedule is shared, don't delete it.
|
|
||||||
if ((u = IsScheduleShared(v)) != NULL) {
|
|
||||||
v->schedule_ptr = NULL;
|
|
||||||
InvalidateWindow(WC_VEHICLE_ORDERS, u->index);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sched = v->schedule_ptr;
|
|
||||||
v->schedule_ptr = NULL;
|
|
||||||
|
|
||||||
num = v->num_orders + 1;
|
|
||||||
|
|
||||||
_ptr_to_next_order -= num;
|
|
||||||
|
|
||||||
cur = sched;
|
|
||||||
while (cur != _ptr_to_next_order) {
|
|
||||||
assert(cur < _ptr_to_next_order);
|
|
||||||
cur[0] = cur[num];
|
|
||||||
cur++;
|
|
||||||
}
|
|
||||||
|
|
||||||
FOR_ALL_VEHICLES(v) {
|
|
||||||
if (v->schedule_ptr != NULL && sched < v->schedule_ptr) {
|
|
||||||
v->schedule_ptr -= num;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeleteCommandFromVehicleSchedule(Order cmd)
|
|
||||||
{
|
|
||||||
Vehicle *v;
|
|
||||||
bool need_invalidate;
|
|
||||||
|
|
||||||
FOR_ALL_VEHICLES(v) {
|
|
||||||
if (v->type != 0 && v->schedule_ptr != NULL) {
|
|
||||||
Order *sched;
|
|
||||||
|
|
||||||
// clear last station visited
|
|
||||||
if (v->last_station_visited == cmd.station && cmd.type == OT_GOTO_STATION)
|
|
||||||
v->last_station_visited = 0xFFFF;
|
|
||||||
|
|
||||||
// check the next order
|
|
||||||
if (v->current_order.type == cmd.type &&
|
|
||||||
v->current_order.station == cmd.station) {
|
|
||||||
v->current_order.type = OT_DUMMY;
|
|
||||||
v->current_order.flags = 0;
|
|
||||||
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear the order list
|
|
||||||
need_invalidate = false;
|
|
||||||
for (sched = v->schedule_ptr; sched->type != OT_NOTHING; ++sched) {
|
|
||||||
if (sched->type == cmd.type && sched->station == cmd.station) {
|
|
||||||
sched->type = OT_DUMMY;
|
|
||||||
sched->flags = 0;
|
|
||||||
need_invalidate = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (need_invalidate)
|
|
||||||
InvalidateWindow(WC_VEHICLE_ORDERS, v->index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DoDeleteDepot(uint tile)
|
void DoDeleteDepot(uint tile)
|
||||||
{
|
{
|
||||||
Order order;
|
Order order;
|
||||||
|
@ -538,9 +428,8 @@ void DoDeleteDepot(uint tile)
|
||||||
d->xy = 0;
|
d->xy = 0;
|
||||||
|
|
||||||
order.type = OT_GOTO_DEPOT;
|
order.type = OT_GOTO_DEPOT;
|
||||||
order.flags = 0;
|
|
||||||
order.station = dep_index;
|
order.station = dep_index;
|
||||||
DeleteCommandFromVehicleSchedule(order);
|
DeleteDestinationFromVehicleOrder(order);
|
||||||
|
|
||||||
// Delete the depot
|
// Delete the depot
|
||||||
DeleteWindowById(WC_VEHICLE_DEPOT, tile);
|
DeleteWindowById(WC_VEHICLE_DEPOT, tile);
|
||||||
|
@ -553,8 +442,8 @@ void DeleteVehicle(Vehicle *v)
|
||||||
UpdateVehiclePosHash(v, INVALID_COORD, 0);
|
UpdateVehiclePosHash(v, INVALID_COORD, 0);
|
||||||
v->next_hash = 0xffff;
|
v->next_hash = 0xffff;
|
||||||
|
|
||||||
if (v->schedule_ptr != NULL)
|
if (v->orders != NULL)
|
||||||
DeleteVehicleSchedule(v);
|
DeleteVehicleOrders(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteVehicleChain(Vehicle *v)
|
void DeleteVehicleChain(Vehicle *v)
|
||||||
|
@ -1699,12 +1588,6 @@ void EndVehicleMove(Vehicle *v)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InvalidateVehicleOrderWidget(Vehicle *v)
|
|
||||||
{
|
|
||||||
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
|
|
||||||
InvalidateWindowWidget(WC_VEHICLE_ORDERS, v->index, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns true if staying in the same tile */
|
/* returns true if staying in the same tile */
|
||||||
bool GetNewVehiclePos(Vehicle *v, GetNewVehiclePosResult *gp)
|
bool GetNewVehiclePos(Vehicle *v, GetNewVehiclePosResult *gp)
|
||||||
{
|
{
|
||||||
|
@ -1846,7 +1729,7 @@ const byte _common_veh_desc[] = {
|
||||||
SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, flags), SLE_UINT8, 5, 255),
|
SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, flags), SLE_UINT8, 5, 255),
|
||||||
SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, station), SLE_UINT16, 5, 255),
|
SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, station), SLE_UINT16, 5, 255),
|
||||||
|
|
||||||
SLE_REF(Vehicle,schedule_ptr, REF_SCHEDULE),
|
SLE_REF(Vehicle,orders, REF_ORDER),
|
||||||
|
|
||||||
SLE_VAR(Vehicle,age, SLE_UINT16),
|
SLE_VAR(Vehicle,age, SLE_UINT16),
|
||||||
SLE_VAR(Vehicle,max_age, SLE_UINT16),
|
SLE_VAR(Vehicle,max_age, SLE_UINT16),
|
||||||
|
@ -1869,9 +1752,11 @@ const byte _common_veh_desc[] = {
|
||||||
SLE_VAR(Vehicle,random_bits, SLE_UINT8),
|
SLE_VAR(Vehicle,random_bits, SLE_UINT8),
|
||||||
SLE_VAR(Vehicle,waiting_triggers, SLE_UINT8),
|
SLE_VAR(Vehicle,waiting_triggers, SLE_UINT8),
|
||||||
|
|
||||||
// reserve extra space in savegame here. (currently 14 bytes)
|
SLE_REF(Vehicle,next_shared, REF_VEHICLE),
|
||||||
|
SLE_REF(Vehicle,prev_shared, REF_VEHICLE),
|
||||||
|
|
||||||
|
// reserve extra space in savegame here. (currently 10 bytes)
|
||||||
SLE_CONDARR(NullStruct,null,SLE_FILE_U8 | SLE_VAR_NULL, 2, 2, 255), /* 2 */
|
SLE_CONDARR(NullStruct,null,SLE_FILE_U8 | SLE_VAR_NULL, 2, 2, 255), /* 2 */
|
||||||
SLE_CONDARR(NullStruct,null,SLE_FILE_U16 | SLE_VAR_NULL, 2, 2, 255), /* 4 */
|
|
||||||
SLE_CONDARR(NullStruct,null,SLE_FILE_U32 | SLE_VAR_NULL, 2, 2, 255), /* 8 */
|
SLE_CONDARR(NullStruct,null,SLE_FILE_U32 | SLE_VAR_NULL, 2, 2, 255), /* 8 */
|
||||||
|
|
||||||
SLE_END()
|
SLE_END()
|
||||||
|
@ -2068,6 +1953,29 @@ static void Load_VEHS()
|
||||||
w->u.rail.first_engine = v->engine_type;
|
w->u.rail.first_engine = v->engine_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check for shared order-lists (we now use pointers for that) */
|
||||||
|
if (_sl.full_version < 0x502) {
|
||||||
|
FOR_ALL_VEHICLES(v) {
|
||||||
|
Vehicle *u;
|
||||||
|
|
||||||
|
if (v->type == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FOR_ALL_VEHICLES_FROM(u, v->index + 1) {
|
||||||
|
if (u->type == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* If a vehicle has the same orders, add the link to eachother
|
||||||
|
in both vehicles */
|
||||||
|
if (v->orders == u->orders) {
|
||||||
|
v->next_shared = u;
|
||||||
|
u->prev_shared = v;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* This is to ensure all pointers are within the limits of
|
/* This is to ensure all pointers are within the limits of
|
||||||
_vehicles_size */
|
_vehicles_size */
|
||||||
if (_vehicle_id_ctr_day >= _vehicles_size)
|
if (_vehicle_id_ctr_day >= _vehicles_size)
|
||||||
|
@ -2131,55 +2039,8 @@ static void Load_CHKP()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void Save_ORDR()
|
|
||||||
{
|
|
||||||
uint32 orders[lengthof(_order_array)];
|
|
||||||
uint len = _ptr_to_next_order - _order_array;
|
|
||||||
uint i;
|
|
||||||
|
|
||||||
assert (len <= lengthof(orders));
|
|
||||||
|
|
||||||
for (i = 0; i < len; ++i)
|
|
||||||
orders[i] = PackOrder(&_order_array[i]);
|
|
||||||
|
|
||||||
SlArray(orders, len, SLE_UINT32);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Load_ORDR()
|
|
||||||
{
|
|
||||||
uint len = SlGetFieldLength();
|
|
||||||
uint i;
|
|
||||||
|
|
||||||
if (_sl.version < 5) {
|
|
||||||
/* Older version had an other layout for orders.. convert them correctly */
|
|
||||||
uint16 orders[lengthof(_order_array)];
|
|
||||||
|
|
||||||
len /= sizeof(uint16);
|
|
||||||
assert (len <= lengthof(orders));
|
|
||||||
|
|
||||||
SlArray(orders, len, SLE_UINT16);
|
|
||||||
|
|
||||||
for (i = 0; i < len; ++i)
|
|
||||||
_order_array[i] = UnpackVersion4Order(orders[i]);
|
|
||||||
} else {
|
|
||||||
uint32 orders[lengthof(_order_array)];
|
|
||||||
|
|
||||||
len /= sizeof(uint32);
|
|
||||||
assert (len <= lengthof(orders));
|
|
||||||
|
|
||||||
SlArray(orders, len, SLE_UINT32);
|
|
||||||
|
|
||||||
for (i = 0; i < len; ++i)
|
|
||||||
_order_array[i] = UnpackOrder(orders[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
_ptr_to_next_order = _order_array + len;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ChunkHandler _veh_chunk_handlers[] = {
|
const ChunkHandler _veh_chunk_handlers[] = {
|
||||||
{ 'VEHS', Save_VEHS, Load_VEHS, CH_SPARSE_ARRAY},
|
{ 'VEHS', Save_VEHS, Load_VEHS, CH_SPARSE_ARRAY},
|
||||||
{ 'ORDR', Save_ORDR, Load_ORDR, CH_RIFF},
|
|
||||||
{ 'DEPT', Save_DEPT, Load_DEPT, CH_ARRAY},
|
{ 'DEPT', Save_DEPT, Load_DEPT, CH_ARRAY},
|
||||||
{ 'CHKP', Save_CHKP, Load_CHKP, CH_ARRAY | CH_LAST},
|
{ 'CHKP', Save_CHKP, Load_CHKP, CH_ARRAY | CH_LAST},
|
||||||
};
|
};
|
||||||
|
|
132
vehicle.h
132
vehicle.h
|
@ -2,42 +2,7 @@
|
||||||
#define VEHICLE_H
|
#define VEHICLE_H
|
||||||
|
|
||||||
#include "vehicle_gui.h"
|
#include "vehicle_gui.h"
|
||||||
|
#include "order.h"
|
||||||
/* If you change this, keep in mind that it is saved on 3 places:
|
|
||||||
- Load_ORDR, all the global orders
|
|
||||||
- Vehicle -> current_order
|
|
||||||
- REF_SHEDULE (all REFs are currently limited to 16 bits!!) */
|
|
||||||
typedef struct Order {
|
|
||||||
uint8 type;
|
|
||||||
uint8 flags;
|
|
||||||
uint16 station;
|
|
||||||
} Order;
|
|
||||||
|
|
||||||
static inline uint32 PackOrder(const Order *order)
|
|
||||||
{
|
|
||||||
return order->station << 16 | order->flags << 8 | order->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Order UnpackOrder(uint32 packed)
|
|
||||||
{
|
|
||||||
Order order;
|
|
||||||
order.type = (packed & 0x000000FF);
|
|
||||||
order.flags = (packed & 0x0000FF00) >> 8;
|
|
||||||
order.station = (packed & 0xFFFF0000) >> 16;
|
|
||||||
return order;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Order UnpackVersion4Order(uint16 packed)
|
|
||||||
{
|
|
||||||
Order order;
|
|
||||||
order.type = (packed & 0x000F);
|
|
||||||
order.flags = (packed & 0x00F0) >> 4;
|
|
||||||
order.station = (packed & 0xFF00) >> 8;
|
|
||||||
return order;
|
|
||||||
}
|
|
||||||
|
|
||||||
Order UnpackOldOrder(uint16 packed);
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct VehicleRail {
|
typedef struct VehicleRail {
|
||||||
uint16 last_speed; // NOSAVE: only used in UI
|
uint16 last_speed; // NOSAVE: only used in UI
|
||||||
|
@ -177,11 +142,16 @@ struct Vehicle {
|
||||||
byte day_counter; // increased by one for each day
|
byte day_counter; // increased by one for each day
|
||||||
byte tick_counter;// increased by one for each tick
|
byte tick_counter;// increased by one for each tick
|
||||||
|
|
||||||
// related to the current order
|
/* Begin Order-stuff */
|
||||||
byte cur_order_index;
|
Order current_order; //! The current order (+ status, like: loading)
|
||||||
byte num_orders;
|
byte cur_order_index; //! The index to the current order
|
||||||
Order current_order;
|
|
||||||
Order *schedule_ptr;
|
Order *orders; //! Pointer to the first order for this vehicle
|
||||||
|
byte num_orders; //! How many orders there are in the list
|
||||||
|
|
||||||
|
Vehicle *next_shared; //! If not NULL, this points to the next vehicle that shared the order
|
||||||
|
Vehicle *prev_shared; //! If not NULL, this points to the prev vehicle that shared the order
|
||||||
|
/* End Order-stuff */
|
||||||
|
|
||||||
// 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()
|
||||||
|
@ -248,25 +218,6 @@ enum {
|
||||||
VEH_Disaster = 0x15,
|
VEH_Disaster = 0x15,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Order types */
|
|
||||||
enum {
|
|
||||||
OT_NOTHING = 0,
|
|
||||||
OT_GOTO_STATION = 1,
|
|
||||||
OT_GOTO_DEPOT = 2,
|
|
||||||
OT_LOADING = 3,
|
|
||||||
OT_LEAVESTATION = 4,
|
|
||||||
OT_DUMMY = 5,
|
|
||||||
OT_GOTO_WAYPOINT = 6,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Order flags */
|
|
||||||
enum {
|
|
||||||
OF_UNLOAD = 0x2,
|
|
||||||
OF_FULL_LOAD = 0x4, // Also used when to force an aircraft into a depot
|
|
||||||
OF_NON_STOP = 0x8
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
enum VehStatus {
|
enum VehStatus {
|
||||||
VS_HIDDEN = 1,
|
VS_HIDDEN = 1,
|
||||||
VS_STOPPED = 2,
|
VS_STOPPED = 2,
|
||||||
|
@ -302,22 +253,11 @@ enum {
|
||||||
typedef void VehicleTickProc(Vehicle *v);
|
typedef void VehicleTickProc(Vehicle *v);
|
||||||
typedef void *VehicleFromPosProc(Vehicle *v, void *data);
|
typedef void *VehicleFromPosProc(Vehicle *v, void *data);
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
VehicleID clone;
|
|
||||||
byte orderindex;
|
|
||||||
Order order[41];
|
|
||||||
uint16 service_interval;
|
|
||||||
char name[32];
|
|
||||||
} BackuppedOrders;
|
|
||||||
|
|
||||||
void VehicleServiceInDepot(Vehicle *v);
|
void VehicleServiceInDepot(Vehicle *v);
|
||||||
void BackupVehicleOrders(Vehicle *v, BackuppedOrders *order);
|
|
||||||
void RestoreVehicleOrders(Vehicle *v, BackuppedOrders *order);
|
|
||||||
Vehicle *AllocateVehicle();
|
Vehicle *AllocateVehicle();
|
||||||
Vehicle *ForceAllocateVehicle();
|
Vehicle *ForceAllocateVehicle();
|
||||||
Vehicle *ForceAllocateSpecialVehicle();
|
Vehicle *ForceAllocateSpecialVehicle();
|
||||||
void UpdateVehiclePosHash(Vehicle *v, int x, int y);
|
void UpdateVehiclePosHash(Vehicle *v, int x, int y);
|
||||||
void InitializeVehicles();
|
|
||||||
void VehiclePositionChanged(Vehicle *v);
|
void VehiclePositionChanged(Vehicle *v);
|
||||||
void AfterLoadVehicles();
|
void AfterLoadVehicles();
|
||||||
Vehicle *GetLastVehicleInChain(Vehicle *v);
|
Vehicle *GetLastVehicleInChain(Vehicle *v);
|
||||||
|
@ -328,8 +268,6 @@ void DeleteVehicle(Vehicle *v);
|
||||||
void DeleteVehicleChain(Vehicle *v);
|
void DeleteVehicleChain(Vehicle *v);
|
||||||
void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc);
|
void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc);
|
||||||
void CallVehicleTicks();
|
void CallVehicleTicks();
|
||||||
void DeleteVehicleSchedule(Vehicle *v);
|
|
||||||
Vehicle *IsScheduleShared(Vehicle *v);
|
|
||||||
|
|
||||||
Depot *AllocateDepot();
|
Depot *AllocateDepot();
|
||||||
Waypoint *AllocateWaypoint();
|
Waypoint *AllocateWaypoint();
|
||||||
|
@ -373,16 +311,12 @@ void CheckVehicleBreakdown(Vehicle *v);
|
||||||
void AgeVehicle(Vehicle *v);
|
void AgeVehicle(Vehicle *v);
|
||||||
void MaybeReplaceVehicle(Vehicle *v);
|
void MaybeReplaceVehicle(Vehicle *v);
|
||||||
|
|
||||||
void DeleteCommandFromVehicleSchedule(Order cmd);
|
|
||||||
|
|
||||||
void BeginVehicleMove(Vehicle *v);
|
void BeginVehicleMove(Vehicle *v);
|
||||||
void EndVehicleMove(Vehicle *v);
|
void EndVehicleMove(Vehicle *v);
|
||||||
|
|
||||||
bool IsAircraftHangarTile(TileIndex tile);
|
bool IsAircraftHangarTile(TileIndex tile);
|
||||||
void ShowAircraftViewWindow(Vehicle *v);
|
void ShowAircraftViewWindow(Vehicle *v);
|
||||||
|
|
||||||
void InvalidateVehicleOrderWidget(Vehicle *v);
|
|
||||||
|
|
||||||
bool IsShipDepotTile(TileIndex tile);
|
bool IsShipDepotTile(TileIndex tile);
|
||||||
uint GetFreeUnitNumber(byte type);
|
uint GetFreeUnitNumber(byte type);
|
||||||
|
|
||||||
|
@ -397,9 +331,6 @@ int32 GetTrainRunningCost(Vehicle *v);
|
||||||
|
|
||||||
int CheckStoppedInDepot(Vehicle *v);
|
int CheckStoppedInDepot(Vehicle *v);
|
||||||
|
|
||||||
int ScheduleHasDepotOrders(const Order *schedule);
|
|
||||||
int CheckOrders(Vehicle *v);
|
|
||||||
|
|
||||||
bool VehicleNeedsService(const Vehicle *v);
|
bool VehicleNeedsService(const Vehicle *v);
|
||||||
|
|
||||||
void InvalidateAircraftWindows(const Vehicle *v);
|
void InvalidateAircraftWindows(const Vehicle *v);
|
||||||
|
@ -439,8 +370,43 @@ static inline Vehicle *GetVehicle(uint index)
|
||||||
#define FOR_ALL_VEHICLES(v) for(v = _vehicles; v != &_vehicles[_vehicles_size]; v++)
|
#define FOR_ALL_VEHICLES(v) for(v = _vehicles; v != &_vehicles[_vehicles_size]; v++)
|
||||||
#define FOR_ALL_VEHICLES_FROM(v, from) for(v = GetVehicle(from); v != &_vehicles[_vehicles_size]; v++)
|
#define FOR_ALL_VEHICLES_FROM(v, from) for(v = GetVehicle(from); v != &_vehicles[_vehicles_size]; v++)
|
||||||
|
|
||||||
VARDEF Order _order_array[5000];
|
/* Returns order 'index' of a vehicle or NULL when it doesn't exists */
|
||||||
VARDEF Order *_ptr_to_next_order;
|
static inline Order *GetVehicleOrder(const Vehicle *v, int index)
|
||||||
|
{
|
||||||
|
Order *order = v->orders;
|
||||||
|
|
||||||
|
if (index < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (order != NULL && index-- > 0)
|
||||||
|
order = order->next;
|
||||||
|
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the last order of a vehicle, or NULL if it doesn't exists */
|
||||||
|
static inline Order *GetLastVehicleOrder(const Vehicle *v)
|
||||||
|
{
|
||||||
|
Order *order = v->orders;
|
||||||
|
|
||||||
|
if (order == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (order->next != NULL)
|
||||||
|
order = order->next;
|
||||||
|
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the first vehicle of a shared-list, so we only have to walk forwards */
|
||||||
|
static inline Vehicle *GetFirstVehicleFromSharedList(Vehicle *v)
|
||||||
|
{
|
||||||
|
Vehicle *u = v;
|
||||||
|
while (u->prev_shared != NULL)
|
||||||
|
u = u->prev_shared;
|
||||||
|
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
VARDEF Depot _depots[255];
|
VARDEF Depot _depots[255];
|
||||||
|
|
||||||
|
@ -465,8 +431,6 @@ VARDEF TileIndex _last_built_train_depot_tile;
|
||||||
VARDEF TileIndex _last_built_road_depot_tile;
|
VARDEF TileIndex _last_built_road_depot_tile;
|
||||||
VARDEF TileIndex _last_built_aircraft_depot_tile;
|
VARDEF TileIndex _last_built_aircraft_depot_tile;
|
||||||
VARDEF TileIndex _last_built_ship_depot_tile;
|
VARDEF TileIndex _last_built_ship_depot_tile;
|
||||||
VARDEF TileIndex _backup_orders_tile;
|
|
||||||
VARDEF BackuppedOrders _backup_orders_data[1];
|
|
||||||
|
|
||||||
// for each player, for each vehicle type, keep a list of the vehicles.
|
// for each player, for each vehicle type, keep a list of the vehicles.
|
||||||
//VARDEF Vehicle *_vehicle_arr[8][4];
|
//VARDEF Vehicle *_vehicle_arr[8][4];
|
||||||
|
|
|
@ -90,14 +90,16 @@ void BuildVehicleList(vehiclelist_d *vl, int type, int owner, int station)
|
||||||
const Vehicle *v;
|
const Vehicle *v;
|
||||||
FOR_ALL_VEHICLES(v) {
|
FOR_ALL_VEHICLES(v) {
|
||||||
if (v->type == type && v->subtype <= subtype) {
|
if (v->type == type && v->subtype <= subtype) {
|
||||||
const Order *ord;
|
const Order *order;
|
||||||
for (ord = v->schedule_ptr; ord->type != OT_NOTHING; ++ord)
|
|
||||||
if (ord->type == OT_GOTO_STATION && ord->station == station) {
|
FOR_VEHICLE_ORDERS(v, order) {
|
||||||
|
if (order->type == OT_GOTO_STATION && order->station == station) {
|
||||||
_vehicle_sort[n].index = v->index;
|
_vehicle_sort[n].index = v->index;
|
||||||
_vehicle_sort[n].owner = v->owner;
|
_vehicle_sort[n].owner = v->owner;
|
||||||
++n;
|
++n;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue