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). Individual armor piece (e.g., Ghost Helmet, Shogun Harness).
Each piece protects one slot and can have one plate attached. 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 name: str
item_id: str item_id: str
slot: ArmorSlot slot: ArmorSlot
set_name: Optional[str] = None # e.g., "Ghost", "Shogun" 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) protection: ProtectionProfile = field(default_factory=ProtectionProfile)
durability: int = 10000 durability: int = 10000
weight: Decimal = Decimal("1.0") # Weight in kg weight: Decimal = Decimal("1.0") # Weight in kg
@ -212,6 +218,9 @@ class ArmorPiece:
# Optional plate attachment # Optional plate attachment
attached_plate: Optional[ArmorPlate] = None 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: def get_base_protection(self) -> ProtectionProfile:
"""Get base protection without plate.""" """Get base protection without plate."""
return self.protection return self.protection
@ -226,13 +235,24 @@ class ArmorPiece:
"""Get total protection value including plate.""" """Get total protection value including plate."""
return self.get_total_protection().get_total() 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. Calculate armor decay for absorbing damage.
Plate absorbs first, so damage_after_plate is what gets through.
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 if damage_absorbed <= 0:
return self.decay_per_hit + (damage_after_plate * Decimal("0.001")) return Decimal("0")
return damage_absorbed * self.decay_per_hp
def attach_plate(self, plate: ArmorPlate) -> bool: def attach_plate(self, plate: ArmorPlate) -> bool:
"""Attach a plate to this armor piece.""" """Attach a plate to this armor piece."""
@ -265,7 +285,7 @@ class ArmorPiece:
'item_id': self.item_id, 'item_id': self.item_id,
'slot': self.slot.value, 'slot': self.slot.value,
'set_name': self.set_name, '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(), 'protection': self.protection.to_dict(),
'durability': self.durability, 'durability': self.durability,
'weight': str(self.weight), 'weight': str(self.weight),
@ -280,7 +300,7 @@ class ArmorPiece:
item_id=data['item_id'], item_id=data['item_id'],
slot=ArmorSlot(data['slot']), slot=ArmorSlot(data['slot']),
set_name=data.get('set_name'), 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', {})), protection=ProtectionProfile.from_dict(data.get('protection', {})),
durability=data.get('durability', 10000), durability=data.get('durability', 10000),
weight=Decimal(data.get('weight', '1.0')), weight=Decimal(data.get('weight', '1.0')),
@ -328,12 +348,26 @@ class ArmorSet:
return total return total
def get_total_decay_per_hit(self) -> Decimal: 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") total = Decimal("0")
for piece in self.pieces.values(): 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: 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 return total
def get_pieces_list(self) -> List[ArmorPiece]: def get_pieces_list(self) -> List[ArmorPiece]: