Postado Outubro 13, 2021 3 anos Opa, preciso de ajuda com uma coisa, alguns itens como zaoan armor e war hammer possuem level mínimo necessário, porém pelo menos no meu servidor eles podem ser equipados e eu gostaria que se o level não for o necessário, o item não seja equipado, eu uso TFS 04 rev4393, eu acredito que seja no movements.cpp, eu tentei mexer, mas meu conhecimento em C/C++ é bem fraco, alguém poderia me ajudar? Por script eu sei fazer, mas gostaria que fosse diretamente nas sources pra ser automático já //////////////////////////////////////////////////////////////////////// // OpenTibia - an opensource roleplaying game //////////////////////////////////////////////////////////////////////// // 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 3 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, see <http://www.gnu.org/licenses/>. //////////////////////////////////////////////////////////////////////// #include "otpch.h" #include <libxml/xmlmemory.h> #include <libxml/parser.h> #include "movement.h" #include "tools.h" #include "creature.h" #include "player.h" #include "tile.h" #include "vocation.h" #include "combat.h" #include "game.h" extern Game g_game; extern MoveEvents* g_moveEvents; MoveEvent* MoveEventScript::event = NULL; void MoveEventScript::registerFunctions() { LuaInterface::registerFunctions(); lua_register(m_luaState, "callFunction", MoveEventScript::luaCallFunction); } int32_t MoveEventScript::luaCallFunction(lua_State* L) { //callFunction(...) MoveEvent* event = MoveEventScript::event; if(!event) { error(__FUNCTION__, "MoveEvent not set!"); lua_pushboolean(L, false); return 1; } if(event->getEventType() == MOVE_EVENT_EQUIP || event->getEventType() == MOVE_EVENT_DE_EQUIP) { ScriptEnviroment* env = getEnv(); bool boolean = popNumber(L); slots_t slot = (slots_t)popNumber(L); Item* item = env->getItemByUID(popNumber(L)); if(!item) { error(__FUNCTION__, getError(LUA_ERROR_ITEM_NOT_FOUND)); lua_pushboolean(L, false); return 1; } Player* player = env->getPlayerByUID(popNumber(L)); if(!player) { error(__FUNCTION__, getError(LUA_ERROR_PLAYER_NOT_FOUND)); lua_pushboolean(L, false); return 1; } if(event->getEventType() != MOVE_EVENT_EQUIP) lua_pushboolean(L, MoveEvent::DeEquipItem(event, player, item, slot, boolean)); else lua_pushboolean(L, MoveEvent::EquipItem(event, player, item, slot, boolean)); return 1; } else if(event->getEventType() == MOVE_EVENT_STEP_IN) { ScriptEnviroment* env = getEnv(); Item* item = env->getItemByUID(popNumber(L)); if(!item) { error(__FUNCTION__, getError(LUA_ERROR_ITEM_NOT_FOUND)); lua_pushboolean(L, false); return 1; } Creature* creature = env->getCreatureByUID(popNumber(L)); if(!creature) { error(__FUNCTION__, getError(LUA_ERROR_CREATURE_NOT_FOUND)); lua_pushboolean(L, false); return 1; } lua_pushboolean(L, MoveEvent::StepInField(creature, item)); return 1; } else if(event->getEventType() == MOVE_EVENT_ADD_ITEM) { ScriptEnviroment* env = getEnv(); Item* item = env->getItemByUID(popNumber(L)); if(!item) { error(__FUNCTION__, getError(LUA_ERROR_ITEM_NOT_FOUND)); lua_pushboolean(L, false); return 1; } lua_pushboolean(L, MoveEvent::AddItemField(item)); return 1; } error(__FUNCTION__, "callFunction not available for current event."); lua_pushboolean(L, false); return 1; } MoveEvents::MoveEvents(): m_lastCacheTile(NULL) { m_interface.initState(); } inline void MoveEvents::clearMap(MoveListMap& map) { for(MoveListMap::iterator it = map.begin(); it != map.end(); ++it) { for(int32_t i = MOVE_EVENT_FIRST; i <= MOVE_EVENT_LAST; ++i) { EventList& moveEventList = it->second.moveEvent[i]; for(EventList::iterator it = moveEventList.begin(); it != moveEventList.end(); ++it) delete (*it); moveEventList.clear(); } } map.clear(); } void MoveEvents::clear() { clearMap(m_itemIdMap); clearMap(m_actionIdMap); clearMap(m_uniqueIdMap); for(MovePosListMap::iterator it = m_positionMap.begin(); it != m_positionMap.end(); ++it) { for(int32_t i = MOVE_EVENT_FIRST; i <= MOVE_EVENT_LAST; ++i) { EventList& moveEventList = it->second.moveEvent[i]; for(EventList::iterator it = moveEventList.begin(); it != moveEventList.end(); ++it) delete (*it); moveEventList.clear(); } } m_positionMap.clear(); m_interface.reInitState(); m_lastCacheTile = NULL; m_lastCacheItemVector.clear(); } Event* MoveEvents::getEvent(const std::string& nodeName) { std::string tmpNodeName = asLowerCaseString(nodeName); if(tmpNodeName == "movevent" || tmpNodeName == "moveevent" || tmpNodeName == "movement") return new MoveEvent(&m_interface); return NULL; } bool MoveEvents::registerEvent(Event* event, xmlNodePtr p, bool override) { MoveEvent* moveEvent = dynamic_cast<MoveEvent*>(event); if(!moveEvent) return false; std::string strValue, endStrValue; MoveEvent_t eventType = moveEvent->getEventType(); if((eventType == MOVE_EVENT_ADD_ITEM || eventType == MOVE_EVENT_REMOVE_ITEM) && readXMLString(p, "tileitem", strValue) && booleanString(strValue)) { switch(eventType) { case MOVE_EVENT_ADD_ITEM: moveEvent->setEventType(MOVE_EVENT_ADD_TILEITEM); break; case MOVE_EVENT_REMOVE_ITEM: moveEvent->setEventType(MOVE_EVENT_REMOVE_TILEITEM); break; default: break; } } StringVec strVector; IntegerVec intVector, endIntVector; bool success = true; if(readXMLString(p, "itemid", strValue)) { strVector = explodeString(strValue, ";"); for(StringVec::iterator it = strVector.begin(); it != strVector.end(); ++it) { intVector = vectorAtoi(explodeString((*it), "-")); if(!intVector[0]) continue; bool equip = moveEvent->getEventType() == MOVE_EVENT_EQUIP; addEvent(moveEvent, intVector[0], m_itemIdMap, override); if(equip) { ItemType& it = Item::items.getItemType(intVector[0]); it.wieldInfo = moveEvent->getWieldInfo(); it.minReqLevel = moveEvent->getReqLevel(); it.minReqMagicLevel = moveEvent->getReqMagLv(); it.vocationString = moveEvent->getVocationString(); } if(intVector.size() > 1) { while(intVector[0] < intVector[1]) { addEvent(new MoveEvent(moveEvent), ++intVector[0], m_itemIdMap, override); if(equip) { ItemType& tit = Item::items.getItemType(intVector[0]); tit.wieldInfo = moveEvent->getWieldInfo(); tit.minReqLevel = moveEvent->getReqLevel(); tit.minReqMagicLevel = moveEvent->getReqMagLv(); tit.vocationString = moveEvent->getVocationString(); } } } } } if(readXMLString(p, "fromid", strValue) && readXMLString(p, "toid", endStrValue)) { intVector = vectorAtoi(explodeString(strValue, ";")); endIntVector = vectorAtoi(explodeString(endStrValue, ";")); if(intVector[0] && endIntVector[0] && intVector.size() == endIntVector.size()) { for(size_t i = 0, size = intVector.size(); i < size; ++i) { bool equip = moveEvent->getEventType() == MOVE_EVENT_EQUIP; addEvent(moveEvent, intVector[i], m_itemIdMap, override); if(equip) { ItemType& it = Item::items.getItemType(intVector[i]); it.wieldInfo = moveEvent->getWieldInfo(); it.minReqLevel = moveEvent->getReqLevel(); it.minReqMagicLevel = moveEvent->getReqMagLv(); it.vocationString = moveEvent->getVocationString(); } while(intVector[i] < endIntVector[i]) { addEvent(new MoveEvent(moveEvent), ++intVector[i], m_itemIdMap, override); if(equip) { ItemType& tit = Item::items.getItemType(intVector[i]); tit.wieldInfo = moveEvent->getWieldInfo(); tit.minReqLevel = moveEvent->getReqLevel(); tit.minReqMagicLevel = moveEvent->getReqMagLv(); tit.vocationString = moveEvent->getVocationString(); } } } } else std::clog << "[Warning - MoveEvents::registerEvent] Malformed entry (from item: \"" << strValue << "\", to item: \"" << endStrValue << "\")" << std::endl; } if(readXMLString(p, "uniqueid", strValue)) { strVector = explodeString(strValue, ";"); for(StringVec::iterator it = strVector.begin(); it != strVector.end(); ++it) { intVector = vectorAtoi(explodeString((*it), "-")); if(!intVector[0]) continue; addEvent(moveEvent, intVector[0], m_uniqueIdMap, override); if(intVector.size() > 1) { while(intVector[0] < intVector[1]) addEvent(new MoveEvent(moveEvent), ++intVector[0], m_uniqueIdMap, override); } } } if(readXMLString(p, "fromuid", strValue) && readXMLString(p, "touid", endStrValue)) { intVector = vectorAtoi(explodeString(strValue, ";")); endIntVector = vectorAtoi(explodeString(endStrValue, ";")); if(intVector[0] && endIntVector[0] && intVector.size() == endIntVector.size()) { for(size_t i = 0, size = intVector.size(); i < size; ++i) { addEvent(moveEvent, intVector[i], m_uniqueIdMap, override); while(intVector[i] < endIntVector[i]) addEvent(new MoveEvent(moveEvent), ++intVector[i], m_uniqueIdMap, override); } } else std::clog << "[Warning - MoveEvents::registerEvent] Malformed entry (from unique: \"" << strValue << "\", to unique: \"" << endStrValue << "\")" << std::endl; } if(readXMLString(p, "actionid", strValue) || readXMLString(p, "aid", strValue)) { strVector = explodeString(strValue, ";"); for(StringVec::iterator it = strVector.begin(); it != strVector.end(); ++it) { intVector = vectorAtoi(explodeString((*it), "-")); if(!intVector[0]) continue; addEvent(moveEvent, intVector[0], m_actionIdMap, override); if(intVector.size() > 1) { while(intVector[0] < intVector[1]) addEvent(new MoveEvent(moveEvent), ++intVector[0], m_actionIdMap, override); } } } if(readXMLString(p, "fromaid", strValue) && readXMLString(p, "toaid", endStrValue)) { intVector = vectorAtoi(explodeString(strValue, ";")); endIntVector = vectorAtoi(explodeString(endStrValue, ";")); if(intVector[0] && endIntVector[0] && intVector.size() == endIntVector.size()) { for(size_t i = 0, size = intVector.size(); i < size; ++i) { addEvent(moveEvent, intVector[i], m_actionIdMap, override); while(intVector[i] < endIntVector[i]) addEvent(new MoveEvent(moveEvent), ++intVector[i], m_actionIdMap, override); } } else std::clog << "[Warning - MoveEvents::registerEvent] Malformed entry (from action: \"" << strValue << "\", to action: \"" << endStrValue << "\")" << std::endl; } if(readXMLString(p, "pos", strValue) || readXMLString(p, "position", strValue)) { strVector = explodeString(strValue, ";"); for(StringVec::iterator it = strVector.begin(); it != strVector.end(); ++it) { intVector = vectorAtoi(explodeString((*it), ",")); if(intVector.size() > 2) addEvent(moveEvent, Position(intVector[0], intVector[1], intVector[2]), m_positionMap, override); else success = false; } } return success; } void MoveEvents::addEvent(MoveEvent* moveEvent, int32_t id, MoveListMap& map, bool override) { MoveListMap::iterator it = map.find(id); if(it != map.end()) { EventList& moveEventList = it->second.moveEvent[moveEvent->getEventType()]; for(EventList::iterator it = moveEventList.begin(); it != moveEventList.end(); ++it) { if((*it)->getSlot() != moveEvent->getSlot()) continue; if(override) { delete *it; *it = moveEvent; } else std::clog << "[Warning - MoveEvents::addEvent] Duplicate move event found: " << id << std::endl; return; } moveEventList.push_back(moveEvent); } else { MoveEventList moveEventList; moveEventList.moveEvent[moveEvent->getEventType()].push_back(moveEvent); map[id] = moveEventList; } } MoveEvent* MoveEvents::getEvent(Item* item, MoveEvent_t eventType) { MoveListMap::iterator it; if(item->getUniqueId()) { it = m_uniqueIdMap.find(item->getUniqueId()); if(it != m_uniqueIdMap.end()) { EventList& moveEventList = it->second.moveEvent[eventType]; if(!moveEventList.empty()) return *moveEventList.begin(); } } if(item->getActionId()) { it = m_actionIdMap.find(item->getActionId()); if(it != m_actionIdMap.end()) { EventList& moveEventList = it->second.moveEvent[eventType]; if(!moveEventList.empty()) return *moveEventList.begin(); } } it = m_itemIdMap.find(item->getID()); if(it != m_itemIdMap.end()) { EventList& moveEventList = it->second.moveEvent[eventType]; if(!moveEventList.empty()) return *moveEventList.begin(); } return NULL; } MoveEvent* MoveEvents::getEvent(Item* item, MoveEvent_t eventType, slots_t slot) { uint32_t slotp = 0; switch(slot) { case SLOT_HEAD: slotp = SLOTP_HEAD; break; case SLOT_NECKLACE: slotp = SLOTP_NECKLACE; break; case SLOT_BACKPACK: slotp = SLOTP_BACKPACK; break; case SLOT_ARMOR: slotp = SLOTP_ARMOR; break; case SLOT_RIGHT: slotp = SLOTP_RIGHT; break; case SLOT_LEFT: slotp = SLOTP_LEFT; break; case SLOT_LEGS: slotp = SLOTP_LEGS; break; case SLOT_FEET: slotp = SLOTP_FEET; break; case SLOT_AMMO: slotp = SLOTP_AMMO; break; case SLOT_RING: slotp = SLOTP_RING; break; default: break; } MoveListMap::iterator it = m_itemIdMap.find(item->getID()); if(it == m_itemIdMap.end()) return NULL; EventList& moveEventList = it->second.moveEvent[eventType]; for(EventList::iterator it = moveEventList.begin(); it != moveEventList.end(); ++it) { if(((*it)->getSlot() & slotp)) return *it; } return NULL; } void MoveEvents::addEvent(MoveEvent* moveEvent, Position pos, MovePosListMap& map, bool override) { MovePosListMap::iterator it = map.find(pos); if(it != map.end()) { bool add = true; if(!it->second.moveEvent[moveEvent->getEventType()].empty()) { if(!override) { std::clog << "[Warning - MoveEvents::addEvent] Duplicate move event found: " << pos << std::endl; add = false; } else it->second.moveEvent[moveEvent->getEventType()].clear(); } if(add) it->second.moveEvent[moveEvent->getEventType()].push_back(moveEvent); } else { MoveEventList moveEventList; moveEventList.moveEvent[moveEvent->getEventType()].push_back(moveEvent); map[pos] = moveEventList; } } MoveEvent* MoveEvents::getEvent(const Tile* tile, MoveEvent_t eventType) { MovePosListMap::iterator it = m_positionMap.find(tile->getPosition()); if(it == m_positionMap.end()) return NULL; EventList& moveEventList = it->second.moveEvent[eventType]; if(!moveEventList.empty()) return *moveEventList.begin(); return NULL; } bool MoveEvents::hasEquipEvent(Item* item) { MoveEvent* event = NULL; return (event = getEvent(item, MOVE_EVENT_EQUIP)) && !event->isScripted() && (event = getEvent(item, MOVE_EVENT_DE_EQUIP)) && !event->isScripted(); } bool MoveEvents::hasTileEvent(Item* item) { return getEvent(item, MOVE_EVENT_STEP_IN) || getEvent(item, MOVE_EVENT_STEP_OUT) || getEvent( item, MOVE_EVENT_ADD_TILEITEM) || getEvent(item, MOVE_EVENT_REMOVE_TILEITEM); } uint32_t MoveEvents::onCreatureMove(Creature* actor, Creature* creature, const Tile* fromTile, const Tile* toTile, bool isStepping) { MoveEvent_t eventType = MOVE_EVENT_STEP_OUT; const Tile* tile = fromTile; if(isStepping) { eventType = MOVE_EVENT_STEP_IN; tile = toTile; } Position fromPos; if(fromTile) fromPos = fromTile->getPosition(); Position toPos; if(toTile) toPos = toTile->getPosition(); uint32_t ret = 1; MoveEvent* moveEvent = NULL; if((moveEvent = getEvent(tile, eventType))) ret &= moveEvent->fireStepEvent(actor, creature, NULL, Position(), fromPos, toPos); Item* tileItem = NULL; if(m_lastCacheTile == tile) { if(m_lastCacheItemVector.empty()) return ret; //We cannot use iterators here since the scripts can invalidate the iterator for(uint32_t i = 0; i < m_lastCacheItemVector.size(); ++i) { if((tileItem = m_lastCacheItemVector[i]) && (moveEvent = getEvent(tileItem, eventType))) ret &= moveEvent->fireStepEvent(actor, creature, tileItem, tile->getPosition(), fromPos, toPos); } return ret; } m_lastCacheTile = tile; m_lastCacheItemVector.clear(); //We cannot use iterators here since the scripts can invalidate the iterator Thing* thing = NULL; for(int32_t i = tile->__getFirstIndex(), j = tile->__getLastIndex(); i < j; ++i) //already checked the ground { if(!(thing = tile->__getThing(i)) || !(tileItem = thing->getItem())) continue; if((moveEvent = getEvent(tileItem, eventType))) { m_lastCacheItemVector.push_back(tileItem); ret &= moveEvent->fireStepEvent(actor, creature, tileItem, tile->getPosition(), fromPos, toPos); } else if(hasTileEvent(tileItem)) m_lastCacheItemVector.push_back(tileItem); } return ret; } bool MoveEvents::onPlayerEquip(Player* player, Item* item, slots_t slot, bool isCheck) { if(MoveEvent* moveEvent = getEvent(item, MOVE_EVENT_EQUIP, slot)) return moveEvent->fireEquip(player, item, slot, isCheck); return true; } bool MoveEvents::onPlayerDeEquip(Player* player, Item* item, slots_t slot, bool isRemoval) { if(MoveEvent* moveEvent = getEvent(item, MOVE_EVENT_DE_EQUIP, slot)) return moveEvent->fireEquip(player, item, slot, isRemoval); return true; } uint32_t MoveEvents::onItemMove(Creature* actor, Item* item, Tile* tile, bool isAdd) { MoveEvent_t eventType = MOVE_EVENT_REMOVE_ITEM, tileEventType = MOVE_EVENT_REMOVE_TILEITEM; if(isAdd) { eventType = MOVE_EVENT_ADD_ITEM; tileEventType = MOVE_EVENT_ADD_TILEITEM; } uint32_t ret = 1; MoveEvent* moveEvent = getEvent(tile, eventType); if(moveEvent) ret &= moveEvent->fireAddRemItem(actor, item, NULL, tile->getPosition()); moveEvent = getEvent(item, eventType); if(moveEvent) ret &= moveEvent->fireAddRemItem(actor, item, NULL, tile->getPosition()); Item* tileItem = NULL; if(m_lastCacheTile == tile) { if(m_lastCacheItemVector.empty()) return ret; //We cannot use iterators here since the scripts can invalidate the iterator for(uint32_t i = 0; i < m_lastCacheItemVector.size(); ++i) { if((tileItem = m_lastCacheItemVector[i]) && tileItem != item && (moveEvent = getEvent(tileItem, tileEventType))) ret &= moveEvent->fireAddRemItem(actor, item, tileItem, tile->getPosition()); } return ret; } m_lastCacheTile = tile; m_lastCacheItemVector.clear(); //we cannot use iterators here since the scripts can invalidate the iterator Thing* thing = NULL; for(int32_t i = tile->__getFirstIndex(), j = tile->__getLastIndex(); i < j; ++i) //already checked the ground { if(!(thing = tile->__getThing(i)) || !(tileItem = thing->getItem()) || tileItem == item) continue; if((moveEvent = getEvent(tileItem, tileEventType))) { m_lastCacheItemVector.push_back(tileItem); ret &= moveEvent->fireAddRemItem(actor, item, tileItem, tile->getPosition()); } else if(hasTileEvent(tileItem)) m_lastCacheItemVector.push_back(tileItem); } return ret; } void MoveEvents::onAddTileItem(const Tile* tile, Item* item) { if(m_lastCacheTile != tile) return; std::vector<Item*>::iterator it = std::find(m_lastCacheItemVector.begin(), m_lastCacheItemVector.end(), item); if(it == m_lastCacheItemVector.end() && hasTileEvent(item)) m_lastCacheItemVector.push_back(item); } void MoveEvents::onRemoveTileItem(const Tile* tile, Item* item) { if(m_lastCacheTile != tile) return; for(uint32_t i = 0; i < m_lastCacheItemVector.size(); ++i) { if(m_lastCacheItemVector[i] != item) continue; m_lastCacheItemVector[i] = NULL; break; } } MoveEvent::MoveEvent(LuaInterface* _interface): Event(_interface) { m_eventType = MOVE_EVENT_NONE; stepFunction = NULL; moveFunction = NULL; equipFunction = NULL; slot = SLOTP_WHEREEVER; wieldInfo = 0; reqLevel = 0; reqMagLevel = 0; premium = false; } MoveEvent::MoveEvent(const MoveEvent* copy): Event(copy) { m_eventType = copy->m_eventType; stepFunction = copy->stepFunction; moveFunction = copy->moveFunction; equipFunction = copy->equipFunction; slot = copy->slot; if(copy->m_eventType == MOVE_EVENT_EQUIP) { wieldInfo = copy->wieldInfo; reqLevel = copy->reqLevel; reqMagLevel = copy->reqMagLevel; vocationString = copy->vocationString; premium = copy->premium; vocEquipMap = copy->vocEquipMap; } } MoveEvent::~MoveEvent() { // } std::string MoveEvent::getScriptEventName() const { switch(m_eventType) { case MOVE_EVENT_STEP_IN: return "onStepIn"; case MOVE_EVENT_STEP_OUT: return "onStepOut"; case MOVE_EVENT_EQUIP: return "onEquip"; case MOVE_EVENT_DE_EQUIP: return "onDeEquip"; case MOVE_EVENT_ADD_ITEM: return "onAddItem"; case MOVE_EVENT_REMOVE_ITEM: return "onRemoveItem"; default: break; } std::clog << "[Error - MoveEvent::getScriptEventName] No valid event type." << std::endl; return ""; } std::string MoveEvent::getScriptEventParams() const { switch(m_eventType) { case MOVE_EVENT_STEP_IN: case MOVE_EVENT_STEP_OUT: return "cid, item, position, lastPosition, fromPosition, toPosition, actor"; case MOVE_EVENT_EQUIP: case MOVE_EVENT_DE_EQUIP: return "cid, item, slot, boolean"; case MOVE_EVENT_ADD_ITEM: case MOVE_EVENT_REMOVE_ITEM: return "moveItem, tileItem, position, cid"; default: break; } std::clog << "[Error - MoveEvent::getScriptEventParams] No valid event type." << std::endl; return ""; } bool MoveEvent::configureEvent(xmlNodePtr p) { std::string strValue; int32_t intValue; if(readXMLString(p, "type", strValue) || readXMLString(p, "event", strValue)) { std::string tmpStrValue = asLowerCaseString(strValue); if(tmpStrValue == "stepin") m_eventType = MOVE_EVENT_STEP_IN; else if(tmpStrValue == "stepout") m_eventType = MOVE_EVENT_STEP_OUT; else if(tmpStrValue == "equip") m_eventType = MOVE_EVENT_EQUIP; else if(tmpStrValue == "deequip") m_eventType = MOVE_EVENT_DE_EQUIP; else if(tmpStrValue == "additem") m_eventType = MOVE_EVENT_ADD_ITEM; else if(tmpStrValue == "removeitem") m_eventType = MOVE_EVENT_REMOVE_ITEM; else { if(tmpStrValue == "function" || tmpStrValue == "buffer" || tmpStrValue == "script") std::clog << "[Error - MoveEvent::configureMoveEvent] No event type found." << std::endl; else std::clog << "[Error - MoveEvent::configureMoveEvent] Unknown event type \"" << strValue << "\"" << std::endl; return false; } if(m_eventType == MOVE_EVENT_EQUIP || m_eventType == MOVE_EVENT_DE_EQUIP) { if(readXMLString(p, "slot", strValue)) { std::string tmpStrValue = asLowerCaseString(strValue); if(tmpStrValue == "head") slot = SLOTP_HEAD; else if(tmpStrValue == "necklace") slot = SLOTP_NECKLACE; else if(tmpStrValue == "backpack") slot = SLOTP_BACKPACK; else if(tmpStrValue == "armor") slot = SLOTP_ARMOR; else if(tmpStrValue == "left-hand") slot = SLOTP_LEFT; else if(tmpStrValue == "right-hand") slot = SLOTP_RIGHT; else if(tmpStrValue == "hands" || tmpStrValue == "two-handed") slot = SLOTP_TWO_HAND; else if(tmpStrValue == "hand" || tmpStrValue == "shield") slot = SLOTP_RIGHT | SLOTP_LEFT; else if(tmpStrValue == "legs") slot = SLOTP_LEGS; else if(tmpStrValue == "feet") slot = SLOTP_FEET; else if(tmpStrValue == "ring") slot = SLOTP_RING; else if(tmpStrValue == "ammo" || tmpStrValue == "ammunition") slot = SLOTP_AMMO; else if(tmpStrValue == "pickupable") slot = SLOTP_RIGHT | SLOTP_LEFT | SLOTP_AMMO; else if(tmpStrValue == "wherever" || tmpStrValue == "any") slot = SLOTP_WHEREEVER; else std::clog << "[Warning - MoveEvent::configureMoveEvent] Unknown slot type \"" << strValue << "\"" << std::endl; } wieldInfo = 0; if(readXMLInteger(p, "lvl", intValue) || readXMLInteger(p, "level", intValue)) { reqLevel = intValue; if(reqLevel > 0) wieldInfo |= WIELDINFO_LEVEL; } if(readXMLInteger(p, "maglv", intValue) || readXMLInteger(p, "maglevel", intValue)) { reqMagLevel = intValue; if(reqMagLevel > 0) wieldInfo |= WIELDINFO_MAGLV; } if(readXMLString(p, "prem", strValue) || readXMLString(p, "premium", strValue)) { premium = booleanString(strValue); if(premium) wieldInfo |= WIELDINFO_PREMIUM; } StringVec vocStringVec; std::string error = ""; for(xmlNodePtr vocationNode = p->children; vocationNode; vocationNode = vocationNode->next) { if(!parseVocationNode(vocationNode, vocEquipMap, vocStringVec, error)) std::clog << "[Warning - MoveEvent::configureEvent] " << error << std::endl; } if(!vocEquipMap.empty()) wieldInfo |= WIELDINFO_VOCREQ; vocationString = parseVocationString(vocStringVec); } } else { std::clog << "[Error - MoveEvent::configureMoveEvent] No event type found." << std::endl; return false; } return true; } bool MoveEvent::loadFunction(const std::string& functionName) { std::string tmpFunctionName = asLowerCaseString(functionName); if(tmpFunctionName == "onstepinfield") stepFunction = StepInField; else if(tmpFunctionName == "onaddfield") moveFunction = AddItemField; else if(tmpFunctionName == "onequipitem") equipFunction = EquipItem; else if(tmpFunctionName == "ondeequipitem") equipFunction = DeEquipItem; else { std::clog << "[Warning - MoveEvent::loadFunction] Function \"" << functionName << "\" does not exist." << std::endl; return false; } m_scripted = EVENT_SCRIPT_FALSE; return true; } MoveEvent_t MoveEvent::getEventType() const { if(m_eventType == MOVE_EVENT_NONE) std::clog << "[Error - MoveEvent::getEventType] MOVE_EVENT_NONE" << std::endl; return m_eventType; } void MoveEvent::setEventType(MoveEvent_t type) { m_eventType = type; } uint32_t MoveEvent::StepInField(Creature* creature, Item* item) { if(MagicField* field = item->getMagicField()) { field->onStepInField(creature, creature->getPlayer()); return 1; } return LUA_ERROR_ITEM_NOT_FOUND; } uint32_t MoveEvent::AddItemField(Item* item) { if(MagicField* field = item->getMagicField()) { if(Tile* tile = item->getTile()) { if(CreatureVector* creatures = tile->getCreatures()) { for(CreatureVector::iterator cit = creatures->begin(); cit != creatures->end(); ++cit) field->onStepInField(*cit); } } return 1; } return LUA_ERROR_ITEM_NOT_FOUND; } bool MoveEvent::EquipItem(MoveEvent* moveEvent, Player* player, Item* item, slots_t slot, bool isCheck) { if(player->isItemAbilityEnabled(slot)) return true; if(!player->hasFlag(PlayerFlag_IgnoreEquipCheck) && moveEvent->getWieldInfo() != 0) { if(player->getLevel() < (uint32_t)moveEvent->getReqLevel() || player->getMagicLevel() < (uint32_t)moveEvent->getReqMagLv()) return false; if(moveEvent->isPremium() && !player->isPremium()) return false; if(!moveEvent->getVocEquipMap().empty() && moveEvent->getVocEquipMap().find(player->getVocationId()) == moveEvent->getVocEquipMap().end()) return false; } if(isCheck) return true; const ItemType& it = Item::items[item->getID()]; if(it.transformEquipTo) { Item* newItem = g_game.transformItem(item, it.transformEquipTo); g_game.startDecay(newItem); } player->setItemAbility(slot, true); if(it.abilities.invisible) { Condition* condition = Condition::createCondition((ConditionId_t)slot, CONDITION_INVISIBLE, -1, 0); player->addCondition(condition); } if(it.abilities.manaShield) { Condition* condition = Condition::createCondition((ConditionId_t)slot, CONDITION_MANASHIELD, -1, 0); player->addCondition(condition); } if(it.abilities.speed) g_game.changeSpeed(player, it.abilities.speed); if(it.abilities.conditionSuppressions) { player->setConditionSuppressions(it.abilities.conditionSuppressions, false); player->sendIcons(); } if(it.abilities.regeneration) { Condition* condition = Condition::createCondition((ConditionId_t)slot, CONDITION_REGENERATION, -1, 0); if(it.abilities.healthGain) condition->setParam(CONDITIONPARAM_HEALTHGAIN, it.abilities.healthGain); if(it.abilities.healthTicks) condition->setParam(CONDITIONPARAM_HEALTHTICKS, it.abilities.healthTicks); if(it.abilities.manaGain) condition->setParam(CONDITIONPARAM_MANAGAIN, it.abilities.manaGain); if(it.abilities.manaTicks) condition->setParam(CONDITIONPARAM_MANATICKS, it.abilities.manaTicks); player->addCondition(condition); } bool needUpdateSkills = false; for(uint32_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) { if(it.abilities.skills[i]) { player->setVarSkill((skills_t)i, it.abilities.skills[i]); if(!needUpdateSkills) needUpdateSkills = true; } if(it.abilities.skillsPercent[i]) { player->setVarSkill((skills_t)i, (int32_t)(player->getSkill((skills_t)i, SKILL_LEVEL) * ((it.abilities.skillsPercent[i] - 100) / 100.f))); if(!needUpdateSkills) needUpdateSkills = true; } } if(needUpdateSkills) player->sendSkills(); bool needUpdateStats = false; for(uint32_t s = STAT_FIRST; s <= STAT_LAST; ++s) { if(it.abilities.stats[s]) { player->setVarStats((stats_t)s, it.abilities.stats[s]); if(!needUpdateStats) needUpdateStats = true; } if(it.abilities.statsPercent[s]) { player->setVarStats((stats_t)s, (int32_t)(player->getDefaultStats((stats_t)s) * ((it.abilities.statsPercent[s] - 100) / 100.f))); if(!needUpdateStats) needUpdateStats = true; } } if(needUpdateStats) player->sendStats(); return true; } bool MoveEvent::DeEquipItem(MoveEvent*, Player* player, Item* item, slots_t slot, bool isRemoval) { if(!player->isItemAbilityEnabled(slot)) return true; const ItemType& it = Item::items[item->getID()]; if(isRemoval && it.transformDeEquipTo) { g_game.transformItem(item, it.transformDeEquipTo); g_game.startDecay(item); } player->setItemAbility(slot, false); if(it.abilities.invisible) player->removeCondition(CONDITION_INVISIBLE, (ConditionId_t)slot); if(it.abilities.manaShield) player->removeCondition(CONDITION_MANASHIELD, (ConditionId_t)slot); if(it.abilities.speed) g_game.changeSpeed(player, -it.abilities.speed); if(it.abilities.conditionSuppressions) { player->setConditionSuppressions(it.abilities.conditionSuppressions, true); player->sendIcons(); } if(it.abilities.regeneration) player->removeCondition(CONDITION_REGENERATION, (ConditionId_t)slot); bool needUpdateSkills = false; for(uint32_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) { if(it.abilities.skills[i]) { needUpdateSkills = true; player->setVarSkill((skills_t)i, -it.abilities.skills[i]); } if(it.abilities.skillsPercent[i]) { needUpdateSkills = true; player->setVarSkill((skills_t)i, -(int32_t)(player->getSkill((skills_t)i, SKILL_LEVEL) * ((it.abilities.skillsPercent[i] - 100) / 100.f))); } } if(needUpdateSkills) player->sendSkills(); bool needUpdateStats = false; for(uint32_t s = STAT_FIRST; s <= STAT_LAST; ++s) { if(it.abilities.stats[s]) { needUpdateStats = true; player->setVarStats((stats_t)s, -it.abilities.stats[s]); } if(it.abilities.statsPercent[s]) { needUpdateStats = true; player->setVarStats((stats_t)s, -(int32_t)(player->getDefaultStats((stats_t)s) * ((it.abilities.statsPercent[s] - 100) / 100.f))); } } if(needUpdateStats) player->sendStats(); return true; } uint32_t MoveEvent::fireStepEvent(Creature* actor, Creature* creature, Item* item, const Position& pos, const Position& fromPos, const Position& toPos) { if(isScripted()) return executeStep(actor, creature, item, pos, fromPos, toPos); return stepFunction(creature, item); } uint32_t MoveEvent::executeStep(Creature* actor, Creature* creature, Item* item, const Position& pos, const Position& fromPos, const Position& toPos) { //onStepIn(cid, item, position, lastPosition, fromPosition, toPosition, actor) //onStepOut(cid, item, position, lastPosition, fromPosition, toPosition, actor) if(m_interface->reserveEnv()) { MoveEventScript::event = this; ScriptEnviroment* env = m_interface->getEnv(); if(m_scripted == EVENT_SCRIPT_BUFFER) { env->setRealPos(creature->getPosition()); std::stringstream scriptstream; scriptstream << "local cid = " << env->addThing(creature) << std::endl; env->streamThing(scriptstream, "item", item, env->addThing(item)); env->streamPosition(scriptstream, "position", pos, 0); env->streamPosition(scriptstream, "lastPosition", creature->getLastPosition(), 0); env->streamPosition(scriptstream, "fromPosition", fromPos, 0); env->streamPosition(scriptstream, "toPosition", toPos, 0); scriptstream << "local actor = " << env->addThing(actor) << std::endl; if(m_scriptData) scriptstream << *m_scriptData; bool result = true; if(m_interface->loadBuffer(scriptstream.str())) { lua_State* L = m_interface->getState(); result = m_interface->getGlobalBool(L, "_result", true); } m_interface->releaseEnv(); return result; } else { #ifdef __DEBUG_LUASCRIPTS__ std::stringstream desc; desc << creature->getName() << " itemid: " << item->getID() << " - " << pos; env->setEvent(desc.str()); #endif env->setScriptId(m_scriptId, m_interface); env->setRealPos(creature->getPosition()); lua_State* L = m_interface->getState(); m_interface->pushFunction(m_scriptId); lua_pushnumber(L, env->addThing(creature)); LuaInterface::pushThing(L, item, env->addThing(item)); LuaInterface::pushPosition(L, pos, 0); LuaInterface::pushPosition(L, creature->getLastPosition(), 0); LuaInterface::pushPosition(L, fromPos, 0); LuaInterface::pushPosition(L, toPos, 0); lua_pushnumber(L, env->addThing(actor)); bool result = m_interface->callFunction(7); m_interface->releaseEnv(); return result; } } else { std::clog << "[Error - MoveEvent::executeStep] Call stack overflow." << std::endl; return 0; } } bool MoveEvent::fireEquip(Player* player, Item* item, slots_t slot, bool boolean) { if(isScripted()) return executeEquip(player, item, slot, boolean); return equipFunction(this, player, item, slot, boolean); } bool MoveEvent::executeEquip(Player* player, Item* item, slots_t slot, bool boolean) { //onEquip(cid, item, slot, boolean) //onDeEquip(cid, item, slot, boolean) if(m_interface->reserveEnv()) { MoveEventScript::event = this; ScriptEnviroment* env = m_interface->getEnv(); if(m_scripted == EVENT_SCRIPT_BUFFER) { env->setRealPos(player->getPosition()); std::stringstream scriptstream; scriptstream << "local cid = " << env->addThing(player) << std::endl; env->streamThing(scriptstream, "item", item, env->addThing(item)); scriptstream << "local slot = " << slot << std::endl; scriptstream << "local boolean = " << (boolean ? "true" : "false") << std::endl; if(m_scriptData) scriptstream << *m_scriptData; bool result = true; if(m_interface->loadBuffer(scriptstream.str())) { lua_State* L = m_interface->getState(); result = m_interface->getGlobalBool(L, "_result", true); } m_interface->releaseEnv(); return result; } else { #ifdef __DEBUG_LUASCRIPTS__ std::stringstream desc; desc << player->getName() << " itemid: " << item->getID() << " slot: " << slot; env->setEvent(desc.str()); #endif env->setScriptId(m_scriptId, m_interface); env->setRealPos(player->getPosition()); lua_State* L = m_interface->getState(); m_interface->pushFunction(m_scriptId); lua_pushnumber(L, env->addThing(player)); LuaInterface::pushThing(L, item, env->addThing(item)); lua_pushnumber(L, slot); lua_pushboolean(L, boolean); bool result = m_interface->callFunction(4); m_interface->releaseEnv(); return result; } } else { std::clog << "[Error - MoveEvent::executeEquip] Call stack overflow." << std::endl; return false; } } uint32_t MoveEvent::fireAddRemItem(Creature* actor, Item* item, Item* tileItem, const Position& pos) { if(isScripted()) return executeAddRemItem(actor, item, tileItem, pos); return moveFunction(item); } uint32_t MoveEvent::executeAddRemItem(Creature* actor, Item* item, Item* tileItem, const Position& pos) { //onAddItem(moveItem, tileItem, position, cid) //onRemoveItem(moveItem, tileItem, position, cid) if(m_interface->reserveEnv()) { MoveEventScript::event = this; ScriptEnviroment* env = m_interface->getEnv(); if(m_scripted == EVENT_SCRIPT_BUFFER) { env->setRealPos(pos); std::stringstream scriptstream; env->streamThing(scriptstream, "moveItem", item, env->addThing(item)); env->streamThing(scriptstream, "tileItem", tileItem, env->addThing(tileItem)); env->streamPosition(scriptstream, "position", pos, 0); scriptstream << "local cid = " << env->addThing(actor) << std::endl; if(m_scriptData) scriptstream << *m_scriptData; bool result = true; if(m_interface->loadBuffer(scriptstream.str())) { lua_State* L = m_interface->getState(); result = m_interface->getGlobalBool(L, "_result", true); } m_interface->releaseEnv(); return result; } else { #ifdef __DEBUG_LUASCRIPTS__ std::stringstream desc; if(tileItem) desc << "tileid: " << tileItem->getID(); desc << " itemid: " << item->getID() << " - " << pos; env->setEvent(desc.str()); #endif env->setScriptId(m_scriptId, m_interface); env->setRealPos(pos); lua_State* L = m_interface->getState(); m_interface->pushFunction(m_scriptId); LuaInterface::pushThing(L, item, env->addThing(item)); LuaInterface::pushThing(L, tileItem, env->addThing(tileItem)); LuaInterface::pushPosition(L, pos, 0); lua_pushnumber(L, env->addThing(actor)); bool result = m_interface->callFunction(4); m_interface->releaseEnv(); return result; } } else { std::clog << "[Error - MoveEvent::executeAddRemItem] Call stack overflow." << std::endl; return 0; } } tibia.com Eu que não fumo, queria um cigarro Eu que não amo você Envelheci dez anos ou mais Nesse último mês Eu que não bebo, pedi um conhaque Pra enfrentar o inverno Que entra pela porta Que você deixou aberta ao sair
Postado Outubro 13, 2021 3 anos Solução Colocou eles no movements.xml? mídias sociais talk to me vídeos
Postado Outubro 15, 2021 3 anos Autor Em 13/10/2021 em 01:03, Rogex Joyz disse: Colocou eles no movements.xml? coloquei assim <movevent type="Equip" itemid="7758" slot="left-hand" event="function" value="onEquipItem"/> <movevent type="DeEquip" itemid="7758" slot="left-hand" event="function" value="onDeEquipItem"/> no movements.xml e o item continua sendo equipado tibia.com Eu que não fumo, queria um cigarro Eu que não amo você Envelheci dez anos ou mais Nesse último mês Eu que não bebo, pedi um conhaque Pra enfrentar o inverno Que entra pela porta Que você deixou aberta ao sair
Postado Outubro 15, 2021 3 anos Autor 5 minutos atrás, Rogex Joyz disse: Adiciona isso level="8" ficou assim: <movevent type="Equip" level="45" itemid="7758" slot="left-hand" event="function" value="onEquipItem"/> <movevent type="DeEquip" level="45" itemid="7758" slot="left-hand" event="function" value="onDeEquipItem"/> porém ainda é equipado Na real, deu certo até certa parte, armaduras não são equipadas, porém as armas são equipadas ainda tibia.com Eu que não fumo, queria um cigarro Eu que não amo você Envelheci dez anos ou mais Nesse último mês Eu que não bebo, pedi um conhaque Pra enfrentar o inverno Que entra pela porta Que você deixou aberta ao sair
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.