mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-28 17:09:41 +00:00
Merge branch 'imperfectoil' into 'master'
Implement auto calculated potion values Closes #7859 See merge request OpenMW/openmw!3918
This commit is contained in:
commit
828bf3d11a
11 changed files with 56 additions and 14 deletions
|
@ -154,6 +154,7 @@
|
|||
Bug #7832: Ingredient tooltips show magnitude for Fortify Maximum Magicka effect
|
||||
Bug #7840: First run of the launcher doesn't save viewing distance as the default value
|
||||
Bug #7841: Editor: "Dirty" water heights are saved in modified CELLs
|
||||
Bug #7859: AutoCalc flag is not used to calculate potion value
|
||||
Feature #2566: Handle NAM9 records for manual cell references
|
||||
Feature #3537: Shader-based water ripples
|
||||
Feature #5173: Support for NiFogProperty
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "labels.hpp"
|
||||
|
||||
#include <components/esm3/loadalch.hpp>
|
||||
#include <components/esm3/loadbody.hpp>
|
||||
#include <components/esm3/loadcell.hpp>
|
||||
#include <components/esm3/loadcont.hpp>
|
||||
|
@ -987,3 +988,16 @@ std::string recordFlags(uint32_t flags)
|
|||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
||||
return properties;
|
||||
}
|
||||
|
||||
std::string potionFlags(int flags)
|
||||
{
|
||||
std::string properties;
|
||||
if (flags == 0)
|
||||
properties += "[None] ";
|
||||
if (flags & ESM::Potion::Autocalc)
|
||||
properties += "Autocalc ";
|
||||
if (flags & (0xFFFFFFFF ^ ESM::Enchantment::Autocalc))
|
||||
properties += "Invalid ";
|
||||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
||||
return properties;
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ std::string itemListFlags(int flags);
|
|||
std::string lightFlags(int flags);
|
||||
std::string magicEffectFlags(int flags);
|
||||
std::string npcFlags(int flags);
|
||||
std::string potionFlags(int flags);
|
||||
std::string raceFlags(int flags);
|
||||
std::string spellFlags(int flags);
|
||||
std::string weaponFlags(int flags);
|
||||
|
|
|
@ -479,7 +479,7 @@ namespace EsmTool
|
|||
std::cout << " Script: " << mData.mScript << std::endl;
|
||||
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
|
||||
std::cout << " Value: " << mData.mData.mValue << std::endl;
|
||||
std::cout << " AutoCalc: " << mData.mData.mAutoCalc << std::endl;
|
||||
std::cout << " Flags: " << potionFlags(mData.mData.mFlags) << std::endl;
|
||||
printEffectList(mData.mEffects);
|
||||
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ QVariant CSMWorld::PotionRefIdAdapter::getData(const RefIdColumn* column, const
|
|||
data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Potion)));
|
||||
|
||||
if (column == mAutoCalc)
|
||||
return record.get().mData.mAutoCalc != 0;
|
||||
return record.get().mData.mFlags & ESM::Potion::Autocalc;
|
||||
|
||||
// to show nested tables in dialogue subview, see IdTree::hasChildren()
|
||||
if (column == mColumns.mEffects)
|
||||
|
@ -51,7 +51,7 @@ void CSMWorld::PotionRefIdAdapter::setData(
|
|||
ESM::Potion potion = record.get();
|
||||
|
||||
if (column == mAutoCalc)
|
||||
potion.mData.mAutoCalc = value.toInt();
|
||||
potion.mData.mFlags = value.toBool();
|
||||
else
|
||||
{
|
||||
InventoryRefIdAdapter<ESM::Potion>::setData(column, data, index, value);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "../mwrender/renderinginterface.hpp"
|
||||
|
||||
#include "../mwmechanics/alchemy.hpp"
|
||||
#include "../mwmechanics/spellutil.hpp"
|
||||
|
||||
#include "classmodel.hpp"
|
||||
|
||||
|
@ -65,9 +66,7 @@ namespace MWClass
|
|||
|
||||
int Potion::getValue(const MWWorld::ConstPtr& ptr) const
|
||||
{
|
||||
const MWWorld::LiveCellRef<ESM::Potion>* ref = ptr.get<ESM::Potion>();
|
||||
|
||||
return ref->mBase->mData.mValue;
|
||||
return MWMechanics::getPotionValue(*ptr.get<ESM::Potion>()->mBase);
|
||||
}
|
||||
|
||||
const ESM::RefId& Potion::getUpSoundId(const MWWorld::ConstPtr& ptr) const
|
||||
|
@ -101,7 +100,7 @@ namespace MWClass
|
|||
std::string text;
|
||||
|
||||
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
|
||||
text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}");
|
||||
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
|
||||
|
||||
info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects);
|
||||
|
||||
|
|
|
@ -250,7 +250,7 @@ const ESM::Potion* MWMechanics::Alchemy::getRecord(const ESM::Potion& toFind) co
|
|||
|
||||
if (iter->mName != toFind.mName || iter->mScript != toFind.mScript
|
||||
|| iter->mData.mWeight != toFind.mData.mWeight || iter->mData.mValue != toFind.mData.mValue
|
||||
|| iter->mData.mAutoCalc != toFind.mData.mAutoCalc)
|
||||
|| iter->mData.mFlags != toFind.mData.mFlags)
|
||||
continue;
|
||||
|
||||
// Don't choose an ID that came from the content files, would have unintended side effects
|
||||
|
@ -310,7 +310,7 @@ void MWMechanics::Alchemy::addPotion(const std::string& name)
|
|||
newRecord.mData.mWeight /= countIngredients();
|
||||
|
||||
newRecord.mData.mValue = mValue;
|
||||
newRecord.mData.mAutoCalc = 0;
|
||||
newRecord.mData.mFlags = 0;
|
||||
newRecord.mRecordFlags = 0;
|
||||
|
||||
newRecord.mName = name;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <limits>
|
||||
|
||||
#include <components/esm3/loadalch.hpp>
|
||||
#include <components/esm3/loadench.hpp>
|
||||
#include <components/esm3/loadmgef.hpp>
|
||||
|
||||
|
@ -48,7 +49,7 @@ namespace MWMechanics
|
|||
bool appliedOnce = magicEffect->mData.mFlags & ESM::MagicEffect::AppliedOnce;
|
||||
int minMagn = hasMagnitude ? effect.mMagnMin : 1;
|
||||
int maxMagn = hasMagnitude ? effect.mMagnMax : 1;
|
||||
if (method != EffectCostMethod::GameEnchantment)
|
||||
if (method == EffectCostMethod::PlayerSpell || method == EffectCostMethod::GameSpell)
|
||||
{
|
||||
minMagn = std::max(1, minMagn);
|
||||
maxMagn = std::max(1, maxMagn);
|
||||
|
@ -57,21 +58,28 @@ namespace MWMechanics
|
|||
if (!appliedOnce)
|
||||
duration = std::max(1, duration);
|
||||
static const float fEffectCostMult = store.get<ESM::GameSetting>().find("fEffectCostMult")->mValue.getFloat();
|
||||
static const float iAlchemyMod = store.get<ESM::GameSetting>().find("iAlchemyMod")->mValue.getFloat();
|
||||
|
||||
int durationOffset = 0;
|
||||
int minArea = 0;
|
||||
float costMult = fEffectCostMult;
|
||||
if (method == EffectCostMethod::PlayerSpell)
|
||||
{
|
||||
durationOffset = 1;
|
||||
minArea = 1;
|
||||
}
|
||||
else if (method == EffectCostMethod::GamePotion)
|
||||
{
|
||||
minArea = 1;
|
||||
costMult = iAlchemyMod;
|
||||
}
|
||||
|
||||
float x = 0.5 * (minMagn + maxMagn);
|
||||
x *= 0.1 * magicEffect->mData.mBaseCost;
|
||||
x *= durationOffset + duration;
|
||||
x += 0.05 * std::max(minArea, effect.mArea) * magicEffect->mData.mBaseCost;
|
||||
|
||||
return x * fEffectCostMult;
|
||||
return x * costMult;
|
||||
}
|
||||
|
||||
int calcSpellCost(const ESM::Spell& spell)
|
||||
|
@ -140,6 +148,16 @@ namespace MWMechanics
|
|||
return enchantment.mData.mCharge;
|
||||
}
|
||||
|
||||
int getPotionValue(const ESM::Potion& potion)
|
||||
{
|
||||
if (potion.mData.mFlags & ESM::Potion::Autocalc)
|
||||
{
|
||||
float cost = getTotalCost(potion.mEffects, EffectCostMethod::GamePotion);
|
||||
return std::round(cost);
|
||||
}
|
||||
return potion.mData.mValue;
|
||||
}
|
||||
|
||||
float calcSpellBaseSuccessChance(const ESM::Spell* spell, const MWWorld::Ptr& actor, ESM::RefId* effectiveSchool)
|
||||
{
|
||||
// Morrowind for some reason uses a formula slightly different from magicka cost calculation
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace ESM
|
|||
struct ENAMstruct;
|
||||
struct Enchantment;
|
||||
struct MagicEffect;
|
||||
struct Potion;
|
||||
struct Spell;
|
||||
}
|
||||
|
||||
|
@ -23,6 +24,7 @@ namespace MWMechanics
|
|||
GameSpell,
|
||||
PlayerSpell,
|
||||
GameEnchantment,
|
||||
GamePotion,
|
||||
};
|
||||
|
||||
float calcEffectCost(const ESM::ENAMstruct& effect, const ESM::MagicEffect* magicEffect = nullptr,
|
||||
|
@ -33,6 +35,8 @@ namespace MWMechanics
|
|||
int getEffectiveEnchantmentCastCost(const ESM::Enchantment& enchantment, const MWWorld::Ptr& actor);
|
||||
int getEnchantmentCharge(const ESM::Enchantment& enchantment);
|
||||
|
||||
int getPotionValue(const ESM::Potion& potion);
|
||||
|
||||
/**
|
||||
* @param spell spell to cast
|
||||
* @param actor calculate spell success chance for this actor (depends on actor's skills)
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace ESM
|
|||
mName = esm.getHString();
|
||||
break;
|
||||
case fourCC("ALDT"):
|
||||
esm.getHT(mData.mWeight, mData.mValue, mData.mAutoCalc);
|
||||
esm.getHT(mData.mWeight, mData.mValue, mData.mFlags);
|
||||
hasData = true;
|
||||
break;
|
||||
case fourCC("ENAM"):
|
||||
|
@ -80,7 +80,7 @@ namespace ESM
|
|||
mRecordFlags = 0;
|
||||
mData.mWeight = 0;
|
||||
mData.mValue = 0;
|
||||
mData.mAutoCalc = 0;
|
||||
mData.mFlags = 0;
|
||||
mName.clear();
|
||||
mModel.clear();
|
||||
mIcon.clear();
|
||||
|
|
|
@ -25,11 +25,16 @@ namespace ESM
|
|||
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||
static std::string_view getRecordType() { return "Potion"; }
|
||||
|
||||
enum Flags
|
||||
{
|
||||
Autocalc = 1 // Determines value
|
||||
};
|
||||
|
||||
struct ALDTstruct
|
||||
{
|
||||
float mWeight;
|
||||
int32_t mValue;
|
||||
int32_t mAutoCalc;
|
||||
int32_t mFlags;
|
||||
};
|
||||
ALDTstruct mData;
|
||||
|
||||
|
|
Loading…
Reference in a new issue