diff --git a/game/engines/default/engine/Map.lua b/game/engines/default/engine/Map.lua index 9823ac71498b14cfd85789fe408a180ca14a35df..2e54bc5ff3ee682d7cb88cb4e4ccae8da717f75c 100644 --- a/game/engines/default/engine/Map.lua +++ b/game/engines/default/engine/Map.lua @@ -1007,6 +1007,7 @@ function _M:addEffect(src, x, y, duration, damtype, dam, radius, dir, angle, ove table.insert(self.effects, e) self.changed = true + return e end --- Display the overlay effects, called by self:display() @@ -1041,7 +1042,9 @@ function _M:processEffects() elseif act and e.src and e.src.reactionToward and (e.src:reactionToward(act) >= 0) and not ((type(e.friendlyfire) == "number" and rng.percent(e.friendlyfire)) or (type(e.friendlyfire) ~= "number" and e.friendlyfire)) then -- Otherwise hit else + e.src.__project_source = e -- intermediate projector source DamageType:get(e.damtype).projector(e.src, lx, ly, e.damtype, e.dam) + e.src.__project_source = nil end end end diff --git a/game/engines/default/engine/Projectile.lua b/game/engines/default/engine/Projectile.lua index 26732cc668a7aa28dffb3188e526e72766ad449c..31f5ee46787ee658c6a317828a1248dc8acc1800 100644 --- a/game/engines/default/engine/Projectile.lua +++ b/game/engines/default/engine/Projectile.lua @@ -205,6 +205,7 @@ function _M:act() if self.project then local x, y, act, stop = self.src:projectDoMove(self.project.def.typ, self.project.def.x, self.project.def.y, self.x, self.y, self.project.def.start_x, self.project.def.start_y) if x and y then self:move(x, y) end + if self.src then self.src.__project_source = self end -- intermediate projector source if act then self.src:projectDoAct(self.project.def.typ, self.project.def.tg, self.project.def.damtype, self.project.def.dam, self.project.def.particles, self.x, self.y, self.tmp_proj) end if stop then local block, hit, hit_radius = false, true, true @@ -219,9 +220,11 @@ function _M:act() end self.src:projectDoStop(self.project.def.typ, self.project.def.tg, self.project.def.damtype, self.project.def.dam, self.project.def.particles, self.x, self.y, self.tmp_proj, radius_x, radius_y, self) end + if self.src then self.src.__project_source = nil end -- intermediate projector source elseif self.homing then self:moveDirection(self.homing.target.x, self.homing.target.y) self.homing.count = self.homing.count - 1 + if self.src then self.src.__project_source = self end -- intermediate projector source if (self.x == self.homing.target.x and self.y == self.homing.target.y) or self.homing.count <= 0 then game.level:removeEntity(self, true) self.dead = true @@ -229,18 +232,21 @@ function _M:act() else self.homing.on_move(self, self.src) end + if self.src then self.src.__project_source = nil end -- intermediate projector source end end - return true end --- Something moved in the same spot as us, hit ? function _M:on_move(x, y, target) + self.src.__project_source = self -- intermediate projector source if self.project and self.project.def.typ.line then self.src:projectDoAct(self.project.def.typ, self.project.def.tg, self.project.def.damtype, self.project.def.dam, self.project.def.particles, self.x, self.y, self.tmp_proj) end if self.project and self.project.def.typ.stop_block then + self.src:projectDoStop(self.project.def.typ, self.project.def.tg, self.project.def.damtype, self.project.def.dam, self.project.def.particles, self.x, self.y, self.tmp_proj, self.x, self.y, self) end + self.src.__project_source = nil end --- Premature end diff --git a/game/engines/default/engine/Trap.lua b/game/engines/default/engine/Trap.lua index 3af64cfe1dd2f0917ad1dbaf0b79a0a3f3cc5498..3443301ed9e877c39ca49a69c4d662230a66f058 100644 --- a/game/engines/default/engine/Trap.lua +++ b/game/engines/default/engine/Trap.lua @@ -135,7 +135,9 @@ function _M:trigger(x, y, who) game.logSeen(who, "%s", str) end local known, del = false, false + if self.summoner then self.summoner.__project_source = self end -- intermediate projector source if self.triggered then known, del = self:triggered(x, y, who) end + if self.summoner then self.summoner.__project_source = nil end if known then self:setKnown(who, true) game.level.map:updateMap(x, y) diff --git a/game/engines/default/engine/interface/ActorProject.lua b/game/engines/default/engine/interface/ActorProject.lua index 207280f1202ea96b488c59baf264e24bc23ba7fc..886ea386d3faaf6e58afbbbb3fdd35992ea1dd72 100644 --- a/game/engines/default/engine/interface/ActorProject.lua +++ b/game/engines/default/engine/interface/ActorProject.lua @@ -311,6 +311,7 @@ function _M:projectile(t, x, y, damtype, dam, particles) game.zone:addEntity(game.level, proj, "projectile", typ.start_x, typ.start_y) self:check("on_projectile_fired", proj, typ, x, y, damtype, dam, particles) + return proj end -- @param typ a target type table diff --git a/game/engines/default/engine/interface/ActorTemporaryEffects.lua b/game/engines/default/engine/interface/ActorTemporaryEffects.lua index 7a58d713da01f0864d390e2a209dcd792af2eee7..a057bafaea5b5ca87751af53578805c1704dde2b 100644 --- a/game/engines/default/engine/interface/ActorTemporaryEffects.lua +++ b/game/engines/default/engine/interface/ActorTemporaryEffects.lua @@ -73,9 +73,11 @@ function _M:timedEffects(filter) todel[#todel+1] = eff else if def.on_timeout then + if p.src then p.src.__project_source = p end -- intermediate projector source if def.on_timeout(self, p) then todel[#todel+1] = eff end + if p.src then p.src.__project_source = nil end end end p.dur = p.dur - def.decrease @@ -103,6 +105,7 @@ function _M:setEffect(eff_id, dur, p, silent) if not p[k] then p[k] = e end end p.dur = dur + p.effect_id = eff_id self:check("on_set_temporary_effect", eff_id, _M.tempeffect_def[eff_id], p) if p.dur <= 0 then return self:removeEffect(eff_id) end diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index 97f583b835b9bed35f96c8e7729b094fe3020765..2c1d209e1062e2de31d05455679a38a8e97a65f9 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -1046,7 +1046,7 @@ function _M:move(x, y, force) local grids = core.fov.circle_grids(self.x, self.y, 1, true) for x, yy in pairs(grids) do for y, _ in pairs(yy) do local trap = game.level.map(x, y, Map.TRAP) - if trap and not trap:knownBy(self) and self:checkHit(power, trap.detect_power) then + if trap and not trap:knownBy(self) and self:canSee(trap) and self:checkHit(power, trap.detect_power) then trap:setKnown(self, true) game.level.map:updateMap(x, y) game.logPlayer(self, "You have found a trap (%s)!", trap:getName()) @@ -1539,7 +1539,7 @@ function _M:onHeal(value, src) if eff.src == self then game.logSeen(self, "%s heal is doubled!", self.name) else - game.logSeen(self, "%s steals %s heal!", eff.src.name:capitalize(), self.name) + self:logCombat(eff.src, "#Target# steals #Source#'s heal!") return 0 end end @@ -1663,7 +1663,7 @@ function _M:onTakeHit(value, src, death_note) local a = rng.table(tgts) if a then - game.logSeen(self, "Some of the damage has been displaced onto %s!", a.name:capitalize()) + self:logCombat(a, "Some of the damage has been displaced onto #Target#!") a:takeHit(value / 2, self) value = value / 2 end @@ -1741,7 +1741,7 @@ function _M:onTakeHit(value, src, death_note) local a = game.level.map(src.x, src.y, Map.ACTOR) if a and self:reactionToward(a) < 0 then a:takeHit(math.ceil(reflect_damage * reflection), self) - game.logSeen(self, "The damage shield reflects %d damage back to %s!", math.ceil(reflect_damage * reflection), a.name:capitalize()) + self:logCombat(a, "The damage shield reflects %d damage back to #Target#!", math.ceil(reflect_damage * reflection)) end end -- If we are at the end of the capacity, release the time shield damage @@ -1755,7 +1755,7 @@ function _M:onTakeHit(value, src, death_note) -- Absorb damage into the displacement shield if rng.percent(self.displacement_shield_chance) then if value <= self.displacement_shield then - game.logSeen(self, "The displacement shield teleports the damage to %s!", self.displacement_shield_target.name) + game:delayedLogMessage(self, src, "displacement_shield", "#CRIMSON##Source# teleports some damage to #Target#!") self.displacement_shield = self.displacement_shield - value self.displacement_shield_target:takeHit(value, src) value = 0 @@ -2003,7 +2003,7 @@ function _M:onTakeHit(value, src, death_note) a:removeAllMOs() a.x, a.y = nil, nil game.zone:addEntity(game.level, a, "actor", x, y) - game.logSeen(self, "%s is split in two!", self.name:capitalize()) + game.logSeen(self, "%s splits in two!", self.name:capitalize()) value = value / 2 end end @@ -2021,7 +2021,10 @@ function _M:onTakeHit(value, src, death_note) damage_to_psi = self:getPsi() self:incPsi(-damage_to_psi) end - game.logSeen(self, "%s's mind suffers #YELLOW#%d psi#LAST# damage from the attack.", self.name:capitalize(), damage_to_psi*psi_damage_resist) + local mindcolor = DamageType:get(DamageType.MIND).text_color or "#aaaaaa#" + game:delayedLogMessage(self, nil, "Solipsism hit", mindcolor.."#Source# converts some damage to Psi!") + game:delayedLogDamage(src, self, damage_to_psi*psi_damage_resist, ("%s%d %s#LAST#"):format(mindcolor, damage_to_psi*psi_damage_resist, "to psi"), false) + value = value - damage_to_psi end @@ -2077,7 +2080,7 @@ function _M:onTakeHit(value, src, death_note) local vt = self:getTalentFromId(self.T_LEECH) self:incVim(vt.getVim(self, vt)) self:heal(vt.getHeal(self, vt)) - game.logPlayer(self, "#AQUAMARINE#You leech a part of %s's vim.", src.name:capitalize()) + if self.player then src:logCombat(src, "#AQUAMARINE#You leech a part of #Target#'s vim.") end end -- Invisible on hit @@ -2121,7 +2124,7 @@ function _M:onTakeHit(value, src, death_note) local leech = math.min(value, self.life) * src.life_leech_value / 100 if leech > 0 then src:heal(leech) - game.logSeen(src, "#CRIMSON#%s leeches life from its victim!", src.name:capitalize()) + game:delayedLogMessage(src, self, "life_leech"..self.uid, "#CRIMSON##Source# leeches life from #Target#!") end end @@ -2139,7 +2142,7 @@ function _M:onTakeHit(value, src, death_note) src:incStamina(leech * 0.65) src:incHate(leech * 0.2) src:incPsi(leech * 0.2) - game.logSeen(src, "#CRIMSON#%s leeches energies from its victim!", src.name:capitalize()) + game:delayedLogMessage(src, self, "resource_leech", "#CRIMSON##Source# leeches energies from #Target#!") end if self:knowTalent(self.T_DRACONIC_BODY) then @@ -4036,7 +4039,7 @@ function _M:postUseTalent(ab, ret, silent) local t = rng.tableRemove(tids) if not t then break end self.talents_cd[t.id] = self:attr("random_talent_cooldown_on_use_turns") - game.log("%s talent '%s%s' is disrupted by the mind parasite.", self.name:capitalize(), (t.display_entity and t.display_entity:getDisplayString() or ""), t.name) + game.logSeen(self, "%s talent '%s%s' is disrupted by the mind parasite.", self.name:capitalize(), (t.display_entity and t.display_entity:getDisplayString() or ""), t.name) end end @@ -4385,7 +4388,7 @@ function _M:suffocate(value, src, death_message) return false, true end ---- Can the actor see the target actor +-- Can the actor see the target actor (or other entity) -- This does not check LOS or such, only the actual ability to see it.<br/> -- Check for telepathy, invisibility, stealth, ... function _M:canSeeNoCache(actor, def, def_pct) @@ -4415,7 +4418,7 @@ function _M:canSeeNoCache(actor, def, def_pct) end -- Check for stealth. Checks against the target cunning and level - if actor:attr("stealth") and actor ~= self then + if actor ~= self and actor.attr and actor:attr("stealth") then local def = self:combatSeeStealth() local hit, chance = self:checkHitOld(def, actor:attr("stealth") + (actor:attr("inc_stealth") or 0), 0, 100) if not hit then @@ -4424,7 +4427,7 @@ function _M:canSeeNoCache(actor, def, def_pct) end -- Check for invisibility. This is a "simple" checkHit between invisible and see_invisible attrs - if actor:attr("invisible") and actor ~= self then + if actor ~= self and actor.attr and actor:attr("invisible") then -- Special case, 0 see invisible, can NEVER see invisible things local def = self:combatSeeInvisible() if def <= 0 then return false, 0 end @@ -4569,6 +4572,8 @@ local save_for_effects = { --- Adjust temporary effects function _M:on_set_temporary_effect(eff_id, e, p) + p.getName = self.tempeffect_def[eff_id].getName + p.resolveSource = self.tempeffect_def[eff_id].resolveSource if p.apply_power and (save_for_effects[e.type] or p.apply_save) then local save = 0 p.maximum = p.dur @@ -4669,7 +4674,7 @@ function _M:on_project_acquire(tx, ty, who, t, x, y, damtype, dam, particles, is else dir = "to the "..dir.."!" end - game.logSeen(self, "%s deflects the projectile from %s %s", self.name:capitalize(), who.name, dir) + self:logCombat(who, "#Source# deflects the projectile from #Target# %s", dir) return true end end diff --git a/game/modules/tome/class/FortressPC.lua b/game/modules/tome/class/FortressPC.lua index f4e8d3e2575212832339dc675042cccdcded2100..13ebd56ac445f2b6929ec3ab4aebf211b9bddf3b 100644 --- a/game/modules/tome/class/FortressPC.lua +++ b/game/modules/tome/class/FortressPC.lua @@ -170,7 +170,7 @@ function _M:moveModActor(x, y, force) local grids = core.fov.circle_grids(self.x, self.y, 1, true) for x, yy in pairs(grids) do for y, _ in pairs(yy) do local trap = game.level.map(x, y, Map.TRAP) - if trap and not trap:knownBy(self) and self:checkHit(power, trap.detect_power) then + if trap and not trap:knownBy(self) and self:canSee(trap) and self:checkHit(power, trap.detect_power) then trap:setKnown(self, true) game.level.map:updateMap(x, y) game.logPlayer(self, "You have found a trap (%s)!", trap:getName()) diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index 26fb61a1f1c821cd8b865a6b49286398355ae69a..3c61524ed49a83ea435d75f5ca10e2b99ae42b17 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -94,6 +94,7 @@ end function _M:runReal() self.delayed_log_damage = {} + self.delayed_log_messages = {} self.calendar = Calendar.new("/data/calendar_allied.lua", "Today is the %s %s of the %s year of the Age of Ascendancy of Maj'Eyal.\nThe time is %02d:%02d.", 122, 167, 11) self.uiset:activate() @@ -1132,6 +1133,7 @@ function _M:tick() end -- Check damages to log + self:displayDelayedLogMessages() self:displayDelayedLogDamage() if self.tick_loopback then @@ -1144,28 +1146,125 @@ function _M:tick() -- if self.on_tick_end and #self.on_tick_end > 0 then return true end end +-- Game Log management functions: +-- logVisible to determine if a message should be visible to the player +-- logMessage to add a message to the display +-- delayedLogMessage to queue an actor-specific message for display at the end of the current game tick +-- displayDelayedLogMessages() to display the queued messages (before combat damage messages) +-- delayedLogDamage to queue a combat (damage) message for display at the end of the current game tick +-- displayDelayedLogDamage to display the queued combat messages + +-- output a message to the log based on the visibility of an actor to the player +function _M.logSeen(e, style, ...) + if e and e.player or (not e.dead and e.x and e.y and game.level and game.level.map.seens(e.x, e.y) and game.player:canSee(e)) then game.log(style, ...) end +end + +-- determine whether an action between 2 actors should produce a message in the log and if the player +-- can identify them +-- output: src, srcSeen: source display?, identify? +-- tgt, tgtSeen: target display?, identify? +-- output: Visible? and srcSeen (source is identified by the player), tgtSeen(target is identified by the player) +function _M:logVisible(source, target) + -- target should display if it's the player, an actor in a seen tile, or a non-actor without coordinates + local tgt = target and (target.player or (target.__is_actor and game.level.map.seens(target.x, target.y)) or (not target.__is_actor and not target.x)) + local tgtSeen = tgt and (target.player or game.player:canSee(target)) or false + local src, srcSeen = false, false +-- local srcSeen = src and (not source.x or (game.player:canSee(source) and game.player:canSee(target))) + -- Special cases + if not source.x then -- special case: unpositioned source uses target parameters (for timed effects on target) + if tgtSeen then + src, srcSeen = tgt, tgtSeen + else + src, tgt = nil, nil + end + else -- source should display if it's the player or an actor in a seen tile, or same as target for non-actors + src = source.player or (source.__is_actor and game.level.map.seens(source.x, source.y)) or (not source.__is_actor and tgt) + srcSeen = src and game.player:canSee(source) or false + end + + return src or tgt or false, srcSeen, tgtSeen +end + +-- Generate a message (string) for the log with possible source and target, +-- highlighting the player and taking visibility into account +-- srcSeen, tgtSeen = can player see(identify) the source, target? +-- style text message to display, may contain: +-- #source#|#Source# -> <displayString>..self.name|self.name:capitalize() +-- #target#|#Target# -> target.name|target.name:capitalize() +function _M:logMessage(source, srcSeen, target, tgtSeen, style, ...) + style = style:format(...) + local srcname = "something" + local Dstring + if source.player then + srcname = source.name.."(YOU)" + elseif srcSeen then + srcname = engine.Entity.check(source, "getName") or source.name or "unknown" + end + if srcname ~= "something" then Dstring = source.__is_actor and source.getDisplayString and source:getDisplayString() end + style = style:gsub("#source#", srcname) + style = style:gsub("#Source#", (Dstring or "")..srcname:capitalize()) + if target then + local tgtname = "something" + if target.player then + tgtname = target.name.."(YOU)" + elseif tgtSeen then + tgtname = engine.Entity.check(target, "getName") or target.name or "unknown" + end + style = style:gsub("#target#", tgtname) + style = style:gsub("#Target#", tgtname:capitalize()) + end + return style +end + +-- log an entity-specific message for display later with displayDelayedLogDamage +-- only one message (processed with logMessage) will be logged for each source and label +-- useful to avoid spamming repeated messages +-- target is optional and is used only to resolve the msg +function _M:delayedLogMessage(source, target, label, msg, ...) + local visible, srcSeen, tgtSeen = self:logVisible(source, target) + if visible then + self.delayed_log_messages[source] = self.delayed_log_messages[source] or {} + local src = self.delayed_log_messages[source] + src[label] = self:logMessage(source, srcSeen, target, tgtSeen, msg, ...) + end +end + +-- display the delayed log messages +function _M:displayDelayedLogMessages() + if not self.uiset or not self.uiset.logdisplay then return end + for src, msgs in pairs(self.delayed_log_messages) do + for label, msg in pairs(msgs) do + game.uiset.logdisplay(self:logMessage(src, true, nil, nil, msg)) + end + end + self.delayed_log_messages = {} +end + +-- Note: There can be up to a 1 tick delay in displaying log information function _M:displayDelayedLogDamage() + if not self.uiset or not self.uiset.logdisplay then return end +local newmessage = false --debugging for src, tgts in pairs(self.delayed_log_damage) do +newmessage = true -- debugging for target, dams in pairs(tgts) do if #dams.descs > 1 then - self.logSeen(target, "%s%s hits %s for %s damage (total %0.2f).", src:getDisplayString(), src.name:capitalize(), target.name, table.concat(dams.descs, ", "), dams.total) + game.uiset.logdisplay(self:logMessage(src, dams.srcSeen, target, dams.tgtSeen, "#Source# hits #Target# for %s damage (total %0.1f).", table.concat(dams.descs, ", "), dams.total)) else - self.logSeen(target, "%s%s hits %s for %s damage.", src:getDisplayString(), src.name:capitalize(), target.name, table.concat(dams.descs, ", ")) + game.uiset.logdisplay(self:logMessage(src, dams.srcSeen, target, dams.tgtSeen, "#Source# hits #Target# for %s damage.", table.concat(dams.descs, ", "))) end - local rsrc = src.resolveSource and src:resolveSource() or src local rtarget = target.resolveSource and target:resolveSource() or target local x, y = target.x or -1, target.y or -1 local sx, sy = self.level.map:getTileToScreen(x, y) if target.dead then - if self.level.map.seens(x, y) and (rsrc == self.player or rtarget == self.player or self.party:hasMember(rsrc) or self.party:hasMember(rtarget)) then + if dams.tgtSeen and (rsrc == self.player or rtarget == self.player or self.party:hasMember(rsrc) or self.party:hasMember(rtarget)) then self.flyers:add(sx, sy, 30, (rng.range(0,2)-1) * 0.5, rng.float(-2.5, -1.5), ("Kill (%d)!"):format(dams.total), {255,0,255}, true) - game.logSeen(target, "#{bold}#%s%s killed %s!#{normal}#", src:getDisplayString(), src.name:capitalize(), target.name) + self:delayedLogMessage(target, nil, "death", self:logMessage(src, dams.srcSeen, target, dams.tgtSeen, "#{bold}##Source# killed #Target#!#{normal}#")) end else - if self.level.map.seens(x, y) and (rsrc == self.player or self.party:hasMember(rsrc)) then + if dams.tgtSeen and (rsrc == self.player or self.party:hasMember(rsrc)) then self.flyers:add(sx, sy, 30, (rng.range(0,2)-1) * 0.5, rng.float(-3, -2), tostring(-math.ceil(dams.total)), {0,255,dams.is_crit and 200 or 0}, dams.is_crit) - elseif self.level.map.seens(x, y) and (rtarget == self.player or self.party:hasMember(rtarget)) then + elseif dams.tgtSeen and (rtarget == self.player or self.party:hasMember(rtarget)) then self.flyers:add(sx, sy, 30, (rng.range(0,2)-1) * 0.5, -rng.float(-3, -2), tostring(-math.ceil(dams.total)), {255,dams.is_crit and 200 or 0,0}, dams.is_crit) end end @@ -1176,17 +1275,23 @@ function _M:displayDelayedLogDamage() self.delayed_log_damage = {} end +-- log and collate combat damage for later display with displayDelayedLogDamage function _M:delayedLogDamage(src, target, dam, desc, crit) - self.delayed_log_damage[src] = self.delayed_log_damage[src] or {} - self.delayed_log_damage[src][target] = self.delayed_log_damage[src][target] or {total=0, descs={}} - local t = self.delayed_log_damage[src][target] - t.descs[#t.descs+1] = desc - t.total = t.total + dam - t.is_crit = t.is_crit or crit + src = src.__project_source or src -- assign message to indirect damage source if available + local visible, srcSeen, tgtSeen = self:logVisible(src, target) + if visible then -- only log damage the player is aware of + self.delayed_log_damage[src] = self.delayed_log_damage[src] or {} + self.delayed_log_damage[src][target] = self.delayed_log_damage[src][target] or {total=0, descs={}} + local t = self.delayed_log_damage[src][target] + t.descs[#t.descs+1] = desc + t.total = t.total + dam + t.is_crit = t.is_crit or crit + t.srcSeen = srcSeen + t.tgtSeen = tgtSeen + end end --- Called every game turns --- Does nothing, you can override it function _M:onTurn() if self.zone then if self.zone.on_turn then self.zone:on_turn() end diff --git a/game/modules/tome/class/Grid.lua b/game/modules/tome/class/Grid.lua index b1f42ff7e547d1dacd2e5627559986db985c55e1..bd55114a1e36f716d52393a64bef105df78ca11e 100644 --- a/game/modules/tome/class/Grid.lua +++ b/game/modules/tome/class/Grid.lua @@ -22,9 +22,12 @@ require "engine.Grid" local Map = require "engine.Map" local Dialog = require "engine.ui.Dialog" local DamageType = require "engine.DamageType" +local Combat = require "mod.class.interface.Combat" module(..., package.seeall, class.inherit(engine.Grid)) +_M.logCombat = Combat.logCombat + function _M:init(t, no_default) engine.Grid.init(self, t, no_default) @@ -123,6 +126,24 @@ function _M:on_move(x, y, who, forced) end end +function _M:resolveSource() + if self.summoner_gain_exp and self.summoner then + return self.summoner:resolveSource() + else + return self + end +end + +-- Gets the full name of the grid +function _M:getName() + local name = self.name or "spot" + if self.summoner and self.summoner.name then + return self.summoner.name:capitalize().."'s "..name + else + return name + end +end + function _M:tooltip(x, y) local tstr local dist = nil diff --git a/game/modules/tome/class/MapEffects.lua b/game/modules/tome/class/MapEffects.lua new file mode 100644 index 0000000000000000000000000000000000000000..72ca171bdb4cea39f3e6a160f474dfd031ef52f2 --- /dev/null +++ b/game/modules/tome/class/MapEffects.lua @@ -0,0 +1,47 @@ +-- TE4 - T-Engine 4 +-- Copyright (C) 2009, 2010, 2011, 2012, 2013 Nicolas Casalini +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- Nicolas Casalini "DarkGod" +-- darkgod@te4.org + +local Map = require "engine.Map" + +local function getEffectName(self) + local name = self.name or self.damtype and engine.DamageType.dam_def[self.damtype].name.." area effect" or "area effect" + if self.src then + return self.src.name.."'s "..name + else + return name + end +end + +local function resolveSource(self) + if self.src and self.src.resolveSource then + return self.src:resolveSource() + else + return self + end +end + +local addEffect = Map.addEffect +Map.addEffect = function (...) + local e = addEffect(...) + if e then + e.getName = getEffectName + e.resolveSource = resolveSource + end + return e +end diff --git a/game/modules/tome/class/NPC.lua b/game/modules/tome/class/NPC.lua index 24dc91125c617cd09a1e6a0be45e02b43ec5d549..5e4bb8c3805a26531127dfec69670d35aed1b746 100644 --- a/game/modules/tome/class/NPC.lua +++ b/game/modules/tome/class/NPC.lua @@ -537,7 +537,7 @@ function _M:aiCanPass(x, y) local check_dir = sides[side] local sx, sy = util.coordAddDir(target.x, target.y, check_dir) if target:canMove(sx, sy) and target:move(sx, sy) then - game.logSeen(target, "%s shoves %s forward.", self.name:capitalize(), target.name) + self:logCombat(target, "#Source# shoves #Target# forward.") target.shove_pressure = nil target._last_shove_pressure = nil break diff --git a/game/modules/tome/class/Object.lua b/game/modules/tome/class/Object.lua index 9daf94f15646efb0f0d3f4059abf0735e958f189..10319a52b63cb56e1fe309f2f5c187fac354ada5 100644 --- a/game/modules/tome/class/Object.lua +++ b/game/modules/tome/class/Object.lua @@ -27,6 +27,7 @@ require "engine.interface.ObjectIdentify" local Stats = require("engine.interface.ActorStats") local Talents = require("engine.interface.ActorTalents") local DamageType = require("engine.DamageType") +local Combat = require("mod.class.interface.Combat") module(..., package.seeall, class.inherit( engine.Object, @@ -37,6 +38,8 @@ module(..., package.seeall, class.inherit( _M.projectile_class = "mod.class.Projectile" +_M.logCombat = Combat.logCombat + function _M:init(t, no_default) t.encumber = t.encumber or 0 @@ -237,6 +240,16 @@ function _M:getDisplayColor() end end +function _M:resolveSource() + if self.summoner_gain_exp and self.summoner then + return self.summoner:resolveSource() + elseif self.summoner_gain_exp and self.src then + return self.src:resolveSource() + else + return self + end +end + --- Gets the full name of the object function _M:getName(t) t = t or {} diff --git a/game/modules/tome/class/Party.lua b/game/modules/tome/class/Party.lua index e8d8adb38476c9692cfed57c3b47ce6a96277666..1b18d8fd7633192a300d08bc209871d63a461ae8 100644 --- a/game/modules/tome/class/Party.lua +++ b/game/modules/tome/class/Party.lua @@ -354,7 +354,7 @@ function _M:giveOrder(actor, order) local x, y, act = game.player:getTarget({type="hit", range=10}) if act then actor:setTarget(act) - game.logPlayer(game.player, "%s targets %s.", actor.name:capitalize(), act.name) + game.player:logCombat(act, "%s targets #Target#.", actor.name:capitalize()) end end) local ok, err = coroutine.resume(co) diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua index 82a10eeec4360fb122e27fa4b25b75116ca5c321..53af85e5c2ad5d1d56d2521c54df542995dbabfb 100644 --- a/game/modules/tome/class/Player.lua +++ b/game/modules/tome/class/Player.lua @@ -1409,7 +1409,7 @@ function _M:useOrbPortal(portal) local spotted = spotHostiles(self) if #spotted > 0 then local dir = game.level.map:compassDirection(spotted[1].x - self.x, spotted[1].y - self.y) - game.logPlayer(self, "You can not use the Orb with foes in sight (%s to the %s%s)", spotted[1].actor.name, dir, game.level.map:isOnScreen(spotted[1].x, spotted[1].y) and "" or " - offscreen") + self:logCombat(spotted[1].actor, "You can not use the Orb with foes watching (#Target# to the %s%s)",dir, game.level.map:isOnScreen(spotted[1].x, spotted[1].y) and "" or " - offscreen") return end if portal.on_preuse then portal:on_preuse(self) end diff --git a/game/modules/tome/class/Projectile.lua b/game/modules/tome/class/Projectile.lua index 419dba34bfba1bc378136c559d0e6bacef6ee8ee..a52c91a259bda5d689e2062a9a40fc7b31d53fd0 100644 --- a/game/modules/tome/class/Projectile.lua +++ b/game/modules/tome/class/Projectile.lua @@ -19,9 +19,12 @@ require "engine.class" require "engine.Projectile" +local Combat = require "mod.class.interface.Combat" module(..., package.seeall, class.inherit(engine.Projectile)) +_M.logCombat = Combat.logCombat + function _M:init(t, no_default) engine.Projectile.init(self, t, no_default) end @@ -68,3 +71,21 @@ function _M:tooltip(x, y) end return tstr end + +function _M:resolveSource() + if self.src then + return self.src:resolveSource() + else + return self + end +end + +--gets the full name of the projectile +function _M:getName() + local name = self.name or "projectile" + if self.src and self.src.name then + return self.src.name:capitalize().."'s "..name + else + return name + end +end diff --git a/game/modules/tome/class/Trap.lua b/game/modules/tome/class/Trap.lua index 64c798da3046388b5461fe8e684b2eae7fe4aa8a..757f00a2c3381358c8669433bf5cac974ff2fd34 100644 --- a/game/modules/tome/class/Trap.lua +++ b/game/modules/tome/class/Trap.lua @@ -21,12 +21,14 @@ require "engine.class" require "engine.Trap" require "engine.interface.ActorProject" require "engine.interface.ObjectIdentify" +require "mod.class.interface.Combat" local Faction = require "engine.Faction" module(..., package.seeall, class.inherit( engine.Trap, engine.interface.ObjectIdentify, - engine.interface.ActorProject + engine.interface.ActorProject, + mod.class.interface.Combat )) _M.projectile_class = "mod.class.Projectile" @@ -47,14 +49,26 @@ function _M:combatSpellpower() return mod.class.interface.Combat:rescaleCombatSt function _M:combatMindpower() return mod.class.interface.Combat:rescaleCombatStats(self.wil) end function _M:combatAttack() return mod.class.interface.Combat:rescaleCombatStats(self.dex) end ---- Gets the full name of the object +function _M:resolveSource() + if self.summoner_gain_exp and self.summoner then + return self.summoner:resolveSource() + else + return self + end +end + +-- Gets the full name of the trap function _M:getName() - local name = self.name + local name = self.name or "trap" if not self:isIdentified() and self:getUnidentifiedName() then name = self:getUnidentifiedName() end - return name + if self.summoner and self.summoner.name then + return self.summoner.name:capitalize().."'s "..name + else + return name + end end ---- Returns a tooltip for the trap +-- Returns a tooltip for the trap function _M:tooltip() if self:knownBy(game.player) then local res = tstring{{"uid", self.uid}, self:getName()} @@ -121,18 +135,9 @@ end --- Trigger the trap function _M:trigger(x, y, who) engine.Trap.trigger(self, x, y, who) - if who.runStop then who:runStop("trap") end end -function _M:resolveSource() - if self.summoner_gain_exp and self.summoner then - return self.summoner:resolveSource() - else - return self - end -end - --- Identify the trap function _M:identify(id) self.identified = id diff --git a/game/modules/tome/class/WorldNPC.lua b/game/modules/tome/class/WorldNPC.lua index 5d532df1ea516792a22b71e71c03ff6293fefcbc..3a4c7df7668bb63df8e01fc40eb5b9f1e411f690 100644 --- a/game/modules/tome/class/WorldNPC.lua +++ b/game/modules/tome/class/WorldNPC.lua @@ -152,7 +152,7 @@ end function _M:takePowerHit(val, src) self.unit_power = (self.unit_power or 0) - val if self.unit_power <= 0 then - game.logSeen(self, "%s kills %s.", src.name:capitalize(), self.name) + self.logCombat(src, self, "#Source# kills #Target#.") self:die(src) end end @@ -174,11 +174,11 @@ function _M:encounterAttack(target, x, y) end if self.unit_power <= 0 then - game.logSeen(self, "%s kills %s.", target.name:capitalize(), self.name) + self:logCombat(target, "#Target# kills #Source#.") self:die(target) end if target.unit_power <= 0 then - game.logSeen(target, "%s kills %s.", self.name:capitalize(), target.name) + self:logCombat(target, "#Source# kills #Target#.") target:die(src) end end diff --git a/game/modules/tome/class/interface/Archery.lua b/game/modules/tome/class/interface/Archery.lua index 5b8927e3884fc3d199aec4ee670801bff4d5b24d..06dd698ea7c01dbcd0c2a8afa10fad9ef7c5ba79 100644 --- a/game/modules/tome/class/interface/Archery.lua +++ b/game/modules/tome/class/interface/Archery.lua @@ -229,7 +229,7 @@ local function archery_projectile(tx, ty, tg, self, tmp) end print("[ATTACK ARCHERY] after hook", dam) - if crit then game.logSeen(self, "#{bold}#%s performs a critical strike!#{normal}#", self.name:capitalize()) end + if crit then self:logCombat(target, "#{bold}##Source# performs a ranged critical strike against #Target#!#{normal}#") end -- Damage conversion? -- Reduces base damage but converts it into another damage type diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index 703263f18b392769cdab791540565b4d554332f3..81894307c086769a5945b0433b5343c63f11c570 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -112,7 +112,7 @@ function _M:attackTarget(target, damtype, mult, noenergy, force_unharmed) if self:isTalentActive(self.T_STEALTH) and target:canSee(self) then self:useTalent(self.T_STEALTH) self.changed = true - game.logPlayer(self, "%s notices you at the last moment!", target.name:capitalize()) + if self.player then self:logCombat(target, "#Target# notices you at the last moment!") end end if target:isTalentActive(target.T_INTUITIVE_SHOTS) and rng.percent(target:callTalent(target.T_INTUITIVE_SHOTS, "getChance")) then @@ -377,23 +377,23 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) local crit = false local evaded = false if repelled then - game.logSeen(target, "%s repels an attack from %s.", target.name:capitalize(), self.name) + self:logCombat(target, "#Target# repels an attack from #Source#.") elseif self:checkEvasion(target) then evaded = true - game.logSeen(target, "%s evades %s.", target.name:capitalize(), self.name) + self:logCombat(target, "#Target# evades #Source#.") elseif self:checkHit(atk, def) and (self:canSee(target) or self:attr("blind_fight") or rng.chance(3)) then local pres = util.bound(target:combatArmorHardiness() / 100, 0, 1) if target.knowTalent and target:hasEffect(target.EFF_DUAL_WEAPON_DEFENSE) then - local deflect = math.max(dam, target:callTalent(target.T_DUAL_WEAPON_DEFENSE, "doDeflect")) + local deflect = math.min(dam, target:callTalent(target.T_DUAL_WEAPON_DEFENSE, "doDeflect")) if deflect > 0 then - game.logSeen(target, "%s parries %d damage from %s's attack.", target.name:capitalize(), deflect, self.name:capitalize()) + self:logCombat(target, "#Target# parries %d damage from #Source#'s attack.", deflect) dam = math.max(dam - deflect,0) print("[ATTACK] after DUAL_WEAPON_DEFENSE", dam) end end if target.knowTalent and target:hasEffect(target.EFF_GESTURE_OF_GUARDING) then local deflected = math.min(dam, target:callTalent(target.T_GESTURE_OF_GUARDING, "doGuard")) - game.logSeen(target, "%s dismisses %d damage from %s's attack with a sweeping gesture.", target.name:capitalize(), deflected, self.name:capitalize()) + self:logCombat(target, "#Target# dismisses %d damage from #Source#'s attack with a sweeping gesture.", deflected) dam = dam - deflected print("[ATTACK] after GESTURE_OF_GUARDING", dam) end @@ -424,7 +424,7 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) print("[ATTACK] after inc by type", dam) end - if crit then game.logSeen(self, "#{bold}#%s performs a critical strike!#{normal}#", self.name:capitalize()) end + if crit then self:logCombat(target, "#{bold}##Source# performs a melee critical strike against #Target#!#{normal}#") end -- Phasing, percent of weapon damage bypasses shields -- It's done like this because onTakeHit has no knowledge of the weapon @@ -474,9 +474,7 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam) hitted = true else - local srcname = game.level.map.seens(self.x, self.y) and self.name:capitalize() or "Something" - game.logSeen(target, "%s misses %s.", srcname, target.name) - + self:logCombat(target, "#Source# misses #Target#.") target:fireTalentCheck("callbackOnMeleeMiss", self) end @@ -2142,7 +2140,7 @@ end function _M:grappleSizeCheck(target) size = target.size_category - self.size_category if size > 1 then - game.logSeen(target, "%s fails because %s is too big!", self.name:capitalize(), target.name:capitalize()) + self:logCombat(target, "#Source#'s grapple fails because #Target# is too big!") return true else return false @@ -2179,3 +2177,11 @@ function _M:startGrapple(target) end end +-- Display Combat log messages, highlighting the player and taking LOS and visibility into account +-- #source#|#Source# -> <displayString> self.name|self.name:capitalize() +-- #target#|#Target# -> target.name|target.name:capitalize() +function _M:logCombat(target, style, ...) + if not game.uiset or not game.uiset.logdisplay then return end + local visible, srcSeen, tgtSeen = game:logVisible(self, target) -- should a message be displayed? + if visible then game.uiset.logdisplay(game:logMessage(self, srcSeen, target, tgtSeen, style, ...)) end +end diff --git a/game/modules/tome/class/uiset/Classic.lua b/game/modules/tome/class/uiset/Classic.lua index 9760e4164a167495cad3ace1a881d4a2a8cd110f..5d0e0c37183f947202c589f78f3c17c523f317ac 100644 --- a/game/modules/tome/class/uiset/Classic.lua +++ b/game/modules/tome/class/uiset/Classic.lua @@ -90,7 +90,7 @@ function _M:activate() game.uiset.logdisplay(...) else game.uiset.logdisplay(style, ...) end if game.uiset.show_userchat then game.uiset.logdisplay.changed = old end end - game.logSeen = function(e, style, ...) if e and e.x and e.y and game.level.map.seens(e.x, e.y) then game.log(style, ...) end end +-- game.logSeen = function(e, style, ...) if e and e.player or (not e.dead and e.x and e.y and game.level and game.level.map.seens(e.x, e.y) and game.player:canSee(e)) then game.log(style, ...) end end game.logPlayer = function(e, style, ...) if e == game.player or e == game.party then game.log(style, ...) end end end diff --git a/game/modules/tome/class/uiset/Minimalist.lua b/game/modules/tome/class/uiset/Minimalist.lua index f663f8282c4e65772c0dc91e547b9b0bd36ab001..0a9bbff7d1d71635ffbe10578dc41bb54935bb6e 100644 --- a/game/modules/tome/class/uiset/Minimalist.lua +++ b/game/modules/tome/class/uiset/Minimalist.lua @@ -383,7 +383,7 @@ function _M:activate() game.uiset.logdisplay(...) else game.uiset.logdisplay(style, ...) end if game.uiset.show_userchat then game.uiset.logdisplay.changed = old end end - game.logSeen = function(e, style, ...) if e and e.x and e.y and game.level and game.level.map.seens(e.x, e.y) then game.log(style, ...) end end +-- game.logSeen = function(e, style, ...) if e and e.player or (not e.dead and e.x and e.y and game.level and game.level.map.seens(e.x, e.y) and game.player:canSee(e)) then game.log(style, ...) end end game.logPlayer = function(e, style, ...) if e == game.player or e == game.party then game.log(style, ...) end end self:boundPlaces() diff --git a/game/modules/tome/data/chats/alchemist-last-hope.lua b/game/modules/tome/data/chats/alchemist-last-hope.lua index bd662fdac891ce19e58837964060c9fd69bfa5ec..92122934f2fd8e982e8e710f0198b8d7c42fc058 100644 --- a/game/modules/tome/data/chats/alchemist-last-hope.lua +++ b/game/modules/tome/data/chats/alchemist-last-hope.lua @@ -553,7 +553,7 @@ It's strange what death can do to people, how it can take over their minds. Some game.nicer_tiles:updateAround(game.level, spot.x, spot.y) game.state:locationRevealAround(spot.x, spot.y) end) - game.log("He points the location of the graveyard on your map.") + game.log("He points out the location of the graveyard on your map.") player:grantQuest("grave-necromancer") end}, } diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index 0f9b85d5f9fdc0551e9b77b3668b84c4960ab3aa..759c7ea7bd701d22c080228bf1687a9c33ab8718 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -164,7 +164,7 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr) game:onTickEnd(function() src:removeEffect(src.EFF_FROZEN) end) eff.begone = game.turn else - game:delayedLogDamage(src, {name="Iceblock", x=src.x, y=src.y}, dam, ("%s%d %s#LAST#"):format(DamageType:get(type).text_color or "#aaaaaa#", math.ceil(dam), DamageType:get(type).name)) + game:delayedLogDamage(src, eff.ice, dam, ("%s%d %s#LAST#"):format(DamageType:get(type).text_color or "#aaaaaa#", math.ceil(dam), DamageType:get(type).name)) if eff.begone and eff.begone < game.turn and eff.hp < 0 then game.logSeen(src, "%s forces the iceblock to shatter.", src.name:capitalize()) src:removeEffect(src.EFF_FROZEN) @@ -174,11 +174,12 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr) end -- dark vision increases damage done in creeping dark - if src and game.level.map:checkAllEntities(x, y, "creepingDark") then + if src and src ~= target and game.level.map:checkAllEntities(x, y, "creepingDark") then local dark = game.level.map:checkAllEntities(x, y, "creepingDark") if dark.summoner == src and dark.damageIncrease > 0 and not dark.projecting then - game.logPlayer(src, "You strike in the darkness. (+%d damage)", (dam * dark.damageIncrease / 100)) + local source = src.__project_source or src dam = dam + (dam * dark.damageIncrease / 100) + game:delayedLogMessage(source, target, "dark_strike"..(source.uid or ""), "#Source# strikes #Target# in the darkness (%+d%%%%%%%% damage).", dark.damageIncrease) -- resolve %% 3 levels deep end end @@ -367,11 +368,14 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr) -- Log damage for later if not DamageType:get(type).hideMessage then - local srcname = src.x and src.y and game.level.map.seens(src.x, src.y) and src.name:capitalize() or "Something" - if src.turn_procs and src.turn_procs.is_crit then - game:delayedLogDamage(src, target, dam, ("#{bold}#%s%d %s#{normal}##LAST#"):format(DamageType:get(type).text_color or "#aaaaaa#", math.ceil(dam), DamageType:get(type).name), true) - else - game:delayedLogDamage(src, target, dam, ("%s%d %s#LAST#"):format(DamageType:get(type).text_color or "#aaaaaa#", math.ceil(dam), DamageType:get(type).name), false) + local visible, srcSeen, tgtSeen = game:logVisible(src, target) + if visible then -- don't log damage that the player doesn't know about + local source = src.__project_source or src + if src.turn_procs and src.turn_procs.is_crit then + game:delayedLogDamage(source, target, dam, ("#{bold}#%s%d %s#{normal}##LAST#"):format(DamageType:get(type).text_color or "#aaaaaa#", math.ceil(dam), DamageType:get(type).name), true) + else + game:delayedLogDamage(source, target, dam, ("%s%d %s#LAST#"):format(DamageType:get(type).text_color or "#aaaaaa#", math.ceil(dam), DamageType:get(type).name), false) + end end end @@ -412,7 +416,7 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr) -- damage affinity healing if not target.dead and affinity_heal > 0 then target:heal(affinity_heal) - game.logSeen(target, "%s is healed by the %s%s#LAST# damage!", target.name:capitalize(), DamageType:get(type).text_color or "#aaaaaa#", DamageType:get(type).name) + game:delayedLogMessage(target, nil, "Affinity"..type, "#Source# heals from "..(DamageType:get(type).text_color or "#aaaaaa#")..DamageType:get(type).name.."#LAST# damage!") end if dam > 0 and src.damage_log and src.damage_log.weapon then @@ -710,7 +714,7 @@ newDamageType{ -- Temporal + Stun newDamageType{ - name = "temporalstun", type = "TEMPORALSTUN", + name = "temporal stun", type = "TEMPORALSTUN", projector = function(src, x, y, type, dam) DamageType:get(DamageType.TEMPORAL).projector(src, x, y, DamageType.TEMPORAL, dam) local target = game.level.map(x, y, Map.ACTOR) @@ -741,7 +745,7 @@ newDamageType{ -- Break stealth newDamageType{ - name = "break stealth", type = "BREAK_STEALTH", + name = "illumination", type = "BREAK_STEALTH", projector = function(src, x, y, type, dam) -- Dont lit magically unlit grids local a = game.level.map(x, y, Map.ACTOR) @@ -753,7 +757,7 @@ newDamageType{ -- Silence newDamageType{ - name = "SILENCE", type = "SILENCE", + name = "silence", type = "SILENCE", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target then @@ -788,7 +792,7 @@ newDamageType{ -- Silence newDamageType{ - name = "% chance to silence target", type = "RANDOM_SILENCE", + name = "silence", type = "RANDOM_SILENCE", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target and rng.percent(dam) then @@ -883,7 +887,7 @@ newDamageType{ end, } newDamageType{ - name = "fireburn", type = "GOLEM_FIREBURN", + name = "fire burn", type = "GOLEM_FIREBURN", projector = function(src, x, y, type, dam) local realdam = 0 local target = game.level.map(x, y, Map.ACTOR) @@ -905,12 +909,12 @@ newDamageType{ -- Darkness + Stun newDamageType{ - name = "darkstun", type = "DARKSTUN", + name = "darkness", type = "DARKSTUN", projector = function(src, x, y, type, dam) DamageType:get(DamageType.DARKNESS).projector(src, x, y, DamageType.DARKNESS, dam) local target = game.level.map(x, y, Map.ACTOR) if target then - -- Set on fire! + -- try to stun if target:canBe("stun") then target:setEffect(target.EFF_STUNNED, 4, {apply_power=src:combatSpellpower()}) else @@ -922,7 +926,7 @@ newDamageType{ -- Darkness but not over minions newDamageType{ - name = "minions darkness", type = "MINION_DARKNESS", + name = "darkness", type = "MINION_DARKNESS", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target and (not target.necrotic_minion or target.summoner ~= src) then @@ -933,7 +937,7 @@ newDamageType{ -- Fore but not over minions newDamageType{ - name = "firey no friends", type = "FIRE_FRIENDS", + name = "fire", type = "FIRE_FRIENDS", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target and target.summoner ~= src then @@ -944,7 +948,7 @@ newDamageType{ -- Cold + Stun newDamageType{ - name = "coldstun", type = "COLDSTUN", + name = "cold", type = "COLDSTUN", projector = function(src, x, y, type, dam) DamageType:get(DamageType.COLD).projector(src, x, y, DamageType.COLD, dam) local target = game.level.map(x, y, Map.ACTOR) @@ -988,7 +992,7 @@ newDamageType{ -- Cold damage + freeze ground newDamageType{ - name = "coldnevermove", type = "COLDNEVERMOVE", + name = "cold ground", type = "COLDNEVERMOVE", projector = function(src, x, y, type, dam) if _G.type(dam) == "number" then dam = {dam=dam, dur=4} end DamageType:get(DamageType.COLD).projector(src, x, y, DamageType.COLD, dam.dam) @@ -1088,7 +1092,7 @@ newDamageType{ -- Lightning damage + daze chance newDamageType{ - name = "lightning daze", type = "LIGHTNING_DAZE", text_color = "#ROYAL_BLUE#", + name = "lightning", type = "LIGHTNING_DAZE", text_color = "#ROYAL_BLUE#", projector = function(src, x, y, type, dam) if _G.type(dam) == "number" then dam = {dam=dam, daze=25} end dam.daze = dam.daze or 25 @@ -1111,7 +1115,7 @@ newDamageType{ -- Cold/physical damage + repulsion; checks for spell power against physical resistance newDamageType{ - name = "wave", type = "WAVE", + name = "cold repulsion", type = "WAVE", projector = function(src, x, y, type, dam) local srcx, srcy = dam.x, dam.y local base = dam @@ -1137,7 +1141,7 @@ newDamageType{ -- Fireburn damage + repulsion; checks for spell power against physical resistance newDamageType{ - name = "fire knockback", type = "FIREKNOCKBACK", + name = "fire repulsion", type = "FIREKNOCKBACK", projector = function(src, x, y, type, dam, tmp) local target = game.level.map(x, y, Map.ACTOR) if _G.type(dam) ~= "table" then dam = {dam=dam, dist=3} end @@ -1158,7 +1162,7 @@ newDamageType{ -- Fireburn damage + repulsion; checks for mind power against physical resistance newDamageType{ - name = "fire knockback mind", type = "FIREKNOCKBACK_MIND", + name = "burning repulsion", type = "FIREKNOCKBACK_MIND", projector = function(src, x, y, type, dam, tmp) local target = game.level.map(x, y, Map.ACTOR) if _G.type(dam) ~= "table" then dam = {dam=dam, dist=3} end @@ -1179,7 +1183,7 @@ newDamageType{ -- Darkness damage + repulsion; checks for spell power against mental resistance newDamageType{ - name = "darkness knockback", type = "DARKKNOCKBACK", + name = "darkness repulsion", type = "DARKKNOCKBACK", projector = function(src, x, y, type, dam, tmp) local target = game.level.map(x, y, Map.ACTOR) if _G.type(dam) ~= "table" then dam = {dam=dam, dist=3} end @@ -1200,7 +1204,7 @@ newDamageType{ -- Physical damage + repulsion; checks for spell power against physical resistance newDamageType{ - name = "spell knockback", type = "SPELLKNOCKBACK", + name = "physical repulsion", type = "SPELLKNOCKBACK", projector = function(src, x, y, type, dam, tmp) local target = game.level.map(x, y, Map.ACTOR) local realdam = 0 @@ -1223,7 +1227,7 @@ newDamageType{ -- Physical damage + repulsion; checks for mind power against physical resistance newDamageType{ - name = "mind knockback", type = "MINDKNOCKBACK", + name = "physical repulsion", type = "MINDKNOCKBACK", projector = function(src, x, y, type, dam, tmp) local target = game.level.map(x, y, Map.ACTOR) tmp = tmp or {} @@ -1243,7 +1247,7 @@ newDamageType{ -- Physical damage + repulsion; checks for attack power against physical resistance newDamageType{ - name = "physknockback", type = "PHYSKNOCKBACK", + name = "physical repulsion", type = "PHYSKNOCKBACK", projector = function(src, x, y, type, dam, tmp) local target = game.level.map(x, y, Map.ACTOR) tmp = tmp or {} @@ -1264,7 +1268,7 @@ newDamageType{ -- Fear check + repulsion; checks for mind power against physical resistance newDamageType{ - name = "fear knockback", type = "FEARKNOCKBACK", + name = "fear repulsion", type = "FEARKNOCKBACK", projector = function(src, x, y, type, dam, tmp) local target = game.level.map(x, y, Map.ACTOR) tmp = tmp or {} @@ -1299,9 +1303,9 @@ newDamageType{ end, } --- Inferno: fire and maybe remove suff +-- Inferno: fire and maybe remove stuff newDamageType{ - name = "inferno", type = "INFERNO", + name = "cleansing fire", type = "INFERNO", projector = function(src, x, y, type, dam) local realdam = DamageType:get(DamageType.FIRE).projector(src, x, y, DamageType.FIRE, dam) local target = game.level.map(x, y, Map.ACTOR) @@ -1378,7 +1382,7 @@ newDamageType{ -- Physical damage + bleeding % of it newDamageType{ - name = "physical + bleeding", type = "PHYSICALBLEED", + name = "physical bleed", type = "PHYSICALBLEED", projector = function(src, x, y, type, dam) local realdam = DamageType:get(DamageType.PHYSICAL).projector(src, x, y, DamageType.PHYSICAL, dam) local target = game.level.map(x, y, Map.ACTOR) @@ -1390,7 +1394,7 @@ newDamageType{ -- Slime damage newDamageType{ - name = "slime", type = "SLIME", text_color = "#LIGHT_GREEN#", + name = "nature slow", type = "SLIME", text_color = "#LIGHT_GREEN#", projector = function(src, x, y, type, dam) if _G.type(dam) == "number" then dam = {dam=dam, power=0.15} end DamageType:get(DamageType.NATURE).projector(src, x, y, DamageType.NATURE, dam.dam) @@ -1487,7 +1491,7 @@ newDamageType{ -- Confusion newDamageType{ - name = "% chance to confuse", type = "RANDOM_CONFUSION", + name = "confusion", type = "RANDOM_CONFUSION", projector = function(src, x, y, type, dam) if _G.type(dam) == "number" then dam = {dam=dam} end local target = game.level.map(x, y, Map.ACTOR) @@ -1502,7 +1506,7 @@ newDamageType{ } newDamageType{ - name = "% chance to cause a gloom effect", type = "RANDOM_GLOOM", + name = "gloom", type = "RANDOM_GLOOM", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target and rng.percent(dam) then @@ -1530,7 +1534,7 @@ newDamageType{ -- gBlind newDamageType{ - name = "% chance to blind", type = "RANDOM_BLIND", + name = "blinding", type = "RANDOM_BLIND", projector = function(src, x, y, type, dam) if _G.type(dam) == "number" then dam = {dam=dam} end local target = game.level.map(x, y, Map.ACTOR) @@ -1546,7 +1550,7 @@ newDamageType{ -- Physical + Blind newDamageType{ - name = "sand", type = "SAND", + name = "blinding physical", type = "SAND", projector = function(src, x, y, type, dam) DamageType:get(DamageType.PHYSICAL).projector(src, x, y, DamageType.PHYSICAL, dam.dam) local target = game.level.map(x, y, Map.ACTOR) @@ -1562,7 +1566,7 @@ newDamageType{ -- Physical + Pinned newDamageType{ - name = "pinning", type = "PINNING", + name = "physical pinning", type = "PINNING", projector = function(src, x, y, type, dam) DamageType:get(DamageType.PHYSICAL).projector(src, x, y, DamageType.PHYSICAL, dam.dam) local target = game.level.map(x, y, Map.ACTOR) @@ -1578,7 +1582,7 @@ newDamageType{ -- Drain Exp newDamageType{ - name = "drain experience", type = "DRAINEXP", + name = "regressive blight", type = "DRAINEXP", projector = function(src, x, y, type, dam) if _G.type(dam) == "number" then dam = {dam=dam} end local realdam = DamageType:get(DamageType.BLIGHT).projector(src, x, y, DamageType.BLIGHT, dam.dam) @@ -1586,7 +1590,7 @@ newDamageType{ if target then if target:checkHit((dam.power_check or src.combatSpellpower)(src), (dam.resist_check or target.combatMentalResist)(target), 0, 95, 15) then target:gainExp(-dam.dam*2) - game.logSeen(target, "%s drains experience from %s!", src.name:capitalize(), target.name) + src:logCombat(target, "#Source# drains experience from #Target#!") else game.logSeen(target, "%s resists!", target.name:capitalize()) end @@ -1597,14 +1601,14 @@ newDamageType{ -- Drain Life newDamageType{ - name = "drain life", type = "DRAINLIFE", text_color = "#DARK_GREEN#", + name = "draining blight", type = "DRAINLIFE", text_color = "#DARK_GREEN#", projector = function(src, x, y, type, dam) if _G.type(dam) == "number" then dam = {dam=dam, healfactor=0.4} end local target = game.level.map(x, y, Map.ACTOR) -- Get the target first to make sure we heal even on kill local realdam = DamageType:get(DamageType.BLIGHT).projector(src, x, y, DamageType.BLIGHT, dam.dam) if target and realdam > 0 then src:heal(realdam * dam.healfactor) - game.logSeen(target, "%s drains life from %s!", src.name:capitalize(), target.name) + src:logCombat(target, "#Source# drains life from #Target#!") end return realdam end, @@ -1612,7 +1616,7 @@ newDamageType{ -- Drain Vim newDamageType{ - name = "drain vim", type = "DRAIN_VIM", + name = "enervating blight", type = "DRAIN_VIM", projector = function(src, x, y, type, dam) if _G.type(dam) == "number" then dam = {dam=dam, vim=0.2} end local target = game.level.map(x, y, Map.ACTOR) @@ -1641,10 +1645,10 @@ newDamageType{ -- Retch: heal undead; damage living newDamageType{ - name = "retch", type = "RETCH", + name = "purging blight", type = "RETCH", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) - if target and (target:attr("undead") or target.retch_heal) then + if target and (target:attr("undead") or target:attr(retch_heal)) then target:heal(dam * 1.5) if src.callTalent then @@ -1713,7 +1717,7 @@ newDamageType{ } newDamageType{ - name = "healing power", type = "HEALING_POWER", + name = "healing light", type = "HEALING_POWER", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target and not target:attr("undead") then @@ -1745,7 +1749,7 @@ newDamageType{ -- Corrupted blood, blight damage + potential diseases newDamageType{ - name = "corrupted blood", type = "CORRUPTED_BLOOD", text_color = "#DARK_GREEN#", + name = "infective blight", type = "CORRUPTED_BLOOD", text_color = "#DARK_GREEN#", projector = function(src, x, y, type, dam) if _G.type(dam) == "number" then dam = {dam=dam} end DamageType:get(DamageType.BLIGHT).projector(src, x, y, DamageType.BLIGHT, dam.dam) @@ -1759,7 +1763,7 @@ newDamageType{ -- blood boiled, blight damage + slow newDamageType{ - name = "blood boil", type = "BLOOD_BOIL", + name = "hindering_blight", type = "BLOOD_BOIL", projector = function(src, x, y, type, dam) DamageType:get(DamageType.BLIGHT).projector(src, x, y, DamageType.BLIGHT, dam) local target = game.level.map(x, y, Map.ACTOR) @@ -1796,7 +1800,7 @@ newDamageType{ -- Physical Damage/Cut Split newDamageType{ - name = "split bleed", type = "SPLIT_BLEED", + name = "physical bleed", type = "SPLIT_BLEED", projector = function(src, x, y, type, dam) DamageType:get(DamageType.PHYSICAL).projector(src, x, y, DamageType.PHYSICAL, dam / 2) DamageType:get(DamageType.PHYSICAL).projector(src, x, y, DamageType.PHYSICAL, dam / 12) @@ -1811,7 +1815,7 @@ newDamageType{ -- Temporal/Physical damage newDamageType{ - name = "matter", type = "MATTER", + name = "temporal shear", type = "MATTER", projector = function(src, x, y, type, dam) DamageType:get(DamageType.TEMPORAL).projector(src, x, y, DamageType.TEMPORAL, dam / 2) DamageType:get(DamageType.PHYSICAL).projector(src, x, y, DamageType.PHYSICAL, dam / 2) @@ -1820,7 +1824,7 @@ newDamageType{ -- Temporal/Darkness damage newDamageType{ - name = "void", type = "VOID", text_color = "#GREY#", + name = "temporal darkness", type = "VOID", text_color = "#GREY#", projector = function(src, x, y, type, dam) DamageType:get(DamageType.TEMPORAL).projector(src, x, y, DamageType.TEMPORAL, dam / 2) DamageType:get(DamageType.DARKNESS).projector(src, x, y, DamageType.DARKNESS, dam / 2) @@ -1864,7 +1868,7 @@ newDamageType{ } newDamageType{ - name = "repulsion", type = "REPULSION", + name = "physical repulsion", type = "REPULSION", projector = function(src, x, y, type, dam, tmp) local target = game.level.map(x, y, Map.ACTOR) tmp = tmp or {} @@ -1909,7 +1913,7 @@ newDamageType{ -- Mosses newDamageType{ - name = "grasping moss", type = "GRASPING_MOSS", + name = "pinning nature", type = "GRASPING_MOSS", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target and src:reactionToward(target) < 0 then @@ -1925,7 +1929,7 @@ newDamageType{ } newDamageType{ - name = "nourishing moss", type = "NOURISHING_MOSS", + name = "healing nature", type = "NOURISHING_MOSS", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target and src:reactionToward(target) < 0 then @@ -1936,7 +1940,7 @@ newDamageType{ } newDamageType{ - name = "slippery moss", type = "SLIPPERY_MOSS", + name = "impeding nature", type = "SLIPPERY_MOSS", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target and src:reactionToward(target) < 0 then @@ -1947,7 +1951,7 @@ newDamageType{ } newDamageType{ - name = "hallucinogenic moss", type = "HALLUCINOGENIC_MOSS", + name = "confounding nature", type = "HALLUCINOGENIC_MOSS", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target and src:reactionToward(target) < 0 then @@ -1979,7 +1983,7 @@ newDamageType{ } newDamageType{ - name = "shiftingshadows", type = "SHIFTINGSHADOWS", + name = "defensive darkness", type = "SHIFTINGSHADOWS", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target then @@ -1993,7 +1997,7 @@ newDamageType{ } newDamageType{ - name = "blazinglight", type = "BLAZINGLIGHT", + name = "blazing light", type = "BLAZINGLIGHT", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target then @@ -2008,7 +2012,7 @@ newDamageType{ } newDamageType{ - name = "warding", type = "WARDING", + name = "prismatic repulsion", type = "WARDING", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target then @@ -2030,7 +2034,7 @@ newDamageType{ } newDamageType{ - name = "mindslow", type = "MINDSLOW", + name = "mind slow", type = "MINDSLOW", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target then @@ -2042,7 +2046,7 @@ newDamageType{ -- Freezes target, checks for physresistance newDamageType{ - name = "mindfreeze", type = "MINDFREEZE", + name = "mind freeze", type = "MINDFREEZE", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target then @@ -2074,7 +2078,7 @@ newDamageType{ -- Temporal + Stat damage newDamageType{ - name = "reverse aging", type = "CLOCK", + name = "regressive temporal", type = "CLOCK", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target then @@ -2088,7 +2092,7 @@ newDamageType{ -- Temporal Over Time newDamageType{ - name = "wasting", type = "WASTING", text_color = "#LIGHT_STEEL_BLUE#", + name = "wasting temporal", type = "WASTING", text_color = "#LIGHT_STEEL_BLUE#", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) local dur = 3 @@ -2097,7 +2101,7 @@ newDamageType{ local init_dam = dam * perc / 100 if init_dam > 0 then DamageType:get(DamageType.TEMPORAL).projector(src, x, y, DamageType.TEMPORAL, init_dam) end if target then - -- Set on fire! + -- Set wasting effect dam = dam - init_dam target:setEffect(target.EFF_WASTING, dur, {src=src, power=dam / dur, no_ct_effect=true}) end @@ -2120,7 +2124,7 @@ newDamageType{ } newDamageType{ - name = "rethread", type = "RETHREAD", + name = "debilitating temporal", type = "RETHREAD", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) local chance = rng.range(1, 4) @@ -2170,7 +2174,7 @@ newDamageType{ } newDamageType{ - name = "devour life", type = "DEVOUR_LIFE", + name = "draining physical", type = "DEVOUR_LIFE", projector = function(src, x, y, type, dam) if _G.type(dam) == "number" then dam = {dam=dam} end local target = game.level.map(x, y, Map.ACTOR) -- Get the target first to make sure we heal even on kill @@ -2183,14 +2187,14 @@ newDamageType{ src.healing_factor = 1 src:heal(heal) src.healing_factor = temp - game.logSeen(target, "%s consumes %d life from %s!", src.name:capitalize(), heal, target.name) + src:logCombat(target, "#Source# consumes %d life from #Target#!", heal) end end, hideMessage=true, } newDamageType{ - name = "chronoslow", type = "CHRONOSLOW", + name = "temporal slow", type = "CHRONOSLOW", projector = function(src, x, y, type, dam) DamageType:get(DamageType.TEMPORAL).projector(src, x, y, DamageType.TEMPORAL, dam.dam) local target = game.level.map(x, y, Map.ACTOR) @@ -2233,7 +2237,7 @@ newDamageType{ } newDamageType{ - name = "manaworm", type = "MANAWORM", + name = "manaworm arcane", type = "MANAWORM", projector = function(src, x, y, type, dam) local realdam = DamageType:get(DamageType.ARCANE).projector(src, x, y, DamageType.ARCANE, dam) local target = game.level.map(x, y, Map.ACTOR) @@ -2252,7 +2256,7 @@ newDamageType{ } newDamageType{ - name = "void blast", type = "VOID_BLAST", + name = "arcane blast", type = "VOID_BLAST", projector = function(src, x, y, type, dam) local realdam = DamageType:get(DamageType.ARCANE).projector(src, x, y, DamageType.ARCANE, dam) local target = game.level.map(x, y, Map.ACTOR) @@ -2285,7 +2289,7 @@ newDamageType{ -- Darkness damage + speed reduction + minion damage inc newDamageType{ - name = "rigor mortis", type = "RIGOR_MORTIS", + name = "decaying darkness", type = "RIGOR_MORTIS", projector = function(src, x, y, type, dam, tmp) local target = game.level.map(x, y, Map.ACTOR) if target then @@ -2297,7 +2301,7 @@ newDamageType{ } newDamageType{ - name = "abyssal shroud", type = "ABYSSAL_SHROUD", + name = "abyssal darkness", type = "ABYSSAL_SHROUD", projector = function(src, x, y, type, dam) --make it dark game.level.map.remembers(x, y, false) @@ -2320,7 +2324,7 @@ newDamageType{ } newDamageType{ - name = "% chance to summon an orc spirit", type = "GARKUL_INVOKE", + name = "Garkul spirit", type = "GARKUL_INVOKE", projector = function(src, x, y, type, dam) if not rng.percent(dam) then return end local target = game.level.map(x, y, engine.Map.ACTOR) @@ -2413,7 +2417,7 @@ newDamageType{ -- Generic apply temporary effect newDamageType{ - name = "temp effect", type = "TEMP_EFFECT", + name = "special effect", type = "TEMP_EFFECT", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target then @@ -2428,7 +2432,7 @@ newDamageType{ } newDamageType{ - name = "manaburn", type = "MANABURN", text_color = "#PURPLE#", + name = "manaburn arcane", type = "MANABURN", text_color = "#PURPLE#", projector = function(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target then @@ -2472,7 +2476,7 @@ newDamageType{ -- Distortion; Includes knockback, penetrate, stun, and explosion paramters newDamageType{ - name = "distortion", type = "DISTORTION", + name = "distorting physical", type = "DISTORTION", projector = function(src, x, y, type, dam, tmp) local target = game.level.map(x, y, Map.ACTOR) if not target then return end @@ -2580,7 +2584,7 @@ newDamageType{ newDamageType{ - name = "mucus", type = "MUCUS", + name = "natural mucus", type = "MUCUS", projector = function(src, x, y, type, dam, tmp) local target = game.level.map(x, y, Map.ACTOR) if target and not target.turn_procs.mucus then @@ -2601,7 +2605,7 @@ newDamageType{ } newDamageType{ - name = "acid disarm", type = "ACID_DISARM", text_color = "#GREEN#", + name = "disarming acid", type = "ACID_DISARM", text_color = "#GREEN#", projector = function(src, x, y, type, dam) if _G.type(dam) == "number" then dam = {chance=25, dam=dam} end local realdam = DamageType:get(DamageType.ACID).projector(src, x, y, DamageType.ACID, dam.dam) diff --git a/game/modules/tome/data/general/grids/lava.lua b/game/modules/tome/data/general/grids/lava.lua index e636daa9f48dc0f084d997aa83a8b28ffafb5fe0..c5d24bd8270fd4991c4aa8f05d01f7b7dfd7c81a 100644 --- a/game/modules/tome/data/general/grids/lava.lua +++ b/game/modules/tome/data/general/grids/lava.lua @@ -32,7 +32,8 @@ newEntity{ on_stand = function(self, x, y, who) local DT = engine.DamageType local dam = DT:get(DT.FIRE).projector(self, x, y, DT.FIRE, rng.range(self.mindam, self.maxdam)) - if dam > 0 then game.logPlayer(who, "The lava burns you!") end + self.x, self.y = x, y + if dam > 0 and who.player then self:logCombat(who, "#Source# burns #Target#!") end end, nice_tiler = { method="replace", base={"LAVA_FLOOR", 100, 1, 16}}, nice_editer = lava_editer, diff --git a/game/modules/tome/data/general/grids/water.lua b/game/modules/tome/data/general/grids/water.lua index 986ceebabce2490ced46b86a177ea1a68b4b228f..1884bebabc94f6b2df82bd1b036d3559d08aeda8 100644 --- a/game/modules/tome/data/general/grids/water.lua +++ b/game/modules/tome/data/general/grids/water.lua @@ -168,7 +168,8 @@ newEntity{ local DT = engine.DamageType local dam = DT:get(DT.POISON).projector(self, x, y, DT.POISON, rng.range(self.mindam, self.maxdam)) - if dam > 0 then game.logPlayer(who, "The water poisons you!") end + self.x, self.y = x, y + if dam > 0 and who.player then self:logCombat(who, "#Source# poisons #Target#!") end end, combatAttack = function(self) return rng.range(self.mindam, self.maxdam) end, nice_tiler = { method="replace", base={"POISON_DEEP_WATER", 100, 1, 6}}, diff --git a/game/modules/tome/data/general/npcs/horror.lua b/game/modules/tome/data/general/npcs/horror.lua index 70c5fe3f621d5730fca58c8924c17c0dc9bfd44e..33c8bb659b119f90348af7e1757f555c05c2e657 100644 --- a/game/modules/tome/data/general/npcs/horror.lua +++ b/game/modules/tome/data/general/npcs/horror.lua @@ -271,7 +271,7 @@ newEntity{ base = "BASE_NPC_HORROR", define_as = "BASE_NPC_ELDRICTH_EYE", on_die = function(self, src) if not self.summoner or not self.summoner.is_headless_horror then return end - game.logSeen(self, "#AQUAMARINE#As %s falls %s seems to weaken!", self.name, self.summoner.name) + self:logCombat(self.summoner, "#AQUAMARINE#As #Source# falls #Target# seems to weaken!") local damtype = next(self.resists) self.summoner.resists.all = (self.summoner.resists.all or 0) - 30 self.summoner.resists[damtype] = nil @@ -891,7 +891,7 @@ newEntity{ base="BASE_NPC_HORROR", define_as = "GRGGLCK_TENTACLE", on_die = function(self, who) if self.summoner and not self.summoner.dead and who then - game.logSeen(self, "#AQUAMARINE#As %s falls you notice that %s seems to shudder in pain!", self.name, self.summoner.name) + self:logCombat(self.summoner, "#AQUAMARINE#As #Source# falls you notice that #Target# seems to shudder in pain!") if self.summoner.is_grgglck then self.summoner:takeHit(self.max_life, who) else diff --git a/game/modules/tome/data/general/objects/boss-artifacts.lua b/game/modules/tome/data/general/objects/boss-artifacts.lua index b4a9416aec31fe67c2fe1f4872a7546bca1ff3a3..7fb255bcc38b211384825ab25aafd37f789fa78f 100644 --- a/game/modules/tome/data/general/objects/boss-artifacts.lua +++ b/game/modules/tome/data/general/objects/boss-artifacts.lua @@ -1482,7 +1482,7 @@ newEntity{ base = "BASE_LONGBOW", who:project(tg, a.x, a.y, engine.DamageType.LIGHTNING_DAZE, {daze=40, dam = rng.avg(1,3) * (40+ who:getMag() * 1.5)} ) game.level.map:particleEmitter(who.x, who.y, math.max(math.abs(a.x-who.x), math.abs(a.y-who.y)), "lightning", {tx=a.x-who.x, ty=a.y-who.y}) game:playSoundNear(self, "talents/lightning") - game.logSeen(who, "#GOLD#A bolt of lightning fires from %s's bow, striking %s!", who.name:capitalize(), a.name:capitalize()) + who:logCombat(a, "#GOLD#A bolt of lightning fires from #Source#'s bow, striking #Target#!") end end, on_wear = function(self, who) diff --git a/game/modules/tome/data/general/objects/world-artifacts.lua b/game/modules/tome/data/general/objects/world-artifacts.lua index 9a41b83fae42bee5c770e85cea49d751dc359244..0ec63f268fd0231edd1fc9663e7b9bfadc8bba98 100644 --- a/game/modules/tome/data/general/objects/world-artifacts.lua +++ b/game/modules/tome/data/general/objects/world-artifacts.lua @@ -1258,10 +1258,10 @@ newEntity{ base = "BASE_HELM", define_as = "HELM_KROLTAR", self:specialSetAdd({"wielder","combat_spellresist"}, 15) self:specialSetAdd({"wielder","combat_mentalresist"}, 15) self:specialSetAdd({"wielder","combat_physresist"}, 15) - game.logPlayer(who, "#GOLD#As the Kroltar helm approches the scale mail, they begin to emit fumes and fires.") + game.logPlayer(who, "#GOLD#As the helm of Kroltar approaches the your scale armour, they begin to fume and emit fire.") end, on_set_broken = function(self, who) - game.logPlayer(who, "#GOLD#The funes and fires disappear.") + game.logPlayer(who, "#GOLD#The fumes and fire fade away.") end, } @@ -3455,7 +3455,7 @@ newEntity{ base = "BASE_WHIP", who:project(blast, x, y, engine.DamageType.LIGHTNING, rng.avg(dam / 3, dam, 3)) game.level.map:particleEmitter(x, y, radius, "ball_lightning", {radius=blast.radius}) game:playSoundNear(self, "talents/lightning") - game.logSeen(who, "%s strikes %s, sending out an arc of lightning!", who.name:capitalize(), target.name) + who:logCombat(target, "#Source# strikes #Target#, sending out an arc of lightning!") return {id=true, used=true} end }, @@ -3830,7 +3830,7 @@ newEntity{ base = "BASE_LONGSWORD", if not rng.percent(20) then return end if not who:checkHit(who:combatMindpower(), target:combatMentalResist()) then return end target:setEffect(target.EFF_WEAKENED_MIND, 2, {power=5}) - game.logSeen(who, "Anima's eye glares at %s, piercing their mind!", target.name:capitalize()) + who:logCombat(target, "Anmalice focuses its mind-piercing eye on #Target#!") end) end, on_takeoff = function(self, who) @@ -3950,9 +3950,9 @@ newEntity{ base = "BASE_WHIP", define_as = "HYDRA_BITE", o.running = 1 if tries >= 100 or #tgts==1 then twohits=nil end if twohits then - game.logSeen(who, "%s's three headed flail lashes at %s and %s!",who.name:capitalize(), target1.name:capitalize(),target2.name:capitalize()) + who:logCombat(target1, "#Source#'s three headed flail lashes at #Target#%s!",who:canSee(target2) and (" and %s"):format(target2.name:capitalize()) or "") else - game.logSeen(who, "%s's three headed flail lashes at %s!",who.name:capitalize(), target1.name:capitalize()) + who:logCombat(target1, "#Source#'s three headed flail lashes at #Target#!") end who:attackTarget(target1, engine.DamageType.PHYSICAL, 0.4, true) if twohits then who:attackTarget(target2, engine.DamageType.PHYSICAL, 0.4, true) end @@ -4976,7 +4976,7 @@ newEntity{ base = "BASE_SHIELD", --Thanks SageAcrin! who:project(burst, target.x, target.y, engine.DamageType.ICE, 30) game.level.map:particleEmitter(who.x, who.y, burst.radius, "breath_cold", {radius=burst.radius, tx=target.x-who.x, ty=target.y-who.y}) - game.logSeen(who, "A burst of chilling water launches from %s's shield to %s!", who.name:capitalize(), target.name:capitalize()) + who:logCombat(target, "A wave of icy water bursts out from #Source#'s shield towards #Target#!") end end, } diff --git a/game/modules/tome/data/maps/vaults/greater-crypt.lua b/game/modules/tome/data/maps/vaults/greater-crypt.lua index 65403204335e77e9b6cd8932a467bd438172ce67..4e70e489192e1bf5d9a60cf66ea39a8f246c00df 100644 --- a/game/modules/tome/data/maps/vaults/greater-crypt.lua +++ b/game/modules/tome/data/maps/vaults/greater-crypt.lua @@ -80,7 +80,7 @@ defineTile('1', mod.class.Grid.new{ end actor:move(fx, fy, true) - game.logPlayer(actor, "Something in the floor clicks ominously, and suddenly the world spins around you!") + game.logPlayer(actor, "Something in the floor clicks ominously%s", actor.lite > 0 and not actor:attr("blind") and ", and suddenly the world spins around you!" or ".") local g = game.zone:makeEntityByName(game.level, "terrain", "FLOOR") if not g then return end game.zone:addEntity(game.level, g, "terrain", x, y) @@ -111,8 +111,7 @@ defineTile('2', mod.class.Grid.new{ game.zone:addEntity(game.level, f, "terrain", x, y) game.nicer_tiles:updateAround(game.level, x, y) - - game.logPlayer(actor, "Something in the floor clicks ominously, and the crypt rearranges itself around you!") + game.logPlayer(actor, "Something in the floor clicks ominously%s", actor.lite > 0 and not actor:attr("blind") and ", and the crypt rearranges itself around you!" or ".") end, } @@ -164,8 +163,7 @@ defineTile('4', mod.class.Grid.new{ game.zone:addEntity(game.level, f, "terrain", x, y) game.nicer_tiles:updateAround(game.level, x, y) - game.logPlayer(actor, "Something underfoot clicks ominously, and the crypt rearranges itself around you!") - + game.logPlayer(actor, "Something in the floor clicks ominously%s", actor.lite > 0 and not actor:attr("blind") and ", and the crypt rearranges itself around you!" or ".") end, } ) diff --git a/game/modules/tome/data/maps/vaults/paladin-vs-vampire.lua b/game/modules/tome/data/maps/vaults/paladin-vs-vampire.lua index 83f0f47c15a93de96c70722f791acb84019117dd..25c1455a7de71c6aa3389865b0fc50b5346f262b 100644 --- a/game/modules/tome/data/maps/vaults/paladin-vs-vampire.lua +++ b/game/modules/tome/data/maps/vaults/paladin-vs-vampire.lua @@ -33,10 +33,12 @@ defineTile('~', mod.class.Grid.new{ on_stand = function(self, x, y, who) local DT = engine.DamageType local dam = DT:get(DT.RETCH).projector(self, x, y, DT.RETCH, rng.range(self.mindam, self.maxdam)) - if not who:attr("undead") then game.logPlayer(who, "Dark energies course upwards through the lava.") end + self.x, self.y = x, y + if who.player and not who:attr("undead") then self:logCombat(who, "#Source# emits dark energies at your feet.") end if who.dead and not who:attr("undead") then --add undead local m = game.zone:makeEntityByName(game.level, "actor", "RISEN_CORPSE") + game.logSeen(who, "The corrupted lava reanimates %s's corpse!", who.name:capitalize()) game.zone:addEntity(game.level, m, "actor", x, y) end end, diff --git a/game/modules/tome/data/talents/celestial/twilight.lua b/game/modules/tome/data/talents/celestial/twilight.lua index cc14c56b2e0d92c732815342777646cecc1012b3..1612ad1b4cfd9efd5db8efc755616d6700c41b2b 100644 --- a/game/modules/tome/data/talents/celestial/twilight.lua +++ b/game/modules/tome/data/talents/celestial/twilight.lua @@ -222,7 +222,7 @@ newTalent{ target:reactionToward(self) >= 0 or -- No friends target.size_category > allowed then - game.logPlayer(self, "%s resists!", target.name:capitalize()) + game.logSeen(target, "%s resists!", target.name:capitalize()) return true end diff --git a/game/modules/tome/data/talents/chronomancy/timeline-threading.lua b/game/modules/tome/data/talents/chronomancy/timeline-threading.lua index 20b6d12d378751c0d9dd6139ede8fa59164f3bb2..b45ed1c68538b08908aec735ca283d88b80b806d 100644 --- a/game/modules/tome/data/talents/chronomancy/timeline-threading.lua +++ b/game/modules/tome/data/talents/chronomancy/timeline-threading.lua @@ -114,7 +114,7 @@ newTalent{ target:reactionToward(self) >= 0 or -- No friends target.size_category > allowed then - game.logPlayer(self, "%s resists!", target.name:capitalize()) + game.logSeen(target, "%s resists!", target.name:capitalize()) return true end diff --git a/game/modules/tome/data/talents/cunning/dirty.lua b/game/modules/tome/data/talents/cunning/dirty.lua index a14d9b0e07e706a6c1e15b1a3a908136c12f6678..45bb0f8b9dd9f90cfdef8cad619fba4c3572063e 100644 --- a/game/modules/tome/data/talents/cunning/dirty.lua +++ b/game/modules/tome/data/talents/cunning/dirty.lua @@ -43,7 +43,7 @@ newTalent{ target:setEffect(target.EFF_STUNNED, t.getDuration(self, t), {apply_power=self:combatAttack()}) end if not target:hasEffect(target.EFF_STUNNED) then - game.logSeen(target, "%s resists the stun and %s quickly gets back on feet!", target.name:capitalize(), self.name:capitalize()) + self:logCombat(target, "#Target# resists the stun and #Source# quickly regains its footing!") self.energy.value = self.energy.value + game.energy_to_act * self:combatSpeed() end end @@ -101,7 +101,7 @@ newTalent{ if hitted and not self.dead and tx == target.x and ty == target.y then if not self:canMove(tx,ty,true) or not target:canMove(sx,sy,true) then - game.logSeen(self, "%s and %s cannot switch places due to terrain.",self.name:capitalize(),target.name:capitalize()) + self:logCombat(target, "Terrain prevents #Source# from switching places with #Target#.") return false end self:setEffect(self.EFF_EVASION, t.getDuration(self, t), {chance=50}) diff --git a/game/modules/tome/data/talents/cunning/traps.lua b/game/modules/tome/data/talents/cunning/traps.lua index 881f45ff9f16f0ff1ca90341f8bf1a6814b1e99a..1bbb4a794c8e85a8f9ab213236fbc0bc65fab707 100644 --- a/game/modules/tome/data/talents/cunning/traps.lua +++ b/game/modules/tome/data/talents/cunning/traps.lua @@ -673,7 +673,7 @@ newTalent{ if target:canBe("knockback") then target:pull(self.x, self.y, 1) if target.x ~= ox or target.y ~= oy then - game.logSeen(target, "%s is pulled toward %s's gravity trap!", target.name:capitalize(), self.summoner.name:capitalize()) + self.summoner:logCombat(target, "#Target# is pulled towards #Source#'s gravity trap!") end end end diff --git a/game/modules/tome/data/talents/cursed/darkness.lua b/game/modules/tome/data/talents/cursed/darkness.lua index 514873f5ca5d169c5d455011ad65e6b33294ede3..39dbe90df8f4b6196e110f2dc6350cf5bfb9ba40 100644 --- a/game/modules/tome/data/talents/cursed/darkness.lua +++ b/game/modules/tome/data/talents/cursed/darkness.lua @@ -202,7 +202,7 @@ newTalent{ end, createDark = function(summoner, x, y, damage, duration, creep, creepChance, initialCreep) local e = Object.new{ - name = "creeping dark", + name = summoner.name:capitalize() .. "'s creeping dark", block_sight=true, canAct = false, canCreep = true, @@ -224,7 +224,9 @@ newTalent{ local actor = game.level.map(self.x, self.y, Map.ACTOR) if actor and actor ~= self.summoner and (not actor.summoner or actor.summoner ~= self.summoner) then self.projecting = true -- simplest way to indicate that this damage should not be amplified by the in creeping dark bonus + self.summoner.__project_source = self -- intermediate projector source self.summoner:project({type="hit", range=10, talent=self.summoner:getTalentFromId(self.summoner.T_CREEPING_DARKNESS)}, actor.x, actor.y, engine.DamageType.DARKNESS, self.damage) + self.summoner.__project_source = nil self.projecting = false end diff --git a/game/modules/tome/data/talents/cursed/force-of-will.lua b/game/modules/tome/data/talents/cursed/force-of-will.lua index b8d31a3f6e91a4ac24791c463c59937c2ee2ce1b..0dc4fd7324be5865386f66004cdc98d731febb9e 100644 --- a/game/modules/tome/data/talents/cursed/force-of-will.lua +++ b/game/modules/tome/data/talents/cursed/force-of-will.lua @@ -46,7 +46,6 @@ local function forceHit(self, t, target, sourceX, sourceY, damage, knockback, kn local knockbackCount = 0 local blocked = false while knockback > 0 do - blocked = true local x, y, is_corner_blocked = lineFunction:step(true) if not game.level.map:isBound(x, y) or is_corner_blocked or game.level.map:checkAllEntities(x, y, "block_move", target) then @@ -54,14 +53,14 @@ local function forceHit(self, t, target, sourceX, sourceY, damage, knockback, kn local nextTarget = game.level.map(x, y, Map.ACTOR) if nextTarget then if knockbackCount > 0 then - game.logPlayer(self, "%s was blasted %d spaces into %s!", target.name:capitalize(), knockbackCount, nextTarget.name) + target:logCombat(nextTarget, "#Source# was blasted %d spaces into #Target#!", knockbackCount) else - game.logPlayer(self, "%s was blasted into %s!", target.name:capitalize(), nextTarget.name) + target:logCombat(nextTarget, "#Source# was blasted into #Target#!") end elseif knockbackCount > 0 then - game.logPlayer(self, "%s was smashed back %d spaces!", target.name:capitalize(), knockbackCount) + game.logSeen(target, "%s was smashed back %d spaces!", target.name:capitalize(), knockbackCount) else - game.logPlayer(self, "%s was smashed!", target.name:capitalize()) + game.logSeen(target, "%s was smashed!", target.name:capitalize()) end -- take partial damage @@ -76,6 +75,7 @@ local function forceHit(self, t, target, sourceX, sourceY, damage, knockback, kn end knockback = 0 + blocked = true else -- allow move finalX, finalY = x, y @@ -85,7 +85,7 @@ local function forceHit(self, t, target, sourceX, sourceY, damage, knockback, kn end if not blocked and knockbackCount > 0 then - game.logPlayer(self, "%s was blasted back %d spaces!", target.name:capitalize()) + game.logSeen(target, "%s was blasted back %d spaces!", target.name:capitalize(), knockbackCount) end if not target.dead and (finalX ~= target.x or finalY ~= target.y) then @@ -310,7 +310,7 @@ newTalent{ end, getSecondHitChance = function(self, t) return self:combatTalentScale(self:getTalentLevel(t)-4, 15, 35) end, action = function(self, t) - game.logSeen(self, "An unseen force begin to swirl around %s!", self.name) + game.logSeen(self, "An unseen force begins to swirl around %s!", self.name) local duration = t.getDuration(self, t) local particles = self:addParticles(Particles.new("force_area", 1, { radius = self:getTalentRange(t) })) diff --git a/game/modules/tome/data/talents/cursed/gestures.lua b/game/modules/tome/data/talents/cursed/gestures.lua index d4665fe96278b357056358c20f1600bb2aca40b3..2382d8ba579ad63b0f49768714f6e036337110a8 100644 --- a/game/modules/tome/data/talents/cursed/gestures.lua +++ b/game/modules/tome/data/talents/cursed/gestures.lua @@ -231,7 +231,7 @@ newTalent{ -- Counterattack handled in _M:attackTargetWith function in mod.class.interface.Combat.lua (requires EFF_GESTURE_OF_GUARDING) on_hit = function(self, t, who) if rng.percent(t.getCounterAttackChance(self, t)) and self:isTalentActive(self.T_GESTURE_OF_PAIN) and canUseGestures(self) then - game.logSeen(self, "#F53CBE#%s lashes back at %s!", self.name:capitalize(), who.name) + self:logCombat(who, "#F53CBE##Source# lashes back at #Target#!") local tGestureOfPain = self:getTalentFromId(self.T_GESTURE_OF_PAIN) tGestureOfPain.attack(self, tGestureOfPain, who) end diff --git a/game/modules/tome/data/talents/cursed/predator.lua b/game/modules/tome/data/talents/cursed/predator.lua index 71000dafd0164498ad4275cba63a386d7ec19b97..04db0f8a485f5b7199d02de06413edefb9c68eb9 100644 --- a/game/modules/tome/data/talents/cursed/predator.lua +++ b/game/modules/tome/data/talents/cursed/predator.lua @@ -57,7 +57,7 @@ newTalent{ if eff and eff.type == target.type and eff.subtype == target.subtype then return false end - if eff then self:removeEffect(self.EFF_PREDATOR) end + if eff then self:removeEffect(self.EFF_PREDATOR, true, true) end self:setEffect(self.EFF_PREDATOR, 1, { type=target.type, subtype=target.subtype, killExperience = 0, subtypeKills = 0, typeKills = 0 }) return true diff --git a/game/modules/tome/data/talents/cursed/shadows.lua b/game/modules/tome/data/talents/cursed/shadows.lua index a41883be27767e9bfea88428e78c427e67a47889..af46b974182a523bf41ef8f1795ecdac37ca49a2 100644 --- a/game/modules/tome/data/talents/cursed/shadows.lua +++ b/game/modules/tome/data/talents/cursed/shadows.lua @@ -596,7 +596,7 @@ newTalent{ end if shadowCount > 0 then - game.logPlayer(self, "#PINK#The shadows converge on %s!", target.name) + self:logCombat(target, "#PINK#The shadows converge on #Target#!") return true else game.logPlayer(self, "Their are no shadows to heed the call!") @@ -617,7 +617,7 @@ newTalent{ end if shadowCount > 0 then - game.logPlayer(self, "#PINK#The shadows form around %s!", target.name) + self:logCombat(target, "#PINK#The shadows form around #Target#!") return true else game.logPlayer(self, "Their are no shadows to heed the call!") diff --git a/game/modules/tome/data/talents/cursed/slaughter.lua b/game/modules/tome/data/talents/cursed/slaughter.lua index 3b09aa9f4fcda5db450a0d85c45fdbce5a2125dd..d065316c845f485ce79d014563e8268b905188e3 100644 --- a/game/modules/tome/data/talents/cursed/slaughter.lua +++ b/game/modules/tome/data/talents/cursed/slaughter.lua @@ -186,7 +186,7 @@ newTalent{ and game.level.map:isBound(x, y) and not game.level.map:checkAllEntities(x, y, "block_move", self) then blockingTarget:move(x, y, true) - game.logSeen(self, "%s knocks back %s!", self.name:capitalize(), blockingTarget.name) + self:logCombat(blockingTarget, "#Source# knocks back #Target#!") blocked = false break end @@ -195,7 +195,7 @@ newTalent{ end if blocked then - game.logSeen(self, "%s blocks %s!", blockingTarget.name:capitalize(), self.name) + self:logCombat(blockingTarget, "#Target# blocks #Source#!") end end @@ -341,7 +341,7 @@ newTalent{ local secondTarget = game.level.map(x, y, Map.ACTOR) if secondTarget and secondTarget ~= target and self:reactionToward(secondTarget) < 0 then local damageMultiplier = t.getDamageMultiplier(self, t) - game.logSeen(self, "%s cleaves through %s!", self.name:capitalize(), secondTarget.name) + self:logCombat(secondTarget, "#Source# cleaves through #Target#!") self:attackTarget(secondTarget, nil, damageMultiplier, true) inCleave = false return diff --git a/game/modules/tome/data/talents/gifts/sand-drake.lua b/game/modules/tome/data/talents/gifts/sand-drake.lua index e964fd32f9922d547b634623e993178dcd577a55..3367dbf0b4fde5c342045d72bf33d80fed6c1f90 100644 --- a/game/modules/tome/data/talents/gifts/sand-drake.lua +++ b/game/modules/tome/data/talents/gifts/sand-drake.lua @@ -39,9 +39,7 @@ newTalent{ local x, y, target = self:getTarget(tg) if not x or not y or not target then return nil end if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end - - game.logSeen(self, "%s tries to swallow %s!", self.name:capitalize(), target.name) - + self:logCombat(target, "#Source# tries to swallow #Target#!") local hit = self:attackTarget(target, DamageType.NATURE, self:combatTalentWeaponDamage(t, 1, 1.5), true) if not hit then return true end diff --git a/game/modules/tome/data/talents/gifts/storm-drake.lua b/game/modules/tome/data/talents/gifts/storm-drake.lua index a2932da15fe748568c535f018e31abbee0b540d5..4becd302cda9de7c14c0f3dbc3f54499e4e91fb3 100644 --- a/game/modules/tome/data/talents/gifts/storm-drake.lua +++ b/game/modules/tome/data/talents/gifts/storm-drake.lua @@ -125,7 +125,7 @@ newTalent{ local movedam = self:mindCrit(self:combatTalentMindDamage(t, 10, 110)) local dam = self:mindCrit(self:combatTalentMindDamage(t, 15, 190)) - local proj = require("engine.Projectile"):makeHoming( + local proj = require("mod.class.Projectile"):makeHoming( self, {particle="bolt_lightning", trail="lightningtrail"}, {speed=2, name="Tornado", dam=dam, movedam=movedam}, diff --git a/game/modules/tome/data/talents/gifts/summon-melee.lua b/game/modules/tome/data/talents/gifts/summon-melee.lua index f9d0c06ee697184d4ca43cbd1527b1a23d75f62d..2eeedffdd51b6233f23bf6e91c676b39ee1bba2d 100644 --- a/game/modules/tome/data/talents/gifts/summon-melee.lua +++ b/game/modules/tome/data/talents/gifts/summon-melee.lua @@ -192,7 +192,7 @@ newTalent{ local p = value * 0.10 if self.summoner and not self.summoner.dead then self.summoner:incEquilibrium(-p) - game.logSeen(self, "#GREEN#%s absorbs part of the blow. %s is closer to nature.", self.name:capitalize(), self.summoner.name:capitalize()) + self:logCombat(self.summoner, "#GREEN##Source# absorbs part of the blow. #Target# is closer to nature.") end return value - p end, diff --git a/game/modules/tome/data/talents/misc/npcs.lua b/game/modules/tome/data/talents/misc/npcs.lua index 19691cfb5fb8bf1b90442b6a3c70be1bd153b6dc..a20fd4f0e2f32e768cbf620b0235577af493aa75 100644 --- a/game/modules/tome/data/talents/misc/npcs.lua +++ b/game/modules/tome/data/talents/misc/npcs.lua @@ -389,7 +389,7 @@ newTalent{ game.zone:addEntity(game.level, m, "actor", x, y) - game.logSeen(self, "%s summons %s!", self.name:capitalize(), m.name) + self:logCombat(m, "#Source# summons #Target#!") -- Apply summon destabilization if self:hasEffect(self.EFF_SUMMON_DESTABILIZATION) then @@ -1223,7 +1223,7 @@ newTalent{ game.zone:addEntity(game.level, m, "actor", x, y) - game.logSeen(self, "%s spawns one of its tentacle!", self.name:capitalize()) + game.logSeen(self, "%s spawns one of its tentacles!", self.name:capitalize()) end return true diff --git a/game/modules/tome/data/talents/psionic/distortion.lua b/game/modules/tome/data/talents/psionic/distortion.lua index 9e3b3cdd30cb51ec0a17aa1537585f64e0885dd5..62a1c26ac7b471bd4e95172846a847362e910c2c 100644 --- a/game/modules/tome/data/talents/psionic/distortion.lua +++ b/game/modules/tome/data/talents/psionic/distortion.lua @@ -196,8 +196,9 @@ newTalent{ local e = Object.new{ old_feat = oe, type = oe.type, subtype = oe.subtype, - name = "maelstrom", image = oe.image, + name = self.name:capitalize().. "'s maelstrom", image = oe.image, display = oe.display, color=oe.color, back_color=oe.back_color, + tooltip = mod.class.Grid.tooltip, always_remember = true, temporary = t.getDuration(self, t), is_maelstrom = true, @@ -224,11 +225,13 @@ newTalent{ end end table.sort(tgts, "sqdist") for i, target in ipairs(tgts) do + self.summoner.__project_source = self if target.actor:canBe("knockback") then target.actor:pull(self.x, self.y, 1) - game.logSeen(target.actor, "%s is pulled in by the %s!", target.actor.name:capitalize(), self.name) + target.actor.logCombat(self, target.actor, "#Source# pulls #Target# in!") end DamageType:get(DamageType.PHYSICAL).projector(self.summoner, target.actor.x, target.actor.y, DamageType.PHYSICAL, self.dam) + self.summoner.__project_source = nil target.actor:setEffect(target.actor.EFF_DISTORTION, 2, {power=self.distortionPower}) end diff --git a/game/modules/tome/data/talents/psionic/dream-forge.lua b/game/modules/tome/data/talents/psionic/dream-forge.lua index e4a00088170e865c2e1c344627b51321b60aa814..6afd06c889a0f998bdabb49d0cc821f144a6d002 100644 --- a/game/modules/tome/data/talents/psionic/dream-forge.lua +++ b/game/modules/tome/data/talents/psionic/dream-forge.lua @@ -133,7 +133,8 @@ newTalent{ local e = Object.new{ old_feat = oe, type = oe.type, subtype = oe.subtype, - name = "forge barrier", image = "terrain/lava/lava_mountain5.png", + name = self.name:capitalize().."'s forge barrier", + image = "terrain/lava/lava_mountain5.png", display = '#', color=colors.RED, back_color=colors.DARK_GREY, shader = "shadow_simulacrum", shader_args = { color = {0.6, 0.0, 0.0}, base = 0.9, time_factor = 1500 }, @@ -152,8 +153,9 @@ newTalent{ radius = self:getTalentRadius(t), act = function(self) local tg = {type="ball", range=0, friendlyfire=false, radius = 1, talent=t, x=self.x, y=self.y,} + self.summoner.__project_source = self self.summoner:project(tg, self.x, self.y, engine.DamageType.DREAMFORGE, self.dam) - + self.summoner.__project_source = nil self:useEnergy() self.temporary = self.temporary - 1 if self.temporary <= 0 then diff --git a/game/modules/tome/data/talents/psionic/possession.lua b/game/modules/tome/data/talents/psionic/possession.lua index 88a62a83526d4c7c23fd5d36d449bd068135b6fb..793c56cc873b305c97d8c15b655ebcdc030ecd03 100644 --- a/game/modules/tome/data/talents/psionic/possession.lua +++ b/game/modules/tome/data/talents/psionic/possession.lua @@ -50,10 +50,9 @@ newTalent{ if not t.allowedTypes(self, t, target.type) then game.logPlayer(self, "You may not possess this kind of creature.") return nil end -- if target.life > target.max_life * 0.25 then game.logPlayer(self, "You may not possess this creature yet its life is too high.") return nil end - if target.dead then game.logPlayer(self, "This creature is dead!") return nil end - + if target.dead then game.logPlayer(self, "Your target is dead!") return nil end if not self:checkHit(self:combatMindpower(), target:combatMentalResist(), 0, 95, 5) then -- or not target:canBe("instakill") then - game.logPlayer(self, "You fail to shatter %s mind, leaving you unable to possess its body.", target.name) + self:logCombat(target, "#Source# fails to shatter #Target#'s mind, preventing its possession.") return true end diff --git a/game/modules/tome/data/talents/psionic/solipsism.lua b/game/modules/tome/data/talents/psionic/solipsism.lua index 03aeba24ff7ceee94ff3fd1be7e7ab42d49f5c41..2b0883865e43d6f9a2620cf8d626c1f3f3be6af0 100644 --- a/game/modules/tome/data/talents/psionic/solipsism.lua +++ b/game/modules/tome/data/talents/psionic/solipsism.lua @@ -189,7 +189,8 @@ newTalent{ print("[Dismissal] ", self.name:capitalize(), " attempting to ignore ", value, "damage from ", src.name:capitalize(), "using", saving_throw, "mental save.") if self:checkHit(saving_throw, value) then local dismissed = value * 1/self:mindCrit(2) -- Diminishing returns on high crits - game.logSeen(self, "%s dismisses %d damage from %s!", self.name:capitalize(), dismissed, src.name:capitalize()) + game:delayedLogMessage(self, nil, "Dismissal", "#TAN##Source# mentally dismisses some damage!") + game:delayedLogDamage(src, self, 0, ("#TAN#(%d dismissed)#LAST#"):format(dismissed)) return value - dismissed else return value diff --git a/game/modules/tome/data/talents/spells/aether.lua b/game/modules/tome/data/talents/spells/aether.lua index a783f57458212696035e626b1a0815b5761dfcbf..0eeb8818410add0704192acc7c1743a4652c63a7 100644 --- a/game/modules/tome/data/talents/spells/aether.lua +++ b/game/modules/tome/data/talents/spells/aether.lua @@ -98,8 +98,10 @@ newTalent{ self.list.i = util.boundWrap(self.list.i + 1, 1, #self.list) local tg = {type="beam", x=self.x, y=self.y, range=self.rad, selffire=self.summoner:spellFriendlyFire()} + self.summoner.__project_source = self self.summoner:project(tg, x, y, engine.DamageType.ARCANE_SILENCE, {dam=self.dam, chance=25}, nil) self.summoner:project(tg, self.x, self.y, engine.DamageType.ARCANE, self.dam/10, nil) + self.summoner.__project_source = nil local _ _, x, y = self:canProject(tg, x, y) game.level.map:particleEmitter(self.x, self.y, math.max(math.abs(x-self.x), math.abs(y-self.y)), "mana_beam", {tx=x-self.x, ty=y-self.y}) end, @@ -152,7 +154,7 @@ newTalent{ local list = {} self:project(tg, x, y, function(px, py) list[#list+1] = {x=px, y=py} end) - self:setEffect(self.EFF_AETHER_BREACH, t.getNb(self, t), {list=list, level=game.zone.short_name.."-"..game.level.level, dam=self:spellCrit(t.getDamage(self, t))}) + self:setEffect(self.EFF_AETHER_BREACH, t.getNb(self, t), {src = self, list=list, level=game.zone.short_name.."-"..game.level.level, dam=self:spellCrit(t.getDamage(self, t))}) game:playSoundNear(self, "talents/arcane") return true diff --git a/game/modules/tome/data/talents/spells/fire-alchemy.lua b/game/modules/tome/data/talents/spells/fire-alchemy.lua index 720d4c15db55fcad9d341877703e05660fad3c18..06d2ef73ee660022b676da07c396e3f60b33a837 100644 --- a/game/modules/tome/data/talents/spells/fire-alchemy.lua +++ b/game/modules/tome/data/talents/spells/fire-alchemy.lua @@ -131,7 +131,7 @@ newTalent{ getDamage = function(self, t) return self:combatTalentSpellDamage(t, 5, 120) end, action = function(self, t) -- Add a lasting map effect - game.level.map:addEffect(self, + local ef = game.level.map:addEffect(self, self.x, self.y, t.getDuration(self, t), DamageType.FIRE_FRIENDS, t.getDamage(self, t), 3, @@ -144,6 +144,7 @@ newTalent{ end, false ) + ef.name = "firestorm" game:playSoundNear(self, "talents/fire") return true end, @@ -195,7 +196,7 @@ newTalent{ local a, id = rng.table(tgts) table.remove(tgts, id) - self:projectile(tg, a.x, a.y, DamageType.FIRE, self:spellCrit(t.getFireDamageInSight(self, t)), {type="flame"}) + self:projectile(table.clone(tg), a.x, a.y, DamageType.FIRE, self:spellCrit(t.getFireDamageInSight(self, t)), {type="flame"}) game:playSoundNear(self, "talents/fire") end end, diff --git a/game/modules/tome/data/talents/spells/golem.lua b/game/modules/tome/data/talents/spells/golem.lua index 9369ee76ba9d22ade851a1d4f3237fb133689142..87bbc9b71a72d28fac3daaa3e4b4efb93a7ed185 100644 --- a/game/modules/tome/data/talents/spells/golem.lua +++ b/game/modules/tome/data/talents/spells/golem.lua @@ -124,7 +124,7 @@ newTalent{ if self:reactionToward(target) < 0 then if self.ai_target then self.ai_target.target = target end target:setTarget(self) - game.logSeen(self, "%s provokes %s to attack it.", self.name:capitalize(), target.name) + self:logCombat(target, "#Source# provokes #Target# to attack it.") end end) return true @@ -419,7 +419,7 @@ newTalent{ table.sort(tgts, "sqdist") for i, target in ipairs(tgts) do target.actor:pull(self.x, self.y, tg.radius) - game.logSeen(target.actor, "%s is pulled by %s!", target.actor.name:capitalize(), self.name) + self:logCombat(target.actor, "#Target# is pulled toward #Source#!") DamageType:get(DamageType.ARCANE).projector(self, target.actor.x, target.actor.y, DamageType.ARCANE, t.getDamage(self, t)) end return true diff --git a/game/modules/tome/data/talents/spells/golemancy.lua b/game/modules/tome/data/talents/spells/golemancy.lua index 9a6b02f9354b123c3397e756c67a73650c103442..f59c4957b85fe05c87f0c65198802644ccc4a6fc 100644 --- a/game/modules/tome/data/talents/spells/golemancy.lua +++ b/game/modules/tome/data/talents/spells/golemancy.lua @@ -431,7 +431,7 @@ newTalent{ local _, _, tgt = e:getTarget() if e:reactionToward(self) < 0 and tgt == self and rng.percent(chance) then e:setTarget(golem) - game.logSeen(e, "%s focuses on %s.", e.name:capitalize(), golem.name) + golem:logCombat(e, "#Target# focuses on #Source#.") end end end diff --git a/game/modules/tome/data/talents/techniques/dualweapon.lua b/game/modules/tome/data/talents/techniques/dualweapon.lua index 646ffea61ac91d681b71c5bda096e18c9431d4b1..609a22b5961a151d0a6cf76ffe8346f59b0bb76d 100644 --- a/game/modules/tome/data/talents/techniques/dualweapon.lua +++ b/game/modules/tome/data/talents/techniques/dualweapon.lua @@ -95,7 +95,7 @@ newTalent{ cooldown = 10, sustain_stamina = 20, tactical = { BUFF = 2 }, - on_pre_use = function(self, t, silent) if not self:hasDualWeapon() then if not silent then game.logPlayer(self, "You require a two weapons to use this talent.") end return false end return true end, + on_pre_use = function(self, t, silent) if not self:hasDualWeapon() then if not silent then game.logPlayer(self, "You require two weapons to use this talent.") end return false end return true end, getApr = function(self, t) return self:combatScale(self:getTalentLevel(t) * self:getDex(), 4, 0, 25, 500, 0.75) end, activate = function(self, t) local weapon, offweapon = self:hasDualWeapon() @@ -164,7 +164,7 @@ newTalent{ require = techs_dex_req1, requires_target = true, tactical = { ATTACK = { weapon = 1 }, DISABLE = { stun = 2 } }, - on_pre_use = function(self, t, silent) if not self:hasDualWeapon() then if not silent then game.logPlayer(self, "You require a two weapons to use this talent.") end return false end return true end, + on_pre_use = function(self, t, silent) if not self:hasDualWeapon() then if not silent then game.logPlayer(self, "You require two weapons to use this talent.") end return false end return true end, getStunDuration = function(self, t) return math.floor(self:combatTalentScale(t, 3, 7)) end, action = function(self, t) local weapon, offweapon = self:hasDualWeapon() @@ -212,7 +212,7 @@ newTalent{ require = techs_dex_req2, requires_target = true, tactical = { ATTACK = { weapon = 4 } }, - on_pre_use = function(self, t, silent) if not self:hasDualWeapon() then if not silent then game.logPlayer(self, "You require a two weapons to use this talent.") end return false end return true end, + on_pre_use = function(self, t, silent) if not self:hasDualWeapon() then if not silent then game.logPlayer(self, "You require two weapons to use this talent.") end return false end return true end, action = function(self, t) local weapon, offweapon = self:hasDualWeapon() if not weapon then @@ -245,7 +245,7 @@ newTalent{ require = techs_dex_req3, requires_target = true, tactical = { ATTACKAREA = { weapon = 1, cut = 1 } }, - on_pre_use = function(self, t, silent) if not self:hasDualWeapon() then if not silent then game.logPlayer(self, "You require a two weapons to use this talent.") end return false end return true end, + on_pre_use = function(self, t, silent) if not self:hasDualWeapon() then if not silent then game.logPlayer(self, "You require two weapons to use this talent.") end return false end return true end, cutdur = function(self,t) return math.floor(self:combatTalentScale(t, 4, 8)) end, cutPower = function(self, t) local main, off = self:hasDualWeapon() @@ -314,7 +314,7 @@ newTalent{ target = function(self, t) return {type="ball", radius=self:getTalentRadius(t), range=self:getTalentRange(t)} end, - on_pre_use = function(self, t, silent) if not self:hasDualWeapon() then if not silent then game.logPlayer(self, "You require a two weapons to use this talent.") end return false end return true end, + on_pre_use = function(self, t, silent) if not self:hasDualWeapon() then if not silent then game.logPlayer(self, "You require two weapons to use this talent.") end return false end return true end, action = function(self, t) local weapon, offweapon = self:hasDualWeapon() if not weapon then diff --git a/game/modules/tome/data/talents/techniques/excellence.lua b/game/modules/tome/data/talents/techniques/excellence.lua index d7cc9b2e7e5f6a9717a562ee320d34ce5817f913..f76e5f51515daeabc01dc2f772c4cf72d8b76c2f 100644 --- a/game/modules/tome/data/talents/techniques/excellence.lua +++ b/game/modules/tome/data/talents/techniques/excellence.lua @@ -44,7 +44,7 @@ newTalent{ proj:terminate(x, y) game.level:removeEntity(proj, true) proj.dead = true - game.logSeen(self, "%s takes down '%s'.", self.name:capitalize(), proj.name) + self:logCombat(proj, "#Source# shoots down '#Target#'.") end end diff --git a/game/modules/tome/data/talents/techniques/unarmed-discipline.lua b/game/modules/tome/data/talents/techniques/unarmed-discipline.lua index d7903d1e915344330a1ed477535a31ff754526ef..02c2fbf9b65f2858c7d669f8561483862c29547c 100644 --- a/game/modules/tome/data/talents/techniques/unarmed-discipline.lua +++ b/game/modules/tome/data/talents/techniques/unarmed-discipline.lua @@ -34,8 +34,7 @@ newTalent{ if not x or not y or not target then return nil end if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end - local hit = target:checkHit(self:combatAttack(), target:combatDefense(), 0, 95) -- Deprecated checkHit call - + local hit = target:checkHit(self:combatAttack(), target:combatDefense(), 0, 95) and self:checkEvasion(target) -- Try to knockback ! if hit then local can = function(target) @@ -57,7 +56,7 @@ newTalent{ self:buildCombo() else - game.logSeen(target, "%s misses %s.", self.name:capitalize(), target.name:capitalize()) + self:logCombat(target, "#Source# misses #Target#.") end return true @@ -92,26 +91,27 @@ newTalent{ do_throw = function(self, target, t) local ef = self:hasEffect(self.EFF_DEFENSIVE_GRAPPLING) if not ef or not rng.percent(self.tempeffect_def.EFF_DEFENSIVE_GRAPPLING.throwchance(self, ef)) then return end - local hit = self:checkHit(self:combatAttack(), target:combatDefense(), 0, 95) -- Deprecated checkHit call removed + local grappled = target:isGrappled(self) + local hit = self:checkHit(self:combatAttack(), target:combatDefense(), 0, 95) and (grappled or not self:checkEvasion(target)) -- grappled target can't evade ef.throws = ef.throws - 1 if ef.throws <= 0 then self:removeEffect(self.EFF_DEFENSIVE_GRAPPLING) end if hit then self:project(target, target.x, target.y, DamageType.PHYSICAL, self:physicalCrit(t.getDamageTwo(self, t), nil, target, self:combatAttack(), target:combatDefense())) -- if grappled stun - if target:isGrappled(self) and target:canBe("stun") then + if grappled and target:canBe("stun") then target:setEffect(target.EFF_STUNNED, 2, {apply_power=self:combatAttack(), min_dur=1}) - game.logSeen(target, "%s has been slammed into the ground!", target.name:capitalize()) + self:logCombat(target, "#Source# slams #Target# into the ground!") -- if not grappled daze else - game.logSeen(target, "%s has been thrown to the ground!", target.name:capitalize()) + self:logCombat(target, "#Source# throws #Target# to the ground!") -- see if the throw dazes the enemy if target:canBe("stun") then target:setEffect(target.EFF_DAZED, 2, {apply_power=self:combatAttack(), min_dur=1}) end end else - game.logSeen(target, "%s misses a defensive throw against %s!", self.name:capitalize(),target.name:capitalize()) + self:logCombat(target, "#Source# misses a defensive throw against #Target#!", self.name:capitalize(),target.name:capitalize()) end end, on_unlearn = function(self, t) diff --git a/game/modules/tome/data/talents/uber/wil.lua b/game/modules/tome/data/talents/uber/wil.lua index 3bc54a9020dcca1828d8265e3753c2fe2febf8db..d63f306e61adbca61cb00a5031c916c247c62067 100644 --- a/game/modules/tome/data/talents/uber/wil.lua +++ b/game/modules/tome/data/talents/uber/wil.lua @@ -210,7 +210,7 @@ uberTalent{ require = { special={desc="Antimagic", fct=function(self) return self:knowTalentType("wild-gift/antimagic") end} }, trigger = function(self, t, target, source_t) self:startTalentCooldown(t) - game.logSeen(self, "#LIGHT_BLUE#%s punishes %s for casting a spell!", self.name:capitalize(), target.name) + self:logCombat(target, "#LIGHT_BLUE##Source# punishes #Target# for casting a spell!", self.name:capitalize(), target.name) DamageType:get(DamageType.MIND).projector(self, target.x, target.y, DamageType.MIND, 20 + self:getWil() * 2) local dur = target:getTalentCooldown(source_t) @@ -220,9 +220,10 @@ uberTalent{ return true end, info = function(self, t) - return ([[Your will is a shield against the assault of crazed arcane users. + return ([[Your will is a shield against assaults from crazed arcane users. Each time that you take damage from a spell, you punish the spellcaster with %0.2f mind damage. - Also, they will suffer a 35%% spell failure chance for the cooldown duration of the spell they used on you.]]) + Also, they will suffer a 35%% spell failure chance (with duration equal to the cooldown of the spell they used on you). + Note: this talent has a cooldown.]]) :format(damDesc(self, DamageType.MIND, 20 + self:getWil() * 2)) end, } diff --git a/game/modules/tome/data/talents/undeads/ghoul.lua b/game/modules/tome/data/talents/undeads/ghoul.lua index 0888a1feffcca9a452d567414b7722daa9044620..75487928dd37df60f5bbd5d07a5a4ae1b42f48a4 100644 --- a/game/modules/tome/data/talents/undeads/ghoul.lua +++ b/game/modules/tome/data/talents/undeads/ghoul.lua @@ -155,7 +155,7 @@ newTalent{ game.zone:addEntity(game.level, m, "actor", target.x, target.y) game.level.map:particleEmitter(target.x, target.y, 1, "slime") game:playSoundNear(target, "talents/slime") - game.logPlayer(game.player, "A #DARK_GREEN#ghoul#LAST# rises from the corpse of %s.", target.name) + m:logCombat(target, "A #GREY##Source##LAST# rises from the corpse of #Target#.") end, action = function(self, t) local tg = {type="hit", range=self:getTalentRange(t)} diff --git a/game/modules/tome/data/timed_effects.lua b/game/modules/tome/data/timed_effects.lua index dbd92ff2645b9864c237342163ccccabb7304219..eb3ce93f72af33206e239b19b782e9b9b046d221 100644 --- a/game/modules/tome/data/timed_effects.lua +++ b/game/modules/tome/data/timed_effects.lua @@ -33,6 +33,24 @@ local Chat = require "engine.Chat" local Map = require "engine.Map" local Level = require "engine.Level" +local resolveSource = function(self) + if self.src then + return self.src:resolveSource() + else + return self + end +end + +--gets the full name of the effect +local getName = function(self) + local name = self.effect_id and mod.class.Actor.tempeffect_def[self.effect_id].desc or "effect" + if self.src and self.src.name then + return name .." from "..self.src.name:capitalize() + else + return name + end +end + local oldNewEffect = TemporaryEffects.newEffect TemporaryEffects.newEffect = function(self, t) if not t.image then @@ -41,7 +59,8 @@ TemporaryEffects.newEffect = function(self, t) if fs.exists("/data/gfx/"..t.image) then t.display_entity = Entity.new{image=t.image, is_effect=true} else t.display_entity = Entity.new{image="effects/default.png", is_effect=true} print("===", t.type, t.name) end - + t.getName = getName + t.resolveSource = resolveSource return oldNewEffect(self, t) end diff --git a/game/modules/tome/data/timed_effects/magical.lua b/game/modules/tome/data/timed_effects/magical.lua index a56fbe7c2e287531311006b4c460053004ece8bb..10c52e287880d1144f40b13718b6caedbdc0db05 100644 --- a/game/modules/tome/data/timed_effects/magical.lua +++ b/game/modules/tome/data/timed_effects/magical.lua @@ -1939,7 +1939,6 @@ newEffect{ local spot = rng.table(eff.list) if not spot or not spot.x then return end - self:project({type="ball", x=spot.x, y=spot.y, radius=2, selffire=self:spellFriendlyFire()}, spot.x, spot.y, DamageType.ARCANE, eff.dam) game.level.map:particleEmitter(spot.x, spot.y, 2, "generic_sploom", {rm=150, rM=180, gm=20, gM=60, bm=180, bM=200, am=80, aM=150, radius=2, basenb=120}) diff --git a/game/modules/tome/data/timed_effects/mental.lua b/game/modules/tome/data/timed_effects/mental.lua index 18a6a3ec9fb2d7b389b06437e5c43ea549cc5478..09481017be769480731bf283b72ad07294ba7142 100644 --- a/game/modules/tome/data/timed_effects/mental.lua +++ b/game/modules/tome/data/timed_effects/mental.lua @@ -359,10 +359,10 @@ newEffect{ status = "beneficial", parameters = {}, activate = function(self, eff) - game.logSeen(self, "#F53CBE#%s is being stalked by %s!", eff.target.name:capitalize(), self.name) + self:logCombat(eff.target, "#F53CBE##Target# is being stalked by #Source#!") end, deactivate = function(self, eff) - game.logSeen(self, "#F53CBE#%s is no longer being stalked by %s.", eff.target.name:capitalize(), self.name) + self:logCombat(eff.target, "#F53CBE##Target# is no longer being stalked by #Source#.") end, on_timeout = function(self, eff) if not eff.target or eff.target.dead or not eff.target:hasEffect(eff.target.EFF_STALKED) then @@ -1047,7 +1047,7 @@ newEffect{ if (self.x ~= x or self.y ~= y) then local target = game.level.map(x, y, Map.ACTOR) if target then - game.logSeen(self, "#F53CBE#%s attacks %s in a fit of paranoia.", self.name:capitalize(), target.name) + self:logCombat(target, "#F53CBE##Source# attacks #Target# in a fit of paranoia.") if self:attackTarget(target, nil, 1, false) and target ~= eff.source then if not target:canBe("fear") then game.logSeen(target, "#F53CBE#%s ignores the fear!", target.name:capitalize()) @@ -1327,7 +1327,7 @@ newEffect{ self:move(bestX, bestY, false) game.logPlayer(self, "#F53CBE#You panic and flee from %s.", eff.source.name) else - game.logSeen(self, "#F53CBE#%s panics and tries to flee from %s.", self.name:capitalize(), eff.source.name) + self:logCombat(eff.source, "#F53CBE##Source# panics but fails to flee from #Target#.") self:useEnergy(game.energy_to_act * self:combatMovementSpeed(bestX, bestY)) end end @@ -1908,7 +1908,7 @@ newEffect{ if self.life <= 0 then self.life = 1 self:setEffect(self.EFF_STUNNED, 3, {}) - game.logSeen(self, "%s's increased life wears off and is stunned by the change.", self.name:capitalize()) + game.logSeen(self, "%s's increased life fades, leaving it stunned by the loss.", self.name:capitalize()) end end, } @@ -2228,9 +2228,9 @@ newEffect{ end if not eff.incStatsId then - game.logSeen(self, ("%s is mimicking %s. (no gains)."):format(self.name:capitalize(), eff.target.name)) + self:logCombat(eff.target, "#Source# is mimicking #Target#. (no gains).") else - local desc = ("%s is mimicking %s. ("):format(self.name:capitalize(), eff.target.name) + local desc = "#Source# is mimicking #Target#. (" local first = true for id, value in pairs(eff.incStats) do if not first then desc = desc..", " end @@ -2238,7 +2238,7 @@ newEffect{ desc = desc..("%+d %s"):format(value, Stats.stats_def[id].name:capitalize()) end desc = desc..")" - game.logSeen(self, desc) + self:logCombat(eff.target, desc) end end, deactivate = function(self, eff) diff --git a/game/modules/tome/data/timed_effects/other.lua b/game/modules/tome/data/timed_effects/other.lua index 66a3fe35d600b831f00c3c2c47e72a84195500e8..080d75d9710a3479941d15a34e1d4052004942fc 100644 --- a/game/modules/tome/data/timed_effects/other.lua +++ b/game/modules/tome/data/timed_effects/other.lua @@ -883,8 +883,8 @@ newEffect{ on_merge = function(self, old_eff, new_eff) return old_eff end, doConspirator = function(self, eff, target) if math.min(eff.unlockLevel, eff.level) >= 3 and self:attr("confused") and target:canBe("confusion") then - target:setEffect(target.EFF_CONFUSED, 3, {power=50}) -- Make consistent - game.logSeen(self, "#F53CBE#%s spreads confusion to %s.", self.name:capitalize(), target.name) + target:setEffect(target.EFF_CONFUSED, 3, {power=50}) + self:logCombat(target, "#F53CBE##Source# spreads confusion to #Target#.") end end, } @@ -1330,7 +1330,7 @@ newEffect{ subtype = { miscellaneous=true }, status = "beneficial", parameters = {}, - activate = function(self, eff) game.logPlayer(self, "#LIGHT_BLUE#You begin reloading.") end, + activate = function(self, eff) game.logSeen(self, "#LIGHT_BLUE#%s begins reloading.", self.name:capitalize()) end, deactivate = function(self, eff) end, on_timeout = function(self, eff) diff --git a/game/modules/tome/data/timed_effects/physical.lua b/game/modules/tome/data/timed_effects/physical.lua index 04c6172ddb31951a465909778e59fdc81f6f4fe3..85d5e16f48d5c63bdbbee384fc8198a92411da07 100644 --- a/game/modules/tome/data/timed_effects/physical.lua +++ b/game/modules/tome/data/timed_effects/physical.lua @@ -585,6 +585,7 @@ newEffect{ self.add_displays = { Entity.new{image='npc/iceblock.png', display=' ', display_on_seen=true } } eff.added_display = true end + eff.ice = mod.class.Object.new{name = "Iceblock", type = "wall", image='npc/iceblock.png', display = ' '} -- use type Object to facilitate the combat log self:removeAllMOs() game.level.map:updateMap(self.x, self.y) diff --git a/game/modules/tome/data/zones/deep-bellow/npcs.lua b/game/modules/tome/data/zones/deep-bellow/npcs.lua index 038c1563a5933a674bba97db624aff9c1e978e5b..9934f9f478a027519c9ecce817dd02a073a1994b 100644 --- a/game/modules/tome/data/zones/deep-bellow/npcs.lua +++ b/game/modules/tome/data/zones/deep-bellow/npcs.lua @@ -115,13 +115,13 @@ It seems to come from the digestive system of the mouth.]], if self.summoner.dead then self:die() - game.logSeen(self, "#AQUAMARINE#With the Mouth death its crawler also falls lifeless on the ground!") + game.logSeen(self, "#AQUAMARINE#With the Mouth's death its crawler also falls lifeless on the ground!") end end, on_die = function(self, who) if self.summoner and not self.summoner.dead then - game.logSeen(self, "#AQUAMARINE#As %s falls you notice that %s seems to shudder in pain!", self.name, self.summoner.name) + self:logCombat(self.summoner, "#AQUAMARINE#As #Source# falls you notice that #Target# seems to shudder in pain!") self.summoner.no_take_hit_achievements = true self.summoner:takeHit(1000, who) self.summoner.no_take_hit_achievements = nil diff --git a/game/modules/tome/data/zones/demon-plane-spell/grids.lua b/game/modules/tome/data/zones/demon-plane-spell/grids.lua index e3694b5a4411ddbb200bb1724b862957fb06f286..f800e740f0a6c3de3e1d69c7a38a087a969beb49 100644 --- a/game/modules/tome/data/zones/demon-plane-spell/grids.lua +++ b/game/modules/tome/data/zones/demon-plane-spell/grids.lua @@ -24,8 +24,9 @@ load("/data/general/grids/lava.lua", function(e) if e.define_as == "LAVA_FLOOR" local DT = engine.DamageType local dam = DT:get(DT.DEMONFIRE).projector(game.level.plane_owner, x, y, DT.DEMONFIRE, game.level.demonfire_dam or 1) if dam then - if dam > 0 then game.logPlayer(who, "The lava burns you!") - elseif dam < 0 then game.logPlayer(who, "The lava heals you!") end + self.x, self.y = x, y + if dam > 0 then self:logCombat(who, "#Source# burns #Target#!") + elseif dam < 0 then self:logCombat(who, "#Source# heals #Target#!") end end end end end) diff --git a/game/modules/tome/load.lua b/game/modules/tome/load.lua index a80f87115b22513aad499ebb47e6c93be8e55b6e..245582d49b2880666e8e332821e038ca10de04cc 100644 --- a/game/modules/tome/load.lua +++ b/game/modules/tome/load.lua @@ -30,6 +30,7 @@ local KeyBind = require "engine.KeyBind" local DamageType = require "engine.DamageType" local Faction = require "engine.Faction" local Map = require "engine.Map" +local MapEffects = require "mod.class.MapEffects" -- This alters Map local Level = require "engine.Level" local Tiles = require "engine.Tiles" local InventoryUI = require "engine.ui.Inventory"