New, 'flexible' Explosion Expert
Posted: Fri Nov 26, 2010 7:33 pm
				
				There's an issue with Explosion Expert. 
Buying it can actually be to your disadvantage, because as a passive, it ALWAYS makes your bomb explosion larger, even when you don't really want too.
Yes, Alchemist Protection now also applies to your golem, but thisis still not as good as, you know, NOT hurting yourself and your golem at all. Not to mention escorts and other potential allies.
Making it a sustain would be an improvement, but it's still all-or-nothing. If you have 5 points in this, you'd be forced to choose between the base radius of 1, and a radius of 6.
A bit extreme...and silly - if you are an expert, why can't you choose to control the radius of your blasts by making it 'appropriately' large?
So I coded something different: let the player pick how much extra radius they want, without adding extra talents, prompting for a number, or complicated stuff like that.
Basically:
Explosion Expert becomes an activated talent that takes no time(no_energy) and has no cost.
Using it cycles between available bomb radiuses, from 1(what you start with) to 6.
So you buy the talent, you use it once - your bomb radius is now 2. Use it again - radius is now 1.
If you buy it again, you have 2 levels and cano gup to radius 3, and so on.
Would also be nice to show the current bomb range on the screen/left panel - but it's not REALLY needed as you can check the Throw Bomb talent info or just use Throw Bomb and see the radius(and escape/change it if you're not ok with it).
Here's the code: check for any errors, tweak as appropriate, maybe rewrite the Explosion Expert talent info and then replace what we have now in explosives.lua
 
			Buying it can actually be to your disadvantage, because as a passive, it ALWAYS makes your bomb explosion larger, even when you don't really want too.
Yes, Alchemist Protection now also applies to your golem, but thisis still not as good as, you know, NOT hurting yourself and your golem at all. Not to mention escorts and other potential allies.
Making it a sustain would be an improvement, but it's still all-or-nothing. If you have 5 points in this, you'd be forced to choose between the base radius of 1, and a radius of 6.
A bit extreme...and silly - if you are an expert, why can't you choose to control the radius of your blasts by making it 'appropriately' large?
So I coded something different: let the player pick how much extra radius they want, without adding extra talents, prompting for a number, or complicated stuff like that.
Basically:
Explosion Expert becomes an activated talent that takes no time(no_energy) and has no cost.
Using it cycles between available bomb radiuses, from 1(what you start with) to 6.
So you buy the talent, you use it once - your bomb radius is now 2. Use it again - radius is now 1.
If you buy it again, you have 2 levels and cano gup to radius 3, and so on.
Would also be nice to show the current bomb range on the screen/left panel - but it's not REALLY needed as you can check the Throw Bomb talent info or just use Throw Bomb and see the radius(and escape/change it if you're not ok with it).
Here's the code: check for any errors, tweak as appropriate, maybe rewrite the Explosion Expert talent info and then replace what we have now in explosives.lua
Code: Select all
newTalent{
	name = "Throw Bomb",
	type = {"spell/explosives", 1},
	require = spells_req1,
	points = 5,
	mana = 5,
	cooldown = 4,
	range = function(self, t)
		return math.ceil(5 + self:getDex(12))
	end,
	direct_hit = true,
	requires_target = true,
	computeDamage = function(self, t, ammo)
		local inc_dam = 0
		local damtype = DamageType.FIRE
		local particle = "ball_fire"
		if self:isTalentActive(self.T_ACID_INFUSION) then inc_dam = self:getTalentLevel(self.T_ACID_INFUSION) * 0.05; damtype = DamageType.ACID_BLIND; particle = "ball_acid"
		elseif self:isTalentActive(self.T_LIGHTNING_INFUSION) then inc_dam = self:getTalentLevel(self.T_LIGHTNING_INFUSION) * 0.05; damtype = DamageType.LIGHTNING_DAZE; particle = "ball_lightning"
		elseif self:isTalentActive(self.T_FROST_INFUSION) then inc_dam = self:getTalentLevel(self.T_FROST_INFUSION) * 0.05; damtype = DamageType.ICE; particle = "ball_ice"
		else inc_dam = self:getTalentLevel(self.T_FIRE_INFUSION) * 0.07 + (ammo.alchemist_bomb.power or 0) / 100; damtype = self:knowTalent(self.T_FIRE_INFUSION) and DamageType.FIREBURN or DamageType.FIRE
		end
		local dam = self:combatTalentSpellDamage(t, 15, 150, (ammo.alchemist_power + self:combatSpellpower()) / 2)
		dam = dam * (1 + inc_dam)
		return dam, damtype, particle
	end,
	action = function(self, t)
		local ammo = self:hasAlchemistWeapon()
		if not ammo then
			game.logPlayer(self, "You need to ready alchemist gems in your quiver.")
			return
		end
		local tg = {type="ball", range=self:getTalentRange(t)+(ammo.alchemist_bomb.range or 0 ), radius=1+(self.extra_bomb_radius or 0), talent=t}
		local x, y = self:getTarget(tg)
		if not x or not y then return nil end
		ammo = self:removeObject(self:getInven("QUIVER"), 1)
		if not ammo then return end
		local dam, damtype, particle = t.computeDamage(self, t, ammo)
		local prot = self:getTalentLevelRaw(self.T_ALCHEMIST_PROTECTION) * 0.2
		local golem
		if self.alchemy_golem then
			golem = game.level:hasEntity(self.alchemy_golem) and self.alchemy_golem or nil
		end
		local dam_done = 0
		local tmp = {}
		local grids = self:project(tg, x, y, function(tx, ty)
			local d = dam
			-- Protect yourself
			if tx == self.x and ty == self.y then d = dam * (1 - prot) end
			-- Protect the golem
			if golem and tx == golem.x and ty == golem.y then d = dam * (1 - prot) end
			if d == 0 then return end
			dam_done = dam_done + DamageType:get(damtype).projector(self, tx, ty, damtype, self:spellCrit(d), tmp)
			local target = game.level.map(tx, ty, Map.ACTOR)
			if not target then return end
			if ammo.alchemist_bomb.splash then
				DamageType:get(DamageType[ammo.alchemist_bomb.splash.type]).projector(self, tx, ty, DamageType[ammo.alchemist_bomb.splash.type], ammo.alchemist_bomb.splash.dam)
			end
			if ammo.alchemist_bomb.stun and rng.percent(ammo.alchemist_bomb.stun.chance) and target:checkHit(self:combatSpellpower(), target:combatPhysicalResist(), 0, 95, 5) and target:canBe("stun") then
				target:setEffect(target.EFF_STUNNED, ammo.alchemist_bomb.stun.dur, {})
			end
			if ammo.alchemist_bomb.daze and rng.percent(ammo.alchemist_bomb.daze.chance) and target:checkHit(self:combatSpellpower(), target:combatPhysicalResist(), 0, 95, 5) and target:canBe("stun") then
				target:setEffect(target.EFF_DAZED, ammo.alchemist_bomb.daze.dur, {})
			end
		end)
		if ammo.alchemist_bomb.leech then self:heal(math.min(self.max_life * ammo.alchemist_bomb.leech / 100, dam_done)) end
		local _ _, x, y = self:canProject(tg, x, y)
		-- Lightning ball gets a special treatment to make it look neat
		if particle == "ball_lightning" then
			local sradius = (tg.radius + 0.5) * (engine.Map.tile_w + engine.Map.tile_h) / 2
			local nb_forks = 16
			local angle_diff = 360 / nb_forks
			for i = 0, nb_forks - 1 do
				local a = math.rad(rng.range(0+i*angle_diff,angle_diff+i*angle_diff))
				local tx = x + math.floor(math.cos(a) * tg.radius)
				local ty = y + math.floor(math.sin(a) * tg.radius)
				game.level.map:particleEmitter(x, y, tg.radius, "lightning", {radius=tg.radius, grids=grids, tx=tx-x, ty=ty-y, nb_particles=25, life=8})
			end
		else
			game.level.map:particleEmitter(x, y, tg.radius, particle, {radius=tg.radius, grids=grids, tx=x, ty=y})
		end
		if ammo.alchemist_bomb.mana then self:incMana(ammo.alchemist_bomb.mana) end
		game:playSoundNear(self, "talents/arcane")
		return true
	end,
	info = function(self, t)
		local ammo = self:hasAlchemistWeapon()
		local dam, damtype = 1, DamageType.FIRE
		if ammo then dam, damtype = t.computeDamage(self, t, ammo) end
		dam = damDesc(self, damtype, dam)
		return ([[Imbue an alchemist gem with an explosive charge of mana and throw it.
		The gem will explode(radius %d) for %0.2f %s damage.
		Each kind of gem will also provide a specific effect.
		The damage will improve with better gems and Magic stat and the range with your dexterity.]]):format(1+(self.extra_bomb_radius or 0),dam, DamageType:get(damtype).name)
	end,
}
newTalent{
	name = "Explosion Expert",
	type = {"spell/explosives", 2},
	require = spells_req2,
	no_energy = "true",
	points = 5,
	action = function(self, t)
		local max = self:getTalentLevelRaw(t)
		local xtra = self.extra_bomb_radius	or 0
		xtra = xtra +1
		if xtra > max then xtra = 0 end
		self.extra_bomb_radius = xtra
		game.logPlayer(self, "Bomb radius is now %d.", xtra+1)
		return true
	end,
	info = function(self, t)
		return ([[You can increase the radius of your alchemist bombs by up to %d. 
			Activate this talent to cycle through available radiuses.]]):format(self:getTalentLevelRaw(t))
	end,
}