diff --git a/game/modules/tome/data/autolevel_schemes.lua b/game/modules/tome/data/autolevel_schemes.lua index 69a382be93598727f3bd5d1dcf8f1ac0e1f9a868..e3b7ae6a7d704ab09b70b6e5bb559ea7b534c978 100644 --- a/game/modules/tome/data/autolevel_schemes.lua +++ b/game/modules/tome/data/autolevel_schemes.lua @@ -14,9 +14,9 @@ Autolevel:registerScheme{ name = "warrior", levelup = function(self) learnStats(self, { self.STAT_STR, self.STAT_STR, self.STAT_DEX }) end} -Autolevel:registerScheme{ name = "warrior", levelup = function(self) - -- 2 STR for 1 DEX - learnStats(self, { self.STAT_STR, self.STAT_STR, self.STAT_DEX }) +Autolevel:registerScheme{ name = "ghoul", levelup = function(self) + -- 1 STR for 1 CON, 1 nothing + learnStats(self, { self.STAT_STR, self.STAT_CON }) end} Autolevel:registerScheme{ name = "rogue", levelup = function(self) diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index f14343741c9abcbd36ed9f511ff21afb25cff35a..8d34bfebf9e00eea5882fc27c6ecaa58cb99ef13 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -71,9 +71,15 @@ newDamageType{ end end, } + +-- Nature & Blight: Opposing damage types newDamageType{ name = "nature", type = "NATURE", } +newDamageType{ + name = "blight", type = "BLIGHT", +} + newDamageType{ name = "lightning", type = "LIGHTNING", projector = function(src, x, y, type, dam) diff --git a/game/modules/tome/data/general/npcs/ghoul.lua b/game/modules/tome/data/general/npcs/ghoul.lua new file mode 100644 index 0000000000000000000000000000000000000000..b6de65d2f2007a6cc3a9a2d18fdee6b8d81bb029 --- /dev/null +++ b/game/modules/tome/data/general/npcs/ghoul.lua @@ -0,0 +1,72 @@ +local Talents = require("engine.interface.ActorTalents") + +newEntity{ + define_as = "BASE_NPC_GHOUL", + type = "undead", subtype = "ghoul", + display = "z", color=colors.WHITE, + + combat = { dam=1, atk=1, apr=1 }, + + body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 }, + drops = resolvers.drops{chance=70, nb=1, {type="money"}, {} }, + autolevel = "ghoul", + ai = "dumb_talented_simple", ai_state = { talent_in=4, }, + energy = { mod=1 }, + stats = { str=14, dex=12, mag=10, con=12 }, + + tmasteries = resolvers.tmasteries{ ["technique/other"]=0.3, }, + + blind_immune = 1, + see_invisible = 2, + undead = 1, +} + +newEntity{ base = "BASE_NPC_GHOUL", + name = "ghoul", color=colors.TAN, + desc = [[Flesh is falling off in chunks from this decaying abomination.]], + level_range = {7, 50}, exp_worth = 1, + rarity = 5, + max_life = resolvers.rngavg(90,100), + combat_armor = 2, combat_def = 7, + talents = resolvers.talents{ [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=1, [Talents.T_BITE_POISON]=1, [Talents.T_ROTTING_DISEASE]=1, }, + ai_state = { talent_in=4, }, + + combat = { dam=5, atk=5, apr=3, dammod={str=0.6} }, +} + +newEntity{ base = "BASE_NPC_GHOUL", + name = "ghast", color=colors.UMBER, + desc = [[This vile abomination is a relative of ghouls, and often leads packs of them. It smells foul, and its bite carries a rotting disease.]], + level_range = {10, 50}, exp_worth = 1, + rarity = 7, + max_life = resolvers.rngavg(90,100), + combat_armor = 2, combat_def = 8, + ai_state = { talent_in=3, }, + + combat = { dam=7, atk=6, apr=3, dammod={str=0.6} }, + + summon = {{type="undead", subtype="ghoul", name="ghoul", number=1, hasxp=true}, }, + talents = resolvers.talents{ [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=2, [Talents.T_BITE_POISON]=2, [Talents.T_SUMMON]=1, [Talents.T_ROTTING_DISEASE]=2, [Talents.T_DECREPITUDE_DISEASE]=2, }, +} + +newEntity{ base = "BASE_NPC_GHOUL", + name = "ghoulking", color={0,0,0}, + desc = [[Stench rises from this rotting abomination, its brow is adorned with gold, and it moves at you with hatred gleaming from its eyes.]], + level_range = {15, 50}, exp_worth = 1, + rarity = 10, + max_life = resolvers.rngavg(90,100), + combat_armor = 3, combat_def = 10, + ai_state = { talent_in=2, }, + + combat = { dam=10, atk=8, apr=4, dammod={str=0.6} }, + + summon = { + {type="undead", subtype="ghoul", name="ghoul", number=1, hasxp=true}, + {type="undead", subtype="ghoul", name="ghast", number=1, hasxp=true}, + }, + + talents = resolvers.talents{ + [Talents.T_STAMINA_POOL]=1, [Talents.T_STUN]=3, [Talents.T_BITE_POISON]=3, [Talents.T_SUMMON]=1, + [Talents.T_ROTTING_DISEASE]=4, [Talents.T_DECREPITUDE_DISEASE]=3, [Talents.T_WEAKNESS_DISEASE]=3, + }, +} diff --git a/game/modules/tome/data/talents/misc/npcs.lua b/game/modules/tome/data/talents/misc/npcs.lua index 93e1892b9fd39a0f0ff661304f5718a9e0dc4054..e933f28d8f3dc7ed29658b2c59c65581a80999b2 100644 --- a/game/modules/tome/data/talents/misc/npcs.lua +++ b/game/modules/tome/data/talents/misc/npcs.lua @@ -244,3 +244,90 @@ newTalent{ return ([[Summon allies.]]) end, } + +newTalent{ + name = "Rotting Disease", + type = {"technique/other", 1}, + points = 5, + cooldown = 8, + message = "@Source@ diseases @target@.", + action = function(self, t) + local tg = {type="hit", range=self:getTalentRange(t)} + local x, y, target = self:getTarget(tg) + if not x or not y or not target then return nil end + if math.floor(core.fov.distance(self.x, self.y, x, y)) > 1 then return nil end + local hit = self:attackTarget(target, nil, 0.5 + self:getTalentLevel(t) / 10, true) + + -- Try to rot ! + if hit then + if target:checkHit(self:combatAttackStr(), target:combatPhysicalResist(), 0, 95, 5 - self:getTalentLevel(t) / 2) then + target:setEffect(target.EFF_ROTTING_DISEASE, 10 + self:getTalentLevel(t) * 3, {src=self, dam=self:getStr() / 3 + self:getTalentLevel(t) * 2, con=math.floor(4 + target:getCon() * 0.1)}) + else + game.logSeen(target, "%s resists the disease!", target.name:capitalize()) + end + end + + return true + end, + info = function(self, t) + return ([[Hits the target doing %d%% damage, if the atatck hits, the target is diseased.]]):format(100 * (0.5 + self:getTalentLevel(t) / 10)) + end, +} + +newTalent{ + name = "Decrepitude Disease", + type = {"technique/other", 1}, + points = 5, + cooldown = 8, + message = "@Source@ diseases @target@.", + action = function(self, t) + local tg = {type="hit", range=self:getTalentRange(t)} + local x, y, target = self:getTarget(tg) + if not x or not y or not target then return nil end + if math.floor(core.fov.distance(self.x, self.y, x, y)) > 1 then return nil end + local hit = self:attackTarget(target, nil, 0.5 + self:getTalentLevel(t) / 10, true) + + -- Try to rot ! + if hit then + if target:checkHit(self:combatAttackStr(), target:combatPhysicalResist(), 0, 95, 5 - self:getTalentLevel(t) / 2) then + target:setEffect(target.EFF_DECREPITUDE_DISEASE, 10 + self:getTalentLevel(t) * 3, {src=self, dam=self:getStr() / 3 + self:getTalentLevel(t) * 2, dex=math.floor(4 + target:getDex() * 0.1)}) + else + game.logSeen(target, "%s resists the disease!", target.name:capitalize()) + end + end + + return true + end, + info = function(self, t) + return ([[Hits the target doing %d%% damage, if the atatck hits, the target is diseased.]]):format(100 * (0.5 + self:getTalentLevel(t) / 10)) + end, +} + +newTalent{ + name = "Weakness Disease", + type = {"technique/other", 1}, + points = 5, + cooldown = 8, + message = "@Source@ diseases @target@.", + action = function(self, t) + local tg = {type="hit", range=self:getTalentRange(t)} + local x, y, target = self:getTarget(tg) + if not x or not y or not target then return nil end + if math.floor(core.fov.distance(self.x, self.y, x, y)) > 1 then return nil end + local hit = self:attackTarget(target, nil, 0.5 + self:getTalentLevel(t) / 10, true) + + -- Try to rot ! + if hit then + if target:checkHit(self:combatAttackStr(), target:combatPhysicalResist(), 0, 95, 5 - self:getTalentLevel(t) / 2) then + target:setEffect(target.EFF_WEAKNESS_DISEASE, 10 + self:getTalentLevel(t) * 3, {src=self, dam=self:getStr() / 3 + self:getTalentLevel(t) * 2, str=math.floor(4 + target:getStr() * 0.1)}) + else + game.logSeen(target, "%s resists the disease!", target.name:capitalize()) + end + end + + return true + end, + info = function(self, t) + return ([[Hits the target doing %d%% damage, if the atatck hits, the target is diseased.]]):format(100 * (0.5 + self:getTalentLevel(t) / 10)) + end, +} diff --git a/game/modules/tome/data/timed_effects.lua b/game/modules/tome/data/timed_effects.lua index a9cb19c4689aa28ec59c583b9547a797820df25f..c8967d2b72ed30afad6b16e3d7bdd054c235168d 100644 --- a/game/modules/tome/data/timed_effects.lua +++ b/game/modules/tome/data/timed_effects.lua @@ -61,7 +61,7 @@ newEffect{ newEffect{ name = "POISONED", desc = "Poisoned", - type = "magical", + type = "poison", status = "detrimental", parameters = { power=10 }, on_gain = function(self, err) return "#Target# is poisoned!", "+Poison" end, @@ -277,7 +277,7 @@ newEffect{ newEffect{ name = "TIME_PRISON", desc = "Time Prison", - type = "other", + type = "other", -- Type "other" so that nothing can dispel it status = "detrimental", parameters = {}, on_gain = function(self, err) return "#Target# is removed from time!", "+Out of Time" end, @@ -322,7 +322,7 @@ newEffect{ status = "beneficial", parameters = { power=1 }, activate = function(self, eff) - eff.stat = self:addTemporaryValue("stats", + eff.stat = self:addTemporaryValue("inc_stats", { [Stats.STAT_STR] = eff.power, [Stats.STAT_DEX] = eff.power, @@ -333,14 +333,14 @@ newEffect{ }) end, deactivate = function(self, eff) - self:removeTemporaryValue("stats", eff.stat) + self:removeTemporaryValue("inc_stats", eff.stat) end, } newEffect{ name = "TIME_SHIELD", desc = "Time Shield", - type = "time", + type = "time", -- Type "time" so that very little should be able to dispel it status = "beneficial", parameters = { power=10 }, on_gain = function(self, err) return "The very fabric of time alters around #target#.", "+Time Shield" end, @@ -434,3 +434,87 @@ newEffect{ self:removeTemporaryValue("combat_atk", eff.tmpid) end, } + +newEffect{ + name = "ROTTING_DISEASE", + desc = "Rotting Disease", + type = "disease", + status = "detrimental", + parameters = {}, + on_gain = function(self, err) return "#Target# is afflicted by a rotting disease!" end, + on_lose = function(self, err) return "#Target# is free from the rotting disease." end, + -- Damage each turn + on_timeout = function(self, eff) + DamageType:get(DamageType.BLIGHT).projector(eff.src, self.x, self.y, DamageType.BLIGHT, eff.power) + end, + -- Lost of CON + activate = function(self, eff) + eff.tmpid = self:addTemporaryValue("inc_stats", {[Stats.STAT_CON] = eff.con}) + end, + deactivate = function(self, eff) + self:removeTemporaryValue("inc_stats", eff.tmpid) + end, +} + +newEffect{ + name = "ROTTING_DISEASE", + desc = "Rotting Disease", + type = "disease", + status = "detrimental", + parameters = {}, + on_gain = function(self, err) return "#Target# is afflicted by a rotting disease!" end, + on_lose = function(self, err) return "#Target# is free from the rotting disease." end, + -- Damage each turn + on_timeout = function(self, eff) + DamageType:get(DamageType.BLIGHT).projector(eff.src, self.x, self.y, DamageType.BLIGHT, eff.dam) + end, + -- Lost of CON + activate = function(self, eff) + eff.tmpid = self:addTemporaryValue("inc_stats", {[Stats.STAT_CON] = -eff.con}) + end, + deactivate = function(self, eff) + self:removeTemporaryValue("inc_stats", eff.tmpid) + end, +} + +newEffect{ + name = "DECREPITUDE_DISEASE", + desc = "Decrepitude Disease", + type = "disease", + status = "detrimental", + parameters = {}, + on_gain = function(self, err) return "#Target# is afflicted by a decrepitude disease!" end, + on_lose = function(self, err) return "#Target# is free from the decrepitude disease." end, + -- Damage each turn + on_timeout = function(self, eff) + DamageType:get(DamageType.BLIGHT).projector(eff.src, self.x, self.y, DamageType.BLIGHT, eff.dam) + end, + -- Lost of CON + activate = function(self, eff) + eff.tmpid = self:addTemporaryValue("inc_stats", {[Stats.STAT_DEX] = -eff.dex}) + end, + deactivate = function(self, eff) + self:removeTemporaryValue("inc_stats", eff.tmpid) + end, +} + +newEffect{ + name = "WEAKNESS_DISEASE", + desc = "Weakness Disease", + type = "disease", + status = "detrimental", + parameters = {}, + on_gain = function(self, err) return "#Target# is afflicted by a weakness disease!" end, + on_lose = function(self, err) return "#Target# is free from the weakness disease." end, + -- Damage each turn + on_timeout = function(self, eff) + DamageType:get(DamageType.BLIGHT).projector(eff.src, self.x, self.y, DamageType.BLIGHT, eff.dam) + end, + -- Lost of CON + activate = function(self, eff) + eff.tmpid = self:addTemporaryValue("inc_stats", {[Stats.STAT_STR] = -eff.str}) + end, + deactivate = function(self, eff) + self:removeTemporaryValue("inc_stats", eff.tmpid) + end, +} diff --git a/game/modules/tome/data/zones/tol-falas/npcs.lua b/game/modules/tome/data/zones/tol-falas/npcs.lua index 9d7a2ddcc286683056f8a65fc5802d6be182efa8..47eaf02d6b33fe537641aa964c1ded4b4af9b911 100644 --- a/game/modules/tome/data/zones/tol-falas/npcs.lua +++ b/game/modules/tome/data/zones/tol-falas/npcs.lua @@ -1,5 +1,5 @@ load("/data/general/npcs/skeleton.lua") -load("/data/general/npcs/snake.lua") +load("/data/general/npcs/ghoul.lua") local Talents = require("engine.interface.ActorTalents")