-- Phantoms, for Tales of Maj'Eyal -- -- 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 . local dd = Talents.damDesc local map = require 'engine.Map' local damage_type = require 'engine.DamageType' local particles = require 'engine.Particles' newTalentType { type = 'cursed/horror', name = 'Horror', description = 'Call upon your dark masters to shatter the minds of those in your way.', allow_random = true,} local make_require = function(tier) return { stat = {wil = function(level) return 2 + tier * 8 + level * 2 end,}, level = function(level) return -5 + tier * 4 + level end,} end newTalent{ name = "Master of Terror", shortname = "MASTER_TERROR", type = {"cursed/horror", 1}, points = 5, mode = "passive", require = make_require(1), on_learn = function(self, t) local lev = self:getTalentLevelRaw(t) if lev == 1 then self:learnTalent((self.T_INSTILL_FEAR), true, nil, {no_unlearn=true}) elseif lev == 2 then self:learnTalent((self.T_INSTILL_FEAR), true, nil, {no_unlearn=true}) elseif lev == 3 then self:learnTalent((self.T_INSTILL_FEAR), true, nil, {no_unlearn=true}) elseif lev == 4 then self:learnTalent((self.T_INSTILL_FEAR), true, nil, {no_unlearn=true}) elseif lev == 5 then self:learnTalent((self.T_INSTILL_FEAR), true, nil, {no_unlearn=true}) end end, on_unlearn = function(self, t) local lev = self:getTalentLevelRaw(t) if lev == 0 then self:unlearnTalent(self.T_INSTILL_FEAR) elseif lev == 1 then self:unlearnTalent(self.T_INSTILL_FEAR) elseif lev == 2 then self:unlearnTalent(self.T_INSTILL_FEAR) elseif lev == 3 then self:unlearnTalent(self.T_INSTILL_FEAR) elseif lev == 4 then self:unlearnTalent(self.T_INSTILL_FEAR) end end, action = function(self, t) local shadow_count = 0 if target:hasEffect(target.EFF_PARANOID) then shadow_count = shadow_count + 1 end if target:hasEffect(target.EFF_DISPAIR) then shadow_count = shadow_count + 1 end if target:hasEffect(target.EFF_TERRIFIED) then shadow_count = shadow_count + 1 end if target:hasEffect(target.EFF_DISTRESSED) then shadow_count = shadow_count + 1 end if target:hasEffect(target.EFF_HAUNTED) then shadow_count = shadow_count + 1 end if target:hasEffect(target.EFF_TORMENTED) then shadow_count = shadow_count + 1 end local tgts = {} local grids = core.fov.circle_grids(self.x, self.y, 10, true) for x, yy in pairs(grids) do for y, _ in pairs(grids[x]) do local a = game.level.map(x, y, Map.ACTOR) if a and self:reactionToward(a) < 0 then tgts[#tgts+1] = a end end end local tg = {type="bolt", range=10, talent=t, display={particle="agony"}, friendlyblock=false} for i = 1, #tgts do if #tgts <= 0 then break end local a, id = rng.table(tgts) table.remove(tgts, id) for i = 1, 1 do local x, y = nil local x, y = util.findFreeGrid(a.x, a.y, 4, true, {[engine.Map.ACTOR]=true}) local NPC = require "mod.class.NPC" local shadowlevel = self.level local m = NPC.new{ type = "undead", subtype = "shadow", name = "ethereal shadow", desc = [[]], display = 'b', color=colors.BLACK, autolevel = "none", ai = "summoned", ai_real = "dumb_talented_simple", ai_state = { talent_in=5, }, stats = {str=0, dex=0, con=0, cun=0, wil=0, mag=0}, level_range = {shadowlevel, shadowlevel}, exp_worth = 0, max_life = self.max_life*0.15, life_rating = self.max_life*0.05, infravision = 10, combat_armor = 2, combat_def = 4, combat = { dam=1 * 3 + rng.avg(12,25), atk=10, apr=10, dammod={str=0.8} }, never_anger = true, summoner = self, summoner_gain_exp=true, summon_time = 4, ai_target = {actor=target} } m.remove_from_party_on_death = true if x and y then game.zone:addEntity(game.level, m, "actor", x, y) m:setTarget(a) a:setTarget(m) if game.party:hasMember(self) then game.party:addMember(m, { control="no", type="ethereal shadow", title="Ethereal Shadow", }) end end end game:playSoundNear(self, "talents/fire") end return true end, info = function(self, t) return ([[You know the most basic trick of horror: Jump scares. Summon 1 Shadow around each feared enemy, 1 for each fear effecting them. These shadows taunt nearby enemies into lashing out at them. These shadows have no special abilities, deal minimal to no damage, and last 4 turns. As they are not 'true' shadows, they do not work with Shadow Alliance. Additionally, you gain Instill Fear at this talent's level.]]) end, } newTalent{ name = "Insanity", shortname = "INSANITY" type = {"cursed/horror", 2}, points = 5, mode = "passive", require = make_require(2), on_learn = function(self, t) local lev = self:getTalentLevelRaw(t) if lev == 1 then self:learnTalent((self.T_TYRANT), true, nil, {no_unlearn=true}) elseif lev == 2 then self:learnTalent((self.TYRANT), true, nil, {no_unlearn=true}) elseif lev == 3 then self:learnTalent((self.T_TYRANT), true, nil, {no_unlearn=true}) elseif lev == 4 then self:learnTalent((self.T_TYRANT), true, nil, {no_unlearn=true}) elseif lev == 5 then self:learnTalent((self.T_TYRANT), true, nil, {no_unlearn=true}) end end, on_unlearn = function(self, t) local lev = self:getTalentLevelRaw(t) if lev == 0 then self:unlearnTalent(self.T_TYRANT) elseif lev == 1 then self:unlearnTalent(self.T_TYRANT) elseif lev == 2 then self:unlearnTalent(self.T_TYRANT) elseif lev == 3 then self:unlearnTalent(self.T_TYRANT) elseif lev == 4 then self:unlearnTalent(self.T_TYRANT) end end, getChance = function(self, t) return self:combatLimit(self:getTalentLevel(t)^0.5, 100, 8, 1, 17.9, 2.23) end, -- Limit < 100% getDarkResistChange = function(self, t) return -self:combatTalentLimit(t, 50, 15, 35) end, -- Limit < 50% doMadness = function(target, t, src) local chance = t.getChance(src, t) if target and src and target:reactionToward(src) < 0 and src:checkHit(src:combatMindpower(), target:combatMentalResist(), 0, chance, 5) then local darkResistChange = t.getDarkResistChange(src, t) local effect = rng.range(1, 3) if effect == 1 then -- confusion if target:canBe("confusion") and not target:hasEffect(target.EFF_MADNESS_CONFUSED) then target:setEffect(target.EFF_MADNESS_CONFUSED, 3, {power=50, mindResistChange=mindResistChange}) -- Consistent with other confusion end elseif effect == 2 then -- stun if target:canBe("stun") and not target:hasEffect(target.EFF_MADNESS_STUNNED) then target:setEffect(target.EFF_MADNESS_STUNNED, 3, {mindResistChange=mindResistChange}) end elseif effect == 3 then -- slow if target:canBe("slow") and not target:hasEffect(target.EFF_MADNESS_SLOW) then target:setEffect(target.EFF_MADNESS_SLOW, 3, {power=0.3, mindResistChange=mindResistChange}) end end end end, info = function(self, t) local chance = t.getChance(self, t) local mindResistChange = t.getMindResistChange(self, t) return ([[Every time you inflict mental damage, there is a %d%% chance that your foe must save against your Mindpower or go mad. Insanity can cause them to become confused, slowed or stunned for 3 turns, and lowers resistance to darkness damage by %d%%. Additionally, you learn Tyrant at this talent's level.]]):format(chance, -darkResistChange) end, }