• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!
  • 2026 staff recruitment is open! Check it out and consider applying!

Add cancel if no monsters on screen

Cornwallis

Member
Joined
Jan 3, 2010
Messages
480
Reaction score
16
I messed around with this script a little, it works, but there is a few things i'd like.
1) add a cancel spell function if no monsters on screen
2) cleaned up a little because a lot of the script i think is unnecessary. -- I used the multi-target wand but made it a spell and made it so you don't need to target. Also, it's only pve, so if everything concerning players could be taken out that would be great.(:
Also, it shoots through walls, i did blockwalls="1" in the xml, but that doesn't help lol
any further questions please ask!
Code:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_BLOCKARMOR, 0)
setCombatParam(combat, COMBAT_PARAM_BLOCKSHIELD, 0)
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
setCombatParam(combat, COMBAT_PARAM_EFFECT, 1)
setCombatParam(combat, COMBAT_PARAM_DISTANCEEFFECT, 4)
setCombatFormula(combat, COMBAT_FORMULA_LEVELMAGIC, -4, -35, -6, -40)

local hitExtraTargets = 100
local hitExtraTargetsInRange = 4

function getCreaturesInRange(position, radiusx, radiusy, showMonsters, showPlayers)
    local creaturesList = {}
    for x = -radiusx, radiusx do
        for y = -radiusy, radiusy do
            if not (x == 0 and y == 0) then
                creature = getTopCreature({x = position.x+x, y = position.y+y, z = position.z, stackpos = STACKPOS_TOP_CREATURE})
                if (creature.type == 2 and showMonsters == 1) then
                    table.insert(creaturesList, creature.uid)
                end
            end
        end
    end
    return creaturesList
end

function onCastSpell(cid, var)
    local ret = doCombat(cid, combat, var)
    if(ret == LUA_ERROR) then
        return LUA_ERROR
    end

    local target = variantToNumber(var)
    local hitplayers = 0
    if(target ~= 0) then
        local nowHit = 0
        local randomId = 0
        local otherTargets = getCreaturesInRange(getCreaturePosition(target), hitExtraTargets, hitExtraTargetsInRange, 1)
        if(#otherTargets > 0) then
            for i = 1, hitExtraTargets do
                randomId = math.random(1, #otherTargets)
                nowHit = otherTargets[randomId]
                if(isCreature(nowHit) == TRUE) then
                    table.remove(otherTargets, randomId)
                    ret = doCombat(cid, combat, numberToVariant(nowHit))
                    if(#otherTargets == 0) then
                        break
                    end
                else
                    break
                end
            end
        end
    end
    return TRUE
end
 
Last edited:
Idk, try this.
LUA:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_BLOCKARMOR, 0)
setCombatParam(combat, COMBAT_PARAM_BLOCKSHIELD, 0)
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
setCombatParam(combat, COMBAT_PARAM_EFFECT, 1)
setCombatParam(combat, COMBAT_PARAM_DISTANCEEFFECT, 4)
setCombatFormula(combat, COMBAT_FORMULA_LEVELMAGIC, -4, -35, -6, -40)

local hitExtraTargets = 100
local hitExtraTargetsInRange = 4

function getCreaturesInRange(position, radiusx, radiusy, showMonsters, showPlayers)
    local creaturesList = {}
    for x = -radiusx, radiusx do
		for y = -radiusy, radiusy do
		    if not(x == 0 and y == 0) then
				creature = getTopCreature({x = position.x+x, y = position.y+y, z = position.z, stackpos = STACKPOS_TOP_CREATURE})
				if(creature.type == 2 and showMonsters == 1 and getTilePzInfo(getPlayerPosition(creature)) == false) then
				    table.insert(creaturesList, creature.uid)
				end
		    end
		end
    end
    return creaturesList
end

function onCastSpell(cid, var)
    local ret = doCombat(cid, combat, var)
    if(ret == LUA_ERROR) then
		return LUA_ERROR and true
    end
    local target = variantToNumber(var)
    local hitplayers = 0
	if(target <= 0) then
		return LUA_ERROR and true
	end
	if(target > 0) then
		local nowHit = 0
		local randomId = 0
		local otherTargets = getCreaturesInRange(getCreaturePosition(target), hitExtraTargets, hitExtraTargetsInRange, 1)
		if(#otherTargets > 0) then
			for i = 1, hitExtraTargets do
				randomId = math.random(1, #otherTargets)
				nowHit = otherTargets[randomId]
				if(isCreature(nowHit) == TRUE) then
					table.remove(otherTargets, randomId)
					ret = doCombat(cid, combat, numberToVariant(nowHit))
					if(#otherTargets == 0) then
						break
					end
				else
					break
				end
			end
		end
	end
	return true
end
 
nope, it just spams the name of the spell, says nothing in console tho.
EDIT; i'm learning some more about scripting, and does this problem mean a return value isn't working correctly?
 
LUA:
local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_BLOCKARMOR, false)
setCombatParam(combat, COMBAT_PARAM_BLOCKSHIELD, false)
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_LOSEENERGY)
setCombatParam(combat, COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY)
setCombatFormula(combat, COMBAT_FORMULA_LEVELMAGIC, -4, -35, -6, -40)

local range = 4

function onCastSpell(cid, var)
	local pos, hit = getThingPos(cid), false

	for x = -range, range do
		for y = -range, range do
			if x ~= 0 or y ~= 0 then
				local p = {x=pos.x+x, y=pos.y+y, z=pos.z}
				local c = getTopCreature(p)
				if c.type == 2 and isSightClear(pos, p, true) then
					doCombat(cid, combat, numberToVariant(c.uid))
					hit = true
				end
			end
		end
	end

	if not hit then
		doPlayerSendCancel(cid, 'There are no targets in range.')
		doSendMagicEffect(pos, CONST_ME_POFF)
	end

	return hit
end
 
Back
Top