Skip to content
Snippets Groups Projects
Commit 6fd2715e authored by dg's avatar dg
Browse files

start talents learning screen

git-svn-id: http://svn.net-core.org/repos/t-engine4@69 51575b47-30f0-44d4-a5cc-537603b46e54
parent 1acb31d3
No related branches found
No related tags found
No related merge requests found
......@@ -113,9 +113,10 @@ function _M:drawHBorder(s, x, y, h)
end
end
function _M:drawSelectionList(s, x, y, hskip, list, sel)
function _M:drawSelectionList(s, x, y, hskip, list, sel, prop)
for i, v in ipairs(list) do
v = tostring(v)
if prop then v = tostring(v[prop])
else v = tostring(v) end
if sel == i then
s:drawColorString(self.font, v, x, y + (i-1) * hskip, 0, 255, 255)
else
......
......@@ -18,14 +18,11 @@ function _M:defineStat(name, short_name, default_value, min, max, desc)
min = min or 1,
max = max or 100,
})
self.stats_def[#self.stats_def].id = #self.stats_def
self.stats_def[short_name] = self.stats_def[#self.stats_def]
self["STAT_"..short_name:upper()] = #self.stats_def
self["get"..short_name:lower():capitalize()] = function(self, scale)
local val = self.stats[_M["STAT_"..short_name:upper()]]
if scale then
val = math.floor(val * scale / max)
end
return val
return self:getStat(_M["STAT_"..short_name:upper()], scale)
end
end
......@@ -59,8 +56,18 @@ end
-- Not that the engine also auto-defines stat specific methods on the form: self:getShortname().
-- If you stat short name is STR then it becomes getStr()
-- @param stat the stat id
function _M:getStat(stat)
return self.stats[stat]
-- @param scale a scaling factor, nil means max stat value
function _M:getStat(stat, scale)
local val
if type(stat) == "string" then
val = self.stats[_M.stats_def[stat].id]
else
val = self.stats[stat]
end
if scale then
val = math.floor(val * scale / _M.stats_def[stat].max)
end
return val
end
--- Notifies a change of stat value
......
......@@ -23,8 +23,9 @@ end
function _M:newTalentType(t)
assert(t.name, "no talent type name")
assert(t.type, "no talent type type")
t.talents = {}
table.insert(self.talents_types_def, t)
self.talents_types_def[t.type] = t
end
--- Defines one talent
......@@ -41,12 +42,17 @@ function _M:newTalent(t)
assert(t.info, "no talent info")
table.insert(self.talents_def, t)
t.id = #self.talents_def
self["T_"..t.short_name] = #self.talents_def
-- Register in the type
table.insert(self.talents_types_def[t.type[1]].talents, t)
end
--- Initialises stats with default values if needed
function _M:init(t)
self.talents = t.talents or {}
self.talents_types = t.talents_types or {}
end
--- Make the actor use the talent
......@@ -66,11 +72,19 @@ function _M:useTalent(id)
end
end
--- Replace some markers in a string with info on the talent
function _M:useTalentMessage(ab)
local str = ab.message
str = str:gsub("@Source@", self.name:capitalize())
str = str:gsub("@source@", self.name)
return str
end
--- Called before an talent is used
-- Redefine as needed
-- @param ab the talent (not the id, the table)
-- @return true to continue, false to stop
function _M:preUseTalent(ab)
function _M:preUseTalent(talent)
return true
end
......@@ -79,6 +93,63 @@ end
-- @param ab the talent (not the id, the table)
-- @param ret the return of the talent action
-- @return true to continue, false to stop
function _M:postUseTalent(ab, ret)
function _M:postUseTalent(talent, ret)
return true
end
--- Returns how many talents of this type the actor knows
function _M:numberKnownTalent(type)
local nb = 0
for id, _ in pairs(self.talents) do
local t = _M.talents_def[id]
if t.type[1] == type then nb = nb + 1 end
end
return nb
end
--- Actor learns a talent
-- @param t_id the id of the talent to learn
-- @return true if the talent was learnt, nil and an error message otherwise
function _M:learnTalent(t_id)
local t = _M.talents_def[t_id]
local ok, err = self:canLearnTalent(t)
if not ok and err then return nil, err end
self.talents[t_id] = true
return true
end
function _M:canLearnTalent(t)
-- Check prerequisites
if t.require then
-- Obviously this requires the ActorStats interface
if t.require.stat then
for s, v in pairs(t.require.stat) do
if self:getStat(s) < v then return nil, "not enough stat" end
end
end
if t.require.level and self.level < t.require.level then
return nil, "not enough levels"
end
end
-- Check talent type
local known = self:numberKnownTalent(t.type[1])
if known < t.type[1] - 1 then
return nil, "not enough talents of this type known"
end
-- Ok!
return true
end
--- Do we know this talent type
function _M:knowTalentType(t)
return self.talents_types[t]
end
--- Do we know this talent
function _M:knowTalent(t)
return self.talents[t]
end
......@@ -27,6 +27,7 @@ function _M:init(t)
self.unused_stats = 0
self.unused_talents = 0
self.unused_talents_types = 0
end
function _M:move(x, y, force)
......@@ -107,6 +108,13 @@ end
-- @return true to continue, false to stop
function _M:postUseTalent(ab, ret)
if ret == nil then 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
self:useEnergy()
return true
end
......@@ -25,6 +25,7 @@ local Calendar = require "engine.Calendar"
local QuitDialog = require "mod.dialogs.Quit"
local LevelupStatsDialog = require "mod.dialogs.LevelupStatsDialog"
local LevelupTalentsDialog = require "mod.dialogs.LevelupTalentsDialog"
module(..., package.seeall, class.inherit(engine.GameTurnBased))
......@@ -75,7 +76,10 @@ end
function _M:newGame()
self.zone = Zone.new("ancient_ruins")
self.player = Player.new{name=self.player_name, max_life=10000, image='player.png', display='@', color_r=230, color_g=230, color_b=230}
self.player = Player.new{
name=self.player_name, max_life=10000, image='player.png', display='@', color_r=230, color_g=230, color_b=230,
talents_types = {["spell/arcane"]=true,["spell/fire"]=true,["physical/1hweapon"]=true},
}
self:changeLevel(1)
end
......@@ -251,7 +255,8 @@ function _M:setupCommands()
end,
[{"_g","shift"}] = function()
local d = LevelupStatsDialog.new(self.player)
-- local d = LevelupStatsDialog.new(self.player)
local d = LevelupTalentsDialog.new(self.player)
self:registerDialog(d)
end,
......
......@@ -35,3 +35,9 @@ newDamageType{
newDamageType{
name = "lightning", type = "LIGHTNING",
}
newDamageType{
name = "light", type = "LIGHT",
projector = function(src, x, y, type, dam)
game.level.map.lites(x, y, true)
end,
}
-- Mana spells
newTalentType{ type="spell/arcane", name = "arcane" }
newTalentType{ type="spell/fire", name = "fire" }
newTalentType{ type="spell/earth", name = "earth" }
newTalentType{ type="spell/cold", name = "cold" }
newTalentType{ type="spell/lightning", name = "lightning" }
newTalentType{ type="spell/conveyance", name = "conveyance" }
newTalentType{ type="spell/arcane", name = "arcane", description = "Arcane manipulates the raw magic energies to shape them into both offensive and defensive spells." }
newTalentType{ type="spell/fire", name = "fire", description = "Harness the power of fire to burn your foes to ashes." }
newTalentType{ type="spell/earth", name = "earth", description = "Harness the power of the earth to protect and destroy." }
newTalentType{ type="spell/cold", name = "cold", description = "Harness the power of winter to shatter your foes." }
newTalentType{ type="spell/lightning", name = "lightning", description = "Harness the power of lightnings to fry your foes." }
newTalentType{ type="spell/conveyance", name = "conveyance", description = "Conveyance is the school of travel. It allows you to travel faster and to track others." }
newTalentType{ type="physical/2hweapon", name = "two handed weapons", description = "Allows the user to be more proficient with two handed weapons." }
newTalentType{ type="physical/1hweapon", name = "one handed weapons", description = "Allows the user to be more proficient with one handed weapons." }
newTalentType{ type="physical/dualweapon", name = "dual wielding", description = "Allows the user to be more proficient with dual wielding weapons." }
newTalentType{ type="physical/shield", name = "shields", description = "Allows the user to be more proficient with shields." }
newTalent{
name = "Manathrust",
type = "spell/arcane",
type = {"spell/arcane", 1},
mana = 10,
tactical = {
ATTACK = 10,
......@@ -26,10 +30,45 @@ newTalent{
The damage will increase with the Magic stat]]):format(10 + self:getMag())
end,
}
newTalent{
name = "Disruption Shield",
type = {"spell/arcane",2},
mana = 80,
tactical = {
DEFEND = 10,
},
action = function(self)
return true
end,
require = { stat = { mag=12 }, },
info = function(self)
return ([[Uses mana instead of life to take damage",
The damage to mana ratio increases with the Magic stat]]):format(10 + self:getMag())
end,
}
newTalent{
name = "Globe of Light",
type = {"spell/fire",1},
mana = 5,
tactical = {
ATTACKAREA = 3,
},
action = function(self)
local t = {type="ball", range=0, friendlyfire=false, radius=5 + self:getMag(10)}
self:project(t, self.x, self.y, DamageType.LIGHT, 1)
return true
end,
require = { stat = { mag=10 }, },
info = function(self)
return ([[Creates a globe of pure light with a radius of %d that illuminates the area.",
The radius will increase with the Magic stat]]):format(5 + self:getMag(10))
end,
}
newTalent{
name = "Fireflash",
type = "spell/fire",
type = {"spell/fire",2},
mana = 45,
tactical = {
ATTACKAREA = 10,
......@@ -50,7 +89,7 @@ newTalent{
newTalent{
name = "Phase Door",
type = "spell/conveyance",
type = {"spell/conveyance",1},
message = "@Source@ blinks.",
mana = 15,
tactical = {
......
......@@ -30,7 +30,7 @@ end
function _M:incStat(v)
if v == 1 then
if self.actor.unused_stats == 0 then
self:simplePopup("Not enough stat points", "You have no stat poins left!")
self:simplePopup("Not enough stat points", "You have no stat points left!")
return
end
else
......
require "engine.class"
require "engine.Dialog"
module(..., package.seeall, class.inherit(engine.Dialog))
function _M:init(actor)
self.actor = actor
self.actor_dup = actor:clone()
engine.Dialog.init(self, "Talents Levelup: "..actor.name, 800, 600)
-- Makes up the list
local list, known = {}, {}
for i, tt in ipairs(self.actor.talents_types_def) do
local cat = tt.type:gsub("/.*", "")
list[#list+1] = { name="<"..cat:capitalize().." / "..tt.name:capitalize()..">", type=tt.type }
if actor:knowTalentType(tt.type) then known[#known+1] = "known" else known[#known+1] = "unknown" end
-- Find all talents of this school
for j, t in ipairs(tt.talents) do
list[#list+1] = { name=" "..t.name, talent=t.id }
if actor:knowTalent(t.id) then known[#known+1] = "known" else known[#known+1] = "unknown" end
end
end
self.list = list
self.list_known = known
self.talentsel = 1
self:keyCommands{
_UP = function() self.talentsel = util.boundWrap(self.talentsel - 1, 1, #list) end,
_DOWN = function() self.talentsel = util.boundWrap(self.talentsel + 1, 1, #list) end,
-- _LEFT = function() self:incStat(-1) end,
-- _RIGHT = function() self:incStat(1) end,
_ESCAPE = function() game:unregisterDialog(self) end,
}
self:mouseZones{
{ x=2, y=45, w=350, h=self.font_h*#list, fct=function(button, x, y, xrel, yrel, tx, ty)
self.talentsel = 1 + math.floor(ty / self.font_h)
-- if button == "left" then self:incStat(1)
-- elseif button == "right" then self:incStat(-1)
-- end
end },
}
end
--[[
function _M:incStat(v)
if v == 1 then
if self.actor.unused_talents == 0 then
self:simplePopup("Not enough talent points", "You have no talent points left!")
return
end
else
if self.actor_dup:getStat(self.talentsel) == self.actor:getStat(self.talentsel) then
self:simplePopup("Impossible", "You cannot take out more points!")
return
end
end
self.actor:incStat(self.talentsel, v)
self.actor.unused_stats = self.actor.unused_stats - v
end
]]
function _M:drawDialog(s)
-- Description part
self:drawHBorder(s, self.iw / 2, 2, self.ih - 4)
--[=[
local statshelp = ([[Keyboard: #00FF00#up key/down key#FFFFFF# to select a stat; #00FF00#right key#FFFFFF# to increase stat; #00FF00#left key#FFFFFF# to decrease a stat.
Mouse: #00FF00#Left click#FFFFFF# to increase a stat; #00FF00#right click#FFFFFF# to decrease a stat.
]]):splitLines(self.iw / 2 - 10, self.font)
local lines = self.actor.talents_def[self.talentsel].description:splitLines(self.iw / 2 - 10, self.font)
for i = 1, #statshelp do
s:drawColorString(self.font, statshelp[i], self.iw / 2 + 5, 2 + (i-1) * self.font:lineSkip())
end
for i = 1, #lines do
s:drawColorString(self.font, lines[i], self.iw / 2 + 5, 2 + (i + #statshelp + 1) * self.font:lineSkip())
end
]=]
-- Talents
s:drawColorString(self.font, "Talents types points left: #00FF00#"..self.actor.unused_talents_types, 2, 2)
s:drawColorString(self.font, "Talents points left: #00FF00#"..self.actor.unused_talents, 2, 2 + self.font_h)
self:drawWBorder(s, 2, 40, 200)
self:drawSelectionList(s, 2, 45, self.font_h, self.list, self.talentsel, "name")
self:drawSelectionList(s, 300, 45, self.font_h, self.list_known, self.talentsel)
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