Fix new station joining
This commit is contained in:
153
gen_commands.py
153
gen_commands.py
@@ -1,3 +1,4 @@
|
||||
import glob
|
||||
import re
|
||||
from pathlib import Path
|
||||
from pprint import pprint
|
||||
@@ -5,6 +6,8 @@ from pprint import pprint
|
||||
RX_COMMAND = re.compile(r'(?P<returns>CommandCost|std::tuple<CommandCost, [^>]*>) (?P<name>Cmd\w*)\((?P<args>[^)]*)\);')
|
||||
RX_DEF_TRAIT = re.compile(r'DEF_CMD_TRAIT\((?P<constant>\w+),\s+(?P<function>\w+),\s+[^,]*,\s+(?P<category>\w+)\)')
|
||||
RX_ARG = re.compile(r'(?P<type>(:?const |)[\w:]* &?)(?P<name>\w*)')
|
||||
RX_CALLBACK = re.compile(r'void\s+(?P<name>Cc\w+)\(Commands')
|
||||
RX_CALLBACK_REF = re.compile(r'CommandCallback\s+(?P<name>Cc\w+);')
|
||||
RX_CAMEL_TO_SNAKE = re.compile(r'(?<!^)(?=[A-Z])')
|
||||
|
||||
FILES = [
|
||||
@@ -24,12 +27,23 @@ OUTPUT = BASE_DIR / 'src/citymania/generated/cm_gen_commands'
|
||||
|
||||
def parse_commands():
|
||||
res = []
|
||||
for f in FILES:
|
||||
data = open(BASE_DIR / f).read()
|
||||
includes = []
|
||||
callbacks = []
|
||||
for f in glob.glob(str(BASE_DIR / 'src' / '*_cmd.h')):
|
||||
includes.append(Path(f).name)
|
||||
data = open(f).read()
|
||||
traits = {}
|
||||
for constant, name, category in RX_DEF_TRAIT.findall(data):
|
||||
traits[name] = constant
|
||||
traits[name] = constant, category
|
||||
callbacks.extend(RX_CALLBACK.findall(data))
|
||||
callbacks.extend(RX_CALLBACK_REF.findall(data))
|
||||
for returns, name, args_str in RX_COMMAND.findall(data):
|
||||
trait = traits.get(name)
|
||||
if not trait:
|
||||
print(f'Not a command: {name}')
|
||||
continue
|
||||
print(f, name, end=' ', flush=True)
|
||||
constant, category = trait
|
||||
if returns.startswith('std::tuple'):
|
||||
ret_type = returns[24: -1]
|
||||
else:
|
||||
@@ -39,25 +53,80 @@ def parse_commands():
|
||||
first_tile_arg = (args[0][0].strip() == 'TileIndex')
|
||||
if first_tile_arg:
|
||||
args = args[1:]
|
||||
print(name, traits[name], args)
|
||||
print(constant, category, args)
|
||||
res.append({
|
||||
'name': name[3:],
|
||||
'constant': traits[name],
|
||||
'constant': constant,
|
||||
'category': category,
|
||||
'args': args,
|
||||
'first_tile_arg': first_tile_arg,
|
||||
'returns': ret_type,
|
||||
})
|
||||
return res
|
||||
return res, includes, callbacks
|
||||
|
||||
CPP_TEMPLATES = '''\
|
||||
inline constexpr size_t _callback_tuple_size = std::tuple_size_v<decltype(_callback_tuple)>;
|
||||
|
||||
#ifdef SILENCE_GCC_FUNCTION_POINTER_CAST
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
#endif
|
||||
|
||||
template <size_t... i>
|
||||
inline auto MakeCallbackTable(std::index_sequence<i...>) noexcept {
|
||||
return std::array<CommandCallback *, sizeof...(i)>{{ reinterpret_cast<CommandCallback *>(reinterpret_cast<void(*)()>(std::get<i>(_callback_tuple)))... }}; // MingW64 fails linking when casting a pointer to its own type. To work around, cast it to some other type first.
|
||||
}
|
||||
/** Type-erased table of callbacks. */
|
||||
static auto _callback_table = MakeCallbackTable(std::make_index_sequence<_callback_tuple_size>{});\n
|
||||
template <typename T> struct CallbackArgsHelper;
|
||||
template <typename... Targs>
|
||||
struct CallbackArgsHelper<void(*const)(Commands, const CommandCost &, Targs...)> {
|
||||
using Args = std::tuple<std::decay_t<Targs>...>;
|
||||
};
|
||||
#ifdef SILENCE_GCC_FUNCTION_POINTER_CAST
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
static size_t FindCallbackIndex(CommandCallback *callback) {
|
||||
if (auto it = std::find(std::cbegin(_callback_table), std::cend(_callback_table), callback); it != std::cend(_callback_table)) {
|
||||
return static_cast<size_t>(std::distance(std::cbegin(_callback_table), it));
|
||||
}
|
||||
return std::numeric_limits<size_t>::max();
|
||||
}
|
||||
|
||||
template <Commands Tcmd, size_t Tcb, typename... Targs>
|
||||
bool _DoPost(StringID err_msg, TileIndex tile, Targs... args) {
|
||||
return ::Command<Tcmd>::Post(err_msg, std::get<Tcb>(_callback_tuple), tile, std::forward<Targs>(args)...);
|
||||
}
|
||||
template <Commands Tcmd, size_t Tcb, typename... Targs>
|
||||
constexpr auto MakeCallback() noexcept {
|
||||
/* Check if the callback matches with the command arguments. If not, don''t generate an Unpack proc. */
|
||||
using Tcallback = std::tuple_element_t<Tcb, decltype(_callback_tuple)>;
|
||||
if constexpr (std::is_same_v<Tcallback, CommandCallback * const> ||
|
||||
std::is_same_v<Tcallback, CommandCallbackData * const> ||
|
||||
std::is_same_v<typename CommandTraits<Tcmd>::CbArgs, typename CallbackArgsHelper<Tcallback>::Args> ||
|
||||
(!std::is_void_v<typename CommandTraits<Tcmd>::RetTypes> && std::is_same_v<typename CallbackArgsHelper<typename CommandTraits<Tcmd>::RetCallbackProc const>::Args, typename CallbackArgsHelper<Tcallback>::Args>)) {
|
||||
return &_DoPost<Tcmd, Tcb, Targs...>;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
'''
|
||||
|
||||
def run():
|
||||
commands = parse_commands()
|
||||
commands, includes, callbacks = parse_commands()
|
||||
with open(OUTPUT.with_suffix('.hpp'), 'w') as f:
|
||||
f.write(
|
||||
'// This file is generated by gen_commands.py, do not edit\n\n'
|
||||
'#ifndef CM_GEN_COMMANDS_HPP\n'
|
||||
'#define CM_GEN_COMMANDS_HPP\n'
|
||||
'#include "../cm_command_type.hpp"\n'
|
||||
)
|
||||
for i in includes:
|
||||
f.write(f'#include "../../{i}"\n')
|
||||
f.write('\n')
|
||||
f.write(
|
||||
'namespace citymania {\n'
|
||||
'namespace cmd {\n\n'
|
||||
)
|
||||
@@ -71,21 +140,26 @@ def run():
|
||||
)
|
||||
for at, an in cmd['args']:
|
||||
f.write(f' {at}{an};\n')
|
||||
f.write(
|
||||
f'\n'
|
||||
f' {name}({args_list})\n'
|
||||
f' :{args_init} {{}}\n'
|
||||
)
|
||||
if cmd.get('first_tile_arg'):
|
||||
f.write(f'\n')
|
||||
if args_init:
|
||||
f.write(
|
||||
f' {name}(TileIndex tile, {args_list})\n'
|
||||
f' :Command{{tile}}, {args_init} {{}}\n'
|
||||
f' {name}({args_list})\n'
|
||||
f' :{args_init} {{}}\n'
|
||||
)
|
||||
else:
|
||||
f.write(f' {name}({args_list}) {{}}\n')
|
||||
|
||||
if cmd.get('first_tile_arg'):
|
||||
separator = ', ' if args_list else ''
|
||||
f.write(
|
||||
f' {name}(TileIndex tile{separator}{args_list})\n'
|
||||
f' :Command{{tile}}{separator}{args_init} {{}}\n'
|
||||
)
|
||||
f.write(
|
||||
f' ~{name}() override {{}}\n'
|
||||
f'\n'
|
||||
f' bool DoPost() override;\n'
|
||||
f' bool DoTest() override;\n'
|
||||
f' bool do_post(CommandCallback * callback) override;\n'
|
||||
f' bool do_test() override;\n'
|
||||
f'}};\n\n'
|
||||
)
|
||||
f.write(
|
||||
@@ -106,24 +180,51 @@ def run():
|
||||
'namespace citymania {\n'
|
||||
'namespace cmd {\n\n'
|
||||
)
|
||||
f.write(
|
||||
'/*\n'
|
||||
' * The code is mostly copied from network_command.cpp\n'
|
||||
' * but the table is not the same.\n'
|
||||
' */\n'
|
||||
'static constexpr auto _callback_tuple = std::make_tuple(\n'
|
||||
' (CommandCallback *)nullptr, // Make sure this is actually a pointer-to-function.\n'
|
||||
)
|
||||
for i, cb in enumerate(callbacks):
|
||||
comma = ',' if i != len(callbacks) - 1 else ''
|
||||
f.write(f' &{cb}{comma}\n')
|
||||
f.write(');\n\n')
|
||||
f.write(CPP_TEMPLATES)
|
||||
|
||||
for cmd in commands:
|
||||
name = cmd['name']
|
||||
constant = cmd['constant']
|
||||
# constant = 'CMD_' + RX_CAMEL_TO_SNAKE.sub('_', name).upper()
|
||||
args_list = ', '.join(f'this->{an}' for _, an in cmd['args'])
|
||||
this_args_list = ', '.join(f'this->{an}' for _, an in cmd['args'])
|
||||
args_list = ', '.join(f'{an}' for _, an in cmd['args'])
|
||||
args_type_list = ', '.join(f'{at}' for at, an in cmd['args'])
|
||||
test_args_list = args_list
|
||||
if cmd.get('first_tile_arg'):
|
||||
test_args_list = f'this->tile, ' + args_list
|
||||
if args_list:
|
||||
test_args_list = f'this->tile, ' + args_list
|
||||
else:
|
||||
test_args_list = f'this->tile'
|
||||
|
||||
cost_getter = '' if cmd['returns'] is None else 'std::get<0>'
|
||||
|
||||
sep_args_list = sep_args_type_list = sep_this_args_list = ''
|
||||
if args_list:
|
||||
sep_args_list = ', ' + args_list
|
||||
sep_args_type_list = ', ' + args_type_list
|
||||
sep_this_args_list = ', ' + this_args_list
|
||||
f.write(
|
||||
f'bool {name}::DoPost() {{\n'
|
||||
f' return ::Command<{constant}>::Post(this->error, this->tile, {args_list});\n'
|
||||
f''
|
||||
'template <typename T, T... i, size_t... j>\n'
|
||||
f'inline constexpr auto MakeDispatchTable{name}(std::index_sequence<i...>) noexcept\n'
|
||||
'{\n'
|
||||
f' return std::array<bool (*)(StringID err_msg, TileIndex tile{sep_args_type_list}), sizeof...(i)>{{MakeCallback<{constant}, i{sep_args_type_list}>()... }};\n'
|
||||
'}\n'
|
||||
)
|
||||
f.write(
|
||||
f'bool {name}::DoTest() {{\n'
|
||||
f'static constexpr auto _{name}_dispatch = MakeDispatchTable{name}(std::make_index_sequence<_callback_tuple_size>{{}});\n'
|
||||
f'bool {name}::do_post(CommandCallback *callback) {{\n'
|
||||
f' return _{name}_dispatch[FindCallbackIndex(callback)](this->error, this->tile{sep_this_args_list});\n'
|
||||
'}\n'
|
||||
f'bool {name}::do_test() {{\n'
|
||||
f' return {cost_getter}(::Command<{constant}>::Do(DC_NONE, {test_args_list})).Succeeded();\n'
|
||||
'}\n'
|
||||
)
|
||||
|
||||
@@ -7,6 +7,8 @@ gen = grf.NewGRF(
|
||||
grfid=b'CMAL',
|
||||
name='CityMania Alpine Landscape',
|
||||
description='Modified OpenGFX sprites for alpine climate.',
|
||||
version=2,
|
||||
min_compatible_version=0,
|
||||
)
|
||||
|
||||
|
||||
@@ -352,8 +354,9 @@ for i in range(81):
|
||||
gen.add(layout := grf.AdvancedSpriteLayout(
|
||||
feature=grf.OBJECT,
|
||||
ground={
|
||||
'sprite': grf.SpriteRef(4550, is_global=True),
|
||||
'sprite': grf.SpriteRef(0, is_global=True),
|
||||
'flags': 2,
|
||||
'add': grf.Temp(1),
|
||||
},
|
||||
buildings=[{
|
||||
'sprite': grf.SpriteRef(i, is_global=False),
|
||||
@@ -363,7 +366,6 @@ for i in range(81):
|
||||
))
|
||||
|
||||
gen.add(layout_switch := grf.Switch(
|
||||
feature=grf.OBJECT,
|
||||
ranges={0: layout},
|
||||
default=layout,
|
||||
code=f'''
|
||||
|
||||
@@ -3,6 +3,7 @@ import numpy as np
|
||||
|
||||
import math
|
||||
import os
|
||||
import random
|
||||
import spectra
|
||||
|
||||
import grf
|
||||
@@ -305,6 +306,10 @@ for i in range (81):
|
||||
# if not inp:
|
||||
|
||||
# continue
|
||||
for ii in inp:
|
||||
for oo in outp:
|
||||
xy = ((edges[ii][0] + xx, edges[ii][1] + yy), (edges[oo][0] + xx, edges[oo][1] + yy))
|
||||
draw_bezier(imd2, 0x38, 5, xy[0], center, xy[1])
|
||||
for ii in inp:
|
||||
for oo in outp:
|
||||
xy = ((edges[ii][0] + xx, edges[ii][1] + yy), (edges[oo][0] + xx, edges[oo][1] + yy))
|
||||
@@ -340,4 +345,14 @@ for i in range (81):
|
||||
# dout[oy + y + 64 * i, ox + x] = find_best_color(c)
|
||||
# im2 = Image.fromarray(dout)
|
||||
# im2.putpalette(im.getpalette())
|
||||
#
|
||||
px = im2.load()
|
||||
for y in range(im2.height):
|
||||
for x in range(im2.width):
|
||||
if px[x, y] == 0xF5:
|
||||
px[x, y] = random.randint(0xF5, 0xF9)
|
||||
elif px[x, y] == 0x42:
|
||||
px[x, y] = random.randint(0x10, 0x14)
|
||||
elif px[x, y] == 0x38:
|
||||
px[x, y] = random.randint(0x19, 0x1e)
|
||||
im2.save(os.path.join(DEST_DIR, "rivers.png"))
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 515 KiB |
@@ -215,14 +215,14 @@ std::multimap<TileIndex, ObjectTileHighlight> Blueprint::GetTiles(TileIndex tile
|
||||
std::set<StationID> can_build_station_sign;
|
||||
for (auto &item: this->items) {
|
||||
if (item.type != Item::Type::RAIL_STATION) continue;
|
||||
if (GetBlueprintCommand(tile, item)->Test())
|
||||
if (GetBlueprintCommand(tile, item)->test())
|
||||
can_build_station_sign.insert(item.u.rail.station.id);
|
||||
}
|
||||
|
||||
for (auto &o: this->items) {
|
||||
auto otile = AddTileIndexDiffCWrap(tile, o.tdiff);
|
||||
auto palette = CM_PALETTE_TINT_WHITE;
|
||||
if (o.type != Item::Type::RAIL_SIGNAL && !GetBlueprintCommand(tile, o)->Test())
|
||||
if (o.type != Item::Type::RAIL_SIGNAL && !GetBlueprintCommand(tile, o)->test())
|
||||
palette = CM_PALETTE_TINT_RED_DEEP;
|
||||
|
||||
switch(o.type) {
|
||||
@@ -600,7 +600,7 @@ void BuildBlueprint(sp<Blueprint> &blueprint, TileIndex start) {
|
||||
case Blueprint::Item::Type::RAIL_TUNNEL:
|
||||
case Blueprint::Item::Type::RAIL_BRIDGE: {
|
||||
auto cc = GetBlueprintCommand(start, item);
|
||||
cc->Post();
|
||||
cc->post();
|
||||
if (item.type == Blueprint::Item::Type::RAIL_TRACK) last_rail = std::move(cc);
|
||||
break;
|
||||
}
|
||||
@@ -634,7 +634,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);
|
||||
cc->Post();
|
||||
cc->post();
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -3,13 +3,21 @@
|
||||
|
||||
#include "../bridge.h"
|
||||
#include "../command_func.h"
|
||||
#include "../depot_type.h"
|
||||
#include "../goal_type.h"
|
||||
#include "../group_cmd.h"
|
||||
#include "../engine_type.h"
|
||||
#include "../livery.h"
|
||||
#include "../misc_cmd.h"
|
||||
#include "../news_type.h"
|
||||
#include "../object_type.h"
|
||||
#include "../order_type.h"
|
||||
#include "../road_type.h"
|
||||
#include "../road_type.h"
|
||||
#include "../station_type.h"
|
||||
#include "../story_type.h"
|
||||
#include "../track_type.h"
|
||||
#include "../vehiclelist.h"
|
||||
|
||||
enum StationClassID : byte;
|
||||
|
||||
@@ -19,50 +27,56 @@ class Command {
|
||||
public:
|
||||
TileIndex tile = 0;
|
||||
bool automatic = false;
|
||||
CompanyID as_company = INVALID_COMPANY;
|
||||
CompanyID company = INVALID_COMPANY;
|
||||
StringID error = (StringID)0;
|
||||
|
||||
Command() {}
|
||||
Command(TileIndex tile) :tile{tile} {}
|
||||
virtual ~Command() {}
|
||||
virtual bool DoPost()=0;
|
||||
virtual bool DoTest()=0;
|
||||
|
||||
bool Post() {
|
||||
virtual bool do_post(CommandCallback *callback)=0;
|
||||
virtual bool do_test()=0;
|
||||
|
||||
template <typename Tcallback>
|
||||
bool post(Tcallback callback) {
|
||||
CompanyID old = _current_company;
|
||||
if (this->as_company != INVALID_COMPANY)
|
||||
_current_company = as_company;
|
||||
bool res = this->DoPost();
|
||||
if (this->company != INVALID_COMPANY)
|
||||
_current_company = company;
|
||||
bool res = this->do_post(reinterpret_cast<CommandCallback *>(reinterpret_cast<void(*)()>(callback)));
|
||||
_current_company = old;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool Test() {
|
||||
bool post() {
|
||||
return this->post<CommandCallback *>(nullptr);
|
||||
}
|
||||
|
||||
bool test() {
|
||||
CompanyID old = _current_company;
|
||||
if (this->as_company != INVALID_COMPANY)
|
||||
_current_company = as_company;
|
||||
bool res = this->DoTest();
|
||||
if (this->company != INVALID_COMPANY)
|
||||
_current_company = company;
|
||||
bool res = this->do_test();
|
||||
_current_company = old;
|
||||
return res;
|
||||
}
|
||||
|
||||
Command &WithTile(TileIndex tile) {
|
||||
Command &with_tile(TileIndex tile) {
|
||||
this->tile = tile;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Command &WithError(StringID error) {
|
||||
Command &with_error(StringID error) {
|
||||
this->error = error;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Command &SetAuto() {
|
||||
Command &set_auto() {
|
||||
this->automatic = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Command &AsCompany(CompanyID company) {
|
||||
this->as_company = company;
|
||||
Command &as_company(CompanyID company) {
|
||||
this->company = company;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -55,7 +55,7 @@ bool ConStep(byte argc, char *argv[]) {
|
||||
auto n = (argc > 1 ? atoi(argv[1]) : 1);
|
||||
|
||||
// FIXME (n << 1)
|
||||
cmd::Pause(PM_PAUSED_NORMAL, 0).Post();
|
||||
cmd::Pause(PM_PAUSED_NORMAL, 0).post();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -329,7 +329,7 @@ void ObjectHighlight::UpdateTiles() {
|
||||
this->tile,
|
||||
_cur_railtype,
|
||||
dir
|
||||
).Test() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP);
|
||||
).test() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP);
|
||||
|
||||
this->tiles.insert(std::make_pair(this->tile, ObjectTileHighlight::make_rail_depot(palette, dir)));
|
||||
auto tile = this->tile + TileOffsByDiagDir(dir);
|
||||
@@ -356,7 +356,7 @@ void ObjectHighlight::UpdateTiles() {
|
||||
_railstation.station_type,
|
||||
NEW_STATION,
|
||||
true
|
||||
).Test() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP);
|
||||
).test() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP);
|
||||
|
||||
auto layout_ptr = AllocaM(byte, (int)numtracks * plat_len);
|
||||
GetStationLayout(layout_ptr, numtracks, plat_len, nullptr); // TODO statspec
|
||||
@@ -388,7 +388,7 @@ void ObjectHighlight::UpdateTiles() {
|
||||
this->roadtype,
|
||||
NEW_STATION,
|
||||
true
|
||||
).Test() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP);
|
||||
).test() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP);
|
||||
for (TileIndex tile : ta) {
|
||||
this->AddTile(tile, ObjectTileHighlight::make_road_stop(palette, this->roadtype, this->ddir, this->is_truck));
|
||||
}
|
||||
@@ -400,7 +400,7 @@ void ObjectHighlight::UpdateTiles() {
|
||||
this->tile,
|
||||
this->roadtype,
|
||||
this->ddir
|
||||
).Test() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP);
|
||||
).test() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP);
|
||||
this->AddTile(this->tile, ObjectTileHighlight::make_road_depot(palette, this->roadtype, this->ddir));
|
||||
break;
|
||||
}
|
||||
@@ -412,7 +412,7 @@ void ObjectHighlight::UpdateTiles() {
|
||||
this->airport_layout,
|
||||
NEW_STATION,
|
||||
true
|
||||
).Test() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP);
|
||||
).test() ? CM_PALETTE_TINT_WHITE : CM_PALETTE_TINT_RED_DEEP);
|
||||
|
||||
const AirportSpec *as = AirportSpec::Get(this->airport_type);
|
||||
if (!as->IsAvailable() || this->airport_layout >= as->num_table) break;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "cm_station_gui.hpp"
|
||||
|
||||
#include "cm_hotkeys.hpp"
|
||||
#include "cm_commands.hpp"
|
||||
|
||||
#include "../core/math_func.hpp"
|
||||
#include "../command_type.h"
|
||||
@@ -189,7 +190,6 @@ const Station *CheckClickOnDeadStationSign() {
|
||||
}
|
||||
|
||||
bool CheckStationJoin(TileIndex start_tile, TileIndex end_tile) {
|
||||
// if (_ctrl_pressed && start_tile == end_tile) {
|
||||
if (citymania::_fn_mod) {
|
||||
if (IsTileType (start_tile, MP_STATION)) {
|
||||
citymania::SelectStationToJoin(Station::GetByTile(start_tile));
|
||||
@@ -204,18 +204,19 @@ bool CheckStationJoin(TileIndex start_tile, TileIndex end_tile) {
|
||||
return false;
|
||||
}
|
||||
|
||||
using JoinAndBuildCmdProc = std::function<bool(bool test, StationID to_join, bool adjacent)>;
|
||||
// using JoinAndBuildCmdProc = std::function<bool(bool test, StationID to_join, bool adjacent)>;
|
||||
|
||||
void JoinAndBuild(JoinAndBuildCmdProc proc) {
|
||||
template <typename Tcommand, typename Tcallback>
|
||||
void JoinAndBuild(Tcommand command, Tcallback *callback) {
|
||||
auto join_to = _highlight_station_to_join;
|
||||
bool adjacent = (citymania::_fn_mod || join_to);
|
||||
StationID to_join = INVALID_STATION;
|
||||
command.adjacent = (citymania::_fn_mod || join_to);
|
||||
command.station_to_join = INVALID_STATION;
|
||||
|
||||
if (citymania::_fn_mod) to_join = NEW_STATION;
|
||||
else if (join_to) to_join = join_to->index;
|
||||
if (citymania::_fn_mod) command.station_to_join = NEW_STATION;
|
||||
else if (join_to) command.station_to_join = join_to->index;
|
||||
|
||||
//FIXME _last_station_bulid_cmd = cmdcont;
|
||||
proc(false, to_join, adjacent);
|
||||
command.post(callback);
|
||||
}
|
||||
|
||||
static DiagDirection TileFractCoordsToDiagDir(Point pt) {
|
||||
@@ -341,24 +342,30 @@ DiagDirection AutodetectDriveThroughRoadStopDirection(TileArea area, Point pt, R
|
||||
return DiagDirToAxis(AutodetectRoadObjectDirection(area.tile, pt, roadtype)) == AXIS_X ? STATIONDIR_X : STATIONDIR_Y;
|
||||
}
|
||||
|
||||
void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, uint32 cmd) {
|
||||
void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, RoadStopType stop_type, bool adjacent, RoadType rt, StringID err_msg) {
|
||||
assert(_thd.cm.type == citymania::ObjectHighlight::Type::ROAD_STOP);
|
||||
uint8 ddir = _thd.cm.ddir;
|
||||
DiagDirection ddir = _thd.cm.ddir;
|
||||
|
||||
SB(p2, 16, 16, INVALID_STATION); // no station to join
|
||||
TileArea ta(start_tile, end_tile);
|
||||
|
||||
if (CheckStationJoin(start_tile, end_tile)) return;
|
||||
|
||||
if (ddir >= DIAGDIR_END) { // drive-through stops
|
||||
SetBit(p2, 1);
|
||||
ddir -= DIAGDIR_END;
|
||||
}
|
||||
p2 |= ddir << 3; // Set the DiagDirecion into p2 bits 3 and 4.
|
||||
bool drive_through = (ddir >= DIAGDIR_END);
|
||||
if (drive_through) ddir = static_cast<DiagDirection>(ddir - DIAGDIR_END); // Adjust picker result to actual direction.
|
||||
|
||||
// FIXME
|
||||
// CommandContainer cmdcont = { ta.tile, (uint32)(ta.w | ta.h << 8), p2, cmd, CcRoadStop, "" };
|
||||
// JoinAndBuild(cmdcont);
|
||||
auto c = cmd::BuildRoadStop(
|
||||
ta.tile,
|
||||
ta.w,
|
||||
ta.h,
|
||||
stop_type,
|
||||
drive_through,
|
||||
static_cast<DiagDirection>(ddir),
|
||||
rt,
|
||||
INVALID_STATION,
|
||||
adjacent
|
||||
);
|
||||
c.with_error(err_msg);
|
||||
JoinAndBuild(c, CcRoadStop);
|
||||
}
|
||||
|
||||
void HandleStationPlacement(TileIndex start, TileIndex end)
|
||||
@@ -371,47 +378,51 @@ void HandleStationPlacement(TileIndex start, TileIndex end)
|
||||
|
||||
if (_railstation.orientation == AXIS_X) Swap(numtracks, platlength);
|
||||
|
||||
uint32 p1 = _cur_railtype | _railstation.orientation << 6 | numtracks << 8 | platlength << 16 | (citymania::_fn_mod ? 1 << 24 : 0);
|
||||
uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16;
|
||||
|
||||
// FIXME
|
||||
// CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" };
|
||||
// JoinAndBuild(cmdcont);
|
||||
auto c = cmd::BuildRailStation(
|
||||
ta.tile,
|
||||
_cur_railtype,
|
||||
_railstation.orientation,
|
||||
numtracks,
|
||||
platlength,
|
||||
_railstation.station_class,
|
||||
_railstation.station_type,
|
||||
INVALID_STATION,
|
||||
false
|
||||
);
|
||||
c.with_error(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION);
|
||||
JoinAndBuild(c, CcStation);
|
||||
}
|
||||
|
||||
void PlaceRail_Station(TileIndex tile) {
|
||||
if (CheckStationJoin(tile, tile)) return;
|
||||
|
||||
uint32 p1 = _cur_railtype | _railstation.orientation << 6 | _settings_client.gui.station_numtracks << 8 | _settings_client.gui.station_platlength << 16 | (citymania::_fn_mod ? 1 << 24 : 0);
|
||||
uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16;
|
||||
|
||||
int w = _settings_client.gui.station_numtracks;
|
||||
int h = _settings_client.gui.station_platlength;
|
||||
if (!_railstation.orientation) Swap(w, h);
|
||||
|
||||
// FIXME
|
||||
// CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" };
|
||||
// JoinAndBuild(cmdcont);
|
||||
auto c = cmd::BuildRailStation(
|
||||
tile,
|
||||
_cur_railtype,
|
||||
_railstation.orientation,
|
||||
_settings_client.gui.station_numtracks,
|
||||
_settings_client.gui.station_platlength,
|
||||
_railstation.station_class,
|
||||
_railstation.station_type,
|
||||
INVALID_STATION,
|
||||
false
|
||||
);
|
||||
c.with_error(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION);
|
||||
JoinAndBuild(c, CcStation);
|
||||
}
|
||||
|
||||
void PlaceDock(TileIndex tile) {
|
||||
if (CheckStationJoin(tile, tile)) return;
|
||||
void PlaceDock(TileIndex tile, TileIndex tile_to) {
|
||||
if (CheckStationJoin(tile, tile_to)) return;
|
||||
|
||||
uint32 p2 = (uint32)INVALID_STATION << 16; // no station to join
|
||||
|
||||
/* tile is always the land tile, so need to evaluate _thd.pos */
|
||||
// CommandContainer cmdcont = { tile, citymania::_fn_mod, p2, CMD_BUILD_DOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_DOCK_HERE), CcBuildDocks, "" };
|
||||
|
||||
/* Determine the watery part of the dock. */
|
||||
// DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile));
|
||||
// TileIndex tile_to = (dir != INVALID_DIAGDIR ? TileAddByDiagDir(tile, ReverseDiagDir(dir)) : tile);
|
||||
|
||||
// FIXME
|
||||
// JoinAndBuild(cmdcont);
|
||||
auto c = cmd::BuildDock(
|
||||
tile,
|
||||
INVALID_STATION,
|
||||
false
|
||||
);
|
||||
c.with_error(STR_ERROR_CAN_T_BUILD_DOCK_HERE);
|
||||
JoinAndBuild(c, CcBuildDocks);
|
||||
}
|
||||
|
||||
void PlaceAirport(TileIndex tile) {
|
||||
// FIXME
|
||||
if (CheckStationJoin(tile, tile)) return;
|
||||
|
||||
if (_selected_airport_index == -1) return;
|
||||
@@ -419,15 +430,15 @@ void PlaceAirport(TileIndex tile) {
|
||||
byte airport_type = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->GetIndex();
|
||||
byte layout = _selected_airport_layout;
|
||||
|
||||
auto proc = [=](bool test, StationID to_join, bool adjacent) -> bool {
|
||||
if (test) {
|
||||
return Command<CMD_BUILD_AIRPORT>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_AIRPORT>()), tile, airport_type, layout, INVALID_STATION, adjacent).Succeeded();
|
||||
} else {
|
||||
return Command<CMD_BUILD_AIRPORT>::Post(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE, CcBuildAirport, tile, airport_type, layout, to_join, adjacent);
|
||||
}
|
||||
};
|
||||
|
||||
// FIXME JoinAndBuild(cmdcont);
|
||||
auto c = cmd::BuildAirport(
|
||||
tile,
|
||||
airport_type,
|
||||
layout,
|
||||
INVALID_STATION,
|
||||
false
|
||||
);
|
||||
c.with_error(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE);
|
||||
JoinAndBuild(c, CcBuildAirport);
|
||||
}
|
||||
|
||||
static void FindStationsAroundSelection(const TileArea &location)
|
||||
|
||||
@@ -27,10 +27,10 @@ enum class StationBuildingStatus {
|
||||
bool UseImprovedStationJoin();
|
||||
void OnStationTileSetChange(const Station *station, bool adding, StationType type);
|
||||
void OnStationPartBuilt(const Station *station, TileIndex tile, uint32 p1, uint32 p2);
|
||||
void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, uint32 cmd);
|
||||
void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, RoadStopType stop_type, bool adjacent, RoadType rt, StringID err_msg);
|
||||
void HandleStationPlacement(TileIndex start, TileIndex end);
|
||||
void PlaceRail_Station(TileIndex tile);
|
||||
void PlaceDock(TileIndex tile);
|
||||
void PlaceDock(TileIndex tile, TileIndex tile_to);
|
||||
void PlaceAirport(TileIndex tile);
|
||||
|
||||
void SelectStationToJoin(const Station *station);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -217,6 +217,11 @@ struct BuildDocksToolbarWindow : Window {
|
||||
DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile));
|
||||
TileIndex tile_to = (dir != INVALID_DIAGDIR ? TileAddByDiagDir(tile, ReverseDiagDir(dir)) : tile);
|
||||
|
||||
if (citymania::UseImprovedStationJoin()) {
|
||||
citymania::PlaceDock(tile, tile_to);
|
||||
break;
|
||||
}
|
||||
|
||||
bool adjacent = _ctrl_pressed;
|
||||
auto proc = [=](bool test, StationID to_join) -> bool {
|
||||
if (test) {
|
||||
|
||||
@@ -375,8 +375,8 @@ struct MainWindow : Window
|
||||
|
||||
case GHK_BORROW_ALL:
|
||||
citymania::cmd::IncreaseLoan(LoanCommand::Max, 0)
|
||||
.WithError(STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY)
|
||||
.Post();
|
||||
.with_error(STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY)
|
||||
.post();
|
||||
break;
|
||||
|
||||
case GHK_CHAT: // smart chat; send to team if any, otherwise to all
|
||||
|
||||
@@ -170,8 +170,7 @@ void CcRoadStop(Commands cmd, const CommandCost &result, TileIndex tile, uint8 w
|
||||
static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, RoadStopType stop_type, bool adjacent, RoadType rt, StringID err_msg)
|
||||
{
|
||||
if (citymania::UseImprovedStationJoin()) {
|
||||
// FIXME
|
||||
// citymania::PlaceRoadStop(start_tile, end_tile, stop_type, adjacent, rt, err_msg);
|
||||
citymania::PlaceRoadStop(start_tile, end_tile, stop_type, adjacent, rt, err_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -2213,10 +2213,10 @@ void UpdateAirportsNoise()
|
||||
* @param airport_type airport type, @see airport.h
|
||||
* @param layout airport layout
|
||||
* @param station_to_join station ID to join (NEW_STATION if build new one)
|
||||
* @param allow_adjacent allow airports directly adjacent to other airports.
|
||||
* @param adjacent allow airports directly adjacent to other airports.
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, byte airport_type, byte layout, StationID station_to_join, bool allow_adjacent)
|
||||
CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, byte airport_type, byte layout, StationID station_to_join, bool adjacent)
|
||||
{
|
||||
bool reuse = (station_to_join != NEW_STATION);
|
||||
if (!reuse) station_to_join = INVALID_STATION;
|
||||
@@ -2281,7 +2281,7 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, byte airport_ty
|
||||
}
|
||||
|
||||
Station *st = nullptr;
|
||||
ret = FindJoiningStation(INVALID_STATION, station_to_join, allow_adjacent, airport_area, &st);
|
||||
ret = FindJoiningStation(INVALID_STATION, station_to_join, adjacent, airport_area, &st);
|
||||
if (ret.Failed()) return ret;
|
||||
|
||||
/* Distant join */
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
enum StationClassID : byte;
|
||||
|
||||
CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, byte airport_type, byte layout, StationID station_to_join, bool allow_adjacent);
|
||||
CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, byte airport_type, byte layout, StationID station_to_join, bool adjacent);
|
||||
CommandCost CmdBuildDock(DoCommandFlag flags, TileIndex tile, StationID station_to_join, bool adjacent);
|
||||
CommandCost CmdBuildRailStation(DoCommandFlag flags, TileIndex tile_org, RailType rt, Axis axis, byte numtracks, byte plat_len, StationClassID spec_class, byte spec_index, StationID station_to_join, bool adjacent);
|
||||
CommandCost CmdRemoveFromRailStation(DoCommandFlag flags, TileIndex start, TileIndex end, bool keep_rail);
|
||||
|
||||
@@ -2170,9 +2170,9 @@ struct MainToolbarWindow : Window {
|
||||
|
||||
case CM_CBF_BUILD_HQ:
|
||||
if(citymania::cmd::BuildObject(OBJECT_HQ, 0)
|
||||
.WithTile(tile)
|
||||
.WithError(STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS)
|
||||
.Post()) {
|
||||
.with_tile(tile)
|
||||
.with_error(STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS)
|
||||
.post()) {
|
||||
ResetObjectToPlace();
|
||||
this->RaiseButtons();
|
||||
}
|
||||
|
||||
@@ -920,10 +920,10 @@ static void DoRegularFunding(Town *t)
|
||||
} else if (_tick_counter - t->last_funding < TOWN_GROWTH_TICKS) return;
|
||||
|
||||
citymania::cmd::DoTownAction(t->index, HK_FUND)
|
||||
.WithTile(t->xy)
|
||||
.SetAuto()
|
||||
.AsCompany(_local_company)
|
||||
.Post();
|
||||
.with_tile(t->xy)
|
||||
.set_auto()
|
||||
.as_company(_local_company)
|
||||
.post();
|
||||
t->last_funding = _tick_counter;
|
||||
}
|
||||
|
||||
@@ -957,10 +957,10 @@ static void DoRegularAdvertising(Town *t) {
|
||||
t->last_advertisement = _tick_counter;
|
||||
|
||||
citymania::cmd::DoTownAction(t->index, HK_LADVERT)
|
||||
.WithTile(t->xy)
|
||||
.SetAuto()
|
||||
.AsCompany(_local_company)
|
||||
.Post();
|
||||
.with_tile(t->xy)
|
||||
.set_auto()
|
||||
.as_company(_local_company)
|
||||
.post();
|
||||
}
|
||||
|
||||
static void TownTickHandler(Town *t)
|
||||
|
||||
@@ -62,9 +62,9 @@ static void DrawExtraTownInfo (const Rect &r, uint &y, Town *town, uint line, bo
|
||||
bool TownExecuteAction(const Town *town, uint action){
|
||||
if(!(action == HK_STATUE && HasBit(town->statues, _current_company))){ //don't built statue when there is one
|
||||
return citymania::cmd::DoTownAction(town->index, action)
|
||||
.WithTile(town->xy)
|
||||
.WithError(STR_ERROR_CAN_T_DO_THIS)
|
||||
.Post();
|
||||
.with_tile(town->xy)
|
||||
.with_error(STR_ERROR_CAN_T_DO_THIS)
|
||||
.post();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user