From 5001fa194c820422dd5de2dd655c17bde131e1cb Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 11 Aug 2013 11:40:12 +0300 Subject: add support for giving item to npc (evol only) chancge network version to 9. --- src/dragdrop.h | 3 +- src/gui/npcdialog.cpp | 219 ++++++++++++++++++++++++++++++-------- src/gui/npcdialog.h | 14 ++- src/gui/widgets/itemcontainer.cpp | 22 ++++ src/inventory.h | 1 + src/net/tmwa/network.h | 2 +- src/net/tmwa/npchandler.cpp | 4 + 7 files changed, 217 insertions(+), 48 deletions(-) diff --git a/src/dragdrop.h b/src/dragdrop.h index 4ca9a2bc3..aaad56b2d 100644 --- a/src/dragdrop.h +++ b/src/dragdrop.h @@ -43,7 +43,8 @@ enum DragDropSource DRAGDROP_SOURCE_GROUND, DRAGDROP_SOURCE_DROP, DRAGDROP_SOURCE_SHORTCUTS, - DRAGDROP_SOURCE_CRAFT + DRAGDROP_SOURCE_CRAFT, + DRAGDROP_SOURCE_NPC, }; class DragDrop diff --git a/src/gui/npcdialog.cpp b/src/gui/npcdialog.cpp index dd2243310..3d8da6d58 100644 --- a/src/gui/npcdialog.cpp +++ b/src/gui/npcdialog.cpp @@ -26,10 +26,13 @@ #include "being.h" #include "configuration.h" #include "client.h" +#include "inventory.h" +#include "item.h" #include "soundconsts.h" #include "soundmanager.h" #include "gui/gui.h" +#include "gui/inventorywindow.h" #include "gui/sdlfont.h" #include "gui/setup.h" #include "gui/viewport.h" @@ -37,6 +40,7 @@ #include "gui/widgets/browserbox.h" #include "gui/widgets/chattab.h" #include "gui/widgets/inttextfield.h" +#include "gui/widgets/itemcontainer.h" #include "gui/widgets/itemlinkhandler.h" #include "gui/widgets/layout.h" #include "gui/widgets/extendedlistbox.h" @@ -102,7 +106,13 @@ NpcDialog::NpcDialog(const int npcId) : // TRANSLATORS: npc dialog button mButton2(new Button(this, _("Close"), "close", this)), // TRANSLATORS: npc dialog button + mButton3(new Button(this, _("Add"), "add", this)), + // TRANSLATORS: npc dialog button mResetButton(new Button(this, _("Reset"), "reset", this)), + mInventory(new Inventory(Inventory::NPC, 1)), + mItemContainer(new ItemContainer(this, mInventory)), + mItemScrollArea(new ScrollArea(mItemContainer, + getOptionBool("showitemsbackground"), "npc_listbackground.xml")), mInputState(NPC_INPUT_NONE), mActionState(NPC_ACTION_WAIT), mLastNextTime(0), @@ -152,6 +162,7 @@ NpcDialog::NpcDialog(const int npcId) : setContentSize(260, 175); mListScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mItemScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); mItemList->setVisible(true); mTextField->setVisible(true); mIntField->setVisible(true); @@ -204,6 +215,8 @@ NpcDialog::~NpcDialog() mButton = nullptr; delete mButton2; mButton2 = nullptr; + delete mButton3; + mButton3 = nullptr; // These might not actually be in the layout, so lets be safe delete mScrollArea; @@ -223,6 +236,13 @@ NpcDialog::~NpcDialog() delete mItemLinkHandler; mItemLinkHandler = nullptr; + delete mItemContainer; + mItemContainer = nullptr; + delete mInventory; + mInventory = nullptr; + delete mItemScrollArea; + mItemScrollArea = nullptr; + delete mListScrollArea; mListScrollArea = nullptr; @@ -287,38 +307,68 @@ void NpcDialog::action(const gcn::ActionEvent &event) std::string printText; // Text that will get printed // in the textbox - if (mInputState == NPC_INPUT_LIST) + switch(mInputState) { - if (gui) - gui->resetClickCount(); - const int selectedIndex = mItemList->getSelected(); - - if (selectedIndex >= static_cast(mItems.size()) - || selectedIndex < 0 - || !Client::limitPackets(PACKET_NPC_INPUT)) + case NPC_INPUT_LIST: + { + if (gui) + gui->resetClickCount(); + const int selectedIndex = mItemList->getSelected(); + + if (selectedIndex >= static_cast(mItems.size()) + || selectedIndex < 0 + || !Client::limitPackets(PACKET_NPC_INPUT)) + { + return; + } + unsigned char choice = static_cast( + selectedIndex + 1); + printText = mItems[selectedIndex]; + + Net::getNpcHandler()->listInput(mNpcId, choice); + break; + } + case NPC_INPUT_STRING: + { + if (!Client::limitPackets(PACKET_NPC_INPUT)) + return; + printText = mTextField->getText(); + Net::getNpcHandler()->stringInput(mNpcId, printText); + } + case NPC_INPUT_INTEGER: { - return; + if (!Client::limitPackets(PACKET_NPC_INPUT)) + return; + printText = strprintf("%d", mIntField->getValue()); + Net::getNpcHandler()->integerInput( + mNpcId, mIntField->getValue()); + } + case NPC_INPUT_ITEM: + { + if (!Client::limitPackets(PACKET_NPC_INPUT)) + return; + + const Item *const item = mInventory->getItem(0); + std::string str; + int color = 1; + if (item) + { + str = strprintf("%d,%d", item->getId(), + item->getColor()); + } + else + { + str = "0,0"; + } + + // need send selected item + Net::getNpcHandler()->stringInput(mNpcId, str); + mInventory->clear(); + break; } - unsigned char choice = static_cast( - selectedIndex + 1); - printText = mItems[selectedIndex]; - Net::getNpcHandler()->listInput(mNpcId, choice); - } - else if (mInputState == NPC_INPUT_STRING) - { - if (!Client::limitPackets(PACKET_NPC_INPUT)) - return; - printText = mTextField->getText(); - Net::getNpcHandler()->stringInput(mNpcId, printText); - } - else if (mInputState == NPC_INPUT_INTEGER) - { - if (!Client::limitPackets(PACKET_NPC_INPUT)) - return; - printText = strprintf("%d", mIntField->getValue()); - Net::getNpcHandler()->integerInput( - mNpcId, mIntField->getValue()); + default: + break; } // addText will auto remove the input layout addText(strprintf("> \"%s\"", printText.c_str()), false); @@ -330,10 +380,20 @@ void NpcDialog::action(const gcn::ActionEvent &event) } else if (eventId == "reset") { - if (mInputState == NPC_INPUT_STRING) - mTextField->setText(mDefaultString); - else if (mInputState == NPC_INPUT_INTEGER) - mIntField->setValue(mDefaultInt); + switch (mInputState) + { + case NPC_INPUT_STRING: + mTextField->setText(mDefaultString); + break; + case NPC_INPUT_INTEGER: + mIntField->setValue(mDefaultInt); + break; + case NPC_INPUT_ITEM: + mInventory->clear(); + break; + default: + break; + } } else if (eventId == "inc") { @@ -345,16 +405,45 @@ void NpcDialog::action(const gcn::ActionEvent &event) } else if (eventId == "clear") { - clearRows(); + switch (mInputState) + { + case NPC_INPUT_ITEM: + mInventory->clear(); + break; + case NPC_INPUT_STRING: + case NPC_INPUT_INTEGER: + default: + clearRows(); + break; + } } else if (eventId == "close") { if (mActionState == NPC_ACTION_INPUT) { - Net::getNpcHandler()->listInput(mNpcId, 255); + switch (mInputState) + { + case NPC_INPUT_ITEM: + Net::getNpcHandler()->stringInput(mNpcId, "0,0"); + break; + case NPC_INPUT_STRING: + case NPC_INPUT_INTEGER: + default: + Net::getNpcHandler()->listInput(mNpcId, 255); + break; + } closeDialog(); } } + else if (eventId == "add") + { + if (inventoryWindow) + { + const Item *const item = inventoryWindow->getSelectedItem(); + if (item) + mInventory->addItem(item->getId(), 1, 1, item->getColor()); + } + } } void NpcDialog::nextDialog() @@ -450,6 +539,7 @@ void NpcDialog::textRequest(const std::string &defaultText) mInputState = NPC_INPUT_STRING; mDefaultString = defaultText; mTextField->setText(defaultText); + buildLayout(); } @@ -486,6 +576,14 @@ void NpcDialog::integerRequest(const int defaultValue, const int min, buildLayout(); } +void NpcDialog::itemRequest() +{ + mActionState = NPC_ACTION_INPUT; + mInputState = NPC_INPUT_ITEM; + + buildLayout(); +} + void NpcDialog::move(const int amount) { if (mActionState != NPC_ACTION_INPUT) @@ -501,6 +599,7 @@ void NpcDialog::move(const int amount) break; case NPC_INPUT_NONE: case NPC_INPUT_STRING: + case NPC_INPUT_ITEM: default: break; } @@ -627,6 +726,27 @@ void NpcDialog::placeIntInputControls() } } +void NpcDialog::placeItemInputControls() +{ + if (mShowAvatar) + { + place(0, 0, mPlayerBox); + place(1, 0, mScrollArea, 6, 3); + place(0, 3, mItemScrollArea, 7, 3); + place(1, 6, mButton3, 2); + place(3, 6, mClearButton, 2); + place(5, 6, mButton, 2); + } + else + { + place(0, 0, mScrollArea, 6, 3); + place(0, 3, mItemScrollArea, 6, 3); + place(0, 6, mButton3, 2); + place(2, 6, mClearButton, 2); + place(4, 6, mButton, 2); + } +} + void NpcDialog::buildLayout() { clearLayout(); @@ -644,18 +764,27 @@ void NpcDialog::buildLayout() else if (mInputState != NPC_INPUT_NONE) { mButton->setCaption(CAPTION_SUBMIT); - if (mInputState == NPC_INPUT_LIST) - { - placeMenuControls(); - mItemList->setSelected(-1); - } - else if (mInputState == NPC_INPUT_STRING) + switch (mInputState) { - placeTextInputControls(); - } - else if (mInputState == NPC_INPUT_INTEGER) - { - placeIntInputControls(); + case NPC_INPUT_LIST: + placeMenuControls(); + mItemList->setSelected(-1); + break; + + case NPC_INPUT_STRING: + placeTextInputControls(); + break; + + case NPC_INPUT_INTEGER: + placeIntInputControls(); + break; + + case NPC_INPUT_ITEM: + placeItemInputControls(); + break; + + default: + break; } } diff --git a/src/gui/npcdialog.h b/src/gui/npcdialog.h index 815bc7564..9e4de0907 100644 --- a/src/gui/npcdialog.h +++ b/src/gui/npcdialog.h @@ -40,7 +40,9 @@ class Button; class BrowserBox; class ExtendedListBox; class ItemLinkHandler; +class Inventory; class IntTextField; +class ItemContainer; class NpcDialog; class PlayerBox; class ScrollArea; @@ -161,6 +163,8 @@ class NpcDialog final : public Window, void integerRequest(const int defaultValue = 0, const int min = 0, const int max = 2147483647); + void itemRequest(); + void move(const int amount); void setVisible(bool visible) override; @@ -227,6 +231,8 @@ class NpcDialog final : public Window, void placeIntInputControls(); + void placeItemInputControls(); + int mNpcId; int mDefaultInt; @@ -255,16 +261,22 @@ class NpcDialog final : public Window, // Used for the button Button *mButton; Button *mButton2; + Button *mButton3; // Will reset the text and integer input to the provided default Button *mResetButton; + Inventory *mInventory; + ItemContainer *mItemContainer; + ScrollArea *mItemScrollArea; + enum NpcInputState { NPC_INPUT_NONE = 0, NPC_INPUT_LIST, NPC_INPUT_STRING, - NPC_INPUT_INTEGER + NPC_INPUT_INTEGER, + NPC_INPUT_ITEM }; enum NpcActionState diff --git a/src/gui/widgets/itemcontainer.cpp b/src/gui/widgets/itemcontainer.cpp index e815b1541..f3fb21336 100644 --- a/src/gui/widgets/itemcontainer.cpp +++ b/src/gui/widgets/itemcontainer.cpp @@ -413,6 +413,8 @@ void ItemContainer::mousePressed(gcn::MouseEvent &event) case Inventory::TRADE: src = DRAGDROP_SOURCE_TRADE; break; + case Inventory::NPC: + src = DRAGDROP_SOURCE_NPC; default: break; } @@ -505,6 +507,9 @@ void ItemContainer::mouseReleased(gcn::MouseEvent &event) case Inventory::TRADE: dst = DRAGDROP_SOURCE_TRADE; break; + case Inventory::NPC: + dst = DRAGDROP_SOURCE_NPC; + break; default: break; } @@ -530,6 +535,23 @@ void ItemContainer::mouseReleased(gcn::MouseEvent &event) { inventory = PlayerInfo::getInventory(); } + else if (src == DRAGDROP_SOURCE_INVENTORY + && dst == DRAGDROP_SOURCE_NPC) + { + inventory = PlayerInfo::getInventory(); + const Item *const item = inventory->getItem(dragDrop.getTag()); + if (item) + mInventory->addItem(item->getId(), 1, 1, item->getColor()); + return; + } + else if (src == DRAGDROP_SOURCE_NPC) + { + inventory = PlayerInfo::getInventory(); + const Item *const item = inventory->getItem(dragDrop.getTag()); + if (item) + mInventory->removeItemAt(dragDrop.getTag()); + return; + } if (inventory) { diff --git a/src/inventory.h b/src/inventory.h index 2ee56a810..6f71c6682 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -57,6 +57,7 @@ class Inventory final STORAGE, CART, TRADE, + NPC, TYPE_END }; diff --git a/src/net/tmwa/network.h b/src/net/tmwa/network.h index 0dfd067a8..62104592b 100644 --- a/src/net/tmwa/network.h +++ b/src/net/tmwa/network.h @@ -32,7 +32,7 @@ * Protocol version, reported to the eAthena char and mapserver who can adjust * the protocol accordingly. */ -#define CLIENT_PROTOCOL_VERSION 8 +#define CLIENT_PROTOCOL_VERSION 9 #define CLIENT_TMW_PROTOCOL_VERSION 1 namespace TmwAthena diff --git a/src/net/tmwa/npchandler.cpp b/src/net/tmwa/npchandler.cpp index ddbc6a220..7bdf671a4 100644 --- a/src/net/tmwa/npchandler.cpp +++ b/src/net/tmwa/npchandler.cpp @@ -318,6 +318,10 @@ void NpcHandler::processNpcCommand(Net::MessageIn &msg, const int npcId) if (mDialog) mDialog->clearRows(); break; + case 10: // send selected item id + if (mDialog) + mDialog->itemRequest(); + break; default: logger->log("unknown npc command: %d", cmd); -- cgit v1.2.3-70-g09d2