Skip to content

Commit

Permalink
feat: playerOnWalk event callback and afk talkaction (opentibiabr#2518)
Browse files Browse the repository at this point in the history
  • Loading branch information
elsongabriel authored Apr 25, 2024
1 parent 13798e5 commit 0998429
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 0 deletions.
1 change: 1 addition & 0 deletions data/scripts/eventcallbacks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Event callbacks are available for several categories of game entities, such as `
- `(void)` `playerOnCombat`
- `(void)` `playerOnInventoryUpdate`
- `(bool)` `playerOnRotateItem`
- `(void)` `playerOnWalk`
- `(void)` `monsterOnDropLoot`
- `(void)` `monsterPostDropLoot`
- `(void)` `monsterOnSpawn`
Expand Down
94 changes: 94 additions & 0 deletions data/scripts/talkactions/gm/afk.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
local afk = TalkAction("/afk")

playersAFKs = {}

local function checkIsAFK(id)
for index, item in pairs(playersAFKs) do
if id == item.id then
return { afk = true, index = index }
end
end
return { afk = false }
end

local function showAfkMessage(playerPosition)
local spectators = Game.getSpectators(playerPosition, false, true, 8, 8, 8, 8)
if #spectators > 0 then
for _, spectator in ipairs(spectators) do
spectator:say("AFK !", TALKTYPE_MONSTER_SAY, false, spectator, playerPosition)
end
end
end

function afk.onSay(player, words, param)
if param == "" then
player:sendCancelMessage("You need to specify on/off param.")
return true
end

local id, playerPosition = player:getId(), player:getPosition()
local isAfk = checkIsAFK(id)
if param == "on" then
if isAfk.afk then
player:sendCancelMessage("You are already AFK!")
return true
end

table.insert(playersAFKs, { id = id, position = playerPosition })
if player:isInGhostMode() then
player:setGhostMode(false)
end
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are now AFK!")
playerPosition:sendMagicEffect(CONST_ME_REDSMOKE)
showAfkMessage(playerPosition)
elseif param == "off" then
if isAfk.afk then
table.remove(playersAFKs, isAfk.index)
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are no longer AFK!")
playerPosition:sendMagicEffect(CONST_ME_REDSMOKE)
end
end

return true
end

afk:separator(" ")
afk:groupType("gamemaster")
afk:register()

------------------ AFK Effect Message ------------------
local afkEffect = GlobalEvent("GodAfkEffect")
function afkEffect.onThink(interval)
for _, player in ipairs(playersAFKs) do
showAfkMessage(player.position)
end
return true
end

afkEffect:interval(5000)
afkEffect:register()

------------------ Stop AFK Message when moves ------------------
local callback = EventCallback()
function callback.playerOnWalk(player, creature, creaturePos, toPos)
local isAfk = checkIsAFK(player:getId())
if isAfk.afk then
table.remove(playersAFKs, isAfk.index)
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are no longer AFK!")
end
return true
end

callback:register()

------------------ Player Logout ------------------
local godAfkLogout = CreatureEvent("GodAfkLogout")
function godAfkLogout.onLogout(player)
local isAfk = checkIsAFK(player:getId())
if isAfk.afk then
table.remove(playersAFKs, isAfk.index)
end
return true
end

godAfkLogout:register()
2 changes: 2 additions & 0 deletions src/creatures/players/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1926,6 +1926,8 @@ void Player::onWalk(Direction &dir) {
Creature::onWalk(dir);
setNextActionTask(nullptr);
setNextAction(OTSYS_TIME() + getStepDuration(dir));

g_callbacks().executeCallback(EventCallback_t::playerOnWalk, &EventCallback::playerOnWalk, getPlayer(), dir);
}

void Player::onCreatureMove(const std::shared_ptr<Creature> &creature, const std::shared_ptr<Tile> &newTile, const Position &newPos, const std::shared_ptr<Tile> &oldTile, const Position &oldPos, bool teleport) {
Expand Down
1 change: 1 addition & 0 deletions src/lua/callbacks/callbacks_definitions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ enum class EventCallback_t : uint16_t {
playerOnCombat,
playerOnInventoryUpdate,
playerOnRotateItem,
playerOnWalk,
// Monster
monsterOnDropLoot,
monsterPostDropLoot,
Expand Down
23 changes: 23 additions & 0 deletions src/lua/callbacks/event_callback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,29 @@ bool EventCallback::playerOnRotateItem(std::shared_ptr<Player> player, std::shar
return getScriptInterface()->callFunction(3);
}

void EventCallback::playerOnWalk(std::shared_ptr<Player> player, Direction &dir) const {
if (!getScriptInterface()->reserveScriptEnv()) {
g_logger().error("[EventCallback::eventOnWalk - "
"Player {}] "
"Call stack overflow. Too many lua script calls being nested.",
player->getName());
return;
}

ScriptEnvironment* scriptEnvironment = getScriptInterface()->getScriptEnv();
scriptEnvironment->setScriptId(getScriptId(), getScriptInterface());

lua_State* L = getScriptInterface()->getLuaState();
getScriptInterface()->pushFunction(getScriptId());

LuaScriptInterface::pushUserdata<Player>(L, player);
LuaScriptInterface::setMetatable(L, -1, "Player");

lua_pushnumber(L, dir);

getScriptInterface()->callVoidFunction(2);
}

void EventCallback::playerOnStorageUpdate(std::shared_ptr<Player> player, const uint32_t key, const int32_t value, int32_t oldValue, uint64_t currentTime) const {
if (!getScriptInterface()->reserveScriptEnv()) {
g_logger().error("[EventCallback::eventOnStorageUpdate - "
Expand Down
1 change: 1 addition & 0 deletions src/lua/callbacks/event_callback.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class EventCallback : public Script {
void playerOnCombat(std::shared_ptr<Player> player, std::shared_ptr<Creature> target, std::shared_ptr<Item> item, CombatDamage &damage) const;
void playerOnInventoryUpdate(std::shared_ptr<Player> player, std::shared_ptr<Item> item, Slots_t slot, bool equip) const;
bool playerOnRotateItem(std::shared_ptr<Player> player, std::shared_ptr<Item> item, const Position &position) const;
void playerOnWalk(std::shared_ptr<Player> player, Direction &dir) const;

// Monster
void monsterOnDropLoot(std::shared_ptr<Monster> monster, std::shared_ptr<Container> corpse) const;
Expand Down

0 comments on commit 0998429

Please sign in to comment.