diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index 3ee8f0fd90f85ac580010406241cf8e95b8ca5d7..f5c6f9587eea054e7a34bc914c9ac348b5ec622d 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -119,6 +119,13 @@ function _M:attackTarget(target, damtype, mult, noenergy, force_unharmed) local ret = target:callTalent(target.T_INTUITIVE_SHOTS, "proc", self) if ret then return false end end + + if not target.turn_procs.warding_weapon and target:knowTalent(target.T_WARDING_WEAPON) and target:getTalentLevelRaw(target.T_WARDING_WEAPON) >= 5 + and rng.percent(target:callTalent(target.T_WARDING_WEAPON, "getChance")) and target:getPsi() >= 15 then + target:setEffect(target.EFF_WEAPON_WARDING, 1, {}) + target.turn_procs.warding_weapon = true + target:incPsi(-15) + end -- Change attack type if using gems if not damtype and self:getInven(self.INVEN_GEM) then diff --git a/game/modules/tome/data/birth/classes/psionic.lua b/game/modules/tome/data/birth/classes/psionic.lua index e30e630e8f0a6cc26124e26e3837550075af8933..60e7866ca0a3c58f20350d7e6aa74f010fa277c8 100644 --- a/game/modules/tome/data/birth/classes/psionic.lua +++ b/game/modules/tome/data/birth/classes/psionic.lua @@ -105,6 +105,11 @@ newBirthDescriptor{ {type="armor", subtype="cloth", name="linen robe", autoreq=true, ego_chance=-1000}, {type="weapon", subtype="greatsword", name="iron greatsword", autoreq=true, ego_chance=-1000}, }, + resolvers.inventorybirth{ id=true, + {type="weapon", subtype="mindstar", name="mossy mindstar", autoreq=true, ego_chance=-1000}, + {type="weapon", subtype="mindstar", name="mossy mindstar", autoreq=true, ego_chance=-1000}, + {type="gem",}, + }, resolvers.generic(function(self) -- Make and wield some alchemist gems local gs = game.zone:makeEntity(game.level, "object", {type="weapon", subtype="greatsword", name="iron greatsword", ego_chance=-1000}, nil, true) diff --git a/game/modules/tome/data/talents/misc/npcs.lua b/game/modules/tome/data/talents/misc/npcs.lua index c3f5c35696c8a5019b3274ab6a0e136a032ee14b..e5618860a9042e9488a2fe15e9c70beb4cc5be2b 100644 --- a/game/modules/tome/data/talents/misc/npcs.lua +++ b/game/modules/tome/data/talents/misc/npcs.lua @@ -2466,40 +2466,140 @@ newTalent{ } newTalent{ - name = "Mindhook", + name = "Shattering Charge", type = {"psionic/other", 1}, - cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 5, 18, 10)) end, -- Limit to >5 - psi = 20, +-- require = psi_wil_req4, points = 5, - tactical = { CLOSEIN = 2 }, - range = function(self, t) - local r = self:combatTalentLimit(t, 10, 3, 7) -- Limit base range to 10 - local gem_level = getGemLevel(self) - local mult = 1 + 0.005*gem_level*self:callTalent(self.T_REACH, "rangebonus") -- reduced effect of reach - return math.floor(r*mult) + psi = 40, + cooldown = 12, + tactical = { CLOSEIN = 2, ATTACK = { PHYSICAL = 2 } }, + range = function(self, t) return self:combatTalentLimit(t, 10, 6, 9) end, + direct_hit = true, + requires_target = true, + getDam = function(self, t) return self:combatTalentMindDamage(t, 20, 180) end, + action = function(self, t) + if self:getTalentLevelRaw(t) < 5 then + local tg = {type="beam", range=self:getTalentRange(t), nolock=true, talent=t} + local x, y = self:getTarget(tg) + if not x or not y then return nil end + if core.fov.distance(self.x, self.y, x, y) > tg.range then return nil end + if self:hasLOS(x, y) and not game.level.map:checkEntity(x, y, Map.TERRAIN, "block_move") then + local dam = self:mindCrit(t.getDam(self, t)) + self:project(tg, x, y, DamageType.MINDKNOCKBACK, self:mindCrit(rng.avg(2*dam/3, dam, 3))) + --local _ _, x, y = self:canProject(tg, x, y) + game.level.map:particleEmitter(self.x, self.y, tg.radius, "flamebeam", {tx=x-self.x, ty=y-self.y}) + game:playSoundNear(self, "talents/lightning") + --self:move(x, y, true) + local fx, fy = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true}) + if fx then + self:move(fx, fy, true) + end + else + game.logSeen(self, "You can't move there.") + return nil + end + return true + else + local tg = {type="beam", range=self:getTalentRange(t), nolock=true, talent=t, display={particle="bolt_earth", trail="earthtrail"}} + local x, y = self:getTarget(tg) + if not x or not y then return nil end + if core.fov.distance(self.x, self.y, x, y) > tg.range then return nil end + local dam = self:mindCrit(t.getDam(self, t)) + + for i = 1, self:getTalentRange(t) do + self:project(tg, x, y, DamageType.DIG, 1) + end + self:project(tg, x, y, DamageType.MINDKNOCKBACK, self:mindCrit(rng.avg(2*dam/3, dam, 3))) + local _ _, x, y = self:canProject(tg, x, y) + game.level.map:particleEmitter(self.x, self.y, tg.radius, "flamebeam", {tx=x-self.x, ty=y-self.y}) + game:playSoundNear(self, "talents/lightning") + + local block_actor = function(_, bx, by) return game.level.map:checkEntity(bx, by, engine.Map.TERRAIN, "block_move", self) end + local l = self:lineFOV(x, y, block_actor) + local lx, ly, is_corner_blocked = l:step() + local tx, ty = self.x, self.y + while lx and ly do + if is_corner_blocked or block_actor(_, lx, ly) then break end + tx, ty = lx, ly + lx, ly, is_corner_blocked = l:step() + end + + --self:move(tx, ty, true) + local fx, fy = util.findFreeGrid(tx, ty, 5, true, {[Map.ACTOR]=true}) + if fx then + self:move(fx, fy, true) + end + return true + end + end, + info = function(self, t) + local range = self:getTalentRange(t) + local dam = damDesc(self, DamageType.PHYSICAL, t.getDam(self, t)) + return ([[You expend massive amounts of energy to launch yourself across %d squares at incredible speed. All enemies in your path will be knocked flying and dealt between %d and %d Physical damage. + At talent level 5, you can batter through solid walls.]]): + format(range, 2*dam/3, dam) + end, +} + +newTalent{ + name = "Telekinetic Throw", + type = {"psionic/other", 1}, +-- require = psi_wil_high2, + points = 5, + random_ego = "attack", + cooldown = 15, + psi = 20, + tactical = { ATTACK = { PHYSICAL = 2 } }, + range = function(self, t) return math.floor(self:combatStatScale("str", 1, 5) + self:combatMindpower()/20) end, + getDamage = function (self, t) + return math.floor(self:combatTalentMindDamage(t, 10, 170)) end, + getKBResistPen = function(self, t) return self:combatTalentLimit(t, 100, 25, 45) end, + requires_target = true, + target = function(self, t) return {type="ball", range=self:getTalentRange(t), radius=2, selffire=false, talent=t} end, action = function(self, t) - local tg = {type="bolt", range=self:getTalentRange(t)} + local tg = {type="hit", range=1} + local x, y, target = self:getTarget(tg) + if not x or not y or not target then return nil end + if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end + + local tg = self:getTalentTarget(t) local x, y = self:getTarget(tg) if not x or not y then return nil end - local _ _, x, y = self:canProject(tg, x, y) - local target = game.level.map(x, y, engine.Map.ACTOR) - if not target then - game.logPlayer(self, "The target is out of range") - return + local dam = self:mindCrit(t.getDamage(self, t)) + + if target:canBe("knockback") or rng.percent(t.getKBResistPen(self, t)) then + self:project({type="hit", range=tg.range}, target.x, target.y, DamageType.PHYSICAL, dam) --Direct Damage + + local tx, ty = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true}) + if tx and ty then + local ox, oy = target.x, target.y + target:move(tx, ty, true) + if config.settings.tome.smooth_move > 0 then + target:resetMoveAnim() + target:setMoveAnim(ox, oy, 8, 5) + end + end + self:project(tg, target.x, target.y, DamageType.SPELLKNOCKBACK, dam/2) --AOE damage + if target:canBe("stun") then + target:setEffect(target.EFF_STUNNED, 4, {apply_power=self:combatMindpower()}) + else + game.logSeen(target, "%s resists the stun!", target.name:capitalize()) + end + else --If the target resists the knockback, do half damage to it. + target:logCombat(self, "#YELLOW##Source# resists #Target#'s throw!") + self:project({type="hit", range=tg.range}, target.x, target.y, DamageType.PHYSICAL, dam/2) end - target:pull(self.x, self.y, tg.range) - target:setEffect(target.EFF_DAZED, 1, {}) - game:playSoundNear(self, "talents/arcane") - return true end, info = function(self, t) local range = self:getTalentRange(t) - return ([[Briefly extend your telekinetic reach to grab an enemy and haul them towards you. - Works on enemies up to %d squares away. The cooldown decreases, and the range increases, with additional talent points spent. - This talent receives a reduced benefit from the Reach talent.]]): - format(range) + local dam = damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t)) + return ([[Use your telekinetic power to enhance your strength, allowing you to pick up an adjacent enemy and hurl it anywhere within radius %d. + Upon landing, your target takes %0.1f Physical damage and is stunned for 4 turns. All other creatures within radius 2 of the landing point take %0.1f Physical damage and are knocked away from you. + This talent ignores %d%% of the knockback resistance of the thrown target, which takes half damage if it resists being thrown. + The damage improves with your Mindpower and the range increases with both Mindpower and Strength.]]): + format(range, dam, dam/2, t.getKBResistPen(self, t)) end, } diff --git a/game/modules/tome/data/talents/psionic/absorption.lua b/game/modules/tome/data/talents/psionic/absorption.lua index 14a6a12c4edeab65d63fda55b73b5340bb1969ee..c92c1dd52574ba32a808491de7b2d4ccbc251ec7 100644 --- a/game/modules/tome/data/talents/psionic/absorption.lua +++ b/game/modules/tome/data/talents/psionic/absorption.lua @@ -21,16 +21,11 @@ -- Note: This is consistent with raw damage but is applied after damage multipliers local function getShieldStrength(self, t) --return math.max(0, self:combatMindpower()) - return self:combatTalentMindDamage(t, 10, 100) -end - -local function getSpikeStrength(self, t) - local ss = getShieldStrength(self, t) - return 75*self:getTalentLevel(t) + ss*6.85 + return self:combatTalentMindDamage(t, 20, 100) end local function getEfficiency(self, t) - return self:combatTalentLimit(t, 100, 20, 70)/100 -- Limit to <100% + return self:combatTalentLimit(t, 100, 20, 55)/100 -- Limit to <100% end local function maxPsiAbsorb(self, t) -- Max psi/turn to prevent runaway psi gains (solipsist randbosses) @@ -60,9 +55,9 @@ local function shieldAbsorb(self, t, p, absorbed) local cturn = math.floor(game.turn / 10) if cturn ~= p.last_absorbs.last_turn then local diff = cturn - p.last_absorbs.last_turn - for i = 5, 0, -1 do + for i = 2, 0, -1 do local ni = i + diff - if ni <= 5 then + if ni <= 2 then p.last_absorbs.values[ni] = p.last_absorbs.values[i] end p.last_absorbs.values[i] = nil @@ -74,14 +69,14 @@ end local function shieldSpike(self, t, p) local val = 0 - for i = 0, 5 do val = val + (p.last_absorbs.values[i] or 0) end + for i = 0, 2 do val = val + (p.last_absorbs.values[i] or 0) end - self:setEffect(self.EFF_PSI_DAMAGE_SHIELD, 5, {power=val}) + self:setEffect(self.EFF_PSI_DAMAGE_SHIELD, 5, {power=val*2}) end local function shieldOverlay(self, t, p) local val = 0 - for i = 0, 5 do val = val + (p.last_absorbs.values[i] or 0) end + for i = 0, 2 do val = val + (p.last_absorbs.values[i] or 0) end if val <= 0 then return "" end local fnt = "buff_font_small" if val >= 1000 then fnt = "buff_font_smaller" end @@ -173,7 +168,6 @@ newTalent{ end, deactivate = function(self, t, p) self:removeParticles(p.particle) - local spike_str = getSpikeStrength(self, t) self:removeTemporaryValue("kinetic_shield", p.am) if self:attr("save_cleanup") then return true end @@ -225,7 +219,7 @@ newTalent{ local absorb = 100*getEfficiency(self,t) return ([[Surround yourself with a shield that will absorb %d%% of any physical/acid/nature/temporal attack, up to a maximum of %d damage per attack. Every time your shield absorbs damage, you convert some of the attack into energy, gaining two points of Psi, plus an additional point for every %0.1f points of damage absorbed, up to a maximum %0.1f points each turn. - At talent level 3, when you de-activate the shield all the absorbed damage in the last 6 turns is released as a full psionic shield (absorbing all damage). + At talent level 3, when you de-activate the shield twice the absorbed damage in the last 3 turns is released as a full psionic shield (absorbing all damage). The maximum amount of damage your shield can absorb and the efficiency of the psi gain scale with your mindpower.]]): format(absorb, s_str, shieldMastery(self, t), maxPsiAbsorb(self,t)) end, @@ -318,7 +312,6 @@ newTalent{ end, deactivate = function(self, t, p) self:removeParticles(p.particle) - local spike_str = getSpikeStrength(self, t) self:removeTemporaryValue("thermal_shield", p.am) if self:attr("save_cleanup") then return true end @@ -368,7 +361,7 @@ newTalent{ local absorb = 100*getEfficiency(self,t) return ([[Surround yourself with a shield that will absorb %d%% of any fire/cold/light/arcane attack, up to a maximum of %d damage per attack. Every time your shield absorbs damage, you convert some of the attack into energy, gaining two points of Psi, plus an additional point for every %0.1f points of damage absorbed, up to a maximum %0.1f points each turn. - At talent level 3, when you de-activate the shield all the absorbed damage in the last 6 turns is released as a full psionic shield (absorbing all damage). + At talent level 3, when you de-activate the shield twice the absorbed damage in the last 3 turns is released as a full psionic shield (absorbing all damage). The maximum amount of damage your shield can absorb and the efficiency of the psi gain scale with your mindpower.]]): format(absorb, s_str, shieldMastery(self, t), maxPsiAbsorb(self,t)) end, @@ -458,7 +451,6 @@ newTalent{ end, deactivate = function(self, t, p) self:removeParticles(p.particle) - local spike_str = getSpikeStrength(self, t) self:removeTemporaryValue("charged_shield", p.am) if self:attr("save_cleanup") then return true end @@ -510,7 +502,7 @@ newTalent{ local absorb = 100*getEfficiency(self,t) return ([[Surround yourself with a shield that will absorb %d%% of any lightning/blight/darkness/mind attack, up to a maximum of %d damage per attack. Every time your shield absorbs damage, you convert some of the attack into energy, gaining two points of Psi, plus an additional point for every %0.1f points of damage absorbed, up to a maximum %0.1f points each turn. - At talent level 3, when you de-activate the shield all the absorbed damage in the last 6 turns is released as a full psionic shield (absorbing all damage). + At talent level 3, when you de-activate the shield twice the absorbed damage in the last 3 turns is released as a full psionic shield (absorbing all damage). The maximum amount of damage your shield can absorb and the efficiency of the psi gain scale with your mindpower.]]): format(absorb, s_str, shieldMastery(self, t), maxPsiAbsorb(self,t)) end, diff --git a/game/modules/tome/data/talents/psionic/augmented-mobility.lua b/game/modules/tome/data/talents/psionic/augmented-mobility.lua index 311755851b1889aa6de1dbc68b07b0788e758272..b178442f8442af7bc88bbbbbe44c4ebd19125008 100644 --- a/game/modules/tome/data/talents/psionic/augmented-mobility.lua +++ b/game/modules/tome/data/talents/psionic/augmented-mobility.lua @@ -59,9 +59,9 @@ newTalent{ psi = 30, no_energy = true, getDuration = function(self, t) return math.floor(self:combatLimit(self:combatMindpower(0.1), 10, 4, 0, 6, 6)) end, -- Limit < 10 - speed = function(self, t) return self:combatTalentScale(t, 0.1, 0.6, 0.75) end, + speed = function(self, t) return self:combatTalentScale(t, 0.1, 0.4, 0.75) end, getBoost = function(self, t) - return self:combatScale(self:getTalentLevel(t)*self:combatStatTalentIntervalDamage(t, "combatMindpower", 1, 9), 15, 0, 49, 34) + return self:combatScale(self:combatTalentMindDamage(t, 20, 60), 0, 0, 50, 100, 0.75) end, action = function(self, t) self:setEffect(self.EFF_QUICKNESS, t.getDuration(self, t), {power=t.speed(self, t)}) @@ -73,122 +73,75 @@ newTalent{ local percentinc = 100 * inc local boost = t.getBoost(self, t) return ([[Encase your body in a sheath of thought-quick forces, allowing you to control your body's movements directly without the inefficiency of dealing with crude mechanisms like nerves and muscles. - Increases Accuracy by %d, your critical strike chance by %0.1f%% and your attack speed by %d%% for %d turns. + Increases Accuracy by %d, your critical strike chance by %0.1f%% and your global speed by %d%% for %d turns. The duration improves with your Mindpower.]]): format(boost, 0.5*boost, percentinc, t.getDuration(self, t)) end, } - newTalent{ - name = "Telekinetic Leap", + name = "Mindhook", type = {"psionic/augmented-mobility", 3}, require = psi_wil_req3, - cooldown = 15, + cooldown = function(self, t) return math.ceil(self:combatTalentLimit(t, 5, 18, 10)) end, -- Limit to >5 psi = 10, points = 5, tactical = { CLOSEIN = 2 }, - range = function(self, t) - return self:combatTalentLimit(t, 10, 5, 9) -- Limit < 10 - end, + range = function(self, t) return self:combatTalentLimit(t, 10, 3, 7) end, -- Limit base range to 10 action = function(self, t) - local tg = {default_target=self, type="ball", nolock=true, pass_terrain=false, nowarning=true, range=self:getTalentRange(t), radius=0, requires_knowledge=false} + local tg = {type="bolt", range=self:getTalentRange(t)} local x, y = self:getTarget(tg) if not x or not y then return nil end local _ _, x, y = self:canProject(tg, x, y) - if not x or not y then return nil end - - - local fx, fy = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true}) - if not fx then + local target = game.level.map(x, y, engine.Map.ACTOR) + if not target then + game.logPlayer(self, "The target is out of range") return end - self:move(fx, fy, true) - + target:pull(self.x, self.y, tg.range) + target:setEffect(target.EFF_DAZED, 1, {apply_power=self:combatMindpower()}) + game:playSoundNear(self, "talents/arcane") return true end, info = function(self, t) local range = self:getTalentRange(t) - return ([[You perform a precise, telekinetically-enhanced leap, landing up to %d squares away.]]): + return ([[Briefly extend your telekinetic reach to grab an enemy and haul them towards you. + Works on enemies up to %d squares away. + The cooldown decreases, and the range increases, with additional talent points spent.]]): format(range) end, } newTalent{ - name = "Shattering Charge", + name = "Telekinetic Leap", type = {"psionic/augmented-mobility", 4}, require = psi_wil_req4, + cooldown = 15, + psi = 10, points = 5, - psi = 40, - cooldown = 12, - tactical = { CLOSEIN = 2, ATTACK = { PHYSICAL = 2 } }, - range = function(self, t) return self:combatTalentLimit(t, 10, 6, 9) end, - direct_hit = true, - requires_target = true, - getDam = function(self, t) return self:combatTalentMindDamage(t, 20, 180) end, + tactical = { CLOSEIN = 2 }, + range = function(self, t) + return math.floor(self:combatTalentLimit(t, 10, 2, 7.5)) -- Limit < 10 + end, action = function(self, t) - if self:getTalentLevelRaw(t) < 5 then - local tg = {type="beam", range=self:getTalentRange(t), nolock=true, talent=t} - local x, y = self:getTarget(tg) - if not x or not y then return nil end - if core.fov.distance(self.x, self.y, x, y) > tg.range then return nil end - if self:hasLOS(x, y) and not game.level.map:checkEntity(x, y, Map.TERRAIN, "block_move") then - local dam = self:mindCrit(t.getDam(self, t)) - self:project(tg, x, y, DamageType.MINDKNOCKBACK, self:mindCrit(rng.avg(2*dam/3, dam, 3))) - --local _ _, x, y = self:canProject(tg, x, y) - game.level.map:particleEmitter(self.x, self.y, tg.radius, "flamebeam", {tx=x-self.x, ty=y-self.y}) - game:playSoundNear(self, "talents/lightning") - --self:move(x, y, true) - local fx, fy = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true}) - if not fx then - return - end - self:move(fx, fy, true) - else - game.logSeen(self, "You can't move there.") - return nil - end - return true - else - local tg = {type="beam", range=self:getTalentRange(t), nolock=true, talent=t, display={particle="bolt_earth", trail="earthtrail"}} - local x, y = self:getTarget(tg) - if not x or not y then return nil end - if core.fov.distance(self.x, self.y, x, y) > tg.range then return nil end - local dam = self:mindCrit(t.getDam(self, t)) - - for i = 1, self:getTalentRange(t) do - self:project(tg, x, y, DamageType.DIG, 1) - end - self:project(tg, x, y, DamageType.MINDKNOCKBACK, self:mindCrit(rng.avg(2*dam/3, dam, 3))) - local _ _, x, y = self:canProject(tg, x, y) - game.level.map:particleEmitter(self.x, self.y, tg.radius, "flamebeam", {tx=x-self.x, ty=y-self.y}) - game:playSoundNear(self, "talents/lightning") - - local block_actor = function(_, bx, by) return game.level.map:checkEntity(bx, by, engine.Map.TERRAIN, "block_move", self) end - local l = self:lineFOV(x, y, block_actor) - local lx, ly, is_corner_blocked = l:step() - local tx, ty = self.x, self.y - while lx and ly do - if is_corner_blocked or block_actor(_, lx, ly) then break end - tx, ty = lx, ly - lx, ly, is_corner_blocked = l:step() - end + local tg = {default_target=self, type="ball", nolock=true, pass_terrain=false, nowarning=true, range=self:getTalentRange(t), radius=0, requires_knowledge=false} + local x, y = self:getTarget(tg) + if not x or not y then return nil end + local _ _, x, y = self:canProject(tg, x, y) + if not x or not y then return nil end - --self:move(tx, ty, true) - local fx, fy = util.findFreeGrid(tx, ty, 5, true, {[Map.ACTOR]=true}) - if not fx then - return - end - self:move(fx, fy, true) - return true + local fx, fy = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true}) + if not fx then + return end + self:move(fx, fy, true) + + return true end, info = function(self, t) local range = self:getTalentRange(t) - local dam = damDesc(self, DamageType.PHYSICAL, t.getDam(self, t)) - return ([[You expend massive amounts of energy to launch yourself across %d squares at incredible speed. All enemies in your path will be knocked flying and dealt between %d and %d Physical damage. - At talent level 5, you can batter through solid walls.]]): - format(range, 2*dam/3, dam) + return ([[You perform a precise, telekinetically-enhanced leap, landing up to %d squares away.]]): + format(range) end, -} \ No newline at end of file +} diff --git a/game/modules/tome/data/talents/psionic/augmented-striking.lua b/game/modules/tome/data/talents/psionic/augmented-striking.lua index d97cf1063c5cfa84cb534b5ff8afd469b43b43e1..6260e0053f35c7044f623e88f704e5e31e96128e 100644 --- a/game/modules/tome/data/talents/psionic/augmented-striking.lua +++ b/game/modules/tome/data/talents/psionic/augmented-striking.lua @@ -28,7 +28,8 @@ newTalent{ range = 1, requires_target = true, tactical = { ATTACK = { PHYSICAL = 2 } }, - getDam = function(self, t) return self:combatTalentMindDamage(t, 10, 100) end, + getDam = function(self, t) return self:combatTalentMindDamage(t, 20, 200) end, + getDur = function(self, t) return self:combatTalentScale(t, 2.0, 6.0) end, action = function(self, t) local weapon = self:getInven("MAINHAND") and self:getInven("MAINHAND")[1] if type(weapon) == "boolean" then weapon = nil end @@ -41,10 +42,18 @@ newTalent{ if not x or not y or not target then return nil end if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end local dam = self:mindCrit(t.getDam(self, t)) + local dur = t.getDur(self, t) - local hit = self:attackTarget(target, DamageType.PHYSICAL, self:combatTalentWeaponDamage(t, 0.5, 2.0), true) + local hit = self:attackTarget(target, DamageType.PHYSICAL, self:combatTalentWeaponDamage(t, 0.5, 3.0), true) if hit then - DamageType:get(DamageType.TK_PUSHPIN).projector(self, x, y, DamageType.TK_PUSHPIN, {push=4, dam=dam, dur=4}) + if target:canBe("pin") then + target:setEffect(target.EFF_PINNED, dur, {apply_power=self:combatMindpower()}) + else + game.logSeen(target, "%s resists the pin!", target.name:capitalize()) + end + if target:attr("frozen") then + DamageType:get(DamageType.PHYSICAL).projector(self, x, y, DamageType.PHYSICAL, dam) + end end if self:hasEffect(self.EFF_TRANSCENDENT_TELEKINESIS) then @@ -56,23 +65,41 @@ newTalent{ local hit if lt then - hit = self:attackTarget(lt, DamageType.PHYSICAL, self:combatTalentWeaponDamage(t, 0.5, 2.0), true) - if hit then DamageType:get(DamageType.TK_PUSHPIN).projector(self, lx, ly, DamageType.TK_PUSHPIN, {push=4, dam=dam, dur=4}) end + hit = self:attackTarget(lt, DamageType.PHYSICAL, self:combatTalentWeaponDamage(t, 0.5, 3.0), true) + if hit then + if lt:canBe("pin") then + lt:setEffect(lt.EFF_PINNED, dur, {apply_power=self:combatMindpower()}) + else + game.logSeen(lt, "%s resists the pin!", lt.name:capitalize()) + end + if target:attr("frozen") then + DamageType:get(DamageType.PHYSICAL).projector(self, x, y, DamageType.PHYSICAL, dam) + end + end end if rt then - hit = self:attackTarget(rt, DamageType.PHYSICAL, self:combatTalentWeaponDamage(t, 0.5, 2.0), true) - if hit then DamageType:get(DamageType.TK_PUSHPIN).projector(self, rx, ry, DamageType.TK_PUSHPIN, {push=4, dam=dam, dur=4}) end + hit = self:attackTarget(rt, DamageType.PHYSICAL, self:combatTalentWeaponDamage(t, 0.5, 3.0), true) + if hit then + if rt:canBe("pin") then + rt:setEffect(rt.EFF_PINNED, dur, {apply_power=self:combatMindpower()}) + else + game.logSeen(rt, "%s resists the pin!", rt.name:capitalize()) + end + if target:attr("frozen") then + DamageType:get(DamageType.PHYSICAL).projector(self, x, y, DamageType.PHYSICAL, dam) + end + end end end - return true end, info = function(self, t) return ([[Focus kinetic energy and strike an enemy for %d%% weapon damage as physical. - They will then be thrown back by the force of the hit, taking an extra %0.1f Physical damage if they hit a wall, where they will be pinned for 4 turns. - The knockback damage will scale with your Mindpower.]]): - format(100 * self:combatTalentWeaponDamage(t, 0.5, 2.0), damDesc(self, DamageType.PHYSICAL, t.getDam(self, t))) + They will be pinned to the ground for %d turns by the force of this attack. + Any frozen creature hit by this attack will take an extra %0.1f physical damage. + The extra damage will scale with your Mindpower.]]): + format(100 * self:combatTalentWeaponDamage(t, 0.5, 2.0), t.getDur(self, t), damDesc(self, DamageType.PHYSICAL, t.getDam(self, t))) end, } @@ -88,7 +115,8 @@ newTalent{ range = 1, requires_target = true, tactical = { ATTACK = { COLD = 2 } }, - getDam = function(self, t) return self:combatTalentMindDamage(t, 10, 100) end, + getDam = function(self, t) return self:combatTalentMindDamage(t, 20, 200) end, + getDur = function(self, t) return self:combatTalentScale(t, 2.0, 6.0) end, action = function(self, t) local weapon = self:getInven("MAINHAND") and self:getInven("MAINHAND")[1] if type(weapon) == "boolean" then weapon = nil end @@ -101,26 +129,27 @@ newTalent{ if not x or not y or not target then return nil end if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end local dam = self:mindCrit(t.getDam(self, t)) + local dur = t.getDur(self, t) local hit = self:attackTarget(target, DamageType.COLD, self:combatTalentWeaponDamage(t, 0.5, 2.0), true) if hit then if self:hasEffect(self.EFF_TRANSCENDENT_PYROKINESIS) then local tg = {type="ball", range=1, radius=1, friendlyfire=false} self:project(tg, x, y, DamageType.COLD, dam) - self:project(tg, x, y, DamageType.FREEZE, {dur=4, hp=dam}) + self:project(tg, x, y, DamageType.FREEZE, {dur=dur, hp=dam}) game.level.map:particleEmitter(x, y, tg.radius, "iceflash", {radius=1}) else DamageType:get(DamageType.COLD).projector(self, x, y, DamageType.COLD, dam) - DamageType:get(DamageType.FREEZE).projector(self, x, y, DamageType.FREEZE, {dur=4, hp=dam}) + DamageType:get(DamageType.FREEZE).projector(self, x, y, DamageType.FREEZE, {dur=dur, hp=dam}) end end return true end, info = function(self, t) return ([[Focus thermal energy and strike an enemy for %d%% weapon damage as cold. - A burst of cold will then engulf them, doing an extra %0.1f Cold damage and also freeze them for 4 turns. + A burst of cold will then engulf them, doing an extra %0.1f Cold damage and also freeze them for %d turns. The cold burst damage will scale with your Mindpower.]]): - format(100 * self:combatTalentWeaponDamage(t, 0.5, 2.0), damDesc(self, DamageType.COLD, t.getDam(self, t))) + format(100 * self:combatTalentWeaponDamage(t, 0.5, 2.0), damDesc(self, DamageType.COLD, t.getDam(self, t)), t.getDur(self, t)) end, } @@ -135,7 +164,8 @@ newTalent{ range = 1, requires_target = true, tactical = { ATTACK = { LIGHTNING = 2 } }, - getDam = function(self, t) return self:combatTalentMindDamage(t, 10, 100) end, + getDam = function(self, t) return self:combatTalentMindDamage(t, 20, 200) end, + getDur = function(self, t) return self:combatTalentScale(t, 2.0, 6.0) end, action = function(self, t) local weapon = self:getInven("MAINHAND") and self:getInven("MAINHAND")[1] if type(weapon) == "boolean" then weapon = nil end @@ -148,6 +178,7 @@ newTalent{ if not x or not y or not target then return nil end if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end local dam = self:mindCrit(t.getDam(self, t)) + local dur = t.getDur(self, t) local hit = self:attackTarget(target, DamageType.LIGHTNING, self:combatTalentWeaponDamage(t, 0.5, 2.0), true) if hit then @@ -195,7 +226,7 @@ newTalent{ local tgr = {type="beam", range=self:getTalentRange(t), selffire=false, talent=t, x=sx, y=sy} print("[Chain lightning] jumping from", sx, sy, "to", actor.x, actor.y) self:project(tgr, actor.x, actor.y, DamageType.LIGHTNING, dam) - self:project(tgr, actor.x, actor.y, DamageType.BLINDCUSTOMMIND, {apply_power=self:combatMindpower(), turns=4}) + actor:setEffect(actor.EFF_SHOCKED, dur, {apply_power=self:combatMindpower()}) if core.shader.active() then game.level.map:particleEmitter(sx, sy, math.max(math.abs(actor.x-sx), math.abs(actor.y-sy)), "lightning_beam", {tx=actor.x-sx, ty=actor.y-sy}, {type="lightning"}) else game.level.map:particleEmitter(sx, sy, math.max(math.abs(actor.x-sx), math.abs(actor.y-sy)), "lightning_beam", {tx=actor.x-sx, ty=actor.y-sy}) end @@ -204,16 +235,19 @@ newTalent{ end else DamageType:get(DamageType.LIGHTNING).projector(self, x, y, DamageType.LIGHTNING, dam) - DamageType:get(DamageType.BLINDCUSTOMMIND).projector(self, x, y, DamageType.BLINDCUSTOMMIND, {apply_power=self:combatMindpower(), turns=4}) + local actor = game.level.map(x, y, Map.ACTOR) + if actor then + actor:setEffect(actor.EFF_SHOCKED, dur, {apply_power=self:combatMindpower()}) + end end end return true end, info = function(self, t) return ([[Focus charged energy and strike an enemy for %d%% weapon damage as lightning. - Energy will then discharge from your weapon, doing an extra %0.1f Lightning damage and blinding them for 4 turns. + Energy will then discharge from your weapon, doing an extra %0.1f Lightning damage and halving their stun/daze/freeze resistance for %d turns. The discharge damage will scale with your Mindpower.]]): - format(100 * self:combatTalentWeaponDamage(t, 0.5, 2.0), damDesc(self, DamageType.LIGHTNING, t.getDam(self, t))) + format(100 * self:combatTalentWeaponDamage(t, 0.5, 2.0), damDesc(self, DamageType.LIGHTNING, t.getDam(self, t)), t.getDur(self, t)) end, } @@ -223,12 +257,13 @@ newTalent{ mode = "passive", points = 5, require = psi_wil_req4, - getPsiRecover = function(self, t) return self:combatTalentScale(t, 1, 3) end, + getPsiRecover = function(self, t) return self:combatTalentScale(t, 1.0, 3.0) end, passives = function(self, t, p) self:talentTemporaryValue(p, "psi_regen_on_hit", t.getPsiRecover(self, t)) + self:talentTemporaryValue(p, "combat_apr", t.getPsiRecover(self, t)*3) end, info = function(self, t) - return ([[Siphon excess energy from each weapon hit you land, gaining %0.1f psi per hit.]]):format(t.getPsiRecover(self, t)) + return ([[Wrap a psionic energy field around you weapons, increasing their armour penentration by %d and allowing you to siphon excess energy from each weapon hit you land, gaining %0.1f psi per hit.]]):format(t.getPsiRecover(self, t)*3, t.getPsiRecover(self, t)) end, } diff --git a/game/modules/tome/data/talents/psionic/charged-mastery.lua b/game/modules/tome/data/talents/psionic/charged-mastery.lua index b16c6e0950a0152c38937e538bd35ae563489a2b..7ed2c43b2b0d2292528d5ffd2024efa84da37259 100644 --- a/game/modules/tome/data/talents/psionic/charged-mastery.lua +++ b/game/modules/tome/data/talents/psionic/charged-mastery.lua @@ -107,7 +107,7 @@ newTalent{ DamageType.STATIC_NET, {dam=t.getDamage(self, t), slow=t.getSlow(self, t), weapon=t.getWeaponDamage(self, t)}, self:getTalentRadius(t), 5, nil, - {type="ice_vapour"}, + MapEffect.new{color_br=30, color_bg=100, color_bb=160, effect_shader="shader_images/retch_effect.png"}, nil, true ) game:playSoundNear(self, "talents/lightning") diff --git a/game/modules/tome/data/talents/psionic/finer-energy-manipulations.lua b/game/modules/tome/data/talents/psionic/finer-energy-manipulations.lua index 77add76ce8af4dcbc0cf4cb1724681a07900d519..23c9c1c230eed978b76ec4756888b29755d218e0 100644 --- a/game/modules/tome/data/talents/psionic/finer-energy-manipulations.lua +++ b/game/modules/tome/data/talents/psionic/finer-energy-manipulations.lua @@ -53,12 +53,10 @@ newTalent{ end end - for i = 1, t.numCure(self, t) do if #effs == 0 then break end local eff = rng.tableRemove(effs) - if eff[1] == "effect" then self:removeEffect(eff[2]) known = true @@ -195,33 +193,7 @@ newTalent{ self:setEffect(self.EFF_PSI_REGEN, dur, {power=amt}) self.changed = true d.used_talent = true - local gem_names = { - GEM_DIAMOND = "Diamond", - GEM_PEARL = "Pearl", - GEM_MOONSTONE = "Moonstone", - GEM_FIRE_OPAL = "Fire Opal", - GEM_BLOODSTONE = "Bloodstone", - GEM_RUBY = "Ruby", - GEM_AMBER = "Amber", - GEM_TURQUOISE = "Turquoise", - GEM_JADE = "Jade", - GEM_SAPPHIRE = "Sapphire", - GEM_QUARTZ = "Quartz", - GEM_EMERALD = "Emerald", - GEM_LAPIS_LAZULI = "Lapis Lazuli", - GEM_GARNET = "Garnet", - GEM_ONYX = "Onyx", - GEM_AMETHYST = "Amethyst", - GEM_OPAL = "Opal", - GEM_TOPAZ = "Topaz", - GEM_AQUAMARINE = "Aquamarine", - GEM_AMETRINE = "Ametrine", - GEM_ZIRCON = "Zircon", - GEM_SPINEL = "Spinel", - GEM_CITRINE = "Citrine", - GEM_AGATE = "Agate", - } - self:setEffect(self.EFF_CRYSTAL_BUFF, dur, {name=gem_names[gem.define_as], gem=gem.define_as}) + self:setEffect(self.EFF_CRYSTAL_BUFF, dur, {name=gem.name, effects=gem.wielder}) end) local co = coroutine.running() d.unload = function(self) coroutine.resume(co, self.used_talent) end @@ -259,9 +231,9 @@ newTalent{ info = function(self, t) local inc = t.bonus(self,t) return ([[By carefully synchronizing your mind to the resonant frequencies of your psionic focus, you strengthen its effects. - For conventional weapons, this increases the percentage of your willpower and cunning that is used in place of strength and dexterity, from 80%% to %d%%. - For mindstars, this increases the chance to pull enemies to you by +%d%%. + For conventional weapons, this increases the percentage of your willpower and cunning that is used in place of strength and dexterity, from 60%% to %d%%. + For mindstars, this increases the amount of Psi you can store by +%d. For gems, this increases the bonus stats by %d.]]): - format(80+inc, inc, math.ceil(inc/5)) + format(60+inc, inc, math.ceil(inc/5)) end, } diff --git a/game/modules/tome/data/talents/psionic/focus.lua b/game/modules/tome/data/talents/psionic/focus.lua index ba6e38ad5cabc090379a187bd27ca48c3ab30c23..5650bd92d9eaf72bcfaa1d13700ed1d31d5d409e 100644 --- a/game/modules/tome/data/talents/psionic/focus.lua +++ b/game/modules/tome/data/talents/psionic/focus.lua @@ -76,7 +76,7 @@ newTalent{ range = 0, radius = function(self,t) return self:combatTalentScale(t, 4, 6) end, getDamage = function (self, t) - return self:combatTalentMindDamage(t, 50, 480) + return self:combatTalentMindDamage(t, 20, 450) end, target = function(self, t) return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), friendlyfire=false} @@ -110,7 +110,7 @@ newTalent{ range = function(self,t) return self:combatTalentScale(t, 3, 5) end, radius = function(self,t) return self:combatTalentScale(t, 2, 3) end, tactical = { DISABLE = 2, ATTACKAREA = { LIGHTNING = 2 } }, - getDamage = function(self, t) return self:combatTalentMindDamage(t, 30, 300) end, + getDamage = function(self, t) return self:combatTalentMindDamage(t, 20, 290) end, action = function(self, t) local tg = {type="ball", range=self:getTalentRange(t), selffire=false, radius=self:getTalentRadius(t), talent=t} local x, y = self:getTarget(tg) @@ -150,13 +150,13 @@ newTalent{ require = psi_wil_req4, points = 5, mode = "passive", - stunImmune = function(self, t) return self:combatTalentLimit(t, 1, 0.10, 0.50) end, - cureChance = function(self, t) return self:combatTalentLimit(t, 1, 0.10, 0.35) end, + stunImmune = function(self, t) return self:combatTalentLimit(t, 1, 0.10, 0.40) end, + cureChance = function(self, t) return self:combatTalentLimit(t, 1, 0.10, 0.30) end, passives = function(self, t, p) self:talentTemporaryValue(p, "stun_immune", t.stunImmune(self, t)) end, callbackOnActBase = function(self, t) - if not rng.chance(t.cureChance(self, t)*100) then return end + if not rng.percent(t.cureChance(self, t)*100) then return end local effs = {} -- Go through all spell effects @@ -170,7 +170,7 @@ newTalent{ if #effs > 0 then local eff = rng.tableRemove(effs) self:removeEffect(eff[2]) - game.logSeen(self, "%s has recovered!", self.name:capitalize()) + game.logSeen(self, "#ORCHID#%s has recovered!", self.name:capitalize()) end end, info = function(self, t) diff --git a/game/modules/tome/data/talents/psionic/kinetic-mastery.lua b/game/modules/tome/data/talents/psionic/kinetic-mastery.lua index 7df2cb19baadb5a7712a4f9f4ef2045cec6eb3ae..5215f10037402811105df901394754162ca2ea7a 100644 --- a/game/modules/tome/data/talents/psionic/kinetic-mastery.lua +++ b/game/modules/tome/data/talents/psionic/kinetic-mastery.lua @@ -53,68 +53,108 @@ newTalent{ end, } + newTalent{ - name = "Telekinetic Throw", + name = "Kinetic Surge", type = {"psionic/kinetic-mastery", 2}, require = psi_wil_high2, points = 5, random_ego = "attack", cooldown = 15, psi = 20, - tactical = { ATTACK = { PHYSICAL = 2 } }, - range = function(self, t) return math.floor(self:combatStatScale("str", 1, 5) + self:combatMindpower()/20) end, + tactical = { CLOSEIN = 2, ATTACK = { PHYSICAL = 2 }, ESCAPE = 2 }, + range = function(self, t) return self:combatTalentLimit(t, 10, 6, 9) end, getDamage = function (self, t) - return math.floor(self:combatTalentMindDamage(t, 10, 170)) + return math.floor(self:combatTalentMindDamage(t, 20, 180)) end, getKBResistPen = function(self, t) return self:combatTalentLimit(t, 100, 25, 45) end, requires_target = true, target = function(self, t) return {type="ball", range=self:getTalentRange(t), radius=2, selffire=false, talent=t} end, action = function(self, t) - local tg = {type="hit", range=1} + local tg = {type="hit", range=1, nowarning=true } local x, y, target = self:getTarget(tg) if not x or not y or not target then return nil end if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end - - local tg = self:getTalentTarget(t) - local x, y = self:getTarget(tg) - if not x or not y then return nil end local dam = self:mindCrit(t.getDamage(self, t)) - - if target:canBe("knockback") or rng.percent(t.getKBResistPen(self, t)) then - self:project({type="hit", range=tg.range}, target.x, target.y, DamageType.PHYSICAL, dam) --Direct Damage - - local tx, ty = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true}) - if tx and ty then - local ox, oy = target.x, target.y - target:move(tx, ty, true) - if config.settings.tome.smooth_move > 0 then - target:resetMoveAnim() - target:setMoveAnim(ox, oy, 8, 5) + + if self:reactionToward(target) < 0 then + local tg = self:getTalentTarget(t) + local x, y = self:getTarget(tg) + if not x or not y then return nil end + + if target:canBe("knockback") or rng.percent(t.getKBResistPen(self, t)) then + self:project({type="hit", range=tg.range}, target.x, target.y, DamageType.PHYSICAL, dam) --Direct Damage + + local tx, ty = util.findFreeGrid(x, y, 5, true, {[Map.ACTOR]=true}) + if tx and ty then + local ox, oy = target.x, target.y + target:move(tx, ty, true) + if config.settings.tome.smooth_move > 0 then + target:resetMoveAnim() + target:setMoveAnim(ox, oy, 8, 5) + end + end + self:project(tg, target.x, target.y, DamageType.SPELLKNOCKBACK, dam/2) --AOE damage + if target:canBe("stun") then + target:setEffect(target.EFF_STUNNED, math.floor(self:getTalentRange(t) / 2), {apply_power=self:combatMindpower()}) + else + game.logSeen(target, "%s resists the stun!", target.name:capitalize()) + end + else --If the target resists the knockback, do half damage to it. + target:logCombat(self, "#YELLOW##Source# resists #Target#'s throw!") + self:project({type="hit", range=tg.range}, target.x, target.y, DamageType.PHYSICAL, dam/2) end - end - self:project(tg, target.x, target.y, DamageType.SPELLKNOCKBACK, dam/2) --AOE damage - if target:canBe("stun") then - target:setEffect(target.EFF_STUNNED, 4, {apply_power=self:combatMindpower()}) else - game.logSeen(target, "%s resists the stun!", target.name:capitalize()) - end - else --If the target resists the knockback, do half damage to it. - target:logCombat(self, "#YELLOW##Source# resists #Target#'s throw!") - self:project({type="hit", range=tg.range}, target.x, target.y, DamageType.PHYSICAL, dam/2) + local tg = {type="beam", range=self:getTalentRange(t), nolock=true, talent=t, display={particle="bolt_earth", trail="earthtrail"}} + local x, y = self:getTarget(tg) + if not x or not y then return nil end + if core.fov.distance(self.x, self.y, x, y) > tg.range then return nil end + + for i = 1, math.floor(self:getTalentRange(t) / 2) do + self:project(tg, x, y, DamageType.DIG, 1) + end + self:project(tg, x, y, DamageType.MINDKNOCKBACK, dam) + local _ _, x, y = self:canProject(tg, x, y) + game.level.map:particleEmitter(self.x, self.y, tg.radius, "flamebeam", {tx=x-self.x, ty=y-self.y}) + game:playSoundNear(self, "talents/lightning") + + local block_actor = function(_, bx, by) return game.level.map:checkEntity(bx, by, engine.Map.TERRAIN, "block_move", self) end + local l = self:lineFOV(x, y, block_actor) + local lx, ly, is_corner_blocked = l:step() + local tx, ty = self.x, self.y + while lx and ly do + if is_corner_blocked or block_actor(_, lx, ly) then break end + tx, ty = lx, ly + lx, ly, is_corner_blocked = l:step() + end + + --self:move(tx, ty, true) + local fx, fy = util.findFreeGrid(tx, ty, 5, true, {[Map.ACTOR]=true}) + if not fx then + self:move(fx, fy, true) + end + return true end return true end, info = function(self, t) local range = self:getTalentRange(t) local dam = damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t)) - return ([[Use your telekinetic power to enhance your strength, allowing you to pick up an adjacent enemy and hurl it anywhere within radius %d. - Upon landing, your target takes %0.1f Physical damage and is stunned for 4 turns. All other creatures within radius 2 of the landing point take %0.1f Physical damage and are knocked away from you. + return ([[Build telekinetic power and dump it onto an adjacent creature or yourself. + This will launch them to where ever you target in a radius of %d. + + Upon landing, launched enemy takes %0.1f Physical damage and is stunned for %d turns. + All other creatures within radius 2 of the landing point take %0.1f Physical damage and are knocked away from you. This talent ignores %d%% of the knockback resistance of the thrown target, which takes half damage if it resists being thrown. + + When used on yourself, you will launch in a straight line, knocking enemies flying and doing %0.1f Physical damage to each. + You can break through %d walls while doing this. The damage improves with your Mindpower and the range increases with both Mindpower and Strength.]]): - format(range, dam, dam/2, t.getKBResistPen(self, t)) + format(range, dam, math.floor(range/2), dam/2, t.getKBResistPen(self, t), dam, math.floor(range/2)) end, } + newTalent{ name = "Deflect Projectiles", type = {"psionic/kinetic-mastery", 3}, diff --git a/game/modules/tome/data/talents/psionic/other.lua b/game/modules/tome/data/talents/psionic/other.lua index 9dd24c3e671ec8fdc09136796b6af858948fb91c..4e1619ad48258b7df080ca8c13ad0c4c9d27a1d1 100644 --- a/game/modules/tome/data/talents/psionic/other.lua +++ b/game/modules/tome/data/talents/psionic/other.lua @@ -249,7 +249,7 @@ newTalent{ local ret = {} if tk.type == "gem" then - local power = (tk.material_level or 1) * 4 + math.ceil(self:callTalent(self.T_RESONANT_FOCUS, "bonus") / 5) + local power = (tk.material_level or 1) * 3 + math.ceil(self:callTalent(self.T_RESONANT_FOCUS, "bonus") / 5) self:talentTemporaryValue(ret, "inc_stats", { [self.STAT_STR] = power, [self.STAT_DEX] = power, @@ -273,7 +273,7 @@ newTalent{ end, info = function(self, t) local base = [[Allows you to wield a physical melee weapon, a mindstar or a gem telekinetically, gaining a special effect for each. - A gem will provide +4 bonus to all primary stats per tier of the gem. + A gem will provide +3 bonus to all primary stats per tier of the gem. A mindstar will randomly try to telekinetically grab a far away foe (5% chance and range 2 for a tier 1 mindstar, +1 range and +5% chance for each tier above 1) and pull it into melee range. A physical melee weapon will act as a semi independant entity, attacking foes nearby each turn while also replacing Strength and Dexterity with Willpower and Cunning for accuracy and damage calculations (for all melee weapons). diff --git a/game/modules/tome/data/talents/psionic/projection.lua b/game/modules/tome/data/talents/psionic/projection.lua index dd93752e85db4a76bd4bfb3ffa2987cecace3aaf..cf458ca3d65e5764d088e6c0d75167069801e2f5 100644 --- a/game/modules/tome/data/talents/psionic/projection.lua +++ b/game/modules/tome/data/talents/psionic/projection.lua @@ -469,7 +469,7 @@ newTalent{ points = 5, tactical = { ATTACK = { PHYSICAL = 3 } }, getTargNum = function(self,t) - return math.ceil(self:combatTalentScale(t, 1.2, 2.1, "log")) + return math.ceil(self:combatTalentScale(t, 1.0, 3.0, "log")) end, getDamage = function (self, t) return math.floor(self:combatTalentMindDamage(t, 10, 200)) @@ -483,9 +483,8 @@ newTalent{ local targets = t.getTargNum(self,t) local dur = t.duration(self,t) return ([[Overcharge your psionic focus with energy for %d turns, producing a different effect depending on what it is. - A telekinetically wielded weapon enters a frenzy, striking up to %d targets every turn, also increases the radius by %d. - A mindstar will attempt to pull in all enemies within its normal range. - A gem will fire an energy bolt at a random enemy in range 6, each turn for %0.1f damage. The type is determined by the colour of the gem. Damage scales with Mindpower.]]): + A telekinetically wielded weapon enters a frenzy, striking up to %d times every turn, also increases the radius by %d. + A mindstar or a gem will fire an energy bolt at a random enemy in range 6, each turn for %0.1f damage. The type is determined by the colour of the gem or mindstar base damage. Damage scales with Mindpower. The mindstar will stop its normal attacks.]]): format(dur, targets, targets, t.getDamage(self,t)) end, } diff --git a/game/modules/tome/data/talents/psionic/psi-fighting.lua b/game/modules/tome/data/talents/psionic/psi-fighting.lua index 4619e0f00ff969a24526009aa9102e6f1301e2e4..356b564b717575cb29d3d279b9d2b7643b552ec3 100644 --- a/game/modules/tome/data/talents/psionic/psi-fighting.lua +++ b/game/modules/tome/data/talents/psionic/psi-fighting.lua @@ -110,6 +110,7 @@ newTalent{ no_energy = true, tactical = { BUFF = 2 }, getWeaponDamage = function(self, t) return self:combatTalentWeaponDamage(t, 0.75, 1.1) end, + getChance = function(self, t) return math.floor(self:combatStatScale("cun", 1, 30)) end, action = function(self, t) self:setEffect(self.EFF_WEAPON_WARDING, 1, {}) return true @@ -117,9 +118,10 @@ newTalent{ info = function(self, t) return ([[Assume a defensive mental state. For one turn, you will fully block the next melee attack used against you with your telekinetically-wielded weapon and then strike the attacker with it for %d%% weapon damage. - At talent level 3 you will also disarm the attacker for 3 turns. - This requires both a mainhand and a telekinetically-wielded weapon.]]): - format(100 * t.getWeaponDamage(self, t)) + At raw talent level 3 you will also disarm the attacker for 3 turns. + At raw talent level 5 you will be able to reflexively block up to one attack per turn with a %d%% chance, based on your cunning. Each trigger requires and uses 15 Psi. + This requires a telekinetically-wielded weapon.]]): + format(100 * t.getWeaponDamage(self, t), t.getChance(self, t)) end, } diff --git a/game/modules/tome/data/talents/psionic/thermal-mastery.lua b/game/modules/tome/data/talents/psionic/thermal-mastery.lua index 508e9827248de50d6f004275742dfa1c0364b76a..9a16dd093cc5627fedbbc4b779e5a09ddccac8ed 100644 --- a/game/modules/tome/data/talents/psionic/thermal-mastery.lua +++ b/game/modules/tome/data/talents/psionic/thermal-mastery.lua @@ -155,8 +155,8 @@ newTalent{ cooldown = 10, range = function(self,t) return self:combatTalentScale(t, 4, 6) end, radius = function(self,t) return self:combatTalentScale(t, 2, 4) end, - tactical = { ATTACKAREA = { FIRE = 2, COLD = 2 } }, - getDamage = function(self, t) return self:combatTalentMindDamage(t, 30, 300) end, + tactical = { ATTACKAREA = { FIRE = 3, COLD = 2 }, PSI = 2 }, + getDamage = function(self, t) return self:combatTalentMindDamage(t, 50, 150) end, action = function(self, t) local tg = {type="ball", range=self:getTalentRange(t), selffire=false, radius=self:getTalentRadius(t), talent=t} local x, y = self:getTarget(tg) @@ -180,7 +180,7 @@ newTalent{ info = function(self, t) local dam = t.getDamage(self, t) local dam1 = dam * (self:getMaxPsi() - self:getPsi()) / self:getMaxPsi() - local dam2 = dam * self:getPsi() / self:getMaxPsi() + local dam2 = dam * self:getPsi() / self:getMaxPsi() * 2 return ([[You seek balance between fire and cold based on your current Psi level. You blast your foes with %0.1f Fire damage based on your current Psi, %0.1f Cold damage based on your max Psi minus your current Psi, in a radius %d ball. This sets your current Psi to half of your maximum Psi. diff --git a/game/modules/tome/data/talents/psionic/voracity.lua b/game/modules/tome/data/talents/psionic/voracity.lua index 97f665bf90488dd1c8aa0237d29a24ae4715ae1d..dd766be58ac83c765f75b10c1f867103eae5f75e 100644 --- a/game/modules/tome/data/talents/psionic/voracity.lua +++ b/game/modules/tome/data/talents/psionic/voracity.lua @@ -37,11 +37,11 @@ newTalent{ end, getLeech = function(self, t, psi) local psi = psi or self:getPsi() - return self:combatTalentScale(t, 10, 27)*math.max(0.5, (1.5-psi/self:getMaxPsi())) + return self:combatTalentScale(t, 10, 20)*math.max(0.5, (1.5-psi/self:getMaxPsi())) end, getDam = function(self, t, psi) local psi = psi or self:getPsi() - return self:combatTalentMindDamage(t, 20, 200)*math.max(0.5, (1.5-psi/self:getMaxPsi())) --this looks high + return self:combatTalentMindDamage(t, 5, 45)*math.max(0.5, (1.5-psi/self:getMaxPsi())) --this looks high end, getSlow = function(self, t, psi) local psi = psi or self:getPsi() @@ -103,11 +103,11 @@ newTalent{ end, getLeech = function(self, t, psi) local psi = psi or self:getPsi() - return self:combatTalentScale(t, 10, 27)*math.max(0.5, (1.5-psi/self:getMaxPsi())) + return self:combatTalentScale(t, 10, 20)*math.max(0.5, (1.5-psi/self:getMaxPsi())) end, getDam = function(self, t, psi) local psi = psi or self:getPsi() - return self:combatTalentMindDamage(t, 20, 200)*math.max(0.5, (1.5-psi/self:getMaxPsi())) + return self:combatTalentMindDamage(t, 20, 130)*math.max(0.5, (1.5-psi/self:getMaxPsi())) end, getDur = function(self, t, psi) local psi = psi or self:getPsi() @@ -163,11 +163,11 @@ newTalent{ end, getLeech = function(self, t, psi) local psi = psi or self:getPsi() - return self:combatTalentScale(t, 10, 27)*math.max(0.5, (1.5-psi/self:getMaxPsi())) + return self:combatTalentScale(t, 10, 20)*math.max(0.5, (1.5-psi/self:getMaxPsi())) end, getDam = function(self, t, psi) local psi = psi or self:getPsi() - return self:combatTalentMindDamage(t, 20, 200)*math.max(0.5, (1.5-psi/self:getMaxPsi())) + return self:combatTalentMindDamage(t, 20, 130)*math.max(0.5, (1.5-psi/self:getMaxPsi())) end, getDaze = function(self, t, psi) local psi = psi or self:getPsi() @@ -222,13 +222,13 @@ newTalent{ getPsiRecover = function(self, t) return self:combatTalentScale(t, 1.5, 5, 0.75) end, passives = function(self, t, p) local recover = t.getPsiRecover(self, t) - self:talentTemporaryValue(p, "max_psi", self:getTalentLevel(t)*10) + self:talentTemporaryValue(p, "max_psi", recover*5) self:talentTemporaryValue(p, "psi_per_kill", recover) self:talentTemporaryValue(p, "psi_on_crit", recover*0.5) end, info = function(self, t) local recover = t.getPsiRecover(self, t) - return ([[Increases your maximum energy by %d. You also gain %0.1f Psi for each kill and %0.1f Psi for each mind critical.]]):format(10 * self:getTalentLevel(t), recover, 0.5*recover) + return ([[Increases your maximum energy by %d. You also gain %0.1f Psi for each kill and %0.1f Psi for each mind critical.]]):format(5 * recover, recover, 0.5*recover) end, } diff --git a/game/modules/tome/data/timed_effects/mental.lua b/game/modules/tome/data/timed_effects/mental.lua index a3ea9d68b2df2224daa3d7f3574cfcf1cb46ec7b..ca2b508f6def15f55477a3b8bf49c3a22892a6e5 100644 --- a/game/modules/tome/data/timed_effects/mental.lua +++ b/game/modules/tome/data/timed_effects/mental.lua @@ -1336,7 +1336,7 @@ newEffect{ newEffect{ name = "QUICKNESS", image = "effects/quickness.png", desc = "Quick", - long_desc = function(self, eff) return ("Increases physical attack speed by %d%%."):format(eff.power * 100) end, + long_desc = function(self, eff) return ("Increases global speed by %d%%."):format(eff.power * 100) end, type = "mental", subtype = { telekinesis=true, speed=true }, status = "beneficial", @@ -1344,12 +1344,13 @@ newEffect{ on_gain = function(self, err) return "#Target# speeds up.", "+Quick" end, on_lose = function(self, err) return "#Target# slows down.", "-Quick" end, activate = function(self, eff) - eff.tmpid = self:addTemporaryValue("combat_physspeed", eff.power) + eff.tmpid = self:addTemporaryValue("global_speed_add", eff.power) end, deactivate = function(self, eff) - self:removeTemporaryValue("combat_physspeed", eff.tmpid) + self:removeTemporaryValue("global_speed_add", eff.tmpid) end, } + newEffect{ name = "PSIFRENZY", image = "talents/frenzied_focus.png", desc = "Frenzied Focus", @@ -3118,6 +3119,7 @@ newEffect{ on_lose = function(self, eff) return nil, nil end, on_merge = function(self, old_eff, new_eff) old_eff.power = new_eff.power + old_eff.power + old_eff.dur = new_eff.dur return old_eff end, activate = function(self, eff)