Skip to content

Commit

Permalink
Refactor the game map to permit exposing it to Lua
Browse files Browse the repository at this point in the history
This adds map[{x,y}] and map[x][y] as valid ways to access the individual tiles of the map, rather than using map.set_terrain and map.get_terrain. This renders get_terrain redundant but not set_terrain (as the latter offers a third parameter).

Special locations as viewed through the map userdata are now iterable, and the length function also works.
  • Loading branch information
CelticMinstrel committed Nov 18, 2019
1 parent de772d9 commit 2992985
Show file tree
Hide file tree
Showing 12 changed files with 578 additions and 719 deletions.
17 changes: 17 additions & 0 deletions data/lua/core.lua
Expand Up @@ -546,6 +546,23 @@ if wesnoth.kernel_type() == "Game Lua Kernel" then
function wesnoth.get_side_variable(side, var)
return wesnoth.sides[side].variables[var]
end

--[========[Map module]========]

local get_map = wesnoth.get_map

-- Deprecated function
function wesnoth.terrain_mask(...)
get_map().terrain_mask(...)
end

-- Again deprecated
wesnoth.special_locations = setmetatable({}, {
__index = function(_, k) return get_map().special_locations[k] end,
__newindex = function(_, k, v) get_map().special_locations[k] = v end,
__len = function(_) return #get_map().special_locations end,
__pairs = function(_) return pairs(get_map().special_locations) end,
})
end

--[========[GUI2 Dialog Manipulations]========]
Expand Down
4 changes: 2 additions & 2 deletions src/editor/action/action.cpp
Expand Up @@ -252,7 +252,7 @@ editor_action* editor_action_starting_position::perform(map_context& mc) const
{
editor_action_ptr undo;

const std::string* old_loc_id = mc.map().is_starting_position(loc_);
const std::string* old_loc_id = mc.map().is_special_location(loc_);
map_location old_loc = mc.map().special_location(loc_id_);

if(old_loc_id != nullptr) {
Expand Down Expand Up @@ -282,7 +282,7 @@ editor_action* editor_action_starting_position::perform(map_context& mc) const

void editor_action_starting_position::perform_without_undo(map_context& mc) const
{
const std::string* old_id = mc.map().is_starting_position(loc_);
const std::string* old_id = mc.map().is_special_location(loc_);
if(old_id != nullptr) {
mc.map().set_special_location(*old_id, map_location());
}
Expand Down
6 changes: 3 additions & 3 deletions src/editor/action/mouse/mouse_action.cpp
Expand Up @@ -107,7 +107,7 @@ editor_action* mouse_action::key_event(
|| event.key.keysym.sym == SDLK_DELETE) {
int res = event.key.keysym.sym - '0';
if (res > gamemap::MAX_PLAYERS || event.key.keysym.sym == SDLK_DELETE) res = 0;
const std::string* old_id = disp.map().is_starting_position(previous_move_hex_);
const std::string* old_id = disp.map().is_special_location(previous_move_hex_);
if (res == 0 && old_id != nullptr) {
a = new editor_action_starting_position(map_location(), *old_id);
} else if (res > 0 && (old_id == nullptr || *old_id == std::to_string(res))) {
Expand Down Expand Up @@ -399,7 +399,7 @@ editor_action* mouse_action_starting_position::up_left(editor_display& disp, int
if (!disp.map().on_board(hex)) {
return nullptr;
}
auto player_starting_at_hex = disp.map().is_starting_position(hex);
auto player_starting_at_hex = disp.map().is_special_location(hex);

if (has_ctrl_modifier()) {
if (player_starting_at_hex) {
Expand Down Expand Up @@ -434,7 +434,7 @@ editor_action* mouse_action_starting_position::click_left(editor_display& /*disp
editor_action* mouse_action_starting_position::up_right(editor_display& disp, int x, int y)
{
map_location hex = disp.hex_clicked_on(x, y);
auto player_starting_at_hex = disp.map().is_starting_position(hex);
auto player_starting_at_hex = disp.map().is_special_location(hex);
if (player_starting_at_hex != nullptr) {
return new editor_action_starting_position(map_location(), *player_starting_at_hex);
} else {
Expand Down
118 changes: 55 additions & 63 deletions src/editor/map/editor_map.cpp
Expand Up @@ -86,20 +86,20 @@ editor_map::~editor_map()
void editor_map::sanity_check()
{
int errors = 0;
if (total_width() != tiles_.w) {
ERR_ED << "total_width is " << total_width() << " but tiles_.size() is " << tiles_.w << std::endl;
if (total_width() != tiles().w) {
ERR_ED << "total_width is " << total_width() << " but tiles().size() is " << tiles().w << std::endl;
++errors;
}
if (total_height() != tiles_.h) {
ERR_ED << "total_height is " << total_height() << " but tiles_[0].size() is " << tiles_.h << std::endl;
if (total_height() != tiles().h) {
ERR_ED << "total_height is " << total_height() << " but tiles()[0].size() is " << tiles().h << std::endl;
++errors;
}
if (w() + 2 * border_size() != total_width()) {
ERR_ED << "h is " << h_ << " and border_size is " << border_size() << " but total_width is " << total_width() << std::endl;
ERR_ED << "h is " << h() << " and border_size is " << border_size() << " but total_width is " << total_width() << std::endl;
++errors;
}
if (h() + 2 * border_size() != total_height()) {
ERR_ED << "w is " << w_ << " and border_size is " << border_size() << " but total_height is " << total_height() << std::endl;
ERR_ED << "w is " << w() << " and border_size is " << border_size() << " but total_height is " << total_height() << std::endl;
++errors;
}
for (const map_location& loc : selection_) {
Expand Down Expand Up @@ -141,7 +141,7 @@ std::set<map_location> editor_map::set_starting_position_labels(display& disp)
std::string label;


for (const auto& pair : starting_positions_.left) {
for (const auto& pair : special_locations().left) {

bool is_number = std::find_if(pair.first.begin(), pair.first.end(), [](char c) { return !std::isdigit(c); }) == pair.first.end();
if (is_number) {
Expand Down Expand Up @@ -250,8 +250,8 @@ void editor_map::resize(int width, int height, int x_offset, int y_offset,

// fix the starting positions
if(x_offset || y_offset) {
for (auto it = starting_positions_.left.begin(); it != starting_positions_.left.end(); ++it) {
starting_positions_.left.modify_data(it, [=](t_translation::coordinate & loc) { loc.add(-x_offset, -y_offset); });
for (auto it = special_locations().left.begin(); it != special_locations().left.end(); ++it) {
special_locations().left.modify_data(it, [=](t_translation::coordinate & loc) { loc.add(-x_offset, -y_offset); });
}
}

Expand Down Expand Up @@ -302,130 +302,122 @@ bool editor_map::same_size_as(const gamemap& other) const

void editor_map::expand_right(int count, const t_translation::terrain_code & filler)
{
t_translation::ter_map tiles_new(tiles_.w + count, tiles_.h);
w_ += count;
for (int x = 0, x_end = tiles_.w; x != x_end; ++x) {
for (int y = 0, y_end = tiles_.h; y != y_end; ++y) {
tiles_new.get(x, y) = tiles_.get(x, y);
t_translation::ter_map tiles_new(tiles().w + count, tiles().h);
for (int x = 0, x_end = tiles().w; x != x_end; ++x) {
for (int y = 0, y_end = tiles().h; y != y_end; ++y) {
tiles_new.get(x, y) = tiles().get(x, y);
}
}
for (int x = tiles_.w, x_end = tiles_.w + count; x != x_end; ++x) {
for (int y = 0, y_end = tiles_.h; y != y_end; ++y) {
tiles_new.get(x, y) = filler == t_translation::NONE_TERRAIN ? tiles_.get(tiles_.w - 1, y) : filler;
for (int x = tiles().w, x_end = tiles().w + count; x != x_end; ++x) {
for (int y = 0, y_end = tiles().h; y != y_end; ++y) {
tiles_new.get(x, y) = filler == t_translation::NONE_TERRAIN ? tiles().get(tiles().w - 1, y) : filler;
}
}
tiles_ = std::move(tiles_new);
tiles() = std::move(tiles_new);
}

void editor_map::expand_left(int count, const t_translation::terrain_code & filler)
{
t_translation::ter_map tiles_new(tiles_.w + count, tiles_.h);
w_ += count;
for (int x = 0, x_end = tiles_.w; x != x_end; ++x) {
for (int y = 0, y_end = tiles_.h; y != y_end; ++y) {
tiles_new.get(x + count, y) = tiles_.get(x, y);
t_translation::ter_map tiles_new(tiles().w + count, tiles().h);
for (int x = 0, x_end = tiles().w; x != x_end; ++x) {
for (int y = 0, y_end = tiles().h; y != y_end; ++y) {
tiles_new.get(x + count, y) = tiles().get(x, y);
}
}
for (int x = 0, x_end = count; x != x_end; ++x) {
for (int y = 0, y_end = tiles_.h; y != y_end; ++y) {
tiles_new.get(x, y) = filler == t_translation::NONE_TERRAIN ? tiles_.get(0, y) : filler;
for (int y = 0, y_end = tiles().h; y != y_end; ++y) {
tiles_new.get(x, y) = filler == t_translation::NONE_TERRAIN ? tiles().get(0, y) : filler;
}
}
tiles_ = std::move(tiles_new);
tiles() = std::move(tiles_new);
}

void editor_map::expand_top(int count, const t_translation::terrain_code & filler)
{
t_translation::ter_map tiles_new(tiles_.w, tiles_.h + count);
h_ += count;
for (int x = 0, x_end = tiles_.w; x != x_end; ++x) {
for (int y = 0, y_end = tiles_.h; y != y_end; ++y) {
tiles_new.get(x, y + count) = tiles_.get(x, y);
t_translation::ter_map tiles_new(tiles().w, tiles().h + count);
for (int x = 0, x_end = tiles().w; x != x_end; ++x) {
for (int y = 0, y_end = tiles().h; y != y_end; ++y) {
tiles_new.get(x, y + count) = tiles().get(x, y);
}
}
for (int x = 0, x_end = tiles_.w; x != x_end; ++x) {
for (int x = 0, x_end = tiles().w; x != x_end; ++x) {
for (int y = 0, y_end = count; y != y_end; ++y) {
tiles_new.get(x, y) = filler == t_translation::NONE_TERRAIN ? tiles_.get(x, 0) : filler;
tiles_new.get(x, y) = filler == t_translation::NONE_TERRAIN ? tiles().get(x, 0) : filler;
}
}
tiles_ = std::move(tiles_new);
tiles() = std::move(tiles_new);
}

void editor_map::expand_bottom(int count, const t_translation::terrain_code & filler)
{
t_translation::ter_map tiles_new(tiles_.w, tiles_.h + count);
h_ += count;
for (int x = 0, x_end = tiles_.w; x != x_end; ++x) {
for (int y = 0, y_end = tiles_.h; y != y_end; ++y) {
tiles_new.get(x, y) = tiles_.get(x, y);
t_translation::ter_map tiles_new(tiles().w, tiles().h + count);
for (int x = 0, x_end = tiles().w; x != x_end; ++x) {
for (int y = 0, y_end = tiles().h; y != y_end; ++y) {
tiles_new.get(x, y) = tiles().get(x, y);
}
}
for (int x = 0, x_end = tiles_.w; x != x_end; ++x) {
for (int y = tiles_.h, y_end = tiles_.h + count; y != y_end; ++y) {
tiles_new.get(x, y) = filler == t_translation::NONE_TERRAIN ? tiles_.get(x, tiles_.h - 1) : filler;
for (int x = 0, x_end = tiles().w; x != x_end; ++x) {
for (int y = tiles().h, y_end = tiles().h + count; y != y_end; ++y) {
tiles_new.get(x, y) = filler == t_translation::NONE_TERRAIN ? tiles().get(x, tiles().h - 1) : filler;
}
}
tiles_ = std::move(tiles_new);
tiles() = std::move(tiles_new);
}

void editor_map::shrink_right(int count)
{
if(count < 0 || count > tiles_.w) {
if(count < 0 || count > tiles().w) {
throw editor_map_operation_exception();
}
t_translation::ter_map tiles_new(tiles_.w - count, tiles_.h);
t_translation::ter_map tiles_new(tiles().w - count, tiles().h);
for (int x = 0, x_end = tiles_new.w; x != x_end; ++x) {
for (int y = 0, y_end = tiles_new.h; y != y_end; ++y) {
tiles_new.get(x, y) = tiles_.get(x, y);
tiles_new.get(x, y) = tiles().get(x, y);
}
}
w_ -= count;
tiles_ = std::move(tiles_new);
tiles() = std::move(tiles_new);
}

void editor_map::shrink_left(int count)
{
if (count < 0 || count > tiles_.w) {
if (count < 0 || count > tiles().w) {
throw editor_map_operation_exception();
}
t_translation::ter_map tiles_new(tiles_.w - count, tiles_.h);
t_translation::ter_map tiles_new(tiles().w - count, tiles().h);
for (int x = 0, x_end = tiles_new.w; x != x_end; ++x) {
for (int y = 0, y_end = tiles_new.h; y != y_end; ++y) {
tiles_new.get(x, y) = tiles_.get(x + count, y);
tiles_new.get(x, y) = tiles().get(x + count, y);
}
}
w_ -= count;
tiles_ = std::move(tiles_new);
tiles() = std::move(tiles_new);
}

void editor_map::shrink_top(int count)
{
if (count < 0 || count > tiles_.h) {
if (count < 0 || count > tiles().h) {
throw editor_map_operation_exception();
}
t_translation::ter_map tiles_new(tiles_.w, tiles_.h - count);
t_translation::ter_map tiles_new(tiles().w, tiles().h - count);
for (int x = 0, x_end = tiles_new.w; x != x_end; ++x) {
for (int y = 0, y_end = tiles_new.h; y != y_end; ++y) {
tiles_new.get(x, y) = tiles_.get(x, y + count);
tiles_new.get(x, y) = tiles().get(x, y + count);
}
}
h_ -= count;
tiles_ = std::move(tiles_new);
tiles() = std::move(tiles_new);
}

void editor_map::shrink_bottom(int count)
{
if (count < 0 || count > tiles_.h) {
if (count < 0 || count > tiles().h) {
throw editor_map_operation_exception();
}
t_translation::ter_map tiles_new(tiles_.w, tiles_.h - count);
t_translation::ter_map tiles_new(tiles().w, tiles().h - count);
for (int x = 0, x_end = tiles_new.w; x != x_end; ++x) {
for (int y = 0, y_end = tiles_new.h; y != y_end; ++y) {
tiles_new.get(x, y) = tiles_.get(x, y);
tiles_new.get(x, y) = tiles().get(x, y);
}
}
h_ -= count;
tiles_ = std::move(tiles_new);
tiles() = std::move(tiles_new);
}


Expand Down

0 comments on commit 2992985

Please sign in to comment.