Draconis
Member
Hi All script for Svargrond Arena. Tested on Canary 3.0.0
First add NPC
data-server/npc/halvar.lua
Now we go to data-server/scripts/actions and on quest_system.lua we add
If you don't have this file you can use main
Now we create on data-server/scripts/creaturescripts/ file arena_kill.lua
now we go to movements data-server/scripts/movements and create file arena_enter.lua
and arena_pit.lua
and arena_trophy.lua
now we go to data-server/startup/door_quest.lua
All scipts and map is compatibile with Canary 3.0.0
All my scripts and map you find on my github
Everything is compatibile with my maps if you want use on your own you have to configure on youself.
Any question send me PM
NOT TESTED ON TFS
First add NPC
data-server/npc/halvar.lua
LUA:
local internalNpcName = "Halvar"
local npcType = Game.createNpcType(internalNpcName)
local npcConfig = {}
npcConfig.name = internalNpcName
npcConfig.description = internalNpcName
npcConfig.health = 100
npcConfig.maxHealth = npcConfig.health
npcConfig.walkInterval = 2000
npcConfig.walkRadius = 2
npcConfig.outfit = {
lookType = 143,
lookHead = 3,
lookBody = 77,
lookLegs = 78,
lookFeet = 39,
lookAddons = 1,
}
npcConfig.flags = {
floorchange = false,
}
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
npcType.onThink = function(npc, interval)
npcHandler:onThink(npc, interval)
end
npcType.onAppear = function(npc, creature)
npcHandler:onAppear(npc, creature)
end
npcType.onDisappear = function(npc, creature)
npcHandler:onDisappear(npc, creature)
end
npcType.onMove = function(npc, creature, fromPosition, toPosition)
npcHandler:onMove(npc, creature, fromPosition, toPosition)
end
npcType.onSay = function(npc, creature, type, message)
npcHandler:onSay(npc, creature, type, message)
end
npcType.onCloseChannel = function(npc, creature)
npcHandler:onCloseChannel(npc, creature)
end
keywordHandler:addKeyword({ "rules" }, StdModule.say, { npcHandler = npcHandler, text = "What do you want to know? Something about the three different {difficulties}, the {general} rules or the {prices}? Maybe you also want to know what happens when you {die}?" })
keywordHandler:addKeyword({ "difficulties" }, StdModule.say, { npcHandler = npcHandler, text = "There are three difficulties: Greenhorn, Scrapper and Warlord. On each challenge you will be confronted with ten monsters increasing in strength." })
keywordHandler:addKeyword({ "levels" }, StdModule.say, { npcHandler = npcHandler, text = "There are three difficulties: Greenhorn, Scrapper and Warlord. On each challenge you will be confronted with ten monsters increasing in strength." })
keywordHandler:addKeyword({ "difficulty" }, StdModule.say, { npcHandler = npcHandler, text = "There are three difficulties: Greenhorn, Scrapper and Warlord. On each challenge you will be confronted with ten monsters increasing in strength." })
keywordHandler:addKeyword({ "greenhorn" }, StdModule.say, { npcHandler = npcHandler, text = "That is the easiest way in our arena. The {fee} is 1000 gold. We were setting this up for of our children to challenge some easy monsters and train them for the future." })
keywordHandler:addKeyword({ "scrapper" }, StdModule.say, { npcHandler = npcHandler, text = "The most common difficulty for us. The {fee} is 5000 gold. So if you are experienced in fighting middle class monsters this is your challenge!" })
keywordHandler:addKeyword({ "warlord" }, StdModule.say, { npcHandler = npcHandler, text = "Only the strongest among us will take this challenge. The {fee} is 10000 gold. If you pass that I promise you the respect of all citizens here. You will be a hero!" })
keywordHandler:addKeyword({ "fee" }, StdModule.say, { npcHandler = npcHandler, text = "The fee is either 1000, 5000 or 10000 gold for one try. Remember that if you {die}, it is YOUR problem and you won't be able to get back to your corpse and your backpack." })
keywordHandler:addKeyword({ "die" }, StdModule.say, { npcHandler = npcHandler, text = "It would be better not to die! In every pit there is an emergency exit, the portal to the south. If you die in a pit... well... your corpse and backpack are gone, so you enter the arena at your own risk." })
keywordHandler:addKeyword({ "general" }, StdModule.say, { npcHandler = npcHandler, text = "Basically you pay me a {fee}, and you are sent into an arena with 10 different stages. If you succeed you will be rewarded accordingly." })
keywordHandler:addKeyword({ "job" }, StdModule.say, { npcHandler = npcHandler, text = "My job is to explain about the rules and to get the fee from the competitors." })
keywordHandler:addKeyword({ "mission" }, StdModule.say, { npcHandler = npcHandler, text = "Well I would rather call it an {Ultimate Challenge} than a mission." })
local function creatureSayCallback(npc, creature, type, message)
local player = Player(creature)
local playerId = player:getId()
if not npcHandler:checkInteraction(npc, creature) then
return false
end
local arenaId = player:getStorageValue(Storage.SvargrondArena.Arena)
if MsgContains(message, "fight") or MsgContains(message, "pit") or MsgContains(message, "challenge") or MsgContains(message, "arena") then
if player:getStorageValue(Storage.SvargrondArena.PitDoor) == 1 then
npcHandler:say("You already paid the fee, go and fight!", npc, creature)
return true
end
if arenaId < 1 then
arenaId = 1
player:setStorageValue(Storage.SvargrondArena.Arena, arenaId)
end
if ARENA[arenaId] then
npcHandler:say("So you agree with the {rules} and want to participate in the {challenge}? The {fee} for one try in {" .. ARENA[arenaId].name .. "} is " .. ARENA[arenaId].price .. " gold pieces. Do you really want to participate and pay the {fee}?", npc, creature)
npcHandler:setTopic(playerId, 1)
else
npcHandler:say("You've already completed the arena in all {difficulty levels}.", npc, creature)
npcHandler:setTopic(playerId, 0)
end
elseif npcHandler:getTopic(playerId) == 1 then
if MsgContains(message, "yes") then
if not ARENA[arenaId] then
npcHandler:setTopic(playerId, 0)
return true
end
if player:removeMoneyBank(ARENA[arenaId].price) then
player:setStorageValue(Storage.SvargrondArena.PitDoor, 1)
npcHandler:say("As you wish! You can pass the door now and enter the teleporter to the pits.", npc, creature)
local cStorage = ARENA[arenaId].questLog
if player:getStorageValue(cStorage) ~= 1 then
player:setStorageValue(cStorage, 1)
end
else
npcHandler:say("You do not have enough money.", npc, creature)
end
else
npcHandler:say("Come back when you are ready then.", npc, creature)
end
npcHandler:setTopic(playerId, 0)
end
return true
end
npcHandler:setMessage(MESSAGE_GREET, "Hello competitor! Do you want to {fight} in the arena or shall I explain the {rules} first?")
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new(), npcConfig.name, true, true, true)
-- npcType registering the npcConfig table
npcType:register(npcConfig)
Code:
local specialQuests = {
[51715] = Storage.SvargrondArena.RewardGreenhorn,
[51716] = Storage.SvargrondArena.RewardScrapper,
[51717] = Storage.SvargrondArena.RewardWarlord,
}
Code:
local specialQuests = {
[51715] = Storage.SvargrondArena.RewardGreenhorn,
[51716] = Storage.SvargrondArena.RewardScrapper,
[51717] = Storage.SvargrondArena.RewardWarlord,
}
local questsExperience = {
[3101] = 1, -- dummy values
}
local questLog = {
}
local tutorialIds = {
[50080] = 5,
[50082] = 6,
[50084] = 10,
[50086] = 11,
}
local function copyContainerItem(originalContainer, newContainer)
for i = 0, originalContainer:getSize() - 1 do
local originalItem = originalContainer:getItem(i)
local newItem = Game.createItem(originalItem.itemid, originalItem.type)
if not newItem then
Spdlog.error("[questSystem1.copyContainerItem] failed to create item " .. originalItem.itemid)
return false
end
newItem:setActionId(originalItem:getActionId())
newItem:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, originalItem:getAttribute(ITEM_ATTRIBUTE_DESCRIPTION))
if originalItem:isContainer() then
copyContainerItem(Container(originalItem.uid), Container(newItem.uid))
end
newContainer:addItemEx(newItem)
end
end
local hotaQuest = { 50950, 50951, 50952, 50953, 50954, 50955 }
local questSystem1 = Action()
function questSystem1.onUse(player, item, fromPosition, target, toPosition, isHotkey)
local storage = specialQuests[item.actionid]
if not storage then
storage = item.uid
if storage > 65535 then
return false
end
end
if storage == 23644 or storage == 24632 or storage == 14338 then
player:setStorageValue(Storage.SvargrondArena.PitDoor, -1)
end
if player:getStorageValue(storage) > 0 and player:getGroup():getId() < GROUP_TYPE_GAMEMASTER then
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The " .. ItemType(item.itemid):getName() .. " is empty.")
return true
end
local items, reward = {}
local size = item:isContainer() and item:getSize() or 0
if size == 0 then
reward = Game.createItem(item.itemid, item.type)
if not reward then
logger.error("[questSystem1.onUse] failed to create reward item")
return false
end
local itemActionId = item:getActionId()
if itemActionId then
reward:setActionId(itemActionId)
end
local itemDescription = item:getAttribute(ITEM_ATTRIBUTE_DESCRIPTION)
if itemDescription then
reward:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, itemDescription)
end
else
local container = Container(item.uid)
if not container then
logger.error("[questSystem1.onUse] failed to create container")
return false
end
for i = 0, container:getSize() - 1 do
local originalItem = container:getItem(i)
local newItem = Game.createItem(originalItem.itemid, originalItem.type)
if not newItem then
logger.error("[questSystem1.onUse] failed to create new item")
return false
end
local newActionId = originalItem:getActionId()
if newActionId then
newItem:setActionId(newActionId)
end
local newDescription = item:getAttribute(ITEM_ATTRIBUTE_DESCRIPTION)
if newDescription then
newItem:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, newDescription)
end
if originalItem:isContainer() then
copyContainerItem(Container(originalItem.uid), Container(newItem.uid))
end
items[#items + 1] = newItem
end
if size == 1 then
reward = items[1]
end
end
local result = ""
if reward then
local ret = ItemType(reward.itemid)
if ret:isRune() then
result = ret:getArticle() .. " " .. ret:getName() .. " (" .. reward.type .. " charges)"
elseif ret:isStackable() and reward:getCount() > 1 then
result = reward:getCount() .. " " .. ret:getPluralName()
elseif ret:getArticle() ~= "" then
result = ret:getArticle() .. " " .. ret:getName()
else
result = ret:getName()
end
else
if size > 20 then
reward = Game.createItem(item.itemid, 1)
elseif size > 8 then
reward = Game.createItem(2854, 1)
else
reward = Game.createItem(2853, 1)
end
for i = 1, size do
local tmp = items[i]
if reward:addItemEx(tmp) ~= RETURNVALUE_NOERROR then
logger.warn("[questSystem1.onUse] - Could not add quest reward to container")
end
end
local ret = ItemType(reward.itemid)
result = ret:getArticle() .. " " .. ret:getName()
end
if player:addItemEx(reward) ~= RETURNVALUE_NOERROR then
local weight = reward:getWeight()
if player:getFreeCapacity() < weight then
player:sendCancelMessage(string.format("You have found %s weighing %.2f oz. You have no capacity.", result, (weight / 100)))
else
player:sendCancelMessage("You have found " .. result .. ", but you have no room to take it.")
end
return true
end
if questsExperience[storage] then
player:addExperience(questsExperience[storage], true)
end
if questLog[storage] then
player:setStorageValue(questLog[storage], 1)
end
if tutorialIds[storage] then
player:sendTutorial(tutorialIds[storage])
if item.uid == 50080 then
player:setStorageValue(Storage.RookgaardTutorialIsland.SantiagoNpcGreetStorage, 3)
end
end
if table.contains(hotaQuest, item.uid) then
if player:getStorageValue(Storage.TheAncientTombs.DefaultStart) ~= 1 then
player:setStorageValue(Storage.TheAncientTombs.DefaultStart, 1)
end
end
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found " .. result .. ".")
player:setStorageValue(storage, 1)
return true
end
for index, value in pairs(specialQuests) do
questSystem1:aid(index)
end
questSystem1:aid(2000)
questSystem1:register()
LUA:
local svargrondArenaKill = CreatureEvent("SvargrondArenaKill")
function svargrondArenaKill.onKill(creature, target)
local targetMonster = target:getMonster()
if not targetMonster then
return
end
local player = creature:getPlayer()
local pit = player:getStorageValue(Storage.SvargrondArena.PitDoor)
if pit < 1 or pit > 10 then
return
end
local arena = player:getStorageValue(Storage.SvargrondArena.Arena)
if arena < 1 then
return
end
if not table.contains(ARENA[arena].creatures, targetMonster:getName():lower()) then
return
end
-- Remove pillar and create teleport
local pillarTile = Tile(PITS[pit].pillar)
if pillarTile then
local pillarItem = pillarTile:getItemById(SvargrondArena.itemPillar)
if pillarItem then
pillarItem:remove()
local teleportItem = Game.createItem(SvargrondArena.itemTeleport, 1, PITS[pit].tp)
if teleportItem then
teleportItem:setActionId(25200)
end
SvargrondArena.sendPillarEffect(pit)
end
end
player:setStorageValue(Storage.SvargrondArena.PitDoor, pit + 1)
player:say("Victory! Head through the new teleporter into the next room.", TALKTYPE_MONSTER_SAY)
return true
end
svargrondArenaKill:register()
LUA:
local arenaEnter = MoveEvent()
function arenaEnter.onStepIn(creature, item, position, fromPosition)
local player = creature:getPlayer()
if not player then
return true
end
local pitId = player:getStorageValue(Storage.SvargrondArena.PitDoor)
if pitId < 1 or pitId > 10 then
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You cannot enter without Halvar's permission.")
player:teleportTo(fromPosition, true)
return true
end
local arenaId = player:getStorageValue(Storage.SvargrondArena.Arena)
if not (PITS[pitId] and ARENA[arenaId]) then
player:teleportTo(fromPosition, true)
return true
end
local occupant = SvargrondArena.getPitOccupant(pitId, player)
if occupant then
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, occupant:getName() .. " is currently in the next arena pit. Please wait until " .. (occupant:getSex() == PLAYERSEX_FEMALE and "s" or "") .. "he is done fighting.")
player:teleportTo(fromPosition, true)
return true
end
SvargrondArena.resetPit(pitId)
SvargrondArena.scheduleKickPlayer(player.uid, pitId)
Game.createMonster(ARENA[arenaId].creatures[pitId], PITS[pitId].summon, false, true)
player:teleportTo(PITS[pitId].center)
player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
player:say("FIGHT!", TALKTYPE_MONSTER_SAY)
return true
end
arenaEnter:type("stepin")
arenaEnter:aid(25100)
arenaEnter:register()
LUA:
local condition = Condition(CONDITION_OUTFIT)
condition:setTicks(120000)
condition:setOutfit({ lookType = 111 })
local arenaPit = MoveEvent()
function arenaPit.onStepIn(creature, item, position, fromPosition)
local player = creature:getPlayer()
if not player then
return true
end
local playerId = player.uid
if item.actionid == 25300 then
player:addCondition(condition)
player:setStorageValue(Storage.SvargrondArena.PitDoor, -1)
player:teleportTo(SvargrondArena.kickPosition)
player:say("Coward!", TALKTYPE_MONSTER_SAY)
SvargrondArena.cancelEvents(playerId)
return true
end
local pitId = player:getStorageValue(Storage.SvargrondArena.PitDoor)
local arenaId = player:getStorageValue(Storage.SvargrondArena.Arena)
if pitId > 10 then
player:teleportTo(SvargrondArena.rewardPosition)
player:setStorageValue(Storage.SvargrondArena.PitDoor, 0)
if arenaId == 1 then
SvargrondArena.rewardPosition:sendMagicEffect(CONST_ME_FIREWORK_BLUE)
player:setStorageValue(Storage.SvargrondArena.GreenhornDoor, 1)
player:say("Welcome back, little hero!", TALKTYPE_MONSTER_SAY)
elseif arenaId == 2 then
SvargrondArena.rewardPosition:sendMagicEffect(CONST_ME_FIREWORK_YELLOW)
player:setStorageValue(Storage.SvargrondArena.ScrapperDoor, 1)
player:say("Congratulations, brave warrior!", TALKTYPE_MONSTER_SAY)
elseif arenaId == 3 then
SvargrondArena.rewardPosition:sendMagicEffect(CONST_ME_FIREWORK_RED)
player:setStorageValue(Storage.SvargrondArena.WarlordDoor, 1)
player:say("Respect and honour to you, champion!", TALKTYPE_MONSTER_SAY)
end
player:setStorageValue(Storage.SvargrondArena.Arena, player:getStorageValue(Storage.SvargrondArena.Arena) + 1)
player:say("Congratulations! You completed " .. ARENA[arenaId].name .. " arena, you should take your reward now.")
player:setStorageValue(ARENA[arenaId].questLog, 2)
player:addAchievement(ARENA[arenaId].achievement)
SvargrondArena.cancelEvents(playerId)
return true
end
local occupant = SvargrondArena.getPitOccupant(pitId, player)
if occupant then
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, occupant:getName() .. " is currently in the next arena pit. Please wait until " .. (occupant:getSex() == PLAYERSEX_FEMALE and "s" or "") .. "he is done fighting.")
player:teleportTo(fromPosition, true)
return true
end
SvargrondArena.cancelEvents(playerId)
SvargrondArena.resetPit(pitId)
SvargrondArena.scheduleKickPlayer(playerId, pitId)
Game.createMonster(ARENA[arenaId].creatures[pitId], PITS[pitId].summon, false, true)
player:teleportTo(PITS[pitId].center)
player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
player:say("Fight!", TALKTYPE_MONSTER_SAY)
return true
end
arenaPit:type("stepin")
arenaPit:aid(25200, 25300)
arenaPit:register()
LUA:
local arenaTrophy = MoveEvent()
function arenaTrophy.onStepIn(creature, item, position, fromPosition)
local player = creature:getPlayer()
if not player then
return true
end
local arenaId = ARENA_TROPHY[item.uid]
if not arenaId then
return true
end
local storage = arenaId.trophyStorage
if player:getStorageValue(storage) == 1 then
return true
end
local rewardPosition = player:getPosition()
rewardPosition.y = rewardPosition.y - 1
local rewardItem = Game.createItem(arenaId.trophy, 1, rewardPosition)
if rewardItem then
rewardItem:setDescription(string.format(arenaId.desc, player:getName()))
end
player:setStorageValue(storage, 1)
player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
return true
end
arenaTrophy:type("stepin")
arenaTrophy:uid(3264, 3265, 3266)
arenaTrophy:register()
LUA:
-- Svargrond arena door
[Storage.SvargrondArena.PitDoor] = {
itemId = false,
itemPos = {
{ x = 5042, y = 5040, z = 7 },
{ x = 5042, y = 5041, z = 7 },
{ x = 5042, y = 5042, z = 7 },
},
},
[Storage.SvargrondArena.GreenhornDoor] = {
itemId = false,
itemPos = { { x = 5036, y = 5008, z = 7 } },
},
[Storage.SvargrondArena.ScrapperDoor] = {
itemId = false,
itemPos = { { x = 5036, y = 5001, z = 7 } },
},
[Storage.SvargrondArena.WarlordDoor] = {
itemId = false,
itemPos = { { x = 5036, y = 4994, z = 7 } },
},
All scipts and map is compatibile with Canary 3.0.0
All my scripts and map you find on my github
Everything is compatibile with my maps if you want use on your own you have to configure on youself.
Any question send me PM
NOT TESTED ON TFS
Attachments
-
world.tar.gz594.9 KB · Views: 10 · VirusTotal
Last edited: