Merge remote-tracking branch 'glorf/enchanting'

Conflicts:
	apps/openmw/CMakeLists.txt
actorid
Marc Zinnschlag 12 years ago
commit 573368849b

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

@ -244,27 +244,44 @@ namespace MWBase
///< Toggle a render mode.
///< \return Resulting mode
virtual const ESM::Potion *createRecord (const ESM::Potion& record)
= 0;
///< Create a new recrod (of type potion) in the ESM store.
virtual const ESM::Potion *createRecord (const ESM::Potion& record) = 0;
///< Create a new record (of type potion) in the ESM store.
/// \return pointer to created record
virtual const ESM::Spell *createRecord (const ESM::Spell& record)
= 0;
///< Create a new recrod (of type spell) in the ESM store.
virtual const ESM::Spell *createRecord (const ESM::Spell& record) = 0;
///< Create a new record (of type spell) in the ESM store.
/// \return pointer to created record
virtual const ESM::Class *createRecord (const ESM::Class& record)
= 0;
///< Create a new recrod (of type class) in the ESM store.
virtual const ESM::Class *createRecord (const ESM::Class& record) = 0;
///< Create a new record (of type class) in the ESM store.
/// \return pointer to created record
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
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
virtual void update (float duration, bool paused) = 0;

@ -274,6 +274,20 @@ namespace MWClass
return ref->mBase->mEnchant;
}
std::string Armor::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const
{
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
ESM::Armor newItem = *ref->mBase;
newItem.mId="";
newItem.mName=newName;
newItem.mData.mEnchant=enchCharge;
newItem.mEnchant=enchId;
const ESM::Armor *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
return record->mId;
}
boost::shared_ptr<MWWorld::Action> Armor::use (const MWWorld::Ptr& ptr) const
{
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr));
@ -291,4 +305,12 @@ namespace MWClass
return MWWorld::Ptr(&cell.mArmors.insert(*ref), &cell);
}
short Armor::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>();
return ref->mBase->mData.mEnchant;
}
}

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

@ -147,6 +147,21 @@ namespace MWClass
return ref->mBase->mEnchant;
}
std::string Book::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const
{
MWWorld::LiveCellRef<ESM::Book> *ref =
ptr.get<ESM::Book>();
ESM::Book newItem = *ref->mBase;
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);
return record->mId;
}
boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const
{
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionRead(ptr));
@ -160,4 +175,12 @@ namespace MWClass
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;
}
}

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

@ -221,6 +221,20 @@ namespace MWClass
return ref->mBase->mEnchant;
}
std::string Clothing::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const
{
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
ESM::Clothing newItem = *ref->mBase;
newItem.mId="";
newItem.mName=newName;
newItem.mData.mEnchant=enchCharge;
newItem.mEnchant=enchId;
const ESM::Clothing *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
return record->mId;
}
boost::shared_ptr<MWWorld::Action> Clothing::use (const MWWorld::Ptr& ptr) const
{
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr));
@ -238,4 +252,12 @@ namespace MWClass
return MWWorld::Ptr(&cell.mClothes.insert(*ref), &cell);
}
short Clothing::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::Clothing> *ref =
ptr.get<ESM::Clothing>();
return ref->mBase->mData.mEnchant;
}
}

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

@ -367,6 +367,20 @@ namespace MWClass
return ref->mBase->mEnchant;
}
std::string Weapon::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const
{
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
ESM::Weapon newItem = *ref->mBase;
newItem.mId="";
newItem.mName=newName;
newItem.mData.mEnchant=enchCharge;
newItem.mEnchant=enchId;
const ESM::Weapon *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
return record->mId;
}
boost::shared_ptr<MWWorld::Action> Weapon::use (const MWWorld::Ptr& ptr) const
{
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionEquip(ptr));
@ -384,4 +398,12 @@ namespace MWClass
return MWWorld::Ptr(&cell.mWeapons.insert(*ref), &cell);
}
short Weapon::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>();
return ref->mBase->mData.mEnchant;
}
}

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

@ -68,6 +68,16 @@ namespace
return compareType(left.getTypeName(), right.getTypeName());
}
}
bool isChargedSoulstone (MWWorld::Ptr ptr)
{
if (ptr.getTypeName() != typeid(ESM::Miscellaneous).name())
return false;
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
ptr.get<ESM::Miscellaneous>();
return (ref->mRef.mSoul != "");
}
}
@ -345,7 +355,7 @@ void ContainerBase::onMouseWheel(MyGUI::Widget* _sender, int _rel)
mItemView->setViewOffset(MyGUI::IntPoint(mItemView->getViewOffset().left + _rel*0.3, 0));
}
void ContainerBase::setFilter(ContainerBase::Filter filter)
void ContainerBase::setFilter(int filter)
{
mFilter = filter;
drawItems();
@ -369,29 +379,34 @@ void ContainerBase::drawItems()
int maxHeight = mItemView->getSize().height - 58;
bool onlyMagic = false;
bool noMagic = false;
int categories = 0;
if (mFilter == Filter_All)
categories = MWWorld::ContainerStore::Type_All;
else if (mFilter == Filter_Weapon)
categories = MWWorld::ContainerStore::Type_Weapon;
else if (mFilter == Filter_Apparel)
categories = MWWorld::ContainerStore::Type_Clothing + MWWorld::ContainerStore::Type_Armor;
else if (mFilter == Filter_Magic)
{
categories = MWWorld::ContainerStore::Type_Clothing + MWWorld::ContainerStore::Type_Armor
+ MWWorld::ContainerStore::Type_Weapon + MWWorld::ContainerStore::Type_Book
+ MWWorld::ContainerStore::Type_Potion;
if (mFilter & Filter_All)
categories |= MWWorld::ContainerStore::Type_All;
if (mFilter & Filter_Weapon)
categories |= MWWorld::ContainerStore::Type_Weapon;
if (mFilter & Filter_Apparel)
categories |= MWWorld::ContainerStore::Type_Clothing | MWWorld::ContainerStore::Type_Armor;
if (mFilter & Filter_Magic)
{
categories |= MWWorld::ContainerStore::Type_Clothing | MWWorld::ContainerStore::Type_Armor
| MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Book
| MWWorld::ContainerStore::Type_Potion;
onlyMagic = true;
}
else if (mFilter == Filter_Misc)
if (mFilter & Filter_Misc)
{
categories = MWWorld::ContainerStore::Type_Miscellaneous + MWWorld::ContainerStore::Type_Book
+ MWWorld::ContainerStore::Type_Ingredient + MWWorld::ContainerStore::Type_Repair
+ MWWorld::ContainerStore::Type_Lockpick + MWWorld::ContainerStore::Type_Light
+ MWWorld::ContainerStore::Type_Apparatus + MWWorld::ContainerStore::Type_Probe;
categories |= MWWorld::ContainerStore::Type_Miscellaneous | MWWorld::ContainerStore::Type_Book
| MWWorld::ContainerStore::Type_Ingredient | MWWorld::ContainerStore::Type_Repair
| MWWorld::ContainerStore::Type_Lockpick | MWWorld::ContainerStore::Type_Light
| MWWorld::ContainerStore::Type_Apparatus | MWWorld::ContainerStore::Type_Probe;
}
else if (mFilter == Filter_Ingredients)
categories = MWWorld::ContainerStore::Type_Ingredient;
if (mFilter & Filter_Ingredients)
categories |= MWWorld::ContainerStore::Type_Ingredient;
if (mFilter & Filter_ChargedSoulstones)
categories |= MWWorld::ContainerStore::Type_Miscellaneous;
if (mFilter & Filter_NoMagic)
noMagic = true;
/// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them
@ -466,12 +481,29 @@ void ContainerBase::drawItems()
{
const MWWorld::Ptr* iter = &((*it).first);
if (onlyMagic
&& it->second != ItemState_Barter
&& MWWorld::Class::get(*iter).getEnchantment(*iter) == ""
&& iter->getTypeName() != typeid(ESM::Potion).name())
continue;
if (noMagic
&& it->second != ItemState_Barter
&& (MWWorld::Class::get(*iter).getEnchantment(*iter) != ""
|| iter->getTypeName() == typeid(ESM::Potion).name()))
continue;
if ( (mFilter & Filter_ChargedSoulstones)
&& !isChargedSoulstone(*iter))
continue;
int displayCount = iter->getRefData().getCount();
if (mDragAndDrop != NULL && mDragAndDrop->mIsOnDragAndDrop && *iter == *mDragAndDrop->mDraggedWidget->getUserData<MWWorld::Ptr>())
{
displayCount -= mDragAndDrop->mDraggedCount;
}
if(displayCount > 0 && !(onlyMagic && it->second != ItemState_Barter && MWWorld::Class::get(*iter).getEnchantment(*iter) == "" && iter->getTypeName() != typeid(ESM::Potion).name()))
if(displayCount > 0)
{
std::string path = std::string("icons\\");
path += MWWorld::Class::get(*iter).getInventoryIcon(*iter);

@ -48,16 +48,17 @@ namespace MWGui
ContainerBase(DragAndDrop* dragAndDrop);
virtual ~ContainerBase();
enum Filter
{
Filter_All = 0x01,
Filter_Weapon = 0x02,
Filter_Apparel = 0x03,
Filter_Magic = 0x04,
Filter_Misc = 0x05,
Filter_Ingredients = 0x06
};
// basic types (inclusive)
static const int Filter_All = (1<<0);
static const int Filter_Weapon = (1<<1);
static const int Filter_Apparel = (1<<2);
static const int Filter_Ingredients = (1<<3);
static const int Filter_Misc = (1<<4);
// special filtering (exclusive)
static const int Filter_Magic = (1<<5);
static const int Filter_NoMagic = (1<<6);
static const int Filter_ChargedSoulstones = (1<<7);
enum ItemState
{
@ -78,7 +79,7 @@ namespace MWGui
MWWorld::ContainerStore& getBoughtItems() { return mBoughtItems; }
void openContainer(MWWorld::Ptr container);
void setFilter(Filter filter); ///< set category filter
void setFilter(int filter); ///< set category filter
void drawItems();
protected:
@ -92,7 +93,7 @@ namespace MWGui
DragAndDrop* mDragAndDrop;
Filter mFilter;
int mFilter;
// bought items are put in a separate ContainerStore so that they don't stack with other (not bought) items.
MWWorld::ContainerStore mBoughtItems;

@ -326,8 +326,8 @@ void DialogueWindow::setKeywords(std::list<std::string> keyWords)
if (mServices & Service_CreateSpells)
mTopicsList->addItem(gmst.find("sSpellmakingMenuTitle")->getString());
// if (mServices & Service_Enchant)
// mTopicsList->addItem(gmst.find("sEnchanting")->getString());
if (mServices & Service_Enchant)
mTopicsList->addItem(gmst.find("sEnchanting")->getString());
if (mServices & Service_Training)
mTopicsList->addItem(gmst.find("sServiceTrainingTitle")->getString());

@ -1,5 +1,15 @@
#include "enchantingdialog.hpp"
#include <boost/lexical_cast.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/manualref.hpp"
#include "itemselection.hpp"
#include "container.hpp"
#include "inventorywindow.hpp"
namespace MWGui
{
@ -8,19 +18,71 @@ namespace MWGui
EnchantingDialog::EnchantingDialog(MWBase::WindowManager &parWindowManager)
: WindowBase("openmw_enchanting_dialog.layout", parWindowManager)
, EffectEditorBase(parWindowManager)
, mItemSelectionDialog(NULL)
, mEnchanting(MWBase::Environment::get().getWorld()->getPlayer().getPlayer())
{
getWidget(mName, "NameEdit");
getWidget(mCancelButton, "CancelButton");
getWidget(mAvailableEffectsList, "AvailableEffects");
getWidget(mUsedEffectsView, "UsedEffects");
getWidget(mItemBox, "ItemBox");
getWidget(mSoulBox, "SoulBox");
getWidget(mEnchantmentPoints, "Enchantment");
getWidget(mCastCost, "CastCost");
getWidget(mCharge, "Charge");
getWidget(mTypeButton, "TypeButton");
getWidget(mBuyButton, "BuyButton");
getWidget(mPrice, "PriceLabel");
setWidgets(mAvailableEffectsList, mUsedEffectsView);
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onCancelButtonClicked);
mItemBox->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onSelectItem);
mSoulBox->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onSelectSoul);
mBuyButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onBuyButtonClicked);
mTypeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onTypeButtonClicked);
}
EnchantingDialog::~EnchantingDialog()
{
delete mItemSelectionDialog;
}
void EnchantingDialog::open()
{
center();
onRemoveItem(NULL);
onRemoveSoul(NULL);
}
void EnchantingDialog::updateLabels()
{
mEnchantmentPoints->setCaption(boost::lexical_cast<std::string>(mEnchanting.getEnchantCost())
+ " / " + boost::lexical_cast<std::string>(mEnchanting.getMaxEnchantValue()));
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)
@ -40,4 +102,159 @@ namespace MWGui
{
mWindowManager.removeGuiMode (GM_Enchanting);
}
void EnchantingDialog::onSelectItem(MyGUI::Widget *sender)
{
delete mItemSelectionDialog;
mItemSelectionDialog = new ItemSelectionDialog("#{sEnchantItems}",
ContainerBase::Filter_Apparel|ContainerBase::Filter_Weapon|ContainerBase::Filter_NoMagic, mWindowManager);
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onItemSelected);
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onItemCancel);
mItemSelectionDialog->setVisible(true);
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
mItemSelectionDialog->drawItems ();
}
void EnchantingDialog::onItemSelected(MWWorld::Ptr item)
{
mItemSelectionDialog->setVisible(false);
while (mItemBox->getChildCount ())
MyGUI::Gui::getInstance ().destroyWidget (mItemBox->getChildAt(0));
MyGUI::ImageBox* image = mItemBox->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(0, 0, 32, 32), MyGUI::Align::Default);
std::string path = std::string("icons\\");
path += MWWorld::Class::get(item).getInventoryIcon(item);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
image->setImageTexture (path);
image->setUserString ("ToolTipType", "ItemPtr");
image->setUserData(item);
image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveItem);
mEnchanting.setOldItem(item);
mEnchanting.nextEnchantType();
updateLabels();
}
void EnchantingDialog::onRemoveItem(MyGUI::Widget *sender)
{
while (mItemBox->getChildCount ())
MyGUI::Gui::getInstance ().destroyWidget (mItemBox->getChildAt(0));
mEnchanting.setOldItem(MWWorld::Ptr());
updateLabels();
}
void EnchantingDialog::onItemCancel()
{
mItemSelectionDialog->setVisible(false);
}
void EnchantingDialog::onSoulSelected(MWWorld::Ptr item)
{
mItemSelectionDialog->setVisible(false);
mEnchanting.setSoulGem(item);
if(mEnchanting.getGemCharge()==0)
{
mWindowManager.messageBox ("#{sNotifyMessage32}", std::vector<std::string>());
return;
}
while (mSoulBox->getChildCount ())
MyGUI::Gui::getInstance ().destroyWidget (mSoulBox->getChildAt(0));
MyGUI::ImageBox* image = mSoulBox->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(0, 0, 32, 32), MyGUI::Align::Default);
std::string path = std::string("icons\\");
path += MWWorld::Class::get(item).getInventoryIcon(item);
int pos = path.rfind(".");
path.erase(pos);
path.append(".dds");
image->setImageTexture (path);
image->setUserString ("ToolTipType", "ItemPtr");
image->setUserData(item);
image->eventMouseButtonClick += MyGUI::newDelegate(this, &EnchantingDialog::onRemoveSoul);
updateLabels();
}
void EnchantingDialog::onRemoveSoul(MyGUI::Widget *sender)
{
while (mSoulBox->getChildCount ())
MyGUI::Gui::getInstance ().destroyWidget (mSoulBox->getChildAt(0));
mEnchanting.setSoulGem(MWWorld::Ptr());
updateLabels();
}
void EnchantingDialog::onSoulCancel()
{
mItemSelectionDialog->setVisible(false);
}
void EnchantingDialog::onSelectSoul(MyGUI::Widget *sender)
{
delete mItemSelectionDialog;
mItemSelectionDialog = new ItemSelectionDialog("#{sSoulGemsWithSouls}",
ContainerBase::Filter_Misc|ContainerBase::Filter_ChargedSoulstones, mWindowManager);
mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &EnchantingDialog::onSoulSelected);
mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &EnchantingDialog::onSoulCancel);
mItemSelectionDialog->setVisible(true);
mItemSelectionDialog->openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer());
mItemSelectionDialog->drawItems ();
//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.messageBox ("#{sEnchantmentMenu12}", std::vector<std::string>());
mWindowManager.removeGuiMode (GM_Enchanting);
}
}

@ -7,23 +7,57 @@
#include "../mwbase/windowmanager.hpp"
#include "../mwmechanics/enchanting.hpp"
namespace MWGui
{
class ItemSelectionDialog;
class EnchantingDialog : public WindowBase, public ReferenceInterface, public EffectEditorBase
{
public:
EnchantingDialog(MWBase::WindowManager& parWindowManager);
virtual ~EnchantingDialog();
virtual void open();
void startEnchanting(MWWorld::Ptr actor);
protected:
virtual void onReferenceUnavailable();
virtual void notifyEffectsChanged ();
void onCancelButtonClicked(MyGUI::Widget* sender);
void onSelectItem (MyGUI::Widget* sender);
void onSelectSoul (MyGUI::Widget* sender);
void onRemoveItem (MyGUI::Widget* sender);
void onRemoveSoul (MyGUI::Widget* sender);
void onItemSelected(MWWorld::Ptr item);
void onItemCancel();
void onSoulSelected(MWWorld::Ptr item);
void onSoulCancel();
void onBuyButtonClicked(MyGUI::Widget* sender);
void updateLabels();
void onTypeButtonClicked(MyGUI::Widget* sender);
ItemSelectionDialog* mItemSelectionDialog;
MyGUI::Button* mCancelButton;
MyGUI::ImageBox* mItemBox;
MyGUI::ImageBox* mSoulBox;
MyGUI::Button* mTypeButton;
MyGUI::Button* mBuyButton;
MyGUI::TextBox* mName;
MyGUI::TextBox* mEnchantmentPoints;
MyGUI::TextBox* mCastCost;
MyGUI::TextBox* mCharge;
MyGUI::TextBox* mPrice;
MWMechanics::Enchanting mEnchanting;
ESM::EffectList mEffectList;
};
}

@ -3,7 +3,7 @@
namespace MWGui
{
ItemSelectionDialog::ItemSelectionDialog(const std::string &label, ContainerBase::Filter filter, MWBase::WindowManager& parWindowManager)
ItemSelectionDialog::ItemSelectionDialog(const std::string &label, int filter, MWBase::WindowManager& parWindowManager)
: ContainerBase(NULL)
, WindowModal("openmw_itemselection_dialog.layout", parWindowManager)
{

@ -8,7 +8,7 @@ namespace MWGui
class ItemSelectionDialog : public ContainerBase, public WindowModal
{
public:
ItemSelectionDialog(const std::string& label, ContainerBase::Filter filter, MWBase::WindowManager& parWindowManager);
ItemSelectionDialog(const std::string& label, int filter, MWBase::WindowManager& parWindowManager);
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
typedef MyGUI::delegates::CMultiDelegate1<MWWorld::Ptr> EventHandle_Item;

@ -72,6 +72,7 @@ namespace MWGui
mMagnitudeMaxSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onMagnitudeMaxChanged);
mDurationSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onDurationChanged);
mAreaSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onAreaChanged);
constantEffect=false;
}
void EditEffectDialog::open()
@ -164,7 +165,7 @@ namespace MWGui
mMagnitudeBox->setVisible (true);
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->setVisible (true);

@ -24,7 +24,7 @@ namespace MWGui
void newEffect (const ESM::MagicEffect* effect);
void editEffect (ESM::ENAMstruct effect);
bool constantEffect;
typedef MyGUI::delegates::CMultiDelegate1<ESM::ENAMstruct> EventHandle_Effect;
EventHandle_Effect eventEffectAdded;
@ -69,7 +69,6 @@ namespace MWGui
void onMagnitudeMaxChanged (MyGUI::ScrollBar* sender, size_t pos);
void onDurationChanged (MyGUI::ScrollBar* sender, size_t pos);
void onAreaChanged (MyGUI::ScrollBar* sender, size_t pos);
void setMagicEffect(const ESM::MagicEffect* effect);
void updateBoxes();

@ -0,0 +1,167 @@
#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()
{
mOldItemPtr.getRefData().setCount(mOldItemPtr.getRefData().getCount()-1);
mSoulGemPtr.getRefData().setCount(mSoulGemPtr.getRefData().getCount()-1);
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);
std::string newobjId = MWWorld::Class::get(mOldItemPtr).applyEnchantment(mOldItemPtr, enchantment->mId, getGemCharge(), mNewItemName);
MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), newobjId);
MWWorld::Ptr newobjPtr = ref.getPtr();
MWWorld::Ptr result = mOldItemPtr;
result.mPtr = newobjPtr.mPtr;
MWWorld::Class::get (mEnchanter).getContainerStore (mEnchanter).add (result);
}
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;
}
}

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

@ -127,6 +127,11 @@ namespace MWWorld
return 0;
}
short Class::getEnchantmentPoints (const MWWorld::Ptr& ptr) const
{
throw std::runtime_error ("class does not support enchanting");
}
MWMechanics::Movement& Class::getMovementSettings (const Ptr& ptr) const
{
throw std::runtime_error ("movement settings not supported by class");
@ -241,6 +246,11 @@ namespace MWWorld
return "";
}
std::string Class::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const
{
throw std::runtime_error ("class can't be enchanted");
}
MWWorld::Ptr
Class::copyToCellImpl(const Ptr &ptr, CellStore &cell) const
{

@ -225,12 +225,17 @@ namespace MWWorld
///< @return the enchantment ID if the object is enchanted, otherwise an empty string
/// (default implementation: return empty string)
virtual short getEnchantmentPoints (const MWWorld::Ptr& ptr) const;
///< @return the number of enchantment points available for possible enchanting
virtual void adjustScale(const MWWorld::Ptr& ptr,float& scale) const;
virtual void adjustRotation(const MWWorld::Ptr& ptr,float& x,float& y,float& z) const;
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
virtual std::string applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const;
virtual Ptr
copyToCell(const Ptr &ptr, CellStore &cell) const;

@ -949,6 +949,31 @@ namespace MWWorld
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)
{
mWeatherManager->update (duration);

@ -272,25 +272,44 @@ namespace MWWorld
///< \return Resulting mode
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
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
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
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
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
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);

@ -22,7 +22,7 @@
<Widget type="Button" skin="MW_ArrowLeft" position="3 2 10 10" align="ALIGN_LEFT ALIGN_VSTRETCH" name="PrevGenderButton"/>
</Widget>
<Widget type="TextBox" skin="HeaderText" position="14 298 227 14" name="GenderChoiceT" />
<Widget type="TextBox" skin="HeaderText" position="25 298 227 14" name="GenderChoiceT" />
<Widget type="Widget" skin="MW_Box" position="234 298 15 14">
<Widget type="Button" skin="MW_ArrowRight" position="1 2 10 10" align="ALIGN_RIGHT ALIGN_VSTRETCH" name="NextGenderButton"/>
@ -34,7 +34,7 @@
<Widget type="Button" skin="MW_ArrowLeft" position="3 2 10 10" align="ALIGN_LEFT ALIGN_VSTRETCH" name="PrevFaceButton"/>
</Widget>
<Widget type="TextBox" skin="HeaderText" position="14 320 227 14" name="FaceChoiceT" />
<Widget type="TextBox" skin="HeaderText" position="25 320 227 14" name="FaceChoiceT" />
<Widget type="Widget" skin="MW_Box" position="234 320 15 14">
<Widget type="Button" skin="MW_ArrowRight" position="1 2 10 10" align="ALIGN_RIGHT ALIGN_VSTRETCH" name="NextFaceButton"/>
@ -46,7 +46,7 @@
<Widget type="Button" skin="MW_ArrowLeft" position="3 2 10 10" align="ALIGN_LEFT ALIGN_VSTRETCH" name="PrevHairButton"/>
</Widget>
<Widget type="TextBox" skin="HeaderText" position="14 342 227 14" name="HairChoiceT" />
<Widget type="TextBox" skin="HeaderText" position="25 342 227 14" name="HairChoiceT" />
<Widget type="Widget" skin="MW_Box" position="234 342 15 14">
<Widget type="Button" skin="MW_ArrowRight" position="1 2 10 10" align="ALIGN_RIGHT ALIGN_VSTRETCH" name="NextHairButton"/>

@ -26,14 +26,18 @@
<Widget type="AutoSizedTextBox" skin="NormalText">
<Property key="Caption" value="#{sItem}"/>
</Widget>
<Widget type="Button" skin="MW_Box" position="0 0 60 59" name="ItemBox"/>
<Widget type="Widget" skin="MW_Box" position="0 0 50 50">
<Widget type="ImageBox" skin="ImageBox" position="9 9 32 32" name="ItemBox"/>
</Widget>
<Widget type="Widget" position="0 0 8 0"/>
<Widget type="AutoSizedTextBox" skin="NormalText">
<Property key="Caption" value="#{sSoulGem}"/>
</Widget>
<Widget type="Button" skin="MW_Box" position="0 0 60 59" name="SoulBox"/>
<Widget type="Button" skin="MW_Box" position="0 0 50 50">
<Widget type="ImageBox" skin="ImageBox" position="9 9 32 32" name="SoulBox"/>
</Widget>
</Widget>
@ -85,7 +89,11 @@
<Widget type="HBox" position="0 340 560 60">
<Property key="Padding" value="16"/>
<Widget type="Widget" position="0 0 0 0">
<Widget type="AutoSizedButton" skin="MW_Button" name="TypeButton">
<Property key="Caption" value="Constant effect"/>
</Widget>
<Widget type="Widget">
<UserString key="HStretch" value="true"/>
</Widget>
@ -97,6 +105,7 @@
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" name="BuyButton">
<Property key="Caption" value="#{sBuy}"/>
</Widget>

Loading…
Cancel
Save