Having a summon's on_die project from the summoner

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

Having a summon's on_die project from the summoner

#1 Post by Razakai »

I have a slightly complex talent. It creates a 'soul fragment' of the target (which is hostile to you, albeit defenseless), which if destroyed will cause damage to the original. Most of it works fine, except I can't quite figure out how to make the backlash damage work correctly. Currently it projects from the soul fragment, which has 0 spellpower/damage boosts and so does virtually no damage. Is there a good way of doing this that doesn't involve hacking in the summoner's spellpower/damage mods to get it right?

Code: Select all

soul_rend = function(self, target, duration, x, y)
	local m = mod.class.NPC.new{
			type = "undead", subtype = "ghost",
			display = "w", color=colors.BLACK, image = "npc/shadow-stalker.png",
			name = "soul fragment", faction = target.faction,
			desc = [[]],
			autolevel = "none",
			ai = "summoned", ai_real = "tactical", 	ai_state = { ai_move="move_complex", talent_in=3 },
			stats = { str=1, dex=1, mag=1, con=1 },
			level_range = {self.level, self.level}, exp_worth = 0,
			global_speed_base = 1.0,
			never_move = 1,
			max_life = 1,
			life_rating = 0,
			size_category = 1,
			cut_immune = 1,
			blind_immune = 1,
			disease_immune = 1,
			dont_act = 1,
			negative_status_effect_immune = 1,		
			combat_armor = 0, combat_def = 0,
			
			summoner = self, summoner_gain_exp=true,
			summon_time = duration,
			ai_target = {actor=target}
	}

	m.unused_stats = 0
	m.unused_talents = 0
	m.unused_generics = 0
	m.unused_talents_types = 0
	m.no_inventory_access = true
	m.no_points_on_levelup = true
	m.save_hotkeys = true
	m.ai_state = m.ai_state or {}
	m.ai_state.tactic_leash = 100
	m.soul_fragment = true
	m.faction = "enemies"
	m.summoner = nil
	-- Try to use stored AI talents to preserve tweaking over multiple summons
	m.ai_talents = self.stored_ai_talents and self.stored_ai_talents[m.name] or {}
	m.on_die = function(self, src)
				local t = self:getTalentFromId(self.T_SOUL_REND)
				local tg = {type="hit", range=10, selffire=true, talent=t}
				local damage = t.getDamage(self,t)
				self:project(tg, target.x, target.y, DamageType.SHADOWFROST, t.getDamage(self,t))
	end
			
	m:resolve() m:resolve(nil, true)
	game.zone:addEntity(game.level, m, "actor", x, y)
	game.level.map:particleEmitter(x, y, 1, "summon")

	-- Summons never flee
	m.ai_tactic = m.ai_tactic or {}
	m.ai_tactic.escape = 0
	m.summon_time = duration

	mod.class.NPC.castAs(m)
	engine.interface.ActorAI.init(m, m)

	return m
end


newTalent{
	name = "Soul Rend",
	type = {"spell/spirit", 1},
	require = mag_req1,
	points = 5,
	mode = "passive",
	hotkey=true,
	getDuration = function(self, t) return math.floor(self:combatTalentScale(t, 3, 6)) end,
	getDamage = function(self, t) return self:combatTalentSpellDamage(t, 15, 100) end,
	activate = function(self, t)
		return true
	end,
	deactivate = function(self, t, p)
		return true
	end,
	callbackOnMeleeAttack = function(self, t, target, hitted)
		if not hitted then return end
		local tg = {type="hit", range=10, talent=t}
		if rng.percent(100) and not target.soul_fragment then
			if not target:hasEffect(target.EFF_SOUL_REND) then
				target:setEffect(target.EFF_STUNNED, t.getDuration(self,t), {src=self, apply_power=self:combatSpellpower()})
				target:setEffect(target.EFF_SOUL_REND, 6, {src=self})
				local x, y = util.findFreeGrid(target.x, target.y, 10, true, {[Map.ACTOR]=true})
				if not x then return nil end
				local m = soul_rend(self, target, t.getDuration(self,t), x, y)
			else
				local tg = {type="hit", range=10, selffire=true, talent=t}
				local damage = t.getDamage(self,t)
				self:project(tg, target.x, target.y, DamageType.SHADOWFROST, damage)
			end		
		else return end
		return
	end,
	info = function(self, t)
		local dam = t.getDamage(self,t)
		local dur = t.getDuration(self,t)
		return ([[ Your melee attacks have a 25%% chance to rend the target's soul for 6 turns, stunning them for %d turns.
		If they are already affected by Soul Rend, this instead deals %0.2f cold damage and %0.2f darkness damage.
		The damage will increase with your Spellpower.]]):
		format(
		dur, damDesc(self, DamageType.COLD, dam/2), damDesc(self, DamageType.DARKNESS, dam/2)
		)
	end,
}

stinkstink
Spiderkin
Posts: 543
Joined: Sat Feb 11, 2012 1:12 am

Re: Having a summon's on_die project from the summoner

#2 Post by stinkstink »

You're having the fragment set its summoner within its definition, then setting that to nil afterwards. Is that required to make it hostile? If so, does including another reference to the summoner under a different variable name and projecting from that work?

Razakai
Uruivellas
Posts: 889
Joined: Tue May 14, 2013 3:45 pm

Re: Having a summon's on_die project from the summoner

#3 Post by Razakai »

Yep, that's exactly what I ended up doing - it seems if something is your summon, you can't make it hostile due to the code in mod. Instead stored summoner as 'source' and called that, thanks for confirming that was correct!

grayswandir
Uruivellas
Posts: 708
Joined: Wed Apr 30, 2008 5:55 pm

Re: Having a summon's on_die project from the summoner

#4 Post by grayswandir »

Note that if this isn't happening immediately, e.g. the backlash can activate several turns after the effect is cast, you'll want to store the source variable as an actual field on the object instead of just a local variable so that it save/loads properly.
Addons: Arcane Blade Tweaks, Fallen Race, Monk Class, Weapons Pack
Currently working on Elementals. It's a big project, so any help would be appreciated. :)

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

Re: Having a summon's on_die project from the summoner

#5 Post by HousePet »

Code: Select all

m.source = m.summoner
m.summoner = nil
   -- Try to use stored AI talents to preserve tweaking over multiple summons
   m.ai_talents = self.stored_ai_talents and self.stored_ai_talents[m.name] or {}
   m.on_die = function(self, src)
            local t = self.source:getTalentFromId(self.T_SOUL_REND)
            local tg = {type="hit", range=10, selffire=true, talent=t}
            local damage = t.getDamage(self.source,t)
            self.source:project(tg, self.x, self.y, DamageType.SHADOWFROST, damage)
   end
Something like that?
My feedback meter decays into coding. Give me feedback and I make mods.

Post Reply