Added merchant repair feature

actorid
scrawl 12 years ago
parent 8e2f9f5186
commit 20774f8f81

@ -31,6 +31,7 @@ add_openmw_dir (mwgui
confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu
itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog
enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons
merchantrepair
) )
add_openmw_dir (mwdialogue add_openmw_dir (mwdialogue

@ -238,6 +238,7 @@ namespace MWBase
virtual void startSpellMaking(MWWorld::Ptr actor) = 0; virtual void startSpellMaking(MWWorld::Ptr actor) = 0;
virtual void startEnchanting(MWWorld::Ptr actor) = 0; virtual void startEnchanting(MWWorld::Ptr actor) = 0;
virtual void startTraining(MWWorld::Ptr actor) = 0; virtual void startTraining(MWWorld::Ptr actor) = 0;
virtual void startRepair(MWWorld::Ptr actor) = 0;
virtual void changePointer (const std::string& name) = 0; virtual void changePointer (const std::string& name) = 0;

@ -367,6 +367,9 @@ namespace MWDialogue
if (services & ESM::NPC::Enchanting) if (services & ESM::NPC::Enchanting)
windowServices |= MWGui::DialogueWindow::Service_Enchant; windowServices |= MWGui::DialogueWindow::Service_Enchant;
if (services & ESM::NPC::Repair)
windowServices |= MWGui::DialogueWindow::Service_Repair;
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
win->setServices (windowServices); win->setServices (windowServices);

@ -280,6 +280,11 @@ void DialogueWindow::onSelectTopic(const std::string& topic, int id)
mWindowManager.pushGuiMode(GM_Training); mWindowManager.pushGuiMode(GM_Training);
mWindowManager.startTraining (mPtr); mWindowManager.startTraining (mPtr);
} }
else if (topic == gmst.find("sRepair")->getString())
{
mWindowManager.pushGuiMode(GM_MerchantRepair);
mWindowManager.startRepair (mPtr);
}
} }
} }
} }
@ -327,6 +332,9 @@ void DialogueWindow::setKeywords(std::list<std::string> keyWords)
if (mServices & Service_Training) if (mServices & Service_Training)
mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString()); mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString());
if (mServices & Service_Repair)
mTopicsList->addItem(gmst.find("sRepair")->getString());
if (anyService || mPtr.getTypeName() == typeid(ESM::NPC).name()) if (anyService || mPtr.getTypeName() == typeid(ESM::NPC).name())
mTopicsList->addSeparator(); mTopicsList->addSeparator();

@ -81,7 +81,8 @@ namespace MWGui
Service_CreateSpells = 0x04, Service_CreateSpells = 0x04,
Service_Enchant = 0x08, Service_Enchant = 0x08,
Service_Training = 0x10, Service_Training = 0x10,
Service_Travel = 0x20 Service_Travel = 0x20,
Service_Repair = 0x40
}; };
protected: protected:

@ -0,0 +1,132 @@
#include "merchantrepair.hpp"
#include <boost/lexical_cast.hpp>
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/class.hpp"
#include "list.hpp"
#include "inventorywindow.hpp"
#include "tradewindow.hpp"
namespace MWGui
{
MerchantRepair::MerchantRepair(MWBase::WindowManager &parWindowManager)
: WindowBase("openmw_merchantrepair.layout", parWindowManager)
{
getWidget(mList, "RepairView");
getWidget(mOkButton, "OkButton");
getWidget(mGoldLabel, "PlayerGold");
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MerchantRepair::onOkButtonClick);
}
void MerchantRepair::startRepair(const MWWorld::Ptr &actor)
{
mActor = actor;
while (mList->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(mList->getChildAt(0));
int currentY = 0;
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
for (MWWorld::ContainerStoreIterator iter (store.begin());
iter!=store.end(); ++iter)
{
if (MWWorld::Class::get(*iter).hasItemHealth(*iter))
{
int maxDurability = MWWorld::Class::get(*iter).getItemMaxHealth(*iter);
int durability = (iter->getCellRef().mCharge == -1) ? maxDurability : iter->getCellRef().mCharge;
if (maxDurability == durability)
continue;
int basePrice = MWWorld::Class::get(*iter).getValue(*iter);
float fRepairMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
.find("fRepairMult")->getFloat();
float p = std::max(1, basePrice);
float r = std::max(1, static_cast<int>(maxDurability / p));
int x = ((maxDurability - durability) / r);
x = (fRepairMult * x);
int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mActor, x, true);
std::string name = MWWorld::Class::get(*iter).getName(*iter)
+ " - " + boost::lexical_cast<std::string>(price)
+ MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
.find("sgp")->getString();;
MyGUI::Button* button =
mList->createWidget<MyGUI::Button>(
(price>mWindowManager.getInventoryWindow()->getPlayerGold()) ? "SandTextGreyedOut" : "SandTextButton",
0,
currentY,
0,
18,
MyGUI::Align::Default
);
currentY += 18;
button->setEnabled(price<=mWindowManager.getInventoryWindow()->getPlayerGold());
button->setUserString("Price", boost::lexical_cast<std::string>(price));
button->setUserData(*iter);
button->setCaptionWithReplacing(name);
button->setSize(button->getTextSize().width,18);
button->eventMouseWheel += MyGUI::newDelegate(this, &MerchantRepair::onMouseWheel);
button->setUserString("ToolTipType", "ItemPtr");
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MerchantRepair::onRepairButtonClick);
}
}
mList->setCanvasSize (MyGUI::IntSize(mList->getWidth(), std::max(mList->getHeight(), currentY)));
mGoldLabel->setCaptionWithReplacing("#{sGold}: "
+ boost::lexical_cast<std::string>(mWindowManager.getInventoryWindow()->getPlayerGold()));
}
void MerchantRepair::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{
if (mList->getViewOffset().top + _rel*0.3 > 0)
mList->setViewOffset(MyGUI::IntPoint(0, 0));
else
mList->setViewOffset(MyGUI::IntPoint(0, mList->getViewOffset().top + _rel*0.3));
}
void MerchantRepair::open()
{
center();
}
void MerchantRepair::onRepairButtonClick(MyGUI::Widget *sender)
{
// repair
MWWorld::Ptr item = *sender->getUserData<MWWorld::Ptr>();
item.getCellRef().mCharge = MWWorld::Class::get(item).getItemMaxHealth(item);
MWBase::Environment::get().getSoundManager()->playSound("Repair",1,1);
int price = boost::lexical_cast<int>(sender->getUserString("Price"));
mWindowManager.getTradeWindow()->addOrRemoveGold(-price);
startRepair(mActor);
}
void MerchantRepair::onOkButtonClick(MyGUI::Widget *sender)
{
mWindowManager.removeGuiMode(GM_MerchantRepair);
}
}

@ -0,0 +1,37 @@
#ifndef OPENMW_MWGUI_MERCHANTREPAIR_H
#define OPENMW_MWGUI_MERCHANTREPAIR_H
#include "window_base.hpp"
#include "../mwworld/ptr.hpp"
namespace MWGui
{
class MerchantRepair : public WindowBase
{
public:
MerchantRepair(MWBase::WindowManager &parWindowManager);
virtual void open();
void startRepair(const MWWorld::Ptr& actor);
private:
MyGUI::ScrollView* mList;
MyGUI::Button* mOkButton;
MyGUI::TextBox* mGoldLabel;
MWWorld::Ptr mActor;
protected:
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
void onRepairButtonClick(MyGUI::Widget* sender);
void onOkButtonClick(MyGUI::Widget* sender);
};
}
#endif

@ -16,6 +16,7 @@ namespace MWGui
GM_Scroll, // Read scroll GM_Scroll, // Read scroll
GM_Book, // Read book GM_Book, // Read book
GM_Alchemy, // Make potions GM_Alchemy, // Make potions
GM_Repair,
GM_Dialogue, // NPC interaction GM_Dialogue, // NPC interaction
GM_Barter, GM_Barter,
@ -26,6 +27,7 @@ namespace MWGui
GM_SpellCreation, GM_SpellCreation,
GM_Enchanting, GM_Enchanting,
GM_Training, GM_Training,
GM_MerchantRepair,
GM_Levelup, GM_Levelup,

@ -32,20 +32,9 @@ namespace MWGui
getWidget(mCancelButton, "CancelButton"); getWidget(mCancelButton, "CancelButton");
getWidget(mPlayerGold, "PlayerGold"); getWidget(mPlayerGold, "PlayerGold");
getWidget(mSelect, "Select");
getWidget(mSpells, "Spells");
getWidget(mSpellsView, "SpellsView"); getWidget(mSpellsView, "SpellsView");
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellBuyingWindow::onCancelButtonClicked); mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellBuyingWindow::onCancelButtonClicked);
mSpells->setCoord(450/2-mSpells->getTextSize().width/2,
mSpells->getTop(),
mSpells->getTextSize().width,
mSpells->getHeight());
mSelect->setCoord(8,
mSelect->getTop(),
mSelect->getTextSize().width,
mSelect->getHeight());
} }
void SpellBuyingWindow::addSpell(const std::string& spellId) void SpellBuyingWindow::addSpell(const std::string& spellId)

@ -28,8 +28,6 @@ namespace MWGui
protected: protected:
MyGUI::Button* mCancelButton; MyGUI::Button* mCancelButton;
MyGUI::TextBox* mPlayerGold; MyGUI::TextBox* mPlayerGold;
MyGUI::TextBox* mSpells;
MyGUI::TextBox* mSelect;
MyGUI::ScrollView* mSpellsView; MyGUI::ScrollView* mSpellsView;

@ -55,6 +55,7 @@
#include "exposedwindow.hpp" #include "exposedwindow.hpp"
#include "cursor.hpp" #include "cursor.hpp"
#include "spellicons.hpp" #include "spellicons.hpp"
#include "merchantrepair.hpp"
using namespace MWGui; using namespace MWGui;
@ -90,6 +91,7 @@ WindowManager::WindowManager(
, mSpellCreationDialog(NULL) , mSpellCreationDialog(NULL)
, mEnchantingDialog(NULL) , mEnchantingDialog(NULL)
, mTrainingWindow(NULL) , mTrainingWindow(NULL)
, mMerchantRepair(NULL)
, mPlayerName() , mPlayerName()
, mPlayerRaceId() , mPlayerRaceId()
, mPlayerAttributes() , mPlayerAttributes()
@ -180,6 +182,7 @@ WindowManager::WindowManager(
mSpellCreationDialog = new SpellCreationDialog(*this); mSpellCreationDialog = new SpellCreationDialog(*this);
mEnchantingDialog = new EnchantingDialog(*this); mEnchantingDialog = new EnchantingDialog(*this);
mTrainingWindow = new TrainingWindow(*this); mTrainingWindow = new TrainingWindow(*this);
mMerchantRepair = new MerchantRepair(*this);
mLoadingScreen = new LoadingScreen(mRendering->getScene (), mRendering->getWindow (), *this); mLoadingScreen = new LoadingScreen(mRendering->getScene (), mRendering->getWindow (), *this);
mLoadingScreen->onResChange (w,h); mLoadingScreen->onResChange (w,h);
@ -245,6 +248,7 @@ WindowManager::~WindowManager()
delete mTrainingWindow; delete mTrainingWindow;
delete mCountDialog; delete mCountDialog;
delete mQuickKeysMenu; delete mQuickKeysMenu;
delete mMerchantRepair;
delete mCursor; delete mCursor;
cleanupGarbage(); cleanupGarbage();
@ -303,6 +307,7 @@ void WindowManager::updateVisible()
mSpellCreationDialog->setVisible(false); mSpellCreationDialog->setVisible(false);
mEnchantingDialog->setVisible(false); mEnchantingDialog->setVisible(false);
mTrainingWindow->setVisible(false); mTrainingWindow->setVisible(false);
mMerchantRepair->setVisible(false);
mHud->setVisible(mHudEnabled); mHud->setVisible(mHudEnabled);
@ -428,6 +433,9 @@ void WindowManager::updateVisible()
case GM_Training: case GM_Training:
mTrainingWindow->setVisible(true); mTrainingWindow->setVisible(true);
break; break;
case GM_MerchantRepair:
mMerchantRepair->setVisible(true);
break;
case GM_InterMessageBox: case GM_InterMessageBox:
break; break;
case GM_Journal: case GM_Journal:
@ -1132,6 +1140,11 @@ void WindowManager::startTraining(MWWorld::Ptr actor)
mTrainingWindow->startTraining(actor); mTrainingWindow->startTraining(actor);
} }
void WindowManager::startRepair(MWWorld::Ptr actor)
{
mMerchantRepair->startRepair(actor);
}
const Translation::Storage& WindowManager::getTranslationDataStorage() const const Translation::Storage& WindowManager::getTranslationDataStorage() const
{ {
return mTranslationDataStorage; return mTranslationDataStorage;

@ -74,6 +74,7 @@ namespace MWGui
class TrainingWindow; class TrainingWindow;
class Cursor; class Cursor;
class SpellIcons; class SpellIcons;
class MerchantRepair;
class WindowManager : public MWBase::WindowManager class WindowManager : public MWBase::WindowManager
{ {
@ -229,6 +230,7 @@ namespace MWGui
virtual void startSpellMaking(MWWorld::Ptr actor); virtual void startSpellMaking(MWWorld::Ptr actor);
virtual void startEnchanting(MWWorld::Ptr actor); virtual void startEnchanting(MWWorld::Ptr actor);
virtual void startTraining(MWWorld::Ptr actor); virtual void startTraining(MWWorld::Ptr actor);
virtual void startRepair(MWWorld::Ptr actor);
virtual void changePointer (const std::string& name); virtual void changePointer (const std::string& name);
@ -266,6 +268,8 @@ namespace MWGui
SpellCreationDialog* mSpellCreationDialog; SpellCreationDialog* mSpellCreationDialog;
EnchantingDialog* mEnchantingDialog; EnchantingDialog* mEnchantingDialog;
TrainingWindow* mTrainingWindow; TrainingWindow* mTrainingWindow;
MerchantRepair* mMerchantRepair;
Translation::Storage& mTranslationDataStorage; Translation::Storage& mTranslationDataStorage;
Cursor* mCursor; Cursor* mCursor;

@ -62,13 +62,13 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::end()
bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2) bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2)
{ {
/// \todo add current weapon/armor health, remaining lockpick/repair uses, current enchantment charge here as soon as they are implemented /// \todo add current enchantment charge here when it is implemented
if ( ptr1.mCellRef->mRefID == ptr2.mCellRef->mRefID if ( ptr1.mCellRef->mRefID == ptr2.mCellRef->mRefID
&& MWWorld::Class::get(ptr1).getScript(ptr1) == "" // item with a script never stacks && MWWorld::Class::get(ptr1).getScript(ptr1) == "" // item with a script never stacks
&& MWWorld::Class::get(ptr1).getEnchantment(ptr1) == "" // item with enchantment never stacks (we could revisit this later, but for now it makes selecting items in the spell window much easier) && MWWorld::Class::get(ptr1).getEnchantment(ptr1) == "" // item with enchantment never stacks (we could revisit this later, but for now it makes selecting items in the spell window much easier)
&& ptr1.mCellRef->mOwner == ptr2.mCellRef->mOwner && ptr1.mCellRef->mOwner == ptr2.mCellRef->mOwner
&& ptr1.mCellRef->mSoul == ptr2.mCellRef->mSoul && ptr1.mCellRef->mSoul == ptr2.mCellRef->mSoul
&& ptr1.mCellRef->mCharge == ptr2.mCellRef->mCharge) && ptr1.mCellRef->mCharge == -1) // item that is already partly used up never stacks
return true; return true;
return false; return false;

@ -78,6 +78,7 @@ set(MYGUI_FILES
openmw_trainingwindow.layout openmw_trainingwindow.layout
openmw_travel_window.layout openmw_travel_window.layout
openmw_persuasion_dialog.layout openmw_persuasion_dialog.layout
openmw_merchantrepair.layout
smallbars.png smallbars.png
DejaVuLGCSansMono.ttf DejaVuLGCSansMono.ttf
markers.png markers.png

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 418 248" name="_Main">
<Property key="Visible" value="false"/>
<Widget type="TextBox" skin="SandText" position="8 18 418 24" align="Right Top">
<Property key="TextAlign" value="Left"/>
<Property key="Caption" value="#{sRepairServiceTitle}"/>
</Widget>
<Widget type="TextBox" skin="NormalText" position="0 0 418 24" align="Right Top">
<Property key="TextAlign" value="Center"/>
<Property key="Caption" value="#{sServiceRepairTitle}"/>
</Widget>
<Widget type="Widget" skin="MW_Box" position="10 46 389 156" align="Left Stretch">
<Widget type="ScrollView" skin="MW_ScrollView" position="4 4 381 147" align="Left Top Stretch" name="RepairView">
<Property key="CanvasAlign" value="Left"/>
</Widget>
</Widget>
<Widget type="TextBox" skin="SandText" position="10 210 300 24" name="PlayerGold" align="Right Top">
<Property key="TextAlign" value="Left"/>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" position="343 210 60 24" name="OkButton" align="Right Top">
<Property key="ExpandDirection" value="Left"/>
<Property key="Caption" value="#{sOK}"/>
</Widget>
</Widget>
</MyGUI>

@ -5,13 +5,13 @@
<Property key="Visible" value="false"/> <Property key="Visible" value="false"/>
<Widget type="TextBox" skin="SandText" position="8 10 24 24" name="Select" align="Right Top"> <Widget type="TextBox" skin="SandText" position="8 10 450 18" align="Right Top">
<Property key="TextAlign" value="Right"/> <Property key="TextAlign" value="Left"/>
<Property key="Caption" value="#{sSpellServiceTitle}"/> <Property key="Caption" value="#{sSpellServiceTitle}"/>
</Widget> </Widget>
<Widget type="TextBox" skin="SandText" position="0 0 24 24" name="Spells" align="Right Top"> <Widget type="TextBox" skin="NormalText" position="0 0 450 18" align="Right Top">
<Property key="TextAlign" value="Right"/> <Property key="TextAlign" value="Center"/>
<Property key="Caption" value="#D8C09A#{sSpells}"/> <Property key="Caption" value="#{sSpells}"/>
</Widget> </Widget>

Loading…
Cancel
Save