characterEnergyState.py (5421B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\characterenergy\characterEnergyState.py 2 from carbon.common.lib.const import SEC 3 4 class CharacterEnergyState(object): 5 6 def __init__(self, energyLevel, lastRechargeTickTimestamp, energyIncreasePerRechargeTick, rechargeTickPeriod, minEnergyLevel, quiescentEnergyLevel): 7 if energyIncreasePerRechargeTick <= 0: 8 raise ValueError('energyIncreasePerRechargeTick must be greater than 0') 9 if rechargeTickPeriod <= 0: 10 raise ValueError('rechargeTickPeriod must be greater than 0') 11 if minEnergyLevel >= quiescentEnergyLevel: 12 raise ValueError('maxInterferenceLevel must be less than quiescentInterferenceLevel') 13 if energyLevel < minEnergyLevel: 14 raise ValueError('energyLevel (%.2f) must be greater than or equal to minEnergyLevel (%.2f)' % (energyLevel, minEnergyLevel)) 15 if energyLevel > quiescentEnergyLevel: 16 raise ValueError('energyLevel (%.2f) must be less than or equal to quiescentEnergyLevel (%.2f)' % (energyLevel, quiescentEnergyLevel)) 17 self._energyLevel = energyLevel 18 self._lastRechargeTickTimestamp = lastRechargeTickTimestamp 19 self._energyIncreasePerRechargeTick = energyIncreasePerRechargeTick 20 self._rechargeTickPeriod = rechargeTickPeriod 21 self._minEnergyLevel = minEnergyLevel 22 self._quiescentEnergyLevel = quiescentEnergyLevel 23 24 def __repr__(self): 25 return 'CharacterEnergyState(energyLevel=%r, lastRechargeTickTimestamp=%r, energyIncreasePerRechargeTick=%r, rechargeTickPeriod=%r, minEnergyLevel=%r, quiescentEnergyLevel=%r)' % (self._energyLevel, 26 self._lastRechargeTickTimestamp, 27 self._energyIncreasePerRechargeTick, 28 self._rechargeTickPeriod, 29 self._minEnergyLevel, 30 self._quiescentEnergyLevel) 31 32 def __eq__(self, other): 33 if other is None: 34 return False 35 return self._energyLevel == other._energyLevel and self._lastRechargeTickTimestamp == other._lastRechargeTickTimestamp and self._energyIncreasePerRechargeTick == other._energyIncreasePerRechargeTick and self._rechargeTickPeriod == other._rechargeTickPeriod and self._minEnergyLevel == other._minEnergyLevel and self._quiescentEnergyLevel == other._quiescentEnergyLevel 36 37 @property 38 def energyLevel(self): 39 return self._energyLevel 40 41 @property 42 def lastRechargeTickTimestamp(self): 43 return self._lastRechargeTickTimestamp 44 45 @property 46 def energyIncreasePerRechargeTick(self): 47 return self._energyIncreasePerRechargeTick 48 49 @property 50 def rechargeTickPeriod(self): 51 return self._rechargeTickPeriod 52 53 @property 54 def minEnergyLevel(self): 55 return self._minEnergyLevel 56 57 @property 58 def quiescentEnergyLevel(self): 59 return self._quiescentEnergyLevel 60 61 @property 62 def isAtQuiescentLevel(self): 63 return self._energyLevel >= self._quiescentEnergyLevel 64 65 @property 66 def energyRange(self): 67 return self._quiescentEnergyLevel - self._minEnergyLevel 68 69 @property 70 def normalisedEnergyLevel(self): 71 return (self._energyLevel - self._minEnergyLevel) / self.energyRange 72 73 def CanAffordCost(self, energyCost): 74 return self._energyLevel - energyCost >= self._minEnergyLevel 75 76 77 def _GetRechargeResult(characterEnergyState, timestamp): 78 timeDelta = timestamp - characterEnergyState.lastRechargeTickTimestamp 79 if timeDelta < 0: 80 raise ValueError('GetRechargeResult cannot be calculated for negative timeDelta') 81 numRechargeTicks = timeDelta / (characterEnergyState.rechargeTickPeriod * SEC) 82 energyIncrease = numRechargeTicks * characterEnergyState.energyIncreasePerRechargeTick 83 newEnergyLevel = min(characterEnergyState.quiescentEnergyLevel, characterEnergyState.energyLevel + energyIncrease) 84 newRechargeTime = characterEnergyState.lastRechargeTickTimestamp + numRechargeTicks * characterEnergyState.rechargeTickPeriod * SEC 85 return (newEnergyLevel, newRechargeTime) 86 87 88 def GetNewState(originalState, newEnergyLevel, newRechargeTime): 89 return CharacterEnergyState(newEnergyLevel, newRechargeTime, originalState.energyIncreasePerRechargeTick, originalState.rechargeTickPeriod, originalState.minEnergyLevel, originalState.quiescentEnergyLevel) 90 91 92 def CalculateStateAtTime(characterEnergyState, timestamp): 93 if characterEnergyState.isAtQuiescentLevel: 94 return characterEnergyState 95 if timestamp < characterEnergyState.lastRechargeTickTimestamp: 96 return characterEnergyState 97 newEnergyLevel, newRechargeTickTimestamp = _GetRechargeResult(characterEnergyState, timestamp) 98 return GetNewState(characterEnergyState, newEnergyLevel, newRechargeTickTimestamp) 99 100 101 def CalculateStateAfterSpendingEnergyAtTime(characterEnergyState, energyCost, timestamp): 102 if energyCost <= 0.0: 103 raise ValueError('energyCost must be greater-than 0') 104 newEnergyLevel, newRechargeTickTimestamp = _GetRechargeResult(characterEnergyState, timestamp) 105 stateAtTime = GetNewState(characterEnergyState, newEnergyLevel, newRechargeTickTimestamp) 106 if not stateAtTime.CanAffordCost(energyCost): 107 raise InsufficientEnergyError('Not enough energy') 108 return GetNewState(characterEnergyState, newEnergyLevel - energyCost, newRechargeTickTimestamp) 109 110 111 class InsufficientEnergyError(Exception): 112 pass