Knocking targets to the side

All development conversation and discussion takes place here

Moderator: Moderator

Post Reply
Message
Author
Razakai
Uruivellas
Posts: 889
Joined: Tue May 14, 2013 3:45 pm

Knocking targets to the side

#1 Post by Razakai »

I've got a talent that fires a beam that knocks targets aside, so I used the You Shall Be My Weapon code as a base. However I'm getting a few errors, seemingly at random. Sometimes it'll work, sometimes not. The errors vary but they're typically relating to the coordToDir function. Error and code below:

Code: Select all

Lua Error: /engine/interface/GameTargeting.lua:118: /engine/interface/ActorTalents.lua:148: /data-fury/talents/techniques/titan.lua:188: attempt to index local 'sides' (a nil value)
stack traceback:
	/data-fury/talents/techniques/titan.lua:188: in function 'damtype'
	/engine/interface/ActorProject.lua:217: in function 'project'
	/data-fury/talents/techniques/titan.lua:179: in function </data-fury/talents/techniques/titan.lua:171>
	[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 

Code: Select all

newTalent{
	name = "Earthbreaker",
	type = {"technique/titan", 4},
	require = techs_str_req_high4,
	points = 5,
	random_ego = "attack",
	stamina = 40,
	cooldown = 15,
	tactical = { ATTACK = {PHYSICAL = 4 },  },
	direct_hit = true,
	requires_target = true,
	target = function(self, t)
		return {type="beam", range=self:getTalentRange(t), friendlyfire=false, talent=t}
	end,
	getDamage = function(self, t) return self:combatTalentWeaponDamage(t, 1.8, 2.7) end,
	getExplosionDamage = function(self,t) return self:combatTalentStatDamage(t, "str", 20, 240) end,
	range = function(self, t) return math.ceil(self:combatTalentScale(t, 3, 7)) end,
	action = function(self, t)
		local tg = self:getTalentTarget(t)
		local x, y = self:getTarget(tg)
		if not x or not y then return nil end
		local _ _, x, y = self:canProject(tg, x, y)
		
		local dam = t.getDamage(self, t)

		grids = self:project(tg, x, y, function(px, py)
			local target = game.level.map(px, py, engine.Map.ACTOR)
			if not target then return end
			local hit = self:attackTarget(target, nil, dam, true)
			if hit then
				local dx, dy = (target.x - self.x), (target.y - self.y)
				local dir = util.coordToDir(dx, dy, 0)
				local sides = util.dirSides(dir, 0)
		
				local d = rng.chance(2) and sides.hard_left or sides.hard_right
				local sx, sy = util.coordAddDir(target.x, target.y, d)
				if target:canBe("knockback") then target:knockback(sx, sy, 2, function(t3) return true end) end
			end
		end)

		for px, ys in pairs(grids) do
			for py, _ in pairs(ys) do
				local oe = game.level.map(px, py, Map.TERRAIN)
				if not oe or oe.special then return end
				if not oe or oe:attr("temporary") or game.level.map:checkAllEntities(px, py, "block_move") then return end
					local e = Object.new{
						old_feat = oe,
						name = "trembling stone", image = "terrain/rocky_mountain.png",
						display = '#', color_r=255, color_g=255, color_b=255, back_color=colors.GREY,
						desc = "a trembling stone",
						type = "wall", --subtype = "floor",
						always_remember = true,
						can_pass = {pass_wall=1},
						does_block_move = true,
						show_tooltip = true,
						block_move = true,
						block_sight = true,
						temporary = 5,
						x = px, y = py,
						canAct = false,
						act = function(self, src, x, y)
							self:useEnergy()
							self.temporary = self.temporary - 1
							if self.temporary <= 0 then
								game.level.map(self.x, self.y, engine.Map.TERRAIN, self.old_feat)
								--local self = game.level.map(x, y, engine.Map.TERRAIN)
								local t = self.summoner:getTalentFromId(self.summoner.T_EARTHBREAKER)
								local tg = {type="ball", range=0, radius = 1, friendlyfire=false, talent=t, x=self.x, y=self.y}
								self.summoner.__project_source = self
								self.summoner:project(tg, self.x, self.y, engine.DamageType.PHYSICAL, t.getExplosionDamage(self.summoner, t))
								self.summoner.__project_source = nil
								game.level.map:particleEmitter(x, y, tg.radius, "ball_earth", {radius=tg.radius})		
								game.nicer_tiles:updateAround(game.level, self.x, self.y)
								game.level:removeEntity(self)								
								game.level.map:scheduleRedisplay()
							end
						end,
						summoner_gain_exp = true,
						summoner = self,
					}
				e.tooltip = mod.class.Grid.tooltip
				game.level:addEntity(e)
				game.level.map(px, py, Map.TERRAIN, e)
				end
		end
		
		game:playSoundNear(self, "talents/spell_earth")		
		return true
	end,
	info = function(self, t)
		weapondam = t.getDamage(self,t)
		dam = t.getExplosionDamage(self,t)
		return ([[Focus your strength into a single almighty blow that ruptures the ground in a line, inflicting %d%% weapon damage, shoving targets to the side and creating stone walls in the affected tiles. 
These walls persist for 5 turns and then shatter, showering adjacent enemies with shrapnel dealing %0.2f physical damage.]]):
		format(weapondam*100, damDesc(self, DamageType.PHYSICAL, dam))
	end,
}

HousePet
Perspiring Physicist
Posts: 6215
Joined: Sun Sep 09, 2012 7:43 am

Re: Knocking targets to the side

#2 Post by HousePet »

Are there targets dying from your attack before you try to knock them aside?
My feedback meter decays into coding. Give me feedback and I make mods.

Post Reply