Commit 94bde388224acd85972cd83e1c8c7ef72211b644

Authored by yutio888
2 parents 44f393fc 905a4a6d

Merge remote-tracking branch 'upstream/master' into power_vs_save_desc

# Conflicts:
#	game/modules/tome/data/talents/psionic/psi-fighting.lua
#	game/modules/tome/data/talents/techniques/2hweapon.lua
#	game/modules/tome/data/talents/techniques/strength-of-the-berserker.lua
... ... @@ -732,6 +732,14 @@ function _M:finishEntity(level, type, e, ego_filter)
732 732 for i = 1, #s do e:stack(s[i], true) end
733 733 end
734 734
  735 + -- Add self-referential property to combat tables
  736 + if e.combat then
  737 + e.combat.self = e
  738 + end
  739 + if e.special_combat then
  740 + e.special_combat.self = e
  741 + end
  742 +
735 743 e:resolve(nil, true)
736 744 e:check("finish", e, self, level)
737 745 self:triggerHook{"Zone:finishEntity", type=type, e=e}
... ...
... ... @@ -2947,7 +2947,7 @@ end
2947 2947 -- @param radius the radius in which to search
2948 2948 -- @param block true if we only consider line of sight
2949 2949 -- @param what a table which can have the fields Map.ACTOR, Map.OBJECT, ..., set to true. If so it will only return grids that are free of this kind of entities.
2950   -function util.findFreeGrid(sx, sy, radius, block, what)
  2950 +function util.findFreeGrid(sx, sy, radius, block, what, checker)
2951 2951 if not sx or not sy then return nil, nil, {} end
2952 2952 what = what or {}
2953 2953 local grids = core.fov.circle_grids(sx, sy, radius, block)
... ... @@ -2961,6 +2961,7 @@ function util.findFreeGrid(sx, sy, radius, block, what)
2961 2961 end
2962 2962 if game.level.map:checkEntity(x, y, game.level.map.TERRAIN, "block_move") then ok = false end
2963 2963 -- print("findFreeGrid", x, y, "from", sx,sy,"=>", ok)
  2964 + if checker and not checker(x, y) then ok = false end
2964 2965 if ok then
2965 2966 gs[#gs+1] = {x, y, core.fov.distance(sx, sy, x, y), rng.range(1, 1000)}
2966 2967 end
... ...
... ... @@ -21,7 +21,7 @@
21 21 -- Where values are {major, minor, patch, engine_name, c_core}
22 22 -- @script engine.version
23 23
24   -engine.version = {1,7,3,"te4",17}
  24 +engine.version = {1,7,4,"te4",17}
25 25 engine.require_c_core = engine.version[5]
26 26 engine.version_id = ("%s-%d_%d.%d.%d"):format(engine.version[4], engine.require_c_core, engine.version[1], engine.version[2], engine.version[3])
27 27
... ...
... ... @@ -197,8 +197,8 @@ Specific information on each talent appears its tooltip.]]
197 197 -------------------------------------------------------------
198 198 TOOLTIP_SPEED_GLOBAL = _t[[#GOLD#Global Speed#LAST#
199 199 Global speed represents how fast you are and affects everything you do.
200   -Higher is faster, so at 200% global speed you can performa twice as many actions as you would at 100% speed.
201   -Note that the amount of time to performa various actions like moving, casting spells, and attacking is also affected by their respective speeds.
  200 +Higher is faster, so at 200% global speed you can perform twice as many actions as you would at 100% speed.
  201 +Note that the amount of time to perform various actions like moving, casting spells, and attacking is also affected by their respective speeds.
202 202 ]]
203 203 TOOLTIP_SPEED_MOVEMENT = _t[[#GOLD#Movement Speed#LAST#
204 204 How quickly you move compared to normal.
... ... @@ -266,8 +266,8 @@ This damage can be reduced by the target's armour or by percentile damage resist
266 266 It is improved by Strength or Dexterity, depending on your weapon. Some talents can change the stats that affect it.
267 267 ]]
268 268 TOOLTIP_COMBAT_BLOCK = _t[[#GOLD#Shield Block Value#LAST#
269   -The amount of damage a shield will block when actively used in defense.
270   -Usually this is only effective against Physical damage, but some special shields (and talents) allow the wearer to block other types.
  269 +The base amount of damage a shield will block when actively used in defense.
  270 +Mind damage cannot be blocked. Against other damage types you gain a 50%% bonus to the block value if the shield used grants resistance to that damage type.
271 271 ]]
272 272 TOOLTIP_COMBAT_APR = _t[[#GOLD#Armour Penetration#LAST#
273 273 Armour penetration allows you to ignore a part of the target's armour (this only works for armour, not damage resistance).
... ...
... ... @@ -109,7 +109,7 @@ newTalent{
109 109 local damage = t.getDamage(self, t)
110 110 local shieldflat = t.getShieldFlat(self, t)
111 111 return ([[Infuse your weapon with the power of the Sun, adding %0.1f light damage on each melee hit.
112   - Additionally, if you have a temporary damage shield active, melee hits will increase its power by %d once per turn.
  112 + Additionally, if you have a temporary damage shield active, melee hits will increase its power by %d and set its duration to 2 (if not already higher), once per turn.
113 113 The damage dealt and shield bonus will increase with your Spellpower.]]):
114 114 tformat(damDesc(self, DamageType.LIGHT, damage), shieldflat)
115 115 end,
... ...
... ... @@ -22,7 +22,7 @@
22 22 -- returns detect, closest = total detection power, distance to closest enemy
23 23 -- if estimate is true, only counts the detection power of seen actors
24 24 local function stealthDetection(self, radius, estimate)
25   - if not self.x then return nil end
  25 + if not self.x then return 0, math.huge end
26 26 local dist = 0
27 27 local closest, detect = math.huge, 0
28 28 for i, act in ipairs(self.fov.actors_dist) do
... ...
... ... @@ -1756,7 +1756,7 @@ newTalent{
1756 1756 return true
1757 1757 end,
1758 1758 short_info = function(self, t)
1759   - return ([[Creates a radius 5 gravitic anomaly lasting up to %d turns. Hostile creatures are dealt %d temporal damgae and pulled in. Triggers out to range 1.]]):
  1759 + return ([[Creates a radius 5 gravitic anomaly lasting up to %d turns. Hostile creatures are dealt %d temporal damage and pulled in. Triggers out to range 1.]]):
1760 1760 tformat(t.getDuration(self,t), damDesc(self, engine.DamageType.TEMPORAL, t.getDamage(self, t)))
1761 1761 end,
1762 1762 info = function(self, t)
... ...
... ... @@ -233,18 +233,18 @@ newInscription{
233 233 tactical = { DEFEND = 1 },
234 234 action = function(self, t)
235 235 local data = self:getInscriptionData(t.short_name)
236   - local bonus = 1 + (1 - self.life / self.max_life)
  236 + local bonus = 1 + (1 - math.max(0, self.life) / self.max_life)
237 237 self:setEffect(self.EFF_HEROISM, math.floor(data.dur * bonus), {die_at=(data.die_at + data.inc_stat * 30) * bonus})
238 238 return true
239 239 end,
240 240 info = function(self, t)
241 241 local data = self:getInscriptionData(t.short_name)
242   - local bonus = 1 + (1 - self.life / self.max_life)
  242 + local bonus = 1 + (1 - math.max(0, self.life) / self.max_life)
243 243 local bonus1 = (data.die_at + data.inc_stat * 30) * bonus
244 244 local bonus2 = math.floor(data.dur * bonus)
245 245 return ([[Activate the infusion to endure even the most grievous of wounds for %d turns.
246 246 While Heroism is active, you will only die when reaching -%d life.
247   - The duration and life will increase by 1%% for every 1%% life you have lost (currently %d life, %d duration)
  247 + The duration and life will increase by 1%% for every 1%% life you have lost, to a maximum of 100%% at 0 life or less (currently %d life, %d duration)
248 248 If your life is below 0 when this effect wears off it will be set to 1.]]):tformat(data.dur, data.die_at + data.inc_stat * 30, bonus1, bonus2)
249 249 end,
250 250 short_info = function(self, t)
... ...
... ... @@ -194,7 +194,7 @@ newTalent{
194 194 info = function(self, t)
195 195 return ([[Focus your will into a powerful thrust of your telekinetically-wielded weapon to impale your target and then viciously rip it free.
196 196 This deals %d%% weapon damage and then causes the victim to bleed for %0.1f Physical damage over four turns %s.
197   - At level 3 the thrust is so powerful that it has %d%% chance to shatter a temporary damage shield if one exists.
  197 + At level 3 the thrust is so powerful that it has %d%% chance to shatter a random temporary magical or psionic damage absorbing shield if one exists.
198 198 The bleeding damage increases with your Mindpower.]]):
199 199 tformat(100 * t.getWeaponDamage(self, t), damDesc(self, DamageType.PHYSICAL, t.getDamage(self,t)), Desc.vs"mp", t.getShatter(self, t))
200 200 end,
... ...
... ... @@ -232,7 +232,7 @@ newTalent{
232 232 when = ("\n#DARK_SEA_GREEN#Next free ghoul in %d turn(s).\n#LAST#"):tformat(t:_getEvery(self) - self.__call_mausoleum_turns)
233 233 end
234 234
235   - return ([[You control dead matter around you, lyring in the ground, decaying.
  235 + return ([[You control dead matter around you, lying in the ground, decaying.
236 236 When you enter combat and every %d turns thereafter a ghoul of level %d automatically raises to fight for you.
237 237 At level 3 you can forcefully activate this spell to summon up to %d ghasts around you.
238 238 At level 5 every 4 summoned ghouls or ghasts a ghoulking is summoned for free.
... ...
... ... @@ -313,7 +313,7 @@ newTalent{
313 313 end,
314 314 info = function(self, t)
315 315 return ([[Hits the target with your weapon, doing %d%% damage. If the attack hits, the target's armour and saves are reduced by %d for %d turns %s.
316   - Also if the target is protected by a temporary damage shield there is %d%% chance to shatter it.]])
  316 + Also if the target is protected by any temporary magical or psionic damage absorbing shields there is %d%% chance to shatter one random shield.]])
317 317 :tformat(100 * self:combatTalentWeaponDamage(t, 1, 1.5),t.getArmorReduc(self, t), t.getDuration(self, t), Desc.vs"pp", t.getShatter(self, t))
318 318 end,
319 319 }
... ...
... ... @@ -199,7 +199,7 @@ newTalent{
199 199 end,
200 200 info = function(self, t)
201 201 return ([[Hits the target with your weapon, doing %d%% damage. If the attack hits, the target's armour and saves are reduced by %d for %d turns %s.
202   - Also if the target is protected by a temporary damage shield there is %d%% chance to shatter it %s.]])
  202 + Also if the target is protected by any temporary magical or psionic damage absorbing shields there is %d%% chance to shatter a random shield %s.]])
203 203 :tformat(100 * self:combatTalentWeaponDamage(t, 0.8, 1.5), t.getArmorReduc(self, t), t.getDuration(self, t), Desc.vs"pp", t.getShatter(self, t), Desc.vs())
204 204 end,
205 205 }
... ...
... ... @@ -367,7 +367,7 @@ newEffect{
367 367 long_desc = function(self, eff) return ("The target is protected a raging storm deflecting up to %d instances of damage over %d."):
368 368 tformat(eff.blocks, eff.threshold) end,
369 369 type = "magical",
370   - subtype = { lightning=true, shield=true },
  370 + subtype = { lightning=true},
371 371 status = "beneficial",
372 372 charges = function(self, eff) return math.floor(eff.blocks) end,
373 373 parameters = {threshold = 1, blocks = 1,},
... ... @@ -1332,7 +1332,7 @@ newEffect{
1332 1332 desc = _t"Providence",
1333 1333 long_desc = function(self, eff) return ("The target is under protection, removing one negative effect per turn."):tformat() end,
1334 1334 type = "magical",
1335   - subtype = { light=true, shield=true },
  1335 + subtype = { light=true},
1336 1336 status = "beneficial",
1337 1337 parameters = {},
1338 1338 on_timeout = function(self, eff)
... ... @@ -1795,7 +1795,7 @@ newEffect{
1795 1795 desc = _t"Bone Shield",
1796 1796 long_desc = function(self, eff) return ("Any attacks doing more than %d%% of your life is reduced to %d%%."):tformat(eff.power, eff.power) end,
1797 1797 type = "magical",
1798   - subtype = { arcane=true, shield=true },
  1798 + subtype = { arcane=true},
1799 1799 status = "beneficial",
1800 1800 parameters = { power=30 },
1801 1801 on_gain = function(self, err) return _t"#Target# protected by flying bones.", _t"+Bone Shield" end,
... ... @@ -2835,7 +2835,6 @@ newEffect{
2835 2835 activate = function(self, eff)
2836 2836 self:effectTemporaryValue(eff, "numbed", eff.reduce)
2837 2837 if eff.resists then
2838   - game.log("plop")
2839 2838 self:effectTemporaryValue(eff, "resists_cap", {[DamageType.LIGHT]=-(self.resists_cap.all or 0)-(self.resists_cap.LIGHT or 0), [DamageType.FIRE]=-(self.resists_cap.all or 0)-(self.resists_cap.FIRE or 0)})
2840 2839 end
2841 2840 end,
... ... @@ -5508,7 +5507,7 @@ newEffect{
5508 5507 desc = _t"Dirge of Pestilence",
5509 5508 long_desc = function(self, eff) return ("The target will gain a shield upon suffering a detrimental effect"):tformat() end,
5510 5509 type = "magical",
5511   - subtype = { shield=true },
  5510 + subtype = { dirge=true },
5512 5511 status = "beneficial",
5513 5512 parameters = { shield=50, cd=5 },
5514 5513 callbackOnTemporaryEffectAdd = function(self, eff, eff_id, e_def, eff_incoming)
... ...
... ... @@ -2146,7 +2146,7 @@ newEffect{
2146 2146 display_desc = function(self, eff) return ("%s Psionic Shield"):tformat(_t(eff.kind):capitalize()) end,
2147 2147 long_desc = function(self, eff) return ("Reduces all incoming %s damage by %d."):tformat(eff.what, eff.power) end,
2148 2148 type = "mental",
2149   - subtype = { psionic=true, shield=true },
  2149 + subtype = { psionic=true },
2150 2150 status = "beneficial",
2151 2151 parameters = { power=10, kind="kinetic" },
2152 2152 activate = function(self, eff)
... ... @@ -2687,7 +2687,7 @@ newEffect{
2687 2687 desc = _t"Shadow Empathy",
2688 2688 long_desc = function(self, eff) return ("%d%% of all damage is redirected to a random shadow."):tformat(eff.power) end,
2689 2689 type = "mental",
2690   - subtype = { mind=true, shield=true },
  2690 + subtype = { mind=true },
2691 2691 status = "beneficial",
2692 2692 parameters = { power=10 },
2693 2693 activate = function(self, eff)
... ... @@ -2704,7 +2704,7 @@ newEffect{
2704 2704 desc = _t"Shadow Decoy",
2705 2705 long_desc = function(self, eff) return ("A random shadow absorbed a fatal blow for you, granting you a negative shield of %d."):tformat(eff.power) end,
2706 2706 type = "mental",
2707   - subtype = { mind=true, shield=true },
  2707 + subtype = { mind=true},
2708 2708 status = "beneficial",
2709 2709 parameters = { power=10 },
2710 2710 activate = function(self, eff)
... ...
... ... @@ -3665,7 +3665,7 @@ newEffect{
3665 3665 desc = _t"Stone Link",
3666 3666 long_desc = function(self, eff) return ("The target protects all those around it in radius %d by redirecting all damage against them to itself."):tformat(eff.rad) end,
3667 3667 type = "physical",
3668   - subtype = { earth=true, shield=true },
  3668 + subtype = { earth=true },
3669 3669 status = "beneficial",
3670 3670 parameters = { rad=3 },
3671 3671 on_gain = function(self, err) return ("#Target# begins protecting %s friends with a stone shield."):tformat(string.his_her(self)), _t"+Stone Link" end,
... ... @@ -3694,7 +3694,7 @@ newEffect{
3694 3694 desc = _t"Stone Link",
3695 3695 long_desc = function(self, eff) return ("The target is protected by %s, redirecting all damage to it."):tformat(eff.src:getName()) end,
3696 3696 type = "physical",
3697   - subtype = { earth=true, shield=true },
  3697 + subtype = { earth=true },
3698 3698 status = "beneficial",
3699 3699 parameters = { },
3700 3700 on_gain = function(self, err) return _t"#Target# is protected by a stone shield.", _t"+Stone Link" end,
... ...