jumpBridgeContController.py (8496B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\spacecomponents\client\ui\jumpbridge\jumpBridgeContController.py 2 import math 3 import gametime 4 import logging 5 from caching import Memoize 6 from carbon.common.script.util.format import FmtAmt 7 from carbonui import TextColor 8 from const import SEC 9 from dogma.const import attributeCapacitorCapacity, attributeBaseJumpBridgeCapacitorCost, dgmTauConstant, attributeRechargeRate 10 from eve.client.script.ui import eveColor 11 from eveexceptions import ExceptionEater 12 from eveformat import client as eveformat 13 from jumpbridge.common.zone_modifier_util import GetCapacitorZoneModifierAndIdx 14 from localization import GetByLabel 15 logger = logging.getLogger(__name__) 16 17 class JumpBridgeContController(object): 18 19 def __init__(self, itemID, typeID): 20 self._item_id = itemID 21 self._type_id = typeID 22 self._jump_bridge_values = None 23 self.michelle = sm.GetService('michelle') 24 self.sov_svc = sm.GetService('sov') 25 self.dogma_lm = sm.GetService('clientDogmaIM').GetDogmaLocation() 26 self._recharge_time = self.dogma_lm.dogmaStaticMgr.GetTypeAttribute2(self._type_id, attributeRechargeRate) 27 self._total_capacity = self.dogma_lm.dogmaStaticMgr.GetTypeAttribute2(self._type_id, attributeCapacitorCapacity) 28 29 def get_slim_item(self): 30 bp = self.michelle.GetBallpark() 31 if not bp: 32 return None 33 return bp.GetSlimItem(self._item_id) 34 35 def get_target_system_name(self): 36 slim_item = self.get_slim_item() 37 if not slim_item: 38 return '' 39 target_system_id = slim_item.targetSolarsystemID 40 if not target_system_id: 41 return GetByLabel('UI/Inflight/SpaceComponents/JumpBridge/JumpBridgeUnlinked') 42 header_text = u'{system_name} {security_status}'.format(system_name=cfg.evelocations.Get(target_system_id).name, security_status=eveformat.solar_system_security_status(target_system_id)) 43 return header_text 44 45 def _get_your_cost_and_zone(self): 46 slim_item = self.get_slim_item() 47 if not slim_item: 48 return (None, None) 49 capital_solar_system_id = get_my_capital_system() 50 if capital_solar_system_id is None: 51 return (None, None) 52 base_capacitor_use = self.dogma_lm.GetAttributeValue(session.shipid, attributeBaseJumpBridgeCapacitorCost) 53 component = self._get_jump_bridge_component() 54 if not component: 55 return (None, None) 56 zone_multiplier, zone_idx = GetCapacitorZoneModifierAndIdx(capital_solar_system_id, slim_item.targetSolarsystemID, component.zoneMultipliers) 57 total_capacitor_use = base_capacitor_use * zone_multiplier 58 return (total_capacitor_use, zone_idx) 59 60 def reset_jump_bridge_values(self): 61 self._jump_bridge_values = None 62 63 def get_jump_bridge_values(self): 64 if self._jump_bridge_values and not self._jump_bridge_values.is_expired: 65 return self._jump_bridge_values 66 self._jump_bridge_values = self._get_new_jump_bridge_values() 67 return self._jump_bridge_values 68 69 def _get_new_jump_bridge_values(self): 70 jump_bridge_values = None 71 with ExceptionEater('JumpBridgeContController:Failed to update ui'): 72 if self.has_correct_alliance_membership(): 73 jump_bridge_values = self._get_values_for_update() 74 else: 75 jump_bridge_values = JumpBridgeValuesNoAccess() 76 return jump_bridge_values 77 78 def _get_values_for_update(self): 79 try: 80 info = self.get_jump_bridge_info() 81 if info is None: 82 return JumpBridgeValuesNoAccess() 83 except AttributeError: 84 return JumpBridgeValuesNoAccess() 85 86 total_capacitor_use_by_ship, zone_idx = self._get_your_cost_and_zone() 87 values = JumpBridgeValuesAccess(info.structure_capacitor, info.sim_timestamp, self._recharge_time, self._total_capacity, total_capacitor_use_by_ship, zone_idx) 88 return values 89 90 def _get_jump_bridge_component(self): 91 bp = self.michelle.GetBallpark() 92 if not bp: 93 return None 94 from jumpbridge.client.jumpBridge import GetJumpBridgeComponent 95 return GetJumpBridgeComponent(bp, self._item_id) 96 97 def get_jump_bridge_info(self): 98 from jumpbridge.client.jumpBridge import GetJumpBridgeInfo 99 return GetJumpBridgeInfo(self.michelle, self._item_id) 100 101 def has_correct_alliance_membership(self): 102 if not session.allianceid: 103 return False 104 sov_info = self.sov_svc.GetSystemSovereigntyInfo(session.solarsystemid2) 105 if not sov_info: 106 return False 107 return sov_info.allianceID == session.allianceid 108 109 def clear_capital_memoize(self): 110 get_my_capital_system.clear_memoized() 111 112 113 @Memoize(60) 114 def get_my_capital_system(): 115 return sm.GetService('sov').GetMyCapitalSystem() 116 117 118 class BaseJumpBridgeValues(object): 119 120 def __init__(self): 121 self._timestamp = gametime.GetWallclockTime() 122 123 @property 124 def is_expired(self): 125 time_since = gametime.GetTimeSinceWallclockTime(self._timestamp) 126 return time_since > 60 * SEC 127 128 129 class JumpBridgeValuesNoAccess(BaseJumpBridgeValues): 130 pass 131 132 133 class JumpBridgeValuesAccess(BaseJumpBridgeValues): 134 135 def __init__(self, capacitor_value, sim_timestamp, recharge_time, total_capacity, capacitor_use_by_ship, zone_idx): 136 super(JumpBridgeValuesAccess, self).__init__() 137 self._capacitor_value = capacitor_value 138 self._sim_timestamp = sim_timestamp 139 self._recharge_time = recharge_time 140 self._total_capacity = total_capacity 141 self._capacitor_use_by_ship = capacitor_use_by_ship 142 self._zone_idx = zone_idx 143 144 @property 145 def zone_text(self): 146 if self._zone_idx is None: 147 return '' 148 return GetByLabel('UI/Inflight/SpaceComponents/JumpBridge/ZoneNumber', zoneNumber=self._zone_idx + 1) 149 150 @property 151 def current_capacitor(self): 152 return self.current_charge_value 153 154 @property 155 def current_charge_value(self): 156 if self._total_capacity <= 0: 157 return 0 158 old_time = self._sim_timestamp 159 tau_value = self._recharge_time / 5.0 160 new_time = gametime.GetSimTime() 161 sq = math.sqrt(max(self._capacitor_value / self._total_capacity, 0)) 162 time_passed = min(old_time - new_time, 0) / float(dgmTauConstant) 163 exp = math.exp(time_passed / tau_value) 164 ret = (1.0 + (sq - 1.0) * exp) ** 2 * self._total_capacity 165 return ret 166 167 @property 168 def cost_text(self): 169 if self._capacitor_use_by_ship is None: 170 return '' 171 cost = self._convert_gj_to_tj_text(self._capacitor_use_by_ship, 1) 172 if self.has_sufficient_charge: 173 percentage = round(self.cost_proportion * 100, 1) 174 text = GetByLabel('UI/Inflight/SpaceComponents/JumpBridge/YourCostWithPercentage', colorValue=TextColor.HIGHLIGHT, cost=cost, percentage=percentage) 175 else: 176 text = GetByLabel('UI/Inflight/SpaceComponents/JumpBridge/YourCostInsufficientCharge', colorValue=eveColor.HOT_RED_HEX, cost=cost) 177 return text 178 179 @property 180 def capacitory_text(self): 181 text = GetByLabel('UI/Inflight/SpaceComponents/JumpBridge/CapacitorStatus', capacitorLeft=self._convert_gj_to_tj_text(self.current_capacitor), totalCapacitor=self._convert_gj_to_tj_text(self._total_capacity)) 182 return text 183 184 @property 185 def capacitor_perc_text(self): 186 percentage = round(self.capacity_proportion * 100, 1) 187 return GetByLabel('UI/Common/Formatting/PercentageDecimal', percentage=percentage) 188 189 @property 190 def capacity_proportion(self): 191 if self._total_capacity: 192 return float(self.current_capacitor) / self._total_capacity 193 return 0 194 195 @property 196 def cost_proportion(self): 197 if self._capacitor_use_by_ship is None: 198 return 0 199 if self._total_capacity: 200 return float(self._capacitor_use_by_ship) / self._total_capacity 201 return 0 202 203 def _convert_gj_to_tj_text(self, value, decimals = 0): 204 in_tj = value / 1000.0 205 rounded = round(in_tj, decimals) 206 if decimals == 0: 207 return FmtAmt(rounded) 208 return FmtAmt(rounded, showFraction=decimals) 209 210 @property 211 def has_sufficient_charge(self): 212 return self._capacitor_use_by_ship <= self.current_capacitor