#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 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), papyrusEnchantment::GetNthEffectDuration(ench, i) ); } return result * magicWeight; } float getSpellStrength(SpellItem * spell) { if (!spell) { return 0.0; } /* * // Sum of effect costs 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)); } */ /* * // 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; } 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) { strength += physicalStrength * (health->health - 1.0) * 20 * count; } } } return strength; } float getItemStackStrength(InventoryEntryData * itemStack) { float strength = 0; float physicalStrength = 0; if (itemStack->type) { if (itemStack->type->IsWeapon()) { TESObjectWEAP* asWeapon = static_cast(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)); } } if (itemStack->type->IsArmor()) { TESObjectARMO* asArmor = static_cast(itemStack->type); if (asArmor) { physicalStrength = papyrusArmor::GetArmorRating(asArmor); strength += physicalStrength; strength += getEnchantmentStrength(papyrusArmor::GetEnchantment(asArmor)); } } if (itemStack->type->formType == kFormType_Book) { TESObjectBOOK* asBook = static_cast(itemStack->type); if (asBook) { SpellItem* spell = papyrusBook::GetSpell(asBook); return getSpellStrength(spell); } } } 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("calculateContentStrength", "EnderalLib", PhasmalistScripts::calculateContentStrength, registry)); return true; } }