Multishot Monster Spell

mail@pastecode.io avatar
unknown
lua
2 years ago
3.4 kB
2
Indexable
Never
--- Multishot Monster Spell ---
--- by ShivaShadowsong -----
--- For TFS 0.3.6 ------------

local function canTargetVictim(caster, victim)
	-- Don't target the caster.
	if caster == victim then
		return false
	end

	local master = getCreatureMaster(caster)
	if master ~= cid then
		-- Don't target the creature if their master is the same as mine.
		if master == getCreatureMaster(victim) then
			return false
		end
	end

	if isPlayer(victim) then
		-- Don't target privileged players.
		if getPlayerGroupId(victim) >= 3 then
			return false
		end
		-- TODO: Don't target any players at all if my master is a player and doesn't have PVP turned on?
		-- ...
	end

	-- Don't target Npcs.
	if isNpc(victim) then
		return false
	end

	return true
end

function onCastSpell(cid, var)
	local configs = {
			["Innate Familiar"] = {
					mindmg = -500, -- Minimum damage (don't forget that this number has to be negative)
					maxdmg = -1000, -- Maximum damage (don't forget that this number has to be negative)
					dmgtype = COMBAT_FIREDAMAGE, -- Damage type (for available types, check your Constants library)
					shooteff = 3, -- Number of distance effect that will be shot (can also be a constant)
					splasheff = 187, -- Number of magic effect that will be displayed when the target is shot (can also be a constant)
					delay = 200, -- Delay at which multiple shots will be fired. In miliseconds.
					shots = 2, -- How many shots will the monster fire per attack?
					shootrange = 6 -- Range at which the monster scans for targets and shoots the shots.
			}
	}

	---- Don't touch anything below unless you know what you're doing ----
	local self = configs[getCreatureName(cid)]
	if ((not self) or (getCreatureTarget(cid) == 0)) then
		return true
	end

	local victims = getSpectators(getThingPos(cid.uid), self.shootrange, self.shootrange) -- List of potential victims to scan through.
	local victimtable = {} -- Will hold an array of all creatures on which we've decided to fire.

	-- First shot will always be fired at the primary target, which is a mandatory target to have in order for this ability to have been used.
	local shotsLeft = self.shots - 1
	table.insert(victimtable, getCreatureTarget(cid))

	-- Form a table of all other creatures who will be shot according to how many shots there are left to fire.
	if shotsLeft > 0 then
		for _, victim in pairs(victims) do
			if shotsLeft > 0 then
				local canTarget = canTargetVictim(cid, victim)
				if (not (isInArray(victimtable, victim)) and canTarget) then
					table.insert(victimtable, victim)
					shotsLeft = shotsLeft - 1
				end
			else
				break
			end
		end
	end

	-- Fire the shots.
	for _, victim in pairs(victimtable) do
		local shotsFired = 0
		addEvent(function()
			if isCreature(cid) and isCreature(victim) then
				if getDistanceBetween(getThingPos(cid.uid), getThingPos(victim)) <= self.shootrange and isSightClear(getThingPos(cid.uid), getThingPos(victim), false) then
					doSendDistanceShoot(getThingPos(cid.uid), getThingPos(victim), self.shooteff)
					doTargetCombatHealth(cid,	victim, self.dmgtype,	self.mindmg, self.maxdmg,	self.splasheff)
				else
					-- TODO: Play some poof effect or display some message if the target got out of range/out of sight before the shot was fired?
				end
			end
		end, shotsFired * self.delay)
	end

	return true
end