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

[OTBR] Trivial NPC Crashed

walltimer

Active Member
Joined
Aug 5, 2020
Messages
170
Reaction score
26
Hi, i have a trivial NCP which is from @Sarah Wesker (greetings man :)) , but when player/npc hp goes to 75% it crashed the engine, as hard that i have to even restart all the Server, nothing react, even ubuntu is dead ;o, so i dont see any errors....
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

function onCreatureAppear(cid) npcHandler:eek:nCreatureAppear(cid) end
function onCreatureDisappear(cid) npcHandler:eek:nCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg) npcHandler:eek:nCreatureSay(cid, type, msg) end
function onThink() npcHandler:eek:nThink() end

local function irandom_prefix(from, to, prefix)
return string.format("%d %s", math.random(from, to), prefix)
end

local talkHppc = {
player = 100,
npc = 100,
damage = function() return math.random(10, 20) end
}
local rewards = {
exp = 1000000,
items = {
{2160, 100},
{2160, 100}
}
}

local questions = {
{
type = "select",
name = "How far is the earth from the moon?",
options = {
irandom_prefix(1, 100, "km"),
irandom_prefix(5000, 9999, "km"),
irandom_prefix(1, 999, "km"),
"384400 km"
},
answer = 4
},
{
type = "select",
name = "Who is the president of the united states?",
options = {
"Kamala Harris",
"Donald Trump",
"Joe Biden",
"Barack Obama"
},
answer = 3
},
{
type = "select",
name = "Which is the vocation that has more magic damage?",
options = {
"Knight",
"Sorcerer",
"Paladin",
"No Vocation"
},
answer = 2
},
{
type = "math",
name = "What is the result of %d %s %d?",
options = 4
}
}

local function shuffle(tbl)
for i = #tbl, 2, -1 do
local j = math.random(i)
tbl, tbl[j] = tbl[j], tbl
end
end

local function delaySay(msg, interval, npcid, cid)
addEvent(function(msg, npcid, cid)
local npc = Npc(npcid)
if npc then
npc:say(msg, TALKTYPE_PRIVATE_NP, false, cid)
end
end, interval, msg, npcid, cid)
end

local talkPlayer = 0
local talkQuest = nil
local talkState = {}
local afterQuests = nil

local function getRandomQuest()
local quest
if not afterQuests then
afterQuests = math.random(1, #questions)
quest = questions[afterQuests]
else
local nrandom = math.random(1, #questions)
quest = questions[nrandom]
while afterQuests == nrandom do
quest = questions[nrandom]
end
afterQuests = nrandom
end
if quest then
if quest.type == "select" then
local options = {}
for i = 1, #quest.options do
local option = quest.options
if type(option) == "function" then
options[#options +1] = option()
elseif type(option) == "string" then
options[#options +1] = option
end
end
shuffle(options)
local answer = 1
for i = 1, #options do
if options == quest.options[quest.answer] then
answer = i
break
end
end
return {
name = quest.name,
options = options,
answer = answer
}
elseif quest.type == "math" then
local operator = ({'+','-','/','*'})[math.random(1, 4)]
local n1, n2 = math.random(1, 100), math.random(1, 100)
local o_result = loadstring(string.format("return %d%s%d", n1, operator, n2))()
local name = string.format(quest.name, n1, operator, n2)
local options = {o_result}
for i = 1, quest.options -1 do
options[#options +1] = math.random(1, 999)
end
shuffle(options)
local answer = 1
for i = 1, #options do
if options == o_result then
answer = i
break
end
end
return {
name = name,
options = options,
answer = answer
}
end
end
end

local function sendNewQuest(cid, nid)
talkQuest = getRandomQuest()
local text = string.format("%s\nOptions: ", talkQuest.name)
for i = 1, #talkQuest.options do
text = string.format("%s[ {%d} ]: %s%s", text, i, talkQuest.options, (i ~= #talkQuest.options and " | " or ""))
end
delaySay(text, 1000, nid, cid)
end

local function sendRewards(player)
local bag = Game.createItem(2002, 1)
if bag then
local description = "You rewards: "
for _, reward in pairs(rewards.items) do
bag:addItem(reward[1], reward[2], INDEX_WHEREEVER, FLAG_NOLIMIT)
description = string.format("%s%d %s%s", description, reward[2], ItemType(reward[1]):getName(), (_ == #rewards.items and '.' or ', '))
end
local inbox = player:getInbox()
if inbox then
inbox:addItemEx(bag, INDEX_WHEREEVER, FLAG_NOLIMIT)
player:sendTextMessage(MESSAGE_INFO_DESCR, description..'\nCheck your depot inbox.')
end
end
if rewards.exp then
player:addExperience(rewards.exp, true)
end
end

function creatureSayCallback(cid, typ, msg)
if not npcHandler:isFocused(cid) then
return false
end

local nid = getNpcCid()
local npc = Npc(nid)
local npcPos = npc:getPosition()

local player = Player(cid)
local playerPos = player:getPosition()

if not talkState[cid] then
if msgcontains(msg, "yes") then
selfSay("Here are some questions which you have to answer, I'll play too ;D", cid)
sendNewQuest(cid, nid)
npcPos:sendMagicEffect(CONST_ME_CRAPS)
talkState[cid] = 1
elseif msgcontains(msg, "no") then
selfSay("Come back when you have the courage to face me.", cid)
npcHandler:releaseFocus(cid)
end
elseif talkState[cid] == 1 then
if talkQuest then
local select_n = tonumber(msg)
if select_n and select_n > 0 and select_n <= #talkQuest.options then
local npc_correct = math.random(1, #talkQuest.options) == talkQuest.answer
if select_n == talkQuest.answer then
if npc_correct then
selfSay("Your answer is correct, mine is also correct, so neither will take damage.", cid)
npcPos:sendMagicEffect(CONST_ME_POFF)
playerPos:sendMagicEffect(CONST_ME_POFF)
else
selfSay("Your answer is correct, mine is not, so I will take damage.", cid)
playerPos:sendMagicEffect(CONST_ME_POFF)
playerPos:sendDistanceEffect(npcPos, CONST_ANI_DEATH)
npcPos:sendMagicEffect(CONST_ME_MORTAREA)
talkHppc.npc = math.max(0, talkHppc.npc - talkHppc.damage())
end
else
if npc_correct then
selfSay("Your answer is wrong, mine is correct, you will receive damage.", cid)
npcPos:sendMagicEffect(CONST_ME_POFF)
npcPos:sendDistanceEffect(playerPos, CONST_ANI_DEATH)
playerPos:sendMagicEffect(CONST_ME_MORTAREA)
talkHppc.player = math.max(0, talkHppc.player - talkHppc.damage())
else
selfSay("Your answer is wrong, I was wrong too, we both received damage.", cid)
playerPos:sendDistanceEffect(npcPos, CONST_ANI_DEATH)
npcPos:sendMagicEffect(CONST_ME_MORTAREA)
npcPos:sendDistanceEffect(playerPos, CONST_ANI_DEATH)
playerPos:sendMagicEffect(CONST_ME_MORTAREA)
talkHppc.player = math.max(0, talkHppc.player - talkHppc.damage())
talkHppc.npc = math.max(0, talkHppc.npc - talkHppc.damage())
end
end
delaySay(string.format("Current status:\nYour health: {%d}/100\nNpc health: {%d}/100", talkHppc.player, talkHppc.npc), 1000, nid, cid)
if talkHppc.player <= 0 then
delaySay("You have been defeated, it was a good fight.", 1500, nid, cid)
npc:say("I have won the trivial battle hahahaha.", TALKTYPE_MONSTER_SAY)
npcHandler:releaseFocus(cid)
elseif talkHppc.npc <= 0 then
delaySay("You're the winner, it was a good fight.", 1500, nid, cid)
player:say("I have won the trivial battle hahahaha.", TALKTYPE_MONSTER_SAY)
sendRewards(player)
playerPos:sendMagicEffect(CONST_ME_FIREWORK_YELLOW)
npcHandler:releaseFocus(cid)
else
delaySay("Ready for the next round?", 1500, nid, cid)
talkState[cid] = 2
end
else
selfSay(string.format("Please select one of the available options, for example: {%d}", math.random(1, #talkQuest.options)), cid)
end
end
elseif talkState[cid] == 2 then
if msgcontains(msg, "yes") then
selfSay(({"Mmmmm...", "Ok...", "I Think..."})[math.random(1, 3)], cid)
sendNewQuest(cid, nid)
npcPos:sendMagicEffect(CONST_ME_CRAPS)
talkState[cid] = 1
elseif msgcontains(msg, "no") then
selfSay("Come back when you have the courage to face me.", cid)
npcHandler:releaseFocus(cid)
end
end

return true
end

function creatureReleaseFocusCallback(cid)
talkState[cid] = nil
talkPlayer = 0
talkHppc.player = 100
talkHppc.npc = 100
return true
end

function creatureGreetCallback(cid)
local player = Player(talkPlayer)
if not player then
player = Player(cid)
selfSay(string.format("Hello {%s}, would you like to answer some questions and earn rewards?", player:getName()), cid)
talkPlayer = cid
npcHandler:addFocus(cid)
elseif player ~= Player(cid) then
selfSay(string.format("Estoy ocupado jugando con {%s}, por favor espera tu turno.", player:getName()), cid)
talkPlayer = 0
end
return false
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:setCallback(CALLBACK_GREET, creatureGreetCallback)
npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, creatureReleaseFocusCallback)
npcHandler:addModule(FocusModule:new())
1.3 TFS OTservbr
Post automatically merged:

adn the second : how can i make it every 60min for each player no all the players? Like every1 has a chance to kill.
local config = {
actionId = 800,
delay = 60 * 60, -- 1 hour
delayPersistent = false,
bosses = {
{ name = "Sight of Surrender", pos = Position(1138, 1115, 4) }
}
}

local movIn = MoveEvent()

function movIn.onStepIn(creature, item, position, fromPosition)
local player = creature:getPlayer()
if not player then
return true
end
local playerId = player:getId()
local ground = Tile(position):getGround()
if ground then
local now = os.time()
local delay = config.delayPersistent and ground:getCustomAttribute("delay") or config.time
if not delay or delay <= now then
position:sendMagicEffect(CONST_ME_MAGIC_BLUE)
for _, info in pairs(config.bosses) do
Game.createMonster(info.name, info.pos)
end
if not config.delayPersistent then
config.time = now + config.delay
else
ground:setCustomAttribute("delay", now + config.delay)
end
else
position:sendMagicEffect(CONST_ME_POFF)
player:sendTextMessage(MESSAGE_STATUS_DEFAULT, string.format("You must wait %d seconds to summon the bosses again.", delay - now))
end
end
return true
end

movIn:aid(config.actionId)
movIn:register()
 
Last edited:
Back
Top