Ir para conteúdo

Featured Replies

Postado

Isso não é um tutorial mas pode ser entendido como.. são os passos que levaram ao funcionamento do sistema da forma que eu precisava. Funcional em TFS 1.2

 

Bem semanas atrás eu estava procurando alguém que me ajudasse a bloquear recebimento de parcel por personagens sem vocação (por costumo o povo fala char de rook)

 

Tentei em lua remover parcel mas só removia 1 e só se o player pegasse, tentei bloquear e nada.. até o Razor tentou com lua e chegou a conclusão que não dava para fazer por lua

 

Depois de um bom tempo luanluciano93 veio com essa possibilidade (imagino que se era fácil qualquer um poderia ter me ajudado, para mostrar que nem todo mundo curte ajudar)

 

Procura essa função no arquivo player.cpp.
 

adicionando uma verificação aqui

depotLocker->internalAddThing(Item::CreateItem(ITEM_MARKET));

Uma condição que verifique se o player tem vocação, tipo assim: 

 if (vocation->getId() != VOCATION_NONE) {
        depotLocker->internalAddThing(Item::CreateItem(ITEM_MARKET));
    }

No meu caso eu queria bloquear tanto o market quanto inbox (onde recebe parcel, item, carta) e só fiz colocar o inbox dentro do if

 

Parte referente ao meu player.cpp alterado

DepotLocker* Player::getDepotLocker(uint32_t depotId)
{
    auto it = depotLockerMap.find(depotId);
    if (it != depotLockerMap.end()) {
        inbox->setParent(it->second);
        return it->second;
    }

    DepotLocker* depotLocker = new DepotLocker(ITEM_LOCKER1);
    depotLocker->setDepotId(depotId);
    if (vocation->getId() != VOCATION_NONE) {
        depotLocker->internalAddThing(Item::CreateItem(ITEM_MARKET));
        depotLocker->internalAddThing(inbox);
    }
    depotLocker->internalAddThing(getDepotChest(depotId, true));
    depotLockerMap[depotId] = depotLocker;
    return depotLocker;
}

 

Resultando nisso

jLxoG6O.gif

 

separador%2B(1).png

 

Depois disso informei nos forums que participo sobre ja ter resolvido metade do problema quando Razor comentou que tinha uma ideia para bloquear o envio.. tentamos o hack na source mas estava gerando erro e não compilava, logo depois o Ninja veio com uma ajuda que deu erro no começo mas resolvido finalmente.. 

 

A alteração gera uma warning, mas não foi algo que atrapalhou.. o proposto que funcionou foi esse, lembrando que a alteração deve ser feita no mailbox.cpp cru e a adição no mailbox.h

 

é um arquivo diff, não sei como funciona no windows, mas eu fiz a alteração de forma manual. link para o diff e o conteudo do diff abaixo

 

mailbox.diff

diff --git a/mailbox.cpp b/mailbox.cpp
index 0083b81..e807275 100644
--- a/mailbox.cpp
+++ b/mailbox.cpp
@@ -102,8 +102,21 @@ bool Mailbox::sendItem(Item* item) const
 
 	Player* player = g_game.getPlayerByName(receiver);
 	if (player) {
+		if (player->getVocationId() == VOCATION_NONE) {
+			Player* writer = g_game.getPlayerByName(getWriterName(item));
+			if (writer) {
+				if (g_game.internalMoveItem(item->getParent(), writer->getInbox(), INDEX_WHEREEVER,
+		                                            item, item->getItemCount(), nullptr, FLAG_NOLIMIT) == RETURNVALUE_NOERROR) {
+					g_game.transformItem(item, item->getID() + 1);
+					writer->onReceiveMail();
+					return true;
+				}
+			}
+			return false;
+		}
+
 		if (g_game.internalMoveItem(item->getParent(), player->getInbox(), INDEX_WHEREEVER,
		                            item, item->getItemCount(), nullptr, FLAG_NOLIMIT) == RETURNVALUE_NOERROR) {
 			g_game.transformItem(item, item->getID() + 1);
 			player->onReceiveMail();
 			return true;
@@ -121,9 +134,26 @@ bool Mailbox::sendItem(Item* item) const
 			return true;
 		}
 	}
+
 	return false;
 }
 
+std::string Mailbox::getWriterName(Item* item) const
+{
+	std::ostringstream s;
+	const Container* container = item->getContainer();
+	if (container) {
+		for (Item* containerItem : container->getItemList()) {
+			if (containerItem->getID() == ITEM_LABEL) {
+				s << containerItem->getWriter();
+				break;
+			}
+		}
+	}
+
+	return s.str();
+}
+
 bool Mailbox::getReceiver(Item* item, std::string& name) const
 {
 	const Container* container = item->getContainer();
@@ -149,4 +179,4 @@ bool Mailbox::getReceiver(Item* item, std::string& name) const
 bool Mailbox::canSend(const Item* item)
 {
 	return item->getID() == ITEM_PARCEL || item->getID() == ITEM_LETTER;
-}
\ No newline at end of file
+}
diff --git a/mailbox.h b/mailbox.h
index bcda048..3a459d1 100644
--- a/mailbox.h
+++ b/mailbox.h
@@ -57,10 +57,11 @@ class Mailbox final : public Item, public Cylinder
 		void postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, cylinderlink_t link = LINK_OWNER) final;
 
 	private:
+		std::string getWriterName(Item* item) const;
 		bool getReceiver(Item* item, std::string& name) const;
 		bool sendItem(Item* item) const;
 
 		static bool canSend(const Item* item);
 };
 
-#endif
\ No newline at end of file
+#endif 

 

Meu mailbox.cpp alterado

/**
 * The Forgotten Server - a free and open-source MMORPG server emulator
 * Copyright (C) 2015  Mark Samman <[email protected]>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "otpch.h"

#include "mailbox.h"
#include "game.h"
#include "player.h"
#include "iologindata.h"
#include "town.h"

extern Game g_game;

ReturnValue Mailbox::queryAdd(int32_t, const Thing& thing, uint32_t, uint32_t, Creature*) const
{
	const Item* item = thing.getItem();
	if (item && Mailbox::canSend(item)) {
		return RETURNVALUE_NOERROR;
	}
	return RETURNVALUE_NOTPOSSIBLE;
}

ReturnValue Mailbox::queryMaxCount(int32_t, const Thing&, uint32_t count, uint32_t& maxQueryCount, uint32_t) const
{
	maxQueryCount = std::max<uint32_t>(1, count);
	return RETURNVALUE_NOERROR;
}

ReturnValue Mailbox::queryRemove(const Thing&, uint32_t, uint32_t) const
{
	return RETURNVALUE_NOTPOSSIBLE;
}

Cylinder* Mailbox::queryDestination(int32_t&, const Thing&, Item**, uint32_t&)
{
	return this;
}

void Mailbox::addThing(Thing* thing)
{
	return addThing(0, thing);
}

void Mailbox::addThing(int32_t, Thing* thing)
{
	Item* item = thing->getItem();
	if (item && Mailbox::canSend(item)) {
		sendItem(item);
	}
}

void Mailbox::updateThing(Thing*, uint16_t, uint32_t)
{
	//
}

void Mailbox::replaceThing(uint32_t, Thing*)
{
	//
}

void Mailbox::removeThing(Thing*, uint32_t)
{
	//
}

void Mailbox::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, cylinderlink_t)
{
	getParent()->postAddNotification(thing, oldParent, index, LINK_PARENT);
}

void Mailbox::postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, cylinderlink_t)
{
	getParent()->postRemoveNotification(thing, newParent, index, LINK_PARENT);
}

bool Mailbox::sendItem(Item* item) const
{
	std::string receiver;
	if (!getReceiver(item, receiver)) {
		return false;
	}

	/**No need to continue if its still empty**/
	if (receiver.empty()) {
		return false;
	}

	Player* player = g_game.getPlayerByName(receiver);
	if (player) {
		if (player->getVocationId() == VOCATION_NONE) {
			Player* writer = g_game.getPlayerByName(getWriterName(item));
			if (writer) {
				if (g_game.internalMoveItem(item->getParent(), writer->getInbox(), INDEX_WHEREEVER,
					item, item->getItemCount(), nullptr, FLAG_NOLIMIT) == RETURNVALUE_NOERROR) {
					g_game.transformItem(item, item->getID() + 1);
					writer->onReceiveMail();
					return true;
				}
			}
			return false;
		}
		if (g_game.internalMoveItem(item->getParent(), player->getInbox(), INDEX_WHEREEVER,
			item, item->getItemCount(), nullptr, FLAG_NOLIMIT) == RETURNVALUE_NOERROR) {
			g_game.transformItem(item, item->getID() + 1);
			player->onReceiveMail();
			return true;
		}
	}
}

std::string Mailbox::getWriterName(Item* item) const
{
	std::ostringstream s;
	const Container* container = item->getContainer();
	if (container) {
		for (Item* containerItem : container->getItemList()) {
			if (containerItem->getID() == ITEM_LABEL) {
				s << containerItem->getWriter();
				break;
			}
		}
	}

	return s.str();
}

bool Mailbox::getReceiver(Item* item, std::string& name) const
{
	const Container* container = item->getContainer();
	if (container) {
		for (Item* containerItem : container->getItemList()) {
			if (containerItem->getID() == ITEM_LABEL && getReceiver(containerItem, name)) {
				return true;
			}
		}
		return false;
	}

	const std::string& text = item->getText();
	if (text.empty()) {
		return false;
	}

	name = getFirstLine(text);
	trimString(name);
	return true;
}

bool Mailbox::canSend(const Item* item)
{
	return item->getID() == ITEM_PARCEL || item->getID() == ITEM_LETTER;
}
 

 

Meu mailbox.h com a adição

/**
 * The Forgotten Server - a free and open-source MMORPG server emulator
 * Copyright (C) 2015  Mark Samman <[email protected]>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef FS_MAILBOX_H_D231C6BE8D384CAAA3AE410C1323F9DB
#define FS_MAILBOX_H_D231C6BE8D384CAAA3AE410C1323F9DB

#include "item.h"
#include "cylinder.h"
#include "const.h"

class Mailbox final : public Item, public Cylinder
{
	public:
		explicit Mailbox(uint16_t itemId) : Item(itemId) {}

		Mailbox* getMailbox() final {
			return this;
		}
		const Mailbox* getMailbox() const final {
			return this;
		}

		//cylinder implementations
		ReturnValue queryAdd(int32_t index, const Thing& thing, uint32_t count,
				uint32_t flags, Creature* actor = nullptr) const final;
		ReturnValue queryMaxCount(int32_t index, const Thing& thing, uint32_t count,
				uint32_t& maxQueryCount, uint32_t flags) const final;
		ReturnValue queryRemove(const Thing& thing, uint32_t count, uint32_t flags) const final;
		Cylinder* queryDestination(int32_t& index, const Thing& thing, Item** destItem,
				uint32_t& flags) final;

		void addThing(Thing* thing) final;
		void addThing(int32_t index, Thing* thing) final;

		void updateThing(Thing* thing, uint16_t itemId, uint32_t count) final;
		void replaceThing(uint32_t index, Thing* thing) final;

		void removeThing(Thing* thing, uint32_t count) final;

		void postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, cylinderlink_t link = LINK_OWNER) final;
		void postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, cylinderlink_t link = LINK_OWNER) final;

	private:
		std::string getWriterName(Item* item) const;
		bool getReceiver(Item* item, std::string& name) const;
		bool sendItem(Item* item) const;

		static bool canSend(const Item* item);
};

#endif
 

 

Que resultou nisso

Se o jogador não tem vocação, ele não conseguirá mandar parcel para player algum.. não importa se o player tem vocação

Se o jogador tem vocação ele consegue mandar parcel para quem tem vocação, mas não manda para quem não tem vocação

 

Q22anYM.gif

separador%2B(1).png

 

Bem você pode perguntar, mas se ja bloqueou o envio de parcel, por que bloquear o inbox? .. bem o inbox eu havia feito primeiro :P mas o bloqueio no envio de parcel previne que o jogador acabe perdendo o item..

 

Digo caso ele envie o jogador só podera receber quando tiver vocação.. E SE o jogador nunca pegar vocação? foi pensando nisso que o segundo código foi feito, a ideia era que ao receber se fosse sem vocação o objeto retornaria e a label seria destruida.. mas estava gerando erros na build, foi quando Ninja veio com a ideia de bloquear o envio.. após 2as tentativas falhas a terceira gerou um warning simples e compilou.

  • 1 month later...

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