diff --git a/game/modules/tome/data/chats/assassin-lord.lua b/game/modules/tome/data/chats/assassin-lord.lua index da45ffc54920178e38dfaa754ea1edcd652166e0..7020e6637b5845b21b25d5d64b01ddb1b67d9b51 100644 --- a/game/modules/tome/data/chats/assassin-lord.lua +++ b/game/modules/tome/data/chats/assassin-lord.lua @@ -29,6 +29,11 @@ local function evil(npc, player) p:learnTalentType("cunning/poisons", true) p:setTalentTypeMastery("cunning/poisons", 1.3) end + elseif p.descriptor.subclass == "Marauder" or p.descriptor.subclass == "Archer" or p.descriptor.subclass == "Skirmisher" then + if p:knowTalentType("cunning/poisons") == nil then + p:learnTalentType("cunning/poisons", false) + if p.descriptor.subclass == "Skirmisher" then p:setTalentTypeMastery("cunning/poisons", 1.3) end + end end if p:knowTalentType("cunning/trapping") then game.log("#LIGHT_GREEN#You and the Lord discuss your new relationship at some length, including the merits of assassination by proxy and some additional trapping techniques.") diff --git a/game/modules/tome/data/general/events/meteor.lua b/game/modules/tome/data/general/events/meteor.lua index fa1f385908ccab5b9439826cea36a07d3a987238..21a8bcdfce8cd04c34ac3104dac904942e10b7eb 100644 --- a/game/modules/tome/data/general/events/meteor.lua +++ b/game/modules/tome/data/general/events/meteor.lua @@ -1,5 +1,5 @@ -- ToME - Tales of Maj'Eyal --- Copyright (C) 2009 - 2019 Nicolas Casalini +-- Copyright (C) 2009 - 2017 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 @@ -57,39 +57,38 @@ game.zone.on_turn = function() game.zone.meteor_event_levels[game.level.level] = nil - game.level.map:particleEmitter(game.level.data.meteor_x, game.level.data.meteor_y, 10, "meteor").on_remove = function() - local x, y = game.level.data.meteor_x, game.level.data.meteor_y - game.level.map:particleEmitter(x, y, 5, "fireflash", {radius=5}) - game:playSoundNear(game.player, "talents/fireflash") - - local terrains = mod.class.Grid:loadList("/data/general/grids/lava.lua") - local npcs = mod.class.NPC:loadList("/data/general/npcs/losgoroth.lua") - - for i = x-2, x+2 do for j = y-2, y+2 do - local og = game.level.map(i, j, engine.Map.TERRAIN) - if (core.fov.distance(x, y, i, j) <= 1 or rng.percent(40)) and og and not og.escort_portal then - local g = terrains.LAVA_FLOOR:clone() - g:resolve() g:resolve(nil, true) - game.zone:addEntity(game.level, g, "terrain", i, j) - - if rng.percent(30) and not game.level.map(i, j, engine.Map.ACTOR) then - local m = game.zone:makeEntity(game.level, "actor", {base_list=npcs}, nil, true) - if m then - m.resists = m.resists or {} - m.resists[engine.DamageType.FIRE] = 100 - game.zone:addEntity(game.level, m, "actor", i, j) - end + game.level.map:particleEmitter(game.level.data.meteor_x, game.level.data.meteor_y, 10, "meteor") + local x, y = game.level.data.meteor_x, game.level.data.meteor_y + game.level.map:particleEmitter(x, y, 5, "fireflash", {radius=5}) + game:playSoundNear(game.player, "talents/fireflash") + + local terrains = mod.class.Grid:loadList("/data/general/grids/lava.lua") + local npcs = mod.class.NPC:loadList("/data/general/npcs/losgoroth.lua") + + for i = x-2, x+2 do for j = y-2, y+2 do + local og = game.level.map(i, j, engine.Map.TERRAIN) + if (core.fov.distance(x, y, i, j) <= 1 or rng.percent(40)) and og and not og.escort_portal then + local g = terrains.LAVA_FLOOR:clone() + g:resolve() g:resolve(nil, true) + game.zone:addEntity(game.level, g, "terrain", i, j) + + if rng.percent(30) and not game.level.map(i, j, engine.Map.ACTOR) then + local m = game.zone:makeEntity(game.level, "actor", {base_list=npcs}, nil, true) + if m then + m.resists = m.resists or {} + m.resists[engine.DamageType.FIRE] = 100 + game.zone:addEntity(game.level, m, "actor", i, j) end end - end end - for i = x-2, x+2 do for j = y-2, y+2 do - game.nicer_tiles:updateAround(game.level, i, j) - end end - - world:gainAchievement("EVENT_METEOR", game:getPlayer(true)) - game:getPlayer(true):attr("meteoric_crash", 1) - require("engine.ui.Dialog"):simplePopup(_t"Meteor!", _t"As you walk you notice a huge rock falling from the sky. It crashes right near you!") - end + end + end end + for i = x-2, x+2 do for j = y-2, y+2 do + game.nicer_tiles:updateAround(game.level, i, j) + end end + + world:gainAchievement("EVENT_METEOR", game:getPlayer(true)) + game:getPlayer(true):attr("meteoric_crash", 1) + require("engine.ui.Dialog"):simplePopup("Meteor!", "As you walk you notice a huge rock falling from the sky. It crashes right near you!") end return true diff --git a/game/modules/tome/data/general/events/pyroclast.lua b/game/modules/tome/data/general/events/pyroclast.lua index ae2b3f2a8b0ac58db5a3ab81ac4b6b69144d29a0..d225be9692e25a091d6af3c6c56ed396272f205d 100644 --- a/game/modules/tome/data/general/events/pyroclast.lua +++ b/game/modules/tome/data/general/events/pyroclast.lua @@ -1,5 +1,5 @@ -- ToME - Tales of Maj'Eyal --- Copyright (C) 2009 - 2019 Nicolas Casalini +-- Copyright (C) 2009 - 2017 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 @@ -70,23 +70,22 @@ if not game.zone.pyroclast_event_on_turn then table.remove(game.zone.pyroclast_event_levels[game.level.level], si) game.level.data.meteor_x, game.level.data.meteor_y = x, y - game.level.map:particleEmitter(game.level.data.meteor_x, game.level.data.meteor_y, 10, "meteor").on_remove = function() - local x, y = game.level.data.meteor_x, game.level.data.meteor_y - game.level.map:particleEmitter(x, y, 5, "fireflash", {radius=5}) - game:playSoundNear(game.player, "talents/fireflash") + game.level.map:particleEmitter(game.level.data.meteor_x, game.level.data.meteor_y, 10, "meteor") + local x, y = game.level.data.meteor_x, game.level.data.meteor_y + game.level.map:particleEmitter(x, y, 5, "fireflash", {radius=5}) + game:playSoundNear(game.player, "talents/fireflash") - for i = x-2, x+2 do for j = y-2, y+2 do - local og = game.level.map(i, j, engine.Map.TERRAIN) - if (core.fov.distance(x, y, i, j) <= 1 or rng.percent(40)) and og and not og.escort_portal and not og.change_level and not og.special then - local g = game.zone.grid_list.LAVA_FLOOR:clone() - g:resolve() g:resolve(nil, true) - game.zone:addEntity(game.level, g, "terrain", i, j) - end - end end - for i = x-2, x+2 do for j = y-2, y+2 do - game.nicer_tiles:updateAround(game.level, i, j) - end end - end + for i = x-2, x+2 do for j = y-2, y+2 do + local og = game.level.map(i, j, engine.Map.TERRAIN) + if (core.fov.distance(x, y, i, j) <= 1 or rng.percent(40)) and og and not og.escort_portal and not og.change_level and not og.special then + local g = game.zone.grid_list.LAVA_FLOOR:clone() + g:resolve() g:resolve(nil, true) + game.zone:addEntity(game.level, g, "terrain", i, j) + end + end end + for i = x-2, x+2 do for j = y-2, y+2 do + game.nicer_tiles:updateAround(game.level, i, j) + end end end end return true diff --git a/game/modules/tome/data/general/objects/egos/amulets.lua b/game/modules/tome/data/general/objects/egos/amulets.lua index e35fa3d99b71f1b1fabe02d7fa5dc6eab6d98760..6016981bd593d38245b0ebda3593bac5d3827fd4 100644 --- a/game/modules/tome/data/general/objects/egos/amulets.lua +++ b/game/modules/tome/data/general/objects/egos/amulets.lua @@ -113,9 +113,9 @@ newEntity{ local tt = rng.table(tts) if not tt then tt = "technique/combat-training" end - e.wielder.talents_types_mastery = {} + e.wielder.talents_types_mastery = e.wielder.talents_types_mastery or {} local v = (10 + rng.mbonus(math.ceil(30 * e.material_level / 5), resolvers.current_level, 50)) / 100 - e.wielder.talents_types_mastery[tt] = v + e.wielder.talents_types_mastery[tt] = (e.wielder.talents_types_mastery[tt] or 0) + v e.cost = e.cost + v * 60 end), } @@ -552,10 +552,10 @@ newEntity{ local tt = rng.tableRemove(tts) local tt2 = rng.tableRemove(tts) - e.wielder.talents_types_mastery = {} + e.wielder.talents_types_mastery = e.wielder.talents_types_mastery or {} local v = (10 + rng.mbonus(math.ceil(30 * e.material_level / 5), resolvers.current_level, 50)) / 100 - if tt then e.wielder.talents_types_mastery[tt] = v end - if tt2 then e.wielder.talents_types_mastery[tt2] = v end + if tt then e.wielder.talents_types_mastery[tt] = (e.wielder.talents_types_mastery[tt] or 0) + v end + if tt2 then e.wielder.talents_types_mastery[tt2] = (e.wielder.talents_types_mastery[tt2] or 0) + v end e.cost = e.cost + v * 60 end), } \ No newline at end of file diff --git a/game/modules/tome/data/gfx/particles/meteor.lua b/game/modules/tome/data/gfx/particles/meteor.lua index 921f56ccf0fc205e6b4163cd009cff397e53e16c..e48ad832ffe4325fdbea332a017dbfc0cdce769a 100644 --- a/game/modules/tome/data/gfx/particles/meteor.lua +++ b/game/modules/tome/data/gfx/particles/meteor.lua @@ -1,5 +1,5 @@ -- ToME - Tales of Maj'Eyal --- Copyright (C) 2009 - 2019 Nicolas Casalini +-- Copyright (C) 2009 - 2017 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 @@ -17,6 +17,8 @@ -- Nicolas Casalini "DarkGod" -- darkgod@te4.org +-- Changed to be very fast, with a longer tail to compensate. + local nb = 1 return { generator = function() @@ -26,7 +28,7 @@ return { generator = function() local x = sradius * math.cos(a) local y = sradius * math.sin(a) a = math.rad(ad + 180) - local life = 10 + local life = 5 return { trail = 1, @@ -51,4 +53,4 @@ function(self) end end, 1, -"shockbolt/object/lava_boulder" +"shockbolt/object/lava_boulder" \ No newline at end of file diff --git a/game/modules/tome/data/talents/celestial/combat.lua b/game/modules/tome/data/talents/celestial/combat.lua index b5c29cbfecfc8ab7611f21624c0868445b5b4c35..1e302abe3d5560c0ee835e456f561454072669c0 100644 --- a/game/modules/tome/data/talents/celestial/combat.lua +++ b/game/modules/tome/data/talents/celestial/combat.lua @@ -127,7 +127,7 @@ newTalent{ points = 5, cooldown = 10, sustain_positive = 10, - rnd_boss_restrict = true, -- martyrdom is fine on fixedbosses specifically given the talents but let's avoid it on randbosses + rnd_boss_restrict = function(self, t, data) return true end, -- martyrdom is fine on fixedbosses specifically given the talents but let's avoid it on randbosses tactical = { BUFF = 2 }, range = 10, getMartyrDamage = function(self, t) return self:combatTalentLimit(t, 50, 5, 25) end, --Limit < 50% diff --git a/game/modules/tome/data/talents/corruptions/vile-life.lua b/game/modules/tome/data/talents/corruptions/vile-life.lua index 3bf4ba6013e755b0d3aad9338f64e7f39ec86e2e..d830930c566de0c00602d3dbb9d432933108bbe4 100644 --- a/game/modules/tome/data/talents/corruptions/vile-life.lua +++ b/game/modules/tome/data/talents/corruptions/vile-life.lua @@ -134,7 +134,7 @@ newTalent{ vim = 16, range = 8, radius = 4, - tactical = { DISABLE = 2 }, + no_npc_use = true, direct_hit = true, requires_target = true, target = function(self, t) return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t), friendlyfire=false, talent=t} end, diff --git a/game/modules/tome/data/talents/cursed/force-of-will.lua b/game/modules/tome/data/talents/cursed/force-of-will.lua index 9d6c6e315034fb794166dd17ee5f8195563ca499..0da01362e8a4b96206e955adabfe51ced64e7e37 100644 --- a/game/modules/tome/data/talents/cursed/force-of-will.lua +++ b/game/modules/tome/data/talents/cursed/force-of-will.lua @@ -269,24 +269,28 @@ newTalent{ local blastX, blastY = self:getTarget(tg) if not self:canProject(tg, blastX, blastY) then return nil end - local list = {} - self:project(tg, blastX, blastY, function(x, y, target, self) - -- your will ignores friendly targets (except for knockback hits) - local target = game.level.map(x, y, Map.ACTOR) - if target and self:reactionToward(target) < 0 then - local distance = core.fov.distance(blastX, blastY, x, y) - local power = 1 - 0.5 * (distance / radius) - list[#list + 1] = {target = target, power = power, damage = damage * power, knockback = math.max(0, knockback - distance)} - end - end) + local tmp = {} + local targets = {} + local grids = self:project(tg, blastX, blastY, + function(x, y, target, self) + -- your will ignores friendly targets (except for knockback hits) + local target = game.level.map(x, y, Map.ACTOR) + if target and self:reactionToward(target) < 0 then + targets[#targets+1] = target - if #list == 0 then return end - local dazeDuration = t.getDazeDuration(self, t) - for i = 1, #list do - local hit = list[i] - self:callTalent(self.T_WILLFUL_STRIKE, "forceHit", hit.target, blastX, blastY, hit.damage, hit.knockback, 7, hit.power, 10) - if hit.target:canBe("stun") then - hit.target:setEffect(hit.target.EFF_DAZED, dazeDuration, {src=self}) + end + end, + nil, nil) + + for _,target in ipairs(targets) do + local distance = core.fov.distance(blastX, blastY, target.x, target.y) + local power = (1 - (distance / radius)) + local localDamage = damage * power + local dazeDuration = t.getDazeDuration(self, t) + + self:callTalent(self.T_WILLFUL_STRIKE, "forceHit", target, blastX, blastY, damage, math.max(0, knockback - distance), 7, power, 10, tmp) + if target:canBe("stun") then + target:setEffect(target.EFF_DAZED, dazeDuration, {src=self}) end end diff --git a/game/modules/tome/data/talents/psionic/dream-smith.lua b/game/modules/tome/data/talents/psionic/dream-smith.lua index cc5b7b735bb1ad20460f69e243e67e5d54b409e5..0f7e5deb28faf2ad38612abe42e9fa7db9cbd526 100644 --- a/game/modules/tome/data/talents/psionic/dream-smith.lua +++ b/game/modules/tome/data/talents/psionic/dream-smith.lua @@ -147,6 +147,8 @@ newTalent{ local x, y = self:getTarget(tg) if not x or not y then return nil end local _ _, x, y = self:canProject(tg, x, y) + tg.toss_end_x = x + tg.toss_end_y = y print("[Dream Hammer Throw] Projection from", self.x, self.y, "to", x, y) self:projectile(tg, x, y, function(px, py, tg, self) @@ -155,7 +157,7 @@ newTalent{ local t = self:getTalentFromId(self.T_HAMMER_TOSS) self:attackTargetWith(tmp_target, t.getDreamHammer(self, t), nil, t.getDamage(self, t)) end - if x == px and y == py and self and self.x and self.y then + if tg.toss_end_x == px and tg.toss_end_y == py and self and self.x and self.y then print("[Dream Hammer Return] Projection from", x, y, "to", self.x, self.y) local tgr = tg tgr.name = _t"Hammer Toss" diff --git a/game/modules/tome/data/talents/spells/glacial-waste.lua b/game/modules/tome/data/talents/spells/glacial-waste.lua index 33dbb0d284495fcc732b2cd8bda2aac8523ba4ee..9b16c7e1bee25c634079b6a031a3da8cdb77df00 100644 --- a/game/modules/tome/data/talents/spells/glacial-waste.lua +++ b/game/modules/tome/data/talents/spells/glacial-waste.lua @@ -74,7 +74,7 @@ newTalent{ soul = self:alterTalentCost(t, "soul", soul) if self:getSoul() < soul or self:getMana() < mana then - game.logPlayer(self, "#GREY#Your hiemal shield does not have enough ressources!") + game.logPlayer(self, "#GREY#Your hiemal shield does not have enough resources!") self:forceUseTalent(t.id, {ignore_energy=true}) else game.logPlayer(self, "#GREY#Your hiemal shield regenerates to full!") diff --git a/game/modules/tome/data/talents/spells/master-of-flesh.lua b/game/modules/tome/data/talents/spells/master-of-flesh.lua index 96376cd08f8b775d7eddb6ea8d18a8a8578eb861..7962091162dbfb32c87ea97fa4d08f52d9ee3371 100644 --- a/game/modules/tome/data/talents/spells/master-of-flesh.lua +++ b/game/modules/tome/data/talents/spells/master-of-flesh.lua @@ -348,7 +348,7 @@ newTalent{ Only one ghoul may explode per turn. The one with the least time left to live is always the first to do so. The damage and disease power is increased by your Spellpower. ]]): - tformat(t:_getDur(self), damDesc(self, DamageType.FROSTDUSK, t:_getDamage(self)), damDesc(self, DamageType.BLIGHT, t:_getDamage(self)), t:_getDiseasePower(self), self:getTalentRadius(t)) + tformat(t:_getDur(self), damDesc(self, DamageType.FROSTDUSK, t:_getDamage(self)), self:getTalentRadius(t), damDesc(self, DamageType.BLIGHT, t:_getDamage(self)), t:_getDiseasePower(self)) end, } diff --git a/game/modules/tome/data/talents/uber/wil.lua b/game/modules/tome/data/talents/uber/wil.lua index 310c3bfe7619b93e798c865394d0b3064c85d2e5..b10700cdf01601dd57cc314bfa7b3b4709449f36 100644 --- a/game/modules/tome/data/talents/uber/wil.lua +++ b/game/modules/tome/data/talents/uber/wil.lua @@ -57,7 +57,7 @@ uberTalent{ local lava_dam = t.getLava(self, t) local dam = t.getDamage(self, t) if self:combatMindCrit() > self:combatSpellCrit() then - _dam = self:mindCrit(dam) + dam = self:mindCrit(dam) lava_dam = self:mindCrit(lava_dam) else dam = self:spellCrit(dam) diff --git a/game/modules/tome/data/zones/demon-plane/npcs.lua b/game/modules/tome/data/zones/demon-plane/npcs.lua index 6b7cc92c695cab75c58d98b208bb2a1ca9f0772f..f801379692b6431381854804172237a2a2006c66 100644 --- a/game/modules/tome/data/zones/demon-plane/npcs.lua +++ b/game/modules/tome/data/zones/demon-plane/npcs.lua @@ -81,6 +81,11 @@ newEntity{ define_as = "DRAEBOR", on_die = function(self, who) require("engine.ui.Dialog"):simplePopup(_t"Back and there again", _t"As the annoying imp falls a portal appears under its corpse.") local g = game.zone:makeEntityByName(game.level, "terrain", "PORTAL_BACK") - game.zone:addEntity(game.level, g, "terrain", self.x, self.y) + local oe = game.level.map(self.x, self.y, engine.Map.TERRAIN) + if oe:attr("temporary") and oe.old_feat then + oe.old_feat = g + else + game.zone:addEntity(game.level, g, "terrain", self.x, self.y) + end end, } diff --git a/game/modules/tome/data/zones/unhallowed-morass/npcs.lua b/game/modules/tome/data/zones/unhallowed-morass/npcs.lua index 48da3838fa289ebc37db3f5f6b9b15ccaee5c73d..ca52de3b9d33df3331d100761d0bf821cb6bdf39 100644 --- a/game/modules/tome/data/zones/unhallowed-morass/npcs.lua +++ b/game/modules/tome/data/zones/unhallowed-morass/npcs.lua @@ -163,7 +163,13 @@ newEntity{ base = "BASE_NPC_SPIDER", define_as = "WEAVER_QUEEN", on_die = function(self, who) game.player:resolveSource():setQuestStatus("start-point-zero", engine.Quest.COMPLETED, "morass") require("engine.ui.Dialog"):simplePopup(_t"Weaver Queen", _t"As you vanquish the queen you notice a temporal thread that seems to have been controlling her. It seems to go through a rift.") - local rift = game.zone:makeEntityByName(game.level, "terrain", "RIFT_HOME") - game.zone:addEntity(game.level, rift, "terrain", self.x, self.y) + + local g = game.zone:makeEntityByName(game.level, "terrain", "RIFT_HOME") + local oe = game.level.map(self.x, self.y, engine.Map.TERRAIN) + if oe:attr("temporary") and oe.old_feat then + oe.old_feat = g + else + game.zone:addEntity(game.level, g, "terrain", self.x, self.y) + end end, }