Postado Setembro 29, 2020 4 anos .Qual servidor ou website você utiliza como base? OT MANAGER Qual o motivo deste tópico? ERRO DE LOGS Está surgindo algum erro? Se sim coloque-o aqui. SIM Citar ERRO DE ACTIONS.CCP, GALERA AO ABRIR O OT EU PERCEBI QUE TODA VEZ QUE LOGA UM PLAYER OU ELE EXECUTA ALGUMA TAREFA, COMO ABRIR DEPOSIT, MATAR OU ATACAR UM BIXO APARECE ESSES LOGS DE (ACTIONS.CCP) E ISSO PODE ESTA CAUSANDO DDOS NO MEU SERVIDOR MTOS LOGS CONSTANTE. ALGUEM ME AJUDA A TIRAR TEM UM ARQUIVO COM O NOME ACTIONS.CCP COM OS SCRPIT ABAIXO Você tem o código disponível? Se tiver publique-o aqui: /** * The Forgotten Server - a free and open-source MMORPG server emulator * Copyright (C) 2019 Mark Samman <[email protected]> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "otpch.h" #include <string> #include <utility> #include "actions.h" #include "bed.h" #include "configmanager.h" #include "container.h" #include "game.h" #include "pugicast.h" #include "rewardchest.h" #include "spells.h" extern Game g_game; extern Spells* g_spells; extern Actions* g_actions; extern ConfigManager g_config; Actions::Actions() : scriptInterface("Action Interface") { scriptInterface.initState(); } Action::Action(LuaScriptInterface* interface) : Event(interface), function(nullptr), allowFarUse(false), checkFloor(true), checkLineOfSight(true) {} Actions::~Actions() { clear(false); } void Actions::clearMap(ActionUseMap* map, bool fromLua) { if(map == nullptr) { DLOG_F(WARNING, "Map pointer is nullptr!"); return; } for (auto it = map->begin(); it != map->end(); ) { if (fromLua == it->second.fromLua) { it = map->erase(it); } else { ++it; } } } void Actions::clear(bool fromLua) { DLOG_F(INFO, "Clear"); DLOG_F(INFO, "Clear Use Item"); clearMap(&useItemMap, fromLua); DLOG_F(INFO, "Clear Unique Item"); clearMap(&uniqueItemMap, fromLua); DLOG_F(INFO, "Clear Action Item"); clearMap(&actionItemMap, fromLua); DLOG_F(INFO, "Restart Lua State?[%s]", fromLua == true ? "yes" : "no"); reInitState(fromLua); } LuaScriptInterface& Actions::getScriptInterface() { DLOG_F(INFO, "Get Script Interface"); return scriptInterface; } std::string Actions::getScriptBaseName() const { DLOG_F(INFO, "Get Script Base Name"); return "actions"; } Event_ptr Actions::getEvent(const std::string& nodeName) { DLOG_F(INFO, "Get Event[%s]", nodeName.c_str()); if (strcasecmp(nodeName.c_str(), "action") != 0) { DLOG_F(WARNING, "Nullptr"); return nullptr; } return Event_ptr(new Action(&scriptInterface)); } bool Actions::registerEvent(Event_ptr event, const pugi::xml_node& node) { // event is guaranteed to be an Action Action_ptr action{static_cast<Action*>(event.release())}; pugi::xml_attribute attr; if ((attr = node.attribute("itemid"))) { uint16_t id = pugi::cast<uint16_t>(attr.value()); auto result = useItemMap.emplace(id, std::move(*action)); if (!result.second) { LOG_F(WARNING, "Duplicate registered item with id:[%d] ", id); } return result.second; } else if ((attr = node.attribute("fromid"))) { pugi::xml_attribute toIdAttribute = node.attribute("toid"); if (!toIdAttribute) { LOG_F(WARNING, "Missing toid in fromid:[%s] ", attr.as_string()); return false; } uint16_t fromId = pugi::cast<uint16_t>(attr.value()); uint16_t iterId = fromId; uint16_t toId = pugi::cast<uint16_t>(toIdAttribute.value()); auto result = useItemMap.emplace(iterId, *action); if (!result.second) { LOG_F(WARNING, "Duplicate registered item with id:[%d] in " "fromid:[%d], toid[%d]!", iterId, fromId, toId); } bool success = result.second; while (++iterId <= toId) { result = useItemMap.emplace(iterId, *action); if (!result.second) { LOG_F(WARNING, "Duplicate registered item with id:[%d] in " "fromid:[%d], toid[%d]!", iterId, fromId, toId); continue; } success = true; } return success; } else if ((attr = node.attribute("uniqueid"))) { uint16_t uid = pugi::cast<uint16_t>(attr.value()); auto result = uniqueItemMap.emplace(uid, std::move(*action)); if (!result.second) { LOG_F(WARNING, "Duplicate registered item with uid:[%d] ", uid); } return result.second; } else if ((attr = node.attribute("fromuid"))) { pugi::xml_attribute toUidAttribute = node.attribute("touid"); if (!toUidAttribute) { LOG_F(WARNING, "Missing touid in fromuid:[%s] ", attr.as_string()); return false; } uint16_t fromUid = pugi::cast<uint16_t>(attr.value()); uint16_t iterUid = fromUid; uint16_t toUid = pugi::cast<uint16_t>(toUidAttribute.value()); auto result = uniqueItemMap.emplace(iterUid, *action); if (!result.second) { LOG_F(WARNING, "Duplicate registered item with uid:[%d] in " "fromuid:[%d], touid[%d]!", iterUid, fromUid, toUid); } bool success = result.second; while (++iterUid <= toUid) { result = uniqueItemMap.emplace(iterUid, *action); if (!result.second) { LOG_F(WARNING, "Duplicate registered item with uid:[%d] in " "fromuid:[%d], touid[%d]!", iterUid, fromUid, toUid); continue; } success = true; } return success; } else if ((attr = node.attribute("actionid"))) { uint16_t aid = pugi::cast<uint16_t>(attr.value()); auto result = actionItemMap.emplace(aid, std::move(*action)); if (!result.second) { LOG_F(WARNING, "Duplicate registered item with aid:[%d] ", aid); } return result.second; } else if ((attr = node.attribute("fromaid"))) { pugi::xml_attribute toAidAttribute = node.attribute("toaid"); if (!toAidAttribute) { LOG_F(WARNING, "Missing toaid in fromaid:[%s] ", attr.as_string()); return false; } uint16_t fromAid = pugi::cast<uint16_t>(attr.value()); uint16_t iterAid = fromAid; uint16_t toAid = pugi::cast<uint16_t>(toAidAttribute.value()); auto result = actionItemMap.emplace(iterAid, *action); if (!result.second) { LOG_F(WARNING, "Duplicate registered item with aid:[%d] in " "fromaid:[%d], toaid[%d]!", iterAid, fromAid, toAid); } bool success = result.second; while (++iterAid <= toAid) { result = actionItemMap.emplace(iterAid, *action); if (!result.second) { LOG_F(WARNING, "Duplicate registered item with aid:[%d] in " "fromaid:[%d], toaid[%d]!", iterAid, fromAid, toAid); continue; } success = true; } return success; } return false; } bool Actions::registerLuaEvent(Action* event) { DLOG_F(INFO, "Register Lua Event"); Action_ptr action{ event }; if (action->getItemIdRange().size() > 0) { if (action->getItemIdRange().size() == 1) { auto result = useItemMap.emplace(action->getItemIdRange().at(0), std::move(*action)); if (!result.second) { LOG_F(WARNING, "Duplicate registered item with id:[%d] ", action->getItemIdRange().at(0)); } return result.second; } else { auto v = action->getItemIdRange(); for (auto i = v.begin(); i != v.end(); i++) { auto result = useItemMap.emplace(*i, std::move(*action)); if (!result.second) { LOG_F(WARNING, "Duplicate registered item with id:[%d] in " "range from id:[%d], to id[%d]!", *i, v.at(0), v.at(v.size() - 1)); continue; } } return true; } } else if (action->getUniqueIdRange().size() > 0) { if (action->getUniqueIdRange().size() == 1) { auto result = uniqueItemMap.emplace( action->getUniqueIdRange().at(0), std::move(*action)); if (!result.second) { LOG_F(WARNING, "Duplicate registered item with uid:[%d] ", action->getUniqueIdRange().at(0)); } return result.second; } else { auto v = action->getUniqueIdRange(); for (auto i = v.begin(); i != v.end(); i++) { auto result = uniqueItemMap.emplace(*i, std::move(*action)); if (!result.second) { LOG_F(WARNING, "Duplicate registered item with uid:[%d] in " "range from uid:[%d], to uid[%d]!", *i, v.at(0), v.at(v.size() - 1)); continue; } } return true; } } else if (action->getActionIdRange().size() > 0) { if (action->getActionIdRange().size() == 1) { auto result = actionItemMap.emplace( action->getActionIdRange().at(0), std::move(*action)); if (!result.second) { LOG_F(WARNING, "Duplicate registered item with aid:[%d] ", action->getActionIdRange().at(0)); } return result.second; } else { auto v = action->getActionIdRange(); for (auto i = v.begin(); i != v.end(); i++) { auto result = actionItemMap.emplace(*i, std::move(*action)); if (!result.second) { LOG_F(WARNING, "Duplicate registered item with aid:[%d] in " "range from aid:[%d], to aid[%d]!", *i, v.at(0), v.at(v.size() - 1)); continue; } } return true; } } else { LOG_F(ERROR, "There is no id / aid / uid set for this event"); return false; } } ReturnValue Actions::canUse(const Player* player, const Position& pos) { DLOG_F(INFO, "Player[%d] canUse from position:x[%d], y[%d], z[%d]?", player == nullptr ? 0 : player->getID(), pos.getX(), pos.getY(), pos.getZ()); if (pos.x != 0xFFFF) { const Position& playerPos = player->getPosition(); if (playerPos.z != pos.z) { DLOG_F(WARNING, "Player[%d] first needs to go [%s]", player == nullptr ? 0 : player->getID(), playerPos.z > pos.z ? "Upstairs" : "Downstairs"); return playerPos.z > pos.z ? RETURNVALUE_FIRSTGOUPSTAIRS : RETURNVALUE_FIRSTGODOWNSTAIRS; } if (!Position::areInRange<1, 1>(playerPos, pos)) { DLOG_F(WARNING, "Player[%d] is too far to use!", player == nullptr ? 0 : player->getID()); return RETURNVALUE_TOOFARAWAY; } } DLOG_F(INFO, "Player[%d] canUse from his position!", player == nullptr ? 0 : player->getID()); return RETURNVALUE_NOERROR; } ReturnValue Actions::canUse(const Player* player, const Position& pos, const Item* item) { DLOG_F(INFO, "Player[%d] canUse cid[%d] from position:x[%d], y[%d], z[%d]?", player == nullptr ? 0 : player->getID(), item == nullptr ? 0 : item->getClientID(), pos.getX(), pos.getY(), pos.getZ()); Action* action = getAction(item); if (action != nullptr) { return action->canExecuteAction(player, pos); } DLOG_F(INFO, "Player[%d] canUse item from his position!", player == nullptr ? 0 : player->getID()); return RETURNVALUE_NOERROR; } ReturnValue Actions::canUseFar(const Creature* creature, const Position& toPos, bool checkLineOfSight, bool checkFloor) { DLOG_F(INFO, "Creature[%d] canUseFar to position:x[%d], y[%d], z[%d]," "checkLineOfSight[%d], checkFloor[%d]", creature == nullptr ? 0 : creature->getID(), toPos.getX(), toPos.getY(), toPos.getZ(), checkLineOfSight, checkFloor); if (toPos.x == 0xFFFF) { DLOG_F(INFO, "Creature[%d] can use from far!", creature == nullptr ? 0 : creature->getID()); return RETURNVALUE_NOERROR; } const Position& creaturePos = creature->getPosition(); if (checkFloor && creaturePos.z != toPos.z) { DLOG_F(WARNING, "Creature[%d] first needs to go [%s]", creature == nullptr ? 0 : creature->getID(), creaturePos.z > toPos.z ? "Upstairs" : "Downstairs"); return creaturePos.z > toPos.z ? RETURNVALUE_FIRSTGOUPSTAIRS : RETURNVALUE_FIRSTGODOWNSTAIRS; } if (!Position::areInRange<7, 5>(toPos, creaturePos)) { DLOG_F(WARNING, "Creature[%d] is too far to use!", creature == nullptr ? 0 : creature->getID()); return RETURNVALUE_TOOFARAWAY; } if (checkLineOfSight && !g_game.canThrowObjectTo(creaturePos, toPos)) { DLOG_F(WARNING, "Creature[%d] can throw!", creature == nullptr ? 0 : creature->getID()); return RETURNVALUE_CANNOTTHROW; } DLOG_F(INFO, "Creature can use far!"); return RETURNVALUE_NOERROR; } Action* Actions::getAction(const Item* item) { DLOG_F(INFO, "Get Item cid:[%d] Action", item == nullptr ? 0 : item->getClientID()); if (item->hasAttribute(ITEM_ATTRIBUTE_UNIQUEID)) { DLOG_F(INFO, "Item has Attribute UniqueID"); auto it = uniqueItemMap.find(item->getUniqueId()); if (it != uniqueItemMap.end()) { return &it->second; } } if (item->hasAttribute(ITEM_ATTRIBUTE_ACTIONID)) { DLOG_F(INFO, "Item has Attribute ActionID"); auto it = actionItemMap.find(item->getActionId()); if (it != actionItemMap.end()) { return &it->second; } } DLOG_F(INFO, "Regular Item"); auto it = useItemMap.find(item->getID()); if (it != useItemMap.end()) { return &it->second; } // rune items DLOG_F(INFO, "Item is a rune"); return g_spells->getRuneSpell(item->getID()); } ReturnValue Actions::internalUseItem(Player* player, const Position& pos, uint8_t index, Item* item, bool isHotkey) { DLOG_F(INFO, "Internal Use Item Player[%d], Position:x[%d], y[%d], z[%d], " "Index:[%d], Item cid:[%d], isHotkey:[%d]", player == nullptr ? 0 : player->getID(), pos.getX(), pos.getY(), pos.getZ(), index, item == nullptr ? 0 : item->getClientID(), isHotkey); if (Door* door = item->getDoor()) { DLOG_F(INFO, "Door"); if (!door->canUse(player)) { DLOG_F(WARNING, "Cannot use on this door!"); return RETURNVALUE_CANNOTUSETHISOBJECT; } } Action* action = getAction(item); if (action != nullptr) { DLOG_F(INFO, "Action"); if (action->isScripted()) { if (action->executeUse(player, item, pos, nullptr, pos, isHotkey)) { DLOG_F(INFO, "Player internalUseItem Success!"); return RETURNVALUE_NOERROR; } if (item->isRemoved()) { DLOG_F(WARNING, "Cannot use on this object(action)!"); return RETURNVALUE_CANNOTUSETHISOBJECT; } } else if (action->function) { if (action->function(player, item, pos, nullptr, pos, isHotkey)) { DLOG_F(INFO, "Player internalUseItem Success!"); return RETURNVALUE_NOERROR; } } } if (BedItem* bed = item->getBed()) { if (!bed->canUse(player)) { DLOG_F(WARNING, "Cannot use on this object(Bed)!"); return RETURNVALUE_CANNOTUSETHISOBJECT; } if (bed->trySleep(player)) { player->setBedItem(bed); g_game.sendOfflineTrainingDialog(player); } DLOG_F(INFO, "Player internalUseItem Success!"); return RETURNVALUE_NOERROR; } if (Container* container = item->getContainer()) { DLOG_F(INFO, "Container"); Container* openContainer; // depot container if (DepotLocker* depot = container->getDepotLocker()) { DLOG_F(INFO, "Depot Locker"); DepotLocker* myDepotLocker = player->getDepotLocker(depot->getDepotId()); myDepotLocker->setParent(depot->getParent()->getTile()); openContainer = myDepotLocker; player->setLastDepotId(depot->getDepotId()); } else { openContainer = container; } // reward chest if (container->getRewardChest() != nullptr) { DLOG_F(INFO, "Reward Chest"); RewardChest* myRewardChest = player->getRewardChest(); if (myRewardChest->size() == 0) { DLOG_F(WARNING, "Reward Chest is Empty"); return RETURNVALUE_REWARDCHESTISEMPTY; } myRewardChest->setParent(container->getParent()->getTile()); for (auto& it : player->rewardMap) { it.second->setParent(myRewardChest); } openContainer = myRewardChest; } // reward container proxy created when the boss dies if (container->getID() == ITEM_REWARD_CONTAINER && !container->getReward()) { DLOG_F(INFO, "Reward Container Proxy(Boss)"); if (Reward* reward = player->getReward( container->getIntAttr(ITEM_ATTRIBUTE_DATE), false)) { reward->setParent(container->getRealParent()); openContainer = reward; } else { DLOG_F(WARNING, "This is impossible!"); return RETURNVALUE_THISISIMPOSSIBLE; } } uint32_t corpseOwner = container->getCorpseOwner(); if (container->isRewardCorpse()) { DLOG_F(INFO, "Corpse"); // only players who participated in the fight can open the corpse if (player->getGroup()->id >= 4 || player->getAccountType() >= 3) { DLOG_F(WARNING, "You can't open corpse(ADM)"); return RETURNVALUE_YOUCANTOPENCORPSEADM; } if (!player->getReward(container->getIntAttr(ITEM_ATTRIBUTE_DATE), false)) { DLOG_F(WARNING, "You aren't the owner!"); return RETURNVALUE_YOUARENOTTHEOWNER; } } else if (corpseOwner != 0 && !player->canOpenCorpse(corpseOwner)) { DLOG_F(WARNING, "You aren't the owner!"); return RETURNVALUE_YOUARENOTTHEOWNER; } // open/close container int32_t oldContainerId = player->getContainerID(openContainer); if (oldContainerId != -1) { DLOG_F(INFO, "Close Container"); player->onCloseContainer(openContainer); player->closeContainer(oldContainerId); } else { DLOG_F(INFO, "Add Container"); player->addContainer(index, openContainer); player->onSendContainer(openContainer); } DLOG_F(INFO, "Player internalUseItem Success!"); return RETURNVALUE_NOERROR; } const ItemType& it = Item::items[item->getID()]; if (it.canReadText) { if (it.canWriteText) { DLOG_F(INFO, "Can Read/Write Text"); player->setWriteItem(item, it.maxTextLen); player->sendTextWindow(item, it.maxTextLen, true); } else { DLOG_F(INFO, "Can Read Text"); player->setWriteItem(nullptr); player->sendTextWindow(item, 0, false); } DLOG_F(INFO, "Player internalUseItem Success!"); return RETURNVALUE_NOERROR; } DLOG_F(WARNING, "Player can't use this object!"); return RETURNVALUE_CANNOTUSETHISOBJECT; } bool Actions::useItem(Player* player, const Position& pos, uint8_t index, Item* item, bool isHotkey) { DLOG_F(INFO, "Use Item Player[%d], Position:x[%d], y[%d], z[%d], " "Index:[%d], Item cid:[%d], isHotkey:[%d]", player == nullptr ? 0 : player->getID(), pos.getX(), pos.getY(), pos.getZ(), index, item == nullptr ? 0 : item->getClientID(), isHotkey); player->setNextAction(OTSYS_TIME() + g_config.getNumber( ConfigManager::ACTIONS_DELAY_INTERVAL)); if (isHotkey) { showUseHotkeyMessage(player, item, player->getItemTypeCount( item->getID(), -1)); } ReturnValue ret = internalUseItem(player, pos, index, item, isHotkey); if (ret != RETURNVALUE_NOERROR) { player->sendCancelMessage(ret); DLOG_F(WARNING, "Player can't use item!"); return false; } DLOG_F(INFO, "Success using item!"); return true; } bool Actions::useItemEx(Player* player, const Position& fromPos, const Position& toPos, uint8_t toStackPos, Item* item, bool isHotkey, Creature* creature/* = nullptr*/) { DLOG_F(INFO, "Use Item Ex Player[%d], From Position:x[%d], y[%d], z[%d], " "To Position:x[%d], y[%d], z[%d], toStackPos[%d], Item cid:[%d], " "isHotkey:[%d]", player == nullptr ? 0 : player->getID(), fromPos.getX(), fromPos.getY(), fromPos.getZ(), toPos.getX(), toPos.getY(), toPos.getZ(), toStackPos, item == nullptr ? 0 : item->getClientID(), isHotkey); player->setNextAction(OTSYS_TIME() + g_config.getNumber( ConfigManager::EX_ACTIONS_DELAY_INTERVAL)); Action* action = getAction(item); if (action == nullptr) { player->sendCancelMessage(RETURNVALUE_CANNOTUSETHISOBJECT); DLOG_F(WARNING, "Player can't use object(no action)!"); return false; } ReturnValue ret = action->canExecuteAction(player, toPos); if (ret != RETURNVALUE_NOERROR) { player->sendCancelMessage(ret); DLOG_F(WARNING, "Player can't use object(with action)!"); return false; } if (isHotkey) { showUseHotkeyMessage(player, item, player->getItemTypeCount(item->getID(), -1)); } if (action->function) { DLOG_F(INFO, "Action is a function"); if (action->function(player, item, fromPos, action->getTarget(player, creature, toPos, toStackPos), toPos, isHotkey)) { DLOG_F(INFO, "Success executing function!"); return true; } DLOG_F(WARNING, "Failed to execute function!"); return false; } if (!action->executeUse(player, item, fromPos, action->getTarget(player, creature, toPos, toStackPos), toPos, isHotkey)) { if (!action->hasOwnErrorHandler()) { player->sendCancelMessage(RETURNVALUE_CANNOTUSETHISOBJECT); } DLOG_F(WARNING, "Player can't use object!"); return false; } DLOG_F(INFO, "Success using item(ex)!"); return true; } void Actions::showUseHotkeyMessage(Player* player, const Item* item, uint32_t count) { DLOG_F(INFO, "Show Use Hotkey Message."); std::ostringstream ss; const ItemType& it = Item::items[item->getID()]; if (!it.showCount) { ss << "Using one of " << item->getName() << "..."; } else if (count == 1) { ss << "Using the last " << item->getName() << "..."; } else { ss << "Using one of " << count << ' ' << item->getPluralName() << "..."; } player->sendTextMessage(MESSAGE_INFO_DESCR, ss.str()); } bool Action::configureEvent(const pugi::xml_node& node) { DLOG_F(INFO, "Configure Event[%s]", node.name()); pugi::xml_attribute allowFarUseAttr = node.attribute("allowfaruse"); if (allowFarUseAttr != nullptr) { allowFarUse = allowFarUseAttr.as_bool(); DLOG_F(INFO, "Event[%s]: Allow Far Use:[%d]", node.name(), allowFarUse); } pugi::xml_attribute blockWallsAttr = node.attribute("blockwalls"); if (blockWallsAttr != nullptr) { checkLineOfSight = blockWallsAttr.as_bool(); DLOG_F(INFO, "Event[%s]: Block Walls:[%d]", node.name(), checkLineOfSight); } pugi::xml_attribute checkFloorAttr = node.attribute("checkfloor"); if (checkFloorAttr != nullptr) { checkFloor = checkFloorAttr.as_bool(); DLOG_F(INFO, "Event[%s]: Check Floor:[%d]", node.name(), checkFloor); } DLOG_F(INFO, "Event[%s] configured with success!", node.name()); return true; } namespace { bool enterMarket(Player* player, Item* /*unused*/, const Position& /*unused*/, Thing* /*unused*/, const Position& /*unused*/, bool /*unused*/) { DLOG_F(INFO, "Player[%d] trying to enter market.", player == nullptr ? 0 : player->getID()); if (player->getLastDepotId() == -1) { DLOG_F(WARNING, "Player[%d] doesn't have depot!", player == nullptr ? 0 : player->getID()); return false; } player->sendMarketEnter(player->getLastDepotId()); DLOG_F(INFO, "enterMarket: Player[%d] Success!", player == nullptr ? 0 : player->getID()); return true; } bool useImbueShrine(Player* player, Item* /*unused*/, const Position& /*unused*/, Thing* target, const Position& toPos, bool /*unused*/) { DLOG_F(INFO, "Use Imbue Shrine: Player[%d], Position: x[%d], y[%d], z[%d],", player == nullptr ? 0 : player->getID(), toPos.getX(), toPos.getY(), toPos.getZ()); Item* item = target != nullptr ? target->getItem() : nullptr; if (item == nullptr) { player->sendTextMessage(MESSAGE_STATUS_SMALL, "This item is not imbuable."); DLOG_F(WARNING, "Thing is not an item!"); return false; } const ItemType& it = Item::items[item->getID()]; if (it.imbuingSlots <= 0) { player->sendTextMessage(MESSAGE_STATUS_SMALL, "This item is not imbuable."); DLOG_F(WARNING, "This item is not imbuable!"); return false; } if (item->getTopParent() != player) { player->sendTextMessage(MESSAGE_STATUS_SMALL, "You have to pick up the item to imbue it."); DLOG_F(WARNING, "You have to pick up the item to imbue it!"); return false; } if ((toPos.y & 0x40) == 0) { player->sendTextMessage(MESSAGE_STATUS_SMALL, "You cannot imbue an equipped item."); DLOG_F(WARNING, "You cannot imbue an equipped item!"); return false; } DLOG_F(INFO, "Send Imbuement Windows."); player->sendImbuementWindow(target->getItem()); DLOG_F(INFO, "useImbueShrine: Success!"); return true; } } // namespace bool Action::loadFunction(const pugi::xml_attribute& attr, bool isScripted) { DLOG_F(INFO, "Load function[%s]", attr.as_string()); const char* functionName = attr.as_string(); if (strcasecmp(functionName, "market") == 0) { DLOG_F(INFO, "function: market"); function = enterMarket; } else if (strcasecmp(functionName, "imbuement") == 0) { DLOG_F(INFO, "function: imbuement"); function = useImbueShrine; } else { if (!isScripted) { LOG_F(WARNING, "Function[%s] does not exist!", functionName); return false; } } if (!isScripted) { DLOG_F(INFO, "Not scripted!"); scripted = false; } DLOG_F(INFO, "loadFunction: Success!"); return true; } std::string Action::getScriptEventName() const { DLOG_F(INFO, "Script Event Name: onUse"); return "onUse"; } ReturnValue Action::canExecuteAction(const Player* player, const Position& toPos) { DLOG_F(INFO, "Player[%d] can execute action position:x[%d], y[%d], z[%d]?", player == nullptr ? 0 : player->getID(), toPos.getX(), toPos.getY(), toPos.getZ()); if (!allowFarUse) { return g_actions->canUse(player, toPos); } return g_actions->canUseFar(player, toPos, checkLineOfSight, checkFloor); } Thing* Action::getTarget(Player* player, Creature* targetCreature, const Position& toPosition, uint8_t toStackPos) const { DLOG_F(INFO, "getTarget:Player[%d], Target[%d], Position:x[%d], y[%d], " "z[%d], toStackPos[%d].", player == nullptr ? 0 : player->getID(), targetCreature == nullptr ? 0 : targetCreature->getID(), toPosition.getX(), toPosition.getY(), toPosition.getZ(), toStackPos); if (targetCreature != nullptr) { return targetCreature; } return g_game.internalGetThing(player, toPosition, toStackPos, 0, STACKPOS_USETARGET); } bool Action::executeUse(Player* player, Item* item, const Position& fromPosition, Thing* target, const Position& toPosition, bool isHotkey) { DLOG_F(INFO, "Use Item Ex Player[%d], From Position:x[%d], y[%d], z[%d], " "To Position:x[%d], y[%d], z[%d], Item cid:[%d], isHotkey:[%d]", player == nullptr ? 0 : player->getID(), fromPosition.getX(), fromPosition.getY(), fromPosition.getZ(), toPosition.getX(), toPosition.getY(), toPosition.getZ(), item == nullptr ? 0 : item->getClientID(), isHotkey); // onUse(player, item, fromPosition, target, toPosition, isHotkey) if (!scriptInterface->reserveScriptEnv()) { LOG_F(WARNING, "Call stack overflow!"); return false; } ScriptEnvironment* env = scriptInterface->getScriptEnv(); env->setScriptId(scriptId, scriptInterface); lua_State* L = scriptInterface->getLuaState(); scriptInterface->pushFunction(scriptId); LuaScriptInterface::pushUserdata<Player>(L, player); LuaScriptInterface::setMetatable(L, -1, "Player"); LuaScriptInterface::pushThing(L, item); LuaScriptInterface::pushPosition(L, fromPosition); LuaScriptInterface::pushThing(L, target); LuaScriptInterface::pushPosition(L, toPosition); LuaScriptInterface::pushBoolean(L, isHotkey); DLOG_F(INFO, "Call lua function"); return scriptInterface->callFunction(6); } Você tem alguma imagem que possa auxiliar no problema? Se sim, coloque-a aqui.
Participe da conversa
Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.