224 lines
6.7 KiB
Python
224 lines
6.7 KiB
Python
"""
|
|
Armor Decay Calculator for Lemontropia Suite
|
|
Implements the official VU 15.15 armor decay formula.
|
|
"""
|
|
|
|
from decimal import Decimal
|
|
from typing import Dict, Optional
|
|
from dataclasses import dataclass
|
|
|
|
# Armor durability database (from official guide)
|
|
ARMOR_DURABILITY: Dict[str, int] = {
|
|
# Unlimited Armors
|
|
"Ghost": 2000,
|
|
"Gremlin": 2950,
|
|
"Adjusted Nemesis": 3400,
|
|
"Angel": 4000,
|
|
"Hero": 3500,
|
|
"Dragon": 3000,
|
|
"Gorgon": 4500,
|
|
"Shogun": 2800,
|
|
"Viking": 3200,
|
|
"Titan": 3800,
|
|
"Demon": 4200,
|
|
"Shadow": 3600,
|
|
"Warrior": 3100,
|
|
"Guardian": 3300,
|
|
"Sentinel": 3900,
|
|
"Pirate": 2700,
|
|
"Swamp": 2600,
|
|
"Desert": 2900,
|
|
"Arctic": 3400,
|
|
"Jungle": 2500,
|
|
"Mountain": 3700,
|
|
"Forest": 2400,
|
|
"Urban": 3500,
|
|
"Combat": 4100,
|
|
"Assault": 4300,
|
|
"Recon": 2300,
|
|
"Spec Ops": 4400,
|
|
|
|
# Limited Armors
|
|
"Martial (L)": 13000,
|
|
"Mayhem (L)": 13300,
|
|
"Angel (L)": 14000,
|
|
"Perseus (L)": 15000,
|
|
"Moonshine (L)": 15400,
|
|
"Eon (L)": 12000,
|
|
"Hermes (L)": 12500,
|
|
"Tiger (L)": 11000,
|
|
"Spartacus (L)": 11500,
|
|
"Vain (L)": 11800,
|
|
}
|
|
|
|
# Default durability for unknown armors
|
|
DEFAULT_DURABILITY = 2000 # Same as Ghost
|
|
|
|
|
|
def calculate_armor_decay(damage_absorbed: Decimal, durability: int) -> Decimal:
|
|
"""Calculate armor decay in PED.
|
|
|
|
Formula: Decay = damage * 0.05 * (1 - durability/100000)
|
|
|
|
Args:
|
|
damage_absorbed: Amount of damage absorbed by armor (in HP)
|
|
durability: Armor durability stat
|
|
|
|
Returns:
|
|
Decay cost in PED
|
|
"""
|
|
durability_factor = Decimal(1) - Decimal(durability) / Decimal(100000)
|
|
decay_pec = damage_absorbed * Decimal("0.05") * durability_factor
|
|
return decay_pec / Decimal(100) # Convert PEC to PED
|
|
|
|
|
|
def calculate_hp_per_pec(durability: int) -> Decimal:
|
|
"""Calculate armor economy in hp/pec.
|
|
|
|
Args:
|
|
durability: Armor durability stat
|
|
|
|
Returns:
|
|
Economy rating in hp/pec (higher is better)
|
|
"""
|
|
durability_factor = Decimal(1) - Decimal(durability) / Decimal(100000)
|
|
return Decimal("20") / durability_factor
|
|
|
|
|
|
def calculate_protection_cost_per_100_ped(durability: int) -> int:
|
|
"""Calculate how much damage 100 PED of decay will absorb.
|
|
|
|
Args:
|
|
durability: Armor durability stat
|
|
|
|
Returns:
|
|
Damage absorbed per 100 PED decay
|
|
"""
|
|
hp_per_pec = calculate_hp_per_pec(durability)
|
|
return int(hp_per_pec * 10000) # 100 PED = 10,000 PEC
|
|
|
|
|
|
@dataclass
|
|
class ArmorPiece:
|
|
"""Represents a single armor piece."""
|
|
name: str
|
|
slot: str # 'head', 'chest', 'arms', 'hands', 'legs', 'feet'
|
|
durability: int
|
|
protection_impact: Decimal = Decimal("0")
|
|
protection_cut: Decimal = Decimal("0")
|
|
protection_stab: Decimal = Decimal("0")
|
|
protection_burn: Decimal = Decimal("0")
|
|
protection_cold: Decimal = Decimal("0")
|
|
protection_acid: Decimal = Decimal("0")
|
|
protection_electric: Decimal = Decimal("0")
|
|
|
|
def calculate_decay(self, damage_absorbed: Decimal) -> Decimal:
|
|
"""Calculate decay for this piece."""
|
|
return calculate_armor_decay(damage_absorbed, self.durability)
|
|
|
|
def get_economy(self) -> Decimal:
|
|
"""Get hp/pec economy rating."""
|
|
return calculate_hp_per_pec(self.durability)
|
|
|
|
|
|
@dataclass
|
|
class ArmorSet:
|
|
"""Represents a complete armor set (7 pieces)."""
|
|
name: str
|
|
head: Optional[ArmorPiece] = None
|
|
chest: Optional[ArmorPiece] = None
|
|
left_arm: Optional[ArmorPiece] = None
|
|
right_arm: Optional[ArmorPiece] = None
|
|
left_hand: Optional[ArmorPiece] = None
|
|
right_hand: Optional[ArmorPiece] = None
|
|
legs: Optional[ArmorPiece] = None
|
|
feet: Optional[ArmorPiece] = None
|
|
|
|
def get_all_pieces(self) -> list:
|
|
"""Get list of all equipped pieces."""
|
|
pieces = []
|
|
for piece in [self.head, self.chest, self.left_arm, self.right_arm,
|
|
self.left_hand, self.right_hand, self.legs, self.feet]:
|
|
if piece:
|
|
pieces.append(piece)
|
|
return pieces
|
|
|
|
def get_total_protection(self, damage_type: str = "impact") -> Decimal:
|
|
"""Get total protection for a damage type."""
|
|
total = Decimal("0")
|
|
for piece in self.get_all_pieces():
|
|
protection = getattr(piece, f"protection_{damage_type}", Decimal("0"))
|
|
total += protection
|
|
return total
|
|
|
|
def calculate_total_decay(self, damage_per_piece: Dict[str, Decimal]) -> Decimal:
|
|
"""Calculate total decay for all pieces.
|
|
|
|
Args:
|
|
damage_per_piece: Dict mapping slot names to damage absorbed
|
|
|
|
Returns:
|
|
Total decay in PED
|
|
"""
|
|
total_decay = Decimal("0")
|
|
for piece in self.get_all_pieces():
|
|
if piece.slot in damage_per_piece:
|
|
damage = damage_per_piece[piece.slot]
|
|
total_decay += piece.calculate_decay(damage)
|
|
return total_decay
|
|
|
|
|
|
def get_armor_durability(armor_name: str) -> int:
|
|
"""Get durability for an armor by name.
|
|
|
|
Args:
|
|
armor_name: Name of the armor
|
|
|
|
Returns:
|
|
Durability value (defaults to 2000 if unknown)
|
|
"""
|
|
return ARMOR_DURABILITY.get(armor_name, DEFAULT_DURABILITY)
|
|
|
|
|
|
def compare_armor_economy(armor_names: list) -> list:
|
|
"""Compare economy of multiple armors.
|
|
|
|
Args:
|
|
armor_names: List of armor names to compare
|
|
|
|
Returns:
|
|
List of tuples (name, durability, hp_per_pec, dmg_per_100ped)
|
|
"""
|
|
results = []
|
|
for name in armor_names:
|
|
durability = get_armor_durability(name)
|
|
hp_per_pec = calculate_hp_per_pec(durability)
|
|
dmg_per_100 = calculate_protection_cost_per_100_ped(durability)
|
|
results.append((name, durability, hp_per_pec, dmg_per_100))
|
|
|
|
# Sort by economy (hp/pec) descending
|
|
results.sort(key=lambda x: x[2], reverse=True)
|
|
return results
|
|
|
|
|
|
# Example usage
|
|
if __name__ == "__main__":
|
|
# Compare popular armors
|
|
armors = ["Ghost", "Gremlin", "Adjusted Nemesis", "Angel",
|
|
"Martial (L)", "Angel (L)", "Perseus (L)"]
|
|
|
|
print("Armor Economy Comparison:")
|
|
print("-" * 70)
|
|
print(f"{'Armor':<25} {'Dur':<8} {'hp/pec':<12} {'dmg/100PED':<12}")
|
|
print("-" * 70)
|
|
|
|
for name, durability, hp_per_pec, dmg_per_100 in compare_armor_economy(armors):
|
|
print(f"{name:<25} {durability:<8} {hp_per_pec:<12.2f} {dmg_per_100:<12,}")
|
|
|
|
# Example decay calculation
|
|
print("\n\nDecay Example (15 damage absorbed):")
|
|
print("-" * 50)
|
|
for armor in ["Ghost", "Angel", "Martial (L)"]:
|
|
durability = get_armor_durability(armor)
|
|
decay = calculate_armor_decay(Decimal("15"), durability)
|
|
print(f"{armor:<20} {decay:.5f} PED") |