truelight@0: #ifndef VEHICLE_H truelight@0: #define VEHICLE_H truelight@0: darkvater@164: #include "vehicle_gui.h" darkvater@164: truelight@956: /* If you change this, keep in mind that it is saved on 3 places: truelight@956: - Load_ORDR, all the global orders truelight@956: - Vehicle -> current_order truelight@956: - REF_SHEDULE (all REFs are currently limited to 16 bits!!) */ tron@555: typedef struct Order { truelight@941: uint8 type; truelight@941: uint8 flags; truelight@817: uint16 station; tron@555: } Order; tron@555: truelight@941: static inline uint32 PackOrder(const Order *order) tron@555: { truelight@941: return order->station << 16 | order->flags << 8 | order->type; tron@555: } tron@555: truelight@941: static inline Order UnpackOrder(uint32 packed) tron@555: { Celestar@567: Order order; truelight@941: order.type = (packed & 0x000000FF); truelight@941: order.flags = (packed & 0x0000FF00) >> 8; truelight@941: order.station = (packed & 0xFFFF0000) >> 16; truelight@941: return order; truelight@941: } truelight@941: truelight@941: static inline Order UnpackVersion4Order(uint16 packed) truelight@941: { truelight@941: Order order; truelight@941: order.type = (packed & 0x000F); truelight@941: order.flags = (packed & 0x00F0) >> 4; truelight@941: order.station = (packed & 0xFF00) >> 8; tron@555: return order; tron@555: } tron@555: tron@577: Order UnpackOldOrder(uint16 packed); tron@577: tron@577: truelight@0: typedef struct VehicleRail { truelight@0: uint16 last_speed; // NOSAVE: only used in UI truelight@0: uint16 crash_anim_pos; truelight@193: uint16 days_since_order_progr; truelight@193: truelight@0: uint16 cached_weight; // cached power and weight for the vehicle. truelight@0: uint32 cached_power; // no need to save those, they are recomputed on load. truelight@0: truelight@0: // NOSAVE: for wagon override - id of the first engine in train truelight@0: // 0xffff == not in train truelight@0: uint16 first_engine; truelight@0: truelight@0: byte track; truelight@0: byte force_proceed; truelight@0: byte railtype; truelight@0: truelight@0: byte flags; truelight@0: } VehicleRail; truelight@0: truelight@0: enum { truelight@954: VRF_REVERSING = 0, truelight@0: truelight@0: // used to calculate if train is going up or down truelight@954: VRF_GOINGUP = 1, truelight@954: VRF_GOINGDOWN = 2, truelight@0: }; truelight@0: truelight@0: typedef struct VehicleAir { truelight@0: uint16 crashed_counter; truelight@0: byte pos; truelight@0: byte previous_pos; truelight@817: uint16 targetairport; truelight@0: byte state; truelight@0: } VehicleAir; truelight@0: truelight@0: typedef struct VehicleRoad { truelight@0: byte state; truelight@0: byte frame; truelight@0: uint16 unk2; truelight@0: byte overtaking; truelight@0: byte overtaking_ctr; truelight@0: uint16 crashed_ctr; truelight@0: byte reverse_ctr; truelight@0: } VehicleRoad; truelight@0: truelight@0: typedef struct VehicleSpecial { truelight@0: uint16 unk0; truelight@0: byte unk2; truelight@0: } VehicleSpecial; truelight@0: truelight@0: typedef struct VehicleDisaster { truelight@0: uint16 image_override; truelight@0: uint16 unk2; truelight@0: } VehicleDisaster; truelight@0: truelight@0: typedef struct VehicleShip { truelight@0: byte state; truelight@0: } VehicleShip; truelight@0: truelight@0: // not used ATM truelight@0: struct WorldSprite { truelight@0: struct WorldSprite *next; // next sprite in hash chain truelight@0: uint16 image; // sprite number for this vehicle truelight@0: truelight@0: // screen coordinates truelight@0: int16 left, top, right, bottom; truelight@193: truelight@0: // world coordinates truelight@0: int16 x; truelight@0: int16 y; truelight@0: byte z; truelight@0: truelight@0: int8 x_offs; // x offset for vehicle sprite truelight@0: int8 y_offs; // y offset for vehicle sprite truelight@0: truelight@0: byte width; // width of vehicle sprite truelight@0: byte height; // height of vehicle sprite truelight@0: byte depth; // depth of vehicle sprite truelight@0: truelight@0: byte flags; // draw flags truelight@0: }; truelight@0: truelight@0: struct Vehicle { truelight@0: byte type; // type, ie roadven,train,ship,aircraft,special darkvater@22: byte subtype; // subtype (for trains, 0 == loco, 4 wagon ??) truelight@0: truelight@0: uint16 index; // NOSAVE: Index in vehicle array truelight@0: truelight@0: Vehicle *next; // next truelight@0: truelight@0: StringID string_id; // Displayed string truelight@0: truelight@0: byte unitnumber; // unit number, for display purposes only truelight@0: byte owner; // which player owns the vehicle? truelight@0: truelight@0: TileIndex tile; // Current tile index truelight@0: TileIndex dest_tile; // Heading for this tile truelight@0: truelight@0: int16 x_pos; // coordinates truelight@0: int16 y_pos; truelight@0: byte z_pos; truelight@0: byte direction; // facing truelight@0: truelight@0: byte spritenum; // currently displayed sprite index truelight@0: // 0xfd == custom sprite, 0xfe == custom second head sprite truelight@0: // 0xff == reserved for another custom sprite tron@445: uint16 cur_image; // sprite number for this vehicle truelight@0: byte sprite_width;// width of vehicle sprite truelight@0: byte sprite_height;// height of vehicle sprite truelight@0: byte z_height; // z-height of vehicle sprite truelight@0: int8 x_offs; // x offset for vehicle sprite truelight@0: int8 y_offs; // y offset for vehicle sprite truelight@0: uint16 engine_type; truelight@0: tron@445: // for randomized variational spritegroups tron@445: // bitmask used to resolve them; parts of it get reseeded when triggers tron@445: // of corresponding spritegroups get matched tron@445: byte random_bits; tron@445: byte waiting_triggers; // triggers to be yet matched tron@445: truelight@0: uint16 max_speed; // maximum speed truelight@0: uint16 cur_speed; // current speed truelight@0: byte subspeed; // fractional speed truelight@0: byte acceleration; // used by train & aircraft truelight@0: byte progress; truelight@0: truelight@0: byte vehstatus; // Status truelight@817: uint16 last_station_visited; truelight@193: truelight@0: byte cargo_type; // type of cargo this vehicle is carrying truelight@0: byte cargo_days; // how many days have the pieces been in transit truelight@0: byte cargo_source;// source of cargo truelight@0: uint16 cargo_cap; // total capacity truelight@0: uint16 cargo_count;// how many pieces are used truelight@0: truelight@0: byte day_counter; // increased by one for each day truelight@0: byte tick_counter;// increased by one for each tick truelight@0: truelight@0: // related to the current order truelight@0: byte cur_order_index; truelight@0: byte num_orders; tron@555: Order current_order; tron@555: Order *schedule_ptr; truelight@0: truelight@0: // Boundaries for the current position in the world and a next hash link. truelight@0: // NOSAVE: All of those can be updated with VehiclePositionChanged() tron@849: int32 left_coord; tron@849: int32 top_coord; tron@849: int32 right_coord; tron@849: int32 bottom_coord; truelight@0: uint16 next_hash; truelight@0: truelight@0: // Related to age and service time truelight@0: uint16 age; // Age in days truelight@0: uint16 max_age; // Maximum age truelight@0: uint16 date_of_last_service; truelight@0: uint16 service_interval; truelight@0: uint16 reliability; truelight@0: uint16 reliability_spd_dec; truelight@0: byte breakdown_ctr; truelight@0: byte breakdown_delay; truelight@0: byte breakdowns_since_last_service; truelight@0: byte breakdown_chance; truelight@0: byte build_year; truelight@0: truelight@0: uint16 load_unload_time_rem; truelight@193: truelight@0: int32 profit_this_year; truelight@0: int32 profit_last_year; truelight@0: uint32 value; truelight@0: truelight@0: union { truelight@0: VehicleRail rail; truelight@0: VehicleAir air; truelight@0: VehicleRoad road; truelight@0: VehicleSpecial special; truelight@0: VehicleDisaster disaster; truelight@0: VehicleShip ship; truelight@0: } u; truelight@0: }; truelight@0: truelight@0: #define is_custom_sprite(x) (x >= 0xfd) truelight@0: #define is_custom_firsthead_sprite(x) (x == 0xfd) truelight@0: #define is_custom_secondhead_sprite(x) (x == 0xfe) truelight@0: truelight@0: struct Depot { truelight@0: TileIndex xy; truelight@0: uint16 town_index; truelight@0: }; truelight@0: darkvater@395: // train waypoint darkvater@395: struct Waypoint { truelight@0: TileIndex xy; truelight@0: uint16 town_or_string; // if this is 0xC000, it's a string id, otherwise a town. truelight@0: ViewportSign sign; truelight@0: uint16 build_date; truelight@0: byte stat_id; darkvater@395: byte deleted; // this is a delete counter. when it reaches 0, the waypoint struct is deleted. truelight@0: }; truelight@0: truelight@0: enum { truelight@0: VEH_Train = 0x10, truelight@0: VEH_Road = 0x11, truelight@0: VEH_Ship = 0x12, truelight@0: VEH_Aircraft = 0x13, truelight@0: VEH_Special = 0x14, truelight@0: VEH_Disaster = 0x15, truelight@0: }; truelight@0: truelight@0: /* Order types */ truelight@0: enum { truelight@0: OT_NOTHING = 0, truelight@0: OT_GOTO_STATION = 1, truelight@0: OT_GOTO_DEPOT = 2, truelight@0: OT_LOADING = 3, truelight@0: OT_LEAVESTATION = 4, truelight@0: OT_DUMMY = 5, darkvater@395: OT_GOTO_WAYPOINT = 6, truelight@0: }; truelight@0: truelight@0: /* Order flags */ truelight@0: enum { tron@555: OF_UNLOAD = 0x2, tron@555: OF_FULL_LOAD = 0x4, // Also used when to force an aircraft into a depot tron@555: OF_NON_STOP = 0x8 truelight@0: }; truelight@0: truelight@0: truelight@0: enum VehStatus { truelight@0: VS_HIDDEN = 1, truelight@0: VS_STOPPED = 2, truelight@0: VS_UNCLICKABLE = 4, truelight@0: VS_DEFPAL = 0x8, truelight@0: VS_TRAIN_SLOWING = 0x10, truelight@0: VS_DISASTER = 0x20, truelight@0: VS_AIRCRAFT_BROKEN = 0x40, truelight@0: VS_CRASHED = 0x80, truelight@0: }; truelight@0: truelight@0: truelight@0: truelight@0: /* Effect vehicle types */ truelight@0: enum { truelight@0: EV_INDUSTRYSMOKE = 0, truelight@0: EV_STEAM_SMOKE = 1, truelight@0: truelight@0: EV_SMOKE_1 = 2, truelight@0: EV_SMOKE_2 = 3, truelight@0: EV_SMOKE_3 = 4, truelight@0: truelight@0: EV_CRASHED_SMOKE = 5, truelight@0: EV_BREAKDOWN_SMOKE = 6, truelight@0: truelight@0: EV_DEMOLISH = 7, truelight@0: EV_ROADWORK = 8, truelight@0: truelight@0: EV_INDUSTRY_SMOKE = 9, truelight@0: truelight@0: }; truelight@0: truelight@0: typedef void VehicleTickProc(Vehicle *v); truelight@0: typedef void *VehicleFromPosProc(Vehicle *v, void *data); truelight@0: truelight@0: typedef struct { tron@555: VehicleID clone; truelight@0: byte orderindex; tron@555: Order order[41]; truelight@0: uint16 service_interval; truelight@0: char name[32]; truelight@0: } BackuppedOrders; truelight@0: bjarni@578: void VehicleServiceInDepot(Vehicle *v); truelight@0: void BackupVehicleOrders(Vehicle *v, BackuppedOrders *order); truelight@0: void RestoreVehicleOrders(Vehicle *v, BackuppedOrders *order); truelight@0: Vehicle *AllocateVehicle(); truelight@0: Vehicle *ForceAllocateVehicle(); truelight@0: Vehicle *ForceAllocateSpecialVehicle(); truelight@0: void UpdateVehiclePosHash(Vehicle *v, int x, int y); truelight@0: void InitializeVehicles(); truelight@0: void VehiclePositionChanged(Vehicle *v); truelight@0: void AfterLoadVehicles(); truelight@0: Vehicle *GetLastVehicleInChain(Vehicle *v); truelight@0: Vehicle *GetPrevVehicleInChain(Vehicle *v); truelight@0: Vehicle *GetFirstVehicleInChain(Vehicle *v); truelight@0: int CountVehiclesInChain(Vehicle *v); truelight@0: void DeleteVehicle(Vehicle *v); truelight@0: void DeleteVehicleChain(Vehicle *v); truelight@0: void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc); truelight@0: void CallVehicleTicks(); truelight@0: void DeleteVehicleSchedule(Vehicle *v); truelight@0: Vehicle *IsScheduleShared(Vehicle *v); truelight@0: truelight@0: Depot *AllocateDepot(); darkvater@395: Waypoint *AllocateWaypoint(); darkvater@395: void UpdateWaypointSign(Waypoint *cp); darkvater@395: void RedrawWaypointSign(Waypoint *cp); truelight@0: truelight@0: void InitializeTrains(); truelight@0: bool IsTrainDepotTile(TileIndex tile); truelight@0: bool IsRoadDepotTile(TileIndex tile); truelight@0: truelight@0: bool CanFillVehicle(Vehicle *v); truelight@0: truelight@0: void ViewportAddVehicles(DrawPixelInfo *dpi); truelight@0: truelight@0: void TrainEnterDepot(Vehicle *v, uint tile); truelight@0: truelight@0: /* train_cmd.h */ truelight@0: int GetTrainImage(Vehicle *v, byte direction); truelight@0: int GetAircraftImage(Vehicle *v, byte direction); truelight@0: int GetRoadVehImage(Vehicle *v, byte direction); truelight@0: int GetShipImage(Vehicle *v, byte direction); truelight@0: truelight@0: Vehicle *CreateEffectVehicle(int x, int y, int z, int type); truelight@0: Vehicle *CreateEffectVehicleAbove(int x, int y, int z, int type); truelight@0: Vehicle *CreateEffectVehicleRel(Vehicle *v, int x, int y, int z, int type); truelight@0: truelight@0: uint32 VehicleEnterTile(Vehicle *v, uint tile, int x, int y); truelight@0: truelight@0: void VehicleInTheWayErrMsg(Vehicle *v); truelight@0: Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z); truelight@0: uint GetVehicleOutOfTunnelTile(Vehicle *v); truelight@0: truelight@0: bool UpdateSignalsOnSegment(uint tile, byte direction); truelight@0: void SetSignalsOnBothDir(uint tile, byte track); truelight@0: truelight@0: Vehicle *CheckClickOnVehicle(ViewPort *vp, int x, int y); truelight@0: //uint GetVehicleWeight(Vehicle *v); truelight@0: truelight@0: void DecreaseVehicleValue(Vehicle *v); truelight@0: void CheckVehicleBreakdown(Vehicle *v); truelight@0: void AgeVehicle(Vehicle *v); bjarni@842: void MaybeReplaceVehicle(Vehicle *v); truelight@0: tron@555: void DeleteCommandFromVehicleSchedule(Order cmd); truelight@0: truelight@0: void BeginVehicleMove(Vehicle *v); truelight@0: void EndVehicleMove(Vehicle *v); truelight@0: truelight@0: bool IsAircraftHangarTile(TileIndex tile); truelight@0: void ShowAircraftViewWindow(Vehicle *v); truelight@0: truelight@0: void InvalidateVehicleOrderWidget(Vehicle *v); truelight@0: truelight@0: bool IsShipDepotTile(TileIndex tile); truelight@0: uint GetFreeUnitNumber(byte type); truelight@0: truelight@0: int LoadUnloadVehicle(Vehicle *v); truelight@0: int GetDepotByTile(uint tile); darkvater@395: uint GetWaypointByTile(uint tile); truelight@0: truelight@0: void DoDeleteDepot(uint tile); truelight@0: truelight@0: void UpdateTrainAcceleration(Vehicle *v); truelight@0: int32 GetTrainRunningCost(Vehicle *v); truelight@0: truelight@0: int CheckStoppedInDepot(Vehicle *v); truelight@0: tron@555: int ScheduleHasDepotOrders(const Order *schedule); dominik@19: int CheckOrders(Vehicle *v); truelight@0: tron@593: bool VehicleNeedsService(const Vehicle *v); tron@593: celestar@1020: void InvalidateAircraftWindows(const Vehicle *v); celestar@1020: void InvalidateShipWindows(const Vehicle *v); celestar@1020: truelight@0: typedef struct GetNewVehiclePosResult { truelight@0: int x,y; truelight@0: uint old_tile; truelight@0: uint new_tile; truelight@0: } GetNewVehiclePosResult; truelight@0: truelight@0: /* returns true if staying in the same tile */ truelight@0: bool GetNewVehiclePos(Vehicle *v, GetNewVehiclePosResult *gp); truelight@0: byte GetDirectionTowards(Vehicle *v, int x, int y); truelight@0: truelight@0: #define BEGIN_ENUM_WAGONS(v) do { truelight@0: #define END_ENUM_WAGONS(v) } while ( (v=v->next) != NULL); truelight@0: truelight@0: /* vehicle.c */ truelight@0: enum { truelight@0: NUM_NORMAL_VEHICLES = 2048, truelight@0: NUM_SPECIAL_VEHICLES = 512, truelight@0: NUM_VEHICLES = NUM_NORMAL_VEHICLES + NUM_SPECIAL_VEHICLES truelight@193: }; truelight@0: truelight@0: VARDEF Vehicle _vehicles[NUM_VEHICLES]; truelight@919: VARDEF uint _vehicles_size; truelight@919: truelight@919: VARDEF SortStruct *_vehicle_sort; truelight@919: truelight@919: static inline Vehicle *GetVehicle(uint index) truelight@919: { truelight@919: assert(index < _vehicles_size); truelight@919: return &_vehicles[index]; truelight@919: } truelight@919: truelight@919: #define FOR_ALL_VEHICLES(v) for(v = _vehicles; v != &_vehicles[_vehicles_size]; v++) truelight@919: #define FOR_ALL_VEHICLES_FROM(v, from) for(v = GetVehicle(from); v != &_vehicles[_vehicles_size]; v++) truelight@0: tron@555: VARDEF Order _order_array[5000]; tron@555: VARDEF Order *_ptr_to_next_order; truelight@0: truelight@0: VARDEF Depot _depots[255]; truelight@0: darkvater@395: // 128 waypoints darkvater@395: VARDEF Waypoint _waypoints[128]; truelight@0: truelight@0: // NOSAVE: Can be regenerated by inspecting the vehicles. truelight@0: VARDEF VehicleID _vehicle_position_hash[0x1000]; truelight@0: truelight@0: // NOSAVE: Return values from various commands. truelight@0: VARDEF VehicleID _new_train_id; truelight@0: VARDEF VehicleID _new_wagon_id; truelight@0: VARDEF VehicleID _new_aircraft_id; truelight@0: VARDEF VehicleID _new_ship_id; truelight@0: VARDEF VehicleID _new_roadveh_id; truelight@0: VARDEF uint16 _aircraft_refit_capacity; truelight@0: VARDEF byte _cmd_build_rail_veh_score; truelight@0: VARDEF byte _cmd_build_rail_veh_var1; truelight@0: truelight@0: // NOSAVE: Player specific info truelight@0: VARDEF TileIndex _last_built_train_depot_tile; truelight@0: VARDEF TileIndex _last_built_road_depot_tile; truelight@0: VARDEF TileIndex _last_built_aircraft_depot_tile; truelight@0: VARDEF TileIndex _last_built_ship_depot_tile; truelight@0: VARDEF TileIndex _backup_orders_tile; truelight@0: VARDEF BackuppedOrders _backup_orders_data[1]; truelight@0: truelight@0: // for each player, for each vehicle type, keep a list of the vehicles. truelight@0: //VARDEF Vehicle *_vehicle_arr[8][4]; truelight@0: truelight@0: #define INVALID_VEHICLE 0xffff truelight@0: darkvater@156: #define MIN_SERVINT_PERCENT 5 darkvater@156: #define MAX_SERVINT_PERCENT 90 darkvater@156: #define MIN_SERVINT_DAYS 30 darkvater@156: #define MAX_SERVINT_DAYS 800 darkvater@156: darkvater@755: /* A lot of code calls for the invalidation of the status bar, which is widget 5. darkvater@755: * Best is to have a virtual value for it when it needs to change again */ darkvater@755: #define STATUS_BAR 5 darkvater@755: truelight@0: #endif /* VEHICLE_H */