If you are curious about use cases, here are some features that were developed using the Zone System: https://github.com/lyuz1n/zone-system-features/tree/main
Zone System is a revolutionary tool that makes it possible to determine specific zones for specific actions, being possible to manipulate within the zone, all creatures, tiles and positions.
In addition to the ease of manipulating everything that happens inside the zones, your code, consequently, becomes more minimalist and abstract, discarding area iterations, getSpectators and other means that can cause a bottleneck.
A zone doesn't necessarily have to be square, it can be a straight line, a circle, a triangle, it can be a zone separated into pieces, it can be whatever you want, just use the Zone Brush in Remeres Map Editor and define how you want your zone and what will be the id.
Zone System has an optimized data structure, making it perform better than the means mentioned above (in occasions where it is necessary to scan the creatures within an area
). To get an idea, see the implementation of the method that gets all monsters within a specific zone:
const std::unordered_map<uint32_t, Monster*>& getMonsters() const {
return monsters;
};
As we can see, it is a constant method. The other methods getPlayers, getNpcs, getTiles and getPositions also follow this same rule.
We can work in C++, but the Zone System was specially developed to work in Lua. These are some available methods and events:
local allZones = Game.getZones()
local zone = tile:getZone()
local zone = creature:getZone()
local zone = Zone(4598)
local id = zone:getId()
local tiles = zone:getTiles()
local players = zone:getPlayers()
local monsters = zone:getMonsters()
local npcs = zone:getNpcs()
local positions = zone:getPositions()
local playersCount = zone:getPlayersCount()
local monstersCount = zone:getMonstersCount()
local npcsCount = zone:getNpcsCount()
zone:clean()
zone:removeMonsters()
zone:removeNpcs()
local zoneEvent = ZoneEvent(4598)
function zoneEvent.onPlayerEnter(player, zone)
print('player entered the zone with id 4598')
return true
end
function zoneEvent.onMonsterEnter(monster, zone)
print('monster entered the zone with id 4598')
return true
end
function zoneEvent.onNpcEnter(npc, zone)
print('npc entered the zone with id 4598')
return true
end
zoneEvent:register()
If we select an area or quest map with a zone id, we can monitor all players, monsters, npcs, tiles and positions in real time. Below is an example of how we can do this:
After using the Zone Brush across the desired area (as in the image above), we can monitor it as follows:
local zone = Zone(7285)
local players = zone:getPlayers()
local monsters = zone:getMonsters()
local npcs = zone:getNpcs()
local tiles = zone:getTiles()
local positions = zone:getPositions()
We can make countless conditions based on the zone the creature is in. See this example where a specific zone does not allow the use of the exani hur
spell:
local zoneId = 4567
function onCastSpell(creature, variant)
local zone = creature:getZone()
if zone and zone:getId() == zoneId then
player:sendCancelMessage('You cannot use this spell in this zone.')
return false
end
local returnValue = levitate(creature, variant:getString())
if returnValue ~= RETURNVALUE_NOERROR then
creature:sendCancelMessage(returnValue)
creature:getPosition():sendMagicEffect(CONST_ME_POFF)
return false
end
return true
end
To implement the Zone System, we recommend TFS (otland/forgottenserver) and RME (hampusborgos/rme).
if you don't use these repositories, some adaptations are necessary.
Zone System is excellent for events, boss rooms, quests, systems involving large areas, zone checks, blocking entry into areas and others.
Next update: make the Zone System serve coffee, because everything else it already does :D