Forked from
tome / Tales of MajEyal
13802 commits behind the upstream repository.
-
dg authored
TE4 can now handle multiple versions of the same engine (or even different ones). Engines are located in game/engines and the default one in game/engines/default Game engines can also come in archived form in a .teae zip file git-svn-id: http://svn.net-core.org/repos/t-engine4@1110 51575b47-30f0-44d4-a5cc-537603b46e54
dg authoredTE4 can now handle multiple versions of the same engine (or even different ones). Engines are located in game/engines and the default one in game/engines/default Game engines can also come in archived form in a .teae zip file git-svn-id: http://svn.net-core.org/repos/t-engine4@1110 51575b47-30f0-44d4-a5cc-537603b46e54
Birther.lua 7.77 KiB
-- TE4 - T-Engine 4
-- Copyright (C) 2009, 2010 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"
require "engine.Dialog"
module(..., package.seeall, class.inherit(engine.Dialog))
_M.birth_descriptor_def = {}
_M.birth_auto = {}
--- Defines birth descriptors
-- Static!
function _M:loadDefinition(file)
local f, err = loadfile(file)
if not f and err then error(err) os.exit() end
setfenv(f, setmetatable({
ActorTalents = require("engine.interface.ActorTalents"),
newBirthDescriptor = function(t) self:newBirthDescriptor(t) end,
setAuto = function(type, v) self.birth_auto[type] = v end,
load = function(f) self:loadDefinition(f) end
}, {__index=_G}))
f()
end
--- Defines one birth descriptor
-- Static!
function _M:newBirthDescriptor(t)
assert(t.name, "no birth name")
assert(t.type, "no birth type")
t.short_name = t.short_name or t.name
t.short_name = t.short_name:upper():gsub("[ ]", "_")
assert(t.desc, "no birth description")
if type(t.desc) == "table" then t.desc = table.concat(t.desc, "\n") end
t.desc = t.desc:gsub("\n\t+", "\n")
t.descriptor_choices = t.descriptor_choices or {}
table.insert(self.birth_descriptor_def, t)
t.id = #self.birth_descriptor_def
self.birth_descriptor_def[t.type] = self.birth_descriptor_def[t.type] or {}
self.birth_descriptor_def[t.type][t.name] = t
table.insert(self.birth_descriptor_def[t.type], t)
end
--- Instanciates a birther for the given actor
function _M:init(actor, order, at_end, quickbirth)
self.quickbirth = quickbirth
self.actor = actor
self.order = order
self.at_end = at_end
engine.Dialog.init(self, "Character Creation: "..actor.name, 600, 400)
self.descriptors = {}
self.cur_order = 1
self:next()
self:keyCommands({
_BACKSPACE = function() self:prev() end,
},{
MOVE_UP = function() self.sel = util.boundWrap(self.sel - 1, 1, #self.list); self.changed = true end,
MOVE_DOWN = function() self.sel = util.boundWrap(self.sel + 1, 1, #self.list); self.changed = true end,
ACCEPT = function() self:next() end,
})
self:mouseZones{
{ x=2, y=25, w=350, h=self.h, fct=function(button, x, y, xrel, yrel, tx, ty)
self.changed = true
if ty < self.font_h*#self.list then
self.sel = 1 + math.floor(ty / self.font_h)
if button == "left" then self:next()
elseif button == "right" then self:prev()
end
end
end },
}
end
function _M:on_register()
if self.quickbirth then
self:yesnoPopup("Quick Birth", "Do you want to recreate the same character?", function(ret)
if ret then
self.do_quickbirth = true
self:quickBirth()
end
end)
end
end
function _M:quickBirth()
if not self.do_quickbirth then return end
-- Aborth quickbirth if stage not found
if not self.quickbirth[self.current_type] then self.do_quickbirth = false end
-- Find the corect descriptor
for i, d in ipairs(self.list) do
if self.quickbirth[self.current_type] == d.name then
print("[QUICK BIRTH] using", d.name, "for", self.current_type)
self.sel = i
self:next()
return true
end
end
-- Abord if not found
self.do_quickbirth = false
end
function _M:selectType(type)
local default = 1
self.list = {}
-- Make up the list
print("[BIRTHER] selecting type", type)
for i, d in ipairs(self.birth_descriptor_def[type]) do
local allowed = true
print("[BIRTHER] checking allowance for ", d.name)
for j, od in ipairs(self.descriptors) do
if od.descriptor_choices[type] then
local what = util.getval(od.descriptor_choices[type][d.name]) or util.getval(od.descriptor_choices[type].__ALL__)
if what and what == "allow" then
allowed = true
elseif what and (what == "never" or what == "disallow") then
allowed = false
elseif what and what == "forbid" then
allowed = nil
end
print("[BIRTHER] test against ", od.name, "=>", what, allowed)
if allowed == nil then break end
end
end
-- Check it is allowed
if allowed then
table.insert(self.list, d)
if d.selection_default then default = #self.list end
end
end
self.sel = default
self.current_type = type
end
function _M:prev()
if self.cur_order == 1 then
if #self.list == 1 and self.birth_auto[self.current_type] ~= false then self:next() end
return
end
if not self.list then return end
self.changed = true
table.remove(self.descriptors)
self.cur_order = self.cur_order - 1
self:selectType(self.order[self.cur_order])
if #self.list == 1 then
self:prev()
end
end
function _M:next()
self.changed = true
if self.list then
table.insert(self.descriptors, self.list[self.sel])
if self.list[self.sel].on_select then self.list[self.sel]:on_select() end
self.cur_order = self.cur_order + 1
if not self.order[self.cur_order] then
game:unregisterDialog(self)
self:apply()
self.at_end()
return
end
end
self:selectType(self.order[self.cur_order])
if self:quickBirth() then return end
if #self.list == 1 and self.birth_auto[self.current_type] ~= false then
self:next()
end
end
--- Apply all birth options to the actor
function _M:apply()
self.actor.descriptor = {}
for i, d in ipairs(self.descriptors) do
print("[BIRTH] Applying descriptor "..d.name)
self.actor.descriptor[d.type] = d.name
if d.copy then
local copy = table.clone(d.copy, true)
-- Append array part
while #copy > 0 do
local f = table.remove(copy)
table.insert(self.actor, f)
end
-- Copy normal data
table.merge(self.actor, copy, true)
end
-- Change stats
if d.stats then
for stat, inc in pairs(d.stats) do
self.actor:incStat(stat, inc)
end
end
if d.talents_types then
for t, v in pairs(d.talents_types) do
local mastery
if type(v) == "table" then
v, mastery = v[1], v[2]
else
v, mastery = v, 0
end
self.actor:learnTalentType(t, v)
self.actor.talents_types_mastery[t] = (self.actor.talents_types_mastery[t] or 1) + mastery
print(t)
end
end
if d.talents then
for tid, lev in pairs(d.talents) do
for i = 1, lev do
self.actor:learnTalent(tid, true)
end
end
end
if d.experience then self.actor.exp_mod = self.actor.exp_mod * d.experience end
if d.body then
self.actor.body = d.body
self.actor:initBody()
end
end
end
function _M:drawDialog(s)
if not self.list or not self.list[self.sel] then return end
-- Description part
self:drawHBorder(s, self.iw / 2, 2, self.ih - 4)
local birthhelp = ([[Keyboard: #00FF00#up key/down key#FFFFFF# to select an option; #00FF00#Enter#FFFFFF# to accept; #00FF00#Backspace#FFFFFF# to go back.
Mouse: #00FF00#Left click#FFFFFF# to accept; #00FF00#right click#FFFFFF# to go back.
]]):splitLines(self.iw / 2 - 10, self.font)
for i = 1, #birthhelp do
s:drawColorStringBlended(self.font, birthhelp[i], self.iw / 2 + 5, 2 + (i-1) * self.font:lineSkip())
end
local lines = self.list[self.sel].desc:splitLines(self.iw / 2 - 10, self.font)
local r, g, b
for i = 1, #lines do
r, g, b = s:drawColorStringBlended(self.font, lines[i], self.iw / 2 + 5, 2 + (i + #birthhelp + 1) * self.font:lineSkip(), r, g, b)
end
-- Stats
s:drawColorStringBlended(self.font, "Selecting: "..self.current_type:capitalize(), 2, 2)
self:drawWBorder(s, 2, 20, 200)
self:drawSelectionList(s, 2, 25, self.font_h, self.list, self.sel, "name")
self.changed = false
end