From 6bcd0ca799216e2aaabc3dde334ebc0c086bcc2d Mon Sep 17 00:00:00 2001 From: LemonNexus Date: Mon, 9 Feb 2026 15:55:55 +0000 Subject: [PATCH] feat(api): add armor sets and mindforce implants endpoints - Added NexusArmorSet dataclass with pieces list and total protection - Added NexusMindforceImplant dataclass for MF chips/implants - Added get_all_armor_sets() method using /armorsets endpoint - Added get_all_mindforce_implants() method using /mindforceimplants endpoint - Added cache variables for both new endpoints --- core/nexus_full_api.py | 99 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/core/nexus_full_api.py b/core/nexus_full_api.py index 010f51f..f955f3b 100644 --- a/core/nexus_full_api.py +++ b/core/nexus_full_api.py @@ -197,6 +197,79 @@ class NexusEnhancer(NexusItem): ) +@dataclass +class NexusArmorSet(NexusItem): + """Armor set from Entropia Nexus API (e.g., 'Ghost Set', 'Shogun Set').""" + pieces: List[str] # List of armor piece names in the set + total_protection: ProtectionProfile + set_bonus: Optional[str] = None + + @classmethod + def from_api(cls, data: Dict[str, Any]) -> "NexusArmorSet": + """Create from API response.""" + props = data.get('Properties', {}) + pieces = data.get('Pieces', []) or [] + + # Calculate total protection from pieces + protection = ProtectionProfile() + for piece_data in pieces: + prot = piece_data.get('Protection', {}) + protection.impact += safe_decimal(prot.get('Impact')) + protection.cut += safe_decimal(prot.get('Cut')) + protection.stab += safe_decimal(prot.get('Stab')) + protection.burn += safe_decimal(prot.get('Burn')) + protection.cold += safe_decimal(prot.get('Cold')) + protection.acid += safe_decimal(prot.get('Acid')) + protection.electric += safe_decimal(prot.get('Electric')) + + return cls( + id=data.get('Id', 0), + name=data.get('Name', 'Unknown'), + item_id=str(data.get('Id', 0)), + category='armorset', + pieces=[p.get('Name', '') for p in pieces], + total_protection=protection, + set_bonus=props.get('SetBonus'), + ) + + +@dataclass +class NexusMindforceImplant(NexusItem): + """Mindforce implant from Entropia Nexus API.""" + implant_type: str # 'damage', 'healing', 'utility' + chip_type: str # 'combustive', 'cryogenic', 'electric', etc. + decay: Decimal + profession_level: int = 0 + is_limited: bool = False + + @classmethod + def from_api(cls, data: Dict[str, Any]) -> "NexusMindforceImplant": + """Create from API response.""" + props = data.get('Properties', {}) + economy = props.get('Economy', {}) + + # Determine type from name or properties + name = data.get('Name', '').lower() + if 'heal' in name or 'restore' in name: + implant_type = 'healing' + elif 'damage' in name or 'attack' in name: + implant_type = 'damage' + else: + implant_type = 'utility' + + return cls( + id=data.get('Id', 0), + name=data.get('Name', 'Unknown'), + item_id=str(data.get('Id', 0)), + category='mindforce', + implant_type=implant_type, + chip_type=props.get('ChipType', 'unknown'), + decay=safe_decimal(economy.get('Decay')), + profession_level=int(props.get('RequiredLevel', 0) or 0), + is_limited='(L)' in data.get('Name', ''), + ) + + def safe_decimal(value: Any, default: str = "0") -> Decimal: """Safely convert a value to Decimal, handling None and invalid values.""" if value is None or value == "": @@ -355,6 +428,7 @@ class EntropiaNexusFullAPI: self.base_url = NEXUS_API_BASE self._weapons_cache: Optional[List[NexusWeapon]] = None self._armors_cache: Optional[List[NexusArmor]] = None + self._armor_sets_cache: Optional[List[NexusArmorSet]] = None self._plates_cache: Optional[List[NexusPlate]] = None self._absorbers_cache: Optional[List[NexusAttachment]] = None self._amplifiers_cache: Optional[List[NexusAttachment]] = None @@ -363,6 +437,7 @@ class EntropiaNexusFullAPI: self._enhancers_cache: Optional[List[NexusEnhancer]] = None self._healing_cache: Optional[List[NexusHealingTool]] = None self._healing_chips_cache: Optional[List[NexusHealingTool]] = None + self._mindforce_implants_cache: Optional[List[NexusMindforceImplant]] = None self._rings_cache: Optional[List[NexusRing]] = None self._clothing_cache: Optional[List[NexusClothing]] = None self._pets_cache: Optional[List[NexusPet]] = None @@ -395,6 +470,18 @@ class EntropiaNexusFullAPI: logger.info(f"Loaded {len(self._armors_cache)} armors") return self._armors_cache + def get_all_armor_sets(self, force_refresh: bool = False) -> List[NexusArmorSet]: + """Fetch all armor sets from Nexus API.""" + if self._armor_sets_cache is None or force_refresh: + data = self._fetch("armorsets") + if data: + self._armor_sets_cache = [NexusArmorSet.from_api(item) for item in data] + logger.info(f"Loaded {len(self._armor_sets_cache)} armor sets from API") + else: + self._armor_sets_cache = [] + logger.warning("No armor sets found in API") + return self._armor_sets_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: @@ -570,6 +657,18 @@ class EntropiaNexusFullAPI: 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_mindforce_implants(self, force_refresh: bool = False) -> List[NexusMindforceImplant]: + """Fetch mindforce implants from /mindforceimplants endpoint.""" + if self._mindforce_implants_cache is None or force_refresh: + data = self._fetch("mindforceimplants") + if data: + self._mindforce_implants_cache = [NexusMindforceImplant.from_api(item) for item in data] + logger.info(f"Loaded {len(self._mindforce_implants_cache)} mindforce implants from API") + else: + self._mindforce_implants_cache = [] + logger.warning("No mindforce implants found in API") + return self._mindforce_implants_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: