You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw-tes3mp/apps/openmw/mwmechanics/enchanting.cpp

215 lines
6.0 KiB
C++

12 years ago
#include "enchanting.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/containerstore.hpp"
#include "creaturestats.hpp"
#include "npcstats.hpp"
12 years ago
namespace MWMechanics
{
Enchanting::Enchanting():
12 years ago
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;
}
int Enchanting::create()
12 years ago
{
mSoulGemPtr.getRefData().setCount(mSoulGemPtr.getRefData().getCount()-1);
if(mSelfEnchanting)
{
if(getEnchantChance()<std::rand()/static_cast<double> (RAND_MAX)*100)
return 0;
MWWorld::Class::get (mEnchanter).skillUsageSucceeded (mEnchanter, ESM::Skill::Enchant, 1);
}
mOldItemPtr.getRefData().setCount(mOldItemPtr.getRefData().getCount()-1);
12 years ago
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);
12 years ago
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);
return 1;
12 years ago
}
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();
/*
Formula from http://www.uesp.net/wiki/Morrowind:Enchant
*/
12 years ago
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;
}
void Enchanting::setSelfEnchanting(bool selfEnchanting)
{
mSelfEnchanting = selfEnchanting;
}
void Enchanting::setEnchanter(MWWorld::Ptr enchanter)
{
mEnchanter = enchanter;
}
float Enchanting::getEnchantChance()
{
/*
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)
{
chance2 *= 2;
}
return (chance1-chance2);
}
12 years ago
}