diff --git a/core/armor_system.py b/core/armor_system.py index c19101f..cf97cb5 100644 --- a/core/armor_system.py +++ b/core/armor_system.py @@ -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]: