add terrain_mask function to lua gamemap object.
This commit is contained in:
parent
b43c132b70
commit
cfd81d38be
4 changed files with 137 additions and 11 deletions
|
@ -208,20 +208,35 @@ std::string gamemap::write() const
|
|||
}
|
||||
|
||||
void gamemap::overlay(const gamemap& m, map_location loc, const std::vector<overlay_rule>& rules, bool m_is_odd, bool ignore_special_locations)
|
||||
{
|
||||
overlay_impl(tiles_, starting_positions_, m.tiles_, m.starting_positions_, [this](auto&&... arg) { set_terrain(std::forward<decltype(arg)>(arg)...); }, loc, rules, m_is_odd, ignore_special_locations);
|
||||
}
|
||||
|
||||
void gamemap::overlay_impl(
|
||||
// const but changed via set_terrain
|
||||
const t_translation::ter_map& m1,
|
||||
starting_positions& m1_st,
|
||||
const t_translation::ter_map& m2,
|
||||
const starting_positions& m2_st,
|
||||
std::function<void (const map_location&, const t_translation::terrain_code&, terrain_type_data::merge_mode, bool)> set_terrain,
|
||||
map_location loc,
|
||||
const std::vector<overlay_rule>& rules,
|
||||
bool m_is_odd,
|
||||
bool ignore_special_locations)
|
||||
{
|
||||
int xpos = loc.wml_x();
|
||||
int ypos = loc.wml_y();
|
||||
|
||||
const int xstart = std::max<int>(0, -xpos);
|
||||
const int xend = std::min<int>(m.total_width(), total_width() -xpos);
|
||||
const int xend = std::min<int>(m2.w, m1.w -xpos);
|
||||
const int xoffset = xpos;
|
||||
|
||||
const int ystart_even = std::max<int>(0, -ypos);
|
||||
const int yend_even = std::min<int>(m.total_height(), total_height() - ypos);
|
||||
const int yend_even = std::min<int>(m2.h, m1.h - ypos);
|
||||
const int yoffset_even = ypos;
|
||||
|
||||
const int ystart_odd = std::max<int>(0, -ypos +(xpos & 1) -(m_is_odd ? 1 : 0));
|
||||
const int yend_odd = std::min<int>(m.total_height(), total_height() - ypos +(xpos & 1) -(m_is_odd ? 1 : 0));
|
||||
const int yend_odd = std::min<int>(m2.h, m1.h - ypos +(xpos & 1) -(m_is_odd ? 1 : 0));
|
||||
const int yoffset_odd = ypos -(xpos & 1) + (m_is_odd ? 1 : 0);
|
||||
|
||||
for(int x1 = xstart; x1 != xend; ++x1) {
|
||||
|
@ -234,10 +249,10 @@ void gamemap::overlay(const gamemap& m, map_location loc, const std::vector<over
|
|||
}
|
||||
for(int y1 = ystart; y1 != yend; ++y1) {
|
||||
const int x2 = x1 + xoffset;
|
||||
const int y2 = y1 + yoffset;//ypos + ((xpos & 1) && (x1 & 1) ? 1 : 0);
|
||||
const int y2 = y1 + yoffset;
|
||||
|
||||
const t_translation::terrain_code t = m.tiles_.get(x1,y1);
|
||||
const t_translation::terrain_code current = tiles_.get(x2, y2);
|
||||
const t_translation::terrain_code t = m2.get(x1,y1);
|
||||
const t_translation::terrain_code current = m1.get(x2, y2);
|
||||
|
||||
if(t == t_translation::FOGGED || t == t_translation::VOID_TERRAIN) {
|
||||
continue;
|
||||
|
@ -258,7 +273,7 @@ void gamemap::overlay(const gamemap& m, map_location loc, const std::vector<over
|
|||
}
|
||||
|
||||
if (!rule) {
|
||||
set_terrain(map_location(x2, y2, wml_loc()), t);
|
||||
set_terrain(map_location(x2, y2, wml_loc()), t, terrain_type_data::BOTH, false);
|
||||
}
|
||||
else if(!rule->use_old_) {
|
||||
set_terrain(map_location(x2, y2, wml_loc()), rule->terrain_ ? *rule->terrain_ : t , rule->mode_, rule->replace_if_failed_);
|
||||
|
@ -267,7 +282,7 @@ void gamemap::overlay(const gamemap& m, map_location loc, const std::vector<over
|
|||
}
|
||||
|
||||
if (!ignore_special_locations) {
|
||||
for(auto& pair : m.starting_positions_.left) {
|
||||
for(auto& pair : m2_st.left) {
|
||||
|
||||
int x = pair.second.wml_x();
|
||||
int y = pair.second.wml_y();
|
||||
|
@ -285,8 +300,8 @@ void gamemap::overlay(const gamemap& m, map_location loc, const std::vector<over
|
|||
int y_new = y + ((x & 1 ) ? yoffset_odd : yoffset_even);
|
||||
map_location pos_new = map_location(x_new, y_new, wml_loc());
|
||||
|
||||
starting_positions_.left.erase(pair.first);
|
||||
starting_positions_.insert(starting_positions::value_type(pair.first, t_translation::coordinate(pos_new.x, pos_new.y)));
|
||||
m1_st.left.erase(pair.first);
|
||||
m1_st.insert(starting_positions::value_type(pair.first, t_translation::coordinate(pos_new.x, pos_new.y)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,6 +109,18 @@ public:
|
|||
/** Overlays another map onto this one at the given position. */
|
||||
void overlay(const gamemap& m, map_location loc, const std::vector<overlay_rule>& rules = std::vector<overlay_rule>(), bool is_odd = false, bool ignore_special_locations = false);
|
||||
|
||||
static void overlay_impl(
|
||||
// const but changed via set_terrain
|
||||
const t_translation::ter_map& m1,
|
||||
starting_positions& m1_st,
|
||||
const t_translation::ter_map& m2,
|
||||
const starting_positions& m2_st,
|
||||
std::function<void (const map_location&, const t_translation::terrain_code&, terrain_type_data::merge_mode, bool)> set_terrain,
|
||||
map_location loc,
|
||||
const std::vector<overlay_rule>& rules,
|
||||
bool is_odd,
|
||||
bool ignore_special_locations);
|
||||
|
||||
/** Effective map width. */
|
||||
int w() const { return w_; }
|
||||
|
||||
|
|
|
@ -341,6 +341,103 @@ static int intf_get_terrain(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static std::vector<gamemap::overlay_rule> read_rules_vector(lua_State *L, int index)
|
||||
{
|
||||
std::vector<gamemap::overlay_rule> rules;
|
||||
for (int i = 1, i_end = lua_rawlen(L, index); i <= i_end; ++i)
|
||||
{
|
||||
lua_rawgeti(L, index, i);
|
||||
if(!lua_istable(L, -1)) {
|
||||
return luaL_argerror(L, index, "rules must be a table of tables");
|
||||
}
|
||||
rules.push_back(gamemap::overlay_rule());
|
||||
auto& rule = rules.back();
|
||||
if(luaW_tableget(L, -1, "old")) {
|
||||
rule.old_ = t_translation::read_list(luaW_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
if(luaW_tableget(L, -1, "new")) {
|
||||
rule.new_ = t_translation::read_list(luaW_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
if(luaW_tableget(L, -1, "mode")) {
|
||||
auto str = luaW_tostring(L, -1);
|
||||
rule.mode_ = str == "base" ? terrain_type_data::BASE : (str == "overlay" ? terrain_type_data::OVERLAY : terrain_type_data::BOTH);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
if(luaW_tableget(L, -1, "terrain")) {
|
||||
const t_translation::ter_list terrain = t_translation::read_list(luaW_tostring(L, -1));
|
||||
if(!terrain.empty()) {
|
||||
rule.terrain_ = terrain[0];
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
if(luaW_tableget(L, -1, "use_old")) {
|
||||
rule.use_old_ = luaW_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
if(luaW_tableget(L, -1, "replace_if_failed")) {
|
||||
rule.replace_if_failed_ = luaW_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
return rules;
|
||||
}
|
||||
/**
|
||||
* Reaplces part of the map.
|
||||
* - Arg 1: map location.
|
||||
* - Arg 2: map data string.
|
||||
* - Arg 3: table for optional named arguments
|
||||
* - is_odd: boolen, if Arg2 has the odd mapo format (as if it was cut from a odd map location)
|
||||
* - ignore_special_locations: boolean
|
||||
* - rules: table of tables
|
||||
*/
|
||||
static int intf_mg_terrain_mask(lua_State *L)
|
||||
{
|
||||
mapgen_gamemap& tm1 = luaW_checkterrainmap(L, 1);
|
||||
map_location loc = luaW_checklocation(L, 2);
|
||||
mapgen_gamemap& tm1 = luaW_checkterrainmap(L, 3);
|
||||
|
||||
bool is_odd = false;
|
||||
bool ignore_special_locations = false;
|
||||
std::vector<gamemap::overlay_rule> rules;
|
||||
|
||||
if(lua_istable(L, 4)) {
|
||||
is_odd = luaW_table_get_def<bool>(L, 4, "is_odd", false);
|
||||
ignore_special_locations = luaW_table_get_def<bool>(L, 4, "ignore_special_locations", false);
|
||||
|
||||
if(luaW_tableget(L, 4, "rules")) {
|
||||
if(!lua_istable(L, -1)) {
|
||||
return luaL_argerror(L, 4, "rules must be a table");
|
||||
}
|
||||
rules = read_rules_vector(L, -1)
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
board().map_->overlay(mask_map, loc, rules, is_odd, ignore_special_locations);
|
||||
|
||||
gamemap::overlay_impl(
|
||||
tm1.tiles_,
|
||||
tm1.starting_positions_,
|
||||
tm2.tiles_,
|
||||
tm2.starting_positions_,
|
||||
[&](const map_location& loc, const t_translation::terrain_code& t, terrain_type_data::merge_mode mode, bool) { tm1.set_terrain(loc, t, mode); },
|
||||
loc,
|
||||
rules,
|
||||
is_odd,
|
||||
ignore_special_locations
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace lua_terrainmap {
|
||||
std::string register_metatables(lua_State* L)
|
||||
{
|
||||
|
@ -366,6 +463,8 @@ namespace lua_terrainmap {
|
|||
lua_setfield(L, -2, "get_locations");
|
||||
lua_pushcfunction(L, intf_mg_get_tiles_radius);
|
||||
lua_setfield(L, -2, "get_tiles_radius");
|
||||
lua_pushcfunction(L, intf_mg_terrain_mask);
|
||||
lua_setfield(L, -2, "terrain_mask");
|
||||
|
||||
cmd_out << "Adding terrainmamap2 metatable...\n";
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
friend int intf_terrain_mask(lua_State *L);
|
||||
private:
|
||||
t_translation::ter_map tiles_;
|
||||
starting_positions starting_positions_;
|
||||
|
|
Loading…
Add table
Reference in a new issue