From b8fc0a803338851d54ae1cb39d215a9faad7ae15 Mon Sep 17 00:00:00 2001 From: LemonNexus Date: Mon, 9 Feb 2026 15:47:53 +0000 Subject: [PATCH] fix(api): fix NexusPlate dataclass - add missing protection_acid and protection_electric fields - Added protection_acid and protection_electric to NexusPlate dataclass - Updated hardcoded plates to use individual protection fields - Fixed plate selector crash when sorting by protection --- core/nexus_full_api.py | 150 ++++++++++++++++++++++++++--------------- 1 file changed, 97 insertions(+), 53 deletions(-) diff --git a/core/nexus_full_api.py b/core/nexus_full_api.py index 32a5986..010f51f 100644 --- a/core/nexus_full_api.py +++ b/core/nexus_full_api.py @@ -30,14 +30,14 @@ class NexusItem: name: str item_id: str category: str - + @classmethod def from_api(cls, data: Dict[str, Any]) -> "NexusItem": """Create from API response.""" raise NotImplementedError -@dataclass +@dataclass class NexusWeapon(NexusItem): """Weapon from Entropia Nexus API.""" damage: Decimal @@ -49,14 +49,14 @@ class NexusWeapon(NexusItem): efficiency: Decimal range_val: Decimal type: str = "" - + @classmethod def from_api(cls, data: Dict[str, Any]) -> "NexusWeapon": """Create from API response.""" props = data.get('Properties', {}) economy = props.get('Economy', {}) damage = props.get('Damage', {}) - + return cls( id=data.get('Id', 0), name=data.get('Name', 'Unknown'), @@ -86,14 +86,14 @@ class NexusArmor(NexusItem): protection_acid: Decimal protection_electric: Decimal type: str = "" - + @classmethod def from_api(cls, data: Dict[str, Any]) -> "NexusArmor": """Create from API response.""" props = data.get('Properties', {}) protection = props.get('Protection', {}) economy = props.get('Economy', {}) - + return cls( id=data.get('Id', 0), name=data.get('Name', 'Unknown'), @@ -119,14 +119,16 @@ class NexusPlate(NexusItem): protection_stab: Decimal protection_burn: Decimal protection_cold: Decimal + protection_acid: Decimal + protection_electric: Decimal decay: Decimal - + @classmethod def from_api(cls, data: Dict[str, Any]) -> "NexusPlate": """Create from API response.""" props = data.get('Properties', {}) protection = props.get('Protection', {}) - + return cls( id=data.get('Id', 0), name=data.get('Name', 'Unknown'), @@ -137,6 +139,8 @@ class NexusPlate(NexusItem): protection_stab=Decimal(str(protection.get('Stab', 0))), protection_burn=Decimal(str(protection.get('Burn', 0))), protection_cold=Decimal(str(protection.get('Cold', 0))), + protection_acid=Decimal(str(protection.get('Acid', 0))), + protection_electric=Decimal(str(protection.get('Electric', 0))), decay=Decimal(str(props.get('Decay', 0))), ) @@ -149,12 +153,12 @@ class NexusAttachment(NexusItem): range_bonus: Decimal decay: Decimal efficiency_bonus: Decimal - + @classmethod def from_api(cls, data: Dict[str, Any]) -> "NexusAttachment": """Create from API response.""" props = data.get('Properties', {}) - + return cls( id=data.get('Id', 0), name=data.get('Name', 'Unknown'), @@ -175,12 +179,12 @@ class NexusEnhancer(NexusItem): tier: int effect_value: Decimal break_chance: Decimal - + @classmethod def from_api(cls, data: Dict[str, Any]) -> "NexusEnhancer": """Create from API response.""" props = data.get('Properties', {}) - + return cls( id=data.get('Id', 0), name=data.get('Name', 'Unknown'), @@ -212,7 +216,7 @@ class NexusHealingTool(NexusItem): type: str # 'fap', 'chip', 'pack' profession_level: int = 0 is_limited: bool = False - + @classmethod def from_api(cls, data: Dict[str, Any]) -> "NexusHealingTool": """Create from API response.""" @@ -262,7 +266,7 @@ class NexusRing(NexusItem): max_tt: Decimal min_tt: Decimal is_limited: bool - + @classmethod def from_api(cls, data: Dict[str, Any]) -> "NexusRing": """Create from API response.""" @@ -327,12 +331,12 @@ class NexusPet(NexusItem): effect_type: str effect_value: Decimal level_required: int - + @classmethod def from_api(cls, data: Dict[str, Any]) -> "NexusPet": """Create from API response.""" props = data.get('Properties', {}) - + return cls( id=data.get('Id', 0), name=data.get('Name', 'Unknown'), @@ -346,7 +350,7 @@ class NexusPet(NexusItem): class EntropiaNexusFullAPI: """Complete Entropia Nexus API client for all gear types.""" - + def __init__(self): self.base_url = NEXUS_API_BASE self._weapons_cache: Optional[List[NexusWeapon]] = None @@ -362,7 +366,7 @@ class EntropiaNexusFullAPI: self._rings_cache: Optional[List[NexusRing]] = None self._clothing_cache: Optional[List[NexusClothing]] = None self._pets_cache: Optional[List[NexusPet]] = None - + def _fetch(self, endpoint: str) -> List[Dict]: """Fetch data from API endpoint.""" try: @@ -374,7 +378,7 @@ class EntropiaNexusFullAPI: except Exception as e: logger.error(f"Failed to fetch {endpoint}: {e}") return [] - + def get_all_weapons(self, force_refresh: bool = False) -> List[NexusWeapon]: """Fetch all weapons from Nexus API.""" if self._weapons_cache is None or force_refresh: @@ -382,7 +386,7 @@ class EntropiaNexusFullAPI: self._weapons_cache = [NexusWeapon.from_api(item) for item in data] logger.info(f"Loaded {len(self._weapons_cache)} weapons") return self._weapons_cache - + def get_all_armors(self, force_refresh: bool = False) -> List[NexusArmor]: """Fetch all armors from Nexus API.""" if self._armors_cache is None or force_refresh: @@ -390,7 +394,7 @@ class EntropiaNexusFullAPI: self._armors_cache = [NexusArmor.from_api(item) for item in data] logger.info(f"Loaded {len(self._armors_cache)} armors") return self._armors_cache - + def get_all_plates(self, force_refresh: bool = False) -> List[NexusPlate]: """Fetch plates from /armorplatings endpoint.""" if self._plates_cache is None or force_refresh: @@ -409,52 +413,92 @@ class EntropiaNexusFullAPI: return [ # Impact Plates NexusPlate(id=1, name="Armor Plating Mk. 5B", item_id="plate_5b", category="plate", - protection=ProtectionProfile(impact=6), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("6"), protection_cut=Decimal("0"), protection_stab=Decimal("0"), + protection_burn=Decimal("0"), protection_cold=Decimal("0"), protection_acid=Decimal("0"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), NexusPlate(id=2, name="Armor Plating Mk. 10A", item_id="plate_10a", category="plate", - protection=ProtectionProfile(impact=12), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("12"), protection_cut=Decimal("0"), protection_stab=Decimal("0"), + protection_burn=Decimal("0"), protection_cold=Decimal("0"), protection_acid=Decimal("0"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), NexusPlate(id=3, name="Armor Plating Mk. 25A", item_id="plate_25a", category="plate", - protection=ProtectionProfile(impact=25), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("25"), protection_cut=Decimal("0"), protection_stab=Decimal("0"), + protection_burn=Decimal("0"), protection_cold=Decimal("0"), protection_acid=Decimal("0"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), NexusPlate(id=4, name="Armor Plating Mk. 50A", item_id="plate_50a", category="plate", - protection=ProtectionProfile(impact=50), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("50"), protection_cut=Decimal("0"), protection_stab=Decimal("0"), + protection_burn=Decimal("0"), protection_cold=Decimal("0"), protection_acid=Decimal("0"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), # Cut/Stab Plates NexusPlate(id=5, name="Armor Plating Mk. 5C", item_id="plate_5c", category="plate", - protection=ProtectionProfile(cut=6, stab=6), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("0"), protection_cut=Decimal("6"), protection_stab=Decimal("6"), + protection_burn=Decimal("0"), protection_cold=Decimal("0"), protection_acid=Decimal("0"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), NexusPlate(id=6, name="Armor Plating Mk. 10C", item_id="plate_10c", category="plate", - protection=ProtectionProfile(cut=12, stab=12), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("0"), protection_cut=Decimal("12"), protection_stab=Decimal("12"), + protection_burn=Decimal("0"), protection_cold=Decimal("0"), protection_acid=Decimal("0"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), NexusPlate(id=7, name="Armor Plating Mk. 25C", item_id="plate_25c", category="plate", - protection=ProtectionProfile(cut=25, stab=25), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("0"), protection_cut=Decimal("25"), protection_stab=Decimal("25"), + protection_burn=Decimal("0"), protection_cold=Decimal("0"), protection_acid=Decimal("0"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), NexusPlate(id=8, name="Armor Plating Mk. 50C", item_id="plate_50c", category="plate", - protection=ProtectionProfile(cut=50, stab=50), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("0"), protection_cut=Decimal("50"), protection_stab=Decimal("50"), + protection_burn=Decimal("0"), protection_cold=Decimal("0"), protection_acid=Decimal("0"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), # Electric Plates NexusPlate(id=9, name="Armor Plating Mk. 10E", item_id="plate_10e", category="plate", - protection=ProtectionProfile(electric=12), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("0"), protection_cut=Decimal("0"), protection_stab=Decimal("0"), + protection_burn=Decimal("0"), protection_cold=Decimal("0"), protection_acid=Decimal("0"), protection_electric=Decimal("12"), + decay=Decimal("0.05")), NexusPlate(id=10, name="Armor Plating Mk. 25E", item_id="plate_25e", category="plate", - protection=ProtectionProfile(electric=25), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("0"), protection_cut=Decimal("0"), protection_stab=Decimal("0"), + protection_burn=Decimal("0"), protection_cold=Decimal("0"), protection_acid=Decimal("0"), protection_electric=Decimal("25"), + decay=Decimal("0.05")), # Burn Plates NexusPlate(id=11, name="Armor Plating Mk. 10F", item_id="plate_10f", category="plate", - protection=ProtectionProfile(burn=12), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("0"), protection_cut=Decimal("0"), protection_stab=Decimal("0"), + protection_burn=Decimal("12"), protection_cold=Decimal("0"), protection_acid=Decimal("0"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), NexusPlate(id=12, name="Armor Plating Mk. 25F", item_id="plate_25f", category="plate", - protection=ProtectionProfile(burn=25), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("0"), protection_cut=Decimal("0"), protection_stab=Decimal("0"), + protection_burn=Decimal("25"), protection_cold=Decimal("0"), protection_acid=Decimal("0"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), # Acid Plates NexusPlate(id=13, name="Armor Plating Mk. 10Acd", item_id="plate_10acd", category="plate", - protection=ProtectionProfile(acid=12), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("0"), protection_cut=Decimal("0"), protection_stab=Decimal("0"), + protection_burn=Decimal("0"), protection_cold=Decimal("0"), protection_acid=Decimal("12"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), NexusPlate(id=14, name="Armor Plating Mk. 25Acd", item_id="plate_25acd", category="plate", - protection=ProtectionProfile(acid=25), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("0"), protection_cut=Decimal("0"), protection_stab=Decimal("0"), + protection_burn=Decimal("0"), protection_cold=Decimal("0"), protection_acid=Decimal("25"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), # Cold Plates NexusPlate(id=15, name="Armor Plating Mk. 10Cl", item_id="plate_10cl", category="plate", - protection=ProtectionProfile(cold=12), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("0"), protection_cut=Decimal("0"), protection_stab=Decimal("0"), + protection_burn=Decimal("0"), protection_cold=Decimal("12"), protection_acid=Decimal("0"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), NexusPlate(id=16, name="Armor Plating Mk. 25Cl", item_id="plate_25cl", category="plate", - protection=ProtectionProfile(cold=25), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("0"), protection_cut=Decimal("0"), protection_stab=Decimal("0"), + protection_burn=Decimal("0"), protection_cold=Decimal("25"), protection_acid=Decimal("0"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), # Shrapnel Plates NexusPlate(id=17, name="Armor Plating Mk. 10S", item_id="plate_10s", category="plate", - protection=ProtectionProfile(shrapnel=12), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("0"), protection_cut=Decimal("0"), protection_stab=Decimal("0"), + protection_burn=Decimal("0"), protection_cold=Decimal("0"), protection_acid=Decimal("0"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), NexusPlate(id=18, name="Armor Plating Mk. 25S", item_id="plate_25s", category="plate", - protection=ProtectionProfile(shrapnel=25), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("0"), protection_cut=Decimal("0"), protection_stab=Decimal("0"), + protection_burn=Decimal("0"), protection_cold=Decimal("0"), protection_acid=Decimal("0"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), # Penetration Plates NexusPlate(id=19, name="Armor Plating Mk. 10P", item_id="plate_10p", category="plate", - protection=ProtectionProfile(penetration=12), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("0"), protection_cut=Decimal("0"), protection_stab=Decimal("0"), + protection_burn=Decimal("0"), protection_cold=Decimal("0"), protection_acid=Decimal("0"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), NexusPlate(id=20, name="Armor Plating Mk. 25P", item_id="plate_25p", category="plate", - protection=ProtectionProfile(penetration=25), decay_per_hp=Decimal("0.05")), + protection_impact=Decimal("0"), protection_cut=Decimal("0"), protection_stab=Decimal("0"), + protection_burn=Decimal("0"), protection_cold=Decimal("0"), protection_acid=Decimal("0"), protection_electric=Decimal("0"), + decay=Decimal("0.05")), ] def get_all_absorbers(self, force_refresh: bool = False) -> List[NexusAttachment]: @@ -500,7 +544,7 @@ class EntropiaNexusFullAPI: else: self._healing_chips_cache = [] return self._healing_chips_cache - + def get_all_enhancers(self, force_refresh: bool = False) -> List[NexusEnhancer]: """Fetch all enhancers from Nexus API.""" if self._enhancers_cache is None or force_refresh: @@ -508,24 +552,24 @@ class EntropiaNexusFullAPI: self._enhancers_cache = [NexusEnhancer.from_api(item) for item in data] logger.info(f"Loaded {len(self._enhancers_cache)} enhancers") return self._enhancers_cache - + def get_all_healing_tools(self, force_refresh: bool = False) -> List[NexusHealingTool]: """Fetch all healing tools from Nexus API (includes medical tools AND chips).""" if self._healing_cache is None or force_refresh: # Fetch both medical tools and medical chips tools_data = self._fetch("medicaltools") chips_data = self._fetch("medicalchips") - + all_healing = [] if tools_data: all_healing.extend([NexusHealingTool.from_api(item) for item in tools_data]) if chips_data: all_healing.extend([NexusHealingTool.from_api(item) for item in chips_data]) - + self._healing_cache = all_healing logger.info(f"Loaded {len(self._healing_cache)} healing tools ({len(tools_data) if tools_data else 0} tools + {len(chips_data) if chips_data else 0} chips)") return self._healing_cache - + def get_all_rings(self, force_refresh: bool = False) -> List[NexusRing]: """Fetch rings from /clothings endpoint (filtered by Type=Ring).""" if self._rings_cache is None or force_refresh: @@ -550,7 +594,7 @@ class EntropiaNexusFullAPI: NexusRing(id=5, name="Courage Ring", item_id="courage_ring", category="ring", slot="Right Finger", gender="Both", effects={"Critical Hit": "1%"}, max_tt=Decimal("10"), min_tt=Decimal("0"), is_limited=False), NexusRing(id=6, name="Courage Ring (L)", item_id="courage_ring_l", category="ring", slot="Right Finger", gender="Both", effects={"Critical Hit": "1%"}, max_tt=Decimal("10"), min_tt=Decimal("0"), is_limited=True), ] - + def get_all_clothing(self, force_refresh: bool = False) -> List[NexusClothing]: """Fetch all clothing from Nexus API.""" if self._clothing_cache is None or force_refresh: @@ -558,7 +602,7 @@ class EntropiaNexusFullAPI: self._clothing_cache = [NexusClothing.from_api(item) for item in data] logger.info(f"Loaded {len(self._clothing_cache)} clothing items") return self._clothing_cache - + def get_all_pets(self, force_refresh: bool = False) -> List[NexusPet]: """Fetch all pets from Nexus API.""" if self._pets_cache is None or force_refresh: @@ -566,31 +610,31 @@ class EntropiaNexusFullAPI: self._pets_cache = [NexusPet.from_api(item) for item in data] logger.info(f"Loaded {len(self._pets_cache)} pets") return self._pets_cache - + def search_weapons(self, query: str) -> List[NexusWeapon]: """Search weapons by name.""" weapons = self.get_all_weapons() query_lower = query.lower() return [w for w in weapons if query_lower in w.name.lower()] - + def search_armors(self, query: str) -> List[NexusArmor]: """Search armors by name.""" armors = self.get_all_armors() query_lower = query.lower() return [a for a in armors if query_lower in a.name.lower()] - + def search_healing_tools(self, query: str) -> List[NexusHealingTool]: """Search healing tools by name.""" tools = self.get_all_healing_tools() query_lower = query.lower() return [t for t in tools if query_lower in t.name.lower()] - + def search_plates(self, query: str) -> List[NexusPlate]: """Search plates by name.""" plates = self.get_all_plates() query_lower = query.lower() return [p for p in plates if query_lower in p.name.lower()] - + def search_all(self, query: str) -> Dict[str, List]: """Search across all gear types.""" return {