2021-10-06 00:45:46 +00:00
|
|
|
#include "PhasmalistInventoryFunctions.h"
|
|
|
|
#include "skse64\GameExtraData.h"
|
|
|
|
#include "skse64\GameBSExtraData.h"
|
|
|
|
#include "skse64\GameRTTI.h"
|
|
|
|
#include "skse64\PapyrusWornObject.h"
|
|
|
|
#include "skse64\PapyrusEnchantment.h"
|
|
|
|
#include "skse64\PapyrusWeapon.h"
|
|
|
|
#include "skse64\PapyrusArmor.h"
|
|
|
|
#include "skse64\PapyrusBook.h"
|
|
|
|
#include "skse64\PapyrusSpell.h"
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
namespace PhasmalistScripts {
|
|
|
|
|
|
|
|
static constexpr float magicWeight = 0.1;
|
|
|
|
|
|
|
|
EntryDataList * getEntryData(TESObjectREFR *container) {
|
|
|
|
ExtraContainerChanges * ecc = DYNAMIC_CAST
|
|
|
|
(container->extraData.GetByType(kExtraData_ContainerChanges), BSExtraData, ExtraContainerChanges);
|
|
|
|
if (!ecc) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return ecc->data->objList;
|
|
|
|
}
|
|
|
|
|
|
|
|
float getMagicEffectStrength(EffectSetting * magicEffect, float magnitude, float area, float duration) {
|
|
|
|
float result = magicEffect->properties.baseCost;
|
|
|
|
if (magnitude > 0) {
|
|
|
|
result *= magnitude;
|
|
|
|
}
|
|
|
|
if (area > 0) {
|
|
|
|
result *= area;
|
|
|
|
}
|
|
|
|
if (duration > 0) {
|
|
|
|
result *= duration;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
float getEnchantmentStrength(EnchantmentItem * ench) {
|
|
|
|
if (!ench) {
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
float result = 0;
|
|
|
|
for (int i = papyrusEnchantment::GetNumEffects(ench) - 1; i >= 0; i--) {
|
|
|
|
result += getMagicEffectStrength(
|
|
|
|
papyrusEnchantment::GetNthEffectMagicEffect(ench, i),
|
|
|
|
papyrusEnchantment::GetNthEffectMagnitude(ench, i),
|
|
|
|
papyrusEnchantment::GetNthEffectArea(ench, i),
|
2021-11-29 20:42:09 +00:00
|
|
|
papyrusEnchantment::GetNthEffectDuration(ench, i)
|
|
|
|
);
|
2021-10-06 00:45:46 +00:00
|
|
|
}
|
|
|
|
return result * magicWeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
float getSpellStrength(SpellItem * spell) {
|
|
|
|
if (!spell) {
|
|
|
|
return 0.0;
|
|
|
|
}
|
2021-11-29 20:42:09 +00:00
|
|
|
/*
|
|
|
|
* // Sum of effect costs
|
2021-10-06 00:45:46 +00:00
|
|
|
float result = 0;
|
|
|
|
for (int i = papyrusSpell::GetNumEffects(spell) - 1; i >= 0; i--) {
|
|
|
|
result += getMagicEffectStrength(
|
|
|
|
papyrusSpell::GetNthEffectMagicEffect(spell, i),
|
|
|
|
papyrusSpell::GetNthEffectMagnitude(spell, i),
|
|
|
|
papyrusSpell::GetNthEffectDuration(spell, i),
|
|
|
|
papyrusSpell::GetNthEffectArea(spell, i));
|
|
|
|
}
|
2021-11-29 20:42:09 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* // The costliest effect
|
|
|
|
int iCostliestEffect = papyrusSpell::GetCostliestEffectIndex(spell);
|
|
|
|
|
|
|
|
float result = getMagicEffectStrength(
|
|
|
|
papyrusSpell::GetNthEffectMagicEffect(spell, iCostliestEffect),
|
|
|
|
papyrusSpell::GetNthEffectMagnitude(spell, iCostliestEffect),
|
|
|
|
papyrusSpell::GetNthEffectDuration(spell, iCostliestEffect),
|
|
|
|
papyrusSpell::GetNthEffectArea(spell, iCostliestEffect)
|
|
|
|
);
|
|
|
|
*/
|
|
|
|
|
|
|
|
// 2.0.10: Switch to flat magicka correlation
|
|
|
|
return papyrusSpell::GetMagickaCost(spell) * 1.5;
|
2021-10-06 00:45:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
float getAdditionalExtendDataStrength(InventoryEntryData * itemStack, float physicalStrength) {
|
|
|
|
float strength = 0;
|
|
|
|
for (int i = itemStack->extendDataList->Count() - 1; i >= 0; i--) {
|
|
|
|
BaseExtraList * extraData = itemStack->extendDataList->GetNthItem(i);
|
|
|
|
if (!extraData) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
ExtraCount * exCount = DYNAMIC_CAST(extraData->GetByType(kExtraData_Count), BSExtraData, ExtraCount);
|
|
|
|
int count = 1;
|
|
|
|
if (exCount) {
|
|
|
|
count = exCount->count;
|
|
|
|
}
|
|
|
|
if (extraData->HasType(kExtraData_Enchantment)) {
|
|
|
|
//item has been enchanted
|
|
|
|
EnchantmentItem * ench = referenceUtils::GetEnchantment(extraData);
|
|
|
|
strength += getEnchantmentStrength(ench) * count;
|
|
|
|
}
|
|
|
|
if (extraData->HasType(kExtraData_Health)) {
|
|
|
|
//item has been tempered
|
|
|
|
ExtraHealth * health = DYNAMIC_CAST(extraData->GetByType(kExtraData_Health), BSExtraData, ExtraHealth);
|
|
|
|
if (health) {
|
2021-11-29 20:42:09 +00:00
|
|
|
strength += physicalStrength * (health->health - 1.0) * 20 * count;
|
2021-10-06 00:45:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return strength;
|
|
|
|
}
|
|
|
|
|
|
|
|
float getItemStackStrength(InventoryEntryData * itemStack) {
|
|
|
|
float strength = 0;
|
|
|
|
float physicalStrength = 0;
|
|
|
|
|
2022-07-28 14:36:17 +00:00
|
|
|
if (itemStack->type) {
|
|
|
|
if (itemStack->type->IsWeapon()) {
|
|
|
|
TESObjectWEAP* asWeapon = static_cast<TESObjectWEAP*>(itemStack->type);
|
|
|
|
if (asWeapon) {
|
|
|
|
float baseDmg = papyrusWeapon::GetBaseDamage(asWeapon) * 1.5;
|
|
|
|
float speed = papyrusWeapon::GetSpeed(asWeapon);
|
|
|
|
physicalStrength = baseDmg * speed;
|
|
|
|
strength += physicalStrength;
|
|
|
|
strength += getEnchantmentStrength(papyrusWeapon::GetEnchantment(asWeapon));
|
|
|
|
}
|
2021-10-06 00:45:46 +00:00
|
|
|
}
|
|
|
|
|
2022-07-28 14:36:17 +00:00
|
|
|
if (itemStack->type->IsArmor()) {
|
|
|
|
TESObjectARMO* asArmor = static_cast<TESObjectARMO*>(itemStack->type);
|
|
|
|
if (asArmor) {
|
|
|
|
physicalStrength = papyrusArmor::GetArmorRating(asArmor);
|
|
|
|
strength += physicalStrength;
|
|
|
|
strength += getEnchantmentStrength(papyrusArmor::GetEnchantment(asArmor));
|
|
|
|
}
|
2021-10-06 00:45:46 +00:00
|
|
|
}
|
|
|
|
|
2022-07-28 14:36:17 +00:00
|
|
|
if (itemStack->type->formType == kFormType_Book) {
|
|
|
|
TESObjectBOOK* asBook = static_cast<TESObjectBOOK*>(itemStack->type);
|
|
|
|
if (asBook) {
|
|
|
|
SpellItem* spell = papyrusBook::GetSpell(asBook);
|
|
|
|
return getSpellStrength(spell);
|
|
|
|
}
|
2021-10-06 00:45:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
strength = strength * itemStack->countDelta;
|
|
|
|
|
|
|
|
strength += getAdditionalExtendDataStrength(itemStack, physicalStrength);
|
|
|
|
|
|
|
|
return strength;
|
|
|
|
}
|
|
|
|
|
|
|
|
float calculateContentStrength(StaticFunctionTag * tag, TESObjectREFR *container) {
|
|
|
|
if (!container) {
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
float strength = 0;
|
|
|
|
for (int i = getEntryData(container)->Count() - 1; i >= 0; --i) {
|
|
|
|
InventoryEntryData * ed = getEntryData(container)->GetNthItem(i);
|
|
|
|
if (!ed) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
strength += getItemStackStrength(ed);
|
|
|
|
}
|
|
|
|
return strength;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RegisterFuncs(VMClassRegistry* registry) {
|
|
|
|
registry->RegisterFunction(
|
|
|
|
new NativeFunction1<StaticFunctionTag, float, TESObjectREFR *>("calculateContentStrength", "EnderalLib", PhasmalistScripts::calculateContentStrength, registry));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|