diff --git a/game/engines/default/engine/ui/Base.lua b/game/engines/default/engine/ui/Base.lua index 627074f6b6060ed03e820f8a10740389e3b3e399..ce071c0ebc4b5336315aac60c04930cd48035627 100644 --- a/game/engines/default/engine/ui/Base.lua +++ b/game/engines/default/engine/ui/Base.lua @@ -50,10 +50,12 @@ _M.ui_conf = {} function _M:loadUIDefinitions(file) local f, err = loadfile(file) - if not f then print("Error while loading UI definition from", file, ":", err) return end + if not f then error("Error while loading UI definition from", file, ":", err) return end + self.ui_conf.def = self.ui_conf setfenv(f, self.ui_conf) local ok, err = pcall(f) - if not f then print("Error while loading UI definition from", file, ":", err) return end + self.ui_conf.def = nil + if not f then error("Error while loading UI definition from", file, ":", err) return end end function _M:uiExists(ui) diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index dca955c76aad1756bf13fc9e88c3320ee6151197..5b02817a610f6140555e9e9782f6cb2bdf5e516c 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -2014,7 +2014,7 @@ end --- Regenerate life, call it from your actor class act() method function _M:regenLife() - if self.life_regen and not self:attr("no_life_regen") then + if self.life_regen then local regen = self.life_regen * util.bound((self.healing_factor or 1), 0, 2.5) -- Solipsism @@ -2029,11 +2029,13 @@ function _M:regenLife() end end - self.life = util.bound(self.life + regen, self.die_at, self.max_life) + if not self:attr("no_life_regen") then + self.life = util.bound(self.life + regen, self.die_at, self.max_life) - -- Blood Lock - if self:attr("blood_lock") then - self.life = util.bound(self.life, self.die_at, self:attr("blood_lock")) + -- Blood Lock + if self:attr("blood_lock") then + self.life = util.bound(self.life, self.die_at, self:attr("blood_lock")) + end end end end @@ -2052,11 +2054,21 @@ end --- Called before healing function _M:onHeal(value, src) + value = value * util.bound((self.healing_factor or 1), 0, 2.5) + + -- Solipsism healing + local psi_heal = 0 + if self:knowTalent(self.T_SOLIPSISM) then + local t = self:getTalentFromId(self.T_SOLIPSISM) + local ratio = t.getConversionRatio(self, t) + psi_heal = value * ratio + self:incPsi(psi_heal) + value = value - psi_heal + end + if self:hasEffect(self.EFF_UNSTOPPABLE) then return 0 end if self:attr("no_healing") then return 0 end - value = value * util.bound((self.healing_factor or 1), 0, 2.5) - --if self:attr("stunned") then value = value / 2 end local eff = self:hasEffect(self.EFF_HEALING_NEXUS) @@ -2083,16 +2095,6 @@ function _M:onHeal(value, src) self:setEffect(self.EFF_REGENERATION, 6, {power=(value * self.fungal_growth / 100) / 6, no_wild_growth=true}) end - -- Solipsism healing - local psi_heal = 0 - if self:knowTalent(self.T_SOLIPSISM) then - local t = self:getTalentFromId(self.T_SOLIPSISM) - local ratio = t.getConversionRatio(self, t) - psi_heal = value * ratio - self:incPsi(psi_heal) - value = value - psi_heal - end - -- Must be last! if self:attr("blood_lock") then if self.life + value > self:attr("blood_lock") then diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index 6cd05ba63d56b3c83377fa6cbed0856185867de9..ddc5af60762fff0d9e8fa0f34d9a788bcb0057c0 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -789,7 +789,7 @@ end function _M:changeLevel(lev, zone, params) params = params or {} - if self:getPlayer(true).last_kill_turn and self:getPlayer(true).last_kill_turn >= self.turn - self:noStairsTime() then + if not params.direct_switch and (self:getPlayer(true).last_kill_turn and self:getPlayer(true).last_kill_turn >= self.turn - self:noStairsTime()) then local left = math.ceil((10 + self:getPlayer(true).last_kill_turn - self.turn + self:noStairsTime()) / 10) self.logPlayer(self.player, "#LIGHT_RED#You may not change level so soon after a kill (%d game turns left to wait)!", left) return diff --git a/game/modules/tome/class/GameState.lua b/game/modules/tome/class/GameState.lua index 4abd8fe5147e52519cfda2692c5dfb0cc02eb9b1..91de7a3b43fcbadcf16ab832ce7dc7fb45e0d4c7 100644 --- a/game/modules/tome/class/GameState.lua +++ b/game/modules/tome/class/GameState.lua @@ -2532,6 +2532,7 @@ function _M:makeChallengeQuest(level, name, desc, data, alter_effect) local q = { id = "id-challenge-"..level.level, name = "Infinite Dungeon Challenge: "..name.." (Level "..level.level..")", + use_ui = "quest-idchallenge", challenge_desc = desc, desc = function(self, who) local desc = {} diff --git a/game/modules/tome/class/interface/Archery.lua b/game/modules/tome/class/interface/Archery.lua index 3ad78b06ddf0de2ecbaefd41deee099ee2f4398f..04762f517ae5209e58500fd2994f6c62a7550bfc 100644 --- a/game/modules/tome/class/interface/Archery.lua +++ b/game/modules/tome/class/interface/Archery.lua @@ -48,7 +48,8 @@ function _M:archery_range(t, type) return 1 end end - return math.max(weapon and weapon.combat.range or 6, offweapon and offweapon.combat and offweapon.combat.range or 0, pf_weapon and pf_weapon.combat and pf_weapon.combat.range or 0, self:attr("archery_range_override") or 0) + local br = (self.archery_bonus_range or 0) + return math.max(weapon and br + weapon.combat.range or 6, offweapon and offweapon.combat and br + offweapon.combat.range or 0, pf_weapon and pf_weapon.combat and br + pf_weapon.combat.range or 0, self:attr("archery_range_override") or 0) end --- Look for possible archery targets @@ -81,7 +82,7 @@ function _M:archeryAcquireTargets(tg, params) game.logPlayer(self, "You do not have enough ammo left!") return nil end - + local br = (self.archery_bonus_range or 0) print("[ARCHERY ACQUIRE TARGETS WITH]", weapon and weapon.name, ammo.name, offweapon and offweapon.name, pf_weapon and pf_weapon.name) tg = tg or {} local max_range, warn_range = self:attr("archery_range_override") or 1, 40 @@ -90,7 +91,7 @@ function _M:archeryAcquireTargets(tg, params) local use_resources if weapon then weaponC = weapon.combat - max_range = math.max(max_range, weaponC.range or 6) + max_range = math.max(max_range, weaponC.range or 6) warn_range = math.min(warn_range, weaponC.range or 6) -- check resources use_resources = (weaponC.use_resources or ammo.combat.use_resources) and table.mergeAdd(table.clone(weaponC.use_resources) or {}, ammo.combat.use_resources or {}) or nil @@ -105,7 +106,7 @@ function _M:archeryAcquireTargets(tg, params) end if offweapon then offweaponC = offweapon.combat - max_range = math.max(max_range, offweaponC.range or 6) + max_range = math.max(max_range, offweaponC.range or 6) warn_range = math.min(warn_range, offweaponC.range or 6) use_resources = (offweaponC.use_resources or ammo.combat.use_resources) and table.mergeAdd(table.clone(offweaponC.use_resources) or {}, ammo.combat.use_resources or {}) or nil if use_resources then @@ -119,7 +120,7 @@ function _M:archeryAcquireTargets(tg, params) end if pf_weapon then pf_weaponC = pf_weapon.combat - max_range = math.max(max_range, pf_weaponC.range or 6) + max_range = math.max(max_range, pf_weaponC.range or 6) warn_range = math.min(warn_range, pf_weaponC.range or 6) use_resources = (pf_weaponC.use_resources or ammo.combat.use_resources) and table.mergeAdd(table.clone(pf_weaponC.use_resources) or {}, ammo.combat.use_resources or {}) or nil if use_resources then @@ -136,9 +137,9 @@ function _M:archeryAcquireTargets(tg, params) -- at least one shot is possible, set up targeting tg.type = tg.type or weaponC and weaponC.tg_type or offweaponC and offweaponC.tg_type or pf_weaponC and pf_weaponC.tg_type or ammo.combat.tg_type or "bolt" if tg.range then - tg.warn_range, tg.max_range = math.min(tg.range, warn_range), math.min(tg.range, max_range) + tg.warn_range, tg.max_range = br + math.min(tg.range, warn_range), br + math.min(tg.range, max_range) else - tg.warn_range, tg.max_range = warn_range, max_range + tg.warn_range, tg.max_range = br + warn_range, br + max_range end -- Pass friendly actors if self:attr("archery_pass_friendly") then @@ -191,7 +192,7 @@ function _M:archeryAcquireTargets(tg, params) local runfire runfire = function(weapon, targets, realweapon) -- Note: if shooters with built-in infinite ammo are reintroduced, handle it here by specifying ammo to use -- calculate the range for the current weapon - local weapon_range = math.min(tg.range or 40, math.max(weapon.range or 6, self:attr("archery_range_override") or 1)) + local weapon_range = math.min(tg.range or 40, math.max(br + weapon.range or 6, self:attr("archery_range_override") or 1)) -- don't fire at targets out of range unless in forced target mode if not params.ignore_weapon_range and not core.key.modState("ctrl") and weapon_range < core.fov.distance(x, y, self.x, self.y) then print("[archeryAcquireTargets runfire] NOT FIRING", realweapon.name, x, y, "range limit:", weapon_range) @@ -377,7 +378,7 @@ local function archery_projectile(tx, ty, tg, self, tmp) end if self and dam > 0 and self.knowTalent and self:isTalentActive(self.T_AIM) and self.__CLASSNAME ~= "mod.class.Grid" then - local dist = math.max(0, core.fov.distance(self.x, self.y, target.x, target.y) - 3) + local dist = math.min(math.max(0, core.fov.distance(self.x, self.y, target.x, target.y) - 3),8) if dist > 0 then local dammult = self:callTalent(self.T_AIM, "getDamage") * dist dam = dam * (1 + (dammult/100)) @@ -695,7 +696,7 @@ function _M:archeryShoot(targets, talent, tg, params) tg.archery.weapon = weapon tg.archery.ammo = targets[i].ammo or ammo.combat -- calculate range, speed, type by shooter/ammo combination - tg.range = math.min(tg.range or 40, math.max(weapon.range or 6, self:attr("archery_range_override") or 1)) + tg.range = math.min(tg.range or 40, math.max((self.archery_bonus_range or 0) + weapon.range or 6, self:attr("archery_range_override") or 1)) tg.speed = (tg.speed or 10) + (ammo.travel_speed or 0) + (weapon.travel_speed or 0) + (self.combat and self.combat.travel_speed or 0) tg.type = tg.type or weapon.tg_type or tg.archery.ammo.tg_type or "bolt" tg.display = tg.display or targets[i].display or self:archeryDefaultProjectileVisual(realweapon, ammo) diff --git a/game/modules/tome/data/chats/escort-quest.lua b/game/modules/tome/data/chats/escort-quest.lua index eefe42f37aaff38ef0ab9ac61267102183ffb834..503f4f9b9cd707247c22887213c797709955c10b 100644 --- a/game/modules/tome/data/chats/escort-quest.lua +++ b/game/modules/tome/data/chats/escort-quest.lua @@ -147,7 +147,7 @@ local reward_types = { }, antimagic = { types = { - ["technique/feedback"] = 0.8, + ["psionic/feedback"] = 0.8, }, talents = { [Talents.T_BIOFEEDBACK] = 1, diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index e0ef013a63757380fb5352a0c0ccf1046688cee6..ec10f29d9ab0e619c547fa40d672fc5fd5b13d07 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -1399,7 +1399,7 @@ newDamageType{ local target = game.level.map(x, y, Map.ACTOR) if target then if target:canBe("blind") then - target:setEffect(target.EFF_DIM_VISION, 7, {sight=dam, apply_power=src:combatAttack()}) + target:setEffect(target.EFF_DIM_VISION, 5, {sight=dam, apply_power=src:combatAttack()}) else game.logSeen(target, "%s resists!", target.name:capitalize()) end @@ -4038,14 +4038,14 @@ newDamageType{ } newDamageType{ - name = "incendiary smoke", type = "INCENDIARY_SMOKE", + name = "sticky pitch", type = "PITCH", projector = function(src, x, y, type, dam, state) state = initState(state) useImplicitCrit(src, state) local target = game.level.map(x, y, Map.ACTOR) if target then - if target:canBe("blind") then - target:setEffect(target.EFF_INCENDIARY_SMOKE, dam.dur, {sight=dam.dam, resist=dam.fire, apply_power=src:combatAttack()}) + if target:canBe("slow") then + target:setEffect(target.EFF_STICKY_PITCH, dam.dur, {slow=dam.dam/100, resist=dam.fire, apply_power=src:combatAttack()}) else game.logSeen(target, "%s resists!", target.name:capitalize()) end @@ -4067,3 +4067,16 @@ newDamageType{ end end, } + +-- Dim vision+confuse +newDamageType{ + name = "shadow smoke", type = "SHADOW_SMOKE", + projector = function(src, x, y, type, dam, state) + state = initState(state) + useImplicitCrit(src, state) + local target = game.level.map(x, y, Map.ACTOR) + if target then + target:setEffect(target.EFF_SHADOW_SMOKE, 5, {sight=dam, apply_power=src:combatAttack()}) + end + end, +} \ No newline at end of file diff --git a/game/modules/tome/data/gfx/particles_images/diffuse_point.png b/game/modules/tome/data/gfx/particles_images/diffuse_point.png new file mode 100644 index 0000000000000000000000000000000000000000..b417a385338260bbc85831109303174aa9338d71 Binary files /dev/null and b/game/modules/tome/data/gfx/particles_images/diffuse_point.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_1.png b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_1.png new file mode 100644 index 0000000000000000000000000000000000000000..275a14bd2426ce28bd463a0f15fff129da6790bf Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_1.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_2_left.png b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_2_left.png new file mode 100644 index 0000000000000000000000000000000000000000..86df8cf90a5bbc2e24942a09cc9d7483638454de Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_2_left.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_2_middle.png b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_2_middle.png new file mode 100644 index 0000000000000000000000000000000000000000..3a07cd526357cf11c5168632e9e964dff5e64529 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_2_middle.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_2_right.png b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_2_right.png new file mode 100644 index 0000000000000000000000000000000000000000..b44165977df87f540335114531fcc8ce8e3eeea5 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_2_right.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_3.png b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_3.png new file mode 100644 index 0000000000000000000000000000000000000000..7f7e80e6bef6971199beff7265354d9a602e2207 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_3.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_4.png b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_4.png new file mode 100644 index 0000000000000000000000000000000000000000..9f30895f17085d713bb70bff21b1d6f6932a3e96 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_4.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_5.png b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_5.png new file mode 100644 index 0000000000000000000000000000000000000000..352b1819230e91b4af39102b1333f9c3e6f2da3c Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_5.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_6.png b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_6.png new file mode 100644 index 0000000000000000000000000000000000000000..41e55c122918e9495952e77b85a292c2eda272d5 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_6.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_7.png b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_7.png new file mode 100644 index 0000000000000000000000000000000000000000..439ecfaa91f86cfb87e4850830a34b7e30a33d57 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_7.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_8_left.png b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_8_left.png new file mode 100644 index 0000000000000000000000000000000000000000..9a52da7a04e41c52b1d532263a06e780ba89244d Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_8_left.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_8_middle.png b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_8_middle.png new file mode 100644 index 0000000000000000000000000000000000000000..b400da5486c86731b967410d03eab546b57c424e Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_8_middle.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_8_right.png b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_8_right.png new file mode 100644 index 0000000000000000000000000000000000000000..6ae7842b3c847bb3e6866b0593d9e56ea6dd2c79 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_8_right.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_9.png b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_9.png new file mode 100644 index 0000000000000000000000000000000000000000..ca5c1c69d8919c733befc32c959067d44571676a Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_9.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_backglow.png b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_backglow.png new file mode 100644 index 0000000000000000000000000000000000000000..e10f54248173b3b864c165dcb3d74a7d33d53e59 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/dialogframe_backglow.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/textbox1.png b/game/modules/tome/data/gfx/quest-escort-ui/textbox1.png new file mode 100644 index 0000000000000000000000000000000000000000..b8f0716583fe3830f591e516431dfa8166a663f5 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/textbox1.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/textbox2.png b/game/modules/tome/data/gfx/quest-escort-ui/textbox2.png new file mode 100644 index 0000000000000000000000000000000000000000..40b67858de0a692e0f657d2374f68f6cd690bb46 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/textbox2.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/textbox3.png b/game/modules/tome/data/gfx/quest-escort-ui/textbox3.png new file mode 100644 index 0000000000000000000000000000000000000000..000ac508264ecc5d359f2adc6d28dcec08332177 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/textbox3.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/textbox4.png b/game/modules/tome/data/gfx/quest-escort-ui/textbox4.png new file mode 100644 index 0000000000000000000000000000000000000000..373c0dabfb79c09ce6d27715c20a4a4ad000c1be Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/textbox4.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/textbox5.png b/game/modules/tome/data/gfx/quest-escort-ui/textbox5.png new file mode 100644 index 0000000000000000000000000000000000000000..e1bc7b8ba499f80cf0d474de44fda7cd1933b82f Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/textbox5.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/textbox6.png b/game/modules/tome/data/gfx/quest-escort-ui/textbox6.png new file mode 100644 index 0000000000000000000000000000000000000000..4a2c5d012621458ddc8060a9ab6820be5178f53d Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/textbox6.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/textbox7.png b/game/modules/tome/data/gfx/quest-escort-ui/textbox7.png new file mode 100644 index 0000000000000000000000000000000000000000..3265a7c5997c69733cd898d356cb098e7472d6bd Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/textbox7.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/textbox8.png b/game/modules/tome/data/gfx/quest-escort-ui/textbox8.png new file mode 100644 index 0000000000000000000000000000000000000000..ddf26cf533d08d9397536ab5a883b204da9b02a5 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/textbox8.png differ diff --git a/game/modules/tome/data/gfx/quest-escort-ui/textbox9.png b/game/modules/tome/data/gfx/quest-escort-ui/textbox9.png new file mode 100644 index 0000000000000000000000000000000000000000..9a015c58b91cc456755c4c93a599cda2b89eda31 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-escort-ui/textbox9.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_1.png b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_1.png new file mode 100644 index 0000000000000000000000000000000000000000..a19dddda89a6a5c895af8ea639a011cfa79551a7 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_1.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_2_left.png b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_2_left.png new file mode 100644 index 0000000000000000000000000000000000000000..7a5a20987ef7464cbf8ebdc769227bc6404eb94c Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_2_left.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_2_middle.png b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_2_middle.png new file mode 100644 index 0000000000000000000000000000000000000000..ff80f0a66b943b755b5f595ef19205a2841a5b82 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_2_middle.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_2_right.png b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_2_right.png new file mode 100644 index 0000000000000000000000000000000000000000..6b2a1c4fa3b53a35cf2a78fcf92e80db5b06492a Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_2_right.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_3.png b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_3.png new file mode 100644 index 0000000000000000000000000000000000000000..cd5028d73e54577779d4178e70bedffba93b177f Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_3.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_4.png b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_4.png new file mode 100644 index 0000000000000000000000000000000000000000..8cb63beda2d5763cea5b810447896d1b1f0dd9b2 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_4.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_5.png b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_5.png new file mode 100644 index 0000000000000000000000000000000000000000..fb27087a9d1866c0875f114b173fabb3af19bfb3 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_5.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_6.png b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_6.png new file mode 100644 index 0000000000000000000000000000000000000000..14c3bd7fdf618b6d44898d6d1bf11b8fca046669 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_6.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_7.png b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_7.png new file mode 100644 index 0000000000000000000000000000000000000000..4bf0603ff7fc93dc92c7e6fefd9b65a9484b71d6 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_7.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_8_left.png b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_8_left.png new file mode 100644 index 0000000000000000000000000000000000000000..34eec077bbadf2ffcd30a97b655deacfc649fd4b Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_8_left.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_8_middle.png b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_8_middle.png new file mode 100644 index 0000000000000000000000000000000000000000..c9bcf7f54d225ed506c732e1b8637dd07fda2214 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_8_middle.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_8_right.png b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_8_right.png new file mode 100644 index 0000000000000000000000000000000000000000..c03a5d6588317b68e3f88e0fa7f0d3032b27e508 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_8_right.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_9.png b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_9.png new file mode 100644 index 0000000000000000000000000000000000000000..68b49ac2b8f874e519a14025a4b61365ec129f6e Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_9.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_backglow.png b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_backglow.png new file mode 100644 index 0000000000000000000000000000000000000000..edf94601c90fa60cca8d8ff193643137e2340c22 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/dialogframe_backglow.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/textbox1.png b/game/modules/tome/data/gfx/quest-fail-ui/textbox1.png new file mode 100644 index 0000000000000000000000000000000000000000..3855a022445da0945e95997b12a423e556c3567a Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/textbox1.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/textbox2.png b/game/modules/tome/data/gfx/quest-fail-ui/textbox2.png new file mode 100644 index 0000000000000000000000000000000000000000..413f95396a41cdfd41e66c32043befd5b1f41667 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/textbox2.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/textbox3.png b/game/modules/tome/data/gfx/quest-fail-ui/textbox3.png new file mode 100644 index 0000000000000000000000000000000000000000..eee2f6f38b845eeaa36b06d0393f7b7292acbf34 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/textbox3.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/textbox4.png b/game/modules/tome/data/gfx/quest-fail-ui/textbox4.png new file mode 100644 index 0000000000000000000000000000000000000000..83f51af774d53fecb9a9e041867d4fec7e7631de Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/textbox4.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/textbox5.png b/game/modules/tome/data/gfx/quest-fail-ui/textbox5.png new file mode 100644 index 0000000000000000000000000000000000000000..7f6e35cfa09c563e171915d5a3283054113b50d5 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/textbox5.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/textbox6.png b/game/modules/tome/data/gfx/quest-fail-ui/textbox6.png new file mode 100644 index 0000000000000000000000000000000000000000..016f98ddb90a8faaf59e86214f2e7add53cdeb8a Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/textbox6.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/textbox7.png b/game/modules/tome/data/gfx/quest-fail-ui/textbox7.png new file mode 100644 index 0000000000000000000000000000000000000000..a8e22b85a8e2e304ea66e629466c1763c9004a9c Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/textbox7.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/textbox8.png b/game/modules/tome/data/gfx/quest-fail-ui/textbox8.png new file mode 100644 index 0000000000000000000000000000000000000000..a1f952c1a36534e7b64112c89849b436e21d7807 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/textbox8.png differ diff --git a/game/modules/tome/data/gfx/quest-fail-ui/textbox9.png b/game/modules/tome/data/gfx/quest-fail-ui/textbox9.png new file mode 100644 index 0000000000000000000000000000000000000000..06749a4f0f4ef8646dcbe87f6c3be5452901e11f Binary files /dev/null and b/game/modules/tome/data/gfx/quest-fail-ui/textbox9.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_1.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_1.png new file mode 100644 index 0000000000000000000000000000000000000000..2086d67acf3ffd209ab0f802b454086c72918572 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_1.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_2_left.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_2_left.png new file mode 100644 index 0000000000000000000000000000000000000000..fc4c5220fde00071bd70f5e774f640532af38c51 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_2_left.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_2_middle.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_2_middle.png new file mode 100644 index 0000000000000000000000000000000000000000..d2c642d06cb203e0d6cb4dd66774ee6b6d645873 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_2_middle.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_2_right.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_2_right.png new file mode 100644 index 0000000000000000000000000000000000000000..6f250636bc029b36b6228c2560f6337ec8230cc5 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_2_right.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_3.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_3.png new file mode 100644 index 0000000000000000000000000000000000000000..46dea6f758038dbdbb577a7dd846fee90c2d9c88 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_3.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_4.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_4.png new file mode 100644 index 0000000000000000000000000000000000000000..4e4c24759279a93a2a3744edf2c3b5931d1a1347 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_4.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_5.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_5.png new file mode 100644 index 0000000000000000000000000000000000000000..f9d4974a3817ceb404e941df9a03f412f7a189fe Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_5.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_6.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_6.png new file mode 100644 index 0000000000000000000000000000000000000000..cd7f238d45a442103956a8fa0aff181dbe29994a Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_6.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_7.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_7.png new file mode 100644 index 0000000000000000000000000000000000000000..dd42a76ca99049de847894638995825a6366181c Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_7.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_8_left.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_8_left.png new file mode 100644 index 0000000000000000000000000000000000000000..dc1bdbb78052f32608c030568276d9fafe38278d Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_8_left.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_8_middle.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_8_middle.png new file mode 100644 index 0000000000000000000000000000000000000000..7e79f8f87f9fad09ca9fa412515f92faa06ec99f Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_8_middle.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_8_right.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_8_right.png new file mode 100644 index 0000000000000000000000000000000000000000..c1ea2db9e872ac9bedb9353be850644a380f9ef1 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_8_right.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_9.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_9.png new file mode 100644 index 0000000000000000000000000000000000000000..739ea46cef40b93fb3dc838762c33f7e4ac506d8 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_9.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_backglow.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_backglow.png new file mode 100644 index 0000000000000000000000000000000000000000..0980fd7801742c337e942497e7a07e8c966b153d Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/dialogframe_backglow.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox1.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox1.png new file mode 100644 index 0000000000000000000000000000000000000000..b7ba9fd43168ae57cfd2eb54b1bbf37b24913c7b Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox1.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox2.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox2.png new file mode 100644 index 0000000000000000000000000000000000000000..8b95d6556eeea7e81d9ece8f68e403b9de1d98b1 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox2.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox3.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox3.png new file mode 100644 index 0000000000000000000000000000000000000000..9d3633487d09f04fcd6b78514bf71a0b7fb6bb9a Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox3.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox4.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox4.png new file mode 100644 index 0000000000000000000000000000000000000000..a203a282ad7f858160d47532988afb43601bc239 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox4.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox5.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox5.png new file mode 100644 index 0000000000000000000000000000000000000000..a7b4b27ec9b9398c2fe97fdc9c0fb86833d35099 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox5.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox6.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox6.png new file mode 100644 index 0000000000000000000000000000000000000000..80ecaa185bca9dd34476e00308eeb7dca6611be9 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox6.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox7.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox7.png new file mode 100644 index 0000000000000000000000000000000000000000..92f4b399792716837aec1ba05be4dbbe1864c2dc Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox7.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox8.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox8.png new file mode 100644 index 0000000000000000000000000000000000000000..43f346f9d5a55c6561c7db518ebfcf655db35608 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox8.png differ diff --git a/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox9.png b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox9.png new file mode 100644 index 0000000000000000000000000000000000000000..96bb9778cee6f851d1b2ecd887e53575462b26a9 Binary files /dev/null and b/game/modules/tome/data/gfx/quest-idchallenge-ui/textbox9.png differ diff --git a/game/modules/tome/data/gfx/quest-ui/dialogframe_8_right.png b/game/modules/tome/data/gfx/quest-ui/dialogframe_8_right.png index a7d0a62f780a3dec065b5fc91b9fa97c88055b40..658b2f8a3194e0a5959aeee7b1dfb97693c8d727 100644 Binary files a/game/modules/tome/data/gfx/quest-ui/dialogframe_8_right.png and b/game/modules/tome/data/gfx/quest-ui/dialogframe_8_right.png differ diff --git a/game/modules/tome/data/gfx/quest-ui/dialogframe_9.png b/game/modules/tome/data/gfx/quest-ui/dialogframe_9.png index 6a4d3ab7e3c45fa2eb277405f5921c714534a4f0..b40eae326f415d432f1a69f2858054a125e52ba5 100644 Binary files a/game/modules/tome/data/gfx/quest-ui/dialogframe_9.png and b/game/modules/tome/data/gfx/quest-ui/dialogframe_9.png differ diff --git a/game/modules/tome/data/gfx/quest-ui/dialogframe_backglow.png b/game/modules/tome/data/gfx/quest-ui/dialogframe_backglow.png index c4518e9c129acbd9eb184e51e72409f962dea04b..5b0288e353180562631cbcb847ad2a455d2ae775 100644 Binary files a/game/modules/tome/data/gfx/quest-ui/dialogframe_backglow.png and b/game/modules/tome/data/gfx/quest-ui/dialogframe_backglow.png differ diff --git a/game/modules/tome/data/gfx/ui/definitions/quest.lua b/game/modules/tome/data/gfx/ui/definitions/quest.lua index b604ccf3cfe33874a17646bf7a70a053ced16a7d..ab0f47ca764acc2eb0012b9e69553ab5f056e852 100644 --- a/game/modules/tome/data/gfx/ui/definitions/quest.lua +++ b/game/modules/tome/data/gfx/ui/definitions/quest.lua @@ -18,7 +18,6 @@ -- darkgod@te4.org quest = { - -- frame_shadow = {x=15, y=15, a=0.3}, frame_alpha = 1, frame_darkness = 0.6, frame_ox1 = -60, @@ -26,4 +25,34 @@ quest = { frame_oy1 = -154, frame_oy2 = 60, dialog_h_middles = true, -} \ No newline at end of file +} + +def['quest-fail'] = { + frame_alpha = 1, + frame_darkness = 0.6, + frame_ox1 = -60, + frame_ox2 = 60, + frame_oy1 = -154, + frame_oy2 = 60, + dialog_h_middles = true, +} + +def['quest-idchallenge'] = { + frame_alpha = 1, + frame_darkness = 0.6, + frame_ox1 = -60, + frame_ox2 = 60, + frame_oy1 = -154, + frame_oy2 = 60, + dialog_h_middles = true, +} + +def['quest-escort'] = { + frame_alpha = 1, + frame_darkness = 0.6, + frame_ox1 = -60, + frame_ox2 = 60, + frame_oy1 = -154, + frame_oy2 = 60, + dialog_h_middles = true, +} diff --git a/game/modules/tome/data/quests/escort-duty.lua b/game/modules/tome/data/quests/escort-duty.lua index b57a15f9afe46bcee7ccd806646a8f179516fef2..fa94b4887e587997b2d01f2c40bf2213a773129f 100644 --- a/game/modules/tome/data/quests/escort-duty.lua +++ b/game/modules/tome/data/quests/escort-duty.lua @@ -22,6 +22,8 @@ local Stats = require("engine.interface.ActorStats") local NameGenerator = require("engine.NameGenerator") local Astar = require("engine.Astar") +use_ui = "quest-escort" + -------------------------------------------------------------------------------- -- Quest data -------------------------------------------------------------------------------- diff --git a/game/modules/tome/data/talents/techniques/agility.lua b/game/modules/tome/data/talents/techniques/agility.lua index 83d6ab5f221287f2abf4fc42aebe67db88cf30d8..a6832aa7d2c5f71bc1513a542996e688667c2353 100644 --- a/game/modules/tome/data/talents/techniques/agility.lua +++ b/game/modules/tome/data/talents/techniques/agility.lua @@ -80,7 +80,7 @@ newTalent{ points = 5, no_unlearn_last = true, mode = "passive", - getChance = function(self, t) return math.floor(self:combatTalentScale(t, 15, 40)) end, + getChance = function(self, t) return math.floor(self:combatTalentScale(t, 15, 45)) end, on_learn = function(self, t) self:attr("show_shield_combat", 1) end, @@ -90,6 +90,15 @@ newTalent{ callbackOnTakeDamage = function(self, t, src, x, y, type, dam, tmp) local chance = t.getChance(self, t) if not rng.percent(chance) then return end + --this might be worth doing later, but for now let it block DoTs + --local psrc = src.__project_source + --if psrc then + -- local kind = util.getval(psrc.getEntityKind) + -- if kind == "projectile" or kind == "trap" or kind == "object" then + -- else + -- return + -- end + --end local lastdam = dam local shield = self:hasShield() if not shield then return end @@ -105,7 +114,7 @@ newTalent{ info = function(self, t) local chance = t.getChance(self, t) return ([[You are trained in an agile, mobile fighting technique combining sling and shield. This allows shields to be equipped, using Dexterity instead of Strength as a requirement. -While you have a shield equip and block is not on cooldown, you have a %d%% chance to deflect any incoming damage, reducing it by 50%% of your shield’s block value.]]) +While you have a shield equip and your Block talent is not on cooldown, you have a %d%% chance to deflect any incoming damage, reducing it by 50%% of your shield’s block value.]]) :format(chance) end, } @@ -130,9 +139,8 @@ newTalent{ getDist = function(self, t) return math.floor(self:combatTalentScale(t, 3, 5)) end, action = function(self, t) local shield, shield_combat = self:hasShield() - local sling = self:hasArcheryWeapon() - if not shield or not sling then - game.logPlayer(self, "You require a ranged weapon and a shield to use this talent.") + if not shield then + game.logPlayer(self, "You require a shield to use this talent.") return nil end @@ -210,7 +218,7 @@ newTalent{ tactical = { ATTACK = { weapon = 1 } }, requires_target = true, on_pre_use = function(self, t, silent) - if not archerPreUse(self, t, silent) then return false end + if not archerPreUse(self, t, silent, "sling") then return false end if self:attr("never_move") then return false end return true end, @@ -220,7 +228,7 @@ newTalent{ self.talents_cd[t.id] = math.max(cooldown - 1, 0) end end, - getDamage = function(self, t) return self:combatTalentWeaponDamage(t, 1.1, 2.4) end, + getDamage = function(self, t) return self:combatTalentWeaponDamage(t, 1.4, 2.6) end, --high damage, high opportunity cost getDist = function(self, t) if self:getTalentLevel(t) >= 3 then return 2 else return 1 end end, archery_onhit = function(self, t, target, x, y) if not target or not target:canBe("knockback") then return end @@ -264,7 +272,8 @@ newTalent{ info = function(self, t) return ([[You rush toward your foe, readying your shot. If you reach the enemy, you release the shot, imbuing it with great power. The shot does %d%% weapon damage and knocks back your target by %d. - The cooldown of this talent is reduced by 1 each time you move.]]): + The cooldown of this talent is reduced by 1 each time you move. + This requires a sling to use.]]): format(t.getDamage(self,t)*100, t.getDist(self, t)) end, } @@ -281,16 +290,19 @@ newTalent{ tactical = { BUFF = 2 }, on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end, getAttackSpeed = function(self, t) return math.floor(self:combatTalentScale(t, 5, 20))/100 end, - getMovementSpeed = function(self, t) return math.floor(self:combatTalentScale(t, 30, 70))/100 end, - getTurn = function(self, t) return math.floor(self:combatTalentScale(t, 5, 15)) end, + getMovementSpeed = function(self, t) return math.floor(self:combatTalentScale(t, 25, 60))/100 end, + getTurn = function(self, t) return math.floor(self:combatTalentLimit(t, 35, 10, 22)) end, + on_pre_use = function(self, t, silent) + if not archerPreUse(self, t, silent, "sling") then return false end + return true + end, callbackOnArcheryAttack = function(self, t, target, hitted) local dist = math.max(0, core.fov.distance(self.x, self.y, target.x, target.y) - 3) if hitted and not target.turn_procs.rapid_fire and dist < 5 then target.turn_procs.rapid_fire = true - turn = t.getTurn(self,t) + turn = t.getTurn(self,t)/100 energy = turn - (turn * dist * 0.2) - local energy = (game.energy_to_act * energy)/100 - self.energy.value = self.energy.value + energy + self.energy.value = self.energy.value + game.energy_to_act*energy end game:onTickEnd(function() self:setEffect(self.EFF_RAPID_MOVEMENT, 1, {src=self, power=t.getMovementSpeed(self,t)}) diff --git a/game/modules/tome/data/talents/techniques/archery.lua b/game/modules/tome/data/talents/techniques/archery.lua index e0f4e22cf61d5e99d1335cafb214b8d8f641b113..44bd9dc400de8dde71d6b43bf282ac60be8cd859 100644 --- a/game/modules/tome/data/talents/techniques/archery.lua +++ b/game/modules/tome/data/talents/techniques/archery.lua @@ -99,7 +99,7 @@ newTalent{ local eff = target:hasEffect(target.EFF_PIN_DOWN) chance = chance + eff.mark end - if self.turn_procs.first_blood_ss then chance = chance * 2 end + if self.turn_procs.first_blood_shoot then chance = chance + 50 end if rng.percent(chance) then target:setEffect(target.EFF_MARKED, 5, {src=self}) end end if self.turn_procs.first_blood_shoot then @@ -109,6 +109,7 @@ newTalent{ target:setEffect(target.EFF_CUT, 5, {power=life_diff * scale / 5, src=self, apply_power=self:combatPhysicalpower(), no_ct_effect=true}) end end + if self:knowTalent(self.T_FIRST_BLOOD) then self:incStamina(self:callTalent(self.T_FIRST_BLOOD, "getStamina")) end end, action = function(self, t) local swap = not self:attr("disarmed") and (self:attr("warden_swap") and doWardenWeaponSwap(self, t, "bow")) @@ -178,17 +179,17 @@ newTalent{ tactical = { ATTACK = { weapon = 2 } }, getDamage = function(self, t) local dam = self:combatTalentWeaponDamage(t, 1.0, 1.8) - if self:hasEffect(self.EFF_TAKING_AIM) then - local eff = self:hasEffect(self.EFF_TAKING_AIM) - dam = dam + (dam * eff.power/100) + if self:hasEffect(self.EFF_CONCEALMENT) then + local eff = self:hasEffect(self.EFF_CONCEALMENT) + if eff.dam > 0 then dam = dam + (dam * eff.dam/100) end end return dam end, getChance = function(self,t) local chance = 20 + math.floor(self:combatTalentScale(t, 2, 10)) - if self:hasEffect(self.EFF_TAKING_AIM) then - local eff = self:hasEffect(self.EFF_TAKING_AIM) - chance = chance + (eff.charges * 30) + if self:hasEffect(self.EFF_CONCEALMENT) then + local eff = self:hasEffect(self.EFF_CONCEALMENT) + if eff.dam > 0 then chance = chance + 100 end end if self:hasEffect(self.EFF_TRUESHOT) then chance = chance * 2 end return math.min(100, chance) @@ -212,7 +213,7 @@ newTalent{ local eff = target:hasEffect(target.EFF_PIN_DOWN) chance = chance + eff.mark end - if self.turn_procs.first_blood_ss then chance = chance * 2 end + if self.turn_procs.first_blood_ss then chance = chance + 50 end if rng.percent(chance) then target:setEffect(target.EFF_MARKED, 5, {src=self}) end if self.turn_procs.first_blood_ss then @@ -222,8 +223,9 @@ newTalent{ target:setEffect(target.EFF_CUT, 5, {power=life_diff * scale / 5, src=self, apply_power=self:combatPhysicalpower(), no_ct_effect=true}) end end - - self:removeEffect(self.EFF_TAKING_AIM) + if self:knowTalent(self.T_FIRST_BLOOD) then self:incStamina(self:callTalent(self.T_FIRST_BLOOD, "getStamina")) end + local eff = self:hasEffect(self.EFF_CONCEALMENT) + if eff then eff.dam = 0 end end, action = function(self, t) local targets = self:archeryAcquireTargets(nil, {one_shot=true}) @@ -258,7 +260,7 @@ newTalent{ getDamage = function(self, t) return self:combatTalentWeaponDamage(t, 0.5, 1.1) end, getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 2.5, 5)) end, getMarkChance = function(self, t) return math.floor(self:combatTalentScale(t, 5, 20)) end, - getCritPower = function(self, t) return math.floor(self:combatTalentScale(t, 10, 25)) end, + getCritPower = function(self, t) return math.floor(self:combatTalentScale(t, 8, 20)) end, on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end, getChance = function(self,t) local chance = 20 + math.floor(self:combatTalentScale(t, 2, 10)) @@ -455,20 +457,27 @@ newTalent{ no_energy = "fake", points = 5, random_ego = "attack", - cooldown = 0, - require = techs_dex_req1, + cooldown = function(self, t) -- this makes it a bit less likely that a mob could lob chain headshots at you + if self.ai and self.ai == "party_member" then + return 0 + elseif self.ai then + return 3 + else + return 3 + end + end, require = techs_dex_req1, range = archery_range, requires_target = true, tactical = { ATTACK = { weapon = 2 } }, getDamage = function(self, t) - local dam = self:combatTalentWeaponDamage(t, 1.1, 2.3) + local dam = self:combatTalentWeaponDamage(t, 1.1, 2.4) -- if self:hasEffect(self.EFF_TAKING_AIM) then -- local eff = self:hasEffect(self.EFF_TAKING_AIM) -- dam = dam + (dam * eff.power/100) -- end return dam end, - getApr = function(self, t) return self:getDex(100,true) end, + getApr = function(self, t) return self:getDex(40,true) end, on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end, archery_onhit = function(self, t, target, x, y) target:removeEffect(target.EFF_MARKED) @@ -497,7 +506,8 @@ newTalent{ local dam = t.getDamage(self,t)*100 local apr = t.getApr(self,t) return ([[Fire a precise shot dealing %d%% weapon damage, with %d increased armor penetration and 100 increased accuracy. This shot will bypass other enemies between you and your target. -Only usable against marked targets, and consumes the mark on hit.]]): +Only usable against marked targets, and consumes the mark on hit. +The armor penetration increases with your Dexterity.]]): format(dam, apr) end, } @@ -581,7 +591,7 @@ newTalent{ target:removeEffect(target.EFF_MARKED) if self:knowTalent(self.T_BULLSEYE) then self:callTalent(self.T_BULLSEYE, "proc") end - if self:knowTalent(self.T_FIRST_BLOOD) then self:incStamina(self:callTalent(self.T_FIRST_BLOOD, "getStamina")) end +-- if self:knowTalent(self.T_FIRST_BLOOD) then self:incStamina(self:callTalent(self.T_FIRST_BLOOD, "getStamina")) end game.target.forced = old_target_forced return true @@ -621,7 +631,7 @@ newTalent{ if target:hasEffect(target.EFF_MARKED) then target:removeEffect(target.EFF_MARKED) if self:knowTalent(self.T_BULLSEYE) then self:callTalent(self.T_BULLSEYE, "proc") end - if self:knowTalent(self.T_FIRST_BLOOD) then self:incStamina(self:callTalent(self.T_FIRST_BLOOD, "getStamina")) end +-- if self:knowTalent(self.T_FIRST_BLOOD) then self:incStamina(self:callTalent(self.T_FIRST_BLOOD, "getStamina")) end end if not target.turn_procs.called_shot_silence then target.turn_procs.called_shot_silence = true @@ -681,9 +691,8 @@ newTalent{ points = 5, mode = "passive", require = techs_dex_req4, - cooldown = 3, - getSpeed = function(self, t) return math.floor(self:combatTalentScale(t, 15, 40))/100 end, - getTalentCount = function(self, t) return math.floor(self:combatTalentScale(t, 1, 3)) end, + getSpeed = function(self, t) return math.floor(self:combatTalentScale(t, 10, 35))/100 end, + getTalentCount = function(self, t) return math.floor(self:combatTalentLimit(t, 4, 1, 2.5)) end, getCooldown = function(self, t) return math.floor(self:combatTalentScale(t, 1, 3)) end, proc = function(self, t) if not self:isTalentCoolingDown(t) then @@ -717,8 +726,7 @@ newTalent{ local speed = t.getSpeed(self,t)*100 local nb = t.getTalentCount(self,t) local cd = t.getCooldown(self,t) - return ([[Each time you trigger a mark, you gain %d%% increased attack speed for 3 turns and the cooldown of %d random techniques are reduced by %d turns. -This talent has a cooldown.]]): + return ([[Each time you consume a mark, you gain %d%% increased attack speed for 2 turns and the cooldown of %d random techniques are reduced by %d turns.]]): format(speed, nb, cd) end, } diff --git a/game/modules/tome/data/talents/techniques/duelist.lua b/game/modules/tome/data/talents/techniques/duelist.lua index 6c2bee97ccf6a46b2bf264a8b7effc13f39ab331..fac95ceee966e9fdc519c431c3f42b68e4129559 100644 --- a/game/modules/tome/data/talents/techniques/duelist.lua +++ b/game/modules/tome/data/talents/techniques/duelist.lua @@ -109,7 +109,7 @@ newTalent{ local speed = t.getSpeed(self,t) return ([[The flow of battle invigorates you, allowing you to press your advantage as the fight progresses. Up to once each per turn, while dual wielding, you may: - Reposte -- If a melee or archery attack misses you or you parry it, you instantly restore %0.1f stamina and gain %d%% of a turn. + Riposte -- If a melee or archery attack misses you or you parry it, you instantly restore %0.1f stamina and gain %d%% of a turn. Recover -- On performing a critical strike with your offhand weapon, you instantly restore %0.1f stamina.]]):format(sta, speed, sta) end, } diff --git a/game/modules/tome/data/talents/techniques/marksmanship.lua b/game/modules/tome/data/talents/techniques/marksmanship.lua index 8e0f1069a9f5ba03f1e4c9d82f7f6648855d1ccd..db5bb66bfbabda2672494cd3b6b3ed5c9a07051b 100644 --- a/game/modules/tome/data/talents/techniques/marksmanship.lua +++ b/game/modules/tome/data/talents/techniques/marksmanship.lua @@ -102,12 +102,12 @@ newTalent{ mode = "passive", require = techs_dex_req2, getBleed = function(self, t) return self:combatTalentScale(t, 0.3, 1.0) end, - getStamina = function(self, t) return math.floor(self:combatTalentScale(t, 5, 15)) end, + getStamina = function(self, t) return self:combatTalentScale(t, 1.5, 4) end, info = function(self, t) local bleed = t.getBleed(self,t)*100 local sta = t.getStamina(self,t) - return ([[You take advantage of unwary foes, doubling the chance for Steady Shot and Shoot to mark targets and bleeding them for %d%% additional damage over 5 turns if the target is at or above 90%% life. -In addition, each time you trigger a mark or marked target dies you gain %d stamina.]]) + return ([[You take advantage of unwary foes, giving Steady Shot and Shoot an additional 50%% chance to mark targets and bleeding them for %d%% additional damage over 5 turns if the target is at or above 90%% life. +In addition, your Steady Shot, Shoot and Headshot now restore %0.1f stamina on hit.]]) :format(bleed, sta) end, } @@ -170,7 +170,7 @@ newTalent{ require = techs_dex_req4, random_ego = "attack", tactical = { BUFF = 3 }, - getSpeed = function(self, t) return self:combatTalentScale(t, 15, 50)/100 end, + getSpeed = function(self, t) return self:combatTalentLimit(t, 60, 15, 45)/100 end, getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 4, 7)) end, action = function(self, t) local dur = t.getDuration(self,t) diff --git a/game/modules/tome/data/talents/techniques/mobility.lua b/game/modules/tome/data/talents/techniques/mobility.lua index 6cc68652fe21f56a4a8ec8939e7fb8da3b9fb1af..1a05668443ccdd93b38c57fe1ec1cebfa8419130 100644 --- a/game/modules/tome/data/talents/techniques/mobility.lua +++ b/game/modules/tome/data/talents/techniques/mobility.lua @@ -188,7 +188,7 @@ newTalent{ base_stamina = 25, stamina = mobility_stamina, no_energy = true, - getDur = function(self, t) return 5 end, + getDur = function(self, t) return 4 end, getChanceDef = function(self, t) if self.perfect_evasion then return 100, 0 end return self:combatLimit(5*self:getTalentLevel(t) + self:getDex(50,true), 50, 10, 10, 37.5, 75), @@ -266,10 +266,10 @@ newTalent { sustain_stamina = 10, no_energy = true, tactical = { DEFEND = 2 }, - pinImmune = function(self, t) return self:combatTalentLimit(t, 1, .17, .5) end, -- limit < 100% - passives = function(self, t, p) - self:talentTemporaryValue(p, "pin_immune", t.pinImmune(self, t)) - end, +-- pinImmune = function(self, t) return self:combatTalentLimit(t, 1, .17, .5) end, -- limit < 100% +-- passives = function(self, t, p) +-- self:talentTemporaryValue(p, "pin_immune", t.pinImmune(self, t)) +-- end, on_pre_use = function(self, t, silent, fake) if self:hasHeavyArmor() then if not silent then game.logPlayer(self, "%s is not usable while wearing heavy armour.", t.name) end @@ -278,11 +278,11 @@ newTalent { return true end, getReduction = function(self, t, fake) -- % reduction based on both TL and Defense - return math.max(0.1, self:combatTalentLimit(t, 0.8, 0.25, 0.65))*self:combatLimit(self:combatDefense(fake), 1.0, 0.25, 0, 0.78, 50) -- vs TL/def: 1/10 == ~12%, 1.3/10 == ~17%, 1.3/50 == ~27%, 6.5/50 == ~53%, 6.5/100 = ~59% + return self:combatTalentLimit(t, 1, 0.15, 0.50) * self:combatLimit(self:combatDefense(), 1, 0.15, 10, 0.5, 50) -- Limit < 100%, 25% for TL 5.0 and 50 defense end, - getStamina = function(self, t) return 20*(1 + self:combatFatigue()/100)*math.max(0.1, self:combatTalentLimit(t, 0.8, 0.25, 0.65)) end, -- Stamina increases in proportion to talent-based effectiveness. Stamina Efficiency increased with level through higher Defense (Automatic from the increased Dexterity required for higher talent levels) + getStamina = function(self, t) return 8 end, -- as per Shibari's comment, this can get pretty annoying if cost was any higher getLifeTrigger = function(self, t) - return self:combatTalentLimit(t, 10, 35, 20) + return self:combatTalentLimit(t, 10, 30, 15) -- Limit trigger > 10% life end, callbackOnTakeDamage = function(self, t, src, x, y, type, dam, state) if dam > 0 and state and not (self:attr("encased_in_ice") or self:attr("invulnerable")) then @@ -304,8 +304,7 @@ newTalent { end stam, stam_cost = self:getStamina(), stam_cost or t.getStamina(self, t) local lt = t.getLifeTrigger(self, t)/100 - local min_dam = self.max_life*0.05 - if stam_cost == 0 or dam > min_dam and dam > self.life*lt then + if stam_cost == 0 or dam > self.max_life*lt then --print(("[PROJECTOR: Trained Reactions] PASSED life/stam test for %s: %s %s damage (%s) (%0.1f/%0.1f stam) from %s (state:%s)"):format(self.name, dam, type, is_attk, stam_cost, stam, src.name, state)) -- debugging self.turn_procs[t.id] = state self:incStamina(-stam_cost) -- Note: force_talent_ignore_ressources has no effect on this @@ -327,16 +326,16 @@ newTalent { return true end, info = function(self, t) +-- local pin = t.pinImmune(self,t) local stam = t.getStamina(self, t) local trigger = t.getLifeTrigger(self, t) local reduce = t.getReduction(self, t, true)*100 return ([[You have trained to be very light on your feet and have conditioned your reflexes to react faster than thought to damage you take. - You permanently gain %d%% pinning immunity. - While this talent is active, you instantly react to any direct damage (not from status effects, etc.) that would hit you for at least %d%% of your current life or %d%% of your maximum life (whichever is greater). + While this talent is active, you instantly react to any direct damage (not from status effects, etc.) that would hit you for at least %d%% of your maximum life. This requires %0.1f stamina and reduces the damage by %d%%. Your reactions are too slow for this if you are wearing heavy armour. The damage reduction improves with your Defense.]]) - :format(t.pinImmune(self, t)*100, trigger, 5, stam, reduce) + :format(trigger, stam, reduce) end, } diff --git a/game/modules/tome/data/talents/techniques/munitions.lua b/game/modules/tome/data/talents/techniques/munitions.lua index ae1410bf2b7058a642400a07ad199ffc77bb470f..0c8b4a7d01d4d568beab17f2b89b17663b6d7e80 100644 --- a/game/modules/tome/data/talents/techniques/munitions.lua +++ b/game/modules/tome/data/talents/techniques/munitions.lua @@ -83,9 +83,9 @@ newTalent{ getIncendiaryDamage = function(self, t) return self:combatTalentWeaponDamage(t, 0.1, 0.4) end, getIncendiaryRadius = function(self, t) if self:getTalentLevel(t)>=3 then return 2 else return 1 end end, getPoisonDamage = function(self, t) return self:combatTalentPhysicalDamage(t, 20, 180) end, - getNumb = function(self, t) return 5 + self:combatTalentLimit(t, 30, 5, 15) end, - getArmorSaveReduction = function(self, t) return 5 + self:combatTalentPhysicalDamage(t, 5, 30) end, - getResistPenalty = function(self, t) return self:combatTalentLimit(t, 100, 15, 35, true) end, + getNumb = function(self, t) return 5 + self:combatTalentLimit(t, 25, 5, 15) end, + getArmorSaveReduction = function(self, t) return self:combatTalentLimit(t, 30, 5, 25, 0.75) end, + getResistPenalty = function(self, t) return self:combatTalentLimit(t, 35, 10, 25, true) end, on_learn = function(self, t) local lev = self:getTalentLevelRaw(t) if lev == 1 then @@ -336,15 +336,15 @@ newTalent{ radius = function(self, t) return math.floor(self:combatTalentScale(t, 1.3, 2.7)) end, getDamage = function(self, t) return self:combatTalentWeaponDamage(t, 0.5, 1.5) end, getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 3.3, 5.5)) end, - getSightLoss = function(self, t) return math.floor(self:combatTalentScale(t,1, 6, "log", 0, 4)) end, -- 1@1 6@5 + getSlow = function(self, t) return math.floor(self:combatTalentLimit(t, 40, 10, 25)) end, getFireResist = function(self, t) return math.floor(self:combatTalentScale(t, 10, 40)) end, getPoisonDamage = function(self, t) return self:combatTalentPhysicalDamage(t, 15, 100) end, - getPoisonFailure = function(self, t) return math.floor(self:combatTalentScale(t, 10, 30)) end, - getRemoveCount = function(self, t) return math.floor(self:combatTalentScale(t, 2, 4)) end, + getPoisonFailure = function(self, t) return math.floor(self:combatTalentScale(t, 10, 20)) end, + getRemoveCount = function(self, t) return self:combatTalentLimit(t, 4, 1, 2.5) end, archery_onreach = function(self, t, x, y) local tg = self:getTalentTarget(t) if self:isTalentActive(self.T_INCENDIARY_AMMUNITION) then - self:project(tg, x, y, DamageType.INCENDIARY_SMOKE, {dam=t.getSightLoss(self,t), dur=t.getDuration(self,t), fire=t.getFireResist(self,t)}) + self:project(tg, x, y, DamageType.PITCH, {dam=t.getSlow(self,t), dur=t.getDuration(self,t), fire=t.getFireResist(self,t)}) end if self:isTalentActive(self.T_VENOMOUS_AMMUNITION) then game.level.map:addEffect(self, @@ -408,7 +408,7 @@ newTalent{ if not targets then return end local dam = t.getDamage(self,t) if self:isTalentActive(self.T_PIERCING_AMMUNITION) then - self:archeryShoot(targets, t, tg, {mult=dam*1.5, damtype=DamageType.PHYSICAL}) + self:archeryShoot(targets, t, tg, {mult=dam, damtype=DamageType.PHYSICAL}) elseif self:isTalentActive(self.T_VENOMOUS_AMMUNITION) then self:archeryShoot(targets, t, nil, {mult=dam, damtype=DamageType.NATURE}) elseif self:isTalentActive(self.T_INCENDIARY_AMMUNITION) then @@ -420,17 +420,17 @@ newTalent{ local dam = t.getDamage(self,t)*100 local radius = self:getTalentRadius(t) local dur = t.getDuration(self,t) - local sight = t.getSightLoss(self,t) + local slow = t.getSlow(self,t) local fire = t.getFireResist(self,t) local poison = t.getPoisonDamage(self,t) local fail = t.getPoisonFailure(self,t) local nb = t.getRemoveCount(self,t) return ([[Fires a special shot based on your currently loaded ammo: -Incendiary - Fire a shot that deals %d%% weapon damage as fire and covers targets in radius %d in incendiary smoke for %d turns, reducing their sight range by %d and increasing fire damage taken by %d%%. +Incendiary - Fire a shot that deals %d%% weapon damage as fire and covers targets in radius %d in sticky pitch for %d turns, reducing global speed by %d%% and increasing fire damage taken by %d%%. Venomous - Fire a shot that deals %d%% weapon damage as nature and explodes into a radius %d cloud of crippling poison for %d turns, dealing %0.2f nature damage each turn and giving affected targets a %d%% chance to fail talent usage. Piercing - Fire a shot that explodes into a radius %d burst of shredding shrapnel, dealing %d%% weapon damage as physical and removing %d beneficial physical effects or sustains. The poison damage dealt increases with your Physical Power, and status chance increases with your Accuracy.]]): - format(dam, radius, dur, sight, fire, dam, radius, dur, damDesc(self, DamageType.NATURE, poison), fail, radius, dam*1.5, nb) + format(dam, radius, dur, slow, fire, dam, radius, dur, damDesc(self, DamageType.NATURE, poison), fail, radius, dam, nb) end, } @@ -439,12 +439,12 @@ newTalent{ type = {"technique/munitions", 3}, mode = "passive", points = 5, - cooldown = 6, + cooldown = 8, require = techs_dex_req_high3, fixed_cooldown = true, getFireDamage = function(self, t) return self:combatTalentPhysicalDamage(t, 10, 100) end, getPoisonDamage = function(self, t) return self:combatTalentPhysicalDamage(t, 20, 240) end, - getResistPenalty = function(self, t) return math.floor(self:combatTalentScale(t, 10, 25)) end, + getResistPenalty = function(self, t) return math.floor(self:combatTalentLimit(t, 25, 5, 20)) end, info = function(self, t) local fire = t.getFireDamage(self,t) local poison = t.getPoisonDamage(self,t) @@ -468,9 +468,9 @@ newTalent{ getPoisonDamage = function(self, t) return self:combatTalentWeaponDamage(t, 0.1, 0.4) end, getPoisonRadius = function(self, t) if self:getTalentLevel(t)>=3 then return 2 else return 1 end end, getPhysicalDamage = function(self, t) return self:combatTalentPhysicalDamage(t, 20, 180) end, - getNumb = function(self, t) return 5 + self:combatTalentLimit(t, 30, 5, 15) end, - getArmorSaveReduction = function(self, t) return 5 + self:combatTalentPhysicalDamage(t, 5, 30) end, - getResistPenalty = function(self, t) return self:combatTalentLimit(t, 100, 15, 35, true) end, + getNumb = function(self, t) return 5 + self:combatTalentLimit(t, 25, 5, 15) end, + getArmorSaveReduction = function(self, t) return self:combatTalentLimit(t, 30, 5, 25, 0.75) end, + getResistPenalty = function(self, t) return self:combatTalentLimit(t, 35, 10, 25, true) end, info = function(self, t) local poison = t.getPoisonDamage(self,t)*100 local radius = t.getPoisonRadius(self,t) diff --git a/game/modules/tome/data/talents/techniques/reflexes.lua b/game/modules/tome/data/talents/techniques/reflexes.lua index 1296f7d5cedd15adf49326b1d109b06aed8c3555..36534f5c6c0e0e0d01fe8830477f9003041dc8ad 100644 --- a/game/modules/tome/data/talents/techniques/reflexes.lua +++ b/game/modules/tome/data/talents/techniques/reflexes.lua @@ -173,6 +173,7 @@ newTalent{ range = archery_range, requires_target = true, no_npc_use = true, + fixed_cooldown = true, -- there's probably some sort of unexpected interaction that would let you chain this infinitely with cooldown reducers getTalentCount = function(self, t) return math.floor(self:combatTalentScale(t, 1, 4)) end, --Limit < 100% getCooldown = function(self, t) return math.floor(self:combatTalentScale(t, 1, 3)) end, --Limit < 100% on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent) end, diff --git a/game/modules/tome/data/talents/techniques/sniper.lua b/game/modules/tome/data/talents/techniques/sniper.lua index 6bec4a637dd69acc29a91f4e60aecf9be506d9fe..1f8c45adf64e8513b698d7e9b67c22501c45856f 100644 --- a/game/modules/tome/data/talents/techniques/sniper.lua +++ b/game/modules/tome/data/talents/techniques/sniper.lua @@ -90,6 +90,22 @@ Talents.wardenPreUse = wardenPreUse archery_range = Talents.main_env.archery_range +local function concealmentDetection(self, radius, estimate) + if not self.x then return nil end + local dist = 0 + local closest, detect = math.huge, 0 + for i, act in ipairs(self.fov.actors_dist) do + dist = core.fov.distance(self.x, self.y, act.x, act.y) + if dist > radius then break end + if act ~= self and act:reactionToward(self) < 0 and not act:attr("blind") and (not act.fov or not act.fov.actors or act.fov.actors[self]) and (not estimate or self:canSee(act)) then + detect = detect + act:combatSeeStealth() * (1.1 - dist/10) -- detection strength reduced 10% per tile + if dist < closest then closest = dist end + end + end + return detect, closest +end +Talents.concealmentDetection = concealmentDetection + newTalent{ name = "Concealment", type = {"technique/sniper", 1}, @@ -97,41 +113,48 @@ newTalent{ mode = "sustained", require = techs_dex_req_high1, cooldown = 10, + no_energy = true, tactical = { BUFF = 2 }, - no_npc_use = true, -- getting 1 shot from an invisible ranged attacker = no - on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "bow") end, - getDamage = function(self, t) return math.floor(self:combatTalentScale(t, 10, 35)) end, - getAvoidance = function(self, t) return math.floor(self:combatTalentScale(t, 15, 40)) end, + no_npc_use = true, -- range 13 mobs are a bit excessive + on_pre_use = function(self, t, silent, fake) + if not archerPreUse(self, t, silent, "bow") then return false end + if self:isTalentActive(t.id) then return true end + + -- Check nearby actors detection ability + if not self.x or not self.y or not game.level then return end + if not rng.percent(self.hide_chance or 0) then + if concealmentDetection(self, t.getRadius(self, t)) > 0 then + if not silent then game.logPlayer(self, "You are being observed too closely to enter Concealment!") end + return nil + end + end + return true + end, + getDamage = function(self, t) return math.floor(self:combatTalentScale(t, 35, 75)) end, + getAvoidance = function(self, t) return math.floor(self:combatTalentLimit(t, 30, 10, 22)) end, + getSight = function(self, t) return math.floor(self:combatTalentScale(t, 1, 3, "log")) end, + getRadius = function(self, t) return math.ceil(self:combatTalentLimit(t, 0, 8.9, 4.6)) end, sustain_lists = "break_with_stealth", activate = function(self, t) local ret = {} - local chance = t.getAvoidance(self, t) - self:talentTemporaryValue(ret, "cancel_damage_chance", chance) - self:talentTemporaryValue(ret, "concealment", 6) + self:setEffect(self.EFF_CONCEALMENT, 3, {power=t.getAvoidance(self,t), dam=t.getDamage(self,t), sight=t.getSight(self,t), charges=3}) return ret end, deactivate = function(self, t, p) return true end, - hasFoes = function(self) - for i = 1, #self.fov.actors_dist do - local act = self.fov.actors_dist[i] - if act and self:reactionToward(act) < 0 and self:canSee(act) then return true end - end - return false - end, callbackOnActBase = function(self, t) - if t.hasFoes(self) then - self:setEffect(self.EFF_TAKING_AIM, 2, {power=t.getDamage(self,t), max_stacks=3, max_power=t.getDamage(self,t)*3 }) - end + self:setEffect(self.EFF_CONCEALMENT, 3, {power=t.getAvoidance(self,t), max_power=t.getAvoidance(self,t)*3, dam=t.getDamage(self,t), sight=t.getSight(self,t), charges=3}) end, info = function(self, t) - local avoid = t.getAvoidance(self,t) + local avoid = t.getAvoidance(self,t)*3 local dam = t.getDamage(self,t) - return ([[Enter a concealed sniping stance. You gain a %d%% chance to completely avoid incoming damage and status effects, and enemies further than 6 tiles away will be unable to clearly see you, effectively blinding them. -While in this stance, you will take aim if a foe is visible. Each stack of take aim increases the damage of your next Steady Shot by %d%% and the chance to mark by 30%%, stacking up to 3 times. -This requires a bow to use.]]): - format(avoid, dam, dam*3) + local range = t.getSight(self,t) + local radius = t.getRadius(self,t) + return ([[Enter a concealed sniping stance, increasing our weapon's attack range and vision range by %d, giving all incoming damage a %d%% chance to miss you, and increasing the damage dealt by Steady Shot by %d%% and chance to mark by 100%%. +Any non-instant, non-movement action will break concealment, but the increased range and vision and damage avoidance will persist for 3 turns, with the damage avoidance decreasing in power by 33%% each turn. +This requires a bow to use, and cannot be used if there are foes in sight within range %d.]]): + format(range, avoid, dam, radius) end, } @@ -151,48 +174,15 @@ newTalent{ on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "bow") end, radius = function(self, t) return math.floor(self:combatTalentScale(t, 1, 2.7)) end, getDamage = function(self, t) return self:combatTalentWeaponDamage(t, 1.1, 1.9) end, - archery_onreach = function(self, t, x, y) - local tg = self:getTalentTarget(t) - self:project(tg, x, y, function(px, py) - local e = Object.new{ - block_sight=true, - temporary = 4, - x = px, y = py, - canAct = false, - act = function(self) - local t = self.summoner:getTalentFromId(self.summoner.T_SHADOW_SHOT) - local rad = self.summoner:getTalentRadius(t) - local Map = require "engine.Map" - self:useEnergy() - local actor = game.level.map(self.x, self.y, Map.ACTOR) - self.temporary = self.temporary - 1 - if self.temporary <= 0 then - if self.particles then game.level.map:removeParticleEmitter(self.particles) end - game.level.map:remove(self.x, self.y, engine.Map.TERRAIN+rad) - self.smokeBomb = nil - game.level:removeEntity(self) - game.level.map:scheduleRedisplay() - end - end, - summoner_gain_exp = true, - summoner = self, - } - e.smokeBomb = e -- used for checkAllEntities to return the dark Object itself - game.level:addEntity(e) - game.level.map(px, py, Map.TERRAIN+self:getTalentRadius(t), e) - e.particles = Particles.new("creeping_dark", 1, { }) - e.particles.x = px - e.particles.y = py - game.level.map:addParticleEmitter(e.particles) - - end, nil, {type="dark"}) - - game.level.map:redisplay() - end, + getSightLoss = function(self, t) return math.floor(self:combatTalentScale(t,1, 6, "log", 0, 4)) end, -- 1@1 6@5 target = function(self, t) local weapon, ammo = self:hasArcheryWeapon() return {type="ball", radius=self:getTalentRadius(t), range=self:getTalentRange(t), selffire=false, display=self:archeryDefaultProjectileVisual(weapon, ammo)} end, + archery_onreach = function(self, t, x, y) + local tg = self:getTalentTarget(t) + self:project(tg, x, y, DamageType.SHADOW_SMOKE, t.getSightLoss(self,t), {type="dark"}) + end, action = function(self, t) local tg = self:getTalentTarget(t) local targets = self:archeryAcquireTargets(nil, {one_shot=true}) @@ -200,9 +190,9 @@ newTalent{ local dam = t.getDamage(self,t) self:archeryShoot(targets, t, nil, {mult=dam}) game:onTickEnd(function() - if self:knowTalent(self.T_CONCEALMENT) and not self:isTalentActive(self.T_CONCEALMENT) then - self.talents_cd[self.T_CONCEALMENT] = 0 - self:forceUseTalent(self.T_CONCEALMENT, {ignore_energy=true, silent = true}) + if self:knowTalent(self.T_CONCEALMENT) and not self:isTalentActive(self.T_CONCEALMENT) then + self:alterTalentCoolingdown(self.T_CONCEALMENT, -20) + self:forceUseTalent(self.T_CONCEALMENT, {ignore_energy=true, ignore_cd=true, no_talent_fail=true, silent=true}) end end) game.level.map:redisplay() @@ -211,9 +201,11 @@ newTalent{ info = function(self, t) local dam = t.getDamage(self,t)*100 local radius = self:getTalentRadius(t) - return ([[Fire an arrow tipped with a smoke bomb, inflicting %d%% damage. The bomb will create a radius %d cloud of smoke on impact for 4 turns that blocks line of sight. -You take advantage of this distraction to immediately enter Concealment.]]): - format(dam, radius) + local sight = t.getSightLoss(self,t) + return ([[Fire an arrow tipped with a smoke bomb inflicting %d%% damage and creating a radius %d cloud of thick, disorientating smoke. Those caught within will be confused (power 50%%) and have their vision range reduced by %d for 5 turns. +You take advantage of this distraction to immediately enter Concealment, regardless of it's cooldown. +The chance for the smoke bomb to affect your targets increases with your Accuracy.]]): + format(dam, radius, sight) end, } @@ -227,16 +219,11 @@ newTalent{ sustain_stamina = 50, tactical = { BUFF = 2 }, on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "bow") end, - getPower = function(self, t) return math.floor(self:combatTalentScale(t, 10, 45)) end, - getSpeed = function(self, t) return math.floor(self:combatTalentLimit(t, 150, 50, 110)) end, - getDamage = function(self, t) return math.floor(self:combatTalentLimit(t, 10, 1, 5)) end, + getPower = function(self, t) return self:combatScale(self:getTalentLevel(t) * self:getDex(10, true), 4, 0, 54, 50) end, + getSpeed = function(self, t) return math.floor(self:combatTalentLimit(t, 150, 50, 100)) end, + getDamage = function(self, t) return 1 + math.min(math.floor(self:getTalentLevel(t)),6) end, --we really don't want a flat damage bonus like this going up past 35% sustain_slots = 'archery_stance', activate = function(self, t) - local weapon = self:hasArcheryWeapon() - if not weapon then - game.logPlayer(self, "You cannot use Aim without a bow or sling!") - return nil - end local power = t.getPower(self,t) local speed = t.getSpeed(self,t) @@ -257,8 +244,9 @@ newTalent{ local speed = t.getSpeed(self,t) local dam = t.getDamage(self,t) return ([[Enter a calm, focused stance, increasing physical power and accuracy by %d and projectile speed by %d%%. -This makes your shots more effective at range, increasing all damage dealt by %d%% per tile travelled beyond 3, to a maximum of %d%% damage at range 10.]]): - format(power, speed, dam, dam*7) +This makes your shots more effective at range, increasing all damage dealt by %d%% per tile travelled beyond 3, to a maximum of %d%% damage at range 8. +The physical power and accuracy increase with your Dexterity.]]): + format(power, speed, dam, dam*5) end, } @@ -275,8 +263,8 @@ newTalent{ tactical = { ATTACK = { weapon = 3 }, }, no_npc_use = true, --no way am i giving a npc a 300%+ ranged shot on_pre_use = function(self, t, silent) return archerPreUse(self, t, silent, "bow") end, - getDamage = function(self, t) return self:combatTalentWeaponDamage(t, 1.4, 3.0) end, -- very high damage as this effectively takes 2 turns - getDamageReduction = function(self, t) return math.floor(self:combatTalentLimit(t, 100, 25, 70)) end, + getDamage = function(self, t) return self:combatTalentWeaponDamage(t, 1.7, 3.5) end, -- very high damage as this effectively takes 2 turns + getDamageReduction = function(self, t) return math.floor(self:combatTalentLimit(t, 90, 30, 70)) end, action = function(self, t) local dam = t.getDamage(self,t) local reduction = t.getDamageReduction(self,t) diff --git a/game/modules/tome/data/timed_effects/other.lua b/game/modules/tome/data/timed_effects/other.lua index f020dbe2969d62762a838ac3a29ff989d872fd41..dd21e92193b03d3ef340401e2e3f9a1606f96d5b 100644 --- a/game/modules/tome/data/timed_effects/other.lua +++ b/game/modules/tome/data/timed_effects/other.lua @@ -3208,9 +3208,9 @@ newEffect{ deactivate = function(self, eff) self:removeParticles(eff.particle) end, - on_die = function(self,eff) - if eff.src and eff.src:knowTalent(eff.src.T_FIRST_BLOOD) then eff.src:incStamina(eff.src:callTalent(eff.src.T_FIRST_BLOOD, "getStamina")) end - end, +-- on_die = function(self,eff) +-- if eff.src and eff.src:knowTalent(eff.src.T_FIRST_BLOOD) then eff.src:incStamina(eff.src:callTalent(eff.src.T_FIRST_BLOOD, "getStamina")) end +-- end, } newEffect{ diff --git a/game/modules/tome/data/timed_effects/physical.lua b/game/modules/tome/data/timed_effects/physical.lua index 6928442314874dd780b002d4571bd88083a9bb2f..e7eb8ffeb94e21b81fdad70d5d669015f5b13ced 100644 --- a/game/modules/tome/data/timed_effects/physical.lua +++ b/game/modules/tome/data/timed_effects/physical.lua @@ -3729,26 +3729,22 @@ newEffect{ } newEffect{ - name = "INCENDIARY_SMOKE", image = "talents/sticky_smoke.png", - desc = "Incendiary Smoke", - long_desc = function(self, eff) return ("The target's vision range is decreased by %d and fire resistance by %d%%."):format(eff.sight, eff.resist) end, + name = "STICKY_PITCH", image = "talents/sticky_smoke.png", + desc = "Sticky Pitch", + long_desc = function(self, eff) return ("The target's global speed is reduced by %d%% and fire resistance by %d%%."):format(eff.slow, eff.resist) end, type = "physical", - subtype = { sense=true }, + subtype = { slow=true }, status = "detrimental", - parameters = { sight=5, resist=10 }, - on_gain = function(self, err) return "#Target# is surrounded by a thick, incendiary smoke.", "+Sticky Flame" end, - on_lose = function(self, err) return "The smoke around #target# dissipate.", "-Sticky Flame" end, + parameters = { slow=0.1, resist=10 }, + on_gain = function(self, err) return "#Target# is covered in sticky, flammable pitch.", "+Pitch" end, + on_lose = function(self, err) return "#Target# is free from the pitch.", "-Pitch" end, activate = function(self, eff) - if self.sight - eff.sight < 1 then eff.sight = self.sight - 1 end - eff.tmpid = self:addTemporaryValue("sight", -eff.sight) + eff.tmpid = self:addTemporaryValue("global_speed_add", -eff.slow) eff.resid = self:addTemporaryValue("resists", {[DamageType.FIRE] = -eff.resist}) - self:setTarget(nil) -- Loose target! - self:doFOV() end, deactivate = function(self, eff) - self:removeTemporaryValue("sight", eff.tmpid) + self:removeTemporaryValue("global_speed_add", eff.tmpid) self:removeTemporaryValue("resists", eff.resid) - self:doFOV() end, } @@ -3856,22 +3852,63 @@ newEffect{ } newEffect{ - name = "TAKING_AIM", image = "talents/concealment.png", - desc = "Taking Aim", - long_desc = function(self, eff) return ("The target is taking aim, increasing the damage of their next marked shot by %d%%."):format(eff.power) end, + name = "CONCEALMENT", image = "talents/concealment.png", + desc = "Concealment", + long_desc = function(self, eff) return ("The target is concealed, increasing sight and attack range by %d and chance to avoid damage by %d%%."):format(eff.sight, eff.power*eff.charges) end, type = "physical", subtype = { tactic=true }, status = "beneficial", charges = function(self, eff) return eff.charges end, - parameters = { power=5, duration=1, max_power=15, charges=1 }, - on_merge = function(self, old_eff, new_eff) - new_eff.charges = math.min(old_eff.charges + 1, 3) - new_eff.power = math.min(new_eff.power + old_eff.power, new_eff.max_power) - return new_eff - end, + parameters = { power=5, duration=1, sight=1, dam=10, max_power=15, charges=3 }, activate = function(self, eff) - eff.charges = 1 + self:effectTemporaryValue(eff, "cancel_damage_chance", eff.max_power) + self:effectTemporaryValue(eff, "sight", eff.sight) + self:effectTemporaryValue(eff, "infravision", eff.sight) + self:effectTemporaryValue(eff, "heightened_senses", eff.sight) + self:effectTemporaryValue(eff, "archery_bonus_range", eff.sight) + self:doFOV() end, deactivate = function(self, eff) + self:doFOV() + end, + on_timeout = function(self, eff) + if not self:isTalentActive(self.T_CONCEALMENT) then + eff.charges = eff.charges -1 + eff.max_power = eff.power*eff.charges + if eff.charges == 0 then self:removeEffect(self.EFF_CONCEALMENT) end + end end, } + +newEffect{ + name = "SHADOW_SMOKE", image = "talents/shadow_shot.png", + desc = "Shadow Smoke", + long_desc = function(self, eff) return ("The target is wrapped in disorientating smoke, confusing them and reducing vision range by %d."):format(eff.sight) end, + type = "physical", + subtype = { sense=true }, + status = "detrimental", + parameters = { sight=5 }, + on_gain = function(self, err) return "#Target# is surrounded by a thick smoke.", "+Shadow Smoke" end, + on_lose = function(self, err) return "The smoke around #target# dissipate.", "-Shadow Smoke" end, + charges = function(self, eff) return -eff.sight end, + activate = function(self, eff) + if self:canBe("blind") then + if self.sight - eff.sight < 1 then eff.sight = self.sight - 1 end + eff.tmpid = self:addTemporaryValue("sight", -eff.sight) + -- self:setTarget(nil) -- Loose target! + self:doFOV() + end + if self:canBe("confusion") then + eff.cid = self:addTemporaryValue("confused", 50) + end + end, + deactivate = function(self, eff) + if eff.tmpid then + self:removeTemporaryValue("sight", eff.tmpid) + self:doFOV() + end + if eff.cid then + self:removeTemporaryValue("confused", eff.cid) + end + end, +} \ No newline at end of file diff --git a/game/modules/tome/dialogs/QuestPopup.lua b/game/modules/tome/dialogs/QuestPopup.lua index 4c641c4efbe580c0a2052e4651d8bb95eb21ab4c..0f2a576dbffa7bb86c50fbe0f5566de5de3fb12a 100644 --- a/game/modules/tome/dialogs/QuestPopup.lua +++ b/game/modules/tome/dialogs/QuestPopup.lua @@ -35,8 +35,12 @@ local statuses = { } function _M:init(quest, status) + local use_ui = "quest" + if quest.use_ui then use_ui = quest.use_ui end + if status == Quest.FAILED then use_ui = "quest-fail" end + self.quest = quest - self.ui = "quest" + self.ui = use_ui Dialog.init(self, "", 666, 150) local add = '' @@ -53,7 +57,7 @@ function _M:init(quest, status) info:setTextShadow(3) info:setShadowShader(Shader.default.textoutline and Shader.default.textoutline.shad, 2) - local status = Textzone.new{ui="quest", auto_width=true, auto_height=true, text="#cc9f33#"..(statuses[status] or "????"), has_box=true, font={FontPackage:getFont("bignews")}} + local status = Textzone.new{ui=use_ui, auto_width=true, auto_height=true, text="#cc9f33#"..(statuses[status] or "????"), has_box=true, font={FontPackage:getFont("bignews")}} status:setTextShadow(3) status:setShadowShader(Shader.default.textoutline and Shader.default.textoutline.shad, 2)