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

split classes

generic combat talents


git-svn-id: http://svn.net-core.org/repos/t-engine4@293 51575b47-30f0-44d4-a5cc-537603b46e54
parent 6e3fde1e
No related branches found
No related tags found
No related merge requests found
......@@ -227,22 +227,24 @@ end
function _M:canLearnTalent(t)
-- Check prerequisites
if t.require then
local req = t.require
if type(req) == "function" then req = req(self, t) end
local tlev = self:getTalentLevelRaw(t) + 1
-- Obviously this requires the ActorStats interface
if t.require.stat then
for s, v in pairs(t.require.stat) do
if req.stat then
for s, v in pairs(req.stat) do
v = util.getval(v, tlev)
if self:getStat(s) < v then return nil, "not enough stat" end
end
end
if t.require.level then
if self.level < util.getval(t.require.level, tlev) then
if req.level then
if self.level < util.getval(req.level, tlev) then
return nil, "not enough levels"
end
end
if t.require.talent then
for _, tid in ipairs(t.require.talent) do
if req.talent then
for _, tid in ipairs(req.talent) do
if not self:knowTalent(tid) then return nil, "missing dependency" end
end
end
......@@ -265,6 +267,7 @@ function _M:getTalentReqDesc(t_id, levmod)
local t = _M.talents_def[t_id]
local req = t.require
if not req then return "" end
if type(req) == "function" then req = req(self, t) end
local tlev = self:getTalentLevelRaw(t_id) + (levmod or 0)
......
......@@ -179,7 +179,14 @@ end
--- Gets the armor
function _M:combatArmor()
return self.combat_armor
local add = 0
if self:hasHeavyArmor() and self:knowTalent(self.T_HEAVY_ARMOUR_TRAINING) then
add = add + self:getTalentLevel(self.T_HEAVY_ARMOUR_TRAINING)
end
if self:hasMassiveArmor() and self:knowTalent(self.T_MASSIVE_ARMOUR_TRAINING) then
add = add + self:getTalentLevel(self.T_MASSIVE_ARMOUR_TRAINING)
end
return self.combat_armor + add
end
--- Gets the attack
......@@ -338,3 +345,23 @@ function _M:hasDualWeapon()
end
return weapon, offweapon
end
--- Check if the actor has a heavy armor
function _M:hasHeavyArmor()
if not self:getInven("BODY") then return end
local armor = self:getInven("BODY")[1]
if not armor or armor.subtype ~= "heavy" then
return nil
end
return shield
end
--- Check if the actor has a massive armor
function _M:hasMassiveArmor()
if not self:getInven("BODY") then return end
local armor = self:getInven("BODY")[1]
if not armor or armor.subtype ~= "massive" then
return nil
end
return shield
end
newBirthDescriptor{
type = "class",
name = "Mage",
desc = {
"The basic spellcaster with lots of different skills",
},
descriptor_choices =
{
subclass =
{
__ALL__ = "never",
["Arcane Blade"] = "allow",
Archmage = "allow",
},
},
talents = { [ActorTalents.T_MANA_POOL]=1, },
copy = {
max_life = 80,
life_rating = 7,
resolvers.equip{ id=true,
{type="weapon", subtype="staff", name="elm staff"},
{type="armor", subtype="cloth", name="robe"}
},
resolvers.inventory{ id=true,
{type="potion", subtype="potion", name="potion of lesser mana"},
{type="potion", subtype="potion", name="potion of lesser mana"},
},
resolvers.generic(function(e)
e.hotkey[10] = {"inventory", "potion of lesser mana"}
end),
},
talents_types = {
["spell/arcane"]={true, -0.3},
["spell/fire"]={true, -0.3},
["spell/earth"]={true, -0.3},
["spell/water"]={true, -0.3},
["spell/air"]={true, -0.3},
["spell/phantasm"]={true, -0.3},
["spell/temporal"]={true, -0.3},
["spell/meta"]={true, -0.3},
["spell/divination"]={true, -0.3},
["spell/conveyance"]={true, -0.3},
["spell/nature"]={true, -0.3},
["spell/necromancy"]={true, -0.3},
},
}
newBirthDescriptor{
type = "subclass",
name = "Archmage",
desc = {
"Archmages devote their whole life to the study of magic. What they lack in most other skills they make up with magic.",
},
stats = { mag=3, wil=2, cun=1, },
talents_types = {
["spell/arcane"]={true, 0.7},
["spell/fire"]={true, 0.7},
["spell/earth"]={true, 0.7},
["spell/water"]={true, 0.7},
["spell/air"]={true, 0.7},
["spell/phantasm"]={true, 0.7},
["spell/temporal"]={true, 0.7},
["spell/meta"]={true, 0.7},
["spell/divination"]={true, 0.7},
["spell/conveyance"]={true, 0.7},
["spell/nature"]={true, 0.7},
["spell/necromancy"]={true, 0.7},
},
talents = {
[ActorTalents.T_MANATHRUST] = 1,
[ActorTalents.T_FLAME] = 1,
[ActorTalents.T_FREEZE] = 1,
},
}
newBirthDescriptor{
type = "subclass",
name = "Arcane Blade",
desc = {
"The Arcane Blade is a mage at heart but who can stand his own in a melee.",
},
stats = { mag=2, wil=1, str=2, dex=1},
talents_types = {
["spell/arcane"]={true, 0.3},
["spell/fire"]={true, 0.3},
["spell/earth"]={true, 0.3},
["spell/water"]={true, 0.3},
["spell/air"]={true, 0.3},
["spell/phantasm"]={true, 0.3},
["spell/temporal"]={false, 0.3},
["spell/meta"]={false, 0.3},
["spell/divination"]={true, 0.3},
["spell/conveyance"]={true, 0.3},
["spell/nature"]={true, 0.3},
["spell/necromancy"]={false, 0.3},
["technique/combat-training"]={true, 0},
["technique/weapon-training"]={true, 0},
},
talents = {
[ActorTalents.T_MANATHRUST] = 1,
[ActorTalents.T_FLAME] = 1,
[ActorTalents.T_WEAPON_COMBAT] = 1,
[ActorTalents.T_STAMINA_POOL]=1,
},
}
newBirthDescriptor{
type = "class",
name = "Rogue",
desc = {
"Rogues are masters of tricks, they can steal from shops and monsters",
"and lure monsters into deadly traps.",
},
descriptor_choices =
{
subclass =
{
__ALL__ = "never",
Rogue = "allow",
},
},
talents = { [ActorTalents.T_STAMINA_POOL]=1, },
copy = {
max_life = 100,
life_rating = 9,
equipment = resolvers.equip{ id=true,
{type="weapon", subtype="dagger", name="iron dagger"},
{type="weapon", subtype="dagger", name="iron dagger"},
{type="armor", subtype="light", name="rough leather armour"}
},
},
}
newBirthDescriptor{
type = "subclass",
name = "Rogue",
desc = {
"Rogues are masters of tricks, they can steal from shops and monsters",
"and lure monsters into deadly traps.",
},
stats = { dex=2, str=1, cun=3, },
talents_types = {
["technique/dualweapon-attack"]={true, 0.3},
["technique/dualweapon-training"]={true, 0.3},
["technique/combat-training"]={true, 0.2},
["technique/weapon-training"]={true, 0.2},
["cunning/stealth"]={true, 0.3},
["cunning/traps"]={true, 0.3},
["cunning/dirty"]={true, 0.3},
},
talents = {
[ActorTalents.T_STEALTH] = 1,
[ActorTalents.T_WEAPON_COMBAT] = 1,
[ActorTalents.T_KNIFE_MASTERY] = 1,
},
}
newBirthDescriptor{
type = "class",
name = "Warrior",
desc = {
"Simple fighters, they hack away with their trusty weapon.",
},
descriptor_choices =
{
subclass =
{
__ALL__ = "never",
Fighter = "allow",
Berserker = "allow",
},
},
talents = { [ActorTalents.T_STAMINA_POOL]=1, },
copy = {
max_life = 120,
life_rating = 10,
},
}
newBirthDescriptor{
type = "subclass",
name = "Fighter",
desc = {
"A warrior specializing in weapon and shield combat.",
},
stats = { str=3, con=2, dex=1, },
talents_types = {
["technique/shield-offense"]={true, 0.3},
["technique/shield-defense"]={true, 0.3},
["technique/2hweapon-offense"]={true, 0},
["technique/2hweapon-cripple"]={true, 0},
["technique/combat-training"]={true, 0.2},
["technique/weapon-training"]={true, 0.2},
},
talents = {
[ActorTalents.T_SHIELD_PUMMEL] = 1,
[ActorTalents.T_WEAPON_COMBAT] = 1,
[ActorTalents.T_HEAVY_ARMOUR_TRAINING] = 1,
},
copy = {
equipment = resolvers.equip{ id=true,
{type="weapon", subtype="longsword", name="iron longsword"},
{type="armor", subtype="shield", name="iron shield"},
{type="armor", subtype="heavy", name="iron mail armour"}
},
},
}
newBirthDescriptor{
type = "subclass",
name = "Berserker",
desc = {
"A warrior specializing in two handed weapon combat",
},
stats = { str=3, con=2, dex=1, },
talents_types = {
["technique/shield-offense"]={true, 0},
["technique/shield-defense"]={true, 0},
["technique/2hweapon-offense"]={true, 0.3},
["technique/2hweapon-cripple"]={true, 0.3},
["technique/combat-training"]={true, 0.2},
["technique/weapon-training"]={true, 0.2},
},
talents = {
[ActorTalents.T_BERSERKER] = 1,
[ActorTalents.T_WEAPON_COMBAT] = 1,
[ActorTalents.T_HEAVY_ARMOUR_TRAINING] = 1,
},
copy = {
equipment = resolvers.equip{ id=true,
{type="weapon", subtype="greatsword", name="iron greatsword"},
{type="armor", subtype="heavy", name="iron mail armour"}
},
},
}
......@@ -5,7 +5,8 @@ newTalent{
points = 5,
require = { stat = { str=18 }, },
info = function(self, t)
return [[Teaches the usage of heavy mail armours.]]
return ([[Teaches the usage of heavy mail armours. Increases amour value by %d when wearing a heavy mail armour.]]):
format(self:getTalentLevel(t))
end,
}
......@@ -16,7 +17,8 @@ newTalent{
points = 5,
require = { stat = { str=22 }, talent = { Talents.T_HEAVY_ARMOUR_TRAINING }, },
info = function(self, t)
return [[Teaches the usage of massive plate armours.]]
return ([[Teaches the usage of massive plate armours. Increases amour value by %d when wearing a massive plate armour.]]):
format(self:getTalentLevel(t))
end,
}
......@@ -25,7 +27,7 @@ newTalent{
type = {"technique/combat-training", 1},
mode = "passive",
points = 5,
require = { stat = { con=function(level) return 14 + level * 5 end }, },
require = { stat = { con=function(level) return 14 + level * 3 end }, },
on_learn = function(self, t)
self.max_life = self.max_life + 40
end,
......@@ -33,6 +35,60 @@ newTalent{
self.max_life = self.max_life - 40
end,
info = function(self, t)
return [[Increases your maximun life by 40 per talent level]]
return ([[Increases your maximun life by %d]]):format(40 * self:getTalentLevel(t))
end,
}
newTalent{
name = "Weapon Combat",
type = {"technique/combat-training", 1},
points = 10,
require = { level=function(level) return (level - 1) * 2 end },
mode = "passive",
info = function(self, t)
return [[Increases chances to hit with melee weapons.]]
end,
}
newTalent{
name = "Sword Mastery",
type = {"technique/combat-training", 1},
points = 10,
require = { stat = { str=function(level) return 12 + level * 3 end }, },
mode = "passive",
info = function(self, t)
return [[Increases damage with swords.]]
end,
}
newTalent{
name = "Axe Mastery",
type = {"technique/combat-training", 1},
points = 10,
require = { stat = { str=function(level) return 12 + level * 3 end }, },
mode = "passive",
info = function(self, t)
return [[Increases damage with axes.]]
end,
}
newTalent{
name = "Mace Mastery",
type = {"technique/combat-training", 1},
points = 10,
require = { stat = { str=function(level) return 14 + level * 3 end }, },
mode = "passive",
info = function(self, t)
return [[Increases damage with maces.]]
end,
}
newTalent{
name = "Knife Mastery",
type = {"technique/combat-training", 1},
points = 10,
require = { stat = { dex=function(level) return 10 + level * 3 end }, },
mode = "passive",
info = function(self, t)
return [[Increases damage with knifes.]]
end,
}
......@@ -52,6 +52,28 @@ techs_dex_req5 = {
level = function(level) return 16 + (level-1) end,
}
-- Generic rquires based either on str or dex
techs_strdex_req1 = function(self, t) local stat = self:getStr() >= self:getDex() and "str" or "dex"; return {
stat = { [stat]=function(level) return 12 + (level-1) * 2 end },
level = function(level) return 0 + (level-1) end,
} end
techs_strdex_req2 = function(self, t) local stat = self:getStr() >= self:getDex() and "str" or "dex"; return {
stat = { [stat]=function(level) return 20 + (level-1) * 2 end },
level = function(level) return 0 + (level-1) end,
} end
techs_strdex_req3 = function(self, t) local stat = self:getStr() >= self:getDex() and "str" or "dex"; return {
stat = { [stat]=function(level) return 28 + (level-1) * 2 end },
level = function(level) return 0 + (level-1) end,
} end
techs_strdex_req4 = function(self, t) local stat = self:getStr() >= self:getDex() and "str" or "dex"; return {
stat = { [stat]=function(level) return 36 + (level-1) * 2 end },
level = function(level) return 0 + (level-1) end,
} end
techs_strdex_req5 = function(self, t) local stat = self:getStr() >= self:getDex() and "str" or "dex"; return {
stat = { [stat]=function(level) return 44 + (level-1) * 2 end },
level = function(level) return 0 + (level-1) end,
} end
load("/data/talents/techniques/2hweapon.lua")
load("/data/talents/techniques/dualweapon.lua")
load("/data/talents/techniques/weaponshield.lua")
......
newTalent{
name = "Weapon Combat",
name = "Precise Striking",
type = {"technique/weapon-training", 1},
points = 10,
require = { level=function(level) return (level - 1) * 2 end },
mode = "passive",
info = function(self, t)
return [[Increases chances to hit with melee weapons.]]
mode = "sustained",
points = 5,
require = techs_strdex_req1,
cooldown = 30,
sustain_stamina = 30,
activate = function(self, t)
return {
speed = self:addTemporaryValue("combat_physspeed", 0.1 + self:getTalentLevel(t) / 20),
atk = self:addTemporaryValue("combat_atk", 4 + (self:getTalentLevel(t) * self:getDex()) / 15),
crit = self:addTemporaryValue("combat_physcrit", 4 + (self:getTalentLevel(t) * self:getDex()) / 25),
}
end,
deactivate = function(self, t, p)
self:removeTemporaryValue("combat_physspeed", p.speed)
self:removeTemporaryValue("combat_physcrit", p.crit)
self:removeTemporaryValue("combat_atk", p.atk)
return true
end,
}
newTalent{
name = "Sword Mastery",
type = {"technique/weapon-training", 1},
points = 10,
require = { stat = { str=function(level) return 12 + level * 3 end }, },
mode = "passive",
info = function(self, t)
return [[Increases damage with swords.]]
return ([[You focus your strikes, reducing your attack speed by %0.2f and increasing your attack by %d and critical chance by %d%%.]]):
format(0.1 + self:getTalentLevel(t) / 20, 4 + (self:getTalentLevel(t) * self:getDex()) / 15, 4 + (self:getTalentLevel(t) * self:getDex()) / 25)
end,
}
newTalent{
name = "Axe Mastery",
type = {"technique/weapon-training", 1},
points = 10,
require = { stat = { str=function(level) return 12 + level * 3 end }, },
mode = "passive",
name = "Blinding Speed",
type = {"technique/weapon-training", 2},
points = 5,
cooldown = 55,
stamina = 25,
require = techs_strdex_req2,
action = function(self, t)
self:setEffect(self.EFF_SPEED, 5, {power=1 + self:getTalentLevel(t) / 7})
return true
end,
info = function(self, t)
return [[Increases damage with axes.]]
return ([[Through rigorous training you have learned to focus your actions for a short while, increasing your speed by %0.2f for 5 turns.]]):format(1 + self:getTalentLevel(t) / 7)
end,
}
newTalent{
name = "Mace Mastery",
type = {"technique/weapon-training", 1},
points = 10,
require = { stat = { str=function(level) return 14 + level * 3 end }, },
mode = "passive",
name = "Perfect Strike",
type = {"technique/weapon-training", 3},
points = 5,
cooldown = 55,
stamina = 25,
require = techs_strdex_req3,
action = function(self, t)
self:setEffect(self.EFF_ATTACK, 1 + self:getTalentLevel(t), {power=100})
return true
end,
info = function(self, t)
return [[Increases damage with maces.]]
return ([[You have learned to focus your blows to hit your target, granting +100 attack for %d turns.]]):format(1 + self:getTalentLevel(t))
end,
}
newTalent{
name = "Knife Mastery",
type = {"technique/weapon-training", 1},
points = 10,
require = { stat = { dex=function(level) return 10 + level * 3 end }, },
mode = "passive",
name = "Rush",
type = {"technique/weapon-training", 4},
message = "@Source@ rushes out!",
require = techs_strdex_req4,
points = 5,
stamina = 45,
cooldown = 50,
tactical = {
ATTACK = 4,
},
range = function(self, t) return math.floor(5 + self:getTalentLevel(t)) end,
action = function(self, t)
local tg = {type="hit", range=self:getTalentRange(t)}
local x, y, target = self:getTarget(tg)
if not x or not y or not target then return nil end
if math.floor(core.fov.distance(self.x, self.y, x, y)) > self:getTalentRange(t) then return nil end
local l = line.new(self.x, self.y, x, y)
local lx, ly = l()
local tx, ty = lx, ly
lx, ly = l()
while lx and ly do
if game.level.map:checkAllEntities(lx, ly, "block_move", self) then break end
tx, ty = lx, ly
lx, ly = l()
end
self:move(tx, ty, true)
-- Attack ?
if math.floor(core.fov.distance(self.x, self.y, x, y)) == 1 then
self:attackTarget(target, nil, 1.2, true)
end
return true
end,
info = function(self, t)
return [[Increases damage with knifes.]]
return ([[Rushes toward your target with incredible speed. If the target is reached you get a free attack doing 120% weapon damage.]])
end,
}
......@@ -418,3 +418,19 @@ newEffect{
self:removeTemporaryValue("never_move", eff.tmpid)
end,
}
newEffect{
name = "ATTACK",
desc = "Attack",
type = "physical",
status = "beneficial",
parameters = { power=10 },
on_gain = function(self, err) return "#Target# aims carefully." end,
on_lose = function(self, err) return "#Target# aims less carefully." end,
activate = function(self, eff)
eff.tmpid = self:addTemporaryValue("combat_atk", eff.power)
end,
deactivate = function(self, eff)
self:removeTemporaryValue("combat_atk", eff.tmpid)
end,
}
No preview for this file type
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