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

Lua Need monster spawn npc

henkas

Well-Known Member
Joined
Jul 8, 2015
Messages
1,051
Solutions
5
Reaction score
62
Does anyone have a NPC that would spawn monster?
\/ table logic
local monsters = {
would contain the monsters names that can be spawned
}

logic with npc \/
-Hi (player)
-Hello 'PLAYERNAME' i can spawn monsters for you(npc)
-Monster Name(player)
 
LUA:
local AVAILABLE_MONSTERS = {
    "rat",
    "orc",
    "cyclops",
    "dragon"
}

local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, talkType, msg) npcHandler:onCreatureSay(cid, talkType, msg) end
function onThink() npcHandler:onThink() end

npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|! It's a pleasure to meet another monster hunter! If you're here to {fight} a {monster}, I can assist you. My {list} is limited, though.")
npcHandler:setMessage(MESSAGE_FAREWELL, "Farewell, brave monster hunter!")
npcHandler:setMessage(MESSAGE_WALKAWAY, "You left without saying goodbye? How rude!")
npcHandler:setMessage(MESSAGE_IDLETIMEOUT, "So indecisive... Next time, come better prepared!")

keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = "My job here is to help monster hunters by summoning various types of {monster}s for them."})

npcHandler:addModule(FocusModule:new())

local function spawnMonster(npc, player, monsterName)
    local playerPos = player:getPosition()
    local spawnPos = Position(playerPos.x + 1, playerPos.y, playerPos.z) -- Adjust coordinates as needed

    if not isInArray(AVAILABLE_MONSTERS, monsterName:lower()) then
        npc:say("I don't know that monster. You can check available monsters with the {list}.", TALKTYPE_SAY)
        return
    end

    Game.createMonster(monsterName, spawnPos)
    npc:say("Let the battle with " .. monsterName .. " begin!", TALKTYPE_SAY)
end

local function handleDialogue(cid, talkType, msg)
    local player = Player(cid)
    local message = msg:lower()

    if message == "monster" or message == "list" then
        local monsterList = "{" .. table.concat(AVAILABLE_MONSTERS, "}, {") .. "}"
        npcHandler:say("You can {fight} one of the following monsters: " .. monsterList .. ".\nWhen you've decided, just say {fight} and tell me the name of the monster you'd like to battle.", cid)
    
    elseif message == "fight" then
        npcHandler:say("Tell me the name of the monster you'd like to fight.", cid)
        npcHandler.topic[cid] = 1
    
    elseif npcHandler.topic[cid] == 1 then
        spawnMonster(npcHandler, player, msg)
        npcHandler.topic[cid] = 0
    end

    return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, handleDialogue)
 
LUA:
local AVAILABLE_MONSTERS = {
    "rat",
    "orc",
    "cyclops",
    "dragon"
}

local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, talkType, msg) npcHandler:onCreatureSay(cid, talkType, msg) end
function onThink() npcHandler:onThink() end

npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|! It's a pleasure to meet another monster hunter! If you're here to {fight} a {monster}, I can assist you. My {list} is limited, though.")
npcHandler:setMessage(MESSAGE_FAREWELL, "Farewell, brave monster hunter!")
npcHandler:setMessage(MESSAGE_WALKAWAY, "You left without saying goodbye? How rude!")
npcHandler:setMessage(MESSAGE_IDLETIMEOUT, "So indecisive... Next time, come better prepared!")

keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = "My job here is to help monster hunters by summoning various types of {monster}s for them."})

npcHandler:addModule(FocusModule:new())

local function spawnMonster(npc, player, monsterName)
    local playerPos = player:getPosition()
    local spawnPos = Position(playerPos.x + 1, playerPos.y, playerPos.z) -- Adjust coordinates as needed

    if not isInArray(AVAILABLE_MONSTERS, monsterName:lower()) then
        npc:say("I don't know that monster. You can check available monsters with the {list}.", TALKTYPE_SAY)
        return
    end

    Game.createMonster(monsterName, spawnPos)
    npc:say("Let the battle with " .. monsterName .. " begin!", TALKTYPE_SAY)
end

local function handleDialogue(cid, talkType, msg)
    local player = Player(cid)
    local message = msg:lower()

    if message == "monster" or message == "list" then
        local monsterList = "{" .. table.concat(AVAILABLE_MONSTERS, "}, {") .. "}"
        npcHandler:say("You can {fight} one of the following monsters: " .. monsterList .. ".\nWhen you've decided, just say {fight} and tell me the name of the monster you'd like to battle.", cid)
   
    elseif message == "fight" then
        npcHandler:say("Tell me the name of the monster you'd like to fight.", cid)
        npcHandler.topic[cid] = 1
   
    elseif npcHandler.topic[cid] == 1 then
        spawnMonster(npcHandler, player, msg)
        npcHandler.topic[cid] = 0
    end

    return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, handleDialogue)
First try perfection
 
I'm glad it works because I wrote it "from my head", because, currently I don't have TFS environment on my PC.
Great that I could help 😅
 
I'm glad it works because I wrote it "from my head", because, currently I don't have TFS environment on my PC.
Great that I could help 😅
Question is it possible to make it only summon one until the previous is killed? So it wont be abused and spawned insane numbers of them
 
Everything is possible, there are several ways how to handle it.
There is the most common one - will check if any creature that is monster still exists in certain radius.

* Reworked NPC:
LUA:
local AVAILABLE_MONSTERS = {
    "rat",
    "orc",
    "cyclops",
    "dragon"
}

local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, talkType, msg) npcHandler:onCreatureSay(cid, talkType, msg) end
function onThink() npcHandler:onThink() end

npcHandler:setMessage(MESSAGE_GREET, "Welcome, |PLAYERNAME|! It's a pleasure to meet another monster hunter! If you're here to {fight} a {monster}, I can assist you. My {list} is limited, though.")
npcHandler:setMessage(MESSAGE_FAREWELL, "Farewell, brave monster hunter!")
npcHandler:setMessage(MESSAGE_WALKAWAY, "You left without saying goodbye? How rude!")
npcHandler:setMessage(MESSAGE_IDLETIMEOUT, "So indecisive... Next time, come better prepared!")

keywordHandler:addKeyword({'job'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = "My job here is to help monster hunters by summoning various types of {monster}s for them."})

npcHandler:addModule(FocusModule:new())

local function isMonsterAliveInArea(centerPos, radiusX, radiusY)
    local spectators = Game.getSpectators(centerPos, false, false, radiusX, radiusX, radiusY, radiusY)
    for _, creature in ipairs(spectators) do
        if creature:isMonster() then
            return true
        end
    end

    return false
end

local function spawnMonster(npc, player, monsterName)
    local playerPos = player:getPosition()
    local spawnPos = Position(playerPos.x + 1, playerPos.y, playerPos.z) -- Adjust coordinates as needed

    local BattleRoomCenterPosition = Position(1000, 1000, 7)
    if isMonsterAliveInArea(BattleRoomCenterPosition, 5, 5) then
        npc:say("Its looks like there is still a living creature inside room. Slay it before another one!", TALKTYPE_SAY)
        return
    end

    if not isInArray(AVAILABLE_MONSTERS, monsterName:lower()) then
        npc:say("I don't know that monster. You can check available monsters with the {list}.", TALKTYPE_SAY)
        return
    end

    Game.createMonster(monsterName, spawnPos)
    npc:say("Let the battle with " .. monsterName .. " begin!", TALKTYPE_SAY)
end

local function handleDialogue(cid, talkType, msg)
    local player = Player(cid)
    local message = msg:lower()

    if message == "monster" or message == "list" then
        local monsterList = "{" .. table.concat(AVAILABLE_MONSTERS, "}, {") .. "}"
        npcHandler:say("You can {fight} one of the following monsters: " .. monsterList .. ".\nWhen you've decided, just say {fight} and tell me the name of the monster you'd like to battle.", cid)
 
    elseif message == "fight" then
        npcHandler:say("Tell me the name of the monster you'd like to fight.", cid)
        npcHandler.topic[cid] = 1
 
    elseif npcHandler.topic[cid] == 1 then
        spawnMonster(npcHandler, player, msg)
        npcHandler.topic[cid] = 0
    end

    return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, handleDialogue)

Remember to edit local BattleRoomCenterPosition = Position(1000, 1000, 7) to your center position of room where creatures are spawning.
And those 2 x 5 in if isMonsterAliveInArea(BattleRoomCenterPosition, 5, 5) then to fit the room size. First 5 is rangeX and second is rangeY.
 

Similar threads

Replies
9
Views
562
Back
Top