mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-28 19:21:04 +00:00
Implement auto calculated potion values
This commit is contained in:
parent
e6f64f5e71
commit
958f70736f
@ -154,6 +154,7 @@
|
|||||||
Bug #7832: Ingredient tooltips show magnitude for Fortify Maximum Magicka effect
|
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 #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 #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 #2566: Handle NAM9 records for manual cell references
|
||||||
Feature #3537: Shader-based water ripples
|
Feature #3537: Shader-based water ripples
|
||||||
Feature #5173: Support for NiFogProperty
|
Feature #5173: Support for NiFogProperty
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "labels.hpp"
|
#include "labels.hpp"
|
||||||
|
|
||||||
|
#include <components/esm3/loadalch.hpp>
|
||||||
#include <components/esm3/loadbody.hpp>
|
#include <components/esm3/loadbody.hpp>
|
||||||
#include <components/esm3/loadcell.hpp>
|
#include <components/esm3/loadcell.hpp>
|
||||||
#include <components/esm3/loadcont.hpp>
|
#include <components/esm3/loadcont.hpp>
|
||||||
@ -987,3 +988,16 @@ std::string recordFlags(uint32_t flags)
|
|||||||
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
properties += Misc::StringUtils::format("(0x%08X)", flags);
|
||||||
return properties;
|
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 lightFlags(int flags);
|
||||||
std::string magicEffectFlags(int flags);
|
std::string magicEffectFlags(int flags);
|
||||||
std::string npcFlags(int flags);
|
std::string npcFlags(int flags);
|
||||||
|
std::string potionFlags(int flags);
|
||||||
std::string raceFlags(int flags);
|
std::string raceFlags(int flags);
|
||||||
std::string spellFlags(int flags);
|
std::string spellFlags(int flags);
|
||||||
std::string weaponFlags(int flags);
|
std::string weaponFlags(int flags);
|
||||||
|
@ -479,7 +479,7 @@ namespace EsmTool
|
|||||||
std::cout << " Script: " << mData.mScript << std::endl;
|
std::cout << " Script: " << mData.mScript << std::endl;
|
||||||
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
|
std::cout << " Weight: " << mData.mData.mWeight << std::endl;
|
||||||
std::cout << " Value: " << mData.mData.mValue << 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);
|
printEffectList(mData.mEffects);
|
||||||
std::cout << " Deleted: " << mIsDeleted << std::endl;
|
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)));
|
data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Potion)));
|
||||||
|
|
||||||
if (column == mAutoCalc)
|
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()
|
// to show nested tables in dialogue subview, see IdTree::hasChildren()
|
||||||
if (column == mColumns.mEffects)
|
if (column == mColumns.mEffects)
|
||||||
@ -51,7 +51,7 @@ void CSMWorld::PotionRefIdAdapter::setData(
|
|||||||
ESM::Potion potion = record.get();
|
ESM::Potion potion = record.get();
|
||||||
|
|
||||||
if (column == mAutoCalc)
|
if (column == mAutoCalc)
|
||||||
potion.mData.mAutoCalc = value.toInt();
|
potion.mData.mFlags = value.toBool();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
InventoryRefIdAdapter<ESM::Potion>::setData(column, data, index, value);
|
InventoryRefIdAdapter<ESM::Potion>::setData(column, data, index, value);
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "../mwrender/renderinginterface.hpp"
|
#include "../mwrender/renderinginterface.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/alchemy.hpp"
|
#include "../mwmechanics/alchemy.hpp"
|
||||||
|
#include "../mwmechanics/spellutil.hpp"
|
||||||
|
|
||||||
#include "classmodel.hpp"
|
#include "classmodel.hpp"
|
||||||
|
|
||||||
@ -65,9 +66,7 @@ namespace MWClass
|
|||||||
|
|
||||||
int Potion::getValue(const MWWorld::ConstPtr& ptr) const
|
int Potion::getValue(const MWWorld::ConstPtr& ptr) const
|
||||||
{
|
{
|
||||||
const MWWorld::LiveCellRef<ESM::Potion>* ref = ptr.get<ESM::Potion>();
|
return MWMechanics::getPotionValue(*ptr.get<ESM::Potion>()->mBase);
|
||||||
|
|
||||||
return ref->mBase->mData.mValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ESM::RefId& Potion::getUpSoundId(const MWWorld::ConstPtr& ptr) const
|
const ESM::RefId& Potion::getUpSoundId(const MWWorld::ConstPtr& ptr) const
|
||||||
@ -101,7 +100,7 @@ namespace MWClass
|
|||||||
std::string text;
|
std::string text;
|
||||||
|
|
||||||
text += "\n#{sWeight}: " + MWGui::ToolTips::toString(ref->mBase->mData.mWeight);
|
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);
|
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
|
if (iter->mName != toFind.mName || iter->mScript != toFind.mScript
|
||||||
|| iter->mData.mWeight != toFind.mData.mWeight || iter->mData.mValue != toFind.mData.mValue
|
|| 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;
|
continue;
|
||||||
|
|
||||||
// Don't choose an ID that came from the content files, would have unintended side effects
|
// 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.mWeight /= countIngredients();
|
||||||
|
|
||||||
newRecord.mData.mValue = mValue;
|
newRecord.mData.mValue = mValue;
|
||||||
newRecord.mData.mAutoCalc = 0;
|
newRecord.mData.mFlags = 0;
|
||||||
newRecord.mRecordFlags = 0;
|
newRecord.mRecordFlags = 0;
|
||||||
|
|
||||||
newRecord.mName = name;
|
newRecord.mName = name;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
#include <components/esm3/loadalch.hpp>
|
||||||
#include <components/esm3/loadench.hpp>
|
#include <components/esm3/loadench.hpp>
|
||||||
#include <components/esm3/loadmgef.hpp>
|
#include <components/esm3/loadmgef.hpp>
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ namespace MWMechanics
|
|||||||
bool appliedOnce = magicEffect->mData.mFlags & ESM::MagicEffect::AppliedOnce;
|
bool appliedOnce = magicEffect->mData.mFlags & ESM::MagicEffect::AppliedOnce;
|
||||||
int minMagn = hasMagnitude ? effect.mMagnMin : 1;
|
int minMagn = hasMagnitude ? effect.mMagnMin : 1;
|
||||||
int maxMagn = hasMagnitude ? effect.mMagnMax : 1;
|
int maxMagn = hasMagnitude ? effect.mMagnMax : 1;
|
||||||
if (method != EffectCostMethod::GameEnchantment)
|
if (method == EffectCostMethod::PlayerSpell || method == EffectCostMethod::GameSpell)
|
||||||
{
|
{
|
||||||
minMagn = std::max(1, minMagn);
|
minMagn = std::max(1, minMagn);
|
||||||
maxMagn = std::max(1, maxMagn);
|
maxMagn = std::max(1, maxMagn);
|
||||||
@ -57,21 +58,28 @@ namespace MWMechanics
|
|||||||
if (!appliedOnce)
|
if (!appliedOnce)
|
||||||
duration = std::max(1, duration);
|
duration = std::max(1, duration);
|
||||||
static const float fEffectCostMult = store.get<ESM::GameSetting>().find("fEffectCostMult")->mValue.getFloat();
|
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 durationOffset = 0;
|
||||||
int minArea = 0;
|
int minArea = 0;
|
||||||
|
float costMult = fEffectCostMult;
|
||||||
if (method == EffectCostMethod::PlayerSpell)
|
if (method == EffectCostMethod::PlayerSpell)
|
||||||
{
|
{
|
||||||
durationOffset = 1;
|
durationOffset = 1;
|
||||||
minArea = 1;
|
minArea = 1;
|
||||||
}
|
}
|
||||||
|
else if (method == EffectCostMethod::GamePotion)
|
||||||
|
{
|
||||||
|
minArea = 1;
|
||||||
|
costMult = iAlchemyMod;
|
||||||
|
}
|
||||||
|
|
||||||
float x = 0.5 * (minMagn + maxMagn);
|
float x = 0.5 * (minMagn + maxMagn);
|
||||||
x *= 0.1 * magicEffect->mData.mBaseCost;
|
x *= 0.1 * magicEffect->mData.mBaseCost;
|
||||||
x *= durationOffset + duration;
|
x *= durationOffset + duration;
|
||||||
x += 0.05 * std::max(minArea, effect.mArea) * magicEffect->mData.mBaseCost;
|
x += 0.05 * std::max(minArea, effect.mArea) * magicEffect->mData.mBaseCost;
|
||||||
|
|
||||||
return x * fEffectCostMult;
|
return x * costMult;
|
||||||
}
|
}
|
||||||
|
|
||||||
int calcSpellCost(const ESM::Spell& spell)
|
int calcSpellCost(const ESM::Spell& spell)
|
||||||
@ -140,6 +148,16 @@ namespace MWMechanics
|
|||||||
return enchantment.mData.mCharge;
|
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)
|
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
|
// Morrowind for some reason uses a formula slightly different from magicka cost calculation
|
||||||
|
@ -8,6 +8,7 @@ namespace ESM
|
|||||||
struct ENAMstruct;
|
struct ENAMstruct;
|
||||||
struct Enchantment;
|
struct Enchantment;
|
||||||
struct MagicEffect;
|
struct MagicEffect;
|
||||||
|
struct Potion;
|
||||||
struct Spell;
|
struct Spell;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,6 +24,7 @@ namespace MWMechanics
|
|||||||
GameSpell,
|
GameSpell,
|
||||||
PlayerSpell,
|
PlayerSpell,
|
||||||
GameEnchantment,
|
GameEnchantment,
|
||||||
|
GamePotion,
|
||||||
};
|
};
|
||||||
|
|
||||||
float calcEffectCost(const ESM::ENAMstruct& effect, const ESM::MagicEffect* magicEffect = nullptr,
|
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 getEffectiveEnchantmentCastCost(const ESM::Enchantment& enchantment, const MWWorld::Ptr& actor);
|
||||||
int getEnchantmentCharge(const ESM::Enchantment& enchantment);
|
int getEnchantmentCharge(const ESM::Enchantment& enchantment);
|
||||||
|
|
||||||
|
int getPotionValue(const ESM::Potion& potion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param spell spell to cast
|
* @param spell spell to cast
|
||||||
* @param actor calculate spell success chance for this actor (depends on actor's skills)
|
* @param actor calculate spell success chance for this actor (depends on actor's skills)
|
||||||
|
@ -36,7 +36,7 @@ namespace ESM
|
|||||||
mName = esm.getHString();
|
mName = esm.getHString();
|
||||||
break;
|
break;
|
||||||
case fourCC("ALDT"):
|
case fourCC("ALDT"):
|
||||||
esm.getHT(mData.mWeight, mData.mValue, mData.mAutoCalc);
|
esm.getHT(mData.mWeight, mData.mValue, mData.mFlags);
|
||||||
hasData = true;
|
hasData = true;
|
||||||
break;
|
break;
|
||||||
case fourCC("ENAM"):
|
case fourCC("ENAM"):
|
||||||
@ -80,7 +80,7 @@ namespace ESM
|
|||||||
mRecordFlags = 0;
|
mRecordFlags = 0;
|
||||||
mData.mWeight = 0;
|
mData.mWeight = 0;
|
||||||
mData.mValue = 0;
|
mData.mValue = 0;
|
||||||
mData.mAutoCalc = 0;
|
mData.mFlags = 0;
|
||||||
mName.clear();
|
mName.clear();
|
||||||
mModel.clear();
|
mModel.clear();
|
||||||
mIcon.clear();
|
mIcon.clear();
|
||||||
|
@ -25,11 +25,16 @@ namespace ESM
|
|||||||
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||||
static std::string_view getRecordType() { return "Potion"; }
|
static std::string_view getRecordType() { return "Potion"; }
|
||||||
|
|
||||||
|
enum Flags
|
||||||
|
{
|
||||||
|
Autocalc = 1 // Determines value
|
||||||
|
};
|
||||||
|
|
||||||
struct ALDTstruct
|
struct ALDTstruct
|
||||||
{
|
{
|
||||||
float mWeight;
|
float mWeight;
|
||||||
int32_t mValue;
|
int32_t mValue;
|
||||||
int32_t mAutoCalc;
|
int32_t mFlags;
|
||||||
};
|
};
|
||||||
ALDTstruct mData;
|
ALDTstruct mData;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user