summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dragdrop.h3
-rw-r--r--src/gui/npcdialog.cpp219
-rw-r--r--src/gui/npcdialog.h14
-rw-r--r--src/gui/widgets/itemcontainer.cpp22
-rw-r--r--src/inventory.h1
-rw-r--r--src/net/tmwa/network.h2
-rw-r--r--src/net/tmwa/npchandler.cpp4
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<int>(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<int>(mItems.size())
+ || selectedIndex < 0
+ || !Client::limitPackets(PACKET_NPC_INPUT))
+ {
+ return;
+ }
+ unsigned char choice = static_cast<unsigned char>(
+ 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<unsigned char>(
- 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);