Ir para conteúdo
  • Cadastre-se

.HuRRiKaNe

Membro
  • Total de itens

    701
  • Registro em

  • Última visita

  • Dias Ganhos

    31

Posts postados por .HuRRiKaNe

  1. Em 25/10/2020 em 14:56, Naze disse:

        Uns dos problemas das maiorias dos otserv casual que estão online é o autoloot, alguns com erros e defeito na checagem dos containers e sempre consumindo muito por ser em lua fazendo checagens de tile, corpo, itens e etc. Por isso decidi da uma contribuição a essa comunidade que me evoluiu bastante um autoloot diretamente na source na função que insere os itens no corpo, otimizando em 100% na hr da entrega do item, e não tendo problemas ocasionais como corpos sobre corpos ou varias bags.

     

         Esse sistema já é bem comum quando comprado, mas gratuito acredito que ainda não tinha disponível, então fiz esse totalmente do 0 na source tfs 0.4 rev 3999 (do yan) e passei para Otx corrigindo alguns erros de compatibilidade.

        

        Atenção na instalação! Qualquer problema pra compilar que envolva as linhas presente no código verifique novamente se instalou corretamente antes de pedir ajuda para evitar flood. Qualquer bug, erro ou mal funcionamento encontrado pode postar que estarei corrigindo, mas não irei customizar a seu agrado, você consegue fazer isso sozinho com atenção e calma, e se precisa de ajuda é só posta as duvidas.

     

    Imagens do Sistema:

      Ocultar conteúdo

    autoloot3.PNGautoloot.PNGautoloot.PNGautoloot2.PNG

     

    Características: 

    
    -> Otimizado executando apenas funções necessarias
    -> Comandos simples e praticos
      -> !autoloot on/off  //Autoloot estara sempre ligado, e caso queria desliga use '!autoloot off'
      -> !autoloot bank/bag //Define para onde ira o dinheiro coletado, direto banco ou no inventario
      -> !autoloot list //Lista todos itens adicionados para coleta
      -> !autoloot clear/clean //Remove todos itens da lista
      -> !autoloot add, name item, name item, ... //Adiciona itens na lista, podendo adicionar quantos quiser de uma vez. Ele retorna um messagem dizendo os itens que foram adicionados e os que deram erro e não foram adicionados, talvez por escrito errado, ja existente na lista, na lista de bloquados, etc.
      -> !autoloot remove, item name, item name, ... //Remove itens da lista, com a mesma logica do add.
    -> Opções configuravel pelo Config.lua
      -> AutoLoot_MoneyIDs //IDs dos Itens Moedas do servidor como gold coins, platinium coins, crystal coins.
      -> AutoLoot_BlockIDs //IDs dos itens bloqueados para autoloot
      -> AutoLoot_MaxItem //Quantidade maxima de itens para adicionar a lista
    -> Sistema livres de bugs ou logs de erros.

     

    Instalação:

    Toda instalação será feita na source, exceto por 1 linha em talkactions.xml e 3 variáveis no config.lua

     

    Otx :

      Mostrar conteúdo oculto

     

    Localize no arquivo "configmanager.h" os enum de string:

    
    
    enum string_config_t
    		{
    			DUMMY_STR = 0,
    			CONFIG_FILE,
    			MAP_NAME,
    			HOUSE_RENT_PERIOD,

     

    E adicione:

    
    
    enum string_config_t
    		{
    			AUTOLOOT_BLOCKIDS, //autoloot by naze#3578
    			AUTOLOOT_MONEYIDS, //autoloot by naze#3578
    			DUMMY_STR = 0,
    			CONFIG_FILE,
    			MAP_NAME,
    			HOUSE_RENT_PERIOD,

     

    No mesmo arquivo localize o enum de number:

    
    
    enum number_config_t
    		{
    			LOGIN_TRIES = 0,
    			RETRY_TIMEOUT,
    			LOGIN_TIMEOUT,
    			LOGIN_PORT,

     

    E adicione:

    
    
    enum number_config_t
    		{
    			AUTOLOOT_MAXITEM, //autoloot by naze#3578
    			LOGIN_TRIES = 0,
    			RETRY_TIMEOUT,
    			LOGIN_TIMEOUT,
    			LOGIN_PORT,

     

    Localize no arquivo "configmanager.cpp" :

    
    
    	m_confString[MAP_AUTHOR] = getGlobalString("mapAuthor", "Unknown");
    	m_confNumber[LOGIN_TRIES] = getGlobalNumber("loginTries", 3);

     

     

    E adicione:

    
    
    	m_confString[AUTOLOOT_BLOCKIDS] = getGlobalString("AutoLoot_BlockIDs", "");	//autoloot by naze#3578
    	m_confString[AUTOLOOT_MONEYIDS] = getGlobalString("AutoLoot_MoneyIDs", "2148;2152;2160"); //autoloot by naze#3578
    	m_confNumber[AUTOLOOT_MAXITEM] = getGlobalNumber("AutoLoot_MaxItem", 100); //autoloot by naze#3578
    	m_confString[MAP_AUTHOR] = getGlobalString("mapAuthor", "Unknown");
    	m_confNumber[LOGIN_TRIES] = getGlobalNumber("loginTries", 3);

     

    Localize no arquivo "iologindata.cpp" :

    
    
    //load storage map
    	query.str("");
    	query << "SELECT `key`, `value` FROM `player_storage` WHERE `player_id` = " << player->getGUID();
    	if((result = db->storeQuery(query.str())))
    	{
    		do
    			player->setStorage(result->getDataString("key"), result->getDataString("value"));
    		while(result->next());
    		result->free();
    	}

     

    E adicione a baixo :

    
    
    	//load autoloot
    	query.str("");
        query << "SELECT `autoloot_list` FROM `player_autoloot` WHERE `player_id` = " << player->getGUID();
        if ((result = db->storeQuery(query.str()))) {
            unsigned long lootListSize;
            const char* autoLootList = result->getDataStream("autoloot_list", lootListSize);
            // PropStream &propStream;
    		PropStream propStream;
            propStream.init(autoLootList, lootListSize);
    
            uint16_t value;
            uint16_t item = propStream.getType<uint16_t>(value);
            while (item) {
                player->addAutoLoot(value);
                item = propStream.getType<uint16_t>(value);
            }
        }
    	player->updateStatusAutoLoot(true);
    	std::string msg = g_config.getString(ConfigManager::AUTOLOOT_MONEYIDS);
    	StringVec strVector = explodeString(msg, ";");
    	for(StringVec::iterator it = strVector.begin(); it != strVector.end(); ++it) {
    		uint16_t id = atoi((*it).c_str());
    		player->addAutoLoot(id);
    	}

     

    ficando dessa forma:

      Mostrar conteúdo oculto
    
    
    
    
    
    
    
    
    
    
    
    	//load storage map
    	query.str("");
    	query << "SELECT `key`, `value` FROM `player_storage` WHERE `player_id` = " << player->getGUID();
    	if((result = db->storeQuery(query.str())))
    	{
    		do
    			player->setStorage(result->getDataString("key"), result->getDataString("value"));
    		while(result->next());
    		result->free();
    	}
    
    	//load autoloot
    	query.str("");
        query << "SELECT `autoloot_list` FROM `player_autoloot` WHERE `player_id` = " << player->getGUID();
        if ((result = db->storeQuery(query.str()))) {
            unsigned long lootListSize;
            const char* autoLootList = result->getDataStream("autoloot_list", lootListSize);
            // PropStream &propStream;
    		PropStream propStream;
            propStream.init(autoLootList, lootListSize);
    
            uint16_t value;
            uint16_t item = propStream.getType<uint16_t>(value);
            while (item) {
                player->addAutoLoot(value);
                item = propStream.getType<uint16_t>(value);
            }
        }
    	player->updateStatusAutoLoot(true);
    	std::string msg = g_config.getString(ConfigManager::AUTOLOOT_MONEYIDS);
    	StringVec strVector = explodeString(msg, ";");
    	for(StringVec::iterator it = strVector.begin(); it != strVector.end(); ++it) {
    		uint16_t id = atoi((*it).c_str());
    		player->addAutoLoot(id);
    	}

     

     

    No mesmo arquivo localize :

    
    
    	query.str("");
    	//save vip list
    	if(!g_config.getBool(ConfigManager::VIPLIST_PER_PLAYER))
    		query << "DELETE FROM `account_viplist` WHERE `account_id` = " << player->getAccount() << " AND `world_id` = " << g_config.getNumber(ConfigManager::WORLD_ID);
    	else
    		query << "DELETE FROM `player_viplist` WHERE `player_id` = " << player->getGUID();
    
    	if(!db->query(query.str()))
    		return false;

    e acima adicione: 

    
    
    //save autoloot
    	query.str("");
    	query << "DELETE FROM `player_autoloot` WHERE `player_id` = " << player->getGUID();
    	if(!db->query(query.str()))
    		return false;
    
    	PropWriteStream PWS_AutoLoot;
    	std::list<uint16_t> autoLootList = player->getAutoLoot();
        for (std::list<uint16_t>::iterator it = autoLootList.begin(); it != autoLootList.end(); ++it) {
    		PWS_AutoLoot.addShort(*it);
        }
    
    	uint32_t PWS_Size = 0;
    	const char* autoLoot = PWS_AutoLoot.getStream(PWS_Size);
    
    	query.str("");
    	stmt.setQuery("INSERT INTO `player_autoloot` (`player_id`, `autoloot_list`) VALUES ");
        query << player->getGUID() << ',' << db->escapeBlob(autoLoot, PWS_Size);
        if (!stmt.addRow(query)) {
            return false;
        }
        if (!stmt.execute()) {
            return false;
        }

     

    ficando dessa forma:

      Mostrar conteúdo oculto
    
    
    
    
    
    
    
    //save autoloot
    	query.str("");
    	query << "DELETE FROM `player_autoloot` WHERE `player_id` = " << player->getGUID();
    	if(!db->query(query.str()))
    		return false;
    
    	PropWriteStream PWS_AutoLoot;
    	std::list<uint16_t> autoLootList = player->getAutoLoot();
        for (std::list<uint16_t>::iterator it = autoLootList.begin(); it != autoLootList.end(); ++it) {
    		PWS_AutoLoot.addShort(*it);
        }
    
    	uint32_t PWS_Size = 0;
    	const char* autoLoot = PWS_AutoLoot.getStream(PWS_Size);
    
    	query.str("");
    	stmt.setQuery("INSERT INTO `player_autoloot` (`player_id`, `autoloot_list`) VALUES ");
        query << player->getGUID() << ',' << db->escapeBlob(autoLoot, PWS_Size);
        if (!stmt.addRow(query)) {
            return false;
        }
        if (!stmt.execute()) {
            return false;
        }
          
        query.str("");
    	//save vip list
    	if(!g_config.getBool(ConfigManager::VIPLIST_PER_PLAYER))
    		query << "DELETE FROM `account_viplist` WHERE `account_id` = " << player->getAccount() << " AND `world_id` = " << g_config.getNumber(ConfigManager::WORLD_ID);
    	else
    		query << "DELETE FROM `player_viplist` WHERE `player_id` = " << player->getGUID();
    
    	if(!db->query(query.str()))
    		return false;

     

     

    Agora no arquivo "monsters.cpp" localize toda a função "dropLoot" :  (ATENÇÃO: não confunda com "monster.cpp")

    
    
    void MonsterType::dropLoot(Container* corpse)
    {
    	ItemList items;
    	for(LootItems::const_iterator it = lootItems.begin(); it != lootItems.end() && !corpse->full(); ++it)
    	{
    		items = createLoot(*it);
    		if(items.empty())
    			continue;
    
    		for(ItemList::iterator iit = items.begin(); iit != items.end(); ++iit)
    		{
    			Item* tmpItem = *iit;
    			if(Container* container = tmpItem->getContainer())
    			{
    				if(createChildLoot(container, *it))
    					corpse->__internalAddThing(tmpItem);
    				else
    					delete container;
    			}
    			else
    				corpse->__internalAddThing(tmpItem);
    		}
    	}
    
    	corpse->__startDecaying();
    	uint32_t ownerId = corpse->getCorpseOwner();
    	if(!ownerId)
    		return;
    
    	Player* owner = g_game.getPlayerByGuid(ownerId);
    	if(!owner)
    		return;
    
    	LootMessage_t message = lootMessage;
    	if(message == LOOTMSG_IGNORE)
    		message = (LootMessage_t)g_config.getNumber(ConfigManager::LOOT_MESSAGE);
    
    	if(message < LOOTMSG_PLAYER)
    		return;
    
    	std::stringstream ss;
    	ss << "Loot of " << nameDescription << ": " << corpse->getContentDescription() << ".";
    	if(owner->getParty() && message > LOOTMSG_PLAYER)
    		owner->getParty()->broadcastMessage((MessageClasses)g_config.getNumber(ConfigManager::LOOT_MESSAGE_TYPE), ss.str());
    	else if(message == LOOTMSG_PLAYER || message == LOOTMSG_BOTH)
    		owner->sendTextMessage((MessageClasses)g_config.getNumber(ConfigManager::LOOT_MESSAGE_TYPE), ss.str());
    }

     

    e substitua com atenção ela toda por essa:

    
    
    void MonsterType::dropLoot(Container* corpse)
    {	
    	uint32_t money = 0;
    	ItemList items;
    	std::stringstream str;
    	for(LootItems::const_iterator it = lootItems.begin(); it != lootItems.end() && !corpse->full(); ++it)
    	{
    		items = createLoot(*it);
    		if(items.empty())
    			continue;
    
    		for(ItemList::iterator iit = items.begin(); iit != items.end(); ++iit)
    		{
    			Item* tmpItem = *iit;
    			if(Container* container = tmpItem->getContainer())
    			{
    				Player* tmpPlayer = g_game.getPlayerByGuid(corpse->getCorpseOwner());
    				if(createChildLoot(container, (*it), money, str, tmpPlayer)) {
    					corpse->__internalAddThing(tmpItem);
    				} else {
    					delete container;
    				}
    			}
    			else {
    				bool LootCatch = false;
    				Player* tmpPlayer = g_game.getPlayerByGuid(corpse->getCorpseOwner());
    				if(tmpPlayer) {
    					if(tmpPlayer->statusAutoLoot() == "On") {
    						LootCatch = tmpPlayer->checkAutoLoot(tmpItem->getID());
    						if(LootCatch) {
    							if(tmpPlayer->isMoneyAutoLoot(tmpItem, money)) {
    								continue;
    							}
    							g_game.internalPlayerAddItem(NULL, tmpPlayer, tmpItem);
    							str << " " << tmpItem->getNameDescription() << ",";
    							continue;
    						}
    					}
    				}
    				corpse->__internalAddThing(tmpItem);
    			}
    		}
    	}
    
    	corpse->__startDecaying();
    	uint32_t ownerId = corpse->getCorpseOwner();
    	if(!ownerId)
    		return;
    
    	Player* owner = g_game.getPlayerByGuid(ownerId);
    	if(!owner)
    		return;
    
    	if(money != 0) {
    		if(owner->statusAutoMoneyCollect() == "Bank"){
    			owner->balance += money;
    		} else {
    			g_game.addMoney(owner, money);
    		}
    		str << " " << money << "x gold coins.";
    	} else {
    		str << " nothing gold coins.";
    	}
    
    	LootMessage_t message = lootMessage;
    	if(message == LOOTMSG_IGNORE)
    		message = (LootMessage_t)g_config.getNumber(ConfigManager::LOOT_MESSAGE);
    
    	if(message < LOOTMSG_PLAYER)
    		return;
    
    	std::stringstream ss;
    	ss << "Loot of " << nameDescription << ": " << corpse->getContentDescription() << ".";
    	if(owner->statusAutoLoot()  == "On") {
    		ss << "\nAutoLoot Colleted:" << str.str();
    	}
    	if(owner->getParty() && message > LOOTMSG_PLAYER)
    		owner->getParty()->broadcastMessage((MessageClasses)g_config.getNumber(ConfigManager::LOOT_MESSAGE_TYPE), ss.str());
    	else if(message == LOOTMSG_PLAYER || message == LOOTMSG_BOTH)
    		owner->sendTextMessage((MessageClasses)g_config.getNumber(ConfigManager::LOOT_MESSAGE_TYPE), ss.str());
    }

     

    No mesmo arquivo localize a função a baixo chamada "createChildLoot": 

    
    
    bool MonsterType::createChildLoot(Container* parent, const LootBlock& lootBlock)
    {
    	LootItems::const_iterator it = lootBlock.childLoot.begin();
    	if(it == lootBlock.childLoot.end())
    		return true;
    
    	ItemList items;
    	for(; it != lootBlock.childLoot.end() && !parent->full(); ++it)
    	{
    		items = createLoot(*it);
    		if(items.empty())
    			continue;
    
    		for(ItemList::iterator iit = items.begin(); iit != items.end(); ++iit)
    		{
    			Item* tmpItem = *iit;
    			if(Container* container = tmpItem->getContainer())
    			{
    				if(createChildLoot(container, *it))
    					parent->__internalAddThing(tmpItem);
    				else
    					delete container;
    			}
    			else
    				parent->__internalAddThing(tmpItem);
    		}
    	}
    
    	return !parent->empty();
    }

    E substitua por essa:

    
    
    bool MonsterType::createChildLoot(Container* parent, const LootBlock& lootBlock, uint32_t& money, std::stringstream& str, Player* player)
    {
    	LootItems::const_iterator it = lootBlock.childLoot.begin();
    	if(it == lootBlock.childLoot.end())
    		return true;
    
    	ItemList items;
    	for(; it != lootBlock.childLoot.end() && !parent->full(); ++it)
    	{
    		items = createLoot(*it);
    		if(items.empty())
    			continue;
    
    		for(ItemList::iterator iit = items.begin(); iit != items.end(); ++iit)
    		{
    			Item* tmpItem = *iit;
    			if(Container* container = tmpItem->getContainer())
    			{
    				if(createChildLoot(container, *it, money, str, player))
    					parent->__internalAddThing(tmpItem);
    				else
    					delete container;
    			}
    			else {
    				bool LootCatch = false;
    				if(player && (player->statusAutoLoot() == "On")) {
    					LootCatch = player->checkAutoLoot(tmpItem->getID());
    				}
    				if(LootCatch) {
    					if(player->isMoneyAutoLoot(tmpItem, money)) {
    						continue;
    					}
    					g_game.internalPlayerAddItem(NULL, player, tmpItem);
    					str << " " << tmpItem->getNameDescription() << ",";
    					continue;
    				}
    					parent->__internalAddThing(tmpItem);
    			}
    		}
    	}
    
    	return !parent->empty();
    }

     

    Agora no arquivo "monsters.h" altera apenas uma linha:

    Encontre:

    
    
    bool createChildLoot(Container* parent, const LootBlock& lootBlock);

    e troque por:

    
    
    bool createChildLoot(Container* parent, const LootBlock& lootBlock, uint32_t& money, std::stringstream& str, Player* player);

     

    Agora no arquivo "player.h" encontre nas funções public:

    
    
    		void learnInstantSpell(const std::string& name);
    		void unlearnInstantSpell(const std::string& name);
    		bool hasLearnedInstantSpell(const std::string& name) const;

    E adicione abaixo

    
    
    		//Autoloot by: Naze
    		std::list<uint16_t> getAutoLoot() {
    			return AutoLoot;
    		}
    		void clearAutoLoot() {
    			AutoLoot.clear();
    		}
    		void addAutoLoot(uint16_t id);
    		void removeAutoLoot(uint16_t id);
    		bool limitAutoLoot();
    		bool checkAutoLoot(uint16_t id);
    		bool isMoneyAutoLoot(Item* item, uint32_t& count);
    		std::string statusAutoLoot() {
    			return (autoLootStatus ? "On" : "Off");
    		}
    		void updateStatusAutoLoot(bool status){
    			autoLootStatus = status;
    		}
    		std::string statusAutoMoneyCollect() {
    			return (autoMoneyCollect ? "Bank" : "Bag");
    		}
    		void updateMoneyCollect(bool status) {
    			autoMoneyCollect = status;
    		}

     

     

    Localize no mesmo arquivo as declarações private: 

    
    
    	private:
    		bool is_spectating;
    		bool talkState[13];
    		bool inventoryAbilities[SLOT_LAST];
    		bool pzLocked;

    e adicione 3 variáveis:

    
    
    	private:
    		bool autoLootStatus; //autoloot by naze
    		bool autoMoneyCollect; //autoloot by naze
    		std::list<uint16_t> AutoLoot; //autoloot by naze
    		bool is_spectating;
    		bool talkState[13];
    		bool inventoryAbilities[SLOT_LAST];
    		bool pzLocked;

     

    Agora no arquivo "player.cpp" localize no começo a função:

    
    
    Player::Player(const std::string& _name, ProtocolGame* p):
    	Creature(), transferContainer(ITEM_LOCKER), name(_name), nameDescription(_name), client(p)
    {
    	if(client)
    		client->setPlayer(this);
    
    	pzLocked = isConnecting = addAttackSkillPoint = requestedOutfit = false;
    	saving = true;
    
    	lastAttackBlockType = BLOCK_NONE;

     

    e adicione: 

    
    
    Player::Player(const std::string& _name, ProtocolGame* p):
    	Creature(), transferContainer(ITEM_LOCKER), name(_name), nameDescription(_name), client(p)
    {
    	if(client)
    		client->setPlayer(this);
    
    	pzLocked = isConnecting = addAttackSkillPoint = requestedOutfit = false;
    	saving = true;
    	autoLootStatus = true; //autoloot by naze
    	autoMoneyCollect = true; //autoloot by naze
    
    	lastAttackBlockType = BLOCK_NONE;

     

    Ainda em "player.cpp" vá até as ultimas função: 

    
    
    void Player::sendCritical() const
    {
    	if(g_config.getBool(ConfigManager::DISPLAY_CRITICAL_HIT))
    		g_game.addAnimatedText(getPosition(), COLOR_DARKRED, "CRITICAL!");
    }
    
    void Player::setPlayerExtraAttackSpeed(uint32_t speed)
    {
    	extraAttackSpeed = speed;
    }

     

    e adicione abaixo: 

    
    
    void Player::addAutoLoot(uint16_t id) {
    	if(checkAutoLoot(id)) {
    		return;
    	}
    	AutoLoot.push_back(id);
    }
    
    void Player::removeAutoLoot(uint16_t id) {
    	if(checkAutoLoot(id)) {
    		return;
    	}
    	AutoLoot.remove(id);
    }
    
    bool Player::limitAutoLoot() {
    	std::list<uint16_t> list = getAutoLoot();
    	if((uint16_t)list.size() >= g_config.getNumber(ConfigManager::AUTOLOOT_MAXITEM)) {
    		return true;
    	}
    	return false;
    }
    
    bool Player::checkAutoLoot(uint16_t id) {
    	if(Item::items[id].isContainer()) {
    		return true;
    	}
    	std::string msg = g_config.getString(ConfigManager::AUTOLOOT_BLOCKIDS);
    	StringVec strVector = explodeString(msg, ";");
    	for(StringVec::iterator it = strVector.begin(); it != strVector.end(); ++it) {
    		if(atoi((*it).c_str()) == id) {
    			return true;
    		}
    	}
    	for(std::list<uint16_t>::iterator it = AutoLoot.begin(); it != AutoLoot.end(); ++it) {
    		if((*it) == id) {
    			return true;
    		}
    	}
    	return false;
    }
    
    bool Player::isMoneyAutoLoot(Item* item, uint32_t& count) {
    	bool isMoney = false;
    	std::string msg = g_config.getString(ConfigManager::AUTOLOOT_MONEYIDS);
    	StringVec strVector = explodeString(msg, ";");
    	for(StringVec::iterator it = strVector.begin(); it != strVector.end(); ++it) {
    		if(item->getID() == atoi((*it).c_str())) {
    			isMoney = true;
    			break;
    		}
    	}
    	if(!isMoney) {
    		return false;
        }
      
    	count += item->getWorth();
    	return true;
    }

     

    Ficando dessa forma:

      Mostrar conteúdo oculto
    
    
    
    
    
    
    
    
    
    
    
    void Player::sendCritical() const
    {
    	if(g_config.getBool(ConfigManager::DISPLAY_CRITICAL_HIT))
    		g_game.addAnimatedText(getPosition(), COLOR_DARKRED, "CRITICAL!");
    }
    
    void Player::setPlayerExtraAttackSpeed(uint32_t speed)
    {
    	extraAttackSpeed = speed;
    }
    
    void Player::addAutoLoot(uint16_t id) {
    	if(checkAutoLoot(id)) {
    		return;
    	}
    	AutoLoot.push_back(id);
    }
    
    void Player::removeAutoLoot(uint16_t id) {
    	if(checkAutoLoot(id)) {
    		return;
    	}
    	AutoLoot.remove(id);
    }
    
    bool Player::limitAutoLoot() {
    	std::list<uint16_t> list = getAutoLoot();
    	if((uint16_t)list.size() >= g_config.getNumber(ConfigManager::AUTOLOOT_MAXITEM)) {
    		return true;
    	}
    	return false;
    }
    
    bool Player::checkAutoLoot(uint16_t id) {
    	if(Item::items[id].isContainer()) {
    		return true;
    	}
    	std::string msg = g_config.getString(ConfigManager::AUTOLOOT_BLOCKIDS);
    	StringVec strVector = explodeString(msg, ";");
    	for(StringVec::iterator it = strVector.begin(); it != strVector.end(); ++it) {
    		if(atoi((*it).c_str()) == id) {
    			return true;
    		}
    	}
    	for(std::list<uint16_t>::iterator it = AutoLoot.begin(); it != AutoLoot.end(); ++it) {
    		if((*it) == id) {
    			return true;
    		}
    	}
    	return false;
    }
    
    bool Player::isMoneyAutoLoot(Item* item, uint32_t& count) {
    	bool isMoney = false;
    	std::string msg = g_config.getString(ConfigManager::AUTOLOOT_MONEYIDS);
    	StringVec strVector = explodeString(msg, ";");
    	for(StringVec::iterator it = strVector.begin(); it != strVector.end(); ++it) {
    		if(item->getID() == atoi((*it).c_str())) {
    			isMoney = true;
    			break;
    		}
    	}
    	if(!isMoney)
    		return false;
    	
    	count += item->getWorth();
    	return true;
    }

     

     

    Agora quase finalizando no arquivo "talkactions.h" localize:

    
    
    		static TalkFunction diagnostics;
    		static TalkFunction addSkill;
    		static TalkFunction ghost;
    		static TalkFunction software;

     

    E adicione:

    
    
    
    		static TalkFunction diagnostics;
    		static TalkFunction addSkill;
    		static TalkFunction autoLoot; //autoloot by naze
    		static TalkFunction ghost;
    		static TalkFunction software;

     

    Encontre no arquivo "talkactions.cpp" :

    
    
    	else if(m_functionName == "diagnostics")
    		m_function = diagnostics;
    	else if(m_functionName == "addskill")
    		m_function = addSkill;
    	else if(m_functionName == "ghost")
    		m_function = ghost;
    	else if(m_functionName == "software")
    		m_function = software;

     

    E adicione o seguinte: 

    
    
    	else if(m_functionName == "diagnostics")
    		m_function = diagnostics;
    	else if(m_functionName == "addskill")
    		m_function = addSkill;	
    	else if(m_functionName == "autoloot") //autoloot by naze
    		m_function = autoLoot;	
    	else if(m_functionName == "ghost")
    		m_function = ghost;
    	else if(m_functionName == "software")
    		m_function = software;

     

    Ainda em "talkactions.cpp" encontre o começo de ghost:

    
    
    bool TalkAction::ghost(Creature* creature, const std::string&, const std::string&)
    {
    	Player* player = creature->getPlayer();
    	if(!player)
    		return false;

     E adicione a cima a seguinte função:

    
    
    bool TalkAction::autoLoot(Creature* creature, const std::string&, const std::string& param)
    {
    	Player* player = creature->getPlayer();
    	if(!player)
    		return false;
    
    	StringVec params = explodeString(param, ",");
    	std::stringstream info;
    	if(params[0] == "on" or params[0] == "off") {
    		player->updateStatusAutoLoot((params[0] == "on" ? true : false));
    		info << "Autoloot-> Status: " << (player->statusAutoLoot()) << ".";
    		player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, info.str());
    		return true;
    	}
    	if(params[0] == "clear" or params[0] == "clean") {
    		player->clearAutoLoot();
    		info << "Autoloot-> Todos itens removidos.";
    		player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, info.str());
    		return true;
    	}
    	if(params[0] == "list" or params[0] == "lista") {
    		std::list<uint16_t> list = player->getAutoLoot();
    		std::list<uint16_t>::iterator it = list.begin();
    		std::string msg = g_config.getString(ConfigManager::AUTOLOOT_MONEYIDS);
    		StringVec strVector = explodeString(msg, ";");
    		for(StringVec::iterator itt = strVector.begin(); itt != strVector.end(); ++itt) {
    			++it;
    		}
    		uint16_t i = 1;
    		for(; it != list.end(); ++it) {	
    			info << i << ": " << Item::items[(*it)].name << std::endl;
    			++i;
    		}
    		player->sendFYIBox((info.str() == "" ? "Nada Adicionado." : info.str()));
    		return true;
    	}
    	if(params.size() <= 1) {
    		info << "_____Perfect AutoLoot System_____\nAutoLoot Status: " << player->statusAutoLoot() << "\nAutoMoney Mode: " << player->statusAutoMoneyCollect() << "\n\nComandos:\n!autoloot on/off\n!autoloot money, bank/bag\n!autoloot add, item name, item name, item name...\n!autoloot remove, item name, item name, item name...\n!autoloot list\n!autoloot clear\n\n\n (Sistema livre de bugs e gratuito no TibiaKing!)";
    		player->sendFYIBox(info.str());
    		return true;
    	}
    
    	if(params[0] == "money") {
    		for(StringVec::iterator it = params.begin(); it != params.end(); ++it) {
    			if((*it) == "money") {
    				continue;
    			}
    			char param[150];
    			sprintf(param, "%s", (*it).c_str());
    			int len = strlen(param);
    			for (int i = 0, pos = 0; i < len; i++, pos++) {
    				if (param[0] == ' '){
    					pos++;
    				}
    				param[i] = param[pos];
    			}
    			if((strcmp(param, "bank") == 0) or (strcmp(param, "bag") == 0)) {
    				player->updateMoneyCollect((strcmp(param, "bank") == 0) ? true : false);
    				info << "AutoMoney-> Collect Mode: " << (player->statusAutoMoneyCollect()) << ".";
    				player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, info.str());
    				return true;
    			}
    		}
    	}
    
    	if(params[0] == "add") {
    		std::stringstream add, err;
    		uint8_t addCount = 0, errCount = 0;
    		std::stringstream ss;
    		for(StringVec::iterator it = params.begin(); it != params.end(); ++it) {
    			if((*it) == "add") {
    				continue;
    			}
    			char name[150];
    			sprintf(name, "%s", (*it).c_str());
    			int len = strlen(name);
    			for (int i = 0, pos = 0; i < len; i++, pos++) {
    				if (name[0] == ' '){
    					pos++;
    				}
    				name[i] = name[pos];
    			}
    			int32_t itemId = Item::items.getItemIdByName(name);
    			if(!player->checkAutoLoot(itemId)) {
    				if(itemId > 0) {
    					std::string str = addCount > 0 ? ", " : "";
    					++addCount;
    					add << str << name;
    					player->addAutoLoot(itemId);
    					continue;
    				}
    			}
    			std::string str = errCount > 0 ? ", " : "";
    			++errCount;
    			err << str << name;
    		}
    		ss << "AutoLoot-> Adicionados: " << ((add.str() == "") ? "Nenhum" : add.str()) << ". Erros: " << ((err.str() == "") ? "Nenhum" : err.str()) << ".";
    		player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, ss.str());
    		return true;
    	}
    
    	if(params[0] == "remove") {
    		std::stringstream remove, err;
    		uint8_t removeCount = 0, errCount = 0;
    		std::stringstream ss;
    		for(StringVec::iterator it = params.begin(); it != params.end(); ++it) {
    			if((*it) == "remove") {
    				continue;
    			}
    			char name[150];
    			sprintf(name, "%s", (*it).c_str());
    			int len = strlen(name);
    			for (int i = 0, pos = 0; i < len; i++, pos++) {
    				if (name[0] == ' '){
    					pos++;
    				}
    				name[i] = name[pos];
    			}
    			int32_t itemId = Item::items.getItemIdByName(name);
    			if(player->checkAutoLoot(itemId)) {
    				if(itemId > 0) {
    					std::string str = removeCount > 0 ? ", " : "";
    					++removeCount;
    					remove << str << name;
    					player->removeAutoLoot(itemId);
    					continue;
    				}
    			}
    			std::string str = errCount > 0 ? ", " : "";
    			++errCount;
    			err << str << name;
    		}
    		ss << "AutoLoot-> Removidos: " << ((remove.str() == "") ? "Nenhum" : remove.str()) << ". Erros: " << ((err.str() == "") ? "Nenhum" : err.str()) << ".";
    		player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, ss.str());
    		return true;
    	}
    	
    	return true;
    }

     

     

    Com isso toda parte na source está instalada, agora vá até seu config.lua e adicione onde achar melhor as seguintes linhas:

    
    
    AutoLoot_BlockIDs = "" -- adicione ids separado por ; ex: "1111;2222;3333"
    AutoLoot_MoneyIDs = "2148;2152;2160" -- adicione os ids dos itens moeda, caso seja os 3 normais pode retirar essa linha
    AutoLoot_MaxItem = 100 --  quantidade de itens maximo na lista

     

    Agora para finalizar abra o data/talkactions/talkactions.xml e adicione a seguinte tag:

    
    
    	<talkaction words="/autoloot;!autoloot" event="function" value="autoloot"/>

     

    E execute a seguinte query em seu banco de dados:

    
    
    CREATE TABLE player_autoloot (
        id int NOT NULL AUTO_INCREMENT,
        player_id int NOT NULL,
        autoloot_list blob,
        PRIMARY KEY (id)
    );


     

     

    Link para TFS -> https://tibiaking.com/forums/topic/101079-otimizado-autoloot-in-sources-for-tfs-036-tfs-04/

     

    Caso ocorra algum erro na compilação so mandar que ajudo a resolver, testei apenas em uma otx que tenho então nao sei se pode sugir outros problemas. Nas versões atual da Otx para servidores 10+ não ira funcionar pois algumas funções são diferente e não irei corrigir agora, em breve passo o mesmo pra tfs 1.3 e otx3.

     

    Esse sistema foi totalmente feito por mim, mas dou créditos também ao @Mathias Kenfi por me ajudar muito na evolução em lua/c++ e a tabela sql é a mesma usada no quick autoloot 1.3 postado por Pedriinz

    Depois que compilei a source, ao ligar o servidor a distro fecha e aparece seguimentation fail algo assim, será que fiz algo errado?

  2. 6 horas atrás, WooX disse:

    Não testado.

    
    --<event type="cast" name="blockSpell" event="script" value="block_spell.lua"/>
    
    function onCast(cid)
    	if isPlayer(cid) and getPlayerStorageValue(cid, 4570) > os.time() then
    		local delay = getPlayerStorageValue(cid, 4570) - os.time()
    		addEvent(function()
    			if isPlayer(cid) then
    				unregisterCreatureEvent(cid, "blockSpell")
    			end
    		end, delay * 1000)
    		return false
    	end
    	return true
    end
    
    --[[
    	<instant name="Block Spell" words="petrificus totalus" lvl="50" mana="200" range="3" blockwalls="1" needtarget="1" exhaustion="2000" needlearn="0" event="script" value="block_spell.lua">
    		<vocation id="1"/>
    		<vocation id="2"/>
    	</instant>
    ]]
    
    local config = {
    	blockTime = 5, -- Segundos
    	affectPlayersOnly = true
    }
    
    local combat = createCombatObject()
    setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE)
    setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_FIREATTACK)
    setCombatParam(combat, COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_FIRE)
    
    function onCastSpell(cid, var)
    	local target = isPlayer(var.number) and var.number or getCreatureTarget(cid)
    	if config.playersOnly and not isPlayer(target) then
    		doPlayerSendCancel(cid, "Somente jogadores sao afetados por essa spell.")
    		return true
    	end
    	setPlayerStorageValue(target, 4570, os.time() + config.blockTime)
    	registerCreatureEvent(target, "blockSpell")
    	return doCombat(cid, combat, var)
    end

     

    Fiz o teste aqui, nenhum erro na distro, mas nao esta bloqueando as magias, o target consegue usar spells normalmente apos ser afetado pelo blockspell (Utilizo otx 2 8.60)

  3. 1 hora atrás, WooX disse:

    A spell está configurada pra não afetar aliados (jogadores na mesma party ou da mesma guild), e também ira apenas remover o target, para realizar o bloqueio do target ainda é necessário utilizar em conjunto a spell o creaturescript postado pelo @Lurk, eu testei a spell novamente e está funcional.

     

      Ocultar conteúdo
    
    
    --[[
    	<instant name="Paralyze Target" words="gtfo" lvl="55" mana="650" selftarget="1" prem="0" exhaustion="1800" needlearn="0" event="script" value="support/paralyze_target.lua">
    		<vocation id="1"/>
    		<vocation id="5"/>
    	</instant>
    ]]
    
    local config = {
    	paralyzeTime = 5, -- Segundos
    	affectAllies = false,
    	affectTargetCasterOnly = false -- Se marcado como true ira paralyzar somente quem estiver atacando o usuario da spell
    }
    
    local combat = createCombatObject()
    setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
    setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_BIGCLOUDS)
    setAttackFormula(combat, COMBAT_FORMULA_LEVELMAGIC, 8, 5, 7, 11)
    
    function onTargetCreature(cid, target)
    	if config.affectTargetCasterOnly and getCreatureTarget(target) ~= cid then
    		return false
    	end
    	if not config.affectAllies then
    		local partyMembers = getPartyMembers(cid)
    		if getPlayerGuildId(cid) == getPlayerGuildId(target) or isInArray(partyMembers, target) then
    			return false
    		end
    	end
    	doCreatureSetNoMove(target, true)
    	addEvent(function()
    		if isPlayer(target)
    			doCreatureSetNoMove(target, false)
    		end
    	end, config.paralyzeTime * 1000)
    	return true
    end
    
    setCombatCallback(combat, CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature")
    
    local area = createCombatArea(AREA_CROSS6X6)
    setCombatArea(combat, area)
    
    function onCastSpell(cid, var)
    	return doCombat(cid, combat, var)
    end

     

     

    Testei aqui nao funcionou, a minha distro é cheia de erros, não consigo ver se deu algum erro..

  4. 17 horas atrás, WooX disse:
    1. Certifique-se de que possui a função instalada na source.
    2. Ao realizar o teste, deixe uma arma no char que deve perder o target para ter certeza de que o ataque foi interrompido.
    3. Dependendo do client que estiver utilizando a marca do target não vai ser removida, essa parte é client-side.

    lqJ8oC1.gif

    Bom dia, consegue adaptar para ao invés de cancelar o target, dar um nomove de 5 segundos e depois remover o nomove ao acabar?

  5. 1 hora atrás, WooX disse:

    Não é necessário, da pra fazer utilizando o callback onTargetCreature.

     

     

    Fiz com base na spell "exevo gran mas vis" do Tibia, os parâmetros da spell podem ser alterados.

    
    --[[
    	<instant name="Remove Target" words="gtfo" lvl="55" mana="650" selftarget="1" prem="0" exhaustion="1800" needlearn="0" event="script" value="support/remove_target.lua">
    		<vocation id="1"/>
    		<vocation id="5"/>
    	</instant>
    ]]
    
    local config = {
    	blockTarget = true,
    	blockTime = 5, -- Segundos
    	affectAllies = false,
    	affectTargetCasterOnly = false -- Se marcado como true ira remover o target somente de quem estiver atacando o usuario da spell
    }
    
    local combat = createCombatObject()
    setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
    setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_BIGCLOUDS)
    setAttackFormula(combat, COMBAT_FORMULA_LEVELMAGIC, 8, 5, 7, 11)
    
    function onTargetCreature(cid, target)
    	if config.affectTargetCasterOnly and getCreatureTarget(target) ~= cid then
    		return false
    	end
    	if not config.affectAllies then
    		local partyMembers = getPartyMembers(cid)
    		if getPlayerGuildId(cid) == getPlayerGuildId(target) or isInArray(partyMembers, target) then
    			return false
    		end
    	end
    	if config.blockTarget then
    		setPlayerStorageValue(target, 234512, os.time() + config.blockTime)
    	end
    	--errors(false)
    	doPlayerTargetCreature(target, target)
    	--errors(true)
    	return true
    end
    
    setCombatCallback(combat, CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature")
    
    local area = createCombatArea(AREA_CROSS6X6)
    setCombatArea(combat, area)
    
    function onCastSpell(cid, var)
    	return doCombat(cid, combat, var)
    end

     

    Testei aqui ele nao esta cancelando o target dos inimigos..

  6. Bom estou aderindo a moda de utilizar o otclient, já consegui estender e configurar tudo ok, mas estou com um problema, as paredes que possuem algo pendurado não aparecem no otclient, alguém tem alguma ideia de como resolver? Isto só ocorre em paredes que tenha algo pendurado, um quadro, lampada, papel de parede e etc..


    Old Client (Paredes Normal):

    image.thumb.png.8abb7e457240e1e2ef29e4c7c814134b.png

     

    Otclient (Paredes somem):

    image.thumb.png.a307a936ad73e6fa3af67a18bfc9b3e1.png

     

    OTC Console:
    image.png.884757826f5a85945ff067e5ff39b99c.png

     

    @Bruxo Ots

    @Viny 13

    @WooX

    @LeoTK

    @xWhiteWolf

    @Yan Liima

  7. 8 horas atrás, Cony disse:

    .Estou utilizando o TFS 0.4 REV3996 War & Cast do Yan Lima - Uint8

     

    Estou com um erro de SQLite na Distro de meu servidor. É um projeto de pequeno porte, onde estou utilizando o SQLite Studio para fazer edições na database s3db. Apenas quero uma ajuda dos senhores para possivelmente resolver este erro e deixar a Distro limpinha. OBS: Questão de leitura e diagnostico de erros eu sou bem leigo, portanto não me crucifiquem. Agradeço a compreensão, aguardo respostas.

     

    Erro a seguir:

    
    [2:55:14.669] OTSYS_SQLITE3_PREPARE(): SQLITE ERROR: no such table: guild_wars (SELECT "id", "guild_id", "enemy_id" FROM "guild_wars" WHERE "status" IN (1,4) AND "end" > 0 AND "end" < 1591422914)

    Imagem:

    Screenshot_1.png

    Execute essa query no banco de dados:

    DROP TABLE IF EXISTS guild_wars;
    CREATE TABLE guild_wars ( 
        id          INTEGER       NOT NULL,
        guild_id    INT           NOT NULL,
        enemy_id    INT           NOT NULL,
        begin       BIGINT        NOT NULL
                                  DEFAULT '0',
        end         BIGINT        NOT NULL
                                  DEFAULT '0',
        frags       INT           NOT NULL
                                  DEFAULT '0',
        payment     BIGINT        NOT NULL
                                  DEFAULT '0',
        guild_kills INT           NOT NULL
                                  DEFAULT '0',
        enemy_kills INT           NOT NULL
                                  DEFAULT '0',
        status      TINYINT( 1 )  NOT NULL
                                  DEFAULT '0',
        PRIMARY KEY ( id ),
        FOREIGN KEY ( guild_id ) REFERENCES guilds ( id ),
        FOREIGN KEY ( enemy_id ) REFERENCES guilds ( id ) 
    );
×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo