Skip to content

Commit

Permalink
feat: implement OTBM Zones, encounters, and raids systems (#1712)
Browse files Browse the repository at this point in the history
This introduces three new systems:

• OTBM Zones: Enables direct editing of zones into the map binary, facilitating the creation of large or irregularly shaped zones. A companion PR has been submitted to RME (opentibiabr/remeres-map-editor#56).

• Encounters: Introduces a flexible framework for defining scripted fights, simplifying the API for easy understanding and implementation. Encounters are tied to Zones and can be triggered via a boss lever. See the Magma Bubble script in this PR for a comprehensive example.

• Raids: A specialized subset of Encounters, Raids are self-scheduling and can spawn within defined zones. This PR replaces Thais' Wild Horse and Rat raids with examples utilizing the new system.
  • Loading branch information
luan authored Oct 21, 2023
1 parent e2263fe commit 393179c
Show file tree
Hide file tree
Showing 53 changed files with 1,159 additions and 440 deletions.
2 changes: 0 additions & 2 deletions data-otservbr-global/raids/raids.xml
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,6 @@
<!-- Thais -->
<raid name="Cyclops" file="thais/cyclops.xml" interval2="500" margin="30" />
<raid name="OrcsThais" file="thais/orcs.xml" interval2="500" margin="70" />
<raid name="RatsThais" file="thais/rats.xml" interval2="500" margin="80" />
<raid name="Wild Horses" file="thais/wild_horses.xml" interval2="500" margin="80" />
<!-- Venore -->
<raid name="Dharalion" file="venore/dharalion.xml" interval2="500" margin="70" />
<raid name="Elves" file="venore/elves.xml" interval2="500" margin="80" />
Expand Down
6 changes: 0 additions & 6 deletions data-otservbr-global/scripts/globalevents/spawn/raids.lua
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
local raids = {
-- Weekly
--Segunda-Feira
["Monday"] = {
["06:00"] = { raidName = "RatsThais" },
},

--Terça-Feira
["Tuesday"] = {
["16:00"] = { raidName = "Midnight Panther" },
Expand Down
3 changes: 1 addition & 2 deletions data-otservbr-global/scripts/lib/register_actions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -465,8 +465,7 @@ function onUseShovel(player, item, fromPosition, target, toPosition, isHotkey)
if table.contains(holes, target.itemid) then
target:transform(target.itemid + 1)
target:decay()
toPosition:moveDownstairs()
toPosition.y = toPosition.y - 1
toPosition.z = toPosition.z + 1
if Tile(toPosition):hasFlag(TILESTATE_PROTECTIONZONE) and player:isPzLocked() then
player:sendCancelMessage(RETURNVALUE_PLAYERISPZLOCKED)
return true
Expand Down
5 changes: 5 additions & 0 deletions data-otservbr-global/scripts/lib/register_monster_type.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ registerMonsterType.description = function(mtype, mask)
mtype:nameDescription(mask.description)
end
end
registerMonsterType.variant = function(mtype, mask)
if mask.variant then
mtype:variant(mask.variant)
end
end
registerMonsterType.experience = function(mtype, mask)
if mask.experience then
mtype:experience(mask.experience)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,71 +25,67 @@ spawnZone:addArea({ x = 33647, y = 32900, z = 15 }, { x = 33659, y = 32913, z =
local encounter = Encounter("Magma Bubble", {
zone = bossZone,
spawnZone = spawnZone,
timeToSpawnMonsters = 2,
timeToSpawnMonsters = "2s",
})

encounter:addStage({
prepare = function()
encounter:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You've entered the volcano.")
end,

start = function()
encounter:spawnMonsters({
name = "The End of Days",
amount = 3,
event = "fight.magma-bubble.TheEndOfDaysHealth",
})
encounter:spawnMonsters({
name = "Magma Crystal",
event = "fight.magma-bubble.MagmaCrystalDeath",
positions = {
Position(33647, 32891, 15),
Position(33647, 32926, 15),
Position(33670, 32898, 15),
},
})
end,
function encounter:onReset(position)
encounter:removeMonsters()
end

finish = function()
encounter:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The whole Volcano starts to vibrate! Prepare yourself!")
end,
encounter:addRemoveMonsters():autoAdvance()
encounter:addBroadcast("You've entered the volcano."):autoAdvance("1s")

encounter:addSpawnMonsters({
{
name = "The End of Days",
amount = 3,
event = "fight.magma-bubble.TheEndOfDaysHealth",
},
{
name = "Magma Crystal",
event = "fight.magma-bubble.MagmaCrystalDeath",
positions = {
Position(33647, 32891, 15),
Position(33647, 32926, 15),
Position(33670, 32898, 15),
},
},
})

encounter:addIntermission(3000)

encounter:addStage({
start = function()
encounter:spawnMonsters({
name = "The End of Days",
amount = 8,
event = "fight.magma-bubble.TheEndOfDaysDeath",
})
end,
encounter:addRemoveMonsters():autoAdvance()
encounter:addBroadcast("The whole Volcano starts to vibrate! Prepare yourself!"):autoAdvance("3s")

finish = function()
encounter:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You've upset the volcano and now it's going to take its revenge!")
end,
encounter:addSpawnMonsters({
{
name = "The End of Days",
amount = 8,
event = "fight.magma-bubble.TheEndOfDaysDeath",
},
})

encounter:addIntermission(3000)
encounter:addRemoveMonsters():autoAdvance()
encounter:addBroadcast("You've upset the volcano and now it's going to take its revenge!"):autoAdvance("3s")

encounter:addStage({
start = function()
encounter:spawnMonsters({
encounter
:addSpawnMonsters({
{
name = "Magma Bubble",
event = "fight.magma-bubble.MagmaBubbleDeath",
positions = {
Position(33654, 32909, 15),
},
})
for i = 0, 4 do
table.insert(encounter.events, addEvent(encounter.spawnMonsters, (45 * i + 10) * 1000, encounter, { name = "Unchained Fire", amount = 5 }))
end
end,
})
},
})
:autoAdvance("10s")

function encounter.beforeEach()
encounter:removeMonsters()
for i = 0, 4 do
local stage = encounter:addSpawnMonsters({
{ name = "Unchained Fire", amount = 5 },
})

if i < 4 then
stage:autoAdvance("45s")
end
end

encounter:register()
Expand Down Expand Up @@ -139,7 +135,7 @@ function overheatedDamage.onThink(interval, lastExecution)
player:getPosition():sendMagicEffect(effect)
else
local damage = player:getMaxHealth() * 0.6 * -1
doTargetCombatHealth(0, player, COMBAT_NEUTRALDAMAGE, damage, damage, CONST_ME_NONE)
doTargetCombatHealth(0, player, COMBAT_AGONYDAMAGE, damage, damage, CONST_ME_NONE)
end
::continue::
end
Expand Down Expand Up @@ -224,7 +220,8 @@ function chargedFlameAction.onUse(player, item, fromPosition, target, toPosition
}
local position = randomPosition(positions)
position:sendMagicEffect(CONST_ME_FIREAREA)
Game.createItem(magicFieldId, 1, position)
local field = Game.createItem(magicFieldId, 1, position)
field:decay()
item:remove()
end

Expand Down Expand Up @@ -271,7 +268,7 @@ function magmaCrystalDeath.onDeath()
if crystals == 0 then
encounter:nextStage()
else
encounter:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A magma crystal has been destroyed! " .. crystals .. " remaining.")
encounter:broadcast(MESSAGE_EVENT_ADVANCE, "A magma crystal has been destroyed! " .. crystals .. " remaining.")
end
end

Expand Down
41 changes: 41 additions & 0 deletions data-otservbr-global/scripts/raids/thais/rats.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
local zone = Zone("thais.rats")
zone:addArea(Position(32331, 32182, 7), Position(32426, 32261, 7))

local raid = Raid("thais.rats", {
zone = zone,
allowedDays = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" },
minActivePlayers = 0,
targetChancePerDay = 30,
maxChancePerCheck = 50,
minGapBetween = "36h",
})

raid:addBroadcast("Rat Plague in Thais!"):autoAdvance("5s")

raid
:addSpawnMonsters({
{
name = "Rat",
amount = 10,
},
{
name = "Cave Rat",
amount = 10,
},
})
:autoAdvance("10m")

raid
:addSpawnMonsters({
{
name = "Rat",
amount = 20,
},
{
name = "Cave Rat",
amount = 20,
},
})
:autoAdvance("10m")

raid:register()
27 changes: 27 additions & 0 deletions data-otservbr-global/scripts/raids/thais/wild_horses.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
local zone = Zone("thais.wild-horses")
zone:addArea(Position(32456, 32193, 7), Position(32491, 32261, 7))
zone:addArea(Position(32431, 32240, 7), Position(32464, 32280, 7))

local raid = Raid("thais.wild-horses", {
zone = zone,
allowedDays = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" },
minActivePlayers = 0,
initialChance = 30,
targetChancePerDay = 50,
maxChancePerCheck = 50,
maxChecksPerDay = 2,
minGapBetween = "23h",
})

for _ = 1, 7 do
raid
:addSpawnMonsters({
{
name = "Wild Horse",
amount = 3,
},
})
:autoAdvance("3h")
end

raid:register()
1 change: 1 addition & 0 deletions data/events/events.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Therefore, we strongly encourage avoiding the use of this file when possible, as
<event class="Party" method="onJoin" enabled="1" />
<event class="Party" method="onLeave" enabled="1" />
<event class="Party" method="onShareExperience" enabled="1" />
<event class="Party" method="onDisband" enabled="1" />

<!-- Player Methods -->
<event class="Player" method="onChangeZone" enabled="1" />
Expand Down
Loading

3 comments on commit 393179c

@Risk-CPU
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-zones.xml: File was not found

@dudantas
Copy link
Member

@dudantas dudantas commented on 393179c Oct 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-zones.xml: File was not found

For these modifications to work correctly, it is necessary to open and save the map using the remeres in this pull:
opentibiabr/remeres-map-editor#56

@Risk-CPU
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-zones.xml: File was not found

You need to save your map with the remeres of this pull request: opentibiabr/remeres-map-editor#56

its still open, will w8 untill merged. thanks

Please sign in to comment.