Implement magic item recharging via soulgem use

actorid
scrawl 11 years ago
parent 16e5477c60
commit cab535dd69

@ -36,6 +36,7 @@ add_openmw_dir (mwgui
merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers savegamedialog tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers savegamedialog
recharge
) )
add_openmw_dir (mwdialogue add_openmw_dir (mwdialogue

@ -265,6 +265,7 @@ namespace MWBase
virtual void showCompanionWindow(MWWorld::Ptr actor) = 0; virtual void showCompanionWindow(MWWorld::Ptr actor) = 0;
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 startRecharge(MWWorld::Ptr soulgem) = 0;
virtual void startSelfEnchanting(MWWorld::Ptr soulgem) = 0; virtual void startSelfEnchanting(MWWorld::Ptr soulgem) = 0;
virtual void startTraining(MWWorld::Ptr actor) = 0; virtual void startTraining(MWWorld::Ptr actor) = 0;
virtual void startRepair(MWWorld::Ptr actor) = 0; virtual void startRepair(MWWorld::Ptr actor) = 0;

@ -28,6 +28,7 @@ namespace MWGui
GM_Travel, GM_Travel,
GM_SpellCreation, GM_SpellCreation,
GM_Enchanting, GM_Enchanting,
GM_Recharge,
GM_Training, GM_Training,
GM_MerchantRepair, GM_MerchantRepair,

@ -0,0 +1,194 @@
#include "recharge.hpp"
#include <boost/lexical_cast.hpp>
#include <boost/format.hpp>
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/class.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "widgets.hpp"
namespace MWGui
{
Recharge::Recharge()
: WindowBase("openmw_recharge_dialog.layout")
{
getWidget(mBox, "Box");
getWidget(mView, "View");
getWidget(mGemBox, "GemBox");
getWidget(mGemIcon, "GemIcon");
getWidget(mChargeLabel, "ChargeLabel");
getWidget(mCancelButton, "CancelButton");
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &Recharge::onCancel);
setVisible(false);
}
void Recharge::open()
{
center();
}
void Recharge::start (const MWWorld::Ptr &item)
{
std::string path = std::string("icons\\");
path += MWWorld::Class::get(item).getInventoryIcon(item);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
mGemIcon->setImageTexture (path);
mGemIcon->setUserString("ToolTipType", "ItemPtr");
mGemIcon->setUserData(item);
updateView();
}
void Recharge::updateView()
{
MWWorld::Ptr gem = *mGemIcon->getUserData<MWWorld::Ptr>();
std::string soul = gem.getCellRef().mSoul;
const ESM::Creature *creature = MWBase::Environment::get().getWorld()->getStore().get<ESM::Creature>().find(soul);
mChargeLabel->setCaptionWithReplacing("#{sCharges} " + boost::lexical_cast<std::string>(creature->mData.mSoul));
bool toolBoxVisible = (gem.getRefData().getCount() != 0);
mGemBox->setVisible(toolBoxVisible);
bool toolBoxWasVisible = (mBox->getPosition().top != mGemBox->getPosition().top);
if (toolBoxVisible && !toolBoxWasVisible)
{
// shrink
mBox->setPosition(mBox->getPosition() + MyGUI::IntPoint(0, mGemBox->getSize().height));
mBox->setSize(mBox->getSize() - MyGUI::IntSize(0,mGemBox->getSize().height));
}
else if (!toolBoxVisible && toolBoxWasVisible)
{
// expand
mBox->setPosition(MyGUI::IntPoint (mBox->getPosition().left, mGemBox->getPosition().top));
mBox->setSize(mBox->getSize() + MyGUI::IntSize(0,mGemBox->getSize().height));
}
while (mView->getChildCount())
MyGUI::Gui::getInstance().destroyWidget(mView->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)
{
std::string enchantmentName = iter->getClass().getEnchantment(*iter);
if (enchantmentName.empty())
continue;
const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(enchantmentName);
if (iter->getCellRef().mEnchantmentCharge >= enchantment->mData.mCharge
|| iter->getCellRef().mEnchantmentCharge == -1)
continue;
MyGUI::TextBox* text = mView->createWidget<MyGUI::TextBox> (
"SandText", MyGUI::IntCoord(8, currentY, mView->getWidth()-8, 18), MyGUI::Align::Default);
text->setCaption(MWWorld::Class::get(*iter).getName(*iter));
text->setNeedMouseFocus(false);
currentY += 19;
MyGUI::ImageBox* icon = mView->createWidget<MyGUI::ImageBox> (
"ImageBox", MyGUI::IntCoord(16, currentY, 32, 32), MyGUI::Align::Default);
std::string path = std::string("icons\\");
path += MWWorld::Class::get(*iter).getInventoryIcon(*iter);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
icon->setImageTexture (path);
icon->setUserString("ToolTipType", "ItemPtr");
icon->setUserData(*iter);
icon->eventMouseButtonClick += MyGUI::newDelegate(this, &Recharge::onItemClicked);
icon->eventMouseWheel += MyGUI::newDelegate(this, &Recharge::onMouseWheel);
Widgets::MWDynamicStatPtr chargeWidget = mView->createWidget<Widgets::MWDynamicStat>
("MW_ChargeBar", MyGUI::IntCoord(72, currentY+2, 199, 20), MyGUI::Align::Default);
chargeWidget->setValue(iter->getCellRef().mEnchantmentCharge, enchantment->mData.mCharge);
chargeWidget->setNeedMouseFocus(false);
currentY += 32 + 4;
}
mView->setCanvasSize (MyGUI::IntSize(mView->getWidth(), std::max(mView->getHeight(), currentY)));
}
void Recharge::onCancel(MyGUI::Widget *sender)
{
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Recharge);
}
void Recharge::onItemClicked(MyGUI::Widget *sender)
{
MWWorld::Ptr gem = *mGemIcon->getUserData<MWWorld::Ptr>();
if (!gem.getRefData().getCount())
return;
MWWorld::Ptr item = *sender->getUserData<MWWorld::Ptr>();
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
MWMechanics::NpcStats& npcStats = player.getClass().getNpcStats(player);
float luckTerm = 0.1 * stats.getAttribute(ESM::Attribute::Luck).getModified();
if (luckTerm < 1|| luckTerm > 10)
luckTerm = 1;
float intelligenceTerm = 0.2 * stats.getAttribute(ESM::Attribute::Intelligence).getModified();
if (intelligenceTerm > 20)
intelligenceTerm = 20;
if (intelligenceTerm < 1)
intelligenceTerm = 1;
float x = (npcStats.getSkill(ESM::Skill::Enchant).getModified() + intelligenceTerm + luckTerm) * stats.getFatigueTerm();
int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
if (roll < x)
{
std::string soul = gem.getCellRef().mSoul;
const ESM::Creature *creature = MWBase::Environment::get().getWorld()->getStore().get<ESM::Creature>().find(soul);
float restored = creature->mData.mSoul * (roll / x);
const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(
item.getClass().getEnchantment(item));
item.getCellRef().mEnchantmentCharge =
std::min(item.getCellRef().mEnchantmentCharge + restored, static_cast<float>(enchantment->mData.mCharge));
}
gem.getContainerStore()->remove(gem, 1, player);
if (gem.getRefData().getCount() == 0)
{
std::string message = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage51")->getString();
message = boost::str(boost::format(message) % gem.getClass().getName(gem));
MWBase::Environment::get().getWindowManager()->messageBox(message);
}
updateView();
}
void Recharge::onMouseWheel(MyGUI::Widget* _sender, int _rel)
{
if (mView->getViewOffset().top + _rel*0.3 > 0)
mView->setViewOffset(MyGUI::IntPoint(0, 0));
else
mView->setViewOffset(MyGUI::IntPoint(0, mView->getViewOffset().top + _rel*0.3));
}
}

@ -0,0 +1,42 @@
#ifndef OPENMW_MWGUI_RECHARGE_H
#define OPENMW_MWGUI_RECHARGE_H
#include "windowbase.hpp"
#include "../mwworld/ptr.hpp"
namespace MWGui
{
class Recharge : public WindowBase
{
public:
Recharge();
virtual void open();
void start (const MWWorld::Ptr& gem);
protected:
MyGUI::Widget* mBox;
MyGUI::ScrollView* mView;
MyGUI::Widget* mGemBox;
MyGUI::ImageBox* mGemIcon;
MyGUI::TextBox* mChargeLabel;
MyGUI::Button* mCancelButton;
void updateView();
void onItemClicked (MyGUI::Widget* sender);
void onCancel (MyGUI::Widget* sender);
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
};
}
#endif

@ -21,7 +21,8 @@ namespace MWGui
{ {
if (button == 0) if (button == 0)
{ {
/// \todo show recharge enchanted item dialog here MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Recharge);
MWBase::Environment::get().getWindowManager()->startRecharge(mSoulgem);
} }
else else
{ {

@ -43,6 +43,7 @@
#include "waitdialog.hpp" #include "waitdialog.hpp"
#include "enchantingdialog.hpp" #include "enchantingdialog.hpp"
#include "trainingwindow.hpp" #include "trainingwindow.hpp"
#include "recharge.hpp"
#include "exposedwindow.hpp" #include "exposedwindow.hpp"
#include "cursor.hpp" #include "cursor.hpp"
#include "merchantrepair.hpp" #include "merchantrepair.hpp"
@ -95,6 +96,7 @@ namespace MWGui
, mTrainingWindow(NULL) , mTrainingWindow(NULL)
, mMerchantRepair(NULL) , mMerchantRepair(NULL)
, mSoulgemDialog(NULL) , mSoulgemDialog(NULL)
, mRecharge(NULL)
, mRepair(NULL) , mRepair(NULL)
, mCompanionWindow(NULL) , mCompanionWindow(NULL)
, mTranslationDataStorage (translationDataStorage) , mTranslationDataStorage (translationDataStorage)
@ -197,6 +199,7 @@ namespace MWGui
mDragAndDrop->mDraggedWidget = 0; mDragAndDrop->mDraggedWidget = 0;
mDragAndDrop->mDragAndDropWidget = dragAndDropWidget; mDragAndDrop->mDragAndDropWidget = dragAndDropWidget;
mRecharge = new Recharge();
mMenu = new MainMenu(w,h); mMenu = new MainMenu(w,h);
mMap = new MapWindow(""); mMap = new MapWindow("");
mStatsWindow = new StatsWindow(); mStatsWindow = new StatsWindow();
@ -312,6 +315,7 @@ namespace MWGui
delete mSoulgemDialog; delete mSoulgemDialog;
delete mSoftwareCursor; delete mSoftwareCursor;
delete mCursorManager; delete mCursorManager;
delete mRecharge;
cleanupGarbage(); cleanupGarbage();
@ -375,6 +379,7 @@ namespace MWGui
mRepair->setVisible(false); mRepair->setVisible(false);
mCompanionWindow->setVisible(false); mCompanionWindow->setVisible(false);
mInventoryWindow->setTrading(false); mInventoryWindow->setTrading(false);
mRecharge->setVisible(false);
mHud->setVisible(mHudEnabled); mHud->setVisible(mHudEnabled);
@ -492,6 +497,9 @@ namespace MWGui
case GM_SpellCreation: case GM_SpellCreation:
mSpellCreationDialog->setVisible(true); mSpellCreationDialog->setVisible(true);
break; break;
case GM_Recharge:
mRecharge->setVisible(true);
break;
case GM_Enchanting: case GM_Enchanting:
mEnchantingDialog->setVisible(true); mEnchantingDialog->setVisible(true);
break; break;
@ -1363,4 +1371,9 @@ namespace MWGui
return mLoadingScreen; return mLoadingScreen;
} }
void WindowManager::startRecharge(MWWorld::Ptr soulgem)
{
mRecharge->start(soulgem);
}
} }

@ -77,6 +77,7 @@ namespace MWGui
class MerchantRepair; class MerchantRepair;
class Repair; class Repair;
class SoulgemDialog; class SoulgemDialog;
class Recharge;
class CompanionWindow; class CompanionWindow;
class WindowManager : public MWBase::WindowManager class WindowManager : public MWBase::WindowManager
@ -263,6 +264,7 @@ namespace MWGui
virtual void startTraining(MWWorld::Ptr actor); virtual void startTraining(MWWorld::Ptr actor);
virtual void startRepair(MWWorld::Ptr actor); virtual void startRepair(MWWorld::Ptr actor);
virtual void startRepairItem(MWWorld::Ptr item); virtual void startRepairItem(MWWorld::Ptr item);
virtual void startRecharge(MWWorld::Ptr soulgem);
virtual void frameStarted(float dt); virtual void frameStarted(float dt);
@ -313,6 +315,7 @@ namespace MWGui
MerchantRepair* mMerchantRepair; MerchantRepair* mMerchantRepair;
SoulgemDialog* mSoulgemDialog; SoulgemDialog* mSoulgemDialog;
Repair* mRepair; Repair* mRepair;
Recharge* mRecharge;
CompanionWindow* mCompanionWindow; CompanionWindow* mCompanionWindow;
Translation::Storage& mTranslationDataStorage; Translation::Storage& mTranslationDataStorage;

@ -81,6 +81,7 @@ set(MYGUI_FILES
openmw_repair.layout openmw_repair.layout
openmw_companion_window.layout openmw_companion_window.layout
openmw_savegame_dialog.layout openmw_savegame_dialog.layout
openmw_recharge_dialog.layout
smallbars.png smallbars.png
DejaVuLGCSansMono.ttf DejaVuLGCSansMono.ttf
markers.png markers.png

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 329 253" name="_Main">
<Widget type="Widget" skin="" position="4 4 321 42" name="GemBox">
<Widget type="ImageBox" skin="ImageBox" position="5 6 32 32" name="GemIcon"/>
<Widget type="TextBox" skin="SandText" position="55 13 250 18" name="ChargeLabel">
<Property key="Caption" value="#{sQuality}"/>
<Property key="TextAlign" value="Right"/>
</Widget>
</Widget>
<Widget type="Widget" skin="MW_Box" position="6 46 309 160" align="Left Stretch" name="Box">
<Widget type="ScrollView" skin="MW_ScrollView" position="4 4 301 152" align="Left Top Stretch" name="View">
<Property key="CanvasAlign" value="Left"/>
</Widget>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" position="239 214 75 24" name="CancelButton">
<Property key="ExpandDirection" value="Left"/>
<Property key="Caption" value="#{sCancel}"/>
</Widget>
</Widget>
</MyGUI>
Loading…
Cancel
Save