1
0
Fork 0
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:
Marc Zinnschlag 2013-11-19 16:56:18 +01:00
commit 8190fdb16c
21 changed files with 403 additions and 14 deletions

View file

@ -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

View file

@ -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.

View file

@ -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;

View file

@ -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);
} }
} }
} }

View file

@ -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);

View file

@ -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,

View 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));
}
}

View 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

View file

@ -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
{ {

View file

@ -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);
}
} }

View file

@ -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;

View file

@ -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);
} }
} }

View file

@ -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)

View file

@ -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())

View file

@ -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.

View file

@ -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())

View file

@ -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);
}
}

View file

@ -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.
}; };
} }

View file

@ -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");

View file

@ -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

View 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>