-- TE4 - T-Engine 4 -- Copyright (C) 2009 - 2019 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 require "engine.class" local Map = require "engine.Map" local Target = require "engine.Target" local DamageType = require "engine.DamageType" --- Handles actors life and death -- @classmod engine.generator.interface.ActorLife module(..., package.seeall, class.make) function _M:init(t) self.max_life = t.max_life or 100 self.life = t.life or self.max_life self.life_regen = t.life_regen or 0 self.die_at = t.die_at or 0 end --- Checks if something bumps in us -- If it happens the method attack is called on the target with the attacker as parameter. -- Do not touch! function _M:block_move(x, y, e, can_attack) -- Dont bump yourself! if e and e ~= self and can_attack then e:attack(self, x, y) return "attack" end return true end --- Regenerate life, call it from your actor class act() method function _M:regenLife() if self.life_regen then self.life = util.bound(self.life + self.life_regen, self.die_at, self.max_life) end end --- Heal some function _M:heal(value, src) if self.onHeal then value = self:onHeal(value, src) end self.life = util.bound(self.life + value, self.die_at, self.max_life) self.changed = true return value end --- Remove some HP from an actor -- If HP is reduced to 0 then remove from the level and call the die method. -- When an actor dies its dead property is set to true, to wait until garbage collection deletes it -- @param value how much damage -- @param src attacker -- @string death_note message for death -- @return true/false if the actor died -- @return the actual damage done function _M:takeHit(value, src, death_note) if self.onTakeHit then value = self:onTakeHit(value, src) end self.life = self.life - value self.changed = true if self.life <= self.die_at and not self.dead then if src and src.on_kill and src:on_kill(self) then return false, value end game.logSeen(self, "#{bold}#%s killed %s!#{normal}#", src and src:getName():capitalize() or _t"something", self:getName()) return self:die(src, death_note), value end return false, value end --- Called when died -- @param src attacker -- @string death_note message for death function _M:die(src, death_note) if game.level:hasEntity(self) then game.level:removeEntity(self) end self.dead = true self.changed = true self:check("on_die", src, death_note) return true end --- Actor is being attacked! -- Module authors should rewrite it to handle combat, dialog, ... -- @param target the actor being attacked -- @param x placeholder -- @param y placeholder function _M:attack(target, x, y) game.logSeen(target, "%s attacks %s.", self.name:capitalize(), target:getName():capitalize()) target:takeHit(10, self) end