From 832deb6dbf5d42cbe19e5d4139c83317824ec3bf Mon Sep 17 00:00:00 2001 From: scara Date: Sun, 11 Jan 2009 16:42:18 +0000 Subject: [PATCH] Accessory sorting due to price. Patched via: http://www.scorched3d.co.uk/phpBB3/viewtopic.php?f=7&t=5563 git-svn-id: https://scorched3d.svn.sourceforge.net/svnroot/scorched3d/trunk/scorched@149 5b6d9151-9f40-0410-9ac9-943e3bcbbd81 --- data/accessories.xml | 1 + src/client/GLW/GLWTankTip.cpp | 8 +-- src/client/dialogs/BuyAccessoryDialog.cpp | 66 ++++++++++++++++++------ src/client/dialogs/BuyAccessoryDialog.h | 7 ++- src/client/dialogs/InventoryDialog.cpp | 57 +++++++++++++++++--- src/client/dialogs/InventoryDialog.h | 13 +++-- src/client/graph/OptionsDisplay.cpp | 18 ++++++- src/client/graph/OptionsDisplay.h | 7 +-- src/client/tankgraph/TankKeyboardControlUtil.cpp | 4 +- src/client/tankgraph/TankMenus.cpp | 4 +- src/common/weapons/AccessoryStore.cpp | 32 ++++++++---- src/common/weapons/AccessoryStore.h | 16 ++++-- 12 files changed, 177 insertions(+), 56 deletions(-) diff --git a/data/accessories.xml b/data/accessories.xml index 3a05dd2..599de77 100644 --- a/data/accessories.xml +++ b/data/accessories.xml @@ -1626,6 +1626,7 @@ and shields damaging the tank directly. Test Script + 0 2 10 diff --git a/src/client/GLW/GLWTankTip.cpp b/src/client/GLW/GLWTankTip.cpp index 7598629..46d83ae 100644 --- a/src/client/GLW/GLWTankTip.cpp +++ b/src/client/GLW/GLWTankTip.cpp @@ -119,7 +119,7 @@ void TankFuelTip::showItems(float x, float y) tank_->getAccessories().getAllAccessoriesByGroup("fuel"); ScorchedClient::instance()->getAccessoryStore().sortList( fuels, - OptionsDisplay::instance()->getSortAccessories()); + OptionsDisplay::instance()->getAccessorySortKey()); std::list::iterator itor; for (itor = fuels.begin(); itor != fuels.end(); @@ -262,7 +262,7 @@ void TankShieldTip::showItems(float x, float y) AccessoryPart::AccessoryShield); ScorchedClient::instance()->getAccessoryStore().sortList( shields, - OptionsDisplay::instance()->getSortAccessories()); + OptionsDisplay::instance()->getAccessorySortKey()); std::list::iterator itor; for (itor = shields.begin(); itor != shields.end(); @@ -405,7 +405,7 @@ void TankParachutesTip::showItems(float x, float y) AccessoryPart::AccessoryParachute); ScorchedClient::instance()->getAccessoryStore().sortList( parachutes, - OptionsDisplay::instance()->getSortAccessories()); + OptionsDisplay::instance()->getAccessorySortKey()); std::list::iterator itor; for (itor = parachutes.begin(); @@ -518,7 +518,7 @@ void TankWeaponTip::showItems(float x, float y) tank_->getAccessories().getAllAccessoriesByGroup("weapon"); ScorchedClient::instance()->getAccessoryStore().sortList( weapons, - OptionsDisplay::instance()->getSortAccessories()); + OptionsDisplay::instance()->getAccessorySortKey()); std::list::iterator itor; for (itor = weapons.begin(); itor != weapons.end(); diff --git a/src/client/dialogs/BuyAccessoryDialog.cpp b/src/client/dialogs/BuyAccessoryDialog.cpp index ead1a70..dd1e929 100644 --- a/src/client/dialogs/BuyAccessoryDialog.cpp +++ b/src/client/dialogs/BuyAccessoryDialog.cpp @@ -74,13 +74,15 @@ BuyAccessoryDialog::BuyAccessoryDialog() : defaultTab_->getLabel().setSize(10); defaultTab_->getCheckBox().setHandler(this); - sortBox_ = (GLWCheckBox *) addWidget(new GLWCheckBox(10, 14)); - sortBox_->setHandler(this); - sortBox_->setW(14); - sortBox_->setH(14); - GLWLabel *label = (GLWLabel *) - addWidget(new GLWLabel(30, 9, LANG_RESOURCE("NAME_SORT", "Sort by name"))); - label->setSize(12); + addWidget(new GLWLabel(15, 9, LANG_RESOURCE("SORT_LABEL", "Sort by:"))); + + sortDropDown_ = (GLWDropDownText *) addWidget(new GLWDropDownText(100, 9, 100)); + + sortDropDown_->addText(LANG_RESOURCE("SORT_NOTHING", "Nothing"), "Nothing"); + sortDropDown_->addText(LANG_RESOURCE("SORT_NAME", "Name"), "Name"); + sortDropDown_->addText(LANG_RESOURCE("SORT_PRICE", "Price"), "Price"); + sortDropDown_->setName("Sort"); + sortDropDown_->setHandler(this); } BuyAccessoryDialog::~BuyAccessoryDialog() @@ -252,7 +254,7 @@ void BuyAccessoryDialog::addPlayerFavorites() std::list acessories = ScorchedClient::instance()-> getAccessoryStore().getAllAccessories( - OptionsDisplay::instance()->getSortAccessories()); + OptionsDisplay::instance()->getAccessorySortKey()); std::list::reverse_iterator itor; for (itor = acessories.rbegin(); itor != acessories.rend(); @@ -274,7 +276,7 @@ void BuyAccessoryDialog::addPlayerWeaponsBuy(GLWTab *tab, const char *group) std::list weapons = ScorchedClient::instance()-> getAccessoryStore().getAllAccessoriesByTabGroup( group, - OptionsDisplay::instance()->getSortAccessories()); + OptionsDisplay::instance()->getAccessorySortKey()); float height = 10.0f; std::list::reverse_iterator itor2; @@ -296,8 +298,8 @@ void BuyAccessoryDialog::addPlayerWeaponsSell() std::list tankAccessories; tank->getAccessories().getAllAccessories( tankAccessories); - ScorchedClient::instance()->getAccessoryStore().sortList(tankAccessories, - OptionsDisplay::instance()->getSortAccessories()); + ScorchedClient::instance()->getAccessoryStore().sortList(tankAccessories, + OptionsDisplay::instance()->getAccessorySortKey()); std::list::reverse_iterator itor; for (itor = tankAccessories.rbegin(); itor != tankAccessories.rend(); @@ -399,7 +401,25 @@ void BuyAccessoryDialog::display() addTabs(); loadFavorites(); - sortBox_->setState(OptionsDisplay::instance()->getSortAccessories()); + sortDropDown_->setHandler(0); + + switch (OptionsDisplay::instance()->getAccessorySortKey()) + { + case AccessoryStore::SortName: + sortDropDown_->setCurrentText(LANG_RESOURCE("SORT_NAME", "Name")); + break; + + case AccessoryStore::SortPrice: + sortDropDown_->setCurrentText(LANG_RESOURCE("SORT_PRICE", "Price")); + break; + + case AccessoryStore::SortNothing: + sortDropDown_->setCurrentText(LANG_RESOURCE("SORT_NOTHING", "Nothing")); + break; + } + + sortDropDown_->setHandler(this); + Tank *tank = ScorchedClient::instance()->getTankContainer().getCurrentTank(); if (tank) { @@ -458,15 +478,27 @@ void BuyAccessoryDialog::tabDown(unsigned int id) } } -void BuyAccessoryDialog::stateChange(bool state, unsigned int id) +void BuyAccessoryDialog::select(unsigned int id, const int pos, GLWSelectorEntry value) { - if (id == sortBox_->getId()) + if (id == sortDropDown_->getId()) { - // The sort accessories check box has been clicked - OptionsDisplay::instance()->getSortAccessoriesEntry().setValue(state); + OptionsDisplay *display = OptionsDisplay::instance(); + const char *dataText = value.getDataText(); + + if (strcmp(dataText, "Name") == 0) + display->getAccessorySortKeyEntry().setValue(AccessoryStore::SortName); + else if (strcmp(dataText, "Price") == 0) + display->getAccessorySortKeyEntry().setValue(AccessoryStore::SortPrice); + else + display->getAccessorySortKeyEntry().setValue(AccessoryStore::SortNothing); + playerRefreshKeepPos(); } - else if (id == defaultTab_->getCheckBox().getId()) +} + +void BuyAccessoryDialog::stateChange(bool state, unsigned int id) +{ + if (id == defaultTab_->getCheckBox().getId()) { if (defaultTab_->getCheckBox().getState()) { diff --git a/src/client/dialogs/BuyAccessoryDialog.h b/src/client/dialogs/BuyAccessoryDialog.h index 72a7c68..8f94f01 100644 --- a/src/client/dialogs/BuyAccessoryDialog.h +++ b/src/client/dialogs/BuyAccessoryDialog.h @@ -31,11 +31,13 @@ #include #include #include +#include class Tank; class BuyAccessoryDialog : public GLWWindow, public GLWButtonI, public GLWCheckBoxI, + public GLWDropDownI, public GLWTabI { public: @@ -49,6 +51,9 @@ public: // Inherited from GLWCheckBoxI virtual void stateChange(bool state, unsigned int id); + // Inherited from GLWDropDownI + virtual void select(unsigned int id, const int pos, GLWSelectorEntry value); + // Inherited from GLWTabI virtual void tabDown(unsigned int id); @@ -62,7 +67,7 @@ protected: GLWTab *sellTab_; GLWTab *favouritesTab_; GLWPanel *topPanel_; - GLWCheckBox *sortBox_; + GLWDropDownText *sortDropDown_; GLWCheckBoxText *defaultTab_; GLWFlag *flag_; std::map sellMap_; diff --git a/src/client/dialogs/InventoryDialog.cpp b/src/client/dialogs/InventoryDialog.cpp index 7cb35ec..204db9c 100644 --- a/src/client/dialogs/InventoryDialog.cpp +++ b/src/client/dialogs/InventoryDialog.cpp @@ -55,9 +55,16 @@ InventoryDialog::InventoryDialog() : addWidget(new GLWTab("Inv", LANG_RESOURCE("INVENTORY_TAB", "Inv"), 10, 40, 420, 160)); topPanel_ = (GLWPanel *) addWidget(new GLWPanel(10, 265, 420, 50)); - sortBox_ = (GLWCheckBox *) addWidget(new GLWCheckBox(10, 10)); - sortBox_->setHandler(this); - addWidget(new GLWLabel(35, 7, LANG_RESOURCE("SORT_ACCESSORIES", "Sort accessories by name"))); + + addWidget(new GLWLabel(15, 9, LANG_RESOURCE("SORT_LABEL", "Sort by:"))); + + sortDropDown_ = (GLWDropDownText *) addWidget(new GLWDropDownText(100, 9, 100)); + + sortDropDown_->addText(LANG_RESOURCE("SORT_NOTHING", "Nothing"), "Nothing"); + sortDropDown_->addText(LANG_RESOURCE("SORT_NAME", "Name"), "Name"); + sortDropDown_->addText(LANG_RESOURCE("SORT_PRICE", "Price"), "Price"); + sortDropDown_->setName("Sort"); + sortDropDown_->setHandler(this); } InventoryDialog::~InventoryDialog() @@ -65,9 +72,45 @@ InventoryDialog::~InventoryDialog() } -void InventoryDialog::stateChange(bool state, unsigned int id) +void InventoryDialog::select(unsigned int id, const int pos, GLWSelectorEntry value) { - OptionsDisplay::instance()->getSortAccessoriesEntry().setValue(state); + if (id == sortDropDown_->getId()) + { + OptionsDisplay *display = OptionsDisplay::instance(); + const char *dataText = value.getDataText(); + + if (strcmp(dataText, "Name") == 0) + display->getAccessorySortKeyEntry().setValue(AccessoryStore::SortName); + else if (strcmp(dataText, "Price") == 0) + display->getAccessorySortKeyEntry().setValue(AccessoryStore::SortPrice); + else + display->getAccessorySortKeyEntry().setValue(AccessoryStore::SortNothing); + + playerRefresh(); + } +} + +void InventoryDialog::display() +{ + sortDropDown_->setHandler(0); + + switch (OptionsDisplay::instance()->getAccessorySortKey()) + { + case AccessoryStore::SortName: + sortDropDown_->setCurrentText(LANG_RESOURCE("SORT_NAME", "Name")); + break; + + case AccessoryStore::SortPrice: + sortDropDown_->setCurrentText(LANG_RESOURCE("SORT_PRICE", "Price")); + break; + + case AccessoryStore::SortNothing: + sortDropDown_->setCurrentText(LANG_RESOURCE("SORT_NOTHING", "Nothing")); + break; + } + + sortDropDown_->setHandler(this); + playerRefresh(); } @@ -83,8 +126,6 @@ void InventoryDialog::setupWindow() topPanel_->setY(240 + addition); needCentered_ = true; - - sortBox_->setState(OptionsDisplay::instance()->getSortAccessories()); } void InventoryDialog::addPlayerName() @@ -116,7 +157,7 @@ void InventoryDialog::addPlayerWeapons() std::list tankAccessories; tank->getAccessories().getAllAccessories(tankAccessories); ScorchedClient::instance()->getAccessoryStore().sortList(tankAccessories, - OptionsDisplay::instance()->getSortAccessories()); + OptionsDisplay::instance()->getAccessorySortKey()); std::list::reverse_iterator itor; for (itor = tankAccessories.rbegin(); diff --git a/src/client/dialogs/InventoryDialog.h b/src/client/dialogs/InventoryDialog.h index 586a9df..8aa188b 100644 --- a/src/client/dialogs/InventoryDialog.h +++ b/src/client/dialogs/InventoryDialog.h @@ -28,11 +28,11 @@ #include #include #include -#include +#include class InventoryDialog : public GLWWindow, public GLWButtonI, - public GLWCheckBoxI + public GLWDropDownI { public: static InventoryDialog *instance(); @@ -41,8 +41,11 @@ public: virtual void buttonDown(unsigned int id); virtual void windowInit(const unsigned state); - // Inherited from GLWCheckBoxI - virtual void stateChange(bool state, unsigned int id); + // Inherited from GLWDropDownI + virtual void select(unsigned int id, const int pos, GLWSelectorEntry value); + + // Inherited from GLWPanel through GLWPanel + virtual void display(); protected: static InventoryDialog *instance_; @@ -50,7 +53,7 @@ protected: unsigned int okId_; GLWTab *sellTab_; GLWPanel *topPanel_; - GLWCheckBox *sortBox_; + GLWDropDownText *sortDropDown_; void setupWindow(); void playerRefresh(); diff --git a/src/client/graph/OptionsDisplay.cpp b/src/client/graph/OptionsDisplay.cpp index e6d9c56..69d8d33 100644 --- a/src/client/graph/OptionsDisplay.cpp +++ b/src/client/graph/OptionsDisplay.cpp @@ -22,6 +22,16 @@ #include #include +// This is a mirror of AccessoryStore::SortKey. + +static OptionEntryEnum::EnumEntry accessorySortKeyEnum[] = +{ + { "SortNothing", 0 }, + { "SortName", 1 }, + { "SortPrice", 2 }, + { "", -1 } +}; + OptionsDisplay *OptionsDisplay::instance_ = 0; OptionsDisplay *OptionsDisplay::instance() @@ -304,8 +314,12 @@ OptionsDisplay::OptionsDisplay() : "Show in game help tooltips for items that have it", RWAccess, true), showContextInfo_(options_, "ShowContextInfo", "Show in game information tooltips for items that have it", RWAccess, true), - sortAccessories_(options_, "SortAccessories", - "Sort accessories alphabetically by name before displaying", RWAccess, false), + deprecatedSortAccessories_(options_, "SortAccessories", + "Sort accessories alphabetically by name before displaying", + RWAccess | OptionEntry::DataDepricated, false), + accessorySortKey_(options_, "AccessorySortKey", + "The key to sort accessories by before displaying", + RWAccess, 0, accessorySortKeyEnum), focusPause_(options_, "FocusPause", "Pause the graphics display when mouse leaves window.", RWAccess, true) diff --git a/src/client/graph/OptionsDisplay.h b/src/client/graph/OptionsDisplay.h index 3385f3b..400494a 100644 --- a/src/client/graph/OptionsDisplay.h +++ b/src/client/graph/OptionsDisplay.h @@ -274,8 +274,8 @@ public: bool getLowTreeDetail() { return lowTreeDetail_; } OptionEntryBool &getLowTreeDetailEntry() { return lowTreeDetail_; } - bool getSortAccessories() { return sortAccessories_; } - OptionEntryBool &getSortAccessoriesEntry() { return sortAccessories_; } + int getAccessorySortKey() { return accessorySortKey_; } + OptionEntryEnum &getAccessorySortKeyEntry() { return accessorySortKey_; } bool getNoDepthSorting() { return noDepthSorting_; } OptionEntryBool &getNoDepthSortingEntry() { return noDepthSorting_; } @@ -457,7 +457,8 @@ protected: OptionEntryBool drawBoundingSpheres_; OptionEntryBool noLenseFlare_; OptionEntryBool noSkins_; - OptionEntryBool sortAccessories_; + OptionEntryBool deprecatedSortAccessories_; + OptionEntryEnum accessorySortKey_; OptionEntryBool drawWater_; OptionEntryBool drawLandscape_; OptionEntryBool drawSurround_; diff --git a/src/client/tankgraph/TankKeyboardControlUtil.cpp b/src/client/tankgraph/TankKeyboardControlUtil.cpp index 09c1aec..7690f6e 100644 --- a/src/client/tankgraph/TankKeyboardControlUtil.cpp +++ b/src/client/tankgraph/TankKeyboardControlUtil.cpp @@ -172,7 +172,7 @@ void TankKeyboardControlUtil::nextWeapon(Tank *tank) tank->getAccessories().getAllAccessoriesByType( AccessoryPart::AccessoryWeapon); ScorchedClient::instance()->getAccessoryStore().sortList(result, - OptionsDisplay::instance()->getSortAccessories()); + OptionsDisplay::instance()->getAccessorySortKey()); std::list::iterator itor; for (itor = result.begin(); @@ -197,7 +197,7 @@ void TankKeyboardControlUtil::prevWeapon(Tank *tank) tank->getAccessories().getAllAccessoriesByType( AccessoryPart::AccessoryWeapon); ScorchedClient::instance()->getAccessoryStore().sortList(result, - OptionsDisplay::instance()->getSortAccessories()); + OptionsDisplay::instance()->getAccessorySortKey()); std::list::iterator itor; for (itor = result.begin(); diff --git a/src/client/tankgraph/TankMenus.cpp b/src/client/tankgraph/TankMenus.cpp index cf1054e..1f9a9c7 100644 --- a/src/client/tankgraph/TankMenus.cpp +++ b/src/client/tankgraph/TankMenus.cpp @@ -181,7 +181,7 @@ void TankMenus::showInventory() std::list accessories; tank->getAccessories().getAllAccessories(accessories); - ScorchedClient::instance()->getAccessoryStore().sortList(accessories, true); + ScorchedClient::instance()->getAccessoryStore().sortList(accessories, AccessoryStore::SortName); std::list::iterator aitor; for (aitor = accessories.begin(); @@ -427,7 +427,7 @@ bool TankMenus::AccessoryMenu::getMenuItems(const char* menuName, std::list weapons = ScorchedClient::instance()-> getAccessoryStore().getAllAccessoriesByTabGroup( group, - OptionsDisplay::instance()->getSortAccessories()); + OptionsDisplay::instance()->getAccessorySortKey()); std::list::iterator itor; for (itor = weapons.begin(); diff --git a/src/common/weapons/AccessoryStore.cpp b/src/common/weapons/AccessoryStore.cpp index ffbc5a9..895981c 100644 --- a/src/common/weapons/AccessoryStore.cpp +++ b/src/common/weapons/AccessoryStore.cpp @@ -163,9 +163,9 @@ AccessoryPart *AccessoryStore::createAccessoryPart( return accessoryPart; } -void AccessoryStore::sortList(std::list &accList, bool alpha) +void AccessoryStore::sortList(std::list &accList, int sortKey) { - if (alpha) + if (sortKey) { std::vector accVector; std::list::iterator itor; @@ -176,7 +176,7 @@ void AccessoryStore::sortList(std::list &accList, bool alpha) accVector.push_back(*itor); } - // Crudely sort by name + // Crudely sort by name or price // stl sort method list is broken in visual c 6 // bubble sort bool changed = true; @@ -185,9 +185,23 @@ void AccessoryStore::sortList(std::list &accList, bool alpha) changed = false; for (int i=0; igetName(), accVector[i+1]->getName())<0) + bool swap = false; + + // When sorting by price, use accessory name as a + // secondary sort key. + + if ((sortKey == SortName) || + (sortKey == SortPrice && accVector[i]->getPrice() == accVector[i + 1]->getPrice())) + { + swap = strcmp(accVector[i]->getName(), accVector[i + 1]->getName()) < 0; + } + else if (sortKey == SortPrice) + { + swap = accVector[i]->getPrice() < accVector[i + 1]->getPrice(); + } + + if (swap) { - // swap Accessory *tmp = accVector[i]; accVector[i] = accVector[i+1]; accVector[i+1] = tmp; @@ -231,7 +245,7 @@ void AccessoryStore::sortList(std::list &accList, bool alpha) } std::list AccessoryStore::getAllAccessoriesByTabGroup( - const char *tabgroup, bool sort) + const char *tabgroup, int sortKey) { std::list result; std::list::iterator itor; @@ -246,11 +260,11 @@ std::list AccessoryStore::getAllAccessoriesByTabGroup( } } - if (sort) sortList(result, true); + if (sortKey) sortList(result, sortKey); return result; } -std::list AccessoryStore::getAllAccessories(bool sort) +std::list AccessoryStore::getAllAccessories(int sortKey) { std::list result; std::list::iterator itor; @@ -261,7 +275,7 @@ std::list AccessoryStore::getAllAccessories(bool sort) result.push_back(*itor); } - if (sort) sortList(result, true); + if (sortKey) sortList(result, sortKey); return result; } diff --git a/src/common/weapons/AccessoryStore.h b/src/common/weapons/AccessoryStore.h index c9f0321..9757ade 100644 --- a/src/common/weapons/AccessoryStore.h +++ b/src/common/weapons/AccessoryStore.h @@ -34,6 +34,16 @@ class XMLNode; class AccessoryStore { public: + + // This is mirrored by accessorySortKeyEnum in client/graph/OptionsDisplay.cpp. + + enum SortKey + { + SortNothing = 0, + SortName = 1, + SortPrice = 2 + }; + AccessoryStore(); virtual ~AccessoryStore(); @@ -50,8 +60,8 @@ public: Weapon *getDeathAnimation(); Weapon *getMuzzelFlash(); - std::list getAllAccessories(bool sort=false); - std::list getAllAccessoriesByTabGroup(const char *tabgroup, bool sort=false); + std::list getAllAccessories(int sortKey=SortNothing); + std::list getAllAccessoriesByTabGroup(const char *tabgroup, int sortKey=SortNothing); std::map &getParsingNodes() { return parsingNodes_; } std::set &getTabGroupNames() { return tabGroups_; } @@ -63,7 +73,7 @@ public: bool writeEconomyToBuffer(NetBuffer &buffer); bool readEconomyFromBuffer(NetBufferReader &reader); - void sortList(std::list &accList, bool alpha); + void sortList(std::list &accList, int sortKey=SortNothing); protected: std::set tabGroups_; -- 2.11.4.GIT