illarion-content/base/character.lua

191 lines
6.9 KiB
Lua
Raw Permalink Normal View History

2014-01-04 15:39:52 +01:00
--[[
Illarion Server
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Affero 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 Affero General Public License for more
details.
You should have received a copy of the GNU Affero General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
2014-01-04 15:39:52 +01:00
]]
-- Collection of helper functions for the handling of characters
2015-10-28 18:44:21 +01:00
local common = require("base.common")
2026-04-21 18:39:43 +02:00
local pulsegwynt = require("magic.nature.effects.pulsegwynt")
local testing = require("base.testing")
2015-10-28 18:44:21 +01:00
2014-10-27 15:59:35 +01:00
local M = {}
2015-01-10 18:32:04 +01:00
local HITPOINTS = "hitpoints"
--- Get the current hitpoints of the character
-- @param User the character that is queried
-- @return the hitpoints of the character
function M.GetHP(User)
return User:increaseAttrib(HITPOINTS, 0)
end
--- Change the hitpoints value of a character.
-- @param User The characters that receives the hitpoints change.
-- @param Value The value the hitpoints are changed by.
-- @return true in case the character is alive after the change of the hitpoints
2026-04-21 18:39:43 +02:00
function M.ChangeHP(defender, valueChange)
local partner, partnerDamage
if valueChange < 0 and valueChange ~= -10000 then -- The character is taking damage, not being healed and it isnt an instakill
valueChange, partner, partnerDamage = pulsegwynt.impactOnDamageTaken(defender, valueChange)
-- If bonded with someone via nature magics deepweave spell Pulsegwynt, they take part of the damage for you
if partner then
partner:increaseAttrib(HITPOINTS, partnerDamage)
end
end
-- A bond is broken if you or your partners health is reduced to 20% or lower
if partner and (M.GetHP(partner) < pulsegwynt.healthLimit or M.GetHP(defender)-valueChange < pulsegwynt.healthLimit) then
pulsegwynt.breakBond(defender, partner)
end
if testing.active and valueChange < 0 and valueChange ~= -10000 then
defender:talk(Character.say,"#me takes "..-valueChange.." damage.", "#me takes "..-valueChange.." damage.")
if partner then
partner:talk(Character.say,"#me takes "..-partnerDamage.." damage.", "#me takes "..-partnerDamage.." damage.")
end
end
return defender:increaseAttrib(HITPOINTS, valueChange) > 0
end;
--- Check if a character would surive if a amount of hitpoints get reduced
-- @param User The character that is tested
-- @param Value The value of hitpoints that are supposed to be reduced
-- @return true in case the character would survive
2014-10-27 15:59:35 +01:00
function M.WouldDie(User, Value)
2015-01-10 18:32:04 +01:00
return M.GetHP(User) <= Value;
end;
2015-01-10 18:32:04 +01:00
--- Check if a character is dead.
-- @param User the character to check
-- @return true in case the character is dead
function M.IsDead(User)
return M.GetHP(User) == 0
end
--- Check if the character is at the brink of death. Means that the character
-- has only one hitpoint left.
-- @param User The character to check
-- @return true in case the character is at the brink of death
2014-10-27 15:59:35 +01:00
function M.AtBrinkOfDeath(User)
2014-11-04 05:17:01 +01:00
return M.WouldDie(User, 1);
end;
--- Bring a character to the brink of death. Means that he has only one hitpoint
-- left.
-- @param User The character to bring to the brink of death
2014-10-27 15:59:35 +01:00
function M.ToBrinkOfDeath(User)
2015-01-10 18:32:04 +01:00
M.ChangeHP(User, 1 - M.GetHP(User));
end;
2025-08-21 20:30:25 +02:00
local overTimeLTEs = {1, 3, 9, 10} -- health, mana and stamina drains over time need to be removed on death, no matter what the killing blow is
2025-03-28 17:09:29 +01:00
2025-08-22 11:02:53 +02:00
local recentlyKilled = {}
--- Kill a character.
-- @param User The character to kill
-- @return true in case the player was killed successfully
2025-03-28 17:09:29 +01:00
function M.Kill(user)
2025-08-21 20:30:25 +02:00
2025-08-22 11:02:53 +02:00
local timeStamp = world:getTime("unix")
2025-03-28 17:09:29 +01:00
for _, lte in pairs(overTimeLTEs) do
local foundEffect = user.effects:find(lte)
if foundEffect then
user.effects:removeEffect(lte)
end
end
2025-08-21 20:30:25 +02:00
2025-08-22 11:02:53 +02:00
if recentlyKilled[user.id] and recentlyKilled[user.id]+5 >= timeStamp then --It's been 5 or less seconds since this character was killed
return --ensures that if a DoT was applied right after or in the same blow as a killing blow, it wont reskill you
end
2025-03-28 17:09:29 +01:00
common.TalkNLS(user, Character.say,"#me geht t<>dlich getroffen zu Boden.","#me goes down, fatally injured.")
M.ChangeHP(user, -10000)
2025-08-22 11:02:53 +02:00
recentlyKilled[user.id] = timeStamp
2025-03-28 17:09:29 +01:00
return true
end
2025-08-23 15:55:31 +02:00
function M.WasKilledRecently(user)
local timeStamp = world:getTime("unix")
if recentlyKilled[user.id] and recentlyKilled[user.id]+5 >= timeStamp then
return true
end
return false
end
--- Change the movepoints of a character by the value handed over.
-- @param User The character thats movepoints are supposed to change
-- @param Value The amount of movepoints that are added
2014-10-27 15:59:35 +01:00
function M.ChangeMovepoints(User, Value)
User.movepoints = User.movepoints + Value;
end;
--- Change the fighting points of a character by the value handed over.
-- @param User The character thats fightingpoints are supposed to change
-- @param Value The amount of fightingpoints that are added
-- @info This is currently set to change the movepoints also because the
-- fighting points do not seem to work on the current server
2014-10-27 15:59:35 +01:00
function M.ChangeFightingpoints(User, Value)
2011-06-19 14:49:55 +00:00
User.fightpoints = User.fightpoints + Value;
end;
--- Check if the character is a player character.
-- @param User The character to check
-- @return true in case the character is a player character
2014-10-27 15:59:35 +01:00
function M.IsPlayer(User)
return User:getType() == Character.player;
end;
2012-08-02 16:28:03 +02:00
-- Kills immediately after a defined period of time
-- @param Character The character (e.g. summoned monster) supposed to die
-- @param deathAfter The period of time after which the character dies in 1/10 sec
-- @param deathGfx The GFX shown on the characters' death, nil for no GFX
2012-08-02 23:01:17 +02:00
-- @param deathSound The sound played on characters' death, nil for no sound
2013-06-18 20:13:40 +02:00
-- @param blood Boolean determining if blood is dropped or not
2014-10-27 15:59:35 +01:00
function M.DeathAfterTime(Character,deathAfter,deathGfx,deathSound,blood)
2021-05-31 15:48:15 +02:00
local find = Character.effects:find(36)
2015-10-28 18:42:01 +01:00
if find then
return
else
2021-05-31 15:48:15 +02:00
local myEffect = LongTimeEffect(36,deathAfter)
2015-10-28 18:42:01 +01:00
if deathGfx ~= nil then
myEffect:addValue("deathGfx",deathGfx)
2012-08-02 16:28:03 +02:00
end
2015-10-28 18:42:01 +01:00
if deathSound ~= nil then
myEffect:addValue("deathSound",deathSound)
end
if blood then
myEffect:addValue("blood",1)
end
Character.effects:addEffect(myEffect)
2012-08-02 16:28:03 +02:00
end
end
2013-03-11 22:18:53 +01:00
-- Get a string that is nicely usable for a character reference in the logfile
-- @param character the character
-- @return the reference string to the character for the logfile
2014-10-27 15:59:35 +01:00
function M.LogText(character)
2015-10-28 18:42:01 +01:00
return string.format("%s (%u)", character.name, character.id);
2013-06-03 00:29:46 +02:00
end
2014-10-27 15:59:35 +01:00
return M