Merge branch 'master' into jgrpp
Replace build and refit, and group collapse implementations Fix template creation build and refit # Conflicts: # Makefile.bundle.in # config.lib # src/animated_tile.cpp # src/blitter/32bpp_anim.hpp # src/blitter/32bpp_base.hpp # src/blitter/8bpp_base.hpp # src/blitter/null.hpp # src/build_vehicle_gui.cpp # src/command.cpp # src/command_func.h # src/console_gui.cpp # src/core/smallstack_type.hpp # src/date.cpp # src/debug.cpp # src/genworld_gui.cpp # src/ground_vehicle.hpp # src/group_gui.cpp # src/lang/korean.txt # src/linkgraph/linkgraph_gui.h # src/main_gui.cpp # src/misc_gui.cpp # src/network/core/game.h # src/network/core/packet.cpp # src/network/core/udp.cpp # src/network/core/udp.h # src/network/network_content.cpp # src/network/network_type.h # src/network/network_udp.cpp # src/newgrf_house.h # src/openttd.cpp # src/order_cmd.cpp # src/order_gui.cpp # src/os/unix/crashlog_unix.cpp # src/os/windows/crashlog_win.cpp # src/osk_gui.cpp # src/pathfinder/opf/opf_ship.cpp # src/rail_cmd.cpp # src/rail_gui.cpp # src/saveload/saveload.cpp # src/settings.cpp # src/settings_gui.cpp # src/smallmap_gui.h # src/station_base.h # src/station_cmd.cpp # src/table/gameopt_settings.ini # src/table/newgrf_debug_data.h # src/table/settings.ini # src/timetable_gui.cpp # src/toolbar_gui.cpp # src/train_gui.cpp # src/vehicle.cpp # src/vehicle_gui.cpp # src/vehiclelist.cpp # src/viewport.cpp # src/widgets/dropdown.cpp # src/window_gui.h
This commit is contained in:
@@ -81,9 +81,10 @@ static CommandCost GetRefitCost(const Vehicle *v, EngineID engine_type, CargoID
|
||||
* @param flags for command
|
||||
* @param p1 various bitstuffed data
|
||||
* bits 0-15: vehicle type being built.
|
||||
* bits 16-31: vehicle type specific bits passed on to the vehicle build functions.
|
||||
* bits 16-23: vehicle type specific bits passed on to the vehicle build functions.
|
||||
* bits 24-31: refit cargo type.
|
||||
* @param p2 User
|
||||
* @param text used for combined build and refit command
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdBuildVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text, uint32 binary_length)
|
||||
@@ -103,11 +104,18 @@ CommandCost CmdBuildVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
|
||||
EngineID eid = GB(p1, 0, 16);
|
||||
if (!IsEngineBuildable(eid, type, _current_company)) return_cmd_error(STR_ERROR_RAIL_VEHICLE_NOT_AVAILABLE + type);
|
||||
|
||||
/* Validate the cargo type. */
|
||||
CargoID cargo = GB(p1, 24, 8);
|
||||
if (cargo >= NUM_CARGO && cargo != CT_INVALID) return CMD_ERROR;
|
||||
|
||||
const Engine *e = Engine::Get(eid);
|
||||
CommandCost value(EXPENSES_NEW_VEHICLES, e->GetCost());
|
||||
|
||||
/* Engines without valid cargo should not be available */
|
||||
if (e->GetDefaultCargoType() == CT_INVALID) return CMD_ERROR;
|
||||
CargoID default_cargo = e->GetDefaultCargoType();
|
||||
if (default_cargo == CT_INVALID) return CMD_ERROR;
|
||||
|
||||
bool refitting = cargo != CT_INVALID && cargo != default_cargo;
|
||||
|
||||
/* Check whether the number of vehicles we need to build can be built according to pool space. */
|
||||
uint num_vehicles;
|
||||
@@ -126,65 +134,57 @@ CommandCost CmdBuildVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
|
||||
UnitID unit_num = (flags & DC_AUTOREPLACE || (type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_WAGON)) ? 0 : GetFreeUnitNumber(type);
|
||||
if (unit_num == UINT16_MAX) return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME);
|
||||
|
||||
Vehicle *v;
|
||||
/* If we are refitting we need to temporarily purchase the vehicle to be able to
|
||||
* test it. */
|
||||
DoCommandFlag subflags = flags;
|
||||
if (refitting) subflags |= DC_EXEC;
|
||||
|
||||
Vehicle *v = NULL;
|
||||
switch (type) {
|
||||
case VEH_TRAIN: value.AddCost(CmdBuildRailVehicle(tile, flags, e, GB(p1, 16, 16), &v)); break;
|
||||
case VEH_ROAD: value.AddCost(CmdBuildRoadVehicle(tile, flags, e, GB(p1, 16, 16), &v)); break;
|
||||
case VEH_SHIP: value.AddCost(CmdBuildShip (tile, flags, e, GB(p1, 16, 16), &v)); break;
|
||||
case VEH_AIRCRAFT: value.AddCost(CmdBuildAircraft (tile, flags, e, GB(p1, 16, 16), &v)); break;
|
||||
case VEH_TRAIN: value.AddCost(CmdBuildRailVehicle(tile, subflags, e, GB(p1, 24, 8), &v)); break;
|
||||
case VEH_ROAD: value.AddCost(CmdBuildRoadVehicle(tile, subflags, e, GB(p1, 24, 8), &v)); break;
|
||||
case VEH_SHIP: value.AddCost(CmdBuildShip (tile, subflags, e, GB(p1, 24, 8), &v)); break;
|
||||
case VEH_AIRCRAFT: value.AddCost(CmdBuildAircraft (tile, subflags, e, GB(p1, 24, 8), &v)); break;
|
||||
default: NOT_REACHED(); // Safe due to IsDepotTile()
|
||||
}
|
||||
|
||||
if (value.Succeeded() && flags & DC_EXEC) {
|
||||
v->unitnumber = unit_num;
|
||||
v->value = value.GetCost();
|
||||
|
||||
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
|
||||
InvalidateWindowClassesData(GetWindowClassForVehicleType(type), 0);
|
||||
SetWindowDirty(WC_COMPANY, _current_company);
|
||||
if (IsLocalCompany()) {
|
||||
InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the auto replace window (must be called before incrementing num_engines)
|
||||
if (value.Succeeded()) {
|
||||
if (refitting || (flags & DC_EXEC)) {
|
||||
v->unitnumber = unit_num;
|
||||
v->value = value.GetCost();
|
||||
}
|
||||
|
||||
GroupStatistics::CountEngine(v, 1);
|
||||
GroupStatistics::UpdateAutoreplace(_current_company);
|
||||
|
||||
if (v->IsPrimaryVehicle()) {
|
||||
GroupStatistics::CountVehicle(v, 1);
|
||||
OrderBackup::Restore(v, p2);
|
||||
if (refitting) {
|
||||
value.AddCost(CmdRefitVehicle(tile, flags, v->index, cargo, NULL));
|
||||
} else {
|
||||
/* Fill in non-refitted capacities */
|
||||
_returned_refit_capacity = e->GetDisplayDefaultCapacity(&_returned_mail_refit_capacity);
|
||||
}
|
||||
}
|
||||
|
||||
if (value.Succeeded() && binary_length == 2 && text && text[0] == 'R') {
|
||||
CargoID cargo = text[1];
|
||||
if (cargo >= NUM_CARGO) return CMD_ERROR;
|
||||
CargoID default_cargo = e->GetDefaultCargoType();
|
||||
if (default_cargo != cargo) {
|
||||
if (flags & DC_EXEC) {
|
||||
value.AddCost(CmdRefitVehicle(tile, flags, v->index, cargo, NULL));
|
||||
} else {
|
||||
bool auto_refit_allowed = false;
|
||||
value.AddCost(GetRefitCost(NULL, eid, cargo, 0, &auto_refit_allowed));
|
||||
if (type == VEH_TRAIN || type == VEH_ROAD) {
|
||||
std::vector<EngineID> engine_ids;
|
||||
GetArticulatedPartsEngineIDs(eid, false, engine_ids);
|
||||
for (size_t i = 0; i < engine_ids.size(); i++) {
|
||||
value.AddCost(GetRefitCost(NULL, engine_ids[i], cargo, 0, &auto_refit_allowed));
|
||||
}
|
||||
}
|
||||
if (type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_MULTIHEAD) {
|
||||
value.AddCost(GetRefitCost(NULL, eid, cargo, 0, &auto_refit_allowed));
|
||||
}
|
||||
if (flags & DC_EXEC) {
|
||||
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
|
||||
InvalidateWindowClassesData(GetWindowClassForVehicleType(type), 0);
|
||||
SetWindowDirty(WC_COMPANY, _current_company);
|
||||
if (IsLocalCompany()) {
|
||||
InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the auto replace window (must be called before incrementing num_engines)
|
||||
}
|
||||
}
|
||||
/* Since we can't estimate the cost of build and refitting a vehicle accurately we must
|
||||
* check whether the company has enough money manually. */
|
||||
if (!CheckCompanyHasMoney(value)) {
|
||||
if (flags & DC_EXEC) {
|
||||
/* The vehicle has already been bought, so now it must be sold again. */
|
||||
DoCommand(tile, v->index, 0, flags, GetCmdSellVeh(type));
|
||||
|
||||
if (refitting || (flags & DC_EXEC)) {
|
||||
GroupStatistics::CountEngine(v, 1);
|
||||
GroupStatistics::UpdateAutoreplace(_current_company);
|
||||
|
||||
if (v->IsPrimaryVehicle()) {
|
||||
GroupStatistics::CountVehicle(v, 1);
|
||||
OrderBackup::Restore(v, p2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If we are not in DC_EXEC undo everything */
|
||||
if (refitting && (flags & DC_EXEC) == 0) {
|
||||
DoCommand(0, v->index, 0, DC_EXEC, GetCmdSellVeh(v));
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
@@ -357,8 +357,7 @@ static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles,
|
||||
v = v->First();
|
||||
}
|
||||
|
||||
static SmallVector<RefitResult, 16> refit_result;
|
||||
refit_result.Clear();
|
||||
std::vector<RefitResult> refit_result;
|
||||
|
||||
v->InvalidateNewGRFCacheOfChain();
|
||||
byte actual_subtype = new_subtype;
|
||||
@@ -366,7 +365,7 @@ static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles,
|
||||
/* Reset actual_subtype for every new vehicle */
|
||||
if (!v->IsArticulatedPart()) actual_subtype = new_subtype;
|
||||
|
||||
if (v->type == VEH_TRAIN && !vehicles_to_refit.Contains(v->index) && !only_this) continue;
|
||||
if (v->type == VEH_TRAIN && std::find(vehicles_to_refit.begin(), vehicles_to_refit.end(), v->index) == vehicles_to_refit.end() && !only_this) continue;
|
||||
|
||||
const Engine *e = v->GetEngine();
|
||||
if (!e->CanCarryCargo()) continue;
|
||||
@@ -428,32 +427,28 @@ static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles,
|
||||
* - We have to call the refit cost callback with the pre-refit configuration of the chain because we want refit and
|
||||
* autorefit to behave the same, and we need its result for auto_refit_allowed.
|
||||
*/
|
||||
RefitResult *result = refit_result.Append();
|
||||
result->v = v;
|
||||
result->capacity = amount;
|
||||
result->mail_capacity = mail_capacity;
|
||||
result->subtype = actual_subtype;
|
||||
refit_result.push_back({v, amount, mail_capacity, actual_subtype});
|
||||
}
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
/* Store the result */
|
||||
for (RefitResult *result = refit_result.Begin(); result != refit_result.End(); result++) {
|
||||
Vehicle *u = result->v;
|
||||
u->refit_cap = (u->cargo_type == new_cid) ? min(result->capacity, u->refit_cap) : 0;
|
||||
for (RefitResult &result : refit_result) {
|
||||
Vehicle *u = result.v;
|
||||
u->refit_cap = (u->cargo_type == new_cid) ? min(result.capacity, u->refit_cap) : 0;
|
||||
if (u->cargo.TotalCount() > u->refit_cap) u->cargo.Truncate(u->cargo.TotalCount() - u->refit_cap);
|
||||
u->cargo_type = new_cid;
|
||||
u->cargo_cap = result->capacity;
|
||||
u->cargo_subtype = result->subtype;
|
||||
u->cargo_cap = result.capacity;
|
||||
u->cargo_subtype = result.subtype;
|
||||
if (u->type == VEH_AIRCRAFT) {
|
||||
Vehicle *w = u->Next();
|
||||
w->refit_cap = min(w->refit_cap, result->mail_capacity);
|
||||
w->cargo_cap = result->mail_capacity;
|
||||
w->refit_cap = min(w->refit_cap, result.mail_capacity);
|
||||
w->cargo_cap = result.mail_capacity;
|
||||
if (w->cargo.TotalCount() > w->refit_cap) w->cargo.Truncate(w->cargo.TotalCount() - w->refit_cap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
refit_result.Clear();
|
||||
refit_result.clear();
|
||||
_returned_refit_capacity = total_capacity;
|
||||
_returned_mail_refit_capacity = total_mail_capacity;
|
||||
return cost;
|
||||
@@ -686,7 +681,7 @@ CommandCost CmdMassStartStopVehicle(TileIndex tile, DoCommandFlag flags, uint32
|
||||
BuildDepotVehicleList(vli.vtype, tile, &list, NULL);
|
||||
}
|
||||
|
||||
for (uint i = 0; i < list.Length(); i++) {
|
||||
for (uint i = 0; i < list.size(); i++) {
|
||||
const Vehicle *v = list[i];
|
||||
|
||||
if (!!(v->vehstatus & VS_STOPPED) != do_start) continue;
|
||||
@@ -725,7 +720,7 @@ CommandCost CmdDepotSellAllVehicles(TileIndex tile, DoCommandFlag flags, uint32
|
||||
|
||||
CommandCost last_error = CMD_ERROR;
|
||||
bool had_success = false;
|
||||
for (uint i = 0; i < list.Length(); i++) {
|
||||
for (uint i = 0; i < list.size(); i++) {
|
||||
CommandCost ret = DoCommand(tile, list[i]->index | (1 << 20), 0, flags, sell_command);
|
||||
if (ret.Succeeded()) {
|
||||
cost.AddCost(ret);
|
||||
@@ -759,7 +754,7 @@ CommandCost CmdDepotMassAutoReplace(TileIndex tile, DoCommandFlag flags, uint32
|
||||
/* Get the list of vehicles in the depot */
|
||||
BuildDepotVehicleList(vehicle_type, tile, &list, &list, true);
|
||||
|
||||
for (uint i = 0; i < list.Length(); i++) {
|
||||
for (uint i = 0; i < list.size(); i++) {
|
||||
const Vehicle *v = list[i];
|
||||
|
||||
/* Ensure that the vehicle completely in the depot */
|
||||
@@ -1373,7 +1368,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
|
||||
DoCommandFlag build_flags = flags;
|
||||
if ((flags & DC_EXEC) && !v->IsPrimaryVehicle()) build_flags |= DC_AUTOREPLACE;
|
||||
|
||||
CommandCost cost = DoCommand(tile, v->engine_type | (1 << 16), 0, build_flags, GetCmdBuildVeh(v));
|
||||
CommandCost cost = DoCommand(tile, v->engine_type | (1 << 16) | (CT_INVALID << 24), 0, build_flags, GetCmdBuildVeh(v));
|
||||
|
||||
if (cost.Failed()) {
|
||||
/* Can't build a part, then sell the stuff we already made; clear up the mess */
|
||||
@@ -1510,7 +1505,7 @@ static CommandCost SendAllVehiclesToDepot(DoCommandFlag flags, DepotCommand depo
|
||||
|
||||
/* Send all the vehicles to a depot */
|
||||
bool had_success = false;
|
||||
for (uint i = 0; i < list.Length(); i++) {
|
||||
for (uint i = 0; i < list.size(); i++) {
|
||||
const Vehicle *v = list[i];
|
||||
CommandCost ret = DoCommand(v->tile, v->index | depot_flags, 0, flags, GetCmdSendToDepot(vli.vtype));
|
||||
|
||||
|
Reference in New Issue
Block a user