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

Boss Spawn with storage teleport - TFS 0.4 - 8.6

hanzoha

New Member
Joined
May 8, 2016
Messages
87
Reaction score
2
Hello guys!
Currently I'm using the tasks system and it works great but I don't have a boss system.

I was thinking in a simple way to implement bosses, so i figured out this.


Create teleport which only works if player has X storage.

'Boss' spawns on position [x: xxx, y: xxx, z: x]

Only 1 player can be in the room at once.

There will be another teleport in the boss room. If the boss kills you, you can Fight again, but if you get into the exit teleport, the exit teleport removes the X storage given before, so he won't be able to enter again (only if he gets the X storage by doing the task again).

Can you help me? Thanks!
 
Just want to clarify..
Players get a storage for completing X quest.
Now he can fight X boss, after going through X portal, which requires X quest's storage..
Player then get's Y storage from killing X boss. Player can now go through Y portal, to get to a reward room..
which removes storages X & Y, when reward is given?

I hope I got it right.
 
Actually yes! You got it right.

At the begining I was thinking in not using a reward room but sounds great.

Using the reward room, the teleport Y (the one in the reward room) would be the one that removes the storage.
 
Okay. I'll make this when I get home.
Expect me to post in about 2 hours from now.
 
Thx Xikini, you're a Master!
BTW, I was thinking... In order to avoid several teleports for each boss, I think it would be way better if only using 3 or 4 teleports with something like "If player has X storage, then boss 1 appears, if player has XX storage other boss appears and so on. That will allow that all players can use the same teleports for different bosses. (If it's not possible don't worry, I can use several teleports)

And for the rewards, in order to avoid the player getting the same reward in the rewards room, I can use your easy chest system right? Having 2 o 3 chests.
Thanks again!
 
Yes, no, and yes.

However, if you makes multiple bosses for a single teleport, then it may confuse the player when they go through, as if they have multiple storages.. it may spawn a harder/weaker/different boss then they expect.
(Also it doesn't have to be a teleport.. it could be a special tile or something. :p)

However, if that's how you want it, I can easily make it check for all bosses in one teleport.

Although, my easy chest system would not support a renewable reward system like this.
We will need to make another script for that purpose.

-- edit

Couldn't merge post below with this one, due to character count restrictions.

Hope you enjoy it.

(For everyone else, please like the post, if you plan on using it. xD)
 
Last edited:
Quick rules.

Player needs to get X storage from somewhere.
You need to know X storages value.

If you want multiple chest rewards for the same boss, then just copy-paste the script, and make chest with a new actionID in actions.xml

Check bottom of scripts for the xml pastes

Boss Chamber(s) in map editor, do not require the boss to be spawned inside.
In fact, it's better if you just leave the boss chamber 'empty'.

boss_chamber_teleport (all bosses)
Code:
local config = {
   [1] = {x_storage = 11111, x_storage_value = 1, teleport_pos = {x = 1397, y = 1416, z = 7}, boss_name = "rat", boss_position = {x = 1398, y = 1416, z = 7}, boss_chamber_top_left_pos = {x = 1397, y = 1416, z = 7}, boss_chamber_bottom_right_pos = {x = 1398, y = 1417, z = 7}},
   [2] = {x_storage = 11111, x_storage_value = 1, teleport_pos = {x = 1000, y = 1000, z = 7}, boss_name = "boss", boss_position = {x = 1000, y = 1000, z = 7}, boss_chamber_top_left_pos = {x = 1900, y = 1900, z = 6}, boss_chamber_bottom_right_pos = {x = 2100, y = 2100, z = 8}},
   [3] = {x_storage = 11111, x_storage_value = 1, teleport_pos = {x = 1000, y = 1000, z = 7}, boss_name = "boss", boss_position = {x = 1000, y = 1000, z = 7}, boss_chamber_top_left_pos = {x = 1900, y = 1900, z = 6}, boss_chamber_bottom_right_pos = {x = 2100, y = 2100, z = 8}}
}

local condition = createConditionObject(CONDITION_INFIGHT)
setConditionParam(condition, CONDITION_PARAM_TICKS, 5000)

function onStepIn(cid, item, position, fromPosition)
  
   if not isPlayer(cid) then
     return true
   end
  
   for i = 1, #config do
     if getPlayerStorageValue(cid, config[i].x_storage) == config[i].x_storage_value then
       local count = 0
       local monster = 0
       for t = config[i].boss_chamber_top_left_pos.x, config[i].boss_chamber_bottom_right_pos.x do
         for f = config[i].boss_chamber_top_left_pos.y, config[i].boss_chamber_bottom_right_pos.y do
           for n = config[i].boss_chamber_top_left_pos.z, config[i].boss_chamber_bottom_right_pos.z do
             pos = {x = t, y = f, z = n}
             pid = getTopCreature(pos).uid
             if isPlayer(pid) then
               count = count + 1
             end
             if isMonster(pid) then
               monster = pid
             end
           end
         end
       end
       if count ~= 0 then
         doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Someone is currently in " .. config[i].boss_name .. "'s chamber. Please wait awhile.")
         doTeleportThing(cid, fromPosition)
         doSendMagicEffect(fromPosition, 10)
         return true
       end
       if monster ~= 0 then
         doRemoveCreature(monster)
       end
       doSendMagicEffect(position, 10)
       doTeleportThing(cid, config[i].teleport_pos)
       doAddCondition(cid, condition)
       local delay = 1000
       for n = 1, 3 do      
         addEvent(doSendMagicEffect, delay, config[i].boss_position, 10)
         delay = delay + 1000
       end
       addEvent(doCreateMonster, 4000, config[i].boss_name:lower(), config[i].boss_position)
       return true
     end
   end
   doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You don't have any required quests completed to access this portal.")
   doTeleportThing(cid, fromPosition)
   doSendMagicEffect(fromPosition, 10)
   return true
end

--[[
<movevent type="StepIn" actionid="45001" event="script" value="test35.lua"/>
]]
Boss_kill_script (all bosses)
Code:
local t = {
   [{"mister squishy squishy foogoo fish"}] = {y_storage = 11111, x_storage = 22222},
   [{"rat"}] = {y_storage = 11111, x_storage = 22222},
   [{"bug"}] = {y_storage = 11111, x_storage = 22222}
}
local teleport_position = {x = 1000, y = 1000, z = 7} -- where player will be sent after killing boss

local function teleport_loop(cid, n)
   doCreatureSay(cid, "Teleported out in " .. n .. " seconds!", TALKTYPE_ORANGE_1, cid)
   if n > 0 then
     addEvent(teleport_loop, 1000, cid, n - 1)
   elseif n == 0 then
     doTeleportThing(cid, teleport_position)
   end
end

function onKill(cid, target, damage, flags)
   for v, k in pairs(t) do
     local master = getCreatureMaster(target)
     if(master and master ~= target) then
       return true
     end
     if(bit.band(flags, 1) == 1 and isMonster(target) and isInArray(v, getCreatureName(target))) then
       if getCreatureStorage(cid, k.y_storage) < 1 then
         doCreatureSetStorage(cid, k.y_storage, 1)
         doCreatureSetStorage(cid, k.x_storage, getCreatureStorage(cid, k.x_storage) + 1)
       end
       doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You have defeated " .. getCreatureName(target):lower() .. "!")
       addEvent(teleport_loop, 1000, cid, 15)
     end
   end
   return true
end

--[[
-- creaturescripts.xml
<event type="kill" name="boss_kill_repeatable_quests" event="script" value="boss_kill_repeatable_quests.lua"/>

-- login.lua
registerCreatureEvent(cid, "boss_kill_repeatable_quests")
]]
reward room (single boss per script) (or you can just skip this step, and make a normal teleporter to a massive reward room)
Code:
local y_storage = 11111
local teleport_position = {x = 1000, y = 1000, z = 7}

function onStepIn(cid, item, position, fromPosition)
   if not isPlayer(cid) then
     return true
   end
   if getPlayerStorageValue(cid, y_storage) == 1 then
     doTeleportThing(cid, teleport_position)
     return true
   end
   doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You don't have any required quest completed to access this portal.")
   doTeleportThing(cid, fromPosition)
   doSendMagicEffect(fromPosition, 10)
   return true
end

--[[
<movevent type="StepIn" actionid="45001" event="script" value="test36.lua"/>
]]
Chest reward (single boss, single reward) (remember "quick rules")
Code:
local y_storage = 11111
local x_storage = 22222
local x_storage_value = 1
local boss = "boss"

local items = { -- max 8 items
   [1] = {item_id = 2471, item_count = 1},
   [2] = {item_id = 2646, item_count = 1},
   [3] = {item_id = 2470, item_count = 1},
   [4] = {item_id = 2466, item_count = 1}
}

function onUse(cid, item, fromPosition, itemEx, toPosition)

   if getPlayerStorageValue(cid, y_storage) ~= 1 then
     doSendMagicEffect(getThingPos(cid), CONST_ME_POFF)
     doPlayerSendCancel(cid, "You need to kill " .. boss .. " before you can get this reward.")
     return true
   end

   if getAllItemWeight(weight) + 8 > getPlayerFreeCap(cid) then
     doSendMagicEffect(getThingPos(cid), CONST_ME_POFF)
     doPlayerSendCancel(cid, "You require ".. string.format("%.2f", getAllItemWeight(weight) + 8) .." capacity to obtain this reward.")
     return true
   end

   item = doCreateItemEx(1987, 1)
   if (doPlayerAddItemEx(cid, item, false) ~= RETURNVALUE_NOERROR) then
     doPlayerSendCancel(cid, "You require free inventory space to obtain this reward.")
   else
     for i = 1, #items do
       doAddContainerItem(item, items.item_id, items.item_count)
     end
     doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You have found a ".. getItemNameById(1987) .." weighing ".. string.format("%.2f", getAllItemWeight(weight) + 8) .." oz.")
     setPlayerStorageValue(cid, y_storage, 0)
     setPlayerStorageValue(cid, x_storage, 0)
   end

   return true
end

function getAllItemWeight(weight)
   local item = {}
   local count = {}
   local weight = 0
   for i = 1, #items do
     table.insert(items, items[i].item_id)
     table.insert(count, items[i].item_count)
   end
   for i = 1, #item do
     weight = (weight + (getItemWeightById(item[i], count[i])))
   end
   return weight
end

--[[
<action actionid="45001" event="script" value="boss1chest.lua"/>
]]
I only tested the main boss spawn movement script.
Everything else is untested, but 'should' work. xD

Cheers,

Xikini
 
Last edited:
Great Work! I've checked and with few changes on the script would work on TFS 1.2 aswell. I'll probably use a version of this for TFS 1.2! Thanks!

Note:
There's some writing mistakes that will make the server crash, be carefull with that!

Code:
<movevent type="StepIn" actionid="45001" event="script" value="test36.lua"/>

movevent = movement*
 
Great Work! I've checked and with few changes on the script would work on TFS 1.2 aswell. I'll probably use a version of this for TFS 1.2! Thanks!

Note:
There's some writing mistakes that will make the server crash, be carefull with that!

Code:
<movevent type="StepIn" actionid="45001" event="script" value="test36.lua"/>

movevent = movement*
If you point out the mistakes for me, I'll definitely edit my post with the changes.
 
Don't change it! So people has to read it all, not just a simple copy-paste without understanding how it works! xDD If i find anything else, i'll post it, wont be today nor tomorrow tho, pretty busy with work!
 
Code:
function getAllItemWeight(weight)
   local item = {}
   local count = {}
   local weight = 0
   for i = 1, #items do
     table.insert(items, items.item_id)
     table.insert(count, items.item_count)
   end
   for i = 1, #item do
     weight = (weight + (getItemWeightById(item, count)))
   end
   return weight
end
Y u do dis? :confused:
 
Code:
function getAllItemWeight(weight)
   local item = {}
   local count = {}
   local weight = 0
   for i = 1, #items do
     table.insert(items, items.item_id)
     table.insert(count, items.item_count)
   end
   for i = 1, #item do
     weight = (weight + (getItemWeightById(item, count)))
   end
   return weight
end
Y u do dis? :confused:
Because I copy pasted it from another script I made. xD
What's wrong with it? :(
ohh, [.i] see what's wrong.
 
Because I copy pasted it from another script I made. xD
What's wrong with it? :(
There are 3 things:
1) Try to make functions that are reusable in different codes, this function only works with the upvalue in this script so it's useless. (and the parameter is useless too)

2) Why do you iterate over the table to insert the values to separate tables to then iterate over them? That's not necessary.

3) It has a bug in this line:
weight = (weight + (getItemWeightById(item, count)))
Item is a table and count is also a table. You would have to index them.
 
Sorry for, revive the topic. @Xikini Trying to use on OTHire. The teleport tile works you appear on the boss room, the magic effect appear 3 times on screen but the boss dont appear. Im getting this error on distro:

Code:
Lua Script Error: [MoveEvents Interface]
data/movements/scripts/boss_room_teleport.lua:onStepIn

LuaScriptInterface::luaAddEvent(). callback parameter should be a function.

on script this part I think:
addEvent(doCreateMonster, 4000, config.boss_name:lower(), config.boss_position)


What can I do?

-- EDIT

nevermind, just changed doCreateMonster for doSummonCreature, sorry
 
Back
Top