ralke
(҂ ͠❛ ෴ ͡❛)ᕤ
Hi! Here's a system made by @Itutorial all credits to him. I wanted to share this in case someone want to use it. This system is a request made in the following thread: Lua - Don't waste potions and runes on area (frompos topos) (https://otland.net/threads/dont-waste-potions-and-runes-on-area-frompos-topos.281692/#post-2700178)
How it works?:
Remere's Set-up (images)
First we need to go to our actions/scripts/liquids/potions.lua and replace this
For
Add this anywhere in global.lua
On data/events/scripts/player.lua add this below
Go to creaturescripts/scripts/login.lua add:
Now in data/scripts create a new file (example: pvpArena.lua) and add this
Now the c++ part
Go to player.h and find: void updateRegeneration(); add under:
Now find: bool inventoryAbilities add under:
Go to luascript.h and find: static int luaPlayerSetStorageValue(lua_State* L); add under:
Go to luascript.cpp and find: registerMethod("Player", "setStorageValue", LuaScriptInterface::luaPlayerSetStorageValue); add under
Now find: int LuaScriptInterface::luaPlayerSetStorageValue(lua_State* L) under whole method add:
Now go to weapons.cpp and look for this:
Change it for this:
In case you have spears that are dropped on the ground, then change this:
To this
Regards!
How it works?:
- PVP arena has 2 entrance tiles. Each one, for a different town
- The entrance, and the exits must be determined on tileEnterPos, tileExitPos, enterPos, exitPos
- This tiles are onStepIn events that makes the player get inside the arena and set creature:setPvPArenaPlayer condition.
- As soon the player enters the arena it's going to have infinite potions, ammunition and runes.
- Also function creatureeventPvPArena.onPrepareDeath(creature, killer) will prevent player's death if is inside the arena.
- After being "killed" the player will spawn on exitPos
- You must use PVP tiles and no-logout tiles inside the arena
Remere's Set-up (images)
First we need to go to our actions/scripts/liquids/potions.lua and replace this
Lua:
item:remove(1)
return true
end
For
Lua:
if not player:isPvPArenaPlayer() then
item:remove(1)
end
return true
end
Add this anywhere in global.lua
Lua:
PVP_ARENA_PLAYERS = {}
On data/events/scripts/player.lua add this below
function Player:onGainSkillTries(skill, tries)
Lua:
if self:isPvPArenaPlayer() then
return 0
end
Go to creaturescripts/scripts/login.lua add:
Lua:
player:registerEvent("PvP_Arena_PrepareDeath")
Now in data/scripts create a new file (example: pvpArena.lua) and add this
Lua:
local config = {
-- TownID Pos enter arena pos exit arena
[1] = {
tileEnterPos = Position(185, 663, 9),
tileExitPos = Position(187, 759, 9),
enterPos = Position(189, 761, 9),
exitPos = Position(182, 664, 9)
},
[2] = {
tileEnterPos = Position(262, 661, 9),
tileExitPos = Position(244, 727, 9),
enterPos = Position(246, 729, 9),
exitPos = Position(264, 662, 9)
}
}
-- Globalevent used to teleport players out of arena when server shuts down --
local globaleventPvPArena = GlobalEvent("PvP_Arena_Global")
function globaleventPvPArena.onShutdown()
for _, player in pairs(Game.getPlayers()) do
if player and player:isPvPArenaPlayer() then
local town = config[player:getTown():getId()]
if town then
player:teleportTo(town.exitPos)
end
end
end
return true
end
globaleventPvPArena:register()
-- Prepare death. Handles players dying in arena. --
local creatureeventPvPArena = CreatureEvent("PvP_Arena_PrepareDeath")
function creatureeventPvPArena.onPrepareDeath(creature, killer)
if not creature:isPlayer() then return true end
if not creature:isPvPArenaPlayer() then return true end
local town = config[creature:getTown():getId()]
if not town then return true end
creature:teleportTo(town.exitPos)
creature:addHealth(creature:getMaxHealth())
creature:addMana(creature:getMaxMana())
print("PVP")
creature:setPvPArenaPlayer(false)
return false
end
creatureeventPvPArena:register()
-- Moveevent used to teleport players in and out of the arena --
local movementPvPArena = MoveEvent()
movementPvPArena:type("stepin")
function movementPvPArena.onStepIn(player, item, position, fromPosition)
if not player then return true end
local town = config[player:getTown():getId()]
if not town then
player:sendCancelMessage("You do not have a town set. Report to GM.")
player:teleportTo(fromPosition, true)
return true
end
if not player:isPvPArenaPlayer() then
if position ~= town.tileEnterPos then
player:sendCancelMessage("You do not have the correct town to enter here.")
player:teleportTo(fromPosition, true)
return true
end
player:teleportTo(town.enterPos)
town.enterPos:sendMagicEffect(CONST_ME_TELEPORT)
player:setPvPArenaPlayer(true)
else
if position ~= town.tileExitPos then
player:sendCancelMessage("You do not have the correct town to exit here.")
player:teleportTo(fromPosition, true)
return true
end
player:teleportTo(town.exitPos)
town.exitPos:sendMagicEffect(CONST_ME_TELEPORT)
player:setPvPArenaPlayer(false)
end
return true
end
movementPvPArena:aid(55235)
movementPvPArena:register()
-- New /c command --
local TalkSetMana = TalkAction("/c")
function TalkSetMana.onSay(player, words, param)
if not player:getGroup():getAccess() then
return false
end
if param == "" then
player:sendCancelMessage("Usage: /c name")
return false
end
local target = Player(param)
if not target then
player:sendCancelMessage("Player is not online or doesn't exist.")
return false
end
if target:isPvPArenaPlayer() then
target:setPvPArenaPlayer(false)
end
target:teleportTo(player:getPosition())
target:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
return false
end
TalkSetMana:separator(" ")
TalkSetMana:register()
Now the c++ part
Go to player.h and find: void updateRegeneration(); add under:
C++:
bool inPvPArenaPlayer() {
return isPvPArenaPlayer;
}
void setPvPArenaPlayer(bool value) {
isPvPArenaPlayer = value;
}
Now find: bool inventoryAbilities add under:
C++:
bool isPvPArenaPlayer = false;
Go to luascript.h and find: static int luaPlayerSetStorageValue(lua_State* L); add under:
C++:
static int luaPlayerIsPvPArenaPlayer(lua_State* L);
static int luaPlayerSetPvPArenaPlayer(lua_State* L);
Go to luascript.cpp and find: registerMethod("Player", "setStorageValue", LuaScriptInterface::luaPlayerSetStorageValue); add under
C++:
registerMethod("Player", "isPvPArenaPlayer", LuaScriptInterface::luaPlayerIsPvPArenaPlayer);
registerMethod("Player", "setPvPArenaPlayer", LuaScriptInterface::luaPlayerSetPvPArenaPlayer);
Now find: int LuaScriptInterface::luaPlayerSetStorageValue(lua_State* L) under whole method add:
C++:
int LuaScriptInterface::luaPlayerIsPvPArenaPlayer(lua_State* L)
{
// player:isPvPArenaPlayer()
Player* player = getUserdata<Player>(L, 1);
if (!player) {
lua_pushboolean(L, false);
return 1;
}
bool value = player->inPvPArenaPlayer();
lua_pushboolean(L, value);
return 1;
}
int LuaScriptInterface::luaPlayerSetPvPArenaPlayer(lua_State* L)
{
// player:setPvPArenaPlayer(bool)
Player* player = getUserdata<Player>(L, 1);
if (!player) {
lua_pushboolean(L, false);
return 1;
}
bool value = getBoolean(L, 2, false);
player->setPvPArenaPlayer(value);
lua_pushboolean(L, true);
return 1;
}
Now go to weapons.cpp and look for this:
C++:
switch (action) {
case WEAPONACTION_REMOVECOUNT:
if (g_config.getBoolean(ConfigManager::REMOVE_WEAPON_AMMO)) {
Weapon::decrementItemCount(item);
}
break;
case WEAPONACTION_REMOVECHARGE: {
uint16_t charges = item->getCharges();
if (charges != 0 && g_config.getBoolean(ConfigManager::REMOVE_WEAPON_CHARGES)) {
g_game.transformItem(item, item->getID(), charges - 1);
}
break;
}
Change it for this:
C++:
switch (action) {
case WEAPONACTION_REMOVECOUNT:
if (g_config.getBoolean(ConfigManager::REMOVE_WEAPON_AMMO)) {
if (!player->inPvPArenaPlayer()) {
Weapon::decrementItemCount(item);
}
}
break;
case WEAPONACTION_REMOVECHARGE: {
uint16_t charges = item->getCharges();
if (charges != 0 && g_config.getBoolean(ConfigManager::REMOVE_WEAPON_CHARGES)) {
if (!player->inPvPArenaPlayer()) {
g_game.transformItem(item, item->getID(), charges - 1);
}
}
break;
}
In case you have spears that are dropped on the ground, then change this:
C++:
case WEAPONACTION_MOVE:
g_game.internalMoveItem(item->getParent(), destTile, INDEX_WHEREEVER, item, 1, nullptr, FLAG_NOLIMIT);
break;
To this
C++:
case WEAPONACTION_MOVE:
if (!player->inPvPArenaPlayer()) {
g_game.internalMoveItem(item->getParent(), destTile, INDEX_WHEREEVER, item, 1, nullptr, FLAG_NOLIMIT);
}
break;
Regards!
Last edited: