1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-12 21:39:26 +00:00
OpenMW/apps/openmw/mwmechanics/repair.cpp
dteviot 3f28634d1f consolidate random number logic
Note, I suspect Rng::rollClosedProbability() is not needed.  The only difference between it and rollProbability() is that one time in 37k (on Windows), it will give an output of 1.0.
On some versions of Linux, the value of 1.0 will occur about 1 time in 4 billion.
2015-03-15 14:07:47 +13:00

109 lines
3.9 KiB
C++

#include "repair.hpp"
#include <boost/format.hpp>
#include <openengine/misc/rng.hpp>
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwworld/containerstore.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/npcstats.hpp"
namespace MWMechanics
{
void Repair::repair(const MWWorld::Ptr &itemToRepair)
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
MWWorld::LiveCellRef<ESM::Repair> *ref =
mTool.get<ESM::Repair>();
// unstack tool if required
player.getClass().getContainerStore(player).unstack(mTool, player);
// reduce number of uses left
int uses = mTool.getClass().getItemHealth(mTool);
mTool.getCellRef().setCharge(uses-1);
MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
MWMechanics::NpcStats& npcStats = player.getClass().getNpcStats(player);
float fatigueTerm = stats.getFatigueTerm();
int pcStrength = stats.getAttribute(ESM::Attribute::Strength).getModified();
int pcLuck = stats.getAttribute(ESM::Attribute::Luck).getModified();
int armorerSkill = npcStats.getSkill(ESM::Skill::Armorer).getModified();
float fRepairAmountMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
.find("fRepairAmountMult")->getFloat();
float toolQuality = ref->mBase->mData.mQuality;
float x = (0.1f * pcStrength + 0.1f * pcLuck + armorerSkill) * fatigueTerm;
int roll = OEngine::Misc::Rng::roll0to99();
if (roll <= x)
{
int y = static_cast<int>(fRepairAmountMult * toolQuality * roll);
y = std::max(1, y);
// repair by 'y' points
int charge = itemToRepair.getClass().getItemHealth(itemToRepair);
charge = std::min(charge + y, itemToRepair.getClass().getItemMaxHealth(itemToRepair));
itemToRepair.getCellRef().setCharge(charge);
// attempt to re-stack item, in case it was fully repaired
MWWorld::ContainerStoreIterator stacked = player.getClass().getContainerStore(player).restack(itemToRepair);
// set the OnPCRepair variable on the item's script
std::string script = stacked->getClass().getScript(itemToRepair);
if(script != "")
stacked->getRefData().getLocals().setVarByInt(script, "onpcrepair", 1);
// increase skill
player.getClass().skillUsageSucceeded(player, ESM::Skill::Armorer, 0);
MWBase::Environment::get().getSoundManager()->playSound("Repair",1,1);
MWBase::Environment::get().getWindowManager()->messageBox("#{sRepairSuccess}");
}
else
{
MWBase::Environment::get().getSoundManager()->playSound("Repair Fail",1,1);
MWBase::Environment::get().getWindowManager()->messageBox("#{sRepairFailed}");
}
// tool used up?
if (mTool.getCellRef().getCharge() == 0)
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
MWWorld::ContainerStore& store = player.getClass().getContainerStore(player);
store.remove(mTool, 1, player);
std::string message = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
.find("sNotifyMessage51")->getString();
MWBase::Environment::get().getWindowManager()->messageBox((boost::format(message) % mTool.getClass().getName(mTool)).str());
// try to find a new tool of the same ID
for (MWWorld::ContainerStoreIterator iter (store.begin());
iter!=store.end(); ++iter)
{
if (Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), mTool.getCellRef().getRefId()))
{
mTool = *iter;
break;
}
}
}
}
}