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:
Jonathan G Rennison
2019-03-27 18:12:04 +00:00
422 changed files with 4697 additions and 6619 deletions

View File

@@ -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));