diff --git a/game/modules/tome/ai/target.lua b/game/modules/tome/ai/target.lua index 246acb38c08266cb25bd199ef1ff236fa86b87e1..e453afdf39d252bc7d108df91292cc89c6483363 100644 --- a/game/modules/tome/ai/target.lua +++ b/game/modules/tome/ai/target.lua @@ -61,6 +61,16 @@ newAI("target_player_radius", function(self) end end) +-- Target the player if within sense radius or if in sight +newAI("target_simple_or_player_radius", function(self) + if self:runAI("target_simple") then return true end + + if core.fov.distance(self.x, self.y, game.player.x, game.player.y) < self.ai_state.sense_radius then + self.ai_target.actor = game.player + return true + end +end) + -- Special targetting for charred scar, select a normal target, if none is found go for the player newAI("charred_scar_target", function(self) if self:runAI("target_simple") then return true end diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index b995b2c977f2fbd65b7ce15eba3ec4a656324d79..69785c54a6a1d9294c91069f7f747b7d1a2b2311 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -722,6 +722,8 @@ function _M:onTakeHit(value, src) end end + if self.on_takehit then value = self:check("on_takehit", value, src) end + return value end diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index a8be69bec940e34a5600fc029650a9bb7aa93aed..6711c851bb02a0fe6738bf59879ee60bbd4aa320 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -686,7 +686,7 @@ function _M:setupCommands() a.faction = "enemies" self.zone:addEntity(self.level, a, "actor", self.player.x+1, self.player.y) --]] --- self.state:generateRandart(false) + self:changeLevel(3, "shadow-crypt") end end, } diff --git a/game/modules/tome/data/achievements/quests.lua b/game/modules/tome/data/achievements/quests.lua index c46ba429e1aae7bddb4de38ed18dc7e99ec66693..6cefb88bf6c6985520a5dd6c153daac2115a2619 100644 --- a/game/modules/tome/data/achievements/quests.lua +++ b/game/modules/tome/data/achievements/quests.lua @@ -137,3 +137,7 @@ newAchievement{ name = "Arachnophobia", id = "SPYDRIC_INFESTATION", desc = [[Destroyed the spydric menace.]], } +newAchievement{ + name = "Clone War", id = "SHADOW_CLONE", + desc = [[Destroyed your own Shade.]], +} diff --git a/game/modules/tome/data/general/encounters/fareast.lua b/game/modules/tome/data/general/encounters/fareast.lua index e2a990ca4c9f00460d249be7f792a1256afc2fd5..e5facc617a3baeadefd78e158f95651f5f83e552 100644 --- a/game/modules/tome/data/general/encounters/fareast.lua +++ b/game/modules/tome/data/general/encounters/fareast.lua @@ -43,3 +43,26 @@ newEntity{ return true end, } + +newEntity{ + name = "Shadow Crypt", + type = "hostile", subtype = "special", unique = true, + level_range = {34, 45}, + rarity = 6, + on_encounter = function(self, who) + local x, y = self:findSpot(who) + if not x then return end + + local g = mod.class.Grid.new{ + show_tooltip=true, + name="Entrance to a dark crypt", + display='>', color=colors.GREY, + notice = true, + change_level=1, change_zone="shadow-crypt" + } + g:resolve() g:resolve(nil, true) + game.zone:addEntity(game.level, g, "terrain", x, y) + game.logPlayer(who, "#LIGHT_BLUE#You notice an entrance to a dark crypt. Fetid wind seems to come out of it.") + return true + end +} diff --git a/game/modules/tome/data/general/npcs/shade.lua b/game/modules/tome/data/general/npcs/shade.lua new file mode 100644 index 0000000000000000000000000000000000000000..0b7767e17523a3e1aac3b57fbb4f59e1b359033b --- /dev/null +++ b/game/modules/tome/data/general/npcs/shade.lua @@ -0,0 +1,109 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +local Talents = require("engine.interface.ActorTalents") + +-- Shades are very special, tehy are not monsters on their own, they are shades of some other monster + +newEntity{ + define_as = "BASE_NPC_SHADE", + type = "undead", subtype = "shade", + display = "G", color=colors.DARK_GREY, + + resolvers.generic(function(e) + local base = game.zone:makeEntity(game.level, "actor", e.shade_filter, nil , true) + while base.unique do base = game.zone:makeEntity(game.level, "actor", e.shade_filter, nil , true) end + + base.color_r = e.color_r + base.color_g = e.color_g + base.color_b = e.color_b + base.desc = e.desc + + e:replaceWith(base) + + -- Make the shade nasty + e.name = "shade of "..e.name + e.can_pass = {pass_wall=70} + e.undead = 1 + e.no_breath = 1 + e.stone_immune = 1 + e.confusion_immune = 1 + e.fear_immune = 1 + e.teleport_immune = 1 + e.disease_immune = 1 + e.poison_immune = 1 + e.stun_immune = 1 + e.blind_immune = 1 + e.see_invisible = 80 + e.max_life = e.max_life * 0.50 + e.life = e.max_life + e.resists.all = 20 + + -- AI + e.ai_state.sense_radius = 6 + e.ai_state.ai_target = "target_simple_or_player_radius" + + -- No escorts + e.make_escort = nil + + -- Remove some talents + local tids = {} + for tid, _ in pairs(e.talents) do tids[#tids+1] = tid end + local nb = math.floor(#tids / 4) + for i = 1, nb do + local tid = rng.tableRemove(tids) + e.talents[tid] = nil + end + + -- Summon shady friends (if possible) + e.summon = { {type="undead", subtype="shade", number=1, hasxp=false}, } + + -- Give some talents + local rtals = { + {tid=e.T_SUMMON, level=1}, + {tid=e.T_DRAIN, level=4}, + {tid=e.T_EMPATHIC_HEX, level=3}, + {tid=e.T_MIND_SEAR, level=4}, + {tid=e.T_VIRULENT_DISEASE, level=4}, + {tid=e.T_CYST_BURST, level=3}, + } + for i = 1, 3 do + local t = rng.tableRemove(rtals) + e.talents[t.tid] = t.level + end + end), +} + +newEntity{ base = "BASE_NPC_SHADE", + rarity = 1, level_range = {30, nil}, + desc = [[Through some terrible process that remains mysterious, this creature shadow has been torn from its body and given unlife.]], + shade_filter = {type="animal", special_rarity="shade_rarity"}, +} + +newEntity{ base = "BASE_NPC_SHADE", + rarity = 1, level_range = {30, nil}, + desc = [[Through some terrible process that remains mysterious, this creature shadow has been torn from its body and given unlife.]], + shade_filter = {type="humanoid", special_rarity="shade_rarity"}, +} + +newEntity{ base = "BASE_NPC_SHADE", + rarity = 1, level_range = {30, nil}, + desc = [[Through some terrible process that remains mysterious, this creature shadow has been torn from its body and given unlife.]], + shade_filter = {type="giant", special_rarity="shade_rarity"}, +} diff --git a/game/modules/tome/data/maps/wilderness/eyal.lua b/game/modules/tome/data/maps/wilderness/eyal.lua index 462d9e0a62958f404105a170217466bbdb3dea81..2ab6295aedf8f3bf9ff32bfb4162ea5ebf00b0e5 100644 --- a/game/modules/tome/data/maps/wilderness/eyal.lua +++ b/game/modules/tome/data/maps/wilderness/eyal.lua @@ -159,6 +159,7 @@ addZone({64, 52, 66, 53}, "zonename", "Tar'Eyal") addZone({11, 87, 16, 94}, "zonename", "Tar'Eyal") addZone({54, 23, 65, 37}, "world-encounter", "lumberjack-cursed") addZone({3, 15, 19, 33}, "world-encounter", "angolwen") +addZone({136, 43, 145, 55}, "world-encounter", "shadow-crypt") -- ASCII map section return { diff --git a/game/modules/tome/data/maps/zones/shadow-crypt-last.lua b/game/modules/tome/data/maps/zones/shadow-crypt-last.lua new file mode 100644 index 0000000000000000000000000000000000000000..5d6ab4a64a58b37de07e0e10e0e19dd04ca238f0 --- /dev/null +++ b/game/modules/tome/data/maps/zones/shadow-crypt-last.lua @@ -0,0 +1,44 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +defineTile('<', "UP") +defineTile("#", "OLD_WALL") +defineTile(".", "FLOOR") +defineTile("@", "FLOOR", nil, "CULTIST_RAK_SHOR") + +startx = 7 +starty = 13 + +-- ASCII map section +return [[ +############### +##...........## +#.............# +#..##.....##..# +#..##.....##..# +#.............# +#......@......# +#.............# +#.............# +#.............# +#..##.....##..# +#..##.....##..# +#.............# +##...........## +###############]] diff --git a/game/modules/tome/data/talents/corruptions/hexes.lua b/game/modules/tome/data/talents/corruptions/hexes.lua index 6cf4149fc97ef15702d58fe64f7be8bec2a7674a..a518dde71d30f69b13413350925f2ebd73d69405 100644 --- a/game/modules/tome/data/talents/corruptions/hexes.lua +++ b/game/modules/tome/data/talents/corruptions/hexes.lua @@ -115,6 +115,7 @@ newTalent{ cooldown = 20, vim = 30, range = 30, + no_npc_use = true, direct_hit = true, requires_target = true, action = function(self, t) diff --git a/game/modules/tome/data/talents/divine/twilight.lua b/game/modules/tome/data/talents/divine/twilight.lua index 4b631ac31f321468163e059afe8c7699b0d12758..6308210a8f9c75960f66b53de9a7d529ecae69cb 100644 --- a/game/modules/tome/data/talents/divine/twilight.lua +++ b/game/modules/tome/data/talents/divine/twilight.lua @@ -50,6 +50,7 @@ newTalent{ MOVE = 10, }, range = 20, + no_npc_use = true, action = function(self, t) local eff = self.sustain_talents[self.T_JUMPGATE] if not eff then @@ -80,6 +81,7 @@ newTalent{ points = 5, cooldown = 20, negative_sustain = 20, + no_npc_use = true, tactical = { MOVE = 10, }, @@ -156,6 +158,7 @@ newTalent{ }, requires_target = true, range = 10, + no_npc_use = true, action = function(self, t) local tg = {type="bolt", range=self:getTalentRange(t), talent=t} local tx, ty, target = self:getTarget(tg) diff --git a/game/modules/tome/data/talents/gifts/call.lua b/game/modules/tome/data/talents/gifts/call.lua index 46248a1d4192473d1c572b4ee0671bb4d56ed7c4..8340f37515dca56ed22ad11baf10eb856a934139 100644 --- a/game/modules/tome/data/talents/gifts/call.lua +++ b/game/modules/tome/data/talents/gifts/call.lua @@ -25,6 +25,7 @@ newTalent{ message = "@Source@ meditates on nature.", cooldown = 150, range = 20, + no_npc_use = true, action = function(self, t) local seen = false -- Check for visible monsters, only see LOS actors, so telepathy wont prevent it @@ -89,6 +90,7 @@ newTalent{ short_name = "NATURE_TOUCH", cooldown = 20, range = 1, requires_target = true, + no_npc_use = true, action = function(self, t) local tg = {default_target=self, type="hit", nowarning=true, range=self:getTalentRange(t), first_target="friend"} local x, y, target = self:getTarget(tg) @@ -117,6 +119,7 @@ newTalent{ cooldown = 10, range = 100, requires_target = true, + no_npc_use = true, action = function(self, t) local x, y = self:getTarget{type="ball", nolock=true, no_restrict=true, nowarning=true, range=100, radius=math.ceil(3 + self:getTalentLevel(t))} if not x then return nil end diff --git a/game/modules/tome/data/talents/gifts/sand-drake.lua b/game/modules/tome/data/talents/gifts/sand-drake.lua index 116b748975deb38f8d46a4e1fcbcaa791152c5be..a2d6b810104f512b8bfe45cf8340032e0a626044 100644 --- a/game/modules/tome/data/talents/gifts/sand-drake.lua +++ b/game/modules/tome/data/talents/gifts/sand-drake.lua @@ -30,6 +30,7 @@ newTalent{ ATTACK = 10, }, requires_target = true, + no_npc_use = true, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t)} local x, y, target = self:getTarget(tg) @@ -68,6 +69,7 @@ newTalent{ ATTACKAREA = 10, }, range = 20, + no_npc_use = true, action = function(self, t) local tg = {type="ball", range=0, friendlyfire=false, radius=2 + self:getTalentLevel(t) / 2, talent=t, no_restrict=true} self:project(tg, self.x, self.y, DamageType.PHYSKNOCKBACK, {dam=self:combatDamage() * 0.8, dist=4}) diff --git a/game/modules/tome/data/talents/gifts/summon-utility.lua b/game/modules/tome/data/talents/gifts/summon-utility.lua index 68bd07774a3e8753912a12883fe15f7fba73587a..bba3113a4c347f347b107dfafcddd75b87d97b34 100644 --- a/game/modules/tome/data/talents/gifts/summon-utility.lua +++ b/game/modules/tome/data/talents/gifts/summon-utility.lua @@ -323,6 +323,7 @@ newTalent{ cooldown = 10, range = 20, requires_target = true, + no_npc_use = true, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t), nolock=true, talent=t, first_target="friend"} local tx, ty, target = self:getTarget(tg) diff --git a/game/modules/tome/data/talents/misc/misc.lua b/game/modules/tome/data/talents/misc/misc.lua index e11c59043fba002538d9f28e1b275961cfc52039..9bca9d9fac337a68139f4e69238408dab1d0c021 100644 --- a/game/modules/tome/data/talents/misc/misc.lua +++ b/game/modules/tome/data/talents/misc/misc.lua @@ -125,6 +125,7 @@ newTalent{ name = "Teleport: Angolwen", type = {"base/class", 1}, cooldown = 1000, + no_npc_use = true, no_silence=true, is_spell=true, action = function(self, t) if not self:canBe("worldport") then diff --git a/game/modules/tome/data/talents/spells/advanced-golemancy.lua b/game/modules/tome/data/talents/spells/advanced-golemancy.lua index 30d84ac37c91b5804b8e3e126d78a58ba1fb40d0..b6627731c0bfb629da81cd73f914050f0d321d98 100644 --- a/game/modules/tome/data/talents/spells/advanced-golemancy.lua +++ b/game/modules/tome/data/talents/spells/advanced-golemancy.lua @@ -66,6 +66,7 @@ newTalent{ range = 10, mana = 5, requires_target = true, + no_npc_use = true, action = function(self, t) local mover, golem = getGolem(self) if not golem then @@ -119,6 +120,7 @@ newTalent{ points = 5, mana = 40, cooldown = 60, + no_npc_use = true, action = function(self, t) local mover, golem = getGolem(self) if not golem then diff --git a/game/modules/tome/data/talents/spells/divination.lua b/game/modules/tome/data/talents/spells/divination.lua index f5ae4aed45b1eb13f27e38daec27d666220672df..04ab9cec537aed04a1f0c69ce0f22e033117c970 100644 --- a/game/modules/tome/data/talents/spells/divination.lua +++ b/game/modules/tome/data/talents/spells/divination.lua @@ -58,6 +58,7 @@ newTalent{ mana = 15, cooldown = 10, no_energy = true, + no_npc_use = true, action = function(self, t) local tg = {type="hit", nolock=true, pass_terrain=true, nowarning=true, range=100, requires_knowledge=false} x, y = self:getTarget(tg) @@ -92,6 +93,7 @@ newTalent{ random_ego = "utility", mana = 20, cooldown = 20, + no_npc_use = true, action = function(self, t) self:magicMap(5 + self:combatTalentSpellDamage(t, 2, 12)) game:playSoundNear(self, "talents/spell_generic") diff --git a/game/modules/tome/data/talents/spells/golemancy.lua b/game/modules/tome/data/talents/spells/golemancy.lua index 55bb8bbb0a8d9d7e29d7b2422def3f4c5ee60c27..cf12d3fe13b98c66d455149ec29a1ee65f23c2a5 100644 --- a/game/modules/tome/data/talents/spells/golemancy.lua +++ b/game/modules/tome/data/talents/spells/golemancy.lua @@ -76,6 +76,7 @@ newTalent{ points = 1, cooldown = 20, mana = 10, + no_npc_use = true, action = function(self, t) if not self.alchemy_golem then self.alchemy_golem = game.zone:finishEntity(game.level, "actor", makeGolem()) @@ -173,6 +174,7 @@ newTalent{ range = 10, mana = 5, requires_target = true, + no_npc_use = true, action = function(self, t) local mover, golem = getGolem(self) if not golem then @@ -207,6 +209,7 @@ newTalent{ range = 10, mana = 5, requires_target = true, + no_npc_use = true, action = function(self, t) local mover, golem = getGolem(self) if not golem then @@ -264,6 +267,7 @@ newTalent{ range = 10, mana = 5, requires_target = true, + no_npc_use = true, action = function(self, t) local mover, golem = getGolem(self) if not golem then @@ -319,6 +323,7 @@ newTalent{ points = 5, mana = 10, cooldown = 20, + no_npc_use = true, action = function(self, t) local mover, golem = getGolem(self) if not golem then diff --git a/game/modules/tome/data/talents/spells/stone-alchemy.lua b/game/modules/tome/data/talents/spells/stone-alchemy.lua index 37f99fa3d799d38ce28c6b1d2e836e274b04565b..1069044f10a4c3df46fff19a3f87f5b4e03247f8 100644 --- a/game/modules/tome/data/talents/spells/stone-alchemy.lua +++ b/game/modules/tome/data/talents/spells/stone-alchemy.lua @@ -26,6 +26,7 @@ newTalent{ return math.ceil(5 + self:getDex(12)) end, mana = 30, + no_npc_use = true, make_gem = function(self, t, base_define) local nb = rng.range(40, 80) local gem = game.zone:makeEntityByName(game.level, "object", "ALCHEMIST_" .. base_define) @@ -63,6 +64,7 @@ newTalent{ points = 5, mana = 5, cooldown = 20, + no_npc_use = true, action = function(self, t) self:showEquipInven("Try to extract gems from which metallic item?", function(o) return o.metallic and (o.material_level or 1) <= self:getTalentLevelRaw(t) end, function(o, inven, item) self:removeObject(inven, item) @@ -89,6 +91,7 @@ newTalent{ points = 5, mana = 80, cooldown = 100, + no_npc_use = true, action = function(self, t) self:showInventory("Use which gem?", self:getInven("INVEN"), function(gem) return gem.type == "gem" and gem.material_level <= self:getTalentLevelRaw(t) end, function(gem, gem_item) self:showInventory("Imbue which armour?", self:getInven("INVEN"), function(o) return o.type == "armor" and o.slot == "BODY" and not o.been_imbued end, function(o, item) @@ -115,6 +118,7 @@ newTalent{ mana = 20, points = 5, range = 1, + no_npc_use = true, action = function(self, t) local ammo = self:hasAlchemistWeapon() if not ammo or ammo:getNumber() < 5 then diff --git a/game/modules/tome/data/talents/techniques/archery.lua b/game/modules/tome/data/talents/techniques/archery.lua index bb84c820d18e88f318b471f4d8a61094c25628d9..9a1c58112410c7b72cf2179303efe41541f76fef 100644 --- a/game/modules/tome/data/talents/techniques/archery.lua +++ b/game/modules/tome/data/talents/techniques/archery.lua @@ -168,6 +168,7 @@ newTalent{ cooldown = 30, sustain_stamina = 30, require = techs_dex_req1, + no_npc_use = true, on_kill = function(self, t, who) -- Can not work without a correct weapon if not self:getInven("MAINHAND") then return nil end diff --git a/game/modules/tome/data/zones/shadow-crypt/grids.lua b/game/modules/tome/data/zones/shadow-crypt/grids.lua new file mode 100644 index 0000000000000000000000000000000000000000..5f504c70426ef0b378fb8b03740dfb1efcffd4cb --- /dev/null +++ b/game/modules/tome/data/zones/shadow-crypt/grids.lua @@ -0,0 +1,28 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +load("/data/general/grids/basic.lua") + +newEntity{ + define_as = "QUICK_EXIT", + name = "teleporting circle to the surface", image = "terrain/maze_teleport.png", + display = '>', color_r=255, color_g=0, color_b=255, + notice = true, show_tooltip = true, + change_level = 1, change_zone = "wilderness", +} diff --git a/game/modules/tome/data/zones/shadow-crypt/npcs.lua b/game/modules/tome/data/zones/shadow-crypt/npcs.lua new file mode 100644 index 0000000000000000000000000000000000000000..3df9b30d70acd53616ce05512e9681ff12d083c8 --- /dev/null +++ b/game/modules/tome/data/zones/shadow-crypt/npcs.lua @@ -0,0 +1,117 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +load("/data/general/npcs/shade.lua", rarity(0)) +load("/data/general/npcs/orc-rak-shor.lua", rarity(10)) + +load("/data/general/npcs/all.lua", function(e) if e.rarity then e.shade_rarity, e.rarity = e.rarity, nil end end) + +local Talents = require("engine.interface.ActorTalents") + +newEntity{ base="BASE_NPC_ORC_RAK_SHOR", define_as = "CULTIST_RAK_SHOR", + name = "Rak'Shor Cultist", color=colors.VIOLET, unique = true, + desc = [[An old orc, wearing black robes. He seems to be responsable for the creation of the shades.]], + level_range = {35, 50}, exp_worth = 2, + rank = 4, + max_life = 150, life_rating = 17, fixed_rating = true, + infravision = 20, + stats = { str=15, dex=10, cun=42, mag=16, con=14 }, + move_others=true, + + instakill_immune = 1, + disease_immune = 1, + confusion_immune = 1, + combat_armor = 10, combat_def = 10, + + open_door = true, + + autolevel = "caster", + ai = "dumb_talented_simple", ai_state = { talent_in=1, ai_move="move_astar", }, + + body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, + + resolvers.equip{ + {type="weapon", subtype="staff", ego_change=100, autoreq=true}, + }, + resolvers.drops{chance=20, nb=1, {defined="JEWELER_TOME"} }, + resolvers.drops{chance=100, nb=1, {unique=true} }, + resolvers.drops{chance=100, nb=5, {ego_chance=100} }, + + inc_damage = {[DamageType.BLIGHT] = -30}, + + resolvers.talents{ + [Talents.T_SOUL_ROT]=5, + [Talents.T_BLOOD_GRASP]=5, + [Talents.T_BONE_SHIELD]=5, + [Talents.T_EVASION]=5, + [Talents.T_VIRULENT_DISEASE]=5, + [Talents.T_CYST_BURST]=3, + [Talents.T_EPIDEMIC]=4, + }, + resolvers.sustains_at_birth(), + + on_takehit = function(self, value, src) + -- When the bone shield is taken down, copy the player + if not self:isTalentActive(self.T_BONE_SHIELD) and not self.copied_player then + local a = mod.class.NPC.new{} + a:replaceWith(game.player:cloneFull()) + mod.class.NPC.castAs(a) + engine.interface.ActorAI.init(a, a) + a.no_drops = true + a.energy.value = 0 + a.player = nil + a.rank = 4 + a.name = "Shade of "..a.name + a.color_r = 150 a.color_g = 150 a.color_b = 150 + a._mo:invalidate() + a.ai = "dumb_talented_simple" + a.ai_state = {talent_in=1} + a.faction = self.faction + a.inc_damage.all = (a.inc_damage.all or 0) - 40 + a.max_life = a.max_life * 1.8 + a.life = a.max_life + a.on_die = function(self) + world:gainAchievement("SHADOW_CLONE", game.player) + game.level.map(self.x, self.y, game.level.map.TERRAIN, game.zone.grid_list.UP_WILDERNESS) + game.logSeen(who, "As your shade dies the magical veil protecting the stairs out vanishes.") + end + + -- Remove some talents + local tids = {} + for tid, _ in pairs(a.talents) do + local t = a:getTalentFromId(tid) + if t.no_npc_use then tids[#tids+1] = t end + end + for i, t in ipairs(tids) do + if t.mode == "sustained" and a:isTalentActive(t.id) then a:forceUseTalent(t.id, {ignore_energy=true}) end + a.talents[t.id] = nil + end + + local x, y = util.findFreeGrid(self.x, self.y, 10, true, {[engine.Map.ACTOR]=true}) + if x and y then + game.zone:addEntity(game.level, a, "actor", x, y) + + game.logPlayer(game.player, "#GREY#The cultist looks deep in your eyes, you feel torn apart!") + self:doEmote("Ra'kk kor merk ZUR!!!", 120) + self.copied_player = true + end + end + return value + end, +} diff --git a/game/modules/tome/data/zones/shadow-crypt/objects.lua b/game/modules/tome/data/zones/shadow-crypt/objects.lua new file mode 100644 index 0000000000000000000000000000000000000000..a33c64687278e94e10f6e24a67d60789a7be4aec --- /dev/null +++ b/game/modules/tome/data/zones/shadow-crypt/objects.lua @@ -0,0 +1,21 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +load("/data/general/objects/objects.lua") +load("/data/general/objects/objects-far-east.lua") diff --git a/game/modules/tome/data/zones/shadow-crypt/traps.lua b/game/modules/tome/data/zones/shadow-crypt/traps.lua new file mode 100644 index 0000000000000000000000000000000000000000..f8f844f583d30b1999a9bf7a520221cdebdfa557 --- /dev/null +++ b/game/modules/tome/data/zones/shadow-crypt/traps.lua @@ -0,0 +1,20 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +load("/data/general/traps/elemental.lua") diff --git a/game/modules/tome/data/zones/shadow-crypt/zone.lua b/game/modules/tome/data/zones/shadow-crypt/zone.lua new file mode 100644 index 0000000000000000000000000000000000000000..63a7b6f4a394f28f043afbc4e0589f38c0269f92 --- /dev/null +++ b/game/modules/tome/data/zones/shadow-crypt/zone.lua @@ -0,0 +1,81 @@ +-- ToME - Tales of Maj'Eyal +-- Copyright (C) 2009, 2010 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +return { + name = "Shadow Crypt", + level_range = {34,45}, + level_scheme = "player", + max_level = 3, + decay = {300, 800}, + actor_adjust_level = function(zone, level, e) return zone.base_level + e:getRankLevelAdjust() + level.level-1 + rng.range(-1,2) end, + width = 50, height = 50, +-- all_remembered = true, +-- all_lited = true, + persistant = "zone", + color_shown = {0.6, 0.6, 0.6, 1}, + color_obscure = {0.6*0.6, 0.6*0.6, 0.6*0.6, 1}, + ambiant_music = "Anne_van_Schothorst_-_Passed_Tense.ogg", + generator = { + map = { + class = "engine.generator.map.TileSet", + tileset = {"3x3/base", "3x3/tunnel", "3x3/windy_tunnel"}, + tunnel_chance = 100, + ['.'] = "OLD_FLOOR", + ['#'] = {"OLD_WALL","WALL","WALL","WALL","WALL"}, + ['+'] = "DOOR", + ["'"] = "DOOR", + up = "UP", + down = "DOWN", + }, + actor = { + class = "engine.generator.actor.Random", + nb_npc = {20, 20}, +-- guardian = "CULTIST_RAK_SHOR", + }, + object = { + class = "engine.generator.object.Random", + nb_object = {6, 9}, + }, + trap = { + class = "engine.generator.trap.Random", + nb_trap = {6, 9}, + }, + }, + levels = + { + [1] = { + generator = { map = { + up = "UP_WILDERNESS_FAREAST", + }, }, + }, + [3] = { + all_remembered = true, + all_lited = true, + generator = { + map = { + class = "engine.generator.map.Static", + map = "zones/shadow-crypt-last", + }, + actor = { nb_npc = {0, 0}, }, + object = { nb_object = {0, 0}, }, + trap = { nb_trap = {0, 0}, }, + }, + }, + }, +} diff --git a/game/modules/tome/data/zones/temple-of-creation/objects.lua b/game/modules/tome/data/zones/temple-of-creation/objects.lua index 3532ab339b8ba84ac70248d7407c587ae30173d0..a024ecaf4ff008ba8a5e887b9000e8073b9f09e5 100644 --- a/game/modules/tome/data/zones/temple-of-creation/objects.lua +++ b/game/modules/tome/data/zones/temple-of-creation/objects.lua @@ -26,7 +26,7 @@ local DamageType = require "engine.DamageType" newEntity{ base = "BASE_LITE", define_as = "ELDRITCH_PEARL", - name = "", unique=true, + name = "Eldritch Pearl", unique=true, display ='*', color = colors.AQUAMARINE, desc = [[Thousands of years spent inside the temple of creation have infused this pearl with the fury of rushing water. It pulses light.]], diff --git a/ideas/quests.ods b/ideas/quests.ods index fc4619a754e986daf9c162570300d748f125c159..20f4b6bce7c4b6f81999553514817327550183ac 100644 Binary files a/ideas/quests.ods and b/ideas/quests.ods differ diff --git a/ideas/zones.ods b/ideas/zones.ods index 15d2050c4f2cd3332f3f1a888dc9757f7a4ef148..b031cb228d72ad6c9fcd40f8bfce61aa9fb2407e 100644 Binary files a/ideas/zones.ods and b/ideas/zones.ods differ diff --git a/tiled-maps/eyal.tmx b/tiled-maps/eyal.tmx index 3265ef23e7f5904a3e7751641862db7a816464ef..73078eedae789537e53cb0449360df7a1d6a8111 100644 --- a/tiled-maps/eyal.tmx +++ b/tiled-maps/eyal.tmx @@ -541,5 +541,11 @@ <property name="type" value=""world-encounter""/> </properties> </object> + <object name="Shadow crypt" x="4357" y="1381" width="284" height="407"> + <properties> + <property name="subtype" value=""shadow-crypt""/> + <property name="type" value=""world-encounter""/> + </properties> + </object> </objectgroup> </map>