Skip to content
Snippets Groups Projects
Commit 0b6b1c9b authored by dg's avatar dg
Browse files

actor resources

talent cooldowns


git-svn-id: http://svn.net-core.org/repos/t-engine4@73 51575b47-30f0-44d4-a5cc-537603b46e54
parent 683b420f
No related branches found
No related tags found
No related merge requests found
require "engine.class"
--- Handles actors life and death
module(..., package.seeall, class.make)
_M.resources_def = {}
--- Defines resource
-- Static!
-- All actors will now have :getResourcename() and :incResourcename() methods as well as a .max_resourcename and .resourcename
-- properties. It is advised to NOT access .resourcename directly and use the get/inc methods. They handle talent
-- dependencies
function _M:defineResource(name, short_name, talent, desc)
assert(name, "no resource name")
assert(short_name, "no resource short_name")
table.insert(self.resources_def, {
name = name,
short_name = short_name,
talent = talent,
description = desc,
})
self.resources_def[#self.resources_def].id = #self.resources_def
self.resources_def[short_name] = self.resources_def[#self.resources_def]
self["RS_"..short_name:upper()] = #self.resources_def
local maxname = "max_"..short_name
self["inc"..short_name:lower():capitalize()] = function(self, v)
self[short_name] = util.bound(self[short_name] + v, 0, self[maxname])
end
self["incMax"..short_name:lower():capitalize()] = function(self, v)
self[maxname] = self[maxname] + v
end
if talent then
-- if there is an associated talent, check for it
self["get"..short_name:lower():capitalize()] = function(self)
if self:knowTalent(talent) then
return self[short_name]
else
return 0
end
end
else
self["get"..short_name:lower():capitalize()] = function(self)
return self[short_name]
end
end
end
function _M:init(t)
for i, r in ipairs(_M.resources_def) do
self["max_"..r.short_name] = t["max_"..r.short_name] or 100
self[r.short_name] = t[r.short_name] or self["max_"..r.short_name]
end
end
......@@ -37,8 +37,6 @@ function _M:newTalent(t)
assert(t.type, "no or unknown talent type")
t.short_name = t.short_name or t.name
t.short_name = t.short_name:upper():gsub("[ ]", "_")
t.mana = t.mana or 0
t.stamina = t.stamina or 0
t.mode = t.mode or "activated"
t.points = t.points or 1
assert(t.mode == "activated" or t.mode == "sustained", "wrong talent mode, requires either 'activated' or 'sustained'")
......@@ -65,6 +63,7 @@ end
function _M:init(t)
self.talents = t.talents or {}
self.talents_types = t.talents_types or {}
self.talents_cd = {}
end
--- Make the actor use the talent
......@@ -73,11 +72,18 @@ function _M:useTalent(id)
assert(ab, "trying to cast talent "..tostring(id).." but it is not defined")
if ab.action then
if self:isTalentCoolingDown(ab) then
game.logPlayer(self, "%s is still on cooldown for %d turns.", ab.name:capitalize(), self.talents_cd[ab.id])
return
end
if not self:preUseTalent(ab) then return end
local co = coroutine.create(function()
local ret = ab.action(self)
if not self:postUseTalent(ab, ret) then return end
-- Everything went ok? then start cooldown if any
self:startTalentCooldown(ab)
end)
local ok, err = coroutine.resume(co)
if not ok and err then error(err) end
......@@ -229,3 +235,25 @@ function _M:unlearnTalentType(tt)
self.talents_types[tt] = nil
return true
end
--- Starts a talent cooldown
-- @param t the talent to cooldown
function _M:startTalentCooldown(t)
if not t.cooldown then return end
self.talents_cd[t.id] = t.cooldown
end
--- Is talent in cooldown?
function _M:isTalentCoolingDown(t)
if not t.cooldown then return false end
if self.talents_cd[t.id] and self.talents_cd[t.id] > 0 then return true else return false end
end
--- Cooldown all talents by one
-- This should be called in your actors "act()" method
function _M:cooldownTalents()
for tid, c in pairs(self.talents_cd) do
self.talents_cd[tid] = self.talents_cd[tid] - 1
if self.talents_cd[tid] == 0 then self.talents_cd[tid] = nil end
end
end
......@@ -4,6 +4,7 @@ require "engine.interface.ActorLife"
require "engine.interface.ActorLevel"
require "engine.interface.ActorStats"
require "engine.interface.ActorTalents"
require "engine.interface.ActorResource"
require "engine.interface.BloodyDeath"
require "mod.class.interface.Combat"
......@@ -14,7 +15,7 @@ module(..., package.seeall, class.inherit(
engine.interface.ActorLevel,
engine.interface.ActorStats,
engine.interface.ActorTalents,
-- engine.interface.ActorResource,
engine.interface.ActorResource,
engine.interface.BloodyDeath,
mod.class.interface.Combat
))
......@@ -25,13 +26,18 @@ function _M:init(t)
engine.interface.ActorLevel.init(self, t)
engine.interface.ActorStats.init(self, t)
engine.interface.ActorTalents.init(self, t)
-- engine.interface.ActorResouce.init(self, t)
engine.interface.ActorResource.init(self, t)
self.unused_stats = 0
self.unused_talents = 0
self.unused_talents_types = 0
end
function _M:act()
-- Cooldown talents
self:cooldownTalents()
end
function _M:move(x, y, force)
local moved = false
if force or self:enoughEnergy() then
......@@ -67,7 +73,8 @@ function _M:onStatChange(stat, v)
if stat == self.STAT_CON then
self.max_life = self.max_life + 5 * v
elseif stat == self.STAT_WIL then
self.max_mana = self.max_mana + 5 * v
self:incMaxMana(5 * v)
self:incMaxStamina(5 * v)
end
end
......@@ -85,17 +92,24 @@ end
-- @param ab the talent (not the id, the table)
-- @return true to continue, false to stop
function _M:preUseTalent(ab)
local ret = self:enoughEnergy()
if ret == true then
if ab.message then
game.logSeen(self, "%s", self:useTalentMessage(ab))
elseif ab.type[1]:find("^spell/") then
game.logSeen(self, "%s casts %s.", self.name:capitalize(), ab.name)
else
game.logSeen(self, "%s uses %s.", self.name:capitalize(), ab.name)
end
if not self:enoughEnergy() then return end
if ab.mana and self:getMana() < ab.mana then
game.logPlayer(self, "You do not have enough mana to cast %s.", ab.name)
return
end
if ab.stamina and self:getStamina() < ab.stamina then
game.logPlayer(self, "You do not have enough stamina to use %s.", ab.name)
return
end
if ab.message then
game.logSeen(self, "%s", self:useTalentMessage(ab))
elseif ab.type[1]:find("^spell/") then
game.logSeen(self, "%s casts %s.", self.name:capitalize(), ab.name)
else
game.logSeen(self, "%s uses %s.", self.name:capitalize(), ab.name)
end
return ret
return true
end
--- Called before a talent is used
......@@ -106,5 +120,13 @@ end
function _M:postUseTalent(ab, ret)
if ret == nil then return end
self:useEnergy()
if ab.mana then
self:incMana(-ab.mana)
end
if ab.stamina then
self:incStamina(-ab.stamina)
end
return true
end
......@@ -11,6 +11,7 @@ local Level = require "engine.Level"
local Grid = require "engine.Grid"
local Actor = require "mod.class.Actor"
local ActorStats = require "engine.interface.ActorStats"
local ActorResource = require "engine.interface.ActorResource"
local ActorTalents = require "engine.interface.ActorTalents"
local Player = require "mod.class.Player"
local NPC = require "mod.class.NPC"
......@@ -39,6 +40,11 @@ end
function _M:run()
-- Damage types
DamageType:loadDefinition("/data/damage_types.lua")
-- Talents
ActorTalents:loadDefinition("/data/talents.lua")
-- Actor resources
ActorResource:defineResource("Mana", "mana", ActorTalents.T_MANA_POOL, "Mana represents your reserve of magical energies. Each spell cast consumes mana and each sustained spell reduces your maximun mana.")
ActorResource:defineResource("Stamina", "stamina", ActorTalents.T_STAMINA_POOL, "Stamina represents your physical fatigue. Each physical ability used reduces it.")
-- Actor stats
ActorStats:defineStat("Strength", "str", 10, 1, 100, "Strength defines your character's ability to apply physical force. It increases your melee damage, damage with heavy weapons, your chance to resist physical effects, and carrying capacity.")
ActorStats:defineStat("Dexterity", "dex", 10, 1, 100, "Dexterity defines your character's ability to be agile and alert. It increases your chance to hit, your ability to avoid attacks and your damage with light weapons.")
......@@ -46,8 +52,6 @@ function _M:run()
ActorStats:defineStat("Willpower", "wil", 10, 1, 100, "Willpower defines your character's ability to concentrate. It increases your mana and stamina capacity, and your chance to resist mental attacks.")
ActorStats:defineStat("Cunning", "cun", 10, 1, 100, "Cunning defines your character's ability to learn and think. It allows you to learn many wordly abilities, increases your mental resistance and armor penetration.")
ActorStats:defineStat("Constitution", "con", 10, 1, 100, "Constitution defines your character's ability to withstand and resist damage. It increases your maximun life and physical resistance.")
-- Talents
ActorTalents:loadDefinition("/data/talents.lua")
self.log = LogDisplay.new(0, self.h * 0.80, self.w * 0.5, self.h * 0.20, nil, nil, nil, {255,255,255}, {30,30,30})
self.player_display = PlayerDisplay.new(0, 0, self.w * 0.2, self.h * 0.8, {30,30,0})
......@@ -58,6 +62,7 @@ function _M:run()
self.log("Welcome to #00FF00#Tales of Middle Earth!")
self.logSeen = function(e, ...) if e and self.level.map.seens(e.x, e.y) then self.log(...) end end
self.logPlayer = function(e, ...) if e == game.player then self.log(...) end end
-- Setup inputs
self:setupCommands()
......
......@@ -8,5 +8,6 @@ function _M:init(t)
end
function _M:act()
mod.class.Actor.act(self)
self:move(self.x + 1, self.y)
end
......@@ -21,6 +21,8 @@ function _M:move(x, y, force)
end
function _M:act()
mod.class.Actor.act(self)
game.paused = true
end
......
......@@ -25,7 +25,13 @@ function _M:display()
self.surface:drawColorString(self.font, "Level: #00ff00#"..game.player.level, 0, h, 255, 255, 255) h = h + self.font_h
self.surface:drawColorString(self.font, ("Exp: #00ff00#%2d%%"):format(100 * cur_exp / max_exp), 0, h, 255, 255, 255) h = h + self.font_h
h = h + self.font_h
self.surface:drawColorString(self.font, ("#c00000#Life: #00ff00#%d/%d"):format(game.player.life, game.player.max_life), 0, h, 255, 255, 255) h = h + self.font_h
self.surface:drawColorString(self.font, ("#c00000#Life: #00ff00#%d/%d"):format(game.player.life, game.player.max_life), 0, h, 255, 255, 255) h = h + self.font_h
if game.player:knowTalent(game.player.T_MANA_POOL) then
self.surface:drawColorString(self.font, ("#7fffd4#Mana: #00ff00#%d/%d"):format(game.player:getMana(), game.player.max_mana), 0, h, 255, 255, 255) h = h + self.font_h
end
if game.player:knowTalent(game.player.T_STAMINA_POOL) then
self.surface:drawColorString(self.font, ("#ffcc80#Stamina: #00ff00#%d/%d"):format(game.player:getMana(), game.player.max_mana), 0, h, 255, 255, 255) h = h + self.font_h
end
h = h + self.font_h
self.surface:drawColorString(self.font, ("STR: #00ff00#%3d"):format(game.player:getStr()), 0, h, 255, 255, 255) h = h + self.font_h
self.surface:drawColorString(self.font, ("DEX: #00ff00#%3d"):format(game.player:getDex()), 0, h, 255, 255, 255) h = h + self.font_h
......
......@@ -51,7 +51,8 @@ newTalent{
newTalent{
name = "Disruption Shield",
type = {"spell/arcane",2},
mana = 80,
mode = "sustained",
sustain_mana = 60,
tactical = {
DEFEND = 10,
},
......@@ -87,7 +88,8 @@ newTalent{
newTalent{
name = "Fireflash",
type = {"spell/fire",2},
mana = 45,
mana = 35,
cooldown = 6,
tactical = {
ATTACKAREA = 10,
},
......@@ -101,6 +103,7 @@ newTalent{
require = { stat = { mag=16 }, },
info = function(self)
return ([[Conjures up a flash of fire doing %0.2f fire damage in a radius of %d.
Cooldown: 6 turns
The damage will increase with the Magic stat]]):format(8 + self:getMag(70), math.min(6, 3 + self:getMag(6)))
end,
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment