feat(armor): final armor system updates from agent swarm

This commit is contained in:
LemonNexus 2026-02-09 10:33:32 +00:00
parent 5b4a8f07ea
commit b59b016c86
1 changed files with 45 additions and 11 deletions

View File

@ -199,12 +199,18 @@ class ArmorPiece:
"""
Individual armor piece (e.g., Ghost Helmet, Shogun Harness).
Each piece protects one slot and can have one plate attached.
Loot 2.0 Mechanics (June 2017):
- Armor decay is LINEAR per damage point absorbed
- Base economy: 20 hp/pec (0.05 pec per hp)
- Armor only decays for damage it ACTUALLY absorbs (after plate)
- Plate absorbs FIRST, then armor takes remainder
"""
name: str
item_id: str
slot: ArmorSlot
set_name: Optional[str] = None # e.g., "Ghost", "Shogun"
decay_per_hit: Decimal = Decimal("0.05") # Decay in PEC when hit
decay_per_hp: Decimal = Decimal("0.05") # Decay in PEC per HP absorbed (20 hp/pec standard)
protection: ProtectionProfile = field(default_factory=ProtectionProfile)
durability: int = 10000
weight: Decimal = Decimal("1.0") # Weight in kg
@ -212,6 +218,9 @@ class ArmorPiece:
# Optional plate attachment
attached_plate: Optional[ArmorPlate] = None
# Loot 2.0: Economy standard is 20 hp/pec = 0.05 pec/hp
DEFAULT_ECONOMY: Decimal = Decimal("0.05") # 20 hp per pec
def get_base_protection(self) -> ProtectionProfile:
"""Get base protection without plate."""
return self.protection
@ -226,13 +235,24 @@ class ArmorPiece:
"""Get total protection value including plate."""
return self.get_total_protection().get_total()
def get_decay_for_hit(self, damage_after_plate: Decimal) -> Decimal:
def get_decay_for_damage(self, damage_absorbed: Decimal) -> Decimal:
"""
Calculate armor piece decay for taking damage.
Plate absorbs first, so damage_after_plate is what gets through.
Calculate armor decay for absorbing damage.
Loot 2.0 Formula:
- Decay is LINEAR per damage point
- Armor only decays for damage it ACTUALLY absorbs
- Base: 20 hp/pec = 0.05 pec per hp absorbed
Args:
damage_absorbed: Amount of damage the armor actually absorbed
Returns:
Decay in PEC
"""
# Base decay plus small amount per damage point that hits armor
return self.decay_per_hit + (damage_after_plate * Decimal("0.001"))
if damage_absorbed <= 0:
return Decimal("0")
return damage_absorbed * self.decay_per_hp
def attach_plate(self, plate: ArmorPlate) -> bool:
"""Attach a plate to this armor piece."""
@ -265,7 +285,7 @@ class ArmorPiece:
'item_id': self.item_id,
'slot': self.slot.value,
'set_name': self.set_name,
'decay_per_hit': str(self.decay_per_hit),
'decay_per_hp': str(self.decay_per_hp),
'protection': self.protection.to_dict(),
'durability': self.durability,
'weight': str(self.weight),
@ -280,7 +300,7 @@ class ArmorPiece:
item_id=data['item_id'],
slot=ArmorSlot(data['slot']),
set_name=data.get('set_name'),
decay_per_hit=Decimal(data['decay_per_hit']),
decay_per_hp=Decimal(data.get('decay_per_hp', '0.05')),
protection=ProtectionProfile.from_dict(data.get('protection', {})),
durability=data.get('durability', 10000),
weight=Decimal(data.get('weight', '1.0')),
@ -328,12 +348,26 @@ class ArmorSet:
return total
def get_total_decay_per_hit(self) -> Decimal:
"""Get total decay per hit across all pieces (including plates)."""
"""
Get total decay per hit across all pieces (including plates).
Note: This is an ESTIMATE assuming average damage absorption.
Actual decay depends on how much damage each piece absorbs.
"""
# This is a rough estimate - actual decay depends on damage absorbed
# Using a typical hit value of 10 hp for estimation
typical_hit = Decimal("10")
total = Decimal("0")
for piece in self.pieces.values():
total += piece.decay_per_hit
# Estimate armor decay (assuming it absorbs typical hit up to its protection)
armor_absorb = min(typical_hit, piece.protection.get_total())
total += piece.get_decay_for_damage(armor_absorb)
if piece.attached_plate:
total += piece.attached_plate.decay_per_hit
# Estimate plate decay
plate_absorb = min(typical_hit, piece.attached_plate.get_total_protection())
total += piece.attached_plate.get_decay_for_damage(plate_absorb)
return total
def get_pieces_list(self) -> List[ArmorPiece]: