Merge branch 'master' into 1.11
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -39,7 +39,8 @@ void DrawAircraftDetails(const Aircraft *v, int left, int right, int y)
|
||||
SetDParam(0, u->engine_type);
|
||||
SetDParam(1, u->build_year);
|
||||
SetDParam(2, u->value);
|
||||
DrawString(left, right, y, STR_VEHICLE_INFO_BUILT_VALUE);
|
||||
if (_settings_client.gui.newgrf_developer_tools) SetDParam(3, v->index); // CM
|
||||
DrawString(left, right, y, _settings_client.gui.newgrf_developer_tools ? STR_CM_VEHICLE_INFO_BUILT_VALUE_WITH_ID : STR_VEHICLE_INFO_BUILT_VALUE);
|
||||
|
||||
SetDParam(0, u->cargo_type);
|
||||
SetDParam(1, u->cargo_cap);
|
||||
|
||||
@@ -10,8 +10,14 @@
|
||||
#include "../fileio_type.h"
|
||||
#include "../map_type.h"
|
||||
#include "../map_func.h"
|
||||
#include "../strings_func.h"
|
||||
#include "../town.h"
|
||||
#include "../tree_map.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <queue>
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
bool ReadHeightMap(DetailedFileType dft, const char *filename, uint *x, uint *y, byte **map);
|
||||
@@ -108,4 +114,87 @@ bool ConTreeMap(byte argc, char *argv[]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
extern void (*UpdateTownGrowthRate)(Town *t);
|
||||
|
||||
bool ConResetTownGrowth(byte argc, char *argv[]) {
|
||||
if (argc == 0) {
|
||||
IConsoleHelp("Resets growth to normal for all towns.");
|
||||
IConsoleHelp("Usage: 'cmresettowngrowth'");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (argc > 1) return false;
|
||||
|
||||
for (Town *town : Town::Iterate()) {
|
||||
ClrBit(town->flags, TOWN_CUSTOM_GROWTH);
|
||||
UpdateTownGrowthRate(town);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct FakeCommand {
|
||||
Date date;
|
||||
DateFract date_fract;
|
||||
uint company_id;
|
||||
uint cmd;
|
||||
TileIndex tile;
|
||||
uint32 p1, p2;
|
||||
std::string text;
|
||||
};
|
||||
|
||||
static std::queue<FakeCommand> _fake_commands;
|
||||
|
||||
void ExecuteFakeCommands(Date date, DateFract date_fract) {
|
||||
auto backup_company = _current_company;
|
||||
while (!_fake_commands.empty() && _fake_commands.front().date <= date && _fake_commands.front().date_fract <= date_fract) {
|
||||
auto &x = _fake_commands.front();
|
||||
if (x.date < date || x.date_fract < date_fract) IConsolePrintF(CC_WARNING,
|
||||
"Queued command is earlier than execution date: %d/%hu vs %d/%hu",
|
||||
x.date, x.date_fract, date, date_fract);
|
||||
fprintf(stderr, "Executing command: company=%u cmd=%u tile=%u p1=%u p2=%u text=%s ... ", x.company_id, x.cmd, x.tile, x.p1, x.p2, x.text.c_str());
|
||||
_current_company = (CompanyID)x.company_id;
|
||||
auto res = DoCommandPInternal(x.tile, x.p1, x.p2, x.cmd | CMD_NETWORK_COMMAND, nullptr, x.text.c_str(), false, false);
|
||||
if (res.Failed()) {
|
||||
if (res.GetErrorMessage() != INVALID_STRING_ID) {
|
||||
char buf[DRAW_STRING_BUFFER];
|
||||
GetString(buf, res.GetErrorMessage(), lastof(buf));
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
} else {
|
||||
fprintf(stderr, "FAIL\n");
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "OK\n");
|
||||
}
|
||||
_fake_commands.pop();
|
||||
}
|
||||
_current_company = backup_company;
|
||||
}
|
||||
|
||||
bool ConLoadCommands(byte argc, char *argv[]) {
|
||||
if (argc == 0) {
|
||||
IConsoleHelp("Loads a file with command queue to execute");
|
||||
IConsoleHelp("Usage: 'cmloadcommands <file>'");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (argc != 2) return false;
|
||||
|
||||
std::queue<FakeCommand>().swap(_fake_commands); // clear queue
|
||||
|
||||
std::ifstream file(argv[1], std::ios::in);
|
||||
std::string str;
|
||||
while(std::getline(file, str))
|
||||
{
|
||||
std::istringstream ss(str);
|
||||
FakeCommand cmd;
|
||||
ss >> cmd.date >> cmd.date_fract >> cmd.company_id >> cmd.cmd >> cmd.p1 >> cmd.p2 >> cmd.tile;
|
||||
std::string s;
|
||||
ss.get();
|
||||
std::getline(ss, cmd.text);
|
||||
// fprintf(stderr, "PARSED: company=%u cmd=%u tile=%u p1=%u p2=%u text=%s\n", cmd.company_id, cmd.cmd, cmd.tile, cmd.p1, cmd.p2, cmd.text.c_str());
|
||||
_fake_commands.push(cmd);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace citymania
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
#ifndef CM_CONSOLE_CMDS_HPP
|
||||
#define CM_CONSOLE_CMDS_HPP
|
||||
|
||||
#include "../date_type.h"
|
||||
|
||||
namespace citymania {
|
||||
|
||||
bool ConStep(byte argc, char *argv[]);
|
||||
bool ConExport(byte argc, char *argv[]);
|
||||
bool ConTreeMap(byte argc, char *argv[]);
|
||||
bool ConResetTownGrowth(byte argc, char *argv[]);
|
||||
bool ConLoadCommands(byte argc, char *argv[]);
|
||||
void ExecuteFakeCommands(Date date, DateFract date_fract);
|
||||
|
||||
} // namespace citymania
|
||||
|
||||
|
||||
+440
-58
@@ -1,20 +1,25 @@
|
||||
#include "../stdafx.h"
|
||||
|
||||
#include "cm_highlight.hpp"
|
||||
|
||||
// #include "cm_blueprint.hpp"
|
||||
#include "cm_main.hpp"
|
||||
#include "cm_station_gui.hpp"
|
||||
#include "cm_zoning.hpp"
|
||||
|
||||
#include "../core/math_func.hpp"
|
||||
#include "../table/bridge_land.h"
|
||||
#include "../command_func.h"
|
||||
#include "../house.h"
|
||||
#include "../industry.h"
|
||||
#include "../landscape.h"
|
||||
#include "../newgrf_railtype.h"
|
||||
#include "../newgrf_station.h"
|
||||
#include "../town.h"
|
||||
#include "../town_kdtree.h"
|
||||
#include "../tilearea_type.h"
|
||||
#include "../tilehighlight_type.h"
|
||||
#include "../tilehighlight_func.h"
|
||||
#include "../viewport_func.h"
|
||||
#include "../table/track_land.h"
|
||||
|
||||
@@ -36,6 +41,17 @@ extern RailType _cur_railtype;
|
||||
RoadBits FindRailsToConnect(TileIndex tile);
|
||||
extern DiagDirection _build_depot_direction; ///< Currently selected depot direction
|
||||
extern uint32 _realtime_tick;
|
||||
extern void GetStationLayout(byte *layout, int numtracks, int plat_len, const StationSpec *statspec);
|
||||
|
||||
struct RailStationGUISettings {
|
||||
Axis orientation; ///< Currently selected rail station orientation
|
||||
|
||||
bool newstations; ///< Are custom station definitions available?
|
||||
StationClassID station_class; ///< Currently selected custom station class (if newstations is \c true )
|
||||
byte station_type; ///< %Station type within the currently selected custom station class (if newstations is \c true )
|
||||
byte station_count; ///< Number of custom stations (if newstations is \c true )
|
||||
};
|
||||
extern RailStationGUISettings _railstation; ///< Settings of the station builder GUI
|
||||
|
||||
|
||||
namespace citymania {
|
||||
@@ -71,27 +87,58 @@ const byte _tileh_to_sprite[32] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 17, 0, 15, 18, 0,
|
||||
};
|
||||
|
||||
|
||||
ObjectTileHighlight ObjectTileHighlight::make_depot(DiagDirection ddir) {
|
||||
auto oh = ObjectTileHighlight(Type::RAIL_DEPOT);
|
||||
oh.u.depot.ddir = ddir;
|
||||
ObjectTileHighlight ObjectTileHighlight::make_rail_depot(SpriteID palette, DiagDirection ddir) {
|
||||
auto oh = ObjectTileHighlight(Type::RAIL_DEPOT, palette);
|
||||
oh.u.rail.depot.ddir = ddir;
|
||||
return oh;
|
||||
}
|
||||
|
||||
ObjectTileHighlight ObjectTileHighlight::make_rail(Track track) {
|
||||
auto oh = ObjectTileHighlight(Type::RAIL_TRACK);
|
||||
ObjectTileHighlight ObjectTileHighlight::make_rail_track(SpriteID palette, Track track) {
|
||||
auto oh = ObjectTileHighlight(Type::RAIL_TRACK, palette);
|
||||
oh.u.rail.track = track;
|
||||
return oh;
|
||||
}
|
||||
|
||||
ObjectTileHighlight ObjectTileHighlight::make_rail_station(SpriteID palette, Axis axis, byte section) {
|
||||
auto oh = ObjectTileHighlight(Type::RAIL_STATION, palette);
|
||||
oh.u.rail.station.axis = axis;
|
||||
oh.u.rail.station.section = section;
|
||||
return oh;
|
||||
}
|
||||
|
||||
ObjectTileHighlight ObjectTileHighlight::make_rail_signal(SpriteID palette, uint pos, SignalType type, SignalVariant variant) {
|
||||
auto oh = ObjectTileHighlight(Type::RAIL_SIGNAL, palette);
|
||||
oh.u.rail.signal.pos = pos;
|
||||
oh.u.rail.signal.type = type;
|
||||
oh.u.rail.signal.variant = variant;
|
||||
return oh;
|
||||
}
|
||||
|
||||
ObjectTileHighlight ObjectTileHighlight::make_rail_bridge_head(SpriteID palette, DiagDirection ddir, BridgeType type) {
|
||||
auto oh = ObjectTileHighlight(Type::RAIL_BRIDGE_HEAD, palette);
|
||||
oh.u.rail.bridge_head.ddir = ddir;
|
||||
oh.u.rail.bridge_head.type = type;
|
||||
return oh;
|
||||
}
|
||||
|
||||
ObjectTileHighlight ObjectTileHighlight::make_rail_tunnel_head(SpriteID palette, DiagDirection ddir) {
|
||||
auto oh = ObjectTileHighlight(Type::RAIL_TUNNEL_HEAD, palette);
|
||||
oh.u.rail.tunnel_head.ddir = ddir;
|
||||
return oh;
|
||||
}
|
||||
|
||||
bool ObjectHighlight::operator==(const ObjectHighlight& oh) {
|
||||
if (this->type != oh.type) return false;
|
||||
switch (this->type) {
|
||||
case Type::RAIL_DEPOT: return this->u.depot.tile == oh.u.depot.tile && this->u.depot.ddir == oh.u.depot.ddir;
|
||||
default: return true;
|
||||
}
|
||||
return true;
|
||||
return (this->tile == oh.tile
|
||||
&& this->end_tile == oh.end_tile
|
||||
&& this->axis == oh.axis
|
||||
&& this->ddir == oh.ddir
|
||||
&& this->blueprint == oh.blueprint);
|
||||
// switch (this->type) {
|
||||
// case Type::RAIL_DEPOT: return this->tile == oh.tile && this->ddir == oh.ddir;
|
||||
// default: return true;
|
||||
// }
|
||||
// return true;
|
||||
}
|
||||
|
||||
bool ObjectHighlight::operator!=(const ObjectHighlight& oh) {
|
||||
@@ -99,13 +146,28 @@ bool ObjectHighlight::operator!=(const ObjectHighlight& oh) {
|
||||
}
|
||||
|
||||
|
||||
ObjectHighlight ObjectHighlight::make_depot(TileIndex tile, DiagDirection ddir) {
|
||||
auto oh = ObjectHighlight(ObjectHighlight::Type::RAIL_DEPOT);
|
||||
oh.u.depot.tile = tile;
|
||||
oh.u.depot.ddir = ddir;
|
||||
ObjectHighlight ObjectHighlight::make_rail_depot(TileIndex tile, DiagDirection ddir) {
|
||||
auto oh = ObjectHighlight{ObjectHighlight::Type::RAIL_DEPOT};
|
||||
oh.tile = tile;
|
||||
oh.ddir = ddir;
|
||||
return oh;
|
||||
}
|
||||
|
||||
ObjectHighlight ObjectHighlight::make_rail_station(TileIndex start_tile, TileIndex end_tile, Axis axis) {
|
||||
auto oh = ObjectHighlight{ObjectHighlight::Type::RAIL_STATION};
|
||||
oh.tile = start_tile;
|
||||
oh.end_tile = end_tile;
|
||||
oh.axis = axis;
|
||||
return oh;
|
||||
}
|
||||
|
||||
// ObjectHighlight ObjectHighlight::make_blueprint(TileIndex tile, sp<Blueprint> blueprint) {
|
||||
// auto oh = ObjectHighlight{ObjectHighlight::Type::BLUEPRINT};
|
||||
// oh.tile = tile;
|
||||
// oh.blueprint = blueprint;
|
||||
// return oh;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Try to add an additional rail-track at the entrance of a depot
|
||||
* @param tile Tile to use for adding the rail-track
|
||||
@@ -118,7 +180,7 @@ void ObjectHighlight::PlaceExtraDepotRail(TileIndex tile, DiagDirection dir, Tra
|
||||
if (GetRailTileType(tile) != RAIL_TILE_NORMAL) return;
|
||||
if ((GetTrackBits(tile) & DiagdirReachesTracks(dir)) == 0) return;
|
||||
|
||||
this->tiles.insert(std::make_pair(tile, ObjectTileHighlight::make_rail(track)));
|
||||
this->tiles.insert(std::make_pair(tile, ObjectTileHighlight::make_rail_track(PALETTE_TINT_WHITE, track)));
|
||||
}
|
||||
|
||||
/** Additional pieces of track to add at the entrance of a depot. */
|
||||
@@ -135,22 +197,84 @@ static const DiagDirection _place_depot_extra_dir[12] = {
|
||||
DIAGDIR_NW, DIAGDIR_NE, DIAGDIR_NW, DIAGDIR_NE,
|
||||
};
|
||||
|
||||
static bool CanBuild(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) {
|
||||
return DoCommandPInternal(
|
||||
tile,
|
||||
p1,
|
||||
p2,
|
||||
cmd,
|
||||
nullptr, // callback
|
||||
nullptr, // text
|
||||
true, // my_cmd
|
||||
true // estimate_only
|
||||
).Succeeded();
|
||||
}
|
||||
|
||||
void ObjectHighlight::UpdateTiles() {
|
||||
this->tiles.clear();
|
||||
switch (this->type) {
|
||||
case Type::NONE:
|
||||
break;
|
||||
|
||||
case Type::RAIL_DEPOT: {
|
||||
auto dir = this->u.depot.ddir;
|
||||
this->tiles.insert(std::make_pair(this->u.depot.tile, ObjectTileHighlight::make_depot(dir)));
|
||||
auto tile = this->u.depot.tile + TileOffsByDiagDir(dir);
|
||||
auto dir = this->ddir;
|
||||
|
||||
auto palette = (CanBuild(
|
||||
this->tile,
|
||||
_cur_railtype,
|
||||
dir,
|
||||
CMD_BUILD_TRAIN_DEPOT
|
||||
) ? PALETTE_TINT_WHITE : PALETTE_TINT_RED_DEEP);
|
||||
|
||||
this->tiles.insert(std::make_pair(this->tile, ObjectTileHighlight::make_rail_depot(palette, dir)));
|
||||
auto tile = this->tile + TileOffsByDiagDir(dir);
|
||||
if (IsTileType(tile, MP_RAILWAY) && IsCompatibleRail(GetRailType(tile), _cur_railtype)) {
|
||||
PlaceExtraDepotRail(tile, _place_depot_extra_dir[dir], _place_depot_extra_track[dir]);
|
||||
PlaceExtraDepotRail(tile, _place_depot_extra_dir[dir + 4], _place_depot_extra_track[dir + 4]);
|
||||
PlaceExtraDepotRail(tile, _place_depot_extra_dir[dir + 8], _place_depot_extra_track[dir + 8]);
|
||||
this->PlaceExtraDepotRail(tile, _place_depot_extra_dir[dir], _place_depot_extra_track[dir]);
|
||||
this->PlaceExtraDepotRail(tile, _place_depot_extra_dir[dir + 4], _place_depot_extra_track[dir + 4]);
|
||||
this->PlaceExtraDepotRail(tile, _place_depot_extra_dir[dir + 8], _place_depot_extra_track[dir + 8]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case Type::RAIL_STATION: {
|
||||
auto ta = OrthogonalTileArea(this->tile, this->end_tile);
|
||||
auto numtracks = ta.w;
|
||||
auto plat_len = ta.h;
|
||||
if (this->axis == AXIS_X) Swap(numtracks, plat_len);
|
||||
|
||||
auto palette = (CanBuild(
|
||||
this->tile,
|
||||
_cur_railtype
|
||||
| (this->axis << 6)
|
||||
| ((uint32)numtracks << 8)
|
||||
| ((uint32)plat_len << 16),
|
||||
NEW_STATION << 16,
|
||||
CMD_BUILD_RAIL_STATION
|
||||
) ? PALETTE_TINT_WHITE : PALETTE_TINT_RED_DEEP);
|
||||
|
||||
auto layout_ptr = AllocaM(byte, (int)numtracks * plat_len);
|
||||
GetStationLayout(layout_ptr, numtracks, plat_len, nullptr); // TODO statspec
|
||||
|
||||
auto tile_delta = (this->axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
|
||||
TileIndex tile_track = this->tile;
|
||||
do {
|
||||
TileIndex tile = tile_track;
|
||||
int w = plat_len;
|
||||
do {
|
||||
byte layout = *layout_ptr++;
|
||||
this->tiles.insert(std::make_pair(tile, ObjectTileHighlight::make_rail_station(palette, this->axis, layout & ~1)));
|
||||
tile += tile_delta;
|
||||
} while (--w);
|
||||
tile_track += tile_delta ^ TileDiffXY(1, 1); // perpendicular to tile_delta
|
||||
} while (--numtracks);
|
||||
|
||||
break;
|
||||
}
|
||||
// case Type::BLUEPRINT:
|
||||
// if (this->blueprint && this->tile != INVALID_TILE)
|
||||
// this->tiles = this->blueprint->GetTiles(this->tile);
|
||||
// break;
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +286,43 @@ void ObjectHighlight::MarkDirty() {
|
||||
}
|
||||
|
||||
|
||||
void DrawTrainDepotSprite(const TileInfo *ti, RailType railtype, DiagDirection ddir)
|
||||
SpriteID GetTintBySelectionColour(SpriteID colour, bool deep=false) {
|
||||
switch(colour) {
|
||||
case SPR_PALETTE_ZONING_RED: return (deep ? PALETTE_TINT_RED_DEEP : PALETTE_TINT_RED);
|
||||
case SPR_PALETTE_ZONING_ORANGE: return (deep ? PALETTE_TINT_ORANGE_DEEP : PALETTE_TINT_ORANGE);
|
||||
case SPR_PALETTE_ZONING_GREEN: return (deep ? PALETTE_TINT_GREEN_DEEP : PALETTE_TINT_GREEN);
|
||||
case SPR_PALETTE_ZONING_LIGHT_BLUE: return (deep ? PALETTE_TINT_CYAN_DEEP : PALETTE_TINT_CYAN);
|
||||
case SPR_PALETTE_ZONING_YELLOW: return PALETTE_TINT_YELLOW;
|
||||
// case SPR_PALETTE_ZONING__: return PALETTE_TINT_YELLOW_WHITE;
|
||||
case SPR_PALETTE_ZONING_WHITE: return PALETTE_TINT_WHITE;
|
||||
default: return PAL_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
SpriteID GetSelectionColourByTint(SpriteID colour) {
|
||||
switch(colour) {
|
||||
case PALETTE_TINT_RED_DEEP:
|
||||
case PALETTE_TINT_RED:
|
||||
return SPR_PALETTE_ZONING_RED;
|
||||
case PALETTE_TINT_ORANGE_DEEP:
|
||||
case PALETTE_TINT_ORANGE:
|
||||
return SPR_PALETTE_ZONING_ORANGE;
|
||||
case PALETTE_TINT_GREEN_DEEP:
|
||||
case PALETTE_TINT_GREEN:
|
||||
return SPR_PALETTE_ZONING_GREEN;
|
||||
case PALETTE_TINT_CYAN_DEEP:
|
||||
case PALETTE_TINT_CYAN:
|
||||
return SPR_PALETTE_ZONING_LIGHT_BLUE;
|
||||
case PALETTE_TINT_YELLOW:
|
||||
return SPR_PALETTE_ZONING_YELLOW;
|
||||
// returnase SPR_PALETTE_ZONING__: return PALETTE_TINT_YELLOW_WHITE;
|
||||
case PALETTE_TINT_WHITE:
|
||||
return SPR_PALETTE_ZONING_WHITE;
|
||||
default: return PAL_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawTrainDepotSprite(SpriteID palette, const TileInfo *ti, RailType railtype, DiagDirection ddir)
|
||||
{
|
||||
const DrawTileSprites *dts = &_depot_gfx_table[ddir];
|
||||
const RailtypeInfo *rti = GetRailTypeInfo(railtype);
|
||||
@@ -170,13 +330,13 @@ void DrawTrainDepotSprite(const TileInfo *ti, RailType railtype, DiagDirection d
|
||||
uint32 offset = rti->GetRailtypeSpriteOffset();
|
||||
|
||||
if (image != SPR_FLAT_GRASS_TILE) image += offset;
|
||||
PaletteID palette = COMPANY_SPRITE_COLOUR(_local_company);
|
||||
// PaletteID palette = COMPANY_SPRITE_COLOUR(_local_company);
|
||||
|
||||
// DrawSprite(image, PAL_NONE, x, y);
|
||||
|
||||
switch (ddir) {
|
||||
case DIAGDIR_SW: DrawAutorailSelection(ti, HT_DIR_X, PAL_NONE); break;
|
||||
case DIAGDIR_SE: DrawAutorailSelection(ti, HT_DIR_Y, PAL_NONE); break;
|
||||
case DIAGDIR_SW: DrawAutorailSelection(ti, HT_DIR_X, GetSelectionColourByTint(palette)); break;
|
||||
case DIAGDIR_SE: DrawAutorailSelection(ti, HT_DIR_Y, GetSelectionColourByTint(palette)); break;
|
||||
default: break;
|
||||
}
|
||||
// if (rti->UsesOverlay()) {
|
||||
@@ -191,27 +351,208 @@ void DrawTrainDepotSprite(const TileInfo *ti, RailType railtype, DiagDirection d
|
||||
int depot_sprite = GetCustomRailSprite(rti, INVALID_TILE, RTSG_DEPOT);
|
||||
if (depot_sprite != 0) offset = depot_sprite - SPR_RAIL_DEPOT_SE_1;
|
||||
|
||||
DrawRailTileSeq(ti, dts, TO_INVALID, offset, 0, PALETTE_TINT_WHITE);
|
||||
DrawRailTileSeq(ti, dts, TO_INVALID, offset, 0, palette);
|
||||
}
|
||||
|
||||
void DrawTrainStationSprite(SpriteID palette, const TileInfo *ti, RailType railtype, Axis axis, byte section) {
|
||||
int32 total_offset = 0;
|
||||
PaletteID pal = COMPANY_SPRITE_COLOUR(_local_company);
|
||||
const DrawTileSprites *t = GetStationTileLayout(STATION_RAIL, section + (axis == AXIS_X ? 0 : 1));
|
||||
const RailtypeInfo *rti = nullptr;
|
||||
|
||||
if (railtype != INVALID_RAILTYPE) {
|
||||
rti = GetRailTypeInfo(railtype);
|
||||
total_offset = rti->GetRailtypeSpriteOffset();
|
||||
}
|
||||
|
||||
DrawAutorailSelection(ti, (axis == AXIS_X ? HT_DIR_X : HT_DIR_Y), GetSelectionColourByTint(palette));
|
||||
|
||||
// if (roadtype != INVALID_ROADTYPE) {
|
||||
// const RoadTypeInfo* rti = GetRoadTypeInfo(roadtype);
|
||||
// if (image >= 4) {
|
||||
// /* Drive-through stop */
|
||||
// uint sprite_offset = 5 - image;
|
||||
|
||||
// /* Road underlay takes precedence over tram */
|
||||
// if (rti->UsesOverlay()) {
|
||||
// SpriteID ground = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_GROUND);
|
||||
// DrawSprite(ground + sprite_offset, PAL_NONE, x, y);
|
||||
|
||||
// SpriteID overlay = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_OVERLAY);
|
||||
// if (overlay) DrawSprite(overlay + sprite_offset, PAL_NONE, x, y);
|
||||
// } else if (RoadTypeIsTram(roadtype)) {
|
||||
// DrawSprite(SPR_TRAMWAY_TRAM + sprite_offset, PAL_NONE, x, y);
|
||||
// }
|
||||
// } else {
|
||||
// /* Drive-in stop */
|
||||
// if (RoadTypeIsRoad(roadtype) && rti->UsesOverlay()) {
|
||||
// SpriteID ground = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_ROADSTOP);
|
||||
// DrawSprite(ground + image, PAL_NONE, x, y);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
/* Default waypoint has no railtype specific sprites */
|
||||
// DrawRailTileSeq(ti, t, TO_INVALID, (st == STATION_WAYPOINT ? 0 : total_offset), 0, PALETTE_TINT_WHITE);
|
||||
DrawRailTileSeq(ti, t, TO_INVALID, total_offset, 0, palette);
|
||||
}
|
||||
|
||||
enum SignalOffsets { // from rail_cmd.cpp
|
||||
SIGNAL_TO_SOUTHWEST,
|
||||
SIGNAL_TO_NORTHEAST,
|
||||
SIGNAL_TO_SOUTHEAST,
|
||||
SIGNAL_TO_NORTHWEST,
|
||||
SIGNAL_TO_EAST,
|
||||
SIGNAL_TO_WEST,
|
||||
SIGNAL_TO_SOUTH,
|
||||
SIGNAL_TO_NORTH,
|
||||
};
|
||||
|
||||
/**
|
||||
* copied from rail_cmd.cpp
|
||||
* Get surface height in point (x,y)
|
||||
* On tiles with halftile foundations move (x,y) to a safe point wrt. track
|
||||
*/
|
||||
static uint GetSaveSlopeZ(uint x, uint y, Track track)
|
||||
{
|
||||
switch (track) {
|
||||
case TRACK_UPPER: x &= ~0xF; y &= ~0xF; break;
|
||||
case TRACK_LOWER: x |= 0xF; y |= 0xF; break;
|
||||
case TRACK_LEFT: x |= 0xF; y &= ~0xF; break;
|
||||
case TRACK_RIGHT: x &= ~0xF; y |= 0xF; break;
|
||||
default: break;
|
||||
}
|
||||
return GetSlopePixelZ(x, y);
|
||||
}
|
||||
|
||||
void DrawSignal(const TileInfo *ti, RailType railtype, uint pos, SignalType type, SignalVariant variant) {
|
||||
// reference: DraawSingleSignal in rail_cmd.cpp
|
||||
bool side;
|
||||
switch (_settings_game.construction.train_signal_side) {
|
||||
case 0: side = false; break; // left
|
||||
case 2: side = true; break; // right
|
||||
default: side = _settings_game.vehicle.road_side != 0; break; // driving side
|
||||
}
|
||||
static const Point SignalPositions[2][12] = {
|
||||
{ // Signals on the left side
|
||||
/* LEFT LEFT RIGHT RIGHT UPPER UPPER */
|
||||
{ 8, 5}, {14, 1}, { 1, 14}, { 9, 11}, { 1, 0}, { 3, 10},
|
||||
/* LOWER LOWER X X Y Y */
|
||||
{11, 4}, {14, 14}, {11, 3}, { 4, 13}, { 3, 4}, {11, 13}
|
||||
}, { // Signals on the right side
|
||||
/* LEFT LEFT RIGHT RIGHT UPPER UPPER */
|
||||
{14, 1}, {12, 10}, { 4, 6}, { 1, 14}, {10, 4}, { 0, 1},
|
||||
/* LOWER LOWER X X Y Y */
|
||||
{14, 14}, { 5, 12}, {11, 13}, { 4, 3}, {13, 4}, { 3, 11}
|
||||
}
|
||||
};
|
||||
|
||||
uint x = TileX(ti->tile) * TILE_SIZE + SignalPositions[side][pos].x;
|
||||
uint y = TileY(ti->tile) * TILE_SIZE + SignalPositions[side][pos].y;
|
||||
|
||||
static const Track pos_track[] = {
|
||||
TRACK_LEFT, TRACK_LEFT, TRACK_RIGHT, TRACK_RIGHT,
|
||||
TRACK_UPPER, TRACK_UPPER, TRACK_LOWER, TRACK_LOWER,
|
||||
TRACK_X, TRACK_X, TRACK_Y, TRACK_Y,
|
||||
};
|
||||
static const SignalOffsets pos_offset[] = {
|
||||
SIGNAL_TO_NORTH, SIGNAL_TO_SOUTH, SIGNAL_TO_NORTH, SIGNAL_TO_SOUTH,
|
||||
SIGNAL_TO_WEST, SIGNAL_TO_EAST, SIGNAL_TO_WEST, SIGNAL_TO_EAST,
|
||||
SIGNAL_TO_SOUTHWEST, SIGNAL_TO_NORTHEAST, SIGNAL_TO_SOUTHEAST, SIGNAL_TO_NORTHWEST,
|
||||
};
|
||||
|
||||
auto track = pos_track[pos];
|
||||
auto image = pos_offset[pos];
|
||||
static const SignalState condition = SIGNAL_STATE_GREEN;
|
||||
|
||||
auto rti = GetRailTypeInfo(railtype);
|
||||
SpriteID sprite = GetCustomSignalSprite(rti, ti->tile, type, variant, condition);
|
||||
if (sprite != 0) {
|
||||
sprite += image;
|
||||
} else {
|
||||
/* Normal electric signals are stored in a different sprite block than all other signals. */
|
||||
sprite = (type == SIGTYPE_NORMAL && variant == SIG_ELECTRIC) ? SPR_ORIGINAL_SIGNALS_BASE : SPR_SIGNALS_BASE - 16;
|
||||
sprite += type * 16 + variant * 64 + image * 2 + condition + (type > SIGTYPE_LAST_NOPBS ? 64 : 0);
|
||||
}
|
||||
|
||||
AddSortableSpriteToDraw(sprite, PALETTE_TINT_WHITE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, GetSaveSlopeZ(x, y, track));
|
||||
}
|
||||
|
||||
// copied from tunnelbridge_cmd.cpp
|
||||
static inline const PalSpriteID *GetBridgeSpriteTable(int index, BridgePieces table)
|
||||
{
|
||||
const BridgeSpec *bridge = GetBridgeSpec(index);
|
||||
assert(table < BRIDGE_PIECE_INVALID);
|
||||
if (bridge->sprite_table == nullptr || bridge->sprite_table[table] == nullptr) {
|
||||
return _bridge_sprite_table[index][table];
|
||||
} else {
|
||||
return bridge->sprite_table[table];
|
||||
}
|
||||
}
|
||||
|
||||
void DrawBridgeHead(const TileInfo *ti, RailType railtype, DiagDirection ddir, BridgeType type) {
|
||||
auto rti = GetRailTypeInfo(railtype);
|
||||
int base_offset = rti->bridge_offset;
|
||||
const PalSpriteID *psid;
|
||||
|
||||
/* HACK Wizardry to convert the bridge ramp direction into a sprite offset */
|
||||
base_offset += (6 - ddir) % 4;
|
||||
|
||||
/* Table number BRIDGE_PIECE_HEAD always refers to the bridge heads for any bridge type */
|
||||
if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
|
||||
psid = &GetBridgeSpriteTable(type, BRIDGE_PIECE_HEAD)[base_offset];
|
||||
|
||||
AddSortableSpriteToDraw(psid->sprite, PALETTE_TINT_WHITE, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 0 : 8, ti->z);
|
||||
// DrawAutorailSelection(ti, (ddir == DIAGDIR_SW || ddir == DIAGDIR_NE ? HT_DIR_X : HT_DIR_Y), PAL_NONE);
|
||||
}
|
||||
|
||||
void DrawTunnelHead(const TileInfo *ti, RailType railtype, DiagDirection ddir) {
|
||||
auto rti = GetRailTypeInfo(railtype);
|
||||
|
||||
SpriteID image;
|
||||
SpriteID railtype_overlay = 0;
|
||||
|
||||
image = rti->base_sprites.tunnel;
|
||||
if (rti->UsesOverlay()) {
|
||||
/* Check if the railtype has custom tunnel portals. */
|
||||
railtype_overlay = GetCustomRailSprite(rti, ti->tile, RTSG_TUNNEL_PORTAL);
|
||||
if (railtype_overlay != 0) image = SPR_RAILTYPE_TUNNEL_BASE; // Draw blank grass tunnel base.
|
||||
}
|
||||
|
||||
image += ddir * 2;
|
||||
AddSortableSpriteToDraw(image, PALETTE_TINT_WHITE, ti->x, ti->y, 16, 16, 0, ti->z);
|
||||
}
|
||||
|
||||
void ObjectHighlight::Draw(const TileInfo *ti) {
|
||||
this->UpdateTiles();
|
||||
auto range = this->tiles.equal_range(ti->tile);
|
||||
for (auto t = range.first; t != range.second; t++) {
|
||||
auto &oth = t->second;
|
||||
switch (oth.type) {
|
||||
case ObjectTileHighlight::Type::RAIL_DEPOT:
|
||||
DrawTrainDepotSprite(ti, _cur_railtype, oth.u.depot.ddir);
|
||||
DrawTrainDepotSprite(oth.palette, ti, _cur_railtype, oth.u.rail.depot.ddir);
|
||||
break;
|
||||
case ObjectTileHighlight::Type::RAIL_TRACK: {
|
||||
auto hs = (HighLightStyle)oth.u.rail.track;
|
||||
DrawAutorailSelection(ti, hs, PAL_NONE);
|
||||
break;
|
||||
}
|
||||
case ObjectTileHighlight::Type::RAIL_STATION:
|
||||
DrawTrainStationSprite(oth.palette, ti, _cur_railtype, oth.u.rail.station.axis, oth.u.rail.station.section);
|
||||
break;
|
||||
case ObjectTileHighlight::Type::RAIL_SIGNAL:
|
||||
DrawSignal(ti, _cur_railtype, oth.u.rail.signal.pos, oth.u.rail.signal.type, oth.u.rail.signal.variant);
|
||||
break;
|
||||
case ObjectTileHighlight::Type::RAIL_BRIDGE_HEAD:
|
||||
DrawBridgeHead(ti, _cur_railtype, oth.u.rail.bridge_head.ddir, oth.u.rail.bridge_head.type);
|
||||
break;
|
||||
case ObjectTileHighlight::Type::RAIL_TUNNEL_HEAD:
|
||||
DrawTunnelHead(ti, _cur_railtype, oth.u.rail.tunnel_head.ddir);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// fprintf(stderr, "TILEH DRAW %d %d %d\n", ti->tile, (int)i, (int)this->tiles.size());
|
||||
}
|
||||
|
||||
|
||||
@@ -294,19 +635,6 @@ SpriteID GetIndustryZoningPalette(TileIndex tile) {
|
||||
return PAL_NONE;
|
||||
}
|
||||
|
||||
SpriteID GetTintBySelectionColour(SpriteID colour, bool deep=false) {
|
||||
switch(colour) {
|
||||
case SPR_PALETTE_ZONING_RED: return (deep ? PALETTE_TINT_RED_DEEP : PALETTE_TINT_RED);
|
||||
case SPR_PALETTE_ZONING_ORANGE: return (deep ? PALETTE_TINT_ORANGE_DEEP : PALETTE_TINT_ORANGE);
|
||||
case SPR_PALETTE_ZONING_GREEN: return (deep ? PALETTE_TINT_GREEN_DEEP : PALETTE_TINT_GREEN);
|
||||
case SPR_PALETTE_ZONING_LIGHT_BLUE: return (deep ? PALETTE_TINT_CYAN_DEEP : PALETTE_TINT_CYAN);
|
||||
case SPR_PALETTE_ZONING_YELLOW: return PALETTE_TINT_YELLOW;
|
||||
// case SPR_PALETTE_ZONING__: return PALETTE_TINT_YELLOW_WHITE;
|
||||
case SPR_PALETTE_ZONING_WHITE: return PALETTE_TINT_WHITE;
|
||||
default: return PAL_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static void SetStationSelectionHighlight(const TileInfo *ti, TileHighlight &th) {
|
||||
bool draw_selection = ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && _thd.outersize.x > 0);
|
||||
const Station *highlight_station = _viewport_highlight_station;
|
||||
@@ -314,17 +642,20 @@ static void SetStationSelectionHighlight(const TileInfo *ti, TileHighlight &th)
|
||||
if (_highlight_station_to_join) highlight_station = _highlight_station_to_join;
|
||||
|
||||
if (draw_selection) {
|
||||
auto b = CalcTileBorders(ti->tile, [](TileIndex t) {
|
||||
auto x = TileX(t) * TILE_SIZE, y = TileY(t) * TILE_SIZE;
|
||||
return IsInsideSelectedRectangle(x, y);
|
||||
});
|
||||
const SpriteID pal[] = {SPR_PALETTE_ZONING_RED, SPR_PALETTE_ZONING_YELLOW, SPR_PALETTE_ZONING_LIGHT_BLUE, SPR_PALETTE_ZONING_GREEN};
|
||||
auto color = pal[(int)_station_building_status];
|
||||
if (_thd.make_square_red) color = SPR_PALETTE_ZONING_RED;
|
||||
if (b.first != ZoningBorder::NONE)
|
||||
th.add_border(b.first, color);
|
||||
// const SpriteID pal[] = {SPR_PALETTE_ZONING_RED, SPR_PALETTE_ZONING_YELLOW, SPR_PALETTE_ZONING_LIGHT_BLUE, SPR_PALETTE_ZONING_GREEN};
|
||||
// auto color = pal[(int)_station_building_status];
|
||||
// if (_thd.make_square_red) color = SPR_PALETTE_ZONING_RED;
|
||||
if (_thd.make_square_red) {
|
||||
auto b = CalcTileBorders(ti->tile, [](TileIndex t) {
|
||||
auto x = TileX(t) * TILE_SIZE, y = TileY(t) * TILE_SIZE;
|
||||
return IsInsideSelectedRectangle(x, y);
|
||||
});
|
||||
if (b.first != ZoningBorder::NONE)
|
||||
th.add_border(b.first, SPR_PALETTE_ZONING_RED);
|
||||
}
|
||||
if (IsInsideSelectedRectangle(TileX(ti->tile) * TILE_SIZE, TileY(ti->tile) * TILE_SIZE)) {
|
||||
th.ground_pal = GetTintBySelectionColour(color);
|
||||
// th.ground_pal = GetTintBySelectionColour(color);
|
||||
th.ground_pal = th.structure_pal = (_thd.make_square_red ? PALETTE_TINT_RED : PAL_NONE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -529,6 +860,7 @@ TileHighlight GetTileHighlight(const TileInfo *ti) {
|
||||
}
|
||||
|
||||
SetStationSelectionHighlight(ti, th);
|
||||
// SetBlueprintHighlight(ti, th);
|
||||
|
||||
return th;
|
||||
}
|
||||
@@ -549,6 +881,8 @@ void DrawTileZoning(const TileInfo *ti, const TileHighlight &th) {
|
||||
bool DrawTileSelection(const TileInfo *ti, const TileHighlightType &tht) {
|
||||
_thd.cm.Draw(ti);
|
||||
|
||||
// if (_thd.drawstyle == CM_HT_BLUEPRINT_PLACE) return true;
|
||||
|
||||
if ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && _thd.outersize.x > 0) {
|
||||
// station selector, handled by DrawTileZoning
|
||||
return true;
|
||||
@@ -612,17 +946,65 @@ DiagDirection AutodetectRailObjectDirection(TileIndex tile, Point pt) {
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
||||
TileIndex _autodetection_tile = INVALID_TILE;
|
||||
DiagDirDiff _autodetection_rotation = DIAGDIRDIFF_SAME;
|
||||
|
||||
static DiagDirDiff GetAutodetectionRotation() {
|
||||
auto pt = GetTileBelowCursor();
|
||||
auto tile = TileVirtXY(pt.x, pt.y);
|
||||
|
||||
if (tile != _autodetection_tile) {
|
||||
_autodetection_tile = tile;
|
||||
_autodetection_rotation = DIAGDIRDIFF_SAME;
|
||||
}
|
||||
|
||||
return _autodetection_rotation;
|
||||
}
|
||||
|
||||
void RotateAutodetection() {
|
||||
auto rotation = GetAutodetectionRotation();
|
||||
if (rotation == DIAGDIRDIFF_90LEFT) rotation = DIAGDIRDIFF_SAME;
|
||||
else rotation++;
|
||||
_autodetection_rotation = rotation;
|
||||
::UpdateTileSelection();
|
||||
}
|
||||
|
||||
void ResetRotateAutodetection() {
|
||||
_autodetection_tile = INVALID_TILE;
|
||||
_autodetection_rotation = DIAGDIRDIFF_SAME;
|
||||
}
|
||||
|
||||
DiagDirection AddAutodetectionRotation(DiagDirection ddir) {
|
||||
return ChangeDiagDir(ddir, GetAutodetectionRotation());
|
||||
}
|
||||
|
||||
HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) {
|
||||
_thd.cm_new = ObjectHighlight(ObjectHighlight::Type::NONE);
|
||||
auto pt = GetTileBelowCursor();
|
||||
auto tile = (pt.x == -1 ? INVALID_TILE : TileVirtXY(pt.x, pt.y));
|
||||
// fprintf(stderr, "UPDATE %d %d %d %d\n", tile, _thd.size.x, _thd.size.y, (int)((_thd.place_mode & HT_DRAG_MASK) == HT_RECT));
|
||||
// if (_thd.place_mode == CM_HT_BLUEPRINT_PLACE) {
|
||||
// UpdateBlueprintTileSelection(pt, tile);
|
||||
// new_drawstyle = CM_HT_BLUEPRINT_PLACE;
|
||||
// } else
|
||||
if ((_thd.place_mode & HT_DRAG_MASK) == HT_RECT &&
|
||||
_cursor.sprite_seq[0].sprite == GetRailTypeInfo(_cur_railtype)->cursor.depot) {
|
||||
auto dir = _build_depot_direction;
|
||||
auto pt = GetTileBelowCursor();
|
||||
auto tile = TileVirtXY(pt.x, pt.y);
|
||||
if (pt.x != -1) {
|
||||
if (dir >= DiagDirection::DIAGDIR_END)
|
||||
dir = AutodetectRailObjectDirection(tile, pt);
|
||||
_thd.cm_new = ObjectHighlight::make_depot(tile, dir);
|
||||
if (dir >= DiagDirection::DIAGDIR_END) {
|
||||
dir = AddAutodetectionRotation(AutodetectRailObjectDirection(tile, pt));
|
||||
}
|
||||
_thd.cm_new = ObjectHighlight::make_rail_depot(tile, dir);
|
||||
}
|
||||
new_drawstyle = HT_RECT;
|
||||
} else if (((_thd.place_mode & HT_DRAG_MASK) == HT_RECT || ((_thd.place_mode & HT_DRAG_MASK) == HT_SPECIAL && (_thd.next_drawstyle & HT_DRAG_MASK) == HT_RECT)) && _thd.new_outersize.x > 0 && !_thd.make_square_red) { // station
|
||||
if (_thd.size.x >= (int)TILE_SIZE && _thd.size.y >= (int)TILE_SIZE) {
|
||||
auto start_tile = TileXY(_thd.new_pos.x / TILE_SIZE, _thd.new_pos.y / TILE_SIZE);
|
||||
auto end_tile = TileXY(
|
||||
std::min((_thd.new_pos.x + _thd.new_size.x) / TILE_SIZE, MapSizeX()) - 1,
|
||||
std::min((_thd.new_pos.y + _thd.new_size.y) / TILE_SIZE, MapSizeY()) - 1
|
||||
);
|
||||
_thd.cm_new = ObjectHighlight::make_rail_station(start_tile, end_tile, _railstation.orientation);
|
||||
}
|
||||
new_drawstyle = HT_RECT;
|
||||
}
|
||||
|
||||
@@ -96,6 +96,9 @@ void SetIndustryForbiddenTilesHighlight(IndustryType type);
|
||||
|
||||
PaletteID GetTreeShadePal(TileIndex tile);
|
||||
|
||||
void RotateAutodetection();
|
||||
void ResetRotateAutodetection();
|
||||
|
||||
} // namespace citymania
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,36 +1,155 @@
|
||||
#ifndef CITYMANIA_HIGHLIGHT_TYPE_HPP
|
||||
#define CITYMANIA_HIGHLIGHT_TYPE_HPP
|
||||
|
||||
#include "../bridge.h"
|
||||
#include "../direction_type.h"
|
||||
#include "../map_func.h"
|
||||
#include "../signal_type.h"
|
||||
#include "../station_type.h"
|
||||
#include "../tile_cmd.h"
|
||||
#include "../tile_type.h"
|
||||
#include "../track_type.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace citymania {
|
||||
|
||||
|
||||
class ObjectTileHighlight {
|
||||
public:
|
||||
enum class Type {
|
||||
RAIL_DEPOT = 0,
|
||||
RAIL_TRACK = 1,
|
||||
BEGIN = 0,
|
||||
RAIL_DEPOT = BEGIN,
|
||||
RAIL_TRACK,
|
||||
RAIL_STATION,
|
||||
RAIL_SIGNAL,
|
||||
RAIL_BRIDGE_HEAD,
|
||||
RAIL_TUNNEL_HEAD,
|
||||
END,
|
||||
};
|
||||
|
||||
Type type;
|
||||
SpriteID palette;
|
||||
|
||||
union {
|
||||
struct {
|
||||
DiagDirection ddir;
|
||||
} depot;
|
||||
struct {
|
||||
struct {
|
||||
DiagDirection ddir;
|
||||
} depot;
|
||||
Track track;
|
||||
struct {
|
||||
Axis axis;
|
||||
byte section;
|
||||
} station;
|
||||
struct {
|
||||
uint pos;
|
||||
SignalType type;
|
||||
SignalVariant variant;
|
||||
} signal;
|
||||
struct {
|
||||
DiagDirection ddir;
|
||||
TileIndex other_end;
|
||||
BridgeType type;
|
||||
} bridge_head;
|
||||
struct {
|
||||
DiagDirection ddir;
|
||||
} tunnel_head;
|
||||
} rail;
|
||||
} u;
|
||||
|
||||
ObjectTileHighlight(Type type): type{type} {}
|
||||
static ObjectTileHighlight make_depot(DiagDirection ddir);
|
||||
static ObjectTileHighlight make_rail(Track track);
|
||||
ObjectTileHighlight(Type type, SpriteID palette): type{type}, palette{palette} {}
|
||||
static ObjectTileHighlight make_rail_depot(SpriteID palette, DiagDirection ddir);
|
||||
static ObjectTileHighlight make_rail_track(SpriteID palette, Track track);
|
||||
static ObjectTileHighlight make_rail_station(SpriteID palette, Axis axis, byte section);
|
||||
static ObjectTileHighlight make_rail_signal(SpriteID palette, uint pos, SignalType type, SignalVariant variant);
|
||||
static ObjectTileHighlight make_rail_bridge_head(SpriteID palette, DiagDirection ddir, BridgeType type);
|
||||
static ObjectTileHighlight make_rail_tunnel_head(SpriteID palette, DiagDirection ddir);
|
||||
};
|
||||
|
||||
class TileIndexDiffCCompare{
|
||||
public:
|
||||
bool operator()(const TileIndexDiffC &a, const TileIndexDiffC &b) const {
|
||||
if (a.x < b.x) return true;
|
||||
if (a.x == b.x && a.y < b.y) return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class Blueprint {
|
||||
public:
|
||||
class Item {
|
||||
public:
|
||||
enum class Type {
|
||||
BEGIN = 0,
|
||||
RAIL_DEPOT = BEGIN,
|
||||
RAIL_TRACK,
|
||||
RAIL_STATION,
|
||||
RAIL_STATION_PART,
|
||||
RAIL_SIGNAL,
|
||||
RAIL_BRIDGE,
|
||||
RAIL_TUNNEL,
|
||||
END,
|
||||
};
|
||||
Type type;
|
||||
TileIndexDiffC tdiff;
|
||||
union {
|
||||
struct {
|
||||
struct {
|
||||
DiagDirection ddir;
|
||||
} depot;
|
||||
struct {
|
||||
uint16 length;
|
||||
Trackdir start_dir;
|
||||
} track;
|
||||
struct {
|
||||
StationID id;
|
||||
bool has_part;
|
||||
} station;
|
||||
struct {
|
||||
Axis axis;
|
||||
StationID id;
|
||||
} station_part;
|
||||
struct {
|
||||
uint pos;
|
||||
SignalType type;
|
||||
SignalVariant variant;
|
||||
} signal;
|
||||
struct {
|
||||
DiagDirection ddir;
|
||||
TileIndexDiffC other_end;
|
||||
BridgeType type;
|
||||
} bridge;
|
||||
struct {
|
||||
DiagDirection ddir;
|
||||
TileIndexDiffC other_end;
|
||||
} tunnel;
|
||||
} rail;
|
||||
} u;
|
||||
Item(Type type, TileIndexDiffC tdiff)
|
||||
: type{type}, tdiff{tdiff} {}
|
||||
};
|
||||
|
||||
std::vector<Item> items;
|
||||
std::set<TileIndexDiffC, TileIndexDiffCCompare> tiles;
|
||||
|
||||
Blueprint() {}
|
||||
|
||||
void Clear() {
|
||||
this->items.clear();
|
||||
this->tiles.clear();
|
||||
}
|
||||
|
||||
void Add(Item item);
|
||||
|
||||
bool HasTile(TileIndexDiffC tdiff) {
|
||||
return (this->tiles.find(tdiff) != this->tiles.end());
|
||||
}
|
||||
|
||||
sp<Blueprint> Rotate();
|
||||
|
||||
std::multimap<TileIndex, ObjectTileHighlight> GetTiles(TileIndex tile);
|
||||
};
|
||||
|
||||
class ObjectHighlight {
|
||||
@@ -38,28 +157,31 @@ public:
|
||||
enum class Type {
|
||||
NONE = 0,
|
||||
RAIL_DEPOT = 1,
|
||||
RAIL_STATION = 2,
|
||||
// BLUEPRINT = 2,
|
||||
};
|
||||
|
||||
protected:
|
||||
Type type;
|
||||
union {
|
||||
struct {
|
||||
TileIndex tile;
|
||||
DiagDirection ddir;
|
||||
} depot;
|
||||
} u;
|
||||
TileIndex tile = INVALID_TILE;
|
||||
TileIndex end_tile = INVALID_TILE;
|
||||
Axis axis = INVALID_AXIS;
|
||||
DiagDirection ddir = INVALID_DIAGDIR;
|
||||
sp<Blueprint> blueprint = nullptr;
|
||||
|
||||
protected:
|
||||
bool tiles_updated = false;
|
||||
std::multimap<TileIndex, ObjectTileHighlight> tiles;
|
||||
void UpdateTiles();
|
||||
void PlaceExtraDepotRail(TileIndex tile, DiagDirection dir, Track track);
|
||||
|
||||
public:
|
||||
ObjectHighlight(Type type = Type::NONE): type{type} { /* get rid of uninitualized warning */ this->u.depot.tile = INVALID_TILE; }
|
||||
ObjectHighlight(Type type = Type::NONE): type{type} {}
|
||||
bool operator==(const ObjectHighlight& oh);
|
||||
bool operator!=(const ObjectHighlight& oh);
|
||||
|
||||
static ObjectHighlight make_depot(TileIndex tile, DiagDirection ddir);
|
||||
static ObjectHighlight make_rail_depot(TileIndex tile, DiagDirection ddir);
|
||||
static ObjectHighlight make_rail_station(TileIndex start_tile, TileIndex end_tile, Axis axis);
|
||||
// static ObjectHighlight make_blueprint(TileIndex tile, sp<Blueprint> blueprint);
|
||||
|
||||
void Draw(const TileInfo *ti);
|
||||
void MarkDirty();
|
||||
|
||||
@@ -34,6 +34,9 @@ bool _fn_mod = false;
|
||||
bool _remove_mod = false;
|
||||
bool _estimate_mod = false;
|
||||
|
||||
bool _middle_button_down; ///< Is middle mouse button pressed?
|
||||
bool _middle_button_clicked; ///< Is middle mouse button clicked?
|
||||
|
||||
static uint32 _effective_actions = 0;
|
||||
static std::optional<std::chrono::steady_clock::time_point> _first_effective_tick = {};
|
||||
static std::queue<std::chrono::steady_clock::time_point> _last_actions;
|
||||
|
||||
@@ -259,6 +259,9 @@ void DecodeSettings(BitIStream &bs, Settings &settings) {
|
||||
uint16 _last_client_version = 1512;
|
||||
|
||||
static u8vector EncodeData() {
|
||||
// Skip if game is not initialized for some reason (i.e. -d desync)
|
||||
if (!_game) return {};
|
||||
|
||||
BitOStream bs;
|
||||
bs.Reserve(1000);
|
||||
bs.WriteBytes(SAVEGAME_DATA_FORMAT_VERSION, 2);
|
||||
|
||||
@@ -8,16 +8,28 @@
|
||||
#include "../command_type.h"
|
||||
#include "../command_func.h"
|
||||
#include "../company_func.h"
|
||||
#include "../industry_map.h"
|
||||
#include "../industry.h"
|
||||
#include "../landscape.h"
|
||||
#include "../newgrf_station.h" // StationClassID
|
||||
#include "../newgrf_house.h" // GetHouseCallback
|
||||
#include "../newgrf_cargo.h" // GetCargoTranslation
|
||||
#include "../object_type.h"
|
||||
#include "../object_map.h"
|
||||
#include "../station_base.h"
|
||||
#include "../strings_func.h" // GetString, SetDParam
|
||||
#include "../tilehighlight_type.h"
|
||||
#include "../town_map.h"
|
||||
#include "../town.h"
|
||||
#include "../viewport_func.h"
|
||||
#include "../viewport_kdtree.h"
|
||||
#include "../window_gui.h"
|
||||
#include "../zoom_type.h"
|
||||
#include "../zoom_func.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
||||
extern const Station *_viewport_highlight_station;
|
||||
extern TileHighlightData _thd;
|
||||
extern void MarkCatchmentTilesDirty();
|
||||
@@ -332,21 +344,21 @@ static void FindStationsAroundSelection(const TileArea &location)
|
||||
_station_building_status = (adjacent == nullptr ? StationBuildingStatus::NEW : StationBuildingStatus::JOIN);
|
||||
}
|
||||
|
||||
void CheckRedrawStationCoverage() {
|
||||
bool CheckRedrawStationCoverage() {
|
||||
// static bool last_ctrl_pressed = false;
|
||||
static TileArea last_location;
|
||||
static bool last_station_mode = false;
|
||||
static bool last_coverage = false;
|
||||
static bool last_fn_mod = false;
|
||||
TileArea location(TileVirtXY(_thd.pos.x, _thd.pos.y), _thd.size.x / TILE_SIZE - 1, _thd.size.y / TILE_SIZE - 1);
|
||||
bool station_mode = ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && _thd.outersize.x > 0);
|
||||
bool location_changed = (location.tile != last_location.tile || location.w != last_location.w || location.h != last_location.h);
|
||||
bool mode_changed = (last_station_mode != station_mode);
|
||||
// if (!location_changed && _ctrl_pressed == last_ctrl_pressed && !mode_changed)
|
||||
// return;
|
||||
if (!location_changed && citymania::_fn_mod == last_fn_mod && !mode_changed)
|
||||
return false;
|
||||
|
||||
// last_ctrl_pressed = _ctrl_pressed;
|
||||
// last_location = location;
|
||||
// last_station_mode = station_mode;
|
||||
last_fn_mod = citymania::_fn_mod;
|
||||
last_location = location;
|
||||
last_station_mode = station_mode;
|
||||
|
||||
if (citymania::_fn_mod) {
|
||||
Station *st = nullptr;
|
||||
@@ -363,6 +375,7 @@ void CheckRedrawStationCoverage() {
|
||||
FindStationsAroundSelection(location);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -380,4 +393,133 @@ void AbortStationPlacement() {
|
||||
}
|
||||
|
||||
|
||||
uint GetMonthlyFrom256Tick(uint amount) {
|
||||
return ((amount * DAY_TICKS * 30) >> 8);
|
||||
}
|
||||
|
||||
uint GetAverageHouseProduction(byte amount) {
|
||||
static const uint AVG[2][256] = {
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 27, 30, 33, 36, 39, 42, 45, 48, 52, 56, 60, 64, 68, 72, 76, 80, 85, 90, 95, 100, 105, 110, 115, 120, 126, 132, 138, 144, 150, 156, 162, 168, 175, 182, 189, 196, 203, 210, 217, 224, 232, 240, 248, 256, 264, 272, 280, 288, 297, 306, 315, 324, 333, 342, 351, 360, 370, 380, 390, 400, 410, 420, 430, 440, 451, 462, 473, 484, 495, 506, 517, 528, 540, 552, 564, 576, 588, 600, 612, 624, 637, 650, 663, 676, 689, 702, 715, 728, 742, 756, 770, 784, 798, 812, 826, 840, 855, 870, 885, 900, 915, 930, 945, 960, 976, 992, 1008, 1024, 1040, 1056, 1072, 1088, 1105, 1122, 1139, 1156, 1173, 1190, 1207, 1224, 1242, 1260, 1278, 1296, 1314, 1332, 1350, 1368, 1387, 1406, 1425, 1444, 1463, 1482, 1501, 1520, 1540, 1560, 1580, 1600, 1620, 1640, 1660, 1680, 1701, 1722, 1743, 1764, 1785, 1806, 1827, 1848, 1870, 1892, 1914, 1936, 1958, 1980, 2002, 2024, 2047, 2070, 2093, 2116, 2139, 2162, 2185, 2208, 2232, 2256, 2280, 2304, 2328, 2352, 2376, 2400, 2425, 2450, 2475, 2500, 2525, 2550, 2575, 2600, 2626, 2652, 2678, 2704, 2730, 2756, 2782, 2808, 2835, 2862, 2889, 2916, 2943, 2970, 2997, 3024, 3052, 3080, 3108, 3136, 3164, 3192, 3220, 3248, 3277, 3306, 3335, 3364, 3393, 3422, 3451, 3480, 3510, 3540, 3570, 3600, 3630, 3660, 3690, 3720, 3751, 3782, 3813, 3844, 3875, 3906, 3937, 3968, 4000, 4032, 4064, 4096, 4128, 4160, 4192},
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 156, 160, 165, 170, 175, 180, 185, 190, 195, 200, 205, 210, 215, 220, 225, 230, 235, 240, 246, 252, 258, 264, 270, 276, 282, 288, 294, 300, 306, 312, 318, 324, 330, 336, 343, 350, 357, 364, 371, 378, 385, 392, 399, 406, 413, 420, 427, 434, 441, 448, 456, 464, 472, 480, 488, 496, 504, 512, 520, 528, 536, 544, 552, 560, 568, 576, 585, 594, 603, 612, 621, 630, 639, 648, 657, 666, 675, 684, 693, 702, 711, 720, 730, 740, 750, 760, 770, 780, 790, 800, 810, 820, 830, 840, 850, 860, 870, 880, 891, 902, 913, 924, 935, 946, 957, 968, 979, 990, 1001, 1012, 1023, 1034, 1045, 1056, 1068, 1080, 1092, 1104, 1116, 1128, 1140, 1152, 1164, 1176, 1188, 1200, 1212, 1224, 1236, 1248, 1261, 1274, 1287, 1300, 1313, 1326, 1339, 1352, 1365, 1378, 1391, 1404, 1417, 1430, 1443, 1456, 1470, 1484, 1498, 1512, 1526, 1540, 1554, 1568, 1582, 1596, 1610, 1624, 1638, 1652, 1666, 1680, 1695, 1710, 1725, 1740, 1755, 1770, 1785, 1800, 1815, 1830, 1845, 1860, 1875, 1890, 1905, 1920, 1936, 1952, 1968, 1984, 2000, 2016, 2032, 2048, 2064, 2080, 2096, 2112, 2128, 2144, 2160}
|
||||
};
|
||||
if (amount == 0) return 0;
|
||||
switch (_settings_game.economy.town_cargogen_mode) {
|
||||
case TCGM_ORIGINAL:
|
||||
return GetMonthlyFrom256Tick(AVG[EconomyIsInRecession() ? 1 : 0][amount]);
|
||||
case TCGM_BITCOUNT: {
|
||||
uint amt = (amount + 7) / 8;
|
||||
if (EconomyIsInRecession()) amt += 2;
|
||||
else amt *= 2;
|
||||
return GetMonthlyFrom256Tick(amt * 16);
|
||||
}
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void AddProducedCargo_Town(TileIndex tile, CargoArray &produced)
|
||||
{
|
||||
if (!IsHouseCompleted(tile)) return;
|
||||
|
||||
HouseID house_id = GetHouseType(tile);
|
||||
const HouseSpec *hs = HouseSpec::Get(house_id);
|
||||
Town *t = Town::GetByTile(tile);
|
||||
|
||||
if (HasBit(hs->callback_mask, CBM_HOUSE_PRODUCE_CARGO)) {
|
||||
for (uint i = 0; i < 256; i++) {
|
||||
uint16 callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, 0, house_id, t, tile);
|
||||
|
||||
if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
|
||||
|
||||
CargoID cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
|
||||
|
||||
if (cargo == CT_INVALID) continue;
|
||||
produced[cargo] += GetMonthlyFrom256Tick((uint)GB(callback, 0, 8)) ;
|
||||
}
|
||||
} else {
|
||||
produced[CT_PASSENGERS] += GetAverageHouseProduction(hs->population);
|
||||
produced[CT_MAIL] += GetAverageHouseProduction(hs->mail_generation);
|
||||
}
|
||||
}
|
||||
|
||||
// Similar to ::GetProductionAroundTiles but counts production total
|
||||
CargoArray GetProductionAroundTiles(TileIndex tile, int w, int h, int rad)
|
||||
{
|
||||
static const uint HQ_AVG_POP[2][5] = {
|
||||
{48, 64, 84, 128, 384},
|
||||
{48, 64, 84, 128, 256},
|
||||
};
|
||||
static const uint HQ_AVG_MAIL[2][5] = {
|
||||
{36, 48, 64, 96, 264},
|
||||
{36, 48, 64, 96, 196}
|
||||
};
|
||||
|
||||
CargoArray produced;
|
||||
std::set<IndustryID> industries;
|
||||
TileArea ta = TileArea(tile, w, h).Expand(rad);
|
||||
|
||||
/* Loop over all tiles to get the produced cargo of
|
||||
* everything except industries */
|
||||
TILE_AREA_LOOP(tile, ta) {
|
||||
switch (GetTileType(tile)) {
|
||||
case MP_INDUSTRY:
|
||||
industries.insert(GetIndustryIndex(tile));
|
||||
break;
|
||||
case MP_HOUSE:
|
||||
AddProducedCargo_Town(tile, produced);
|
||||
break;
|
||||
case MP_OBJECT:
|
||||
if (IsObjectType(tile, OBJECT_HQ)) {
|
||||
produced[CT_PASSENGERS] += GetMonthlyFrom256Tick(HQ_AVG_POP[EconomyIsInRecession() ? 1 : 0][GetAnimationFrame(tile)]);
|
||||
produced[CT_MAIL] += GetMonthlyFrom256Tick(HQ_AVG_MAIL[EconomyIsInRecession() ? 1 : 0][GetAnimationFrame(tile)]);
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop over the seen industries. They produce cargo for
|
||||
* anything that is within 'rad' of any one of their tiles.
|
||||
*/
|
||||
for (IndustryID industry : industries) {
|
||||
const Industry *i = Industry::Get(industry);
|
||||
/* Skip industry with neutral station */
|
||||
if (i->neutral_station != nullptr && !_settings_game.station.serve_neutral_industries) continue;
|
||||
|
||||
for (uint j = 0; j < lengthof(i->produced_cargo); j++) {
|
||||
CargoID cargo = i->produced_cargo[j];
|
||||
if (cargo != CT_INVALID) produced[cargo] += ((uint)i->last_month_production[j]) << 8;
|
||||
}
|
||||
}
|
||||
|
||||
return produced;
|
||||
}
|
||||
|
||||
std::string GetStationCoverageProductionText(TileIndex tile, int w, int h, int rad, StationCoverageType sct) {
|
||||
auto production = GetProductionAroundTiles(tile, w, h, rad);
|
||||
|
||||
std::ostringstream s;
|
||||
char buffer[DRAW_STRING_BUFFER];
|
||||
GetString(buffer, STR_CM_STATION_BUILD_SUPPLIES, lastof(buffer));
|
||||
s << buffer;
|
||||
bool first = true;
|
||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
||||
switch (sct) {
|
||||
case SCT_PASSENGERS_ONLY: if (!IsCargoInClass(i, CC_PASSENGERS)) continue; break;
|
||||
case SCT_NON_PASSENGERS_ONLY: if (IsCargoInClass(i, CC_PASSENGERS)) continue; break;
|
||||
case SCT_ALL: break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
if (production[i] == 0) continue;
|
||||
if (!first) s << ", ";
|
||||
first = false;
|
||||
SetDParam(0, i);
|
||||
SetDParam(1, production[i] >> 8);
|
||||
// GetString(buffer, STR_CM_STATION_BUILD_SUPPLIES_CARGO, lastof(buffer));
|
||||
GetString(buffer, STR_JUST_CARGO, lastof(buffer));
|
||||
s << buffer;
|
||||
}
|
||||
return s.str();
|
||||
}
|
||||
|
||||
} // namespace citymania
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "../core/geometry_type.hpp"
|
||||
#include "../command_type.h"
|
||||
#include "../station_gui.h"
|
||||
#include "../station_type.h"
|
||||
|
||||
namespace citymania {
|
||||
@@ -28,9 +29,11 @@ void PlaceAirport(TileIndex tile);
|
||||
void SelectStationToJoin(const Station *station);
|
||||
// const Station *GetStationToJoin();
|
||||
void MarkCoverageHighlightDirty();
|
||||
void CheckRedrawStationCoverage();
|
||||
bool CheckRedrawStationCoverage();
|
||||
void AbortStationPlacement();
|
||||
|
||||
std::string GetStationCoverageProductionText(TileIndex tile, int w, int h, int rad, StationCoverageType sct);
|
||||
|
||||
} // namespace citymania
|
||||
|
||||
#endif
|
||||
|
||||
+1
-2
@@ -590,8 +590,6 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY)
|
||||
AI::BroadcastNewEvent(new ScriptEventCompanyNew(c->index), c->index);
|
||||
Game::NewEvent(new ScriptEventCompanyNew(c->index));
|
||||
|
||||
if (!is_ai) UpdateAllTownVirtCoords(); //coloured rating
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -862,6 +860,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
* all clients so everything is in sync */
|
||||
SyncCompanySettings();
|
||||
|
||||
UpdateAllTownVirtCoords(); // CityMania (for colouring towns)
|
||||
MarkWholeScreenDirty();
|
||||
}
|
||||
|
||||
|
||||
@@ -2459,4 +2459,6 @@ void IConsoleStdLibRegister()
|
||||
IConsoleCmdRegister("cmexport", citymania::ConExport);
|
||||
IConsoleCmdRegister("cmstep", citymania::ConStep, ConHookNoNetwork);
|
||||
IConsoleCmdRegister("cmtreemap", citymania::ConTreeMap, ConHookNoNetwork);
|
||||
IConsoleCmdRegister("cmresettowngrowth", citymania::ConResetTownGrowth, ConHookNoNetwork);
|
||||
IConsoleCmdRegister("cmloadcommands", citymania::ConLoadCommands, ConHookNoNetwork);
|
||||
}
|
||||
|
||||
+5
-1
@@ -105,13 +105,17 @@ enum WindowKeyCodes {
|
||||
|
||||
WKC_L_BRACE = 154, ///< { Left brace
|
||||
WKC_R_BRACE = 155, ///< } Right brace
|
||||
|
||||
|
||||
WKC_L_PAREN = 157, ///< ( Left parentheses
|
||||
WKC_R_PAREN = 158, ///< ) Right parentheses
|
||||
WKC_PLUS = 159, ///< + Plus
|
||||
WKC_EXCLAIM = 160, ///< ! Exclamation mark
|
||||
WKC_ASTERISK = 161, ///< * Asterisk
|
||||
WKC_DOLLAR = 162, ///< $ Dollar sign
|
||||
|
||||
CM_WKC_MOUSE_MIDDLE = 0x703, ///< CityMania: special code for middle mouse button
|
||||
CM_WKC_MOUSE_OTHER_START = 0x704, ///< CityMania: start of the numbered buttons (whatever number driver reports), starts as MOUSE_4 hotkey
|
||||
CM_WKC_MOUSE_OTHER_END = 0x71f, ///< CityMania: 30 buttons should be enough for any mouse, right? ;)
|
||||
};
|
||||
|
||||
/** A single sprite of a list of animated cursors */
|
||||
|
||||
@@ -95,6 +95,35 @@ static const KeycodeNames _keycode_to_name[] = {
|
||||
{"R_PAREN", WKC_R_PAREN},
|
||||
{"EXCLAIM", WKC_EXCLAIM},
|
||||
{"ASTERISK", WKC_ASTERISK},
|
||||
|
||||
{"MOUSE_MIDDLE", CM_WKC_MOUSE_MIDDLE},
|
||||
{"MOUSE_4", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 0)},
|
||||
{"MOUSE_5", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 1)},
|
||||
{"MOUSE_6", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 2)},
|
||||
{"MOUSE_7", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 3)},
|
||||
{"MOUSE_8", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 4)},
|
||||
{"MOUSE_9", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 5)},
|
||||
{"MOUSE_10", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 6)},
|
||||
{"MOUSE_11", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 7)},
|
||||
{"MOUSE_12", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 8)},
|
||||
{"MOUSE_13", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 9)},
|
||||
{"MOUSE_14", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 10)},
|
||||
{"MOUSE_15", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 11)},
|
||||
{"MOUSE_16", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 12)},
|
||||
{"MOUSE_17", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 13)},
|
||||
{"MOUSE_18", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 14)},
|
||||
{"MOUSE_19", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 15)},
|
||||
{"MOUSE_20", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 16)},
|
||||
{"MOUSE_21", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 17)},
|
||||
{"MOUSE_22", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 18)},
|
||||
{"MOUSE_23", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 19)},
|
||||
{"MOUSE_24", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 20)},
|
||||
{"MOUSE_25", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 21)},
|
||||
{"MOUSE_26", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 22)},
|
||||
{"MOUSE_27", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 23)},
|
||||
{"MOUSE_28", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 24)},
|
||||
{"MOUSE_29", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 25)},
|
||||
{"MOUSE_30", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 26)},
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -3927,6 +3927,7 @@ STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit t
|
||||
STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Reliability: {LTBLUE}{COMMA}% {BLACK}Breakdowns since last service: {LTBLUE}{COMMA}
|
||||
|
||||
STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY_LONG}
|
||||
STR_CM_VEHICLE_INFO_BUILT_VALUE_WITH_ID :{LTBLUE}{ENGINE} {BLACK}Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY_LONG}{BLACK} ID: {LTBLUE}{NUM}
|
||||
STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacity: {LTBLUE}None{STRING}
|
||||
STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO_LONG}{3:STRING}
|
||||
STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacity: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM})
|
||||
@@ -3951,7 +3952,9 @@ STR_QUERY_RENAME_AIRCRAFT_CAPTION :{WHITE}Name air
|
||||
|
||||
# Extra buttons for train details windows
|
||||
STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE :{LTBLUE}{ENGINE}{BLACK} Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY_LONG}
|
||||
STR_CM_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE_WITH_ID :{LTBLUE}{ENGINE}{BLACK} Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY_LONG}{BLACK} ID: {LTBLUE}{NUM}
|
||||
STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE :{LTBLUE}{ENGINE}{BLACK} Value: {LTBLUE}{CURRENCY_LONG}
|
||||
STR_CM_VEHICLE_DETAILS_TRAIN_WAGON_VALUE_WITH_ID :{LTBLUE}{ENGINE}{BLACK} Value: {LTBLUE}{CURRENCY_LONG}{BLACK} ID: {LTBLUE}{NUM}
|
||||
|
||||
STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT :{BLACK}Total cargo capacity of this train:
|
||||
STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT})
|
||||
@@ -5616,3 +5619,4 @@ STR_CM_CONFIG_SETTING_SHADED_TREES_SERVER : As server
|
||||
STR_CM_CONFIG_SETTING_SHOW_APM : Show APM counter: {STRING2}
|
||||
STR_CM_CONFIG_SETTING_SHOW_APM_HELPTEXT : Adds APM (actions per minute) counter to the statusbar.
|
||||
STR_CM_STATUSBAR_APM : {WHITE}APM: {NUM} AVG: {NUM}
|
||||
STR_CM_STATION_BUILD_SUPPLIES :{BLACK}Supplies: {GOLD}
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
|
||||
#include "citymania/cm_highlight.hpp"
|
||||
#include "citymania/cm_main.hpp"
|
||||
#include "citymania/cm_console_cmds.hpp"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <system_error>
|
||||
@@ -1516,6 +1517,7 @@ void GameLoop()
|
||||
* We do this here, because it means that the network is really closed */
|
||||
NetworkClientConnectGame(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port), COMPANY_SPECTATOR);
|
||||
}
|
||||
citymania::ExecuteFakeCommands(_date, _date_fract);
|
||||
/* Singleplayer */
|
||||
StateGameLoop();
|
||||
}
|
||||
|
||||
+90
-27
@@ -43,6 +43,7 @@
|
||||
#include "widgets/rail_widget.h"
|
||||
|
||||
#include "citymania/cm_hotkeys.hpp"
|
||||
#include "citymania/cm_highlight.hpp"
|
||||
#include "citymania/cm_station_gui.hpp"
|
||||
|
||||
#include "safeguards.h"
|
||||
@@ -508,30 +509,6 @@ RoadBits FindRailsToConnect(TileIndex tile) {
|
||||
return passing;
|
||||
}
|
||||
|
||||
/*
|
||||
* Selects orientation for rail object (depot)
|
||||
*/
|
||||
DiagDirection AutodetectRailObjectDirection(TileIndex tile) {
|
||||
RoadBits bits = FindRailsToConnect(tile);
|
||||
// FIXME after this point repeats road autodetection
|
||||
if (HasExactlyOneBit(bits)) return RoadBitsToDiagDir(bits);
|
||||
if (bits == ROAD_NONE) bits = ROAD_ALL;
|
||||
RoadBits frac_bits = DiagDirToRoadBits(TileFractCoordsToDiagDir());
|
||||
if (HasExactlyOneBit(frac_bits & bits)) {
|
||||
return RoadBitsToDiagDir(frac_bits & bits);
|
||||
}
|
||||
frac_bits |= MirrorRoadBits(frac_bits);
|
||||
if (HasExactlyOneBit(frac_bits & bits)) {
|
||||
return RoadBitsToDiagDir(frac_bits & bits);
|
||||
}
|
||||
for (DiagDirection ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
|
||||
if (DiagDirToRoadBits(ddir) & bits) {
|
||||
return ddir;
|
||||
}
|
||||
}
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
||||
/** Rail toolbar management class. */
|
||||
struct BuildRailToolbarWindow : Window {
|
||||
RailType railtype; ///< Rail type to build.
|
||||
@@ -719,6 +696,7 @@ struct BuildRailToolbarWindow : Window {
|
||||
|
||||
case WID_RAT_BUILD_DEPOT:
|
||||
if (HandlePlacePushButton(this, WID_RAT_BUILD_DEPOT, GetRailTypeInfo(_cur_railtype)->cursor.depot, HT_RECT | (HighLightStyle)_build_depot_direction)) {
|
||||
citymania::ResetRotateAutodetection();
|
||||
ShowBuildTrainDepotPicker(this);
|
||||
this->last_user_action = widget;
|
||||
}
|
||||
@@ -850,7 +828,8 @@ struct BuildRailToolbarWindow : Window {
|
||||
case WID_RAT_BUILD_DEPOT:
|
||||
ddir = _build_depot_direction;
|
||||
if (ddir == DIAGDIR_NW + 1) {
|
||||
ddir = AutodetectRailObjectDirection(tile);
|
||||
assert(_thd.cm.type == citymania::ObjectHighlight::Type::RAIL_DEPOT);
|
||||
ddir = _thd.cm.ddir;
|
||||
}
|
||||
DoCommandP(tile, _cur_railtype, ddir,
|
||||
CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT),
|
||||
@@ -1120,7 +1099,14 @@ static void HandleStationPlacement(TileIndex start, TileIndex end)
|
||||
ShowSelectStationIfNeeded(cmdcont, ta);
|
||||
}
|
||||
|
||||
|
||||
struct BuildRailStationWindow : public PickerWindowBase {
|
||||
/* CityMania code start */
|
||||
public:
|
||||
enum class Hotkey : int {
|
||||
ROTATE,
|
||||
};
|
||||
/* CityMania code end */
|
||||
private:
|
||||
uint line_height; ///< Height of a single line in the newstation selection matrix (#WID_BRAS_NEWST_LIST widget).
|
||||
uint coverage_height; ///< Height of the coverage texts.
|
||||
@@ -1727,6 +1713,30 @@ public:
|
||||
{
|
||||
CheckRedrawStationCoverage(this);
|
||||
}
|
||||
|
||||
/* CityMania code start */
|
||||
EventState OnHotkey(int hotkey) override
|
||||
{
|
||||
switch ((BuildRailStationWindow::Hotkey)hotkey) {
|
||||
/* Indicate to the OnClick that the action comes from a hotkey rather
|
||||
* then from a click and that the CTRL state should be ignored. */
|
||||
case BuildRailStationWindow::Hotkey::ROTATE:
|
||||
this->RaiseWidget(_railstation.orientation + WID_BRAS_PLATFORM_DIR_X);
|
||||
_railstation.orientation = OtherAxis(_railstation.orientation);
|
||||
this->LowerWidget(_railstation.orientation + WID_BRAS_PLATFORM_DIR_X);
|
||||
this->SetDirty();
|
||||
DeleteWindowById(WC_SELECT_STATION, 0);
|
||||
return ES_HANDLED;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
||||
return ES_NOT_HANDLED;
|
||||
}
|
||||
|
||||
static HotkeyList hotkeys;
|
||||
/* CityMania code end */
|
||||
};
|
||||
|
||||
Listing BuildRailStationWindow::last_sorting = { false, 0 };
|
||||
@@ -1841,12 +1851,21 @@ static const NWidgetPart _nested_station_builder_widgets[] = {
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
/* CityMania code start */
|
||||
static Hotkey build_station_hotkeys[] = {
|
||||
Hotkey(CM_WKC_MOUSE_MIDDLE, "rotate", (int)BuildRailStationWindow::Hotkey::ROTATE),
|
||||
HOTKEY_LIST_END
|
||||
};
|
||||
HotkeyList BuildRailStationWindow::hotkeys("cm_build_rail_station", build_station_hotkeys);
|
||||
/* CityMania code end */
|
||||
|
||||
/** High level window description of the station-build window (default & newGRF) */
|
||||
static WindowDesc _station_builder_desc(
|
||||
WDP_AUTO, "build_station_rail", 350, 0,
|
||||
WC_BUILD_STATION, WC_BUILD_TOOLBAR,
|
||||
WDF_CONSTRUCTION,
|
||||
_nested_station_builder_widgets, lengthof(_nested_station_builder_widgets)
|
||||
_nested_station_builder_widgets, lengthof(_nested_station_builder_widgets),
|
||||
&BuildRailStationWindow::hotkeys // CityMania addition
|
||||
);
|
||||
|
||||
/** Open station build window */
|
||||
@@ -2069,7 +2088,15 @@ static void ShowSignalBuilder(Window *parent)
|
||||
new BuildSignalWindow(&_signal_builder_desc, parent);
|
||||
}
|
||||
|
||||
|
||||
struct BuildRailDepotWindow : public PickerWindowBase {
|
||||
/* CityMania code start */
|
||||
public:
|
||||
enum class Hotkey : int {
|
||||
ROTATE,
|
||||
};
|
||||
/* CityMania code end */
|
||||
|
||||
BuildRailDepotWindow(WindowDesc *desc, Window *parent) : PickerWindowBase(desc, parent)
|
||||
{
|
||||
this->InitNested(TRANSPORT_RAIL);
|
||||
@@ -2116,8 +2143,43 @@ struct BuildRailDepotWindow : public PickerWindowBase {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* CityMania code start */
|
||||
EventState OnHotkey(int hotkey) override
|
||||
{
|
||||
switch ((BuildRailDepotWindow::Hotkey)hotkey) {
|
||||
/* Indicate to the OnClick that the action comes from a hotkey rather
|
||||
* then from a click and that the CTRL state should be ignored. */
|
||||
case BuildRailDepotWindow::Hotkey::ROTATE:
|
||||
if (_build_depot_direction < DIAGDIR_END) {
|
||||
this->RaiseWidget(_build_depot_direction + WID_BRAD_DEPOT_NE);
|
||||
_build_depot_direction = ChangeDiagDir(_build_depot_direction, DIAGDIRDIFF_90RIGHT);
|
||||
this->LowerWidget(_build_depot_direction + WID_BRAD_DEPOT_NE);
|
||||
} else {
|
||||
citymania::RotateAutodetection();
|
||||
}
|
||||
this->SetDirty();
|
||||
return ES_HANDLED;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
||||
return ES_NOT_HANDLED;
|
||||
}
|
||||
|
||||
static HotkeyList hotkeys;
|
||||
/* CityMania code end */
|
||||
};
|
||||
|
||||
/* CityMania code start */
|
||||
static Hotkey build_depot_hotkeys[] = {
|
||||
Hotkey(CM_WKC_MOUSE_MIDDLE, "rotate", (int)BuildRailDepotWindow::Hotkey::ROTATE),
|
||||
HOTKEY_LIST_END
|
||||
};
|
||||
HotkeyList BuildRailDepotWindow::hotkeys("cm_build_rail_depot", build_depot_hotkeys);
|
||||
/* CityMania code end */
|
||||
|
||||
/** Nested widget definition of the build rail depot window */
|
||||
static const NWidgetPart _nested_build_depot_widgets[] = {
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
@@ -2159,7 +2221,8 @@ static WindowDesc _build_depot_desc(
|
||||
WDP_AUTO, nullptr, 0, 0,
|
||||
WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
|
||||
WDF_CONSTRUCTION,
|
||||
_nested_build_depot_widgets, lengthof(_nested_build_depot_widgets)
|
||||
_nested_build_depot_widgets, lengthof(_nested_build_depot_widgets),
|
||||
&BuildRailDepotWindow::hotkeys // CityMania addition
|
||||
);
|
||||
|
||||
static void ShowBuildTrainDepotPicker(Window *parent)
|
||||
|
||||
+2
-1
@@ -36,7 +36,8 @@ void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y)
|
||||
SetDParam(0, v->engine_type);
|
||||
SetDParam(1, v->build_year);
|
||||
SetDParam(2, v->value);
|
||||
DrawString(left, right, y + y_offset, STR_VEHICLE_INFO_BUILT_VALUE);
|
||||
if (_settings_client.gui.newgrf_developer_tools) SetDParam(3, v->index); // CM
|
||||
DrawString(left, right, y + y_offset, _settings_client.gui.newgrf_developer_tools ? STR_CM_VEHICLE_INFO_BUILT_VALUE_WITH_ID : STR_VEHICLE_INFO_BUILT_VALUE);
|
||||
|
||||
if (v->HasArticulatedPart()) {
|
||||
CargoArray max_cargo;
|
||||
|
||||
+2
-1
@@ -66,7 +66,8 @@ void DrawShipDetails(const Vehicle *v, int left, int right, int y)
|
||||
SetDParam(0, v->engine_type);
|
||||
SetDParam(1, v->build_year);
|
||||
SetDParam(2, v->value);
|
||||
DrawString(left, right, y, STR_VEHICLE_INFO_BUILT_VALUE);
|
||||
if (_settings_client.gui.newgrf_developer_tools) SetDParam(3, v->index); // CM
|
||||
DrawString(left, right, y, _settings_client.gui.newgrf_developer_tools ? STR_CM_VEHICLE_INFO_BUILT_VALUE_WITH_ID : STR_VEHICLE_INFO_BUILT_VALUE);
|
||||
|
||||
SetDParam(0, v->cargo_type);
|
||||
SetDParam(1, v->cargo_cap);
|
||||
|
||||
+11
-1
@@ -60,6 +60,13 @@ int DrawStationCoverageAreaText(int left, int right, int top, StationCoverageTyp
|
||||
TileIndex tile = TileVirtXY(_thd.pos.x, _thd.pos.y);
|
||||
CargoTypes cargo_mask = 0;
|
||||
if (_thd.drawstyle == HT_RECT && tile < MapSize()) {
|
||||
/* CityMania code begin */
|
||||
if (supplies) {
|
||||
auto s = citymania::GetStationCoverageProductionText(tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE, rad, sct);
|
||||
return DrawStringMultiLine(left, right, top, INT32_MAX, s.c_str());
|
||||
}
|
||||
/* CityMania code end */
|
||||
|
||||
CargoArray cargoes;
|
||||
if (supplies) {
|
||||
cargoes = GetProductionAroundTiles(tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE, rad);
|
||||
@@ -146,10 +153,13 @@ static void FindStationsAroundSelection()
|
||||
*/
|
||||
void CheckRedrawStationCoverage(const Window *w)
|
||||
{
|
||||
/* CityMania code begin */
|
||||
if (_settings_client.gui.cm_use_improved_station_join) {
|
||||
citymania::CheckRedrawStationCoverage();
|
||||
if (citymania::CheckRedrawStationCoverage()) w->SetDirty();
|
||||
return;
|
||||
}
|
||||
/* CityMania code end */
|
||||
|
||||
/* Test if ctrl state changed */
|
||||
static bool _last_fn_pressed;
|
||||
if (citymania::_fn_mod != _last_fn_pressed) {
|
||||
|
||||
@@ -4143,3 +4143,7 @@ void ResetHouses()
|
||||
/* Reset any overrides that have been set. */
|
||||
_house_mngr.ResetOverride();
|
||||
}
|
||||
|
||||
namespace citymania {
|
||||
auto UpdateTownGrowthRate = &::UpdateTownGrowthRate;
|
||||
}
|
||||
|
||||
+5
-2
@@ -223,15 +223,18 @@ static void TrainDetailsCargoTab(const CargoSummaryItem *item, int left, int rig
|
||||
*/
|
||||
static void TrainDetailsInfoTab(const Vehicle *v, int left, int right, int y)
|
||||
{
|
||||
|
||||
if (RailVehInfo(v->engine_type)->railveh_type == RAILVEH_WAGON) {
|
||||
SetDParam(0, v->engine_type);
|
||||
SetDParam(1, v->value);
|
||||
DrawString(left, right, y, STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE);
|
||||
if (_settings_client.gui.newgrf_developer_tools) SetDParam(2, v->index); // CM
|
||||
DrawString(left, right, y, _settings_client.gui.newgrf_developer_tools ? STR_CM_VEHICLE_DETAILS_TRAIN_WAGON_VALUE_WITH_ID : STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE);
|
||||
} else {
|
||||
SetDParam(0, v->engine_type);
|
||||
SetDParam(1, v->build_year);
|
||||
SetDParam(2, v->value);
|
||||
DrawString(left, right, y, STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE);
|
||||
if (_settings_client.gui.newgrf_developer_tools) SetDParam(3, v->index); // CM
|
||||
DrawString(left, right, y, _settings_client.gui.newgrf_developer_tools ? STR_CM_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE_WITH_ID : STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -354,7 +354,8 @@ static void QZ_MouseMovedEvent(int x, int y)
|
||||
}
|
||||
|
||||
|
||||
static void QZ_MouseButtonEvent(int button, BOOL down)
|
||||
static void
|
||||
QZ_MouseButtonEvent(int button, BOOL down)
|
||||
{
|
||||
switch (button) {
|
||||
case 0:
|
||||
@@ -376,6 +377,18 @@ static void QZ_MouseButtonEvent(int button, BOOL down)
|
||||
}
|
||||
HandleMouseEvents();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
HandleKeypress(CM_WKC_MOUSE_MIDDLE, 0);
|
||||
break;
|
||||
|
||||
default: {
|
||||
int cm_button = CM_WKC_MOUSE_OTHER_START + button - 3;
|
||||
if (!down && cm_button >= CM_WKC_MOUSE_OTHER_START && cm_button < CM_WKC_MOUSE_OTHER_END) {
|
||||
HandleKeypress(cm_button, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,11 +498,11 @@ static bool QZ_PollEvent()
|
||||
QZ_MouseButtonEvent(1, NO);
|
||||
break;
|
||||
|
||||
#if 0
|
||||
// #if 0 CityMania uses this!
|
||||
/* This is not needed since openttd currently only use two buttons */
|
||||
case NSOtherMouseDown:
|
||||
pt = QZ_GetMouseLocation(event);
|
||||
if (!QZ_MouseIsInsideView(&pt)) {
|
||||
pt = _cocoa_subdriver->GetMouseLocation(event);
|
||||
if (!_cocoa_subdriver->MouseIsInsideView(&pt)) {
|
||||
[ NSApp sendEvent:event ];
|
||||
break;
|
||||
}
|
||||
@@ -499,8 +512,8 @@ static bool QZ_PollEvent()
|
||||
break;
|
||||
|
||||
case NSOtherMouseUp:
|
||||
pt = QZ_GetMouseLocation(event);
|
||||
if (!QZ_MouseIsInsideView(&pt)) {
|
||||
pt = _cocoa_subdriver->GetMouseLocation(event);
|
||||
if (!_cocoa_subdriver->MouseIsInsideView(&pt)) {
|
||||
[ NSApp sendEvent:event ];
|
||||
break;
|
||||
}
|
||||
@@ -508,7 +521,7 @@ static bool QZ_PollEvent()
|
||||
QZ_MouseMovedEvent((int)pt.x, (int)pt.y);
|
||||
QZ_MouseButtonEvent([ event buttonNumber ], NO);
|
||||
break;
|
||||
#endif
|
||||
// #endif
|
||||
|
||||
case NSKeyDown: {
|
||||
/* Quit, hide and minimize */
|
||||
|
||||
+12
-1
@@ -417,7 +417,7 @@ bool VideoDriver_SDL_Base::PollEvent()
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
if (_rightclick_emulate && SDL_GetModState() & KMOD_CTRL) {
|
||||
if (_rightclick_emulate && (SDL_GetModState() & KMOD_CTRL) && ev.button.button == SDL_BUTTON_LEFT) {
|
||||
ev.button.button = SDL_BUTTON_RIGHT;
|
||||
}
|
||||
|
||||
@@ -437,6 +437,17 @@ bool VideoDriver_SDL_Base::PollEvent()
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
if (ev.button.button == SDL_BUTTON_MIDDLE) {
|
||||
HandleKeypress(CM_WKC_MOUSE_MIDDLE, 0);
|
||||
break;
|
||||
} else if (ev.button.button > SDL_BUTTON_RIGHT) {
|
||||
int button = CM_WKC_MOUSE_OTHER_START + ev.button.button - 4;
|
||||
if (button >= CM_WKC_MOUSE_OTHER_START && button < CM_WKC_MOUSE_OTHER_END) {
|
||||
HandleKeypress(button, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (_rightclick_emulate) {
|
||||
_right_button_down = false;
|
||||
_left_button_down = false;
|
||||
|
||||
+13
-2
@@ -24,7 +24,7 @@
|
||||
#include "sdl_v.h"
|
||||
#include <SDL.h>
|
||||
|
||||
#include "../../citymania/cm_hotkeys.hpp"
|
||||
#include "../citymania/cm_hotkeys.hpp"
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
@@ -500,7 +500,7 @@ bool VideoDriver_SDL::PollEvent()
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
if (_rightclick_emulate && SDL_GetModState() & KMOD_CTRL) {
|
||||
if (_rightclick_emulate && (SDL_GetModState() & KMOD_CTRL) && ev.button.button == SDL_BUTTON_LEFT) {
|
||||
ev.button.button = SDL_BUTTON_RIGHT;
|
||||
}
|
||||
|
||||
@@ -523,6 +523,17 @@ bool VideoDriver_SDL::PollEvent()
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
if (ev.button.button == SDL_BUTTON_MIDDLE) {
|
||||
HandleKeypress(CM_WKC_MOUSE_MIDDLE, 0);
|
||||
break;
|
||||
} else if (ev.button.button > SDL_BUTTON_WHEELDOWN) {
|
||||
int button = CM_WKC_MOUSE_OTHER_START + ev.button.button - 4;
|
||||
if (button >= CM_WKC_MOUSE_OTHER_START && button < CM_WKC_MOUSE_OTHER_END) {
|
||||
HandleKeypress(button, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (_rightclick_emulate) {
|
||||
_right_button_down = false;
|
||||
_left_button_down = false;
|
||||
|
||||
@@ -453,6 +453,22 @@ LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
HandleMouseEvents();
|
||||
return 0;
|
||||
|
||||
/* CityMania code start */
|
||||
case WM_MBUTTONUP:
|
||||
ReleaseCapture();
|
||||
HandleKeypress(CM_WKC_MOUSE_MIDDLE, 0);
|
||||
return 0;
|
||||
|
||||
case WM_XBUTTONUP: {
|
||||
ReleaseCapture();
|
||||
int button = CM_WKC_MOUSE_OTHER_START + GET_XBUTTON_WPARAM(wParam) - 1;
|
||||
if (button >= CM_WKC_MOUSE_OTHER_START && button < CM_WKC_MOUSE_OTHER_END) {
|
||||
HandleKeypress(button, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* CityMania code end */
|
||||
|
||||
case WM_MOUSELEAVE:
|
||||
UndrawMouseCursor();
|
||||
_cursor.in_window = false;
|
||||
|
||||
@@ -2983,6 +2983,7 @@ static void MouseLoop(MouseClick click, int mousewheel)
|
||||
case MC_HOVER:
|
||||
DispatchHoverEvent(w, x - w->left, y - w->top);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user