From 32f945ccd9782c9dcaad2af002f1b0c4e512311a Mon Sep 17 00:00:00 2001 From: FlufflesTheMicrosaur Date: Tue, 25 Nov 2025 00:11:10 -0800 Subject: [PATCH 1/2] feat: 104963: initial code for unknown damage --- Mammoth/Include/TSETypes.h | 21 +++++++++++++++++++-- Mammoth/TSE/CDamageAdjDesc.cpp | 1 + Mammoth/TSE/Damage.cpp | 25 +++++++++++++++++++------ 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/Mammoth/Include/TSETypes.h b/Mammoth/Include/TSETypes.h index fb39171e9..cb70428b0 100644 --- a/Mammoth/Include/TSETypes.h +++ b/Mammoth/Include/TSETypes.h @@ -226,9 +226,26 @@ extern Metric g_TimeScale; extern Metric g_SecondsPerUpdate; // Damage Types --------------------------------------------------------------- - +// +// There are several classes of damage types: +// +// Listed damage: the standard damage types in the game +// These are subjected to ingame resistances and bonuses like +// damageAdj +// +// Unlisted damage: special purpose damage types +// Generic: deals true damage that ignores normal damageAdj +// Null: does not deal damage and is not treated as hostile, but +// activates on hit events and applies status effects +// +// Invalid damage: these are not real damage types +// Error: this is applied when an invalid damage type is selected, or +// a parsing error was encountered +// Unknown: this is applied to unknown virtual items for UI purposes +// enum DamageTypes { + damageUnknown = -101, // unknown damage damageError = -100, // invalid damage damageNull = -2, // null damage damageGeneric = -1, // generic damage @@ -238,7 +255,7 @@ enum DamageTypes damageParticle = 2, // charged particle beam damageBlast = 3, // chemical explosives damageIonRadiation = 4, // ionizing radiation - damageThermonuclear = 5, // hydrogen bomb + damageThermonuclear = 5, // fission bomb damagePositron = 6, // anti-matter charged particles damagePlasma = 7, // fusion weapons damageAntiMatter = 8, // anti-matter torpedo diff --git a/Mammoth/TSE/CDamageAdjDesc.cpp b/Mammoth/TSE/CDamageAdjDesc.cpp index e546d1324..96fffc055 100644 --- a/Mammoth/TSE/CDamageAdjDesc.cpp +++ b/Mammoth/TSE/CDamageAdjDesc.cpp @@ -124,6 +124,7 @@ int CDamageAdjDesc::GetAdj (DamageTypes iDamageType) const case damageGeneric: return 100; case damageNull: + case damageUnknown: case damageError: return 0; default: diff --git a/Mammoth/TSE/Damage.cpp b/Mammoth/TSE/Damage.cpp index 08965aed6..4b7f31a3a 100644 --- a/Mammoth/TSE/Damage.cpp +++ b/Mammoth/TSE/Damage.cpp @@ -139,6 +139,8 @@ CString GetDamageName (DamageTypes iType) return CONSTLIT("generic"); else if (iType == damageNull) return CONSTLIT("null"); + else if (iType == damageUnknown) + return CONSTLIT("unknown"); else return CString(DAMAGE_TYPE_DATA[iType].pszName); } @@ -154,6 +156,8 @@ CString GetDamageShortName (DamageTypes iType) return CONSTLIT("generic"); else if (iType == damageNull) return CONSTLIT("null"); + else if (iType == damageUnknown) + return CONSTLIT("unknown"); else return CString(DAMAGE_TYPE_DATA[iType].pszShortName); } @@ -169,6 +173,11 @@ CString GetDamageType (DamageTypes iType) return CONSTLIT("generic"); else if (iType == damageNull) return CONSTLIT("null"); + // unknownDamage is a special case: + // It cant normally be set, but exists on unknown virtual items for UI + // If you try to query it, you get generic damage back as a placeholder + else if (iType == damageUnknown) + return CONSTLIT("generic"); else return CString(DAMAGE_TYPE_DATA[iType].pszID); } @@ -205,6 +214,8 @@ DamageTypes LoadDamageTypeFromXML (const CString &sAttrib) else if (strEquals(sAttrib, CONSTLIT("dark fire"))) return damageDarkFire; + // Invalid damage types + return damageError; } @@ -387,27 +398,29 @@ bool DamageDesc::IsHostile () const ); } -int DamageDesc::GetDamageLevel (DamageTypes iType) - // GetDamageTier // // Returns the damage tier based on damage type. +// Intended to be used for default balance stats +// +int DamageDesc::GetDamageLevel (DamageTypes iType) { - if (iType == damageGeneric || iType == damageNull) + if (iType < damageMinListed || iType > damageMaxListed) return 1; else return DAMAGE_TYPE_DATA[iType].iLevel; } -int DamageDesc::GetDamageTier (DamageTypes iType) - // GetDamageTier // // Returns the damage tier based on damage type. +// Intended to be used for default balance stats +// +int DamageDesc::GetDamageTier (DamageTypes iType) { - if (iType == damageGeneric || iType == damageNull) + if (iType < damageMinListed || iType > damageMaxListed) return 1; else return DAMAGE_TYPE_DATA[iType].iTier; From 85393be658fd5b5ae785f8712ea19b8e2df04be1 Mon Sep 17 00:00:00 2001 From: FlufflesTheMicrosaur Date: Tue, 25 Nov 2025 01:02:51 -0800 Subject: [PATCH 2/2] feat: 104963: create unknown UI reference string --- Mammoth/TSE/CWeaponClass.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Mammoth/TSE/CWeaponClass.cpp b/Mammoth/TSE/CWeaponClass.cpp index f3184ed95..d26bf9595 100644 --- a/Mammoth/TSE/CWeaponClass.cpp +++ b/Mammoth/TSE/CWeaponClass.cpp @@ -3561,8 +3561,13 @@ bool CWeaponClass::GetReferenceDamageType (CItemCtx &Ctx, const CItem &Ammo, Dam CString sFireRate = GetReferenceFireRate(iShotDelay); // Compute the damage string and special string - - if (IsLauncherWithAmmo() && Ammo.IsEmpty()) + + if (!Item.IsKnown()) + { + sReference = CONSTLIT("Unknown ? hp/sec (? hp/shot) • ? ls range • ? shots/sec"); + iDamageType = damageUnknown; + } + else if (IsLauncherWithAmmo() && Ammo.IsEmpty()) { sReference = CONSTLIT("missile launcher");