diff --git a/game/engine/Map.lua b/game/engine/Map.lua index 3df536ffe0b93c8670dce9dcc85ce3b8fb9175c9..15a9d9ce65029dba4e81423d318276ccce6f61f7 100644 --- a/game/engine/Map.lua +++ b/game/engine/Map.lua @@ -80,6 +80,7 @@ end --- Serialization function _M:save() return class.save(self, { + _fov_esp = true, _fov_lite = true, _fov = true, _map = true, @@ -125,6 +126,7 @@ function _M:loaded() self.surface = core.display.newSurface(self.viewport.width, self.viewport.height) self._fov = core.fov.new(_M.opaque, _M.apply, self) self._fov_lite = core.fov.new(_M.opaque, _M.applyLite, self) + self._fov_esp = core.fov.new(_M.opaqueESP, _M.applyESP, self) self.changed = true self:redisplay() @@ -154,6 +156,7 @@ end function _M:close() self._fov = false self._fov_lite = false + self._fov_esp = false end --- Runs the FOV algorithm on the map @@ -184,6 +187,20 @@ function _M:fovLite(x, y, d) self._fov_lite(x, y, d) end +--- Runs the FOV algorithm on the map, finding ESP(Extra Sensorial Power) targets +-- @param x source point of the ligth +-- @param y source point of the ligth +-- @param d radius of the light +function _M:fovESP(x, y, d) + -- Reset seen grids + if self.clean_fov then + self.clean_fov = false + for i = 0, self.w * self.h - 1 do self.seens[i] = nil end + self._map:cleanSeen(); + end + self._fov_esp(x, y, d) +end + function _M:updateMap(x, y) local g = self(x, y, TERRAIN) local o = self(x, y, OBJECT) @@ -192,7 +209,7 @@ function _M:updateMap(x, y) if g then g = self.tiles:get(g.display, g.color_r, g.color_g, g.color_b, g.color_br, g.color_bg, g.color_bb, g.image) end if o then o = self.tiles:get(o.display, o.color_r, o.color_g, o.color_b, o.color_br, o.color_bg, o.color_bb, o.image) end if a then - -- Handles invisibility and telepathy and otehr such things + -- Handles invisibility and telepathy and other such things if not self.actor_player or self.actor_player:canSee(a) then a = self.tiles:get(a.display, a.color_r, a.color_g, a.color_b, a.color_br, a.color_bg, a.color_bb, a.image) else @@ -288,6 +305,14 @@ function _M:opaque(x, y) if e and e:check("block_sight") then return true end end +--- Sets checks if a grid lets ESP pass through +-- Used by FOV ESP code +function _M:opaqueESP(x, y) + if x < 0 or x >= self.w or y < 0 or y >= self.h then return false end + local e = self(x, y, TERRAIN) + if e and e:check("block_esp") then return true end +end + --- Sets a grid as seen and remembered -- Used by FOV code function _M:apply(x, y) @@ -312,6 +337,18 @@ function _M:applyLite(x, y) self._map:setSeen(x, y, true) end +--- Sets a grid as seen if ESP'ed +-- Used by FOV code +function _M:applyESP(x, y) + if not self.actor_player then return end + if x < 0 or x >= self.w or y < 0 or y >= self.h then return end + local a = self(x, y, ACTOR) + if a and self.actor_player:canSee(a, false, 0) then + self.seens[x + y * self.w] = true + self._map:setSeen(x, y, true) + end +end + --- Check all entities of the grid for a property -- @param x position -- @param y position diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index c5c6b35c3d2d8be02f7b0746ac534779f0a06743..c3024a2c9cecd2522840d37a296cb81c55d935a4 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -52,6 +52,8 @@ function _M:init(t, no_default) t.mana_rating = t.mana_rating or 10 t.stamina_rating = t.stamina_rating or 10 + t.esp = {range=10} + -- Resistances t.resists = t.resists or {} @@ -335,7 +337,23 @@ end --- Can the actor see the target actor -- This does not check LOS or such, only the actual ability to see it.<br/> -- Check for telepathy, invisibility, stealth, ... -function _M:canSee(actor) +function _M:canSee(actor, def, def_pct) + -- ESP, see all, or only types/subtypes + if self:attr("esp") then + local esp = self:attr("esp") + -- Full ESP + if esp.all and esp.all > 0 then + if game.level then + game.level.map.seens(actor.x, actor.y, true) + end + return true, 100 + end + + -- Type based ESP + if esp[actor.type] and esp[actor.type] > 0 then return true, 100 end + if esp[actor.type.."/"..actor.subtype] and esp[actor.type.."/"..actor.subtype] > 0 then return true, 100 end + end + -- Blindness means can't see anything if self:attr("blind") then return false, 0 end @@ -343,7 +361,6 @@ function _M:canSee(actor) if actor:attr("stealth") and actor ~= self then local def = self.level / 2 + self:getCun(25) local hit, chance = self:checkHit(def, actor:attr("stealth") + (actor:attr("inc_stealth") or 0), 0, 100) - print("Stealth", actor:attr("stealth") + (actor:attr("inc_stealth") or 0), "<:>", def, " ===> ", hit, chance) if not hit then return false, chance end @@ -358,7 +375,11 @@ function _M:canSee(actor) return false, chance end end - return true, 100 + if def ~= nil then + return def, def_pct + else + return true, 100 + end end --- Can the target be applied some effects diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index 99ff89acf2b916cfe7a14ccaf9c2a112039e4684..9caeba4055b93cb56cbb9c5a328c181e39191a7f 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -205,6 +205,7 @@ function _M:display() if self.level and self.level.map then -- Display the map and compute FOV for the player if needed if self.level.map.changed then + self.level.map:fovESP(self.player.x, self.player.y, self.player.esp.range or 10) self.level.map:fov(self.player.x, self.player.y, 20) if self.player.lite > 0 then self.level.map:fovLite(self.player.x, self.player.y, self.player.lite) end end diff --git a/game/modules/tome/class/Object.lua b/game/modules/tome/class/Object.lua index 810a2e0e99837b4e2eacaf197bf55cdc4725ea9c..bcc4d5e40e817db85f3216ae256dc68b36f39c08 100644 --- a/game/modules/tome/class/Object.lua +++ b/game/modules/tome/class/Object.lua @@ -102,6 +102,22 @@ function _M:getDesc() desc[#desc+1] = ("Increases resistances: %s."):format(table.concat(rs, ',')) end + if w.esp then + local rs = {} + for type, i in pairs(w.esp) do + if type == "all" then rs[#rs+1] = "all" + else + local _, _, t, st = type:find("^([^/]+)/?(.*)$") + if st then + rs[#rs+1] = st + else + rs[#rs+1] = t + end + end + end + desc[#desc+1] = ("Grants telepathy to %s."):format(table.concat(rs, ',')) + end + if w.talents_types_mastery then local tms = {} for ttn, i in pairs(w.talents_types_mastery) do diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua index 2a491ddd61289fc6bcf548b6abcb6f76f1d1703a..f686f4893a2440df5aca546c050e044a91c72681 100644 --- a/game/modules/tome/class/Player.lua +++ b/game/modules/tome/class/Player.lua @@ -32,6 +32,8 @@ function _M:init(t, no_default) } mod.class.Actor.init(self, t, no_default) self.player = true + self.type = "humanoid" + self.subtype = "player" self.faction = "players" self.display='@' diff --git a/game/modules/tome/data/birth/races/dwarf.lua b/game/modules/tome/data/birth/races/dwarf.lua index aeb98a51c6a5a6547fbdc53ac98e9da65460f894..486e9f7ba1bd58ff67b42cd504e49deb3ad94509 100644 --- a/game/modules/tome/data/birth/races/dwarf.lua +++ b/game/modules/tome/data/birth/races/dwarf.lua @@ -27,6 +27,7 @@ newBirthDescriptor{ [ActorTalents.T_DWARF_RESILIENCE]=1, }, copy = { + type = "humanoid", subtype="dwarf", default_wilderness = {"wilderness/main", 41, 18}, life_rating=12, }, diff --git a/game/modules/tome/data/birth/races/elf.lua b/game/modules/tome/data/birth/races/elf.lua index 2ecb00f87e88803bfc934ef8ef9e93db42836442..cb2e2adf924d4af5e5a5082d60b2ed7876ad2dfe 100644 --- a/game/modules/tome/data/birth/races/elf.lua +++ b/game/modules/tome/data/birth/races/elf.lua @@ -22,6 +22,7 @@ newBirthDescriptor{ -- [ActorTalents.T_IMPROVED_MANA_I]=1, }, copy = { + type = "humanoid", subtype="elf", default_wilderness = {"wilderness/main", 41, 18}, }, experience = 1.05, diff --git a/game/modules/tome/data/birth/races/hobbit.lua b/game/modules/tome/data/birth/races/hobbit.lua index 7ad3bab1d5070a8d8fd52d76e012c0bdf9828588..4947b49b8da0d4fc3d987ecf122e63779e04eaf8 100644 --- a/game/modules/tome/data/birth/races/hobbit.lua +++ b/game/modules/tome/data/birth/races/hobbit.lua @@ -36,6 +36,7 @@ newBirthDescriptor{ [ActorTalents.T_HOBBIT_LUCK]=1, }, copy = { + type = "humanoid", subtype="hobbit", life_rating = 12, default_wilderness = {"wilderness/main", 41, 18}, }, diff --git a/game/modules/tome/data/birth/races/human.lua b/game/modules/tome/data/birth/races/human.lua index 0fcdc247e84279d65c76b7981508e3784287fbcb..47a244156ed1f724e113d17bf271b3894bac6cc8 100644 --- a/game/modules/tome/data/birth/races/human.lua +++ b/game/modules/tome/data/birth/races/human.lua @@ -20,6 +20,9 @@ newBirthDescriptor{ }, talents = {}, experience = 1.0, + copy = { + type = "humanoid", subtype="human", + }, } --------------------------------------------------------- diff --git a/game/modules/tome/data/general/objects/egos/amulets.lua b/game/modules/tome/data/general/objects/egos/amulets.lua index d3e45349b36aaeea600494f25546dd508c36597a..9cbcde650dd68abca624945d52c6ace89bf7b444 100644 --- a/game/modules/tome/data/general/objects/egos/amulets.lua +++ b/game/modules/tome/data/general/objects/egos/amulets.lua @@ -56,3 +56,21 @@ newEntity{ e.wielder.talents_types_mastery[tt] = (10 + rng.mbonus(30, resolvers.current_level, 50)) / 100 end), } +newEntity{ + name = " of greater telepathy", + level_range = {40, 50}, + rarity = 15, + cost = 15, + wielder = { + esp = {all=1}, + }, +} +newEntity{ + name = " of telepathic range", + level_range = {40, 50}, + rarity = 15, + cost = 15, + wielder = { + esp = {range=10}, + }, +} diff --git a/game/modules/tome/data/zones/trollshaws/zone.lua b/game/modules/tome/data/zones/trollshaws/zone.lua index e312827b65448e4db6d561814b1eb762b05766fc..1e64bfae787e5929de86d8a8425b0b0c9d054bf0 100644 --- a/game/modules/tome/data/zones/trollshaws/zone.lua +++ b/game/modules/tome/data/zones/trollshaws/zone.lua @@ -29,6 +29,8 @@ return { class = "engine.generator.object.Random", nb_object = {4, 6}, filters = { {type="potion" }, {type="potion" }, {type="potion" }, {type="scroll" }, {}, {} } +-- nb_object = {400, 600}, +-- filters = { {type="jewelry", subtype="amulet" }, } }, }, levels = diff --git a/ideas/spells.ods b/ideas/spells.ods index 6a0645a0ee65447286922de980654b36ecd11b4a..cc4e805cc25dbfea3d042b446556266f2ea2412e 100644 Binary files a/ideas/spells.ods and b/ideas/spells.ods differ