How hard is it to code LUA?
Posted: Fri Oct 19, 2012 6:58 am
I am a computer-programming idiot, but I was thinking of trying my hand at a couple of new Wyrmic trees. How do I set about learning to do this?
Everything about ToME
https://forums.te4.org/
A cursory examination of the Cursed talent "Stalk" indicates you probably want to make an "opponent seized" effect and add target checks to class/interface/Combat.lua's attackTargetWith() function. That would take care of the attack part. You'd probably need a second "seized" effect to put on the opponent to handle the defense reduction.Parcae2 wrote:1. I want to raise the wyrmic's attack and lower its defense with regard to the seized opponent, but ONLY that opponent. (Normally the Flight skill will radically reduce the wyrmic's attack and increase its defense and I want to get rid of those advantages/penalties).
The corruption talent "Bone Grab" makes a decent preliminary guide for pulling the opponent with you. Maybe an on_move() function for the Actor doing the seizing would be easiest? You should always have a free space available when moving, since you vacate one when you do. If you allow that teleportation or using the Wyrmic's digging talent will break the hold, then it greatly simplifies free space finding.Parcae2 wrote:2. I want the seized opponent to say next to the wyrmic at all times. In order to do this, I want to make the engine check whenever the wyrmic moves to see if there is a seized target next to it and, if so, to move the seized target next to the wyrmic's new position. If the wyrmic moves to a tile surrounded by opponents, I want the engine to make the seized opponent swap places with one of the other opponents so as to remain next to the wyrmic.
Maybe something like:Parcae2 wrote:I feel like there's something I need to add to make sure that the target is a neighboring actor with the Seized attribute.
Code: Select all
--Seizing a target?
if self:attr("seizing") then
if tg.x and tg.y and math.abs(self.x - tg.x) <= 2 and math.abs(self.y - tg.y) <= 2 then
target:pull(self.x, self.y, tg.range)
else
-- disable the talent and remove effects if tg is too far away or non-existent
end
end)
return true
end,
I'm referring to the variable "tg" as used in your previously posted code. You can't pull a value out of a variable until you set it to one, so I'm assuming tg is a reference to the seized Actor, that it was stored in the seizer's effect, and that you retrieved it from that effect earlier in whatever function your code snippet comes from.Parcae2 wrote:I didn't understand that last sentence at all:/ I'm sorry!
Code: Select all
if self:hasEffect(self.EFF_SEIZING) then
-- find seized target and pull it towards actor when actor moves]
local tgts = {}
local grids = core.fov.circle_grids(self.x, self.y, self:3, true)
for x, yy in pairs(grids) do for y, _ in pairs(grids[x]) do
local a = game.level.map(x, y, Map.ACTOR)
if a and hasEffect(self.EFF_SEIZED) and (a.x and a.y and math.abs(self.x - a.x) <= 2 and math.abs(self.y - a.y) <= 2) then
a:pull(self.x, self.y, tg.range)
end
end
Code: Select all
newEffect{
name = "SEIZING", image = "talents/clinch.png",
desc = "Seizing",
long_desc = function(self, eff) return ("The target has seized an opponent and carried it away."):format() end,
type = "physical",
subtype = { grapple=true, },
status = "beneficial",
parameters = {},
on_gain = function(self, err) return "#Target# seizes its opponent!", "+Seizing" end,
on_lose = function(self, err) return "#Target# has released the hold.", "-Seizing" end,
on_timeout = function(self, eff)
local p = eff.trgt:hasEffect(eff.trgt.EFF_SEIZED)
if not p or p.src ~= self or core.fov.distance(self.x, self.y, eff.trgt.x, eff.trgt.y) > 1 or eff.trgt.dead or not game.level:hasEntity(eff.trgt) then
self:removeEffect(self.EFF_SEIZING)
end
end,
activate = function(self, eff)
end,
deactivate = function(self, eff)
end,
}
newEffect{
name = "SEIZED", image = "talents/grab.png",
desc = "Seized",
long_desc = function(self, eff) return ("The target has been carried off by a mighty wyrm to feed its young."):format(eff.power) end,
type = "physical",
subtype = { grapple=true, pin=true },
status = "detrimental",
parameters = {},
remove_on_clone = true,
on_gain = function(self, err) return "#Target# has been carried away!", "+Seized" end,
on_lose = function(self, err) return "#Target# is no longer being carried.", "-Seized" end,
activate = function(self, eff)
eff.tmpid = self:addTemporaryValue("never_move", 1)
end,
on_timeout = function(self, eff)
if core.fov.distance(self.x, self.y, eff.src.x, eff.src.y) > 1 or eff.src.dead or not game.level:hasEntity(eff.src) then
self:removeEffect(self.EFF_SEIZED)
end
end,
deactivate = function(self, eff)
self:removeTemporaryValue("never_move", eff.tmpid)
end,
}
Code: Select all
newTalent{
name = "Talon Seize",
type = {"wild-gift/flight", 2},
require = gifts_req2,
points = 5,
stamina = 100,
tactical = { ATTACK = 2, DISABLE = 2 },
getDuration = function(self, t) return 4 + math.floor(self:getTalentLevel(t)) end,
on_pre_use = function(self, t)
local p = self:isTalentActive(self.T_SOAR)
if not p then return end
return true
end,
requires_target = true,
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 core.fov.distance(self.x, self.y, x, y) > 1 then return nil end
local seized = false
-- seize the target
local hit = self:startSeizing(target)
return true
end,
info = function(self, t)
return ([[You seize an opponent from the ground.]])
end,
}
Code: Select all
function _M:startSeizing(target)
-- Breaks the grapple before reapplying
if self:hasEffect(self.EFF_SEIZING) then
self:removeEffect(self.EFF_SEIZING, true)
target:setEffect(target.EFF_SEIZED, {src=self}, true)
self:setEffect(self.EFF_SEIZING, {trgt=target}, true)
return true
elseif target:canBe("pin") then
target:setEffect(target.EFF_SEIZED, {src=self})
self:setEffect(self.EFF_SEIZING, {trgt=target})
return true
else
game.logSeen(target, "%s cannot be seized!", target.name:capitalize())
return false
end
end
Code: Select all
if not force and moved and (self.x ~= ox or self.y ~= oy) and not self.did_energy then