Enchanting system

This commit is contained in:
Glorf 2013-03-28 17:41:00 +01:00
parent c0b0227e8a
commit 6643fe789c
20 changed files with 482 additions and 36 deletions

View file

@ -64,7 +64,7 @@ add_openmw_dir (mwclass
add_openmw_dir (mwmechanics add_openmw_dir (mwmechanics
mechanicsmanagerimp stat character creaturestats magiceffects movement actors activators mechanicsmanagerimp stat character creaturestats magiceffects movement actors activators
drawstate spells activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow drawstate spells activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow
aiescort aiactivate aiescort aiactivate enchanting
) )
add_openmw_dir (mwbase add_openmw_dir (mwbase

View file

@ -243,27 +243,44 @@ namespace MWBase
///< Toggle a render mode. ///< Toggle a render mode.
///< \return Resulting mode ///< \return Resulting mode
virtual const ESM::Potion *createRecord (const ESM::Potion& record) virtual const ESM::Potion *createRecord (const ESM::Potion& record) = 0;
= 0; ///< Create a new record (of type potion) in the ESM store.
///< Create a new recrod (of type potion) in the ESM store.
/// \return pointer to created record /// \return pointer to created record
virtual const ESM::Spell *createRecord (const ESM::Spell& record) virtual const ESM::Spell *createRecord (const ESM::Spell& record) = 0;
= 0; ///< Create a new record (of type spell) in the ESM store.
///< Create a new recrod (of type spell) in the ESM store.
/// \return pointer to created record /// \return pointer to created record
virtual const ESM::Class *createRecord (const ESM::Class& record) virtual const ESM::Class *createRecord (const ESM::Class& record) = 0;
= 0; ///< Create a new record (of type class) in the ESM store.
///< Create a new recrod (of type class) in the ESM store.
/// \return pointer to created record /// \return pointer to created record
virtual const ESM::Cell *createRecord (const ESM::Cell& record) = 0; virtual const ESM::Cell *createRecord (const ESM::Cell& record) = 0;
///< Create a new recrod (of type cell) in the ESM store. ///< Create a new record (of type cell) in the ESM store.
/// \return pointer to created record /// \return pointer to created record
virtual const ESM::NPC *createRecord(const ESM::NPC &record) = 0; virtual const ESM::NPC *createRecord(const ESM::NPC &record) = 0;
///< Create a new recrod (of type npc) in the ESM store. ///< Create a new record (of type npc) in the ESM store.
/// \return pointer to created record
virtual const ESM::Armor *createRecord (const ESM::Armor& record) = 0;
///< Create a new record (of type armor) in the ESM store.
/// \return pointer to created record
virtual const ESM::Weapon *createRecord (const ESM::Weapon& record) = 0;
///< Create a new record (of type weapon) in the ESM store.
/// \return pointer to created record
virtual const ESM::Clothing *createRecord (const ESM::Clothing& record) = 0;
///< Create a new record (of type clothing) in the ESM store.
/// \return pointer to created record
virtual const ESM::Enchantment *createRecord (const ESM::Enchantment& record) = 0;
///< Create a new record (of type enchantment) in the ESM store.
/// \return pointer to created record
virtual const ESM::Book *createRecord (const ESM::Book& record) = 0;
///< Create a new record (of type book) in the ESM store.
/// \return pointer to created record /// \return pointer to created record
virtual void update (float duration, bool paused) = 0; virtual void update (float duration, bool paused) = 0;

View file

@ -16,6 +16,7 @@
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
#include "../mwworld/physicssystem.hpp" #include "../mwworld/physicssystem.hpp"
#include "../mwworld/nullaction.hpp" #include "../mwworld/nullaction.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwrender/objects.hpp" #include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp" #include "../mwrender/renderinginterface.hpp"
@ -273,6 +274,20 @@ namespace MWClass
return ref->mBase->mEnchant; return ref->mBase->mEnchant;
} }
MWWorld::Ptr Armor::applyEnchantment(const MWWorld::Ptr &ptr, std::string enchId, int enchCharge, std::string newName) const
{
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
ESM::Armor oldItem = *store.get<ESM::Armor>().find(ptr.getCellRef().mRefID);
ESM::Armor newItem = oldItem;
newItem.mId="";
newItem.mName=newName;
newItem.mData.mEnchant=enchCharge;
newItem.mEnchant=enchId;
const ESM::Armor *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), record->mId);
return ref.getPtr();
}
boost::shared_ptr<MWWorld::Action> Armor::use (const MWWorld::Ptr& ptr) const boost::shared_ptr<MWWorld::Action> Armor::use (const MWWorld::Ptr& ptr) const
{ {
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr)); boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr));

View file

@ -65,6 +65,8 @@ namespace MWClass
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @return the enchantment ID if the object is enchanted, otherwise an empty string
virtual MWWorld::Ptr applyEnchantment(const MWWorld::Ptr &ptr, std::string enchId, int enchCharge, std::string newName) const;
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
const; const;
///< Generate action for using via inventory menu ///< Generate action for using via inventory menu

View file

@ -11,6 +11,7 @@
#include "../mwworld/actionread.hpp" #include "../mwworld/actionread.hpp"
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
#include "../mwworld/physicssystem.hpp" #include "../mwworld/physicssystem.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwrender/objects.hpp" #include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp" #include "../mwrender/renderinginterface.hpp"
@ -147,6 +148,21 @@ namespace MWClass
return ref->mBase->mEnchant; return ref->mBase->mEnchant;
} }
MWWorld::Ptr Book::applyEnchantment(const MWWorld::Ptr &ptr, std::string enchId, int enchCharge, std::string newName) const
{
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
ESM::Book oldItem = *store.get<ESM::Book>().find(ptr.getCellRef().mRefID);
ESM::Book newItem = oldItem;
newItem.mId="";
newItem.mName=newName;
newItem.mData.mIsScroll = 1;
newItem.mData.mEnchant=enchCharge;
newItem.mEnchant=enchId;
const ESM::Book *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), record->mId);
return ref.getPtr();
}
boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const
{ {
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionRead(ptr)); return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionRead(ptr));
@ -160,4 +176,12 @@ namespace MWClass
return MWWorld::Ptr(&cell.mBooks.insert(*ref), &cell); return MWWorld::Ptr(&cell.mBooks.insert(*ref), &cell);
} }
short Book::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
return ref->mBase->mData.mEnchant;
}
} }

View file

@ -51,10 +51,14 @@ namespace MWClass
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @return the enchantment ID if the object is enchanted, otherwise an empty string
virtual MWWorld::Ptr applyEnchantment(const MWWorld::Ptr &ptr, std::string enchId, int enchCharge, std::string newName) const;
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) const; virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) const;
///< Generate action for using via inventory menu ///< Generate action for using via inventory menu
virtual std::string getModel(const MWWorld::Ptr &ptr) const; virtual std::string getModel(const MWWorld::Ptr &ptr) const;
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
}; };
} }

View file

@ -14,6 +14,7 @@
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
#include "../mwworld/physicssystem.hpp" #include "../mwworld/physicssystem.hpp"
#include "../mwworld/nullaction.hpp" #include "../mwworld/nullaction.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwgui/tooltips.hpp" #include "../mwgui/tooltips.hpp"
@ -221,6 +222,20 @@ namespace MWClass
return ref->mBase->mEnchant; return ref->mBase->mEnchant;
} }
MWWorld::Ptr Clothing::applyEnchantment(const MWWorld::Ptr &ptr, std::string enchId, int enchCharge, std::string newName) const
{
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
ESM::Clothing oldItem = *store.get<ESM::Clothing>().find(ptr.getCellRef().mRefID);
ESM::Clothing newItem = oldItem;
newItem.mId="";
newItem.mName=newName;
newItem.mData.mEnchant=enchCharge;
newItem.mEnchant=enchId;
const ESM::Clothing *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), record->mId);
return ref.getPtr();
}
boost::shared_ptr<MWWorld::Action> Clothing::use (const MWWorld::Ptr& ptr) const boost::shared_ptr<MWWorld::Action> Clothing::use (const MWWorld::Ptr& ptr) const
{ {
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr)); boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr));

View file

@ -59,6 +59,8 @@ namespace MWClass
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @return the enchantment ID if the object is enchanted, otherwise an empty string
virtual MWWorld::Ptr applyEnchantment(const MWWorld::Ptr &ptr, std::string enchId, int enchCharge, std::string newName) const;
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
const; const;
///< Generate action for using via inventory menu ///< Generate action for using via inventory menu

View file

@ -14,6 +14,7 @@
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
#include "../mwworld/physicssystem.hpp" #include "../mwworld/physicssystem.hpp"
#include "../mwworld/nullaction.hpp" #include "../mwworld/nullaction.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwgui/tooltips.hpp" #include "../mwgui/tooltips.hpp"
@ -361,6 +362,20 @@ namespace MWClass
return ref->mBase->mEnchant; return ref->mBase->mEnchant;
} }
MWWorld::Ptr Weapon::applyEnchantment(const MWWorld::Ptr &ptr, std::string enchId, int enchCharge, std::string newName) const
{
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
ESM::Weapon oldItem = *store.get<ESM::Weapon>().find(ptr.getCellRef().mRefID);
ESM::Weapon newItem = oldItem;
newItem.mId="";
newItem.mName=newName;
newItem.mData.mEnchant=enchCharge;
newItem.mEnchant=enchId;
const ESM::Weapon *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), record->mId);
return ref.getPtr();
}
boost::shared_ptr<MWWorld::Action> Weapon::use (const MWWorld::Ptr& ptr) const boost::shared_ptr<MWWorld::Action> Weapon::use (const MWWorld::Ptr& ptr) const
{ {
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr)); boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr));

View file

@ -65,6 +65,8 @@ namespace MWClass
virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const; virtual std::string getEnchantment (const MWWorld::Ptr& ptr) const;
///< @return the enchantment ID if the object is enchanted, otherwise an empty string ///< @return the enchantment ID if the object is enchanted, otherwise an empty string
virtual MWWorld::Ptr applyEnchantment(const MWWorld::Ptr &ptr, std::string enchId, int enchCharge, std::string newName) const;
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr) virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
const; const;
///< Generate action for using via inventory menu ///< Generate action for using via inventory menu

View file

@ -5,9 +5,11 @@
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwworld/manualref.hpp"
#include "itemselection.hpp" #include "itemselection.hpp"
#include "container.hpp" #include "container.hpp"
#include "inventorywindow.hpp"
namespace MWGui namespace MWGui
{ {
@ -17,8 +19,9 @@ namespace MWGui
: WindowBase("openmw_enchanting_dialog.layout", parWindowManager) : WindowBase("openmw_enchanting_dialog.layout", parWindowManager)
, EffectEditorBase(parWindowManager) , EffectEditorBase(parWindowManager)
, mItemSelectionDialog(NULL) , mItemSelectionDialog(NULL)
, mCurrentEnchantmentPoints(0) , mEnchanting(MWBase::Environment::get().getWorld()->getPlayer().getPlayer())
{ {
getWidget(mName, "NameEdit");
getWidget(mCancelButton, "CancelButton"); getWidget(mCancelButton, "CancelButton");
getWidget(mAvailableEffectsList, "AvailableEffects"); getWidget(mAvailableEffectsList, "AvailableEffects");
getWidget(mUsedEffectsView, "UsedEffects"); getWidget(mUsedEffectsView, "UsedEffects");
@ -36,6 +39,8 @@ namespace MWGui
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onCancelButtonClicked); mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onCancelButtonClicked);
mItemBox->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onSelectItem); mItemBox->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onSelectItem);
mSoulBox->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onSelectSoul); mSoulBox->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onSelectSoul);
mBuyButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onBuyButtonClicked);
mTypeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onTypeButtonClicked);
} }
EnchantingDialog::~EnchantingDialog() EnchantingDialog::~EnchantingDialog()
@ -52,9 +57,32 @@ namespace MWGui
void EnchantingDialog::updateLabels() void EnchantingDialog::updateLabels()
{ {
mEnchantmentPoints->setCaption(boost::lexical_cast<std::string>(mCurrentEnchantmentPoints) mEnchantmentPoints->setCaption(boost::lexical_cast<std::string>(mEnchanting.getEnchantCost())
+ " / " + (mItem.isEmpty() ? "0" : boost::lexical_cast<std::string>( + " / " + boost::lexical_cast<std::string>(mEnchanting.getMaxEnchantValue()));
MWWorld::Class::get(mItem).getEnchantmentPoints(mItem))));
mCharge->setCaption(boost::lexical_cast<std::string>(mEnchanting.getGemCharge()));
mCastCost->setCaption(boost::lexical_cast<std::string>(mEnchanting.getEnchantCost()));
switch(mEnchanting.getEnchantType())
{
case 0:
mTypeButton->setCaption(mWindowManager.getGameSettingString("sItemCastOnce","Cast Once"));
mAddEffectDialog.constantEffect=false;
break;
case 1:
mTypeButton->setCaption(mWindowManager.getGameSettingString("sItemCastWhenStrikes", "When Strikes"));
mAddEffectDialog.constantEffect=false;
break;
case 2:
mTypeButton->setCaption(mWindowManager.getGameSettingString("sItemCastWhenUsed", "When Used"));
mAddEffectDialog.constantEffect=false;
break;
case 3:
mTypeButton->setCaption(mWindowManager.getGameSettingString("sItemCastConstant", "Cast Constant"));
mAddEffectDialog.constantEffect=true;
break;
}
} }
void EnchantingDialog::startEnchanting (MWWorld::Ptr actor) void EnchantingDialog::startEnchanting (MWWorld::Ptr actor)
@ -105,7 +133,8 @@ namespace MWGui
image->setUserData(item); image->setUserData(item);
image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveItem); image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveItem);
mItem = item; mEnchanting.setOldItem(item);
mEnchanting.nextEnchantType();
updateLabels(); updateLabels();
} }
@ -113,7 +142,7 @@ namespace MWGui
{ {
while (mItemBox->getChildCount ()) while (mItemBox->getChildCount ())
MyGUI::Gui::getInstance ().destroyWidget (mItemBox->getChildAt(0)); MyGUI::Gui::getInstance ().destroyWidget (mItemBox->getChildAt(0));
mItem = MWWorld::Ptr(); mEnchanting.setOldItem(MWWorld::Ptr());
updateLabels(); updateLabels();
} }
@ -125,6 +154,13 @@ namespace MWGui
void EnchantingDialog::onSoulSelected(MWWorld::Ptr item) void EnchantingDialog::onSoulSelected(MWWorld::Ptr item)
{ {
mItemSelectionDialog->setVisible(false); mItemSelectionDialog->setVisible(false);
mEnchanting.setSoulGem(item);
if(mEnchanting.getGemCharge()==0)
{
mWindowManager.messageBox ("#{sNotifyMessage32}", std::vector<std::string>());
return;
}
while (mSoulBox->getChildCount ()) while (mSoulBox->getChildCount ())
MyGUI::Gui::getInstance ().destroyWidget (mSoulBox->getChildAt(0)); MyGUI::Gui::getInstance ().destroyWidget (mSoulBox->getChildAt(0));
@ -139,8 +175,6 @@ namespace MWGui
image->setUserString ("ToolTipType", "ItemPtr"); image->setUserString ("ToolTipType", "ItemPtr");
image->setUserData(item); image->setUserData(item);
image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveSoul); image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveSoul);
mSoul = item;
updateLabels(); updateLabels();
} }
@ -148,7 +182,7 @@ namespace MWGui
{ {
while (mSoulBox->getChildCount ()) while (mSoulBox->getChildCount ())
MyGUI::Gui::getInstance ().destroyWidget (mSoulBox->getChildAt(0)); MyGUI::Gui::getInstance ().destroyWidget (mSoulBox->getChildAt(0));
mSoul = MWWorld::Ptr(); mEnchanting.setSoulGem(MWWorld::Ptr());
updateLabels(); updateLabels();
} }
@ -170,4 +204,56 @@ namespace MWGui
//mWindowManager.messageBox("#{sInventorySelectNoSoul}"); //mWindowManager.messageBox("#{sInventorySelectNoSoul}");
} }
void EnchantingDialog::notifyEffectsChanged ()
{
mEffectList.mList = mEffects;
mEnchanting.setEffect(mEffectList);
updateLabels();
}
void EnchantingDialog::onTypeButtonClicked(MyGUI::Widget* sender)
{
mEnchanting.nextEnchantType();
updateLabels();
}
void EnchantingDialog::onBuyButtonClicked(MyGUI::Widget* sender)
{
if (mEffects.size() <= 0)
{
mWindowManager.messageBox ("#{sNotifyMessage30}", std::vector<std::string>());
return;
}
if (mName->getCaption ().empty())
{
mWindowManager.messageBox ("#{sNotifyMessage10}", std::vector<std::string>());
return;
}
if (boost::lexical_cast<int>(mPrice->getCaption()) > mWindowManager.getInventoryWindow()->getPlayerGold())
{
mWindowManager.messageBox ("#{sNotifyMessage18}", std::vector<std::string>());
return;
}
if (mEnchanting.soulEmpty())
{
mWindowManager.messageBox ("#{sNotifyMessage52}", std::vector<std::string>());
return;
}
if (mEnchanting.itemEmpty())
{
mWindowManager.messageBox ("#{sNotifyMessage11}", std::vector<std::string>());
return;
}
mEnchanting.setNewItemName(mName->getCaption());
mEnchanting.setEffect(mEffectList);
mEnchanting.create();
mWindowManager.removeGuiMode (GM_Enchanting);
}
} }

View file

@ -7,6 +7,8 @@
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwmechanics/enchanting.hpp"
namespace MWGui namespace MWGui
{ {
@ -23,6 +25,7 @@ namespace MWGui
protected: protected:
virtual void onReferenceUnavailable(); virtual void onReferenceUnavailable();
virtual void notifyEffectsChanged ();
void onCancelButtonClicked(MyGUI::Widget* sender); void onCancelButtonClicked(MyGUI::Widget* sender);
void onSelectItem (MyGUI::Widget* sender); void onSelectItem (MyGUI::Widget* sender);
@ -34,8 +37,9 @@ namespace MWGui
void onItemCancel(); void onItemCancel();
void onSoulSelected(MWWorld::Ptr item); void onSoulSelected(MWWorld::Ptr item);
void onSoulCancel(); void onSoulCancel();
void onBuyButtonClicked(MyGUI::Widget* sender);
void updateLabels(); void updateLabels();
void onTypeButtonClicked(MyGUI::Widget* sender);
ItemSelectionDialog* mItemSelectionDialog; ItemSelectionDialog* mItemSelectionDialog;
@ -46,15 +50,14 @@ namespace MWGui
MyGUI::Button* mTypeButton; MyGUI::Button* mTypeButton;
MyGUI::Button* mBuyButton; MyGUI::Button* mBuyButton;
MyGUI::TextBox* mName;
MyGUI::TextBox* mEnchantmentPoints; MyGUI::TextBox* mEnchantmentPoints;
MyGUI::TextBox* mCastCost; MyGUI::TextBox* mCastCost;
MyGUI::TextBox* mCharge; MyGUI::TextBox* mCharge;
MyGUI::TextBox* mPrice; MyGUI::TextBox* mPrice;
MWWorld::Ptr mItem; MWMechanics::Enchanting mEnchanting;
MWWorld::Ptr mSoul; ESM::EffectList mEffectList;
float mCurrentEnchantmentPoints;
}; };
} }

View file

@ -72,6 +72,7 @@ namespace MWGui
mMagnitudeMaxSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onMagnitudeMaxChanged); mMagnitudeMaxSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onMagnitudeMaxChanged);
mDurationSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onDurationChanged); mDurationSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onDurationChanged);
mAreaSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onAreaChanged); mAreaSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onAreaChanged);
constantEffect=false;
} }
void EditEffectDialog::open() void EditEffectDialog::open()
@ -164,7 +165,7 @@ namespace MWGui
mMagnitudeBox->setVisible (true); mMagnitudeBox->setVisible (true);
curY += mMagnitudeBox->getSize().height; curY += mMagnitudeBox->getSize().height;
} }
if (!(mMagicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)) if (!(mMagicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)&&constantEffect==false)
{ {
mDurationBox->setPosition(mDurationBox->getPosition().left, curY); mDurationBox->setPosition(mDurationBox->getPosition().left, curY);
mDurationBox->setVisible (true); mDurationBox->setVisible (true);
@ -454,10 +455,13 @@ namespace MWGui
mAvailableEffectsList->clear (); mAvailableEffectsList->clear ();
int i=0;
for (std::vector<short>::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it) for (std::vector<short>::const_iterator it = knownEffects.begin(); it != knownEffects.end(); ++it)
{ {
mAvailableEffectsList->addItem(MWBase::Environment::get().getWorld ()->getStore ().get<ESM::GameSetting>().find( mAvailableEffectsList->addItem(MWBase::Environment::get().getWorld ()->getStore ().get<ESM::GameSetting>().find(
ESM::MagicEffect::effectIdToString (*it))->getString()); ESM::MagicEffect::effectIdToString (*it))->getString());
mButtonMapping[i] = *it;
++i;
} }
mAvailableEffectsList->adjustSize (); mAvailableEffectsList->adjustSize ();
@ -466,7 +470,6 @@ namespace MWGui
std::string name = MWBase::Environment::get().getWorld ()->getStore ().get<ESM::GameSetting>().find( std::string name = MWBase::Environment::get().getWorld ()->getStore ().get<ESM::GameSetting>().find(
ESM::MagicEffect::effectIdToString (*it))->getString(); ESM::MagicEffect::effectIdToString (*it))->getString();
MyGUI::Widget* w = mAvailableEffectsList->getItemWidget(name); MyGUI::Widget* w = mAvailableEffectsList->getItemWidget(name);
w->setUserData(*it);
ToolTips::createMagicEffectToolTip (w, *it); ToolTips::createMagicEffectToolTip (w, *it);
} }
@ -518,7 +521,8 @@ namespace MWGui
return; return;
} }
short effectId = *sender->getUserData<short>(); int buttonId = *sender->getUserData<int>();
short effectId = mButtonMapping[buttonId];
for (std::vector<ESM::ENAMstruct>::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it) for (std::vector<ESM::ENAMstruct>::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it)
{ {

View file

@ -24,7 +24,7 @@ namespace MWGui
void newEffect (const ESM::MagicEffect* effect); void newEffect (const ESM::MagicEffect* effect);
void editEffect (ESM::ENAMstruct effect); void editEffect (ESM::ENAMstruct effect);
bool constantEffect;
typedef MyGUI::delegates::CMultiDelegate1<ESM::ENAMstruct> EventHandle_Effect; typedef MyGUI::delegates::CMultiDelegate1<ESM::ENAMstruct> EventHandle_Effect;
EventHandle_Effect eventEffectAdded; EventHandle_Effect eventEffectAdded;
@ -69,7 +69,6 @@ namespace MWGui
void onMagnitudeMaxChanged (MyGUI::ScrollBar* sender, size_t pos); void onMagnitudeMaxChanged (MyGUI::ScrollBar* sender, size_t pos);
void onDurationChanged (MyGUI::ScrollBar* sender, size_t pos); void onDurationChanged (MyGUI::ScrollBar* sender, size_t pos);
void onAreaChanged (MyGUI::ScrollBar* sender, size_t pos); void onAreaChanged (MyGUI::ScrollBar* sender, size_t pos);
void setMagicEffect(const ESM::MagicEffect* effect); void setMagicEffect(const ESM::MagicEffect* effect);
void updateBoxes(); void updateBoxes();
@ -88,6 +87,8 @@ namespace MWGui
protected: protected:
std::map<int, short> mButtonMapping; // maps button ID to effect ID
Widgets::MWList* mAvailableEffectsList; Widgets::MWList* mAvailableEffectsList;
MyGUI::ScrollView* mUsedEffectsView; MyGUI::ScrollView* mUsedEffectsView;

View file

@ -0,0 +1,164 @@
#include "enchanting.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/containerstore.hpp"
namespace MWMechanics
{
Enchanting::Enchanting(MWWorld::Ptr enchanter):
mEnchanter(enchanter),
mEnchantType(0)
{}
void Enchanting::setOldItem(MWWorld::Ptr oldItem)
{
mOldItemPtr=oldItem;
if(!itemEmpty())
{
mObjectType = mOldItemPtr.getTypeName();
mOldItemId = mOldItemPtr.getCellRef().mRefID;
}
else
{
mObjectType="";
mOldItemId="";
}
}
void Enchanting::setNewItemName(std::string s)
{
mNewItemName=s;
}
void Enchanting::setEffect(ESM::EffectList effectList)
{
mEffectList=effectList;
}
int Enchanting::getEnchantType()
{
return mEnchantType;
}
void Enchanting::setSoulGem(MWWorld::Ptr soulGem)
{
mSoulGemPtr=soulGem;
}
void Enchanting::create()
{
mEnchantment.mData.mCharge = getGemCharge();
if(mEnchantType==3)
{
mEnchantment.mData.mCharge=0;
}
mEnchantment.mData.mType = mEnchantType;
mEnchantment.mData.mCost = getEnchantCost();
mEnchantment.mEffects = mEffectList;
const ESM::Enchantment *enchantment = MWBase::Environment::get().getWorld()->createRecord (mEnchantment);
MWWorld::Ptr newobj = MWWorld::Class::get(mOldItemPtr).applyEnchantment(mOldItemPtr, enchantment->mId, getGemCharge(), mNewItemName);
MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), newobj.getCellRef().mRefID);
MWWorld::Class::get (mEnchanter).getContainerStore (mEnchanter).add (ref.getPtr());
mOldItemPtr.getRefData().setCount(0);
mSoulGemPtr.getRefData().setCount(0);
}
void Enchanting::nextEnchantType()
{
mEnchantType++;
if (itemEmpty())
{
mEnchantType = 0;
return;
}
if ((mObjectType == typeid(ESM::Armor).name())||(mObjectType == typeid(ESM::Clothing).name()))
{
switch(mEnchantType)
{
case 1:
mEnchantType = 2;
case 3:
if(getGemCharge()<400)
mEnchantType=2;
case 4:
mEnchantType = 2;
}
}
else if(mObjectType == typeid(ESM::Weapon).name())
{
switch(mEnchantType)
{
case 3:
mEnchantType = 1;
}
}
else if(mObjectType == typeid(ESM::Book).name())
{
mEnchantType=0;
}
}
int Enchanting::getEnchantCost()
{
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
float cost = 0;
std::vector<ESM::ENAMstruct> mEffects = mEffectList.mList;
int i=mEffects.size();
for (std::vector<ESM::ENAMstruct>::const_iterator it = mEffects.begin(); it != mEffects.end(); ++it)
{
const ESM::MagicEffect* effect = store.get<ESM::MagicEffect>().find(it->mEffectID);
float cost1 = ((it->mMagnMin + it->mMagnMax)*it->mDuration*effect->mData.mBaseCost*0.025);
float cost2 = (std::max(1, it->mArea)*0.125*effect->mData.mBaseCost);
if(mEnchantType==3)
{
cost1 *= 100;
cost2 *= 2;
}
if(effect->mData.mFlags & ESM::MagicEffect::CastTarget)
cost1 *= 1.5;
float fullcost = cost1+cost2;
fullcost*= i;
i--;
cost+=fullcost;
}
return cost;
}
int Enchanting::getGemCharge()
{
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
if(soulEmpty())
return 0;
if(mSoulGemPtr.getCellRef().mSoul=="")
return 0;
const ESM::Creature* soul = store.get<ESM::Creature>().find(mSoulGemPtr.getCellRef().mSoul);
return soul->mData.mSoul;
}
int Enchanting::getMaxEnchantValue()
{
if (itemEmpty())
return 0;
return MWWorld::Class::get(mOldItemPtr).getEnchantmentPoints(mOldItemPtr);
}
bool Enchanting::soulEmpty()
{
if (mSoulGemPtr.isEmpty())
return true;
return false;
}
bool Enchanting::itemEmpty()
{
if(mOldItemPtr.isEmpty())
return true;
return false;
}
}

View file

@ -0,0 +1,41 @@
#ifndef GAME_MWMECHANICS_ENCHANTING_H
#define GAME_MWMECHANICS_ENCHANTING_H
#include <string>
#include "../mwworld/ptr.hpp"
#include <components/esm/effectlist.hpp>
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
namespace MWMechanics
{
class Enchanting
{
MWWorld::Ptr mOldItemPtr;
MWWorld::Ptr mSoulGemPtr;
MWWorld::Ptr mEnchanter;
const MWWorld::Ptr *mNewItemPtr;
int mEnchantType;
ESM::EffectList mEffectList;
ESM::Enchantment mEnchantment;
std::string mNewItemName;
std::string mObjectType;
std::string mOldItemId;
public:
Enchanting(MWWorld::Ptr enchanter);
void setOldItem(MWWorld::Ptr oldItem);
void setNewItemName(std::string s);
void setEffect(ESM::EffectList effectList);
void setSoulGem(MWWorld::Ptr soulGem);
void create();
void nextEnchantType();
int getEnchantType();
int getEnchantCost();
int getMaxEnchantValue();
int getGemCharge();
bool soulEmpty();
bool itemEmpty();
};
}
#endif

View file

@ -241,6 +241,11 @@ namespace MWWorld
return ""; return "";
} }
MWWorld::Ptr Class::applyEnchantment(const MWWorld::Ptr &ptr, std::string enchId, int enchCharge, std::string newName) const
{
throw std::runtime_error ("class can't be enchanted");
}
MWWorld::Ptr MWWorld::Ptr
Class::copyToCellImpl(const Ptr &ptr, CellStore &cell) const Class::copyToCellImpl(const Ptr &ptr, CellStore &cell) const
{ {

View file

@ -231,6 +231,8 @@ namespace MWWorld
virtual std::string getModel(const MWWorld::Ptr &ptr) const; virtual std::string getModel(const MWWorld::Ptr &ptr) const;
virtual MWWorld::Ptr applyEnchantment(const MWWorld::Ptr &ptr, std::string enchId, int enchCharge, std::string newName) const;
virtual Ptr virtual Ptr
copyToCell(const Ptr &ptr, CellStore &cell) const; copyToCell(const Ptr &ptr, CellStore &cell) const;

View file

@ -948,6 +948,31 @@ namespace MWWorld
return ret; return ret;
} }
const ESM::Armor *World::createRecord (const ESM::Armor& record)
{
return mStore.insert(record);
}
const ESM::Weapon *World::createRecord (const ESM::Weapon& record)
{
return mStore.insert(record);
}
const ESM::Clothing *World::createRecord (const ESM::Clothing& record)
{
return mStore.insert(record);
}
const ESM::Enchantment *World::createRecord (const ESM::Enchantment& record)
{
return mStore.insert(record);
}
const ESM::Book *World::createRecord (const ESM::Book& record)
{
return mStore.insert(record);
}
void World::update (float duration, bool paused) void World::update (float duration, bool paused)
{ {
mWeatherManager->update (duration); mWeatherManager->update (duration);

View file

@ -272,25 +272,44 @@ namespace MWWorld
///< \return Resulting mode ///< \return Resulting mode
virtual const ESM::Potion *createRecord (const ESM::Potion& record); virtual const ESM::Potion *createRecord (const ESM::Potion& record);
///< Create a new recrod (of type potion) in the ESM store. ///< Create a new record (of type potion) in the ESM store.
/// \return pointer to created record /// \return pointer to created record
virtual const ESM::Spell *createRecord (const ESM::Spell& record); virtual const ESM::Spell *createRecord (const ESM::Spell& record);
///< Create a new recrod (of type spell) in the ESM store. ///< Create a new record (of type spell) in the ESM store.
/// \return pointer to created record /// \return pointer to created record
virtual const ESM::Class *createRecord (const ESM::Class& record); virtual const ESM::Class *createRecord (const ESM::Class& record);
///< Create a new recrod (of type class) in the ESM store. ///< Create a new record (of type class) in the ESM store.
/// \return pointer to created record /// \return pointer to created record
virtual const ESM::Cell *createRecord (const ESM::Cell& record); virtual const ESM::Cell *createRecord (const ESM::Cell& record);
///< Create a new recrod (of type cell) in the ESM store. ///< Create a new record (of type cell) in the ESM store.
/// \return pointer to created record /// \return pointer to created record
virtual const ESM::NPC *createRecord(const ESM::NPC &record); virtual const ESM::NPC *createRecord(const ESM::NPC &record);
///< Create a new recrod (of type npc) in the ESM store. ///< Create a new record (of type npc) in the ESM store.
/// \return pointer to created record /// \return pointer to created record
virtual const ESM::Armor *createRecord (const ESM::Armor& record);
///< Create a new record (of type armor) in the ESM store.
/// \return pointer to created record
virtual const ESM::Weapon *createRecord (const ESM::Weapon& record);
///< Create a new record (of type weapon) in the ESM store.
/// \return pointer to created record
virtual const ESM::Clothing *createRecord (const ESM::Clothing& record);
///< Create a new record (of type clothing) in the ESM store.
/// \return pointer to created record
virtual const ESM::Enchantment *createRecord (const ESM::Enchantment& record);
///< Create a new record (of type enchantment) in the ESM store.
/// \return pointer to created record
virtual const ESM::Book *createRecord (const ESM::Book& record);
///< Create a new record (of type book) in the ESM store.
/// \return pointer to created record
virtual void update (float duration, bool paused); virtual void update (float duration, bool paused);