Improve autoterraforming for polyrail in multiplayer
This commit is contained in:
@@ -39,7 +39,6 @@ bool operator!=(const TileIndexDiffC &a, const TileIndexDiffC &b) {
|
||||
}
|
||||
|
||||
typedef std::tuple<TileIndex, uint32, uint32, uint32> CommandTuple;
|
||||
typedef std::function<void(bool)> CommandCallback;
|
||||
std::map<CommandTuple, std::vector<CommandCallback>> _command_callbacks;
|
||||
|
||||
void AddCommandCallback(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback callback) {
|
||||
@@ -615,8 +614,8 @@ void BuildBlueprint(sp<Blueprint> &blueprint, TileIndex start) {
|
||||
TileIndex tile = AddTileIndexDiffCWrap(start, item.tdiff);
|
||||
auto cc = GetBlueprintCommand(start, item);
|
||||
DoCommandWithCallback(cc,
|
||||
[blueprint, tile, start, sign_part=item.u.rail.station.has_part, sid=item.u.rail.station.id] (bool res) {
|
||||
if (!res) return;
|
||||
[blueprint, tile, start, sign_part=item.u.rail.station.has_part, sid=item.u.rail.station.id] (bool res)->bool {
|
||||
if (!res) return false;
|
||||
StationID station_id = GetStationIndex(tile);
|
||||
for (auto &item : blueprint->items) {
|
||||
if (item.type != Blueprint::Item::Type::RAIL_STATION_PART) continue;
|
||||
@@ -625,6 +624,7 @@ void BuildBlueprint(sp<Blueprint> &blueprint, TileIndex start) {
|
||||
DoCommandP(cc.tile, cc.p1 | (1 << 24), station_id << 16, cc.cmd);
|
||||
}
|
||||
if (!sign_part) DoCommandP(tile, 0, 0, CMD_REMOVE_FROM_RAIL_STATION);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
break;
|
||||
@@ -638,7 +638,7 @@ void BuildBlueprint(sp<Blueprint> &blueprint, TileIndex start) {
|
||||
for (auto &item : blueprint->items) {
|
||||
if (item.type != Blueprint::Item::Type::RAIL_SIGNAL) continue;
|
||||
auto cc = GetBlueprintCommand(start, item);
|
||||
DoCommandP(&cc);
|
||||
return DoCommandP(&cc);
|
||||
}
|
||||
};
|
||||
if (last_rail.cmd != CMD_END) { // there can't be any signals if there are no rails
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
namespace citymania {
|
||||
|
||||
typedef std::function<bool(bool)> CommandCallback;
|
||||
void AddCommandCallback(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback callback);
|
||||
|
||||
void BlueprintCopyArea(TileIndex start, TileIndex end);
|
||||
void ResetActiveBlueprint();
|
||||
void SetBlueprintHighlight(const TileInfo *ti, TileHighlight &th);
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
#include "widgets/rail_widget.h"
|
||||
|
||||
#include "network/network.h"
|
||||
#include "citymania/cm_blueprint.hpp"
|
||||
#include "citymania/cm_hotkeys.hpp"
|
||||
#include "citymania/cm_highlight.hpp"
|
||||
@@ -401,82 +402,93 @@ static CommandContainer DoRailroadTrackCmd(TileIndex start_tile, TileIndex end_t
|
||||
|
||||
namespace citymania {
|
||||
|
||||
static void DoAutodirTerraform(bool diagonal, TileIndex s1, TileIndex e1, TileIndex s2, TileIndex e2) {
|
||||
static bool DoAutodirTerraform(bool diagonal, TileIndex start_tile, TileIndex end_tile, Track track, CommandContainer &rail_cmd, TileIndex s1, TileIndex e1, TileIndex s2, TileIndex e2) {
|
||||
auto h1 = TileHeight(s1);
|
||||
auto h2 = TileHeight(s2);
|
||||
int diag_flag = (int)diagonal;
|
||||
DoCommandP(e1, s1, ((h1 < h2 ? LM_RAISE : LM_LEVEL) << 1) | diag_flag, CMD_LEVEL_LAND, CcTerraform);
|
||||
DoCommandP(e2, s2, ((h2 < h1 ? LM_RAISE : LM_LEVEL) << 1) | diag_flag, CMD_LEVEL_LAND, CcTerraform);
|
||||
uint32 p2 = ((h2 < h1 ? LM_RAISE : LM_LEVEL) << 1) | diag_flag;
|
||||
DoCommandP(e2, s2, p2, CMD_LEVEL_LAND, CcTerraform);
|
||||
auto rail_callback = [rail_cmd, start_tile, end_tile, track](bool res) {
|
||||
if (!citymania::_estimate_mod && end_tile != INVALID_TILE)
|
||||
StoreRailPlacementEndpoints(start_tile, end_tile, track, true);
|
||||
return DoCommandP(&rail_cmd);
|
||||
} ;
|
||||
if (_networking) {
|
||||
citymania::AddCommandCallback(e2, s2, p2, CMD_LEVEL_LAND, rail_callback);
|
||||
return true;
|
||||
} else return rail_callback(true);
|
||||
}
|
||||
|
||||
static void HandleAutodirTerraform(TileIndex start_tile, TileIndex end_tile) {
|
||||
static bool HandleAutodirTerraform(TileIndex start_tile, TileIndex end_tile, Track track, CommandContainer &rail_cmd) {
|
||||
bool eq = (TileX(end_tile) - TileY(end_tile) == TileX(start_tile) - TileY(start_tile));
|
||||
bool ez = (TileX(end_tile) + TileY(end_tile) == TileX(start_tile) + TileY(start_tile));
|
||||
StoreRailPlacementEndpoints(start_tile, end_tile, track, true);
|
||||
switch (_thd.cm_poly_dir) {
|
||||
case TRACKDIR_X_NE:
|
||||
DoAutodirTerraform(false,
|
||||
return DoAutodirTerraform(false, start_tile, end_tile, track, rail_cmd,
|
||||
TILE_ADDXY(start_tile, 1, 0), end_tile,
|
||||
TILE_ADDXY(start_tile, 1, 1), TILE_ADDXY(end_tile, 0, 1));
|
||||
break;
|
||||
case TRACKDIR_X_SW:
|
||||
DoAutodirTerraform(false,
|
||||
return DoAutodirTerraform(false, start_tile, end_tile, track, rail_cmd,
|
||||
start_tile, TILE_ADDXY(end_tile, 1, 0),
|
||||
TILE_ADDXY(start_tile, 0, 1), TILE_ADDXY(end_tile, 1, 1));
|
||||
break;
|
||||
case TRACKDIR_Y_SE:
|
||||
DoAutodirTerraform(false,
|
||||
return DoAutodirTerraform(false, start_tile, end_tile, track, rail_cmd,
|
||||
start_tile, TILE_ADDXY(end_tile, 0, 1),
|
||||
TILE_ADDXY(start_tile, 1, 0), TILE_ADDXY(end_tile, 1, 1));
|
||||
break;
|
||||
case TRACKDIR_Y_NW:
|
||||
DoAutodirTerraform(false,
|
||||
return DoAutodirTerraform(false, start_tile, end_tile, track, rail_cmd,
|
||||
TILE_ADDXY(start_tile, 0, 1), end_tile,
|
||||
TILE_ADDXY(start_tile, 1, 1), TILE_ADDXY(end_tile, 1, 0));
|
||||
break;
|
||||
case TRACKDIR_LEFT_N: {
|
||||
DoAutodirTerraform(true,
|
||||
return DoAutodirTerraform(true, start_tile, end_tile, track, rail_cmd,
|
||||
TILE_ADDXY(start_tile, 1, 0), TILE_ADDXY(end_tile, eq, 0),
|
||||
TILE_ADDXY(start_tile, 1, 1), TILE_ADDXY(end_tile, 0, !eq));
|
||||
break;
|
||||
}
|
||||
case TRACKDIR_RIGHT_N: {
|
||||
DoAutodirTerraform(true,
|
||||
return DoAutodirTerraform(true, start_tile, end_tile, track, rail_cmd,
|
||||
TILE_ADDXY(start_tile, 0, 1), TILE_ADDXY(end_tile, 0, eq),
|
||||
TILE_ADDXY(start_tile, 1, 1), TILE_ADDXY(end_tile, !eq, 0));
|
||||
break;
|
||||
}
|
||||
case TRACKDIR_LEFT_S: {
|
||||
DoAutodirTerraform(true,
|
||||
return DoAutodirTerraform(true, start_tile, end_tile, track, rail_cmd,
|
||||
TILE_ADDXY(start_tile, 1, 0), TILE_ADDXY(end_tile, 1, !eq),
|
||||
start_tile, TILE_ADDXY(end_tile, eq, 1));
|
||||
break;
|
||||
}
|
||||
case TRACKDIR_RIGHT_S: {
|
||||
DoAutodirTerraform(true,
|
||||
return DoAutodirTerraform(true, start_tile, end_tile, track, rail_cmd,
|
||||
TILE_ADDXY(start_tile, 0, 1), TILE_ADDXY(end_tile, !eq, 1),
|
||||
start_tile, TILE_ADDXY(end_tile, 1, eq));
|
||||
break;
|
||||
}
|
||||
case TRACKDIR_UPPER_E: {
|
||||
DoAutodirTerraform(true,
|
||||
return DoAutodirTerraform(true, start_tile, end_tile, track, rail_cmd,
|
||||
start_tile, TILE_ADDXY(end_tile, 0, !ez),
|
||||
TILE_ADDXY(start_tile, 1, 0), TILE_ADDXY(end_tile, !ez, 1));
|
||||
break;
|
||||
}
|
||||
case TRACKDIR_LOWER_E: {
|
||||
DoAutodirTerraform(true,
|
||||
return DoAutodirTerraform(true, start_tile, end_tile, track, rail_cmd,
|
||||
TILE_ADDXY(start_tile, 1, 1), TILE_ADDXY(end_tile, ez, 1),
|
||||
TILE_ADDXY(start_tile, 1, 0), TILE_ADDXY(end_tile, 0, ez));
|
||||
break;
|
||||
}
|
||||
case TRACKDIR_UPPER_W: {
|
||||
DoAutodirTerraform(true,
|
||||
return DoAutodirTerraform(true, start_tile, end_tile, track, rail_cmd,
|
||||
start_tile, TILE_ADDXY(end_tile, !ez, 0),
|
||||
TILE_ADDXY(start_tile, 0, 1), TILE_ADDXY(end_tile, 1, !ez));
|
||||
break;
|
||||
}
|
||||
case TRACKDIR_LOWER_W: {
|
||||
DoAutodirTerraform(true,
|
||||
return DoAutodirTerraform(true, start_tile, end_tile, track, rail_cmd,
|
||||
TILE_ADDXY(start_tile, 1, 1), TILE_ADDXY(end_tile, 1, ez),
|
||||
TILE_ADDXY(start_tile, 0, 1), TILE_ADDXY(end_tile, ez, 0));
|
||||
break;
|
||||
@@ -503,9 +515,11 @@ static void HandleAutodirPlacement()
|
||||
if (citymania::_estimate_mod || !(_thd.place_mode & HT_POLY) ||
|
||||
DoCommand(&cmd, DC_AUTO | DC_NO_WATER).GetErrorMessage() != STR_ERROR_ALREADY_BUILT ||
|
||||
_rail_track_endtile == INVALID_TILE) {
|
||||
if (_thd.cm_poly_terra) citymania::HandleAutodirTerraform(start_tile, end_tile);
|
||||
/* Execute. */
|
||||
if (!DoCommandP(&cmd)) return;
|
||||
if (_thd.cm_poly_terra) {
|
||||
if (!citymania::HandleAutodirTerraform(start_tile, end_tile, track, cmd)) return;
|
||||
} else {
|
||||
if (!DoCommandP(&cmd)) return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save new snap points for the polyline tool, no matter if the command
|
||||
|
||||
Reference in New Issue
Block a user