• 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!

TalkAction [TFS 1.2]Remove nearby Creatures by Name (NPCs, Monsters)

Danat

Member
Joined
Jun 6, 2008
Messages
36
Reaction score
7
Hello OT Land.
I'm currently working on my own Server, and since everyone has shared so many useful things here,
I wanted to share something i put together last night.
So I wanted to address a problem, I think at least a few might be familiar with as OT Admin, deleting NPCs.
So that's what I did,

I made it as a talkaction, that with the name of the NPC you want to remove, it checks the surroundings, and removes any found NPC creature by that name (case sensitive), it also finds any creatures and reports its position.
Then, added some config to personalize it, and added support to remove monster creatures (note, it removes the creature, not the spawn).
And to improve it a bit, I added multiple floors functionality, I mean, it has the option to check for creatures above and below you. It has a check to make sure it doesnt overreach with the floors.
Also made an alternate version that does not remove creatures, instead, it just finds them.
This version has option to find players nearby as well. But will not remove any creatures found.

With all that being said, here it is
talkactions.lua
add (you can change the words needed, rc)
Lua:
<talkaction words="/rc" separator=" " script="remove_creatures.lua" />


remove_creatures.lua
Lua:
-- Credits to OT Land for all their shared ressources and community help.
-- To Danat, me, that made this script
-- To knekarn, which shared a nice npc guard script that I adapted to this one. (I adapted the check radius around player, and added multiple floors)

local config = {
        radiusx = 10, -- radiusx
        radiusy = 10, -- radiusy
        radiusz = 15, -- radiusy, set to 15 or higher to search all floors, set to 0 to search current floor, 1 will search floors above and below.
        find_monsters = TRUE, -- set to TRUE to find monsters
        find_npcs = TRUE, -- set to TRUE to find NPCs
        effectfail = CONST_ME_POFF, -- effect no creatures found
        effectuse = CONST_ME_ENERGYHIT, -- effect creatures found
        effectremoved = CONST_ME_MAGIC_GREEN, -- effect on player when creature removed
        effectremove = CONST_ME_TELEPORT, -- effect on creature when creature removed
        ani = CONST_ANI_ENERGY -- ani from player to creature
}


function onSay(player, words, param)
    if not player:getGroup():getAccess() then
        return true
    end

    if player:getAccountType() < ACCOUNT_TYPE_GOD then
        return false
    end
   
local monsters = { } 
local pos = player:getPosition()
local starting = {x = (pos.x - config.radiusx), y = (pos.y - config.radiusy), z = (pos.z + config.radiusz), stackpos = stack}  
local ending = {x = (pos.x + config.radiusx), y = (pos.y + config.radiusy), z = (pos.z - config.radiusz), stackpos = stack}  
local checking = {x = starting.x, y = starting.y, z = starting.z, stackpos = starting.stackpos}

if starting.z > 15 then
    starting.z = 15
end 
if ending.z < 0 then
    ending.z = 0
end

local creature
    repeat
        creature = getTopCreature(checking)
        -- print(creature, getCreatureName(creature.uid))
            if creature.itemid > 0 then
                if isCreature(creature.uid) == TRUE then 
                    if config.find_npcs == TRUE then
                        if isNpc(creature.uid) == TRUE then
                            table.insert (monsters, creature.uid)
                        end
                    end
                    if config.find_monsters == TRUE then
                        if isMonster(creature.uid) == TRUE then
                            table.insert (monsters, creature.uid)
                        end
                    end
                end
            end
-- this checks to skip player pos, else add +1 to x       
        if checking.x == pos.x-1 and checking.y == pos.y then  
            checking.x = checking.x+2  
        else   
            checking.x = checking.x+1
        end  
-- this checks to see if x reached end, if it did, restart x, and add +1 to y
        if checking.x > ending.x then  
            checking.x = starting.x  
            checking.y = checking.y+1  
        end  
-- this will check if y reached ending, restart x and y and add +1 to z
        if checking.y > ending.y then  
            checking.x = starting.x
            checking.y = starting.y
            checking.z = checking.z-1
        end
    until checking.z < ending.z


    if #monsters >= 1 then
    doSendMagicEffect(pos, config.effectuse)
    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have found the following creatures:")
        for i = 1, #monsters do 
            local monstername = getCreatureName(monsters[i])
            local monsterpos = getThingPos(monsters[i])
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Found a creature called " .. monstername .. " at x: "  .. monsterpos.x .. ", y: "  .. monsterpos.y .. ", z: "  .. monsterpos.z .. ".")
            player:sendCancelMessage("Found Creatures.")
            if(monstername == param) then
                local npcpos = {x =getThingPos(monsters[i]).x, y = getThingPos(monsters[i]).y, z = getThingPos(monsters[i]).z, stackpos = getThingPos(monsters[i]).stackpos}
                local stackmob = getThingPos(monsters[i]).stackpos   
                doSendDistanceShoot(player, getThingPos(monsters[i]), config.ani)
                doSendMagicEffect(getThingPos(monsters[i]), config.effectremove)
                doRemoveCreature(monsters[i])
                doSendMagicEffect(pos, config.effectremoved)
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "The Creature nearby called " .. monstername .. " has been removed.")
            end
        end
    elseif table.getn(monsters) < 1 then  
                    doSendMagicEffect(pos, config.effectfail)
                    player:sendCancelMessage("There are no Creatures nearby.")
    end
    return false
end

Thats it, note that its tested and used on TFS 1.2 but might work on previous 1.x with appropriate libs/mods.
Please give credit everytime its due, whenever using something that isnt made by you.
Until next time,
Danat
 
Here is the alternate version to find creatures, players, monters or/and npcs.
This one will not remove any creatures, and is incomplete as I would like to add some functionality with the param, from talkactions.
 
sorry i double posted this.
here is for
talkaction.lua
Lua:
    <talkaction words="/fc" separator=" " script="find_creatures.lua" />

find_creatures.lua
Lua:
local config = {
        radiusx = 30, -- radiusx
        radiusy = 30, -- radiusy
        radiusz = 15, -- radiusy, set to 15 or higher to search all floors, set to 0 to search current floor
        find_monsters = TRUE, -- set to TRUE to find monsters
        find_npcs = TRUE, -- set to TRUE to find NPCs
        find_players = TRUE, -- set to TRUE to find Players
        effectfail = CONST_ME_POFF, -- effect no creatures found
        effectuse = CONST_ME_ENERGYHIT, -- effect creatures found
        effectremove = CONST_ME_TELEPORT, -- effect on creature when creature removed
        ani = CONST_ANI_ENERGY -- ani from player to creature
}


function onSay(player, words, param)
    if not player:getGroup():getAccess() then
        return true
    end

    if player:getAccountType() < ACCOUNT_TYPE_GOD then
        return false
    end
   
local monsters = { } 
local pos = player:getPosition()
local starting = {x = (pos.x - config.radiusx), y = (pos.y - config.radiusy), z = (pos.z + config.radiusz), stackpos = stack}  
local ending = {x = (pos.x + config.radiusx), y = (pos.y + config.radiusy), z = (pos.z - config.radiusz), stackpos = stack}  
local checking = {x = starting.x, y = starting.y, z = starting.z, stackpos = starting.stackpos}
if starting.z > 15 then
    starting.z = 15
end 
if ending.z < 0 then
    ending.z = 0
end
local creature
    repeat
        creature = getTopCreature(checking)
        -- print(creature, getCreatureName(creature.uid))
            if creature.itemid > 0 then
                if isCreature(creature.uid) == TRUE then 
                    if config.find_npcs == TRUE then
                        if isNpc(creature.uid) == TRUE then
                            table.insert (monsters, creature.uid)
                        end
                    end
                    if config.find_monsters == TRUE then
                        if isMonster(creature.uid) == TRUE then
                            table.insert (monsters, creature.uid)
                        end
                    end
                    if config.find_players == TRUE then
                        if isPlayer(creature.uid) == TRUE then
                            table.insert (monsters, creature.uid)
                        end
                    end
                end
            end
-- this checks to skip player pos, else add +1 to x       
        if checking.x == pos.x-1 and checking.y == pos.y then  
            checking.x = checking.x+2  
        else   
            checking.x = checking.x+1
        end  
-- this checks to see if x reached end, if it did, restart x, and add +1 to y
        if checking.x > ending.x then  
            checking.x = starting.x  
            checking.y = checking.y+1  
        end  
-- this will check if y reached ending, restart x and y and add +1 to z
        if checking.y > ending.y then  
            checking.x = starting.x
            checking.y = starting.y
            checking.z = checking.z-1
        end
    until checking.z < ending.z

   
   
   
   
    -- monster_table = getMonstersfromArea(playerpos, radiusx, radiusy, 253)

   
    if #monsters >= 1 then
        doSendMagicEffect(pos, config.effectuse)
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have found the following creatures:")
        for i = 1, #monsters do 
            local monstername = getCreatureName(monsters[i])
            local monsterpos = getThingPos(monsters[i])
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Found a creature called " .. monstername .. " at x: "  .. monsterpos.x .. ", y: "  .. monsterpos.y .. ", z: "  .. monsterpos.z .. ".")
            player:sendCancelMessage("Found Creatures.")
        end
    elseif table.getn(monsters) < 1 then  
                    doSendMagicEffect(pos, config.effectfail)
                    player:sendCancelMessage("There are no Creatures nearby.")
    end
    return false
end
 
you could write this much better and cleaner by utilizing Game.getSpectators(position[, multifloor = false[, onlyPlayer = false[, minRangeX = 0[, maxRangeX = 0[, minRangeY = 0[, maxRangeY = 0]]]]]])
Lua:
local specs = Game.getSpectators(player:getPosition(), config.radiusz >= 15, false, config.radiusx, config.radiusx, config.radiusy, config.radiusy)
for i = 1, #specs do
    local creature = specs[i]
    -- do whatever
end
 
Thanks for that Static_,
I agree, much shorter and cleaner.
I'll be trying it out, I'll post what I end up with when its done.
Thanks
 
69 views already, seems everyone is busy trying it out and forgot to even login to say anything
 
I see that you are practicing with your own codes ;) very good work, but is that the truth this type of commands are not useful, what matters is the intention that you have, Regards and respect.
 
Thanks I appreciate that Sarah Wesker,
To explain the use of this, I made it because many times I would summon an NPC, with /s name, then I would have no way of removing that NPC without a server restart.
Then I added monsters in there, so I can also remove monsters that I left on map with /m name, again, that I would have to kill, to remove. Killing a monster high HP monsters takes a while. Even impossible if the admin player is too weak.
Now, its also useful to find creatures around you, below you, and above you.
So that's the main purpose of these commands
 
I see that you are practicing with your own codes ;) very good work, but is that the truth this type of commands are not useful, what matters is the intention that you have, Regards and respect.
Actually any contribution of someone's work is useful, it's important to acknowledge those who are brave enough to release their work regardless of their skill level and or popularity.

@Danat Thanks for sharing your code, look forward to seeing your next release! :)
 
Back
Top