Skip to content
Snippets Groups Projects
Commit 8dd5f2a3 authored by dg's avatar dg
Browse files

Fyrk got more life

more alchemy
Staves do elemental damage
resolvers.rngtable{} added
If actors die from a DOT they wont act upon their death


git-svn-id: http://svn.net-core.org/repos/t-engine4@895 51575b47-30f0-44d4-a5cc-537603b46e54
parent 07a7f986
No related branches found
No related tags found
No related merge requests found
Showing
with 199 additions and 12 deletions
......@@ -36,6 +36,14 @@ function resolvers.calc.rngavg(t)
return rng.avg(t[1], t[2])
end
--- Random table element
function resolvers.rngtable(t)
return {__resolver="rngtable", t}
end
function resolvers.calc.rngtable(t)
return rng.table(t[1])
end
--- Random bonus based on level
resolvers.current_level = 1
resolvers.mbonus_max_level = 50
......
......@@ -194,6 +194,9 @@ function _M:act()
-- Still enough energy to act ?
if self.energy.value < game.energy_to_act then return false end
-- Still not dead ?
if self.dead then return false end
return true
end
......
......@@ -100,6 +100,9 @@ function _M:descAttribute(attr)
elseif attr == "COMBAT" then
local c = self.combat
return c.dam.."-"..(c.dam*(c.damrange or 1.1)).." power, "..(c.apr or 0).." apr"
elseif attr == "COMBAT_DAMTYPE" then
local c = self.combat
return c.dam.."-"..(c.dam*(c.damrange or 1.1)).." power, "..(c.apr or 0).." apr, "..DamageType:get(c.damtype).name.." damage"
elseif attr == "ARMOR" then
return (self.wielder and self.wielder.combat_def or 0).." def, "..(self.wielder and self.wielder.combat_armor or 0).." armor"
elseif attr == "ATTACK" then
......@@ -161,13 +164,13 @@ function _M:getTextualDesc()
-- Stop here if unided
if not self:isIdentified() then return table.concat(desc, "\n") end
if self.combat then
local dm = {}
for stat, i in pairs(self.combat.dammod or {}) do
dm[#dm+1] = ("+%d%% %s"):format(i * 100, Stats.stats_def[stat].name)
end
desc[#desc+1] = ("%d Power [Range %0.2f] (%s), %d Attack, %d Armor Penetration, Crit %d%%"):format(self.combat.dam or 0, self.combat.damrange or 1.1, table.concat(dm, ','), self.combat.atk or 0, self.combat.apr or 0, self.combat.physcrit or 0)
desc[#desc+1] = "Damage type: "..DamageType:get(self.combat.damtype or DamageType.PHYSICAL).name
if self.combat.range then desc[#desc+1] = "Firing range: "..self.combat.range end
desc[#desc+1] = ""
end
......@@ -275,7 +278,7 @@ function _M:getTextualDesc()
local use_desc = self:getUseDesc()
if use_desc then desc[#desc+1] = use_desc end
return table.concat(desc, "\n ")
return desc
end
--- Gets the full desc of the object
......@@ -293,7 +296,7 @@ function _M:getDesc()
desc[#desc+1] = reqs
end
local textdesc = self:getTextualDesc()
local textdesc = table.concat(self:getTextualDesc(), "\n")
return table.concat(desc, "\n").."\n"..textdesc
end
......
......@@ -364,8 +364,9 @@ local weapon_talents = {
axe = Talents.T_AXE_MASTERY,
mace = Talents.T_MACE_MASTERY,
knife = Talents.T_KNIFE_MASTERY,
bow = Talents.T_BOW_MASTERY,
bow = Talents.T_BOW_MASTERY,
sling = Talents.T_SLING_MASTERY,
staff = Talents.T_STAFF_MASTERY,
}
--- Checks weapon training
......@@ -595,6 +596,16 @@ function _M:hasAlchemistWeapon()
return ammo
end
--- Check if the actor has a two handed weapon
function _M:hasTwoStaffWeapon()
if not self:getInven("MAINHAND") then return end
local weapon = self:getInven("MAINHAND")[1]
if not weapon or weapon.subtype ~= "staff" then
return nil
end
return weapon
end
--- Check if the actor has a two handed weapon
function _M:hasTwoHandedWeapon()
if not self:getInven("MAINHAND") then return end
......
......@@ -22,10 +22,16 @@ newEntity{
slot = "MAINHAND",
slot_forbid = "OFFHAND",
type = "weapon", subtype="staff",
add_name = " (#COMBAT#)",
add_name = " (#COMBAT_DAMTYPE#)",
display = "\\", color=colors.LIGHT_RED,
encumber = 5,
rarity = 4,
combat = {
talented = "staff",
damrange = 1.2,
sound = "actions/melee", sound_miss = "actions/melee_miss",
damtype = resolvers.rngtable{DamageType.FIRE, DamageType.COLD, DamageType.ACID, DamageType.LIGHTNING, DamageType.LIGHT, DamageType.DARKNESS, DamageType.NATURE, DamageType.BLIGHT},
},
desc = [[Staves designed for wielders of magic, by the greats of the art.]],
egos = "/data/general/objects/egos/staves.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) },
}
......
......@@ -106,7 +106,7 @@ newTalent{
},
activate = function(self, t)
game:playSoundNear(self, "talents/spell_generic")
local power = math.floor(self:combatTalentSpellDamage(t, 2, 18))
local power = math.min(math.floor(self:combatTalentSpellDamage(t, 2, 10)), 11)
return {
stats = self:addTemporaryValue("inc_stats", {
[self.STAT_STR] = power,
......@@ -124,6 +124,6 @@ newTalent{
end,
info = function(self, t)
return ([[You concentrate on your inner self, increasing your stats each by %d.]]):
format(self:combatTalentSpellDamage(t, 2, 18))
format(math.min(math.floor(self:combatTalentSpellDamage(t, 2, 10)), 11))
end,
}
......@@ -39,6 +39,8 @@ local function makeGolem()
open_door = true,
blind_immune = 1,
fear_immune = 1,
poison_immune = 1,
disease_immune = 1,
see_invisible = 2,
no_breath = 1,
}
......@@ -81,7 +83,7 @@ newTalent{
-- Find space
local x, y = util.findFreeGrid(self.x, self.y, 5, true, {[Map.ACTOR]=true})
if not x then
game.logPlayer(self, "Not enough space to summon!")
game.logPlayer(self, "Not enough space to refit!")
return
end
game.zone:addEntity(game.level, self.alchemy_golem, "actor", x, y)
......@@ -247,10 +249,24 @@ newTalent{
mana = 10,
cooldown = 20,
action = function(self, t)
if not game.level:hasEntity(self.alchemy_golem) then
game.logPlayer(self, "Your golem is currently inactive.")
return
end
-- Find space
local x, y = util.findFreeGrid(self.x, self.y, 5, true, {[Map.ACTOR]=true})
if not x then
game.logPlayer(self, "Not enough space to invoke!")
return
end
self.alchemy_golem:setEffect(self.alchemy_golem.EFF_MIGHTY_BLOWS, 5, {power=self:combatTalentSpellDamage(t, 15, 50)})
self.alchemy_golem:move(x, y, true)
game:playSoundNear(self, "talents/arcane")
return true
end,
info = function(self, t)
return ([[Imbue an alchemist gem with an explosive charge of mana and throw it.]]):format()
return ([[You invoke your golem to your side, granting it a temporary melee power increase of %d for 5 turns.]]):format(self:combatTalentSpellDamage(t, 15, 50))
end,
}
......@@ -40,6 +40,7 @@ newTalentType{ type="spell/golemancy", name = "golemancy", description = "Learn
newTalentType{ type="spell/advanced-golemancy", name = "advanced-golemancy", description = "Advanced golem operations." }
newTalentType{ type="spell/gemology", name = "gemology", generic = true, description = "Manipulate gems, imbue their powers into other objects." }
newTalentType{ type="spell/herbalism", name = "herbalism", generic = true, description = "Herbs lore." }
newTalentType{ type="spell/staff-combat", name = "staff combat", generic = true, description = "Harness the power of magical staves." }
-- Generic requires for spells based on talent level
spells_req1 = {
......@@ -79,3 +80,4 @@ load("/data/talents/spells/enhancement.lua")
load("/data/talents/spells/alchemy.lua")
load("/data/talents/spells/infusion.lua")
load("/data/talents/spells/golemancy.lua")
load("/data/talents/spells/staff-combat.lua")
-- ToME - Tales of Middle-Earth
-- 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
newTalent{
name = "Channel Staff",
type = {"spell/staff-combat", 1},
require = spells_req1,
points = 5,
mana = 5,
tactical = {
ATTACK = 10,
},
range = 10,
reflectable = true,
action = function(self, t)
local weapon = self:hasTwoStaffWeapon()
if not weapon then
game.logPlayer(self, "You need a staff to use this spell.")
return
end
local tg = {type="bolt", range=self:getTalentRange(t), talent=t}
local x, y = self:getTarget(tg)
if not x or not y then return nil end
local dam = self:combatDamage(weapon) * self:combatTalentWeaponDamage(t, 0.4, 1.1)
self:project(tg, x, y, weapon.combat.damtype or DamageType.ARCANE, self:spellCrit(dam), {type="manathrust"})
game:playSoundNear(self, "talents/arcane")
return true
end,
info = function(self, t)
return ([[Channel raw mana through your staff, projecting a bolt your staff damage type doing %d%% staff damage.
This attack always hits and ignores target armour.]]):
format(self:combatTalentWeaponDamage(t, 0.4, 1.1) * 100)
end,
}
newTalent{
name = "Staff Mastery",
type = {"spell/staff-combat", 2},
mode = "passive",
require = spells_req2,
points = 5,
info = function(self, t)
return ([[Increases damage done with staves by %d%%.]]):format(100 * (math.sqrt(self:getTalentLevel(t) / 10)))
end,
}
newTalent{
name = "Defensive Posture",
type = {"spell/staff-combat", 3},
require = spells_req3,
mode = "sustained",
points = 5,
sustain_mana = 80,
cooldown = 30,
tactical = {
DEFEND = 20,
},
activate = function(self, t)
local power = self:combatTalentSpellDamage(t, 10, 20)
game:playSoundNear(self, "talents/arcane")
return {
power = self:addTemporaryValue("combat_def", power),
}
end,
deactivate = function(self, t, p)
self:removeTemporaryValue("combat_def", p.power)
return true
end,
info = function(self, t)
return ([[Adopt a defensive posture, reducing your staff attack power by %d and increasing your defense by %d.
The mana restored will increase with the Magic stat]]):format(self:combatTalentSpellDamage(t, 20, 230))
end,
}
newTalent{
name = "Disruption Shield",
type = {"spell/staff-combat",4},
require = spells_req4, no_sustain_autoreset = true,
points = 5,
mode = "sustained",
sustain_mana = 150,
tactical = {
DEFEND = 10,
},
activate = function(self, t)
local power = math.max(0.8, 3 - (self:combatSpellpower(1) * self:getTalentLevel(t)) / 280)
self.disruption_shield_absorb = 0
game:playSoundNear(self, "talents/arcane")
return {
shield = self:addTemporaryValue("disruption_shield", power),
particle = self:addParticles(Particles.new("disruption_shield", 1)),
}
end,
deactivate = function(self, t, p)
self:removeParticles(p.particle)
self:removeTemporaryValue("disruption_shield", p.shield)
self.disruption_shield_absorb = nil
return true
end,
info = function(self, t)
return ([[Uses mana instead of life to take damage. Uses %0.2f mana per damage point taken.
If your mana is brought too low by the shield, it will de-activate and the chain reaction will release a deadly arcane explosion of the amount of damage absorbed.
The damage to mana ratio increases with the Magic stat]]):format(math.max(0.8, 3 - (self:combatSpellpower(1) * self:getTalentLevel(t)) / 280))
end,
}
......@@ -652,6 +652,22 @@ newEffect{
end,
}
newEffect{
name = "MIGHTY_BLOWS",
desc = "Migth Blows",
type = "physical",
status = "beneficial",
parameters = { power=10 },
on_gain = function(self, err) return "#Target# looks menacing." end,
on_lose = function(self, err) return "#Target# looks less menacing." end,
activate = function(self, eff)
eff.tmpid = self:addTemporaryValue("combat_dam", eff.power)
end,
deactivate = function(self, eff)
self:removeTemporaryValue("combat_dam", eff.tmpid)
end,
}
newEffect{
name = "ROTTING_DISEASE",
desc = "Rotting Disease",
......
......@@ -265,7 +265,7 @@ newEntity{ base = "BASE_NPC_FAEROS", define_as = "FYRK",
This one looks even nastier and looks toward you with what seems to be disdain. Flames swirly all around him.]],
level_range = {35, nil}, exp_worth = 2,
rank = 5,
max_life = resolvers.rngavg(300,400), life_rating = 20, fixed_rating = true,
max_life = resolvers.rngavg(800,900), life_rating = 20, fixed_rating = true,
combat_armor = 0, combat_def = 20,
on_melee_hit = { [DamageType.FIRE] = resolvers.mbonus(30, 10), },
move_others=true,
......
......@@ -388,7 +388,7 @@ function _M:dump()
if not self.filter or self.filter(o) then
local char = string.char(string.byte('a') + index)
nl(("%s) %s"):format(char, o:getName{force_id=true}))
nl((" %s"):format(o:getTextualDesc()))
nl((" %s"):format(table.concat(o:getTextualDesc(), "\n ")))
index = index + 1
end
end
......@@ -402,7 +402,7 @@ function _M:dump()
if not self.filter or self.filter(o) then
local char = string.char(string.byte('a') + item - 1)
nl(("%s) %s"):format(char, o:getName{force_id=true}))
nl((" %s"):format(o:getTextualDesc()))
nl((" %s"):format(table.concat(o:getTextualDesc(), "\n ")))
end
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