mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-21 11:23:51 +00:00
Merge remote-tracking branch 'glorf/enchanting'
This commit is contained in:
commit
751c679255
13 changed files with 135 additions and 58 deletions
|
@ -274,7 +274,7 @@ 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
|
||||
void 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>();
|
||||
|
@ -285,7 +285,7 @@ namespace MWClass
|
|||
newItem.mData.mEnchant=enchCharge;
|
||||
newItem.mEnchant=enchId;
|
||||
const ESM::Armor *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
|
||||
return record->mId;
|
||||
ref->mBase = record;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Armor::use (const MWWorld::Ptr& ptr) const
|
||||
|
|
|
@ -65,7 +65,7 @@ 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 void 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;
|
||||
|
|
|
@ -147,7 +147,7 @@ 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
|
||||
void 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>();
|
||||
|
@ -159,7 +159,7 @@ namespace MWClass
|
|||
newItem.mData.mEnchant=enchCharge;
|
||||
newItem.mEnchant=enchId;
|
||||
const ESM::Book *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
|
||||
return record->mId;
|
||||
ref->mBase = record;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Book::use (const MWWorld::Ptr& ptr) const
|
||||
|
|
|
@ -51,7 +51,7 @@ 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 void 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
|
||||
|
|
|
@ -221,7 +221,7 @@ 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
|
||||
void 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>();
|
||||
|
@ -232,7 +232,7 @@ namespace MWClass
|
|||
newItem.mData.mEnchant=enchCharge;
|
||||
newItem.mEnchant=enchId;
|
||||
const ESM::Clothing *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
|
||||
return record->mId;
|
||||
ref->mBase = record;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Clothing::use (const MWWorld::Ptr& ptr) const
|
||||
|
|
|
@ -59,7 +59,7 @@ 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 void 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;
|
||||
|
|
|
@ -367,7 +367,7 @@ 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
|
||||
void 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>();
|
||||
|
@ -378,7 +378,7 @@ namespace MWClass
|
|||
newItem.mData.mEnchant=enchCharge;
|
||||
newItem.mEnchant=enchId;
|
||||
const ESM::Weapon *record = MWBase::Environment::get().getWorld()->createRecord (newItem);
|
||||
return record->mId;
|
||||
ref->mBase = record;
|
||||
}
|
||||
|
||||
boost::shared_ptr<MWWorld::Action> Weapon::use (const MWWorld::Ptr& ptr) const
|
||||
|
|
|
@ -65,7 +65,7 @@ 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 void 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;
|
||||
|
|
|
@ -19,7 +19,6 @@ namespace MWGui
|
|||
: WindowBase("openmw_enchanting_dialog.layout", parWindowManager)
|
||||
, EffectEditorBase(parWindowManager)
|
||||
, mItemSelectionDialog(NULL)
|
||||
, mEnchanting(MWBase::Environment::get().getWorld()->getPlayer().getPlayer())
|
||||
{
|
||||
getWidget(mName, "NameEdit");
|
||||
getWidget(mCancelButton, "CancelButton");
|
||||
|
@ -87,14 +86,30 @@ namespace MWGui
|
|||
|
||||
void EnchantingDialog::startEnchanting (MWWorld::Ptr actor)
|
||||
{
|
||||
mPtr = actor;
|
||||
|
||||
/*Now there's no need to use other enchanters, player is the enchanter here,
|
||||
even if the enchanted object is created by NPC. Could be changed later, probably
|
||||
with some price formulas */
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
|
||||
mEnchanting.setSelfEnchanting(false);
|
||||
mEnchanting.setEnchanter(player);
|
||||
|
||||
mPtr = player;
|
||||
|
||||
startEditing ();
|
||||
}
|
||||
|
||||
void EnchantingDialog::startSelfEnchanting(MWWorld::Ptr soulgem)
|
||||
{
|
||||
/// \todo
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||
|
||||
mEnchanting.setSelfEnchanting(true);
|
||||
mEnchanting.setEnchanter(player);
|
||||
|
||||
mPtr = player;
|
||||
|
||||
startEditing();
|
||||
}
|
||||
|
||||
void EnchantingDialog::onReferenceUnavailable ()
|
||||
|
@ -264,8 +279,13 @@ namespace MWGui
|
|||
mEnchanting.setNewItemName(mName->getCaption());
|
||||
mEnchanting.setEffect(mEffectList);
|
||||
|
||||
mEnchanting.create();
|
||||
mWindowManager.messageBox ("#{sEnchantmentMenu12}");
|
||||
int result = mEnchanting.create();
|
||||
|
||||
if(result==1)
|
||||
mWindowManager.messageBox ("#{sEnchantmentMenu12}");
|
||||
else
|
||||
mWindowManager.messageBox ("#{sNotifyMessage34}");
|
||||
|
||||
mWindowManager.removeGuiMode (GM_Enchanting);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,13 @@
|
|||
#include "../mwworld/manualref.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
|
||||
#include "creaturestats.hpp"
|
||||
#include "npcstats.hpp"
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
Enchanting::Enchanting(MWWorld::Ptr enchanter):
|
||||
mEnchanter(enchanter),
|
||||
Enchanting::Enchanting():
|
||||
mEnchantType(0)
|
||||
{}
|
||||
|
||||
|
@ -17,6 +20,7 @@ namespace MWMechanics
|
|||
{
|
||||
mObjectType = mOldItemPtr.getTypeName();
|
||||
mOldItemId = mOldItemPtr.getCellRef().mRefID;
|
||||
mOldItemCount = mOldItemPtr.getRefData().getCount();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -25,7 +29,7 @@ namespace MWMechanics
|
|||
}
|
||||
}
|
||||
|
||||
void Enchanting::setNewItemName(std::string s)
|
||||
void Enchanting::setNewItemName(const std::string& s)
|
||||
{
|
||||
mNewItemName=s;
|
||||
}
|
||||
|
@ -35,7 +39,7 @@ namespace MWMechanics
|
|||
mEffectList=effectList;
|
||||
}
|
||||
|
||||
int Enchanting::getEnchantType()
|
||||
int Enchanting::getEnchantType() const
|
||||
{
|
||||
return mEnchantType;
|
||||
}
|
||||
|
@ -45,28 +49,39 @@ namespace MWMechanics
|
|||
mSoulGemPtr=soulGem;
|
||||
}
|
||||
|
||||
void Enchanting::create()
|
||||
bool Enchanting::create()
|
||||
{
|
||||
mOldItemPtr.getRefData().setCount(mOldItemPtr.getRefData().getCount()-1);
|
||||
mSoulGemPtr.getRefData().setCount(mSoulGemPtr.getRefData().getCount()-1);
|
||||
ESM::Enchantment enchantment;
|
||||
enchantment.mData.mCharge = getGemCharge();
|
||||
mSoulGemPtr.getRefData().setCount (mSoulGemPtr.getRefData().getCount()-1);
|
||||
|
||||
if(mSelfEnchanting)
|
||||
{
|
||||
if(getEnchantChance()<std::rand()/static_cast<double> (RAND_MAX)*100)
|
||||
return false;
|
||||
|
||||
MWWorld::Class::get (mEnchanter).skillUsageSucceeded (mEnchanter, ESM::Skill::Enchant, 1);
|
||||
}
|
||||
|
||||
mEnchantment.mData.mCharge = getGemCharge();
|
||||
if(mEnchantType==3)
|
||||
{
|
||||
mEnchantment.mData.mCharge=0;
|
||||
enchantment.mData.mCharge=0;
|
||||
}
|
||||
mEnchantment.mData.mType = mEnchantType;
|
||||
mEnchantment.mData.mCost = getEnchantCost();
|
||||
mEnchantment.mEffects = mEffectList;
|
||||
const ESM::Enchantment *enchantment = MWBase::Environment::get().getWorld()->createRecord (mEnchantment);
|
||||
enchantment.mData.mType = mEnchantType;
|
||||
enchantment.mData.mCost = getEnchantCost();
|
||||
enchantment.mEffects = mEffectList;
|
||||
|
||||
std::string newobjId = MWWorld::Class::get(mOldItemPtr).applyEnchantment(mOldItemPtr, enchantment->mId, getGemCharge(), mNewItemName);
|
||||
const ESM::Enchantment *enchantmentPtr = MWBase::Environment::get().getWorld()->createRecord (enchantment);
|
||||
|
||||
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);
|
||||
MWWorld::Class::get(mOldItemPtr).applyEnchantment(mOldItemPtr, enchantmentPtr->mId, getGemCharge(), mNewItemName);
|
||||
|
||||
mOldItemPtr.getRefData().setCount(1);
|
||||
|
||||
MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), mOldItemId);
|
||||
ref.getPtr().getRefData().setCount (mOldItemCount-1);
|
||||
MWWorld::Class::get (mEnchanter).getContainerStore (mEnchanter).add (ref.getPtr());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Enchanting::nextEnchantType()
|
||||
|
@ -79,12 +94,13 @@ namespace MWMechanics
|
|||
}
|
||||
if ((mObjectType == typeid(ESM::Armor).name())||(mObjectType == typeid(ESM::Clothing).name()))
|
||||
{
|
||||
int soulConstAmount = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("iSoulAmountForConstantEffect")->getInt();
|
||||
switch(mEnchantType)
|
||||
{
|
||||
case 1:
|
||||
mEnchantType = 2;
|
||||
case 3:
|
||||
if(getGemCharge()<400)
|
||||
if(getGemCharge()<soulConstAmount)
|
||||
mEnchantType=2;
|
||||
case 4:
|
||||
mEnchantType = 2;
|
||||
|
@ -104,12 +120,16 @@ namespace MWMechanics
|
|||
}
|
||||
}
|
||||
|
||||
int Enchanting::getEnchantCost()
|
||||
int Enchanting::getEnchantCost() const
|
||||
{
|
||||
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
||||
float cost = 0;
|
||||
std::vector<ESM::ENAMstruct> mEffects = mEffectList.mList;
|
||||
int i=mEffects.size();
|
||||
|
||||
/*
|
||||
Formula from http://www.uesp.net/wiki/Morrowind:Enchant
|
||||
*/
|
||||
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);
|
||||
|
@ -120,7 +140,8 @@ namespace MWMechanics
|
|||
|
||||
if(mEnchantType==3)
|
||||
{
|
||||
cost1 *= 100;
|
||||
int constDurationMultipler = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fEnchantmentConstantDurationMult")->getFloat();
|
||||
cost1 *= constDurationMultipler;
|
||||
cost2 *= 2;
|
||||
}
|
||||
if(effect->mData.mFlags & ESM::MagicEffect::CastTarget)
|
||||
|
@ -134,7 +155,7 @@ namespace MWMechanics
|
|||
}
|
||||
return cost;
|
||||
}
|
||||
int Enchanting::getGemCharge()
|
||||
int Enchanting::getGemCharge() const
|
||||
{
|
||||
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
|
||||
if(soulEmpty())
|
||||
|
@ -145,23 +166,54 @@ namespace MWMechanics
|
|||
return soul->mData.mSoul;
|
||||
}
|
||||
|
||||
int Enchanting::getMaxEnchantValue()
|
||||
int Enchanting::getMaxEnchantValue() const
|
||||
{
|
||||
if (itemEmpty())
|
||||
return 0;
|
||||
return MWWorld::Class::get(mOldItemPtr).getEnchantmentPoints(mOldItemPtr);
|
||||
}
|
||||
bool Enchanting::soulEmpty()
|
||||
bool Enchanting::soulEmpty() const
|
||||
{
|
||||
if (mSoulGemPtr.isEmpty())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Enchanting::itemEmpty()
|
||||
bool Enchanting::itemEmpty() const
|
||||
{
|
||||
if(mOldItemPtr.isEmpty())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Enchanting::setSelfEnchanting(bool selfEnchanting)
|
||||
{
|
||||
mSelfEnchanting = selfEnchanting;
|
||||
}
|
||||
|
||||
void Enchanting::setEnchanter(MWWorld::Ptr enchanter)
|
||||
{
|
||||
mEnchanter = enchanter;
|
||||
}
|
||||
|
||||
float Enchanting::getEnchantChance() const
|
||||
{
|
||||
/*
|
||||
Formula from http://www.uesp.net/wiki/Morrowind:Enchant
|
||||
*/
|
||||
const CreatureStats& creatureStats = MWWorld::Class::get (mEnchanter).getCreatureStats (mEnchanter);
|
||||
const NpcStats& npcStats = MWWorld::Class::get (mEnchanter).getNpcStats (mEnchanter);
|
||||
|
||||
float chance1 = (npcStats.getSkill (ESM::Skill::Enchant).getModified() +
|
||||
(0.25 * creatureStats.getAttribute (ESM::Attribute::Intelligence).getModified())
|
||||
+ (0.125 * creatureStats.getAttribute (ESM::Attribute::Luck).getModified()));
|
||||
|
||||
float chance2 = 2.5 * getEnchantCost();
|
||||
if(mEnchantType==3)
|
||||
{
|
||||
float constantChance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find ("fEnchantmentConstantChanceMult")->getFloat();
|
||||
chance2 /= constantChance;
|
||||
}
|
||||
return (chance1-chance2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,33 +9,38 @@ namespace MWMechanics
|
|||
{
|
||||
class Enchanting
|
||||
{
|
||||
|
||||
MWWorld::Ptr mOldItemPtr;
|
||||
MWWorld::Ptr mSoulGemPtr;
|
||||
MWWorld::Ptr mEnchanter;
|
||||
const MWWorld::Ptr *mNewItemPtr;
|
||||
|
||||
int mEnchantType;
|
||||
|
||||
bool mSelfEnchanting;
|
||||
|
||||
ESM::EffectList mEffectList;
|
||||
ESM::Enchantment mEnchantment;
|
||||
|
||||
std::string mNewItemName;
|
||||
std::string mObjectType;
|
||||
std::string mOldItemId;
|
||||
int mOldItemCount;
|
||||
|
||||
public:
|
||||
Enchanting(MWWorld::Ptr enchanter);
|
||||
Enchanting();
|
||||
void setEnchanter(MWWorld::Ptr enchanter);
|
||||
void setSelfEnchanting(bool selfEnchanting);
|
||||
void setOldItem(MWWorld::Ptr oldItem);
|
||||
void setNewItemName(std::string s);
|
||||
void setNewItemName(const 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();
|
||||
bool create(); //Return true if created, false if failed.
|
||||
void nextEnchantType(); //Set enchant type to next possible type (for mOldItemPtr object)
|
||||
int getEnchantType() const;
|
||||
int getEnchantCost() const;
|
||||
int getMaxEnchantValue() const;
|
||||
int getGemCharge() const;
|
||||
float getEnchantChance() const;
|
||||
bool soulEmpty() const; //Return true if empty
|
||||
bool itemEmpty() const; //Return true if empty
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -254,7 +254,7 @@ namespace MWWorld
|
|||
return "";
|
||||
}
|
||||
|
||||
std::string Class::applyEnchantment(const MWWorld::Ptr &ptr, const std::string& enchId, int enchCharge, const std::string& newName) const
|
||||
void 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");
|
||||
}
|
||||
|
|
|
@ -237,7 +237,7 @@ namespace MWWorld
|
|||
|
||||
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 void 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;
|
||||
|
|
Loading…
Reference in a new issue