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

spells

git-svn-id: http://svn.net-core.org/repos/t-engine4@121 51575b47-30f0-44d4-a5cc-537603b46e54
parent b1c291b1
No related branches found
No related tags found
No related merge requests found
......@@ -160,3 +160,24 @@ function _M:removeTemporaryValue(prop, id, noupdate)
end
end
end
--- Increases/decreases an attribute
-- The attributes are just actor properties, but this ensures they are numbers and not booleans
-- thus making them compatible with temporary values system
-- @param prop the property to use
-- @param v the value to add, if nil this the function return
-- @param fix forces the value to v, do not add
-- @return nil if v was specified. If not then it returns the current value if it exists and is not 0 otherwise returns nil
function _M:attr(prop, v, fix)
if v then
if fix then self.prop = v
else self.prop = (self.prop or 0) + v
end
else
if self.prop and self.prop ~= 0 then
return self.prop
else
return nil
end
end
end
......@@ -14,6 +14,7 @@ function _M:loadDefinition(file)
setfenv(f, setmetatable({
DamageType = require("engine.DamageType"),
Talents = self,
Map = require("engine.Map"),
newTalent = function(t) self:newTalent(t) end,
newTalentType = function(t) self:newTalentType(t) end,
load = function(f) self:loadDefinition(f) end
......
......@@ -73,13 +73,31 @@ end
function _M:move(x, y, force)
local moved = false
if force or self:enoughEnergy() then
moved = engine.Actor.move(self, game.level.map, x, y, force)
-- Should we prob travel through walls ?
if not force and self:attr("prob_travel") and game.level.map:checkEntity(x, y, Map.TERRAIN, "block_move", self) then
moved = self:probabilityTravel(x, y)
else
moved = engine.Actor.move(self, game.level.map, x, y, force)
end
if not force and moved and not self.did_energy then self:useEnergy() end
end
self.did_energy = nil
return moved
end
function _M:probabilityTravel(x, y)
local dirx, diry = x - self.x, y - self.y
local tx, ty = x, y
while game.level.map:checkEntity(x, y, Map.TERRAIN, "block_move", self) do
tx = tx + dirx
ty = ty + diry
end
if game.level.map:isBound(x, y) then
return engine.Actor.move(self, game.level.map, tx, ty, false)
end
return true
end
function _M:tooltip()
return ("%s\n#00ffff#Level: %d\nExp: %d/%d\n#ff0000#HP: %d"):format(self.name, self.level, self.exp, self:getExpChart(self.level+1) or "---", self.life)
end
......
......@@ -89,7 +89,10 @@ function _M:getTarget(typ)
if coroutine.running() then
local msg
if type(typ) == "string" then msg, typ = typ, nil
elseif type(typ) == "table" then msg = typ.msg end
elseif type(typ) == "table" then
if typ.default_target then self.target.target.entity = typ.default_target end
msg = typ.msg
end
game:targetMode("exclusive", msg, coroutine.running(), typ)
return coroutine.yield()
end
......
......@@ -75,7 +75,8 @@ newTalent{
tactical = {
DEFEND = 10,
},
action = function(self)
activate = function(self)
game.log("IMPLEMENT ME!")
return true
end,
require = { stat = { mag=60 }, level=40 },
......
......@@ -2,26 +2,35 @@ newTalent{
name = "Phase Door",
type = {"spell/conveyance",1},
message = "@Source@ blinks.",
mana = 15,
cooldown = 9,
mana = 10,
cooldown = 8,
tactical = {
ESCAPE = 4,
},
action = function(self)
local target = self
if self:knowTalent(Talents.T_TARGETED_TELEPORT) then
local tx, ty = self:getTarget{default_target=self, type="hit", range=10}
if tx and ty then
target = game.level.map(tx, ty, Map.ACTOR) or self
end
end
local x, y = self.x, self.y
if self:knowTalent(self.T_TELEPORT_CONTROL) then
x, y = self:getTarget{type="ball", range=10 + self:combatSpellpower(0.1), radius=5 - self:combatSpellpower(0.04)}
if self:knowTalent(Talents.T_CONTROLLED_TELEPORT) then
x, y = self:getTarget{type="ball", range=10 + self:combatSpellpower(0.1), radius=5 - self:combatSpellpower(0.03)}
if not x then return nil end
-- Target code doesnot restrict the target coordinates to the range, it lets the poject function do it
-- but we cant ...
x, y = game.target:pointAtRange(self.x, self.y, x, y, 10 + self:combatSpellpower(0.1))
self:teleportRandom(x, y, 5 - self:combatSpellpower(0.4))
target:teleportRandom(x, y, 5 - self:combatSpellpower(0.03))
else
self:teleportRandom(x, y, 10 + self:combatSpellpower(0.1))
target:teleportRandom(x, y, 10 + self:combatSpellpower(0.1))
end
return true
end,
require = { stat = { mag=12 }, },
require = { stat = { mag=15 }, },
info = function(self)
return ([[Teleports you randomly on a small scale range (%d)
The range will increase with the Magic stat]]):format(10 + self:combatSpellpower(0.1))
......@@ -29,12 +38,133 @@ newTalent{
}
newTalent{
name = "Teleport Control",
name = "Teleport",
type = {"spell/conveyance",2},
message = "@Source@ teleports away.",
mana = 20,
cooldown = 30,
tactical = {
ESCAPE = 8,
},
action = function(self)
local target = self
if self:knowTalent(Talents.T_TARGETED_TELEPORT) then
local tx, ty = self:getTarget{default_target=self, type="hit", range=10}
if tx and ty then
target = game.level.map(tx, ty, Map.ACTOR) or self
end
end
local x, y = self.x, self.y
if self:knowTalent(Talents.T_CONTROLLED_TELEPORT) then
x, y = self:getTarget{type="ball", range=100 + self:combatSpellpower(1), radius=5 - self:combatSpellpower(0.03)}
if not x then return nil end
-- Target code doesnot restrict the target coordinates to the range, it lets the poject function do it
-- but we cant ...
x, y = game.target:pointAtRange(self.x, self.y, x, y, 10 + self:combatSpellpower(0.1))
target:teleportRandom(x, y, 5 - self:combatSpellpower(0.03))
else
target:teleportRandom(x, y, 100 + self:combatSpellpower(1))
end
return true
end,
require = { stat = { mag=24 }, },
info = function(self)
return ([[Teleports you randomly on a small scale range (%d)
The range will increase with the Magic stat]]):format(10 + self:combatSpellpower(0.1))
end,
}
newTalent{
name = "Controlled Teleport",
type = {"spell/conveyance",4},
mode = "passive",
require = { stat = { mag=38 }, },
points = 2,
require = { stat = { mag=50 }, talent = {Talents.T_TELEPORT}, },
info = function(self)
return ([[Allows teleport spells to specify a target area. You will blink in this radius randomly.
The radius (%d) of the target area decreases with Magic stat]]):format(5 - self:combatSpellpower(0.04))
The radius (%d) of the target area decreases with Magic stat]]):format(5 - self:combatSpellpower(0.03))
end,
}
newTalent{
name = "Targeted Teleport",
type = {"spell/conveyance",4},
mode = "passive",
require = { stat = { mag=50 }, talent = {Talents.T_TELEPORT}, },
info = function(self)
return ([[Allows teleport spells to specify the affected target, either you, allies or foes.]])
end,
}
newTalent{
name = "Probability Travel",
type = {"spell/conveyance",4},
mode = "sustained",
points = 2,
cooldown = 40,
sustain_mana = 100,
tactical = {
MOVEMENT = 20,
},
activate = function(self)
self:attr("prob_travel", 1)
return true
end,
deactivate = function(self)
self:attr("prob_travel", -1)
return true
end,
require = { stat = { mag=34 }, level=25 },
info = function(self)
return ([[When you hit a solid surface this spell tears down the laws of probability to make you instantly appear on the other side.]])
end,
}
newTalent{
name = "Recall",
type = {"spell/conveyance",3},
mana = 30,
cooldown = 10,
action = function(self)
--[[
local target = self
local tx, ty = self.x, self.y
if self:knowTalent(Talents.T_TELEKINESIS) or self:knowTalent(Talents.T_IMPERIOUS_SUMMON) then
local tx, ty = self:getTarget{default_target=self, type="hit", range=20}
if tx and ty then
target = game.level.map(tx, ty, Map.ACTOR) or self
end
end
if
]]
game.log("IMPLEMENT ME!")
return true
end,
require = { stat = { mag=34 }, },
info = function(self)
return ([[Recalls you to your home town after a few turns.]])
end,
}
newTalent{
name = "Telekinesis",
type = {"spell/conveyance",4},
mode = "passive",
require = { stat = { mag=50 }, },
info = function(self)
return ([[Recall can now target an object on the floor to teleport it to your inventory.]])
end,
}
newTalent{
name = "Imperious Summon",
type = {"spell/conveyance",4},
mode = "passive",
require = { stat = { mag=50 }, },
info = function(self)
return ([[Recall can now target your foes to teleport one to you.]])
end,
}
......@@ -72,33 +72,34 @@ function _M:learn(v)
end
end
function _M:learnTalent(t, v)
function _M:learnTalent(t_id, v)
local t = self.actor:getTalentFromId(t_id)
if v then
if self.actor.unused_talents == 0 then
if self.actor.unused_talents < t.points then
self:simplePopup("Not enough talent points", "You have no talent points left!")
return
end
if not self.actor:canLearnTalent(self.actor:getTalentFromId(t)) then
if not self.actor:canLearnTalent(t_id) then
self:simplePopup("Cannot learn talent", "Prerequisites not met!")
return
end
if self.actor:knowTalent(t) then
if self.actor:knowTalent(t_id) then
self:simplePopup("Already known", "You already know this talent!")
return
end
self.actor:learnTalent(t)
self.actor.unused_talents = self.actor.unused_talents - 1
self.actor:learnTalent(t_id)
self.actor.unused_talents = self.actor.unused_talents - t.points
else
if not self.actor:knowTalent(t) then
if not self.actor:knowTalent(t_id) then
self:simplePopup("Impossible", "You do not know this talent!")
return
end
if self.actor_dup:knowTalent(t) == true and self.actor:knowTalent(t) == true then
if self.actor_dup:knowTalent(t_id) == true and self.actor:knowTalent(t_id) == true then
self:simplePopup("Impossible", "You cannot unlearn talents!")
return
end
self.actor:unlearnTalent(t)
self.actor.unused_talents = self.actor.unused_talents + 1
self.actor:unlearnTalent(t_id)
self.actor.unused_talents = self.actor.unused_talents + t.points
end
self:generateList()
end
......
No preview for this file type
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