Postado Agosto 12, 2015 10 anos 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 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 Bem você pode perguntar, mas se ja bloqueou o envio de parcel, por que bloquear o inbox? .. bem o inbox eu havia feito primeiro 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. [TFS 1.2 ] Evento Jogos Vorazes [TFS 1.2 ] Sistema de Diálogo em ModalWindow [TFS 1.1+] Sistema de Crafting Avançado em ModalWindow [TFS 1.1+] Sistema de Alquimia Avançada em ModalWindow [TFS 1.2 ] Sistema VIP completo com portas, items, pisos
Postado Agosto 12, 2015 10 anos Tópico aprovado, obrigado por compartilhar. Este tópico foi movido: Para: "OTServ → Programação Open Tibia → Códigos Prontos" STYLLER OT 2022
Postado Outubro 10, 2015 10 anos Cara eu to querendo uma ajuda, tipo eu tento criar uma oferta no market porem eu coloca o preço que quero vender e quando clico em create simplesmente não faz nada, você sabe arrumar?
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.