mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 06:23:53 +00:00
Merge remote-tracking branch 'scrawl/master'
This commit is contained in:
commit
8190fdb16c
21 changed files with 403 additions and 14 deletions
|
@ -38,6 +38,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
|
||||||
|
|
|
@ -59,6 +59,8 @@ namespace MWBase
|
||||||
/// \param paused In game type does not currently advance (this usually means some GUI
|
/// \param paused In game type does not currently advance (this usually means some GUI
|
||||||
/// component is up).
|
/// component is up).
|
||||||
|
|
||||||
|
virtual void advanceTime (float duration) = 0;
|
||||||
|
|
||||||
virtual void setPlayerName (const std::string& name) = 0;
|
virtual void setPlayerName (const std::string& name) = 0;
|
||||||
///< Set player name.
|
///< Set player name.
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -471,6 +471,9 @@ namespace MWClass
|
||||||
|
|
||||||
MWMechanics::CastSpell cast(ptr, victim);
|
MWMechanics::CastSpell cast(ptr, victim);
|
||||||
cast.cast(weapon);
|
cast.cast(weapon);
|
||||||
|
|
||||||
|
if (ptr.getRefData().getHandle() == "player")
|
||||||
|
skillUsageSucceeded (ptr, ESM::Skill::Enchant, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,6 +261,7 @@ namespace MWGui
|
||||||
: MWGui::WindowPinnableBase("openmw_map_window.layout")
|
: MWGui::WindowPinnableBase("openmw_map_window.layout")
|
||||||
, mGlobal(false)
|
, mGlobal(false)
|
||||||
, mGlobalMap(0)
|
, mGlobalMap(0)
|
||||||
|
, mGlobalMapRender(0)
|
||||||
{
|
{
|
||||||
setCoord(500,0,320,300);
|
setCoord(500,0,320,300);
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
||||||
|
|
196
apps/openmw/mwgui/recharge.cpp
Normal file
196
apps/openmw/mwgui/recharge.cpp
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
#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));
|
||||||
|
|
||||||
|
player.getClass().skillUsageSucceeded (player, ESM::Skill::Enchant, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
42
apps/openmw/mwgui/recharge.hpp
Normal file
42
apps/openmw/mwgui/recharge.hpp
Normal file
|
@ -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;
|
||||||
|
|
|
@ -199,7 +199,8 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
Stat<int> stat = creatureStats.getAttribute(i);
|
Stat<int> stat = creatureStats.getAttribute(i);
|
||||||
stat.setModifier(effects.get(EffectKey(ESM::MagicEffect::FortifyAttribute, i)).mMagnitude -
|
stat.setModifier(effects.get(EffectKey(ESM::MagicEffect::FortifyAttribute, i)).mMagnitude -
|
||||||
effects.get(EffectKey(ESM::MagicEffect::DrainAttribute, i)).mMagnitude);
|
effects.get(EffectKey(ESM::MagicEffect::DrainAttribute, i)).mMagnitude -
|
||||||
|
effects.get(EffectKey(ESM::MagicEffect::AbsorbAttribute, i)).mMagnitude);
|
||||||
|
|
||||||
creatureStats.setAttribute(i, stat);
|
creatureStats.setAttribute(i, stat);
|
||||||
}
|
}
|
||||||
|
@ -212,7 +213,8 @@ namespace MWMechanics
|
||||||
effects.get(EffectKey(ESM::MagicEffect::DrainHealth+i)).mMagnitude);
|
effects.get(EffectKey(ESM::MagicEffect::DrainHealth+i)).mMagnitude);
|
||||||
|
|
||||||
float currentDiff = creatureStats.getMagicEffects().get(EffectKey(ESM::MagicEffect::RestoreHealth+i)).mMagnitude
|
float currentDiff = creatureStats.getMagicEffects().get(EffectKey(ESM::MagicEffect::RestoreHealth+i)).mMagnitude
|
||||||
- creatureStats.getMagicEffects().get(EffectKey(ESM::MagicEffect::DamageHealth+i)).mMagnitude;
|
- creatureStats.getMagicEffects().get(EffectKey(ESM::MagicEffect::DamageHealth+i)).mMagnitude
|
||||||
|
- creatureStats.getMagicEffects().get(EffectKey(ESM::MagicEffect::AbsorbHealth)).mMagnitude;
|
||||||
stat.setCurrent(stat.getCurrent() + currentDiff * duration);
|
stat.setCurrent(stat.getCurrent() + currentDiff * duration);
|
||||||
|
|
||||||
creatureStats.setDynamic(i, stat);
|
creatureStats.setDynamic(i, stat);
|
||||||
|
@ -242,7 +244,8 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
Stat<float>& skill = npcStats.getSkill(i);
|
Stat<float>& skill = npcStats.getSkill(i);
|
||||||
skill.setModifier(effects.get(EffectKey(ESM::MagicEffect::FortifySkill, i)).mMagnitude -
|
skill.setModifier(effects.get(EffectKey(ESM::MagicEffect::FortifySkill, i)).mMagnitude -
|
||||||
effects.get(EffectKey(ESM::MagicEffect::DrainSkill, i)).mMagnitude);
|
effects.get(EffectKey(ESM::MagicEffect::DrainSkill, i)).mMagnitude -
|
||||||
|
effects.get(EffectKey(ESM::MagicEffect::AbsorbSkill, i)).mMagnitude);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace MWMechanics
|
||||||
if(getEnchantChance()<std::rand()/static_cast<double> (RAND_MAX)*100)
|
if(getEnchantChance()<std::rand()/static_cast<double> (RAND_MAX)*100)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MWWorld::Class::get (mEnchanter).skillUsageSucceeded (mEnchanter, ESM::Skill::Enchant, 1);
|
MWWorld::Class::get (mEnchanter).skillUsageSucceeded (mEnchanter, ESM::Skill::Enchant, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mCastStyle==ESM::Enchantment::ConstantEffect)
|
if(mCastStyle==ESM::Enchantment::ConstantEffect)
|
||||||
|
|
|
@ -213,6 +213,14 @@ namespace MWMechanics
|
||||||
mWatched = ptr;
|
mWatched = ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MechanicsManager::advanceTime (float duration)
|
||||||
|
{
|
||||||
|
// Uses ingame time, but scaled to real time
|
||||||
|
duration /= MWBase::Environment::get().getWorld()->getTimeScaleFactor();
|
||||||
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||||
|
player.getClass().getInventoryStore(player).rechargeItems(duration);
|
||||||
|
}
|
||||||
|
|
||||||
void MechanicsManager::update(float duration, bool paused)
|
void MechanicsManager::update(float duration, bool paused)
|
||||||
{
|
{
|
||||||
if(!mWatched.isEmpty())
|
if(!mWatched.isEmpty())
|
||||||
|
|
|
@ -64,6 +64,8 @@ namespace MWMechanics
|
||||||
/// \param paused In game type does not currently advance (this usually means some GUI
|
/// \param paused In game type does not currently advance (this usually means some GUI
|
||||||
/// component is up).
|
/// component is up).
|
||||||
|
|
||||||
|
virtual void advanceTime (float duration);
|
||||||
|
|
||||||
virtual void setPlayerName (const std::string& name);
|
virtual void setPlayerName (const std::string& name);
|
||||||
///< Set player name.
|
///< Set player name.
|
||||||
|
|
||||||
|
|
|
@ -95,18 +95,37 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try resisting
|
// Try resisting
|
||||||
if (magnitudeMult > 0 && caster.getClass().isActor())
|
if (magnitudeMult > 0 && target.getClass().isActor())
|
||||||
{
|
{
|
||||||
const ESM::Spell *spell =
|
const ESM::Spell *spell =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search (mId);
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().search (mId);
|
||||||
magnitudeMult = MWMechanics::getEffectMultiplier(effectIt->mEffectID, target, caster, spell);
|
|
||||||
if (magnitudeMult == 0)
|
if (spell->mData.mType == ESM::Spell::ST_Disease || spell->mData.mType == ESM::Spell::ST_Blight)
|
||||||
{
|
{
|
||||||
// Fully resisted, show message
|
float x = (spell->mData.mType == ESM::Spell::ST_Disease) ?
|
||||||
if (target.getRefData().getHandle() == "player")
|
target.getClass().getCreatureStats(target).getMagicEffects().get(ESM::MagicEffect::ResistCommonDisease).mMagnitude
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicPCResisted}");
|
: target.getClass().getCreatureStats(target).getMagicEffects().get(ESM::MagicEffect::ResistBlightDisease).mMagnitude;
|
||||||
else
|
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicTargetResisted}");
|
int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
|
||||||
|
if (roll <= x)
|
||||||
|
{
|
||||||
|
// Fully resisted, show message
|
||||||
|
if (target.getRefData().getHandle() == "player")
|
||||||
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicPCResisted}");
|
||||||
|
magnitudeMult = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
magnitudeMult = MWMechanics::getEffectMultiplier(effectIt->mEffectID, target, caster, spell);
|
||||||
|
if (magnitudeMult == 0)
|
||||||
|
{
|
||||||
|
// Fully resisted, show message
|
||||||
|
if (target.getRefData().getHandle() == "player")
|
||||||
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicPCResisted}");
|
||||||
|
else
|
||||||
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicTargetResisted}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,7 +135,7 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
float random = std::rand() / static_cast<float>(RAND_MAX);
|
float random = std::rand() / static_cast<float>(RAND_MAX);
|
||||||
float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * random;
|
float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * random;
|
||||||
magnitude *= magnitudeMult;
|
magnitude *= magnitudeMult;
|
||||||
|
|
||||||
if (target.getClass().isActor() && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration))
|
if (target.getClass().isActor() && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration))
|
||||||
{
|
{
|
||||||
|
@ -126,6 +145,20 @@ namespace MWMechanics
|
||||||
effect.mMagnitude = magnitude;
|
effect.mMagnitude = magnitude;
|
||||||
|
|
||||||
appliedLastingEffects.push_back(effect);
|
appliedLastingEffects.push_back(effect);
|
||||||
|
|
||||||
|
// For absorb effects, also apply the effect to the caster - but with a negative
|
||||||
|
// magnitude, since we're transfering stats from the target to the caster
|
||||||
|
for (int i=0; i<5; ++i)
|
||||||
|
{
|
||||||
|
if (effectIt->mEffectID == ESM::MagicEffect::AbsorbAttribute+i)
|
||||||
|
{
|
||||||
|
std::vector<ActiveSpells::Effect> effects;
|
||||||
|
ActiveSpells::Effect effect_ = effect;
|
||||||
|
effect_.mMagnitude *= -1;
|
||||||
|
effects.push_back(effect_);
|
||||||
|
caster.getClass().getCreatureStats(caster).getActiveSpells().addSpell("", true, effects, mSourceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
applyInstantEffect(mTarget, effectIt->mEffectID, magnitude);
|
applyInstantEffect(mTarget, effectIt->mEffectID, magnitude);
|
||||||
|
@ -289,6 +322,9 @@ namespace MWMechanics
|
||||||
MWBase::Environment::get().getWindowManager()->setSelectedEnchantItem(item); // Set again to show the modified charge
|
MWBase::Environment::get().getWindowManager()->setSelectedEnchantItem(item); // Set again to show the modified charge
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mCaster.getRefData().getHandle() == "player")
|
||||||
|
mCaster.getClass().skillUsageSucceeded (mCaster, ESM::Skill::Enchant, 1);
|
||||||
|
|
||||||
inflict(mCaster, mCaster, enchantment->mEffects, ESM::RT_Self);
|
inflict(mCaster, mCaster, enchantment->mEffects, ESM::RT_Self);
|
||||||
|
|
||||||
if (!mTarget.isEmpty())
|
if (!mTarget.isEmpty())
|
||||||
|
|
|
@ -88,6 +88,8 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::add(const Ptr& itemPtr,
|
||||||
autoEquip(actorPtr);
|
autoEquip(actorPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateRechargingItems();
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,6 +461,8 @@ int MWWorld::InventoryStore::remove(const Ptr& item, int count, const Ptr& actor
|
||||||
MWBase::Environment::get().getWindowManager()->unsetSelectedSpell();
|
MWBase::Environment::get().getWindowManager()->unsetSelectedSpell();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateRechargingItems();
|
||||||
|
|
||||||
return retCount;
|
return retCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,3 +581,35 @@ void MWWorld::InventoryStore::visitEffectSources(MWMechanics::EffectSourceVisito
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MWWorld::InventoryStore::updateRechargingItems()
|
||||||
|
{
|
||||||
|
mRechargingItems.clear();
|
||||||
|
for (ContainerStoreIterator it = begin(); it != end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->getClass().getEnchantment(*it) != "")
|
||||||
|
{
|
||||||
|
const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(
|
||||||
|
it->getClass().getEnchantment(*it));
|
||||||
|
if (enchantment->mData.mType == ESM::Enchantment::WhenUsed
|
||||||
|
|| enchantment->mData.mType == ESM::Enchantment::WhenStrikes)
|
||||||
|
mRechargingItems.push_back(std::make_pair(it, enchantment->mData.mCharge));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWWorld::InventoryStore::rechargeItems(float duration)
|
||||||
|
{
|
||||||
|
for (TRechargingItems::iterator it = mRechargingItems.begin(); it != mRechargingItems.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->first->getCellRef().mEnchantmentCharge == -1
|
||||||
|
|| it->first->getCellRef().mEnchantmentCharge == it->second)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
static float fMagicItemRechargePerSecond = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
||||||
|
"fMagicItemRechargePerSecond")->getFloat();
|
||||||
|
|
||||||
|
it->first->getCellRef().mEnchantmentCharge = std::min (it->first->getCellRef().mEnchantmentCharge + fMagicItemRechargePerSecond * duration,
|
||||||
|
it->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -92,11 +92,16 @@ namespace MWWorld
|
||||||
// selected magic item (for using enchantments of type "Cast once" or "Cast when used")
|
// selected magic item (for using enchantments of type "Cast once" or "Cast when used")
|
||||||
ContainerStoreIterator mSelectedEnchantItem;
|
ContainerStoreIterator mSelectedEnchantItem;
|
||||||
|
|
||||||
|
// (item, max charge)
|
||||||
|
typedef std::vector<std::pair<ContainerStoreIterator, float> > TRechargingItems;
|
||||||
|
TRechargingItems mRechargingItems;
|
||||||
|
|
||||||
void copySlots (const InventoryStore& store);
|
void copySlots (const InventoryStore& store);
|
||||||
|
|
||||||
void initSlots (TSlots& slots_);
|
void initSlots (TSlots& slots_);
|
||||||
|
|
||||||
void updateMagicEffects(const Ptr& actor);
|
void updateMagicEffects(const Ptr& actor);
|
||||||
|
void updateRechargingItems();
|
||||||
|
|
||||||
void fireEquipmentChangedEvent();
|
void fireEquipmentChangedEvent();
|
||||||
|
|
||||||
|
@ -172,6 +177,9 @@ namespace MWWorld
|
||||||
///< Set a listener for various events, see \a InventoryStoreListener
|
///< Set a listener for various events, see \a InventoryStoreListener
|
||||||
|
|
||||||
void visitEffectSources (MWMechanics::EffectSourceVisitor& visitor);
|
void visitEffectSources (MWMechanics::EffectSourceVisitor& visitor);
|
||||||
|
|
||||||
|
void rechargeItems (float duration);
|
||||||
|
/// Restore charge on enchanted items. Note this should only be done for the player.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -607,6 +607,8 @@ namespace MWWorld
|
||||||
|
|
||||||
void World::advanceTime (double hours)
|
void World::advanceTime (double hours)
|
||||||
{
|
{
|
||||||
|
MWBase::Environment::get().getMechanicsManager()->advanceTime(hours*3600);
|
||||||
|
|
||||||
mWeatherManager->advanceTime (hours);
|
mWeatherManager->advanceTime (hours);
|
||||||
|
|
||||||
hours += mGlobalVariables->getFloat ("gamehour");
|
hours += mGlobalVariables->getFloat ("gamehour");
|
||||||
|
|
|
@ -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
|
||||||
|
|
29
files/mygui/openmw_recharge_dialog.layout
Normal file
29
files/mygui/openmw_recharge_dialog.layout
Normal file
|
@ -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…
Reference in a new issue