From 6e1e63b76bb902f0c688225535f754a603ededc6 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Tue, 16 Feb 2021 01:29:34 -0500 Subject: [PATCH] Add a terrain hex reference API --- data/lua/core.lua | 113 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 1 deletion(-) diff --git a/data/lua/core.lua b/data/lua/core.lua index afe349740347..916374887fa3 100644 --- a/data/lua/core.lua +++ b/data/lua/core.lua @@ -699,8 +699,119 @@ if wesnoth.kernel_type() == "Game Lua Kernel" then return nil, 0 end + local hex_mt = {__metatable = 'terrain hex reference'} + + function hex_mt.__index(self, key) + if key == 'fogged' then + return self:fogged_for(wesnoth.current.side) + elseif key == 'shrouded' then + return self:shrouded_for(wesnoth.current.side) + elseif key == 'team_label' then + local label = self:label_for(wesnoth.current.side) + if label then return label.text end + return nil + elseif key == 'global_label' then + local label = self:label_for(nil) + if label then return label.text end + return nil + elseif key == 'label' then + return self.team_label or self.global_label + elseif key == 'terrain' then + return wesnoth.current.map[self] + elseif key == 'base_terrain' then + return self.terrain:split('^')[1] + elseif key == 'overlay_terrain' then + return self.terrain:split('^', {remove_empty=false})[2] + elseif key == 'info' then + return wesnoth.get_terrain_info(wesnoth.current.map[self]) + elseif #key > 0 and key[0] ~= '_' then + return hex_mt[key] + end + end + + function hex_mt.__newindex(self, key, val) + if key == 'fogged' then + self:set_fogged(wesnoth.current.side, val) + elseif key == 'shrouded' then + self:set_shrouded(wesnoth.current.side, val) + elseif key == 'team_label' or key == 'global_label' or key == 'label' then + local cfg + if type(val) == 'string' or (type(val) == 'userdata' and getmetatable(val) == 'translatable string') then + cfg = {x = self.x, y = self.y, text = val} + else + cfg = wml.parsed(val) + cfg.x, cfg.y = self.x, self.y + end + if key == 'team_label' then + cfg.side = wesnoth.current.side + cfg.team_name = wesnoth.sides[wesnoth.current.side].team_name + elseif key == 'global_label' then + cfg.side = 0 + cfg.team_name = nil + elseif cfg.side == nil and cfg.team_name == nil then + -- If side or team name explicitly specified, use that, otherwise use current side and no team + cfg.side = wesnoth.current.side + cfg.team_name = nil + end + wesnoth.map.add_label(cfg) + elseif key == 'terrain' then + wesnoth.current.map[self] = val + elseif key == 'base_terrain' then + wesnoth.current.map[self] = wesnoth.map.replace_base(val) + elseif key == 'overlay_terrain' then + wesnoth.current.map[self] = wesnoth.map.replace_overlay(val) + elseif key == 'info' then + error('hex.info is read-only', 1) + end + end + + function hex_mt:fogged_for(side) + return wesnoth.map.is_fogged(side, self.x, self.y) + end + + function hex_mt:shrouded_for(side) + return wesnoth.map.is_shrouded(side, self.x, self.y) + end + + function hex_mt:set_fogged(side, val) + if val then + wesnoth.map.place_shroud(side, {val}) + else + wesnoth.map.remove_shroud(side, {val}) + end + end + + function hex_mt:set_fogged(side, val) + if val then + wesnoth.map.place_fog(side, {val}) + else + wesnoth.map.remove_fog(side, {val}) + end + end + + function hex_mt:label_for(who) + return wesnoth.map.get_label(self.x, self.y, who) + end + + function hex_mt:matches(filter) + return wesnoth.map.matches(self.x, self.y, filter) + end + + function wesnoth.map.get_hex(x, y) + return setmetatable({x = x, y = y}, hex_mt) + end + + function wesnoth.map.find_hexes(cfg) + local hexes = wesnoth.map.find(cfg) + for i = 1, #hexes do + hexes[i] = wesnoth.map.get_hex(hexes[i].x, hexes[i].y) + end + return hexes + end + + -- Deprecated stuff wesnoth.terrain_mask = wesnoth.deprecate_api('wesnoth.terrain_mask', 'wesnoth.current.map:terrain_mask', 1, nil, function(...) - wesnoth.current.map.terrain_mask(...) + get_map().terrain_mask(...) end) wesnoth.get_terrain = wesnoth.deprecate_api('wesnoth.get_terrain', 'wesnoth.current.map[loc]', 1, nil, function(x, y) local loc = wesnoth.read_location(x, y)