ralke
(҂ ͠❛ ෴ ͡❛)ᕤ
Hi! Today I will share the first mission of Wrath of the Emperor, "Catering the Lion's Den". With the help @Xikini we took the video of the quest and orts datapack references to build it, and the result is a perfectly working first mission. He coded everything, I did the testings all on discord.
This is the guide video
The first thing that we scripted for the mission is the Marked Crate, this will allow you to use the crate as disguise to get throw the mission.
For this we go to actions/scripts/quests/wrath of the emperor/mission01crate.lua and paste the following:
Another action script we will use are the levers of the quest. This are used to turn off the lights, and to take off the wall on the lower floor.
For this we go to actions/scripts/quests/wrath of the emperor/mission01lever.lua and paste:
Then register both scripts on actions.xml:
Now we have to do the moveevents to catch the player when he does a wrong action.
For this we go to movements/scripts/quests/wrath of the emperor/crate.lua and paste:
Then register the script on movements.xml:
Now we need a globalevent, because there's some windows on the passage doors that open/closes showing up guard's eyes.
Lets go to globalevents/scripts/wrath of the emperor/spydoors.lua and paste:
And register it to globalevents.xml with:
Now we need the npc that will take us out of the prison (where the player goes after a wrong action).
For this we go to data/npc/scripts and create Zumtah.lua
Create the .xml on data/npc aswell:
We also need the Lizard Tunnel Guard npc that will send us to prison if we talk nearby.
For this one we go to data/npc/scripts/Lizard Tunel Guard.lua and paste:
Then create the Lizard Tunnel Guard.xml file at data/npc.
And we're done. Everything should work, we tested every possibility that could happen on the script. Now you have to import the attached map we did on the same positions to make it work. If you wish to change the positions, just match the code with your map.
A fast view to the outcome:
Again, a big thanks to @Xikini for taking the time to help me with this.
Hope you guys enjoy it, regards!
This is the guide video
The first thing that we scripted for the mission is the Marked Crate, this will allow you to use the crate as disguise to get throw the mission.
For this we go to actions/scripts/quests/wrath of the emperor/mission01crate.lua and paste the following:
Lua:
local useableAreas = {
{Position(1115, 723, 12), Position(1209, 861, 12)},
{Position(1125, 731, 13), Position(1176, 749, 13)},
}
local condition = Condition(CONDITION_OUTFIT)
condition:setOutfit({lookTypeEx = 12496})
condition:setTicks(-1)
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
local outfit = player:getOutfit()
if outfit.lookTypeEx ~= 12496 then
local usuable = false
for i = 1, 2 do
if player:getPosition():isInRange(useableAreas[i][1], useableAreas[i][2]) then
usuable = true
break
end
end
if not usuable then
player:say("This is not the time or place to use this.", TALKTYPE_MONSTER_SAY, false, player)
return true
end
player:addCondition(condition)
player:getPosition():sendMagicEffect(CONST_ME_POFF)
end
return true
end
Another action script we will use are the levers of the quest. This are used to turn off the lights, and to take off the wall on the lower floor.
For this we go to actions/scripts/quests/wrath of the emperor/mission01lever.lua and paste:
Lua:
local lights = {
{11447, 11446}, -- on/off
{11449, 11448}, -- vertical
}
local leverIds = {10044, 10045}
local levers = {
[8030] = {
{Position(1163, 747, 12), 1},
{Position(1166, 747, 12), 1},
{Position(1169, 747, 12), 1}
},
[8031] = {
{Position(1154, 751, 12), 2},
{Position(1151, 749, 12), 2}
},
[8032] = {
{Position(1140, 746, 12), 2},
},
[8033] = {
{Position(1149, 740, 13), 9264},
{Position(1149, 741, 13), 9207},
{Position(1149, 742, 13), 9209},
{Position(1149, 743, 13), 9264}
}
}
local positionAdjustment = {
{-1, -1},
{0, -1},
{1, -1},
{-1, 0},
{0, 0},
{1, 0},
{-1, 1},
{0, 1},
{1, 1}
}
local function catchPlayer(player)
player:teleportTo(Position(1155, 878, 12), false)
player:say("The guards have spotted you. You were forcibly dragged into a small cell. It looks like you need to build another disguise.", TALKTYPE_MONSTER_SAY, false, player)
return true
end
local function checkNineTiles(position)
for i = 1, 9 do
local position_ = Position(position.x + positionAdjustment[i][1], position.y + positionAdjustment[i][2], position.z)
local creatures = Tile(position_):getCreatures()
if creatures then
for n = 1, #creatures do
local player = Player(creatures[n])
if player then
catchPlayer(player)
end
end
end
end
end
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
local leverId = item:getId()
item:transform(leverId == leverIds[1] and leverIds[2] or leverIds[1])
local itemActionId = item:getActionId()
if table.contains({8030, 8031, 8032}, itemActionId) then
if leverId == leverIds[1] then
for i = 1, #levers[itemActionId] do
Tile(levers[itemActionId][i][1]):getItemById(levers[itemActionId][i][2] == 1 and lights[1][1] or lights[2][1]):transform(levers[itemActionId][i][2] == 1 and lights[1][2] or lights[2][2])
end
else
for i = 1, #levers[itemActionId] do
Tile(levers[itemActionId][i][1]):getItemById(levers[itemActionId][i][2] == 1 and lights[1][2] or lights[2][2]):transform(levers[itemActionId][i][2] == 1 and lights[1][1] or lights[2][1])
checkNineTiles(levers[itemActionId][i][1])
end
end
return true
end
if itemActionId == 8033 then
for i = 1, 4 do
local wall = Tile(levers[itemActionId][i][1]):getItemById(levers[itemActionId][i][2])
if wall then
wall:remove()
end
end
return true
end
return true
end
Then register both scripts on actions.xml:
XML:
<!-- Wrath of the Emperor -->
<action fromaid="8030" toaid="8033" script="quests/wrath of the emperor/mission01_levers.lua" />
<action itemid="12284" script="quests/wrath of the emperor/Mission01Crate.lua" />
Now we have to do the moveevents to catch the player when he does a wrong action.
For this we go to movements/scripts/quests/wrath of the emperor/crate.lua and paste:
Lua:
local wallPositions = {
{Position(1149, 740, 13), 9264},
{Position(1149, 741, 13), 9207},
{Position(1149, 742, 13), 9209},
{Position(1149, 743, 13), 9264}
}
local positionAdjustment = {
{ 1, 1},
{ 0, 1},
{-1, 1},
{ 1, 0},
{ 0, 0},
{-1, 0},
{ 1, -1},
{ 0, -1},
{-1, -1}
}
local function catchPlayer(player)
player:teleportTo(Position(1155, 878, 12), false)
player:say("The guards have spotted you. You were forcibly dragged into a small cell. It looks like you need to build another disguise.", TALKTYPE_MONSTER_SAY, false, player)
return true
end
local function checkThreeTiles(position)
for i = 1, 3 do
local position_ = Position(position.x + i, position.y, position.z)
local creatures = Tile(position_):getCreatures()
if creatures then
for n = 1, #creatures do
local player = Player(creatures[n])
if player then
catchPlayer(player)
end
end
end
end
end
local function sendText(playerId, text)
local player = Player(playerId)
if player then
player:say(text, TALKTYPE_MONSTER_SAY, false, player)
end
end
function onStepIn(creature, item, position, fromPosition)
local player = Player(creature)
if not player then
return true
end
local tileActionId = item:getActionId()
local outfit = player:getOutfit()
-- beetle hole
if tileActionId == 8036 then
if outfit.lookType ~= 348 then
player:say("You are too large too fit in the hole.", TALKTYPE_MONSTER_SAY, false, player)
else
player:removeCondition(CONDITION_OUTFIT)
player:teleportTo(Position(1153, 855, 12))
end
return true
end
-- final stairs
if tileActionId == 8020 then
if outfit.lookTypeEx == 12496 then
player:removeCondition(CONDITION_OUTFIT)
if item:getId() ~= 9023 then
addEvent(sendText, 0, player:getId(), "On reaching the watchtower you remove your temporary disguise.")
else
addEvent(sendText, 0, player:getId(), "You take off your disguise, as it's not needed here.")
end
end
return true
end
-- warn player of box requirement
if tileActionId == 8015 then
player:say("You hear guards moving behind doors in the distance. If you have any sort of disguise with you, this is the moment to use it.", TALKTYPE_MONSTER_SAY, false, player)
return true
end
-- box check
if outfit.lookTypeEx ~= 12496 then
catchPlayer(player)
return true
end
-- 8016 is box check only
local playerPos = player:getPosition()
if tileActionId == 8017 then
catchPlayer(player)
checkThreeTiles(position)
return true
end
if tileActionId == 8018 then
local doorOpen = Tile(Position(playerPos.x - 2, playerPos.y, playerPos.z)):getItemById(12213)
if doorOpen then
catchPlayer(player)
end
return true
end
if tileActionId == 8019 then
local doorOpen = Tile(Position(playerPos.x - 3, playerPos.y, playerPos.z)):getItemById(12213)
if doorOpen then
catchPlayer(player)
end
return true
end
if tileActionId >= 8021 and tileActionId <= 8029 then
local verticalLight = Tile(Position(position.x + positionAdjustment[tileActionId - 8020][1], position.y + positionAdjustment[tileActionId - 8020][2], position.z)):getItemById(11449)
local horizontalLight = Tile(Position(position.x + positionAdjustment[tileActionId - 8020][1], position.y + positionAdjustment[tileActionId - 8020][2], position.z)):getItemById(11447)
if verticalLight or horizontalLight then
catchPlayer(player)
return true
end
end
if tileActionId == 8034 then
player:say("Guards heavily patrol this area. Try to stay hidden and do not draw any attention to yourself by trying to attack.", TALKTYPE_MONSTER_SAY, false, player)
return true
end
if tileActionId == 8035 then
for i = 1, 4 do
local wall = Tile(wallPositions[i][1]):getItemById(wallPositions[i][2])
if wall then
return true
end
Game.createItem(wallPositions[i][2], 1, wallPositions[i][1])
end
return true
end
return true
end
Then register the script on movements.xml:
XML:
<!-- Wrath of the Emperor -->
<movevent event="StepIn" fromaid="8015" toaid="8029" script="quests/wrath of the emperor/crate.lua" />
<movevent event="StepIn" fromaid="8034" toaid="8036" script="quests/wrath of the emperor/crate.lua" />
Now we need a globalevent, because there's some windows on the passage doors that open/closes showing up guard's eyes.
Lets go to globalevents/scripts/wrath of the emperor/spydoors.lua and paste:
Lua:
local doorIds = {12214, 12213} -- closed, open
local doorPositions = {
Position(1179, 811, 12),
Position(1179, 806, 12),
Position(1179, 798, 12),
Position(1179, 791, 12),
Position(1179, 790, 12),
Position(1174, 765, 12),
Position(1174, 757, 12)
}
function catchPlayer(player)
player:teleportTo(Position(1155, 878, 12), false)
player:say("The guards have spotted you. You were forcibly dragged into a small cell. It looks like you need to build another disguise.", TALKTYPE_MONSTER_SAY, false, player)
return true
end
local function checkThreeTiles(position)
for i = 1, 3 do
local position_ = Position(position.x + i, position.y, position.z)
local creatures = Tile(position_):getCreatures()
if creatures then
for n = 1, #creatures do
local player = Player(creatures[n])
if player then
catchPlayer(player)
end
end
end
end
end
local function wrathOfEmperorSpyDoors(index)
local rand
local doorClosed = Tile(doorPositions[index]):getItemById(doorIds[1])
local doorOpen = Tile(doorPositions[index]):getItemById(doorIds[2])
if doorOpen then
doorOpen:transform(doorIds[1])
if index == 4 then
Tile(doorPositions[5]):getItemById(doorIds[2]):transform(doorIds[1])
end
rand = math.random(2000, 3000)
else
doorClosed:transform(doorIds[2])
checkThreeTiles(doorPositions[index])
if index == 4 then
Tile(doorPositions[5]):getItemById(doorIds[1]):transform(doorIds[2])
checkThreeTiles(doorPositions[5])
end
rand = math.random(10000, 15000)
end
addEvent(wrathOfEmperorSpyDoors, rand, index)
end
function onStartup()
for i = 1, #doorPositions do
if i ~= 5 then
addEvent(wrathOfEmperorSpyDoors, 1000, i)
end
end
return true
end
And register it to globalevents.xml with:
XML:
<globalevent type="startup" name="Spy_Doors" script="wrath of the emperor/spydoors.lua" />
Now we need the npc that will take us out of the prison (where the player goes after a wrong action).
For this we go to data/npc/scripts and create Zumtah.lua
Lua:
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, type, msg)
npcHandler:onCreatureSay(cid, type, msg)
end
function onThink()
npcHandler:onThink()
end
local condition = Condition(CONDITION_OUTFIT)
condition:setOutfit({lookType = 348})
condition:setTicks(-1)
local function creatureSayCallback(cid, type, msg)
if not npcHandler:isFocused(cid) then
return false
end
local player = Player(cid)
if msgcontains(msg, "exit") then
local outfit = player:getOutfit()
if outfit.lookType ~= 348 then
if npcHandler.topic[cid] < 1 then
npcHandler:say("Oh of course, may I show you around a bit before? You want to go straight to the exit? Would you please follow me. Oh right, I am terribly sorry but THERE IS NONE. Will you finally give it up please?", cid)
npcHandler.topic[cid] = 1
elseif npcHandler.topic[cid] == 3 then
npcHandler.topic[cid] = 4
elseif npcHandler.topic[cid] == 6 then
npcHandler.topic[cid] = 7
elseif npcHandler.topic[cid] == 10 then
npcHandler:say("Oh, you mean - if I have ever been out of here in those 278 years? Well, I - I can't remember. No, I can't remember. Sorry.", cid)
npcHandler.topic[cid] = 11
elseif npcHandler.topic[cid] == 11 then
npcHandler:say("No, I really can't remember. I enjoyed my stay here so much that I forgot how it looks outside of this hole. Outside. The air, the sky, the light. Oh well... well.", cid)
npcHandler.topic[cid] = 12
elseif npcHandler.topic[cid] == 12 then
npcHandler:say("Oh yes, yes. I... I never really thought about how you creatures feel in here I guess. I... just watched all these beings die here. ...", cid)
npcHandler.topic[cid] = 13
elseif npcHandler.topic[cid] == 13 then
npcHandler:say("Oh, excuse me of course, you... wanted to go. Like all... the others. I am sorry, so sorry. You... you can leave. Yes. You can go. You are free. I shall stay here and help every poor soul which ever gets thrown in here from this day onward. ...", cid)
npcHandler.topic[cid] = 14
elseif npcHandler.topic[cid] == 14 then
npcHandler:say({
"Alright, as I said you are free now. There will not be an outside for the next three centuries, but you - go. ...",
"Oh and I recovered the strange crate you where hiding in, it will wait for you at the exit since you can't carry it as... a beetle, muhaha. Yes, you shall now crawl through the passage as a beetle. There you go."
}, cid)
npcHandler.topic[cid] = 0
player:addCondition(condition)
end
else
npcHandler:say("It's you, why did they throw you in here again? Anyway, I will just transform you once more. I also recovered your crate which will wait for you at the exit. There, feel free to go.", cid)
player:addCondition(condition)
end
elseif msgcontains(msg, "no") then
if npcHandler.topic[cid] == 1 then
npcHandler:say("You are starting to get on my nerves. Is this the only topic you know?", cid)
npcHandler.topic[cid] = 2
elseif npcHandler.topic[cid] == 4 then
npcHandler.topic[cid] = 5
elseif npcHandler.topic[cid] == 7 then
npcHandler.topic[cid] = 8
end
elseif msgcontains(msg, "yes") then
if npcHandler.topic[cid] == 2 then
npcHandler:say("Pesky, persistent human.", cid)
npcHandler.topic[cid] = 3
elseif npcHandler.topic[cid] == 5 then
npcHandler.topic[cid] = 6
elseif npcHandler.topic[cid] == 8 then
npcHandler:say("Muhahaha. Then I will give you a test. How many years do you think have I been here? {89}, {164} or {278}?", cid)
npcHandler.topic[cid] = 9
end
elseif msgcontains(msg, "278") and npcHandler.topic[cid] == 9 then
npcHandler:say("Correct human, and that is not nearly how high you would need to count to tell all the lost souls I've seen dying here. I AM PERPETUAL. Muahahaha.", cid)
npcHandler.topic[cid] = 10
elseif (msgcontains(msg, "164") or msgcontains(msg, "89")) and npcHandler.topic[cid] == 9 then
npcHandler:say("Wrong answer human! Muahahaha.", cid)
npcHandler.topic[cid] = 0
end
return true
end
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
Create the .xml on data/npc aswell:
XML:
<?xml version="1.0" encoding="UTF-8"?>
<npc name="Zumtah" script="Zumtah.lua" walkinterval="2000" floorchange="0">
<health now="100" max="100" />
<look type="51" />
<parameters>
<parameter key="message_greet" value="Another visitor to this constricted, cosy, calm realm, perfect except for an {exit}. Muhaha." />
</parameters>
</npc>
We also need the Lizard Tunnel Guard npc that will send us to prison if we talk nearby.
For this one we go to data/npc/scripts/Lizard Tunel Guard.lua and paste:
Lua:
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, type, msg) npcHandler:onCreatureSay(cid, type, msg) end
function onThink() npcHandler:onThink() end
local function creatureSayCallback(cid, type, msg)
local player = Player(cid)
player:teleportTo(Position(1155, 878, 12))
player:say("The guards have spotted you. You were forcibly dragged into a small cell. It looks like you need to build another disguise.", TALKTYPE_MONSTER_SAY)
return true
end
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
Then create the Lizard Tunnel Guard.xml file at data/npc.
XML:
<?xml version="1.0" encoding="UTF-8"?>
<npc name="Lizard Tunnel Guard" script="Lizard Tunnel Guard.lua" walkinterval="0" floorchange="0">
<health now="100" max="100" />
<look type="338" />
</npc>
And we're done. Everything should work, we tested every possibility that could happen on the script. Now you have to import the attached map we did on the same positions to make it work. If you wish to change the positions, just match the code with your map.
A fast view to the outcome:
Again, a big thanks to @Xikini for taking the time to help me with this.
Hope you guys enjoy it, regards!
Attachments
-
wote_mission01.rar47.4 KB · Views: 5 · VirusTotal
Last edited: