Page 1 of 1

Error:Entity definition has a closure: realact has upvalue t

Posted: Thu May 14, 2015 8:25 pm
by Razakai
Since 1.3 one of my talents has been failing with an odd error. Could anyone point out where I might be going wrong?

Code: Select all

Lua Error: /engine/interface/GameTargeting.lua:118: /engine/interface/ActorTalents.lua:148: /engine/Entity.lua:110: Entity definition has a closure: realact has upvalue t
stack traceback:
	[C]: in function 'error'
	/engine/Entity.lua:110: in function 'init'
	/engine/Trap.lua:36: in function 'init'
	/mod/class/Trap.lua:39: in function 'init'
	/engine/class.lua:104: in function 'basetrap'
	...eternaldarkness/superload//data/talents/spells/grave.lua:188: in function <...eternaldarkness/superload//data/talents/spells/grave.lua:180>
	[C]: in function 'xpcall'
	/engine/interface/ActorTalents.lua:145: in function </engine/interface/ActorTalents.lua:138>
	At [C]:-1 
	At [C]:-1 error
	At /engine/interface/GameTargeting.lua:118 fct
	At /engine/interface/GameTargeting.lua:124 targetMode
	At /engine/interface/GameTargeting.lua:253 targetMouse
	At /mod/class/Game.lua:2113 fct
	At /engine/Mouse.lua:56 
Talent below:

Code: Select all

newTalent{
	name = "Corpselight",
	type = {"spell/grave", 3},
	require = spells_req3,
	mana = 30,
	points = 5,
	cooldown = 10,
	proj_speed = 3,
	range = 5,
	requires_target = true,
	tactical = { ATTACKAREA = { COLD = 2 } },
	target = function(self, t) return {type="hit", range=self:getTalentRange(t), talent=t, nowarning=true} end,
	getDamage = function(self, t) return self:combatTalentSpellDamage(t, 15, 80) end,
	getNb = function(self,t) return math.floor(self:combatTalentScale(t, 3, 5)) end,
	action = function(self, t)
		local tg = self:getTalentTarget(t)
		local x, y, target = self:getTarget(tg)
		if not x or not y then return nil end
		local _ _, x, y = self:canProject(tg, x, y)
		if game.level.map(x, y, Map.TRAP) then game.logPlayer(self, "You somehow fail to summon the corpselight.") return nil end
		if game.level.map:checkEntity(x, y, Map.TERRAIN, "block_move") then game.logPlayer(self, "You somehow fail to summon the corpselight.") return nil end

		local t = basetrap(self, t, x, y, 4, {
			type = "grave", name = "corpselight", color=colors.BLUE, image = "npc/undead_ghost_will_o__the_wisp.png",
			dam = self:spellCrit(t.getDamage(self, t)),
			nb = t.getNb(self,t),
			proj_speed = 2,
			triggered = function(self, x, y, who) return true, true end,
			combatSpellpower = function(self) return self.summoner:combatSpellpower() end,
			rad = 3,
			energy = {value=0, mod=1},
			detect_power = self:combatSpellpower() / 2,
			disarm_power = self:combatSpellpower() / 2,
			on_added = function(self, level, x, y)
				self.x, self.y = x, y
				local tries = {}
				local list = {i=1}
				local sa = rng.range(0, 359)
				local dir = rng.percent(50) and 1 or -1
				for a = sa, sa + 359 * dir, dir do
					local rx, ry = math.floor(math.cos(math.rad(a)) * self.rad), math.floor(math.sin(math.rad(a)) * self.rad)
					if not tries[rx] or not tries[rx][ry] then
						tries[rx] = tries[rx] or {}
						tries[rx][ry] = true
						list[#list+1] = {x=rx+x, y=ry+y}
					end
				end
				self.list = list
				self.on_added = nil
			end,
			disarmed = function(self, x, y, who)
				game.level:removeEntity(self, true)
			end,
			realact = function(self)
				if game.level.map(self.x, self.y, engine.Map.TRAP) ~= self then game.level:removeEntity(self, true) return end
				
				local x, y = self.list[self.list.i].x, self.list[self.list.i].y				
				self.list.i = util.boundWrap(self.list.i + 1, 1, #self.list)				
			
                local tgts = {}
                local grids = core.fov.circle_grids(self.x, self.y, 5, 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 self:reactionToward(a) < 0 then
                   tgts[#tgts+1] = a
                end
                end end

                local tg = {type="bolt", range=5, talent=t, friendlyblock=false, friendlyfire=false, display={particle="bolt_ice"}, start_x = self.x, start_y = self.y,}
                for i = 1, nb do
					if #tgts <= 0 then break end
					local a, id = rng.table(tgts)
					table.remove(tgts, id)				
					self.summoner:projectile(table.clone(tg), a.x, a.y, engine.DamageType.ICE, self.dam, {type="freeze"})
				end
			end,
		})
		t:identify(true)
		
		t:resolve() t:resolve(nil, true)		
		t:setKnown(self, true)		
		game.level:addEntity(t)		
		game.zone:addEntity(game.level, t, "trap", x, y)		
		game.level.map:particleEmitter(x, y, 1, "summon")
end,

	info = function(self, t)
		local dam = t.getDamage(self, t)
		local nb = t.getNb(self,t)
		return ([[Coalesce souls into an icy orb that fires bolts dealing %0.2f cold damage each turn at up to %d foes, with a 25%% chance to freeze.
		The orb will dissipate after 4 turns, and can potentially be destroyed if a foe moves through it.
		The damage will increase with your Spellpower.]]):
		format(damDesc(self, DamageType.COLD, dam), nb)
	end,
}

Re: Error:Entity definition has a closure: realact has upval

Posted: Thu May 14, 2015 11:09 pm
by HousePet
local tg = {type="bolt", range=5, talent=t, friendlyblock=false, friendlyfire=false, display={particle="bolt_ice"}, start_x = self.x, start_y = self.y,}
That t is not defined in the scope of realact. While it might be able to grab t from higher in the stack, you have also defined another local t as the trap, and should someone save and then load, that t would become nil.

Basically, variable nightmare with t there.

Re: Error:Entity definition has a closure: realact has upval

Posted: Sat May 16, 2015 9:21 pm
by Razakai
Fixed, thanks. Turns out I didn't even need that t, I must've copied it from somewhere.