Ir para conteúdo

Featured Replies

Postado

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;
	}
}

 

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
avatar_1218.gif

Resolvido por Rogex Joyz

Ir para solução
  • Respostas 11
  • Visualizações 802
  • Created
  • Última resposta

Top Posters In This Topic

Postado
  • Solução

Colocou eles no movements.xml? 

                                                                                                               destinyshield.gif.9f031b59b026058f32a1c50da92ebe2a.gif  mídias sociais  destinyshield.gif.02fca81ab0615e050b2bcefd8a73a2e8.gif

                                                                                                                            talk to me              

                                                                                                                               vídeos           

                                                                                             

                                                                                                            LOGONORMAL.png.815b40b04ec583be88d8a1e2626fe430.png

                                                                                                           

                               

Postado
  • 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

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
avatar_1218.gif
Postado

Adiciona isso

level="8"

                                                                                                               destinyshield.gif.9f031b59b026058f32a1c50da92ebe2a.gif  mídias sociais  destinyshield.gif.02fca81ab0615e050b2bcefd8a73a2e8.gif

                                                                                                                            talk to me              

                                                                                                                               vídeos           

                                                                                             

                                                                                                            LOGONORMAL.png.815b40b04ec583be88d8a1e2626fe430.png

                                                                                                           

                               

Postado
  • 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

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
avatar_1218.gif

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.

Visitante
Responder

Quem Está Navegando 0

  • Nenhum usuário registrado visualizando esta página.

Estatísticas dos Fóruns

  • Tópicos 96.9k
  • Posts 519.7k

Informação Importante

Confirmação de Termo