def testCombination(self): tgtAttr = self.ch.attribute(attributeId=1) absAttr = self.ch.attribute(attributeId=2) srcAttr = self.ch.attribute(attributeId=3) invalidModifier = Modifier() invalidModifier.state = State.offline invalidModifier.context = Context.local invalidModifier.sourceAttributeId = absAttr.id invalidModifier.operator = Operator.postPercent invalidModifier.targetAttributeId = tgtAttr.id invalidModifier.location = Location.self_ invalidModifier.filterType = None invalidModifier.filterValue = None validModifier = Modifier() validModifier.state = State.offline validModifier.context = Context.local validModifier.sourceAttributeId = srcAttr.id validModifier.operator = Operator.postMul validModifier.targetAttributeId = tgtAttr.id validModifier.location = Location.self_ validModifier.filterType = None validModifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (invalidModifier, validModifier) holder = IndependentItem(self.ch.type_(typeId=1, effects=(effect,), attributes={srcAttr.id: 1.5, tgtAttr.id: 100})) self.fit.items.add(holder) # Invalid source value shouldn't screw whole calculation process self.assertNotAlmostEqual(holder.attributes[tgtAttr.id], 100) self.assertEqual(len(self.log), 1) logRecord = self.log[0] self.assertEqual(logRecord.name, 'eos_test.attributeCalculator') self.assertEqual(logRecord.levelno, Logger.WARNING) self.assertEqual(logRecord.msg, 'unable to find base value for attribute 2 on item 1') self.fit.items.remove(holder) self.assertBuffersEmpty(self.fit)
def testCombination(self): tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) invalidModifier = Modifier() invalidModifier.state = State.offline invalidModifier.context = Context.local invalidModifier.sourceAttributeId = srcAttr.id invalidModifier.operator = 1008 invalidModifier.targetAttributeId = tgtAttr.id invalidModifier.location = Location.self_ invalidModifier.filterType = None invalidModifier.filterValue = None validModifier = Modifier() validModifier.state = State.offline validModifier.context = Context.local validModifier.sourceAttributeId = srcAttr.id validModifier.operator = Operator.postMul validModifier.targetAttributeId = tgtAttr.id validModifier.location = Location.self_ validModifier.filterType = None validModifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (invalidModifier, validModifier) holder = IndependentItem(self.ch.type_(typeId=1, effects=(effect,), attributes={srcAttr.id: 1.5, tgtAttr.id: 100})) self.fit.items.add(holder) # Make sure presence of invalid operator doesn't prevent # from calculating value based on valid modifiers self.assertNotAlmostEqual(holder.attributes[tgtAttr.id], 100) self.fit.items.remove(holder) self.assertEqual(len(self.log), 1) self.assertLinkBuffersEmpty(self.fit)
def testCombination(self): tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) invalidModifier = Modifier() invalidModifier.state = State.offline invalidModifier.context = Context.local invalidModifier.sourceAttributeId = srcAttr.id invalidModifier.operator = 1008 invalidModifier.targetAttributeId = tgtAttr.id invalidModifier.location = Location.self_ invalidModifier.filterType = None invalidModifier.filterValue = None validModifier = Modifier() validModifier.state = State.offline validModifier.context = Context.local validModifier.sourceAttributeId = srcAttr.id validModifier.operator = Operator.postMul validModifier.targetAttributeId = tgtAttr.id validModifier.location = Location.self_ validModifier.filterType = None validModifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (invalidModifier, validModifier) holder = IndependentItem( self.ch.type_(typeId=1, effects=(effect,), attributes={srcAttr.id: 1.5, tgtAttr.id: 100}) ) self.fit.items.add(holder) # Make sure presence of invalid operator doesn't prevent # from calculating value based on valid modifiers self.assertNotAlmostEqual(holder.attributes[tgtAttr.id], 100) self.fit.items.remove(holder) self.assertEqual(len(self.log), 1) self.assertBuffersEmpty(self.fit)
def setUp(self): AttrCalcTestCase.setUp(self) self.tgtAttr = self.ch.attribute(attributeId=1, stackable=1) srcAttr1 = self.ch.attribute(attributeId=2) srcAttr2 = self.ch.attribute(attributeId=3) srcAttr3 = self.ch.attribute(attributeId=4) srcAttr4 = self.ch.attribute(attributeId=5) modifierOff = Modifier() modifierOff.state = State.offline modifierOff.context = Context.local modifierOff.sourceAttributeId = srcAttr1.id modifierOff.operator = Operator.postMul modifierOff.targetAttributeId = self.tgtAttr.id modifierOff.location = Location.self_ modifierOff.filterType = None modifierOff.filterValue = None modifierOn = Modifier() modifierOn.state = State.online modifierOn.context = Context.local modifierOn.sourceAttributeId = srcAttr2.id modifierOn.operator = Operator.postMul modifierOn.targetAttributeId = self.tgtAttr.id modifierOn.location = Location.self_ modifierOn.filterType = None modifierOn.filterValue = None modifierAct = Modifier() modifierAct.state = State.active modifierAct.context = Context.local modifierAct.sourceAttributeId = srcAttr3.id modifierAct.operator = Operator.postMul modifierAct.targetAttributeId = self.tgtAttr.id modifierAct.location = Location.self_ modifierAct.filterType = None modifierAct.filterValue = None modifierOver = Modifier() modifierOver.state = State.overload modifierOver.context = Context.local modifierOver.sourceAttributeId = srcAttr4.id modifierOver.operator = Operator.postMul modifierOver.targetAttributeId = self.tgtAttr.id modifierOver.location = Location.self_ modifierOver.filterType = None modifierOver.filterValue = None # Overload category will make sure that holder can enter all states effect = self.ch.effect(effectId=1, categoryId=EffectCategory.overload) effect.modifiers = (modifierOff, modifierOn, modifierAct, modifierOver) self.holder = IndependentItem( self.ch.type_( typeId=1, effects=(effect,), attributes={ self.tgtAttr.id: 100, srcAttr1.id: 1.1, srcAttr2.id: 1.3, srcAttr3.id: 1.5, srcAttr4.id: 1.7, }, ) )
def setUp(self): AttrCalcTestCase.setUp(self) self.tgtAttr = self.ch.attribute(attributeId=1, stackable=1) srcAttr1 = self.ch.attribute(attributeId=2) srcAttr2 = self.ch.attribute(attributeId=3) srcAttr3 = self.ch.attribute(attributeId=4) srcAttr4 = self.ch.attribute(attributeId=5) modifierOff = Modifier() modifierOff.state = State.offline modifierOff.context = Context.local modifierOff.sourceAttributeId = srcAttr1.id modifierOff.operator = Operator.postMul modifierOff.targetAttributeId = self.tgtAttr.id modifierOff.location = Location.self_ modifierOff.filterType = None modifierOff.filterValue = None modifierOn = Modifier() modifierOn.state = State.online modifierOn.context = Context.local modifierOn.sourceAttributeId = srcAttr2.id modifierOn.operator = Operator.postMul modifierOn.targetAttributeId = self.tgtAttr.id modifierOn.location = Location.self_ modifierOn.filterType = None modifierOn.filterValue = None modifierAct = Modifier() modifierAct.state = State.active modifierAct.context = Context.local modifierAct.sourceAttributeId = srcAttr3.id modifierAct.operator = Operator.postMul modifierAct.targetAttributeId = self.tgtAttr.id modifierAct.location = Location.self_ modifierAct.filterType = None modifierAct.filterValue = None modifierOver = Modifier() modifierOver.state = State.overload modifierOver.context = Context.local modifierOver.sourceAttributeId = srcAttr4.id modifierOver.operator = Operator.postMul modifierOver.targetAttributeId = self.tgtAttr.id modifierOver.location = Location.self_ modifierOver.filterType = None modifierOver.filterValue = None # Overload category will make sure that holder can enter all states effect = self.ch.effect(effectId=1, categoryId=EffectCategory.overload) effect.modifiers = (modifierOff, modifierOn, modifierAct, modifierOver) self.holder = IndependentItem( self.ch.type_(typeId=1, effects=(effect, ), attributes={ self.tgtAttr.id: 100, srcAttr1.id: 1.1, srcAttr2.id: 1.3, srcAttr3.id: 1.5, srcAttr4.id: 1.7 }))
def testCalculation(self): attr1 = self.ch.attribute(attributeId=1) attr2 = self.ch.attribute(attributeId=2) attr3 = self.ch.attribute(attributeId=3) attr4 = self.ch.attribute(attributeId=4) modifier1 = Modifier() modifier1.state = State.offline modifier1.context = Context.local modifier1.sourceAttributeId = attr1.id modifier1.operator = Operator.postMul modifier1.targetAttributeId = attr2.id modifier1.location = Location.self_ modifier1.filterType = None modifier1.filterValue = None effect1 = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect1.modifiers = (modifier1,) modifier2 = Modifier() modifier2.state = State.offline modifier2.context = Context.local modifier2.sourceAttributeId = attr2.id modifier2.operator = Operator.postPercent modifier2.targetAttributeId = attr3.id modifier2.location = Location.ship modifier2.filterType = None modifier2.filterValue = None effect2 = self.ch.effect(effectId=2, categoryId=EffectCategory.passive) effect2.modifiers = (modifier2,) holder1 = CharacterItem(self.ch.type_(typeId=1, effects=(effect1, effect2), attributes={attr1.id: 5, attr2.id: 20})) modifier3 = Modifier() modifier3.state = State.offline modifier3.context = Context.local modifier3.sourceAttributeId = attr3.id modifier3.operator = Operator.postPercent modifier3.targetAttributeId = attr4.id modifier3.location = Location.ship modifier3.filterType = FilterType.all_ modifier3.filterValue = None effect3 = self.ch.effect(effectId=3, categoryId=EffectCategory.passive) effect3.modifiers = (modifier3,) holder2 = IndependentItem(self.ch.type_(typeId=2, effects=(effect3,), attributes={attr3.id: 150})) holder3 = ShipItem(self.ch.type_(typeId=3, attributes={attr4.id: 12.5})) self.fit.items.add(holder1) self.fit.ship = holder2 self.fit.items.add(holder3) # If everything is processed properly, holder1 will multiply attr2 by attr1 # on self, resulting in 20 * 5 = 100, then apply it as percentage modifier # on ship's (holder2) attr3, resulting in 150 + 100% = 300, then it is applied # to all entities assigned to ship, including holder3, to theirs attr4 as # percentage modifier again - so final result is 12.5 + 300% = 50 self.assertAlmostEqual(holder3.attributes[attr4.id], 50) self.fit.items.remove(holder1) self.fit.ship = None self.fit.items.remove(holder3) self.assertEqual(len(self.log), 0) self.assertLinkBuffersEmpty(self.fit)
def testAttribute(self): attr1 = self.ch.attribute(attributeId=1) attr2 = self.ch.attribute(attributeId=2) attr3 = self.ch.attribute(attributeId=3) modifier1 = Modifier() modifier1.state = State.offline modifier1.context = Context.local modifier1.sourceAttributeId = attr1.id modifier1.operator = Operator.postMul modifier1.targetAttributeId = attr2.id modifier1.location = Location.ship modifier1.filterType = None modifier1.filterValue = None effect1 = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect1.modifiers = (modifier1, ) holder1 = CharacterItem( self.ch.type_(typeId=1, effects=(effect1, ), attributes={attr1.id: 5})) modifier2 = Modifier() modifier2.state = State.offline modifier2.context = Context.local modifier2.sourceAttributeId = attr2.id modifier2.operator = Operator.postPercent modifier2.targetAttributeId = attr3.id modifier2.location = Location.ship modifier2.filterType = FilterType.all_ modifier2.filterValue = None effect2 = self.ch.effect(effectId=2, categoryId=EffectCategory.passive) effect2.modifiers = (modifier2, ) holder2 = IndependentItem( self.ch.type_(typeId=2, effects=(effect2, ), attributes={attr2.id: 7.5})) holder3 = ShipItem(self.ch.type_(typeId=3, attributes={attr3.id: 0.5})) self.fit.items.add(holder1) self.fit.ship = holder2 self.fit.items.add(holder3) self.assertAlmostEqual(holder3.attributes[attr3.id], 0.6875) holder1.attributes[attr1.id] = 4 # Manually changed attribute must trigger damaging whole chain # of attributes, effectively allowing us to recalculate its new value self.assertAlmostEqual(holder3.attributes[attr3.id], 0.65) self.fit.items.remove(holder1) self.fit.ship = None self.fit.items.remove(holder3) self.assertEqual(len(self.log), 0) self.assertLinkBuffersEmpty(self.fit)
def testError(self): tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = tgtAttr.id modifier.location = Location.space modifier.filterType = None modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier, ) influenceSource = IndependentItem( self.ch.type_(typeId=34, effects=(effect, ), attributes={srcAttr.id: 20})) # Space location was introduced in Eos as holder to contain in-space # items like missiles or drones, but it can't be targeted directly self.fit.items.add(influenceSource) self.assertEqual(len(self.log), 1) logRecord = self.log[0] self.assertEqual(logRecord.name, 'eos_test.attributeCalculator') self.assertEqual(logRecord.levelno, Logger.WARNING) self.assertEqual( logRecord.msg, 'malformed modifier on item 34: unsupported target location {} for direct modification' .format(Location.space)) self.fit.items.remove(influenceSource) self.assertLinkBuffersEmpty(self.fit)
def testCombination(self): validModifier = Modifier() validModifier.state = State.offline validModifier.context = Context.local validModifier.sourceAttributeId = self.srcAttr.id validModifier.operator = Operator.postPercent validModifier.targetAttributeId = self.tgtAttr.id validModifier.location = Location.ship validModifier.filterType = FilterType.all_ validModifier.filterValue = None self.effect.modifiers = (self.invalidModifier, validModifier) influenceSource = IndependentItem( self.ch.type_(typeId=1, effects=(self.effect, ), attributes={self.srcAttr.id: 20})) self.fit.items.add(influenceSource) influenceTarget = ShipItem( self.ch.type_(typeId=2, attributes={self.tgtAttr.id: 100})) self.fit.items.add(influenceTarget) # Invalid location in modifier should prevent proper processing of other modifiers self.assertNotAlmostEqual(influenceTarget.attributes[self.tgtAttr.id], 100) self.fit.items.remove(influenceTarget) self.fit.items.remove(influenceSource) self.assertEqual(len(self.log), 1) self.assertLinkBuffersEmpty(self.fit)
def testError(self): tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = tgtAttr.id modifier.location = Location.space modifier.filterType = None modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier,) influenceSource = IndependentItem(self.ch.type_(typeId=34, effects=(effect,), attributes={srcAttr.id: 20})) # Space location was introduced in Eos as holder to contain in-space # items like missiles or drones, but it can't be targeted directly self.fit.items.add(influenceSource) self.assertEqual(len(self.log), 1) logRecord = self.log[0] self.assertEqual(logRecord.name, 'eos_test.attributeCalculator') self.assertEqual(logRecord.levelno, Logger.WARNING) self.assertEqual(logRecord.msg, 'malformed modifier on item 34: unsupported target location {} for direct modification'.format(Location.space)) self.fit.items.remove(influenceSource) self.assertBuffersEmpty(self.fit)
def setUp(self): AttrCalcTestCase.setUp(self) self.tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.preAssignment modifier.targetAttributeId = self.tgtAttr.id modifier.location = Location.ship modifier.filterType = FilterType.all_ modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier, ) self.influenceSource1 = IndependentItem( self.ch.type_(typeId=1, effects=(effect, ), attributes={srcAttr.id: 10})) self.influenceSource2 = IndependentItem( self.ch.type_(typeId=2, effects=(effect, ), attributes={srcAttr.id: -20})) self.influenceSource3 = IndependentItem( self.ch.type_(typeId=3, effects=(effect, ), attributes={srcAttr.id: 53})) self.influenceTarget = ShipItem( self.ch.type_(typeId=4, attributes={self.tgtAttr.id: 100})) self.fit.items.add(self.influenceSource1) self.fit.items.add(self.influenceSource2) self.fit.items.add(self.influenceSource3) self.fit.items.add(self.influenceTarget)
def testError(self): tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = tgtAttr.id modifier.location = Location.target modifier.filterType = FilterType.all_ modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier, ) influenceSource = IndependentItem( self.ch.type_(typeId=88, effects=(effect, ), attributes={srcAttr.id: 20})) # This functionality isn't implemented for now self.fit.items.add(influenceSource) self.assertEqual(len(self.log), 1) logRecord = self.log[0] self.assertEqual(logRecord.name, 'eos_test.attributeCalculator') self.assertEqual(logRecord.levelno, Logger.WARNING) self.assertEqual( logRecord.msg, 'malformed modifier on item 88: unsupported target location {} for filtered modification' .format(Location.target)) self.fit.items.remove(influenceSource) self.assertLinkBuffersEmpty(self.fit)
def setUp(self): AttrCalcTestCase.setUp(self) self.tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = self.tgtAttr.id modifier.location = Location.other modifier.filterType = None modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier, ) # We added target attribute to influence source for testSelf; # currently, eos cannot calculate attributes which are originally # missing on item self.influenceSource = ItemWithOther( self.ch.type_(typeId=1, effects=(effect, ), attributes={ self.tgtAttr.id: 100, srcAttr.id: 20 })) self.fit.items.add(self.influenceSource)
def testLogOther(self): # Check how unknown operator value influences # attribute calculator tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) invalidModifier = Modifier() invalidModifier.state = State.offline invalidModifier.context = Context.local invalidModifier.sourceAttributeId = srcAttr.id invalidModifier.operator = 1008 invalidModifier.targetAttributeId = tgtAttr.id invalidModifier.location = Location.self_ invalidModifier.filterType = None invalidModifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (invalidModifier,) holder = IndependentItem(self.ch.type_(typeId=83, effects=(effect,), attributes={srcAttr.id: 1.2, tgtAttr.id: 100})) self.fit.items.add(holder) self.assertAlmostEqual(holder.attributes[tgtAttr.id], 100) self.assertEqual(len(self.log), 1) logRecord = self.log[0] self.assertEqual(logRecord.name, 'eos_test.attributeCalculator') self.assertEqual(logRecord.levelno, Logger.WARNING) self.assertEqual(logRecord.msg, 'malformed modifier on item 83: unknown operator 1008') self.fit.items.remove(holder) self.assertLinkBuffersEmpty(self.fit)
def testCapUpdate(self): # If cap updates, capped attributes should # be updated too holder = ShipItem(self.ch.type_(typeId=1, effects=(self.effect,), attributes={self.cappedAttr.id: 3, self.sourceAttr.id: 6, self.cappingAttr.id: 2})) self.fit.items.add(holder) # Check attribute vs original cap self.assertAlmostEqual(holder.attributes[self.cappedAttr.id], 2) # Add something which changes capping attribute modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = self.sourceAttr.id modifier.operator = Operator.postMul modifier.targetAttributeId = self.cappingAttr.id modifier.location = Location.ship modifier.filterType = FilterType.all_ modifier.filterValue = None effect = self.ch.effect(effectId=2, categoryId=EffectCategory.passive) effect.modifiers = (modifier,) capUpdater = IndependentItem(self.ch.type_(typeId=2, effects=(effect,), attributes={self.sourceAttr.id: 3.5})) self.fit.items.add(capUpdater) # As capping attribute is updated, capped attribute must be updated too self.assertAlmostEqual(holder.attributes[self.cappedAttr.id], 7) self.fit.items.remove(holder) self.fit.items.remove(capUpdater) self.assertEqual(len(self.log), 0) self.assertLinkBuffersEmpty(self.fit)
def testShip(self): tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = tgtAttr.id modifier.location = Location.ship modifier.filterType = None modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier,) influenceSource = IndependentItem(self.ch.type_(typeId=1, effects=(effect,), attributes={srcAttr.id: 20})) self.fit.items.add(influenceSource) item = self.ch.type_(typeId=None, attributes={tgtAttr.id: 100}) influenceTarget1 = IndependentItem(item) self.fit.ship = influenceTarget1 self.assertNotAlmostEqual(influenceTarget1.attributes[tgtAttr.id], 100) self.fit.ship = None influenceTarget2 = IndependentItem(item) self.fit.ship = influenceTarget2 self.assertNotAlmostEqual(influenceTarget2.attributes[tgtAttr.id], 100) self.fit.items.remove(influenceSource) self.fit.ship = None self.assertEqual(len(self.log), 0) self.assertBuffersEmpty(self.fit)
def testError(self): tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = tgtAttr.id modifier.location = Location.other modifier.filterType = FilterType.all_ modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier, ) influenceSource = IndependentItem( self.ch.type_(typeId=90, effects=(effect, ), attributes={srcAttr.id: 20})) # Charge's container or module's charge can't be 'owner' # of other holders, thus such modification type is unsupported self.fit.items.add(influenceSource) self.assertEqual(len(self.log), 1) logRecord = self.log[0] self.assertEqual(logRecord.name, 'eos_test.attributeCalculator') self.assertEqual(logRecord.levelno, Logger.WARNING) self.assertEqual( logRecord.msg, 'malformed modifier on item 90: unsupported target location {} for filtered modification' .format(Location.other)) self.fit.items.remove(influenceSource) self.assertLinkBuffersEmpty(self.fit)
def testError(self): tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = tgtAttr.id modifier.location = Location.area modifier.filterType = FilterType.all_ modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier,) influenceSource = IndependentItem(self.ch.type_(typeId=56, effects=(effect,), attributes={srcAttr.id: 20})) # This location just isn't used in EVE and unsupported by Eos by design self.fit.items.add(influenceSource) self.assertEqual(len(self.log), 1) logRecord = self.log[0] self.assertEqual(logRecord.name, "eos_test.attributeCalculator") self.assertEqual(logRecord.levelno, Logger.WARNING) self.assertEqual( logRecord.msg, "malformed modifier on item 56: unsupported target location {} for filtered modification".format( Location.area ), ) self.fit.items.remove(influenceSource) self.assertLinkBuffersEmpty(self.fit)
def testLogOther(self): # Check how unknown operator value influences # attribute calculator tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) invalidModifier = Modifier() invalidModifier.state = State.offline invalidModifier.context = Context.local invalidModifier.sourceAttributeId = srcAttr.id invalidModifier.operator = 1008 invalidModifier.targetAttributeId = tgtAttr.id invalidModifier.location = Location.self_ invalidModifier.filterType = None invalidModifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (invalidModifier,) holder = IndependentItem( self.ch.type_(typeId=83, effects=(effect,), attributes={srcAttr.id: 1.2, tgtAttr.id: 100}) ) self.fit.items.add(holder) self.assertAlmostEqual(holder.attributes[tgtAttr.id], 100) self.assertEqual(len(self.log), 1) logRecord = self.log[0] self.assertEqual(logRecord.name, "eos_test.attributeCalculator") self.assertEqual(logRecord.levelno, Logger.WARNING) self.assertEqual(logRecord.msg, "malformed modifier on item 83: unknown operator 1008") self.fit.items.remove(holder) self.assertBuffersEmpty(self.fit)
def setUp(self): AttrCalcTestCase.setUp(self) self.tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = self.tgtAttr.id modifier.location = Location.ship modifier.filterType = FilterType.all_ modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier,) self.influenceSource1 = IndependentItem(self.ch.type_(typeId=1, effects=(effect,), attributes={srcAttr.id: 20})) self.influenceSource2 = IndependentItem(self.ch.type_(typeId=2, effects=(effect,), attributes={srcAttr.id: 50})) self.influenceSource3 = IndependentItem(self.ch.type_(typeId=3, effects=(effect,), attributes={srcAttr.id: -90})) self.influenceSource4 = IndependentItem(self.ch.type_(typeId=4, effects=(effect,), attributes={srcAttr.id: -25})) self.influenceSource5 = IndependentItem(self.ch.type_(typeId=5, effects=(effect,), attributes={srcAttr.id: 400})) self.influenceTarget = ShipItem(self.ch.type_(typeId=6, attributes={self.tgtAttr.id: 100})) self.fit.items.add(self.influenceSource1) self.fit.items.add(self.influenceSource2) self.fit.items.add(self.influenceSource3) self.fit.items.add(self.influenceSource4) self.fit.items.add(self.influenceSource5) self.fit.items.add(self.influenceTarget)
def testError(self): tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = tgtAttr.id modifier.location = Location.other modifier.filterType = FilterType.all_ modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier,) influenceSource = IndependentItem(self.ch.type_(typeId=90, effects=(effect,), attributes={srcAttr.id: 20})) # Charge's container or module's charge can't be 'owner' # of other holders, thus such modification type is unsupported self.fit.items.add(influenceSource) self.assertEqual(len(self.log), 1) logRecord = self.log[0] self.assertEqual(logRecord.name, 'eos_test.attributeCalculator') self.assertEqual(logRecord.levelno, Logger.WARNING) self.assertEqual(logRecord.msg, 'malformed modifier on item 90: unsupported target location {} for filtered modification'.format(Location.other)) self.fit.items.remove(influenceSource) self.assertBuffersEmpty(self.fit)
def testShip(self): tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = tgtAttr.id modifier.location = Location.ship modifier.filterType = None modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier, ) influenceSource = IndependentItem( self.ch.type_(typeId=1, effects=(effect, ), attributes={srcAttr.id: 20})) self.fit.items.add(influenceSource) item = self.ch.type_(typeId=None, attributes={tgtAttr.id: 100}) influenceTarget1 = IndependentItem(item) self.fit.ship = influenceTarget1 self.assertNotAlmostEqual(influenceTarget1.attributes[tgtAttr.id], 100) self.fit.ship = None influenceTarget2 = IndependentItem(item) self.fit.ship = influenceTarget2 self.assertNotAlmostEqual(influenceTarget2.attributes[tgtAttr.id], 100) self.fit.items.remove(influenceSource) self.fit.ship = None self.assertEqual(len(self.log), 0) self.assertLinkBuffersEmpty(self.fit)
def testAttribute(self): attr1 = self.ch.attribute(attributeId=1) attr2 = self.ch.attribute(attributeId=2) attr3 = self.ch.attribute(attributeId=3) modifier1 = Modifier() modifier1.state = State.offline modifier1.context = Context.local modifier1.sourceAttributeId = attr1.id modifier1.operator = Operator.postMul modifier1.targetAttributeId = attr2.id modifier1.location = Location.ship modifier1.filterType = None modifier1.filterValue = None effect1 = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect1.modifiers = (modifier1, ) holder1 = CharacterItem( self.ch.type_(typeId=1, effects=(effect1, ), attributes={attr1.id: 5})) modifier2 = Modifier() modifier2.state = State.offline modifier2.context = Context.local modifier2.sourceAttributeId = attr2.id modifier2.operator = Operator.postPercent modifier2.targetAttributeId = attr3.id modifier2.location = Location.ship modifier2.filterType = FilterType.all_ modifier2.filterValue = None effect2 = self.ch.effect(effectId=2, categoryId=EffectCategory.passive) effect2.modifiers = (modifier2, ) holder2 = IndependentItem( self.ch.type_(typeId=2, effects=(effect2, ), attributes={attr2.id: 7.5})) holder3 = ShipItem(self.ch.type_(typeId=3, attributes={attr3.id: 0.5})) self.fit.ship = holder2 self.fit.items.add(holder3) self.assertAlmostEqual(holder3.attributes[attr3.id], 0.5375) self.fit.items.add(holder1) # Added holder must clean all already calculated attributes # which are now affected by it, to allow recalculation self.assertAlmostEqual(holder3.attributes[attr3.id], 0.6875) self.fit.items.remove(holder1) self.fit.ship = None self.fit.items.remove(holder3) self.assertEqual(len(self.log), 0) self.assertLinkBuffersEmpty(self.fit)
def testTargetAttributes(self): tgtAttr1 = self.ch.attribute(attributeId=1) tgtAttr2 = self.ch.attribute(attributeId=2) tgtAttr3 = self.ch.attribute(attributeId=3) srcAttr = self.ch.attribute(attributeId=4) modifier1 = Modifier() modifier1.state = State.offline modifier1.context = Context.local modifier1.sourceAttributeId = srcAttr.id modifier1.operator = Operator.postPercent modifier1.targetAttributeId = tgtAttr1.id modifier1.location = Location.self_ modifier1.filterType = None modifier1.filterValue = None modifier2 = Modifier() modifier2.state = State.offline modifier2.context = Context.local modifier2.sourceAttributeId = srcAttr.id modifier2.operator = Operator.postPercent modifier2.targetAttributeId = tgtAttr2.id modifier2.location = Location.self_ modifier2.filterType = None modifier2.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier1, modifier2) holder = IndependentItem( self.ch.type_(typeId=1, effects=(effect, ), attributes={ tgtAttr1.id: 50, tgtAttr2.id: 80, tgtAttr3.id: 100, srcAttr.id: 20 })) self.fit.items.add(holder) # First attribute should be modified by modifier1 self.assertAlmostEqual(holder.attributes[tgtAttr1.id], 60) # Second should be modified by modifier2 self.assertAlmostEqual(holder.attributes[tgtAttr2.id], 96) # Third should stay unmodified self.assertAlmostEqual(holder.attributes[tgtAttr3.id], 100) self.fit.items.remove(holder) self.assertEqual(len(self.log), 0) self.assertLinkBuffersEmpty(self.fit)
def testCombination(self): tgtAttr = self.ch.attribute(attributeId=1) absAttr = self.ch.attribute(attributeId=2) srcAttr = self.ch.attribute(attributeId=3) invalidModifier = Modifier() invalidModifier.state = State.offline invalidModifier.context = Context.local invalidModifier.sourceAttributeId = absAttr.id invalidModifier.operator = Operator.postPercent invalidModifier.targetAttributeId = tgtAttr.id invalidModifier.location = Location.self_ invalidModifier.filterType = None invalidModifier.filterValue = None validModifier = Modifier() validModifier.state = State.offline validModifier.context = Context.local validModifier.sourceAttributeId = srcAttr.id validModifier.operator = Operator.postMul validModifier.targetAttributeId = tgtAttr.id validModifier.location = Location.self_ validModifier.filterType = None validModifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (invalidModifier, validModifier) holder = IndependentItem( self.ch.type_(typeId=1, effects=(effect, ), attributes={ srcAttr.id: 1.5, tgtAttr.id: 100 })) self.fit.items.add(holder) # Invalid source value shouldn't screw whole calculation process self.assertNotAlmostEqual(holder.attributes[tgtAttr.id], 100) self.assertEqual(len(self.log), 1) logRecord = self.log[0] self.assertEqual(logRecord.name, 'eos_test.attributeCalculator') self.assertEqual(logRecord.levelno, Logger.WARNING) self.assertEqual( logRecord.msg, 'unable to find base value for attribute 2 on item 1') self.fit.items.remove(holder) self.assertLinkBuffersEmpty(self.fit)
def testAttribute(self): attr1 = self.ch.attribute(attributeId=1) attr2 = self.ch.attribute(attributeId=2) attr3 = self.ch.attribute(attributeId=3) modifier1 = Modifier() modifier1.state = State.offline modifier1.context = Context.local modifier1.sourceAttributeId = attr1.id modifier1.operator = Operator.postMul modifier1.targetAttributeId = attr2.id modifier1.location = Location.ship modifier1.filterType = None modifier1.filterValue = None effect1 = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect1.modifiers = (modifier1,) holder1 = CharacterItem(self.ch.type_(typeId=1, effects=(effect1,), attributes={attr1.id: 5})) modifier2 = Modifier() modifier2.state = State.offline modifier2.context = Context.local modifier2.sourceAttributeId = attr2.id modifier2.operator = Operator.postPercent modifier2.targetAttributeId = attr3.id modifier2.location = Location.ship modifier2.filterType = FilterType.all_ modifier2.filterValue = None effect2 = self.ch.effect(effectId=2, categoryId=EffectCategory.passive) effect2.modifiers = (modifier2,) holder2 = IndependentItem(self.ch.type_(typeId=2, effects=(effect2,), attributes={attr2.id: 7.5})) holder3 = ShipItem(self.ch.type_(typeId=3, attributes={attr3.id: 0.5})) self.fit.items.add(holder1) self.fit.ship = holder2 self.fit.items.add(holder3) self.assertAlmostEqual(holder3.attributes[attr3.id], 0.6875) holder1.attributes[attr1.id] = 4 # Manually changed attribute must trigger damaging whole chain # of attributes, effectively allowing us to recalculate its new value self.assertAlmostEqual(holder3.attributes[attr3.id], 0.65) self.fit.items.remove(holder1) self.fit.ship = None self.fit.items.remove(holder3) self.assertEqual(len(self.log), 0) self.assertBuffersEmpty(self.fit)
def testTargetAttributes(self): tgtAttr1 = self.ch.attribute(attributeId=1) tgtAttr2 = self.ch.attribute(attributeId=2) tgtAttr3 = self.ch.attribute(attributeId=3) srcAttr = self.ch.attribute(attributeId=4) modifier1 = Modifier() modifier1.state = State.offline modifier1.context = Context.local modifier1.sourceAttributeId = srcAttr.id modifier1.operator = Operator.postPercent modifier1.targetAttributeId = tgtAttr1.id modifier1.location = Location.self_ modifier1.filterType = None modifier1.filterValue = None modifier2 = Modifier() modifier2.state = State.offline modifier2.context = Context.local modifier2.sourceAttributeId = srcAttr.id modifier2.operator = Operator.postPercent modifier2.targetAttributeId = tgtAttr2.id modifier2.location = Location.self_ modifier2.filterType = None modifier2.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier1, modifier2) holder = IndependentItem( self.ch.type_( typeId=1, effects=(effect,), attributes={tgtAttr1.id: 50, tgtAttr2.id: 80, tgtAttr3.id: 100, srcAttr.id: 20}, ) ) self.fit.items.add(holder) # First attribute should be modified by modifier1 self.assertAlmostEqual(holder.attributes[tgtAttr1.id], 60) # Second should be modified by modifier2 self.assertAlmostEqual(holder.attributes[tgtAttr2.id], 96) # Third should stay unmodified self.assertAlmostEqual(holder.attributes[tgtAttr3.id], 100) self.fit.items.remove(holder) self.assertEqual(len(self.log), 0) self.assertBuffersEmpty(self.fit)
def testAttribute(self): attr1 = self.ch.attribute(attributeId=1) attr2 = self.ch.attribute(attributeId=2) attr3 = self.ch.attribute(attributeId=3) modifier1 = Modifier() modifier1.state = State.offline modifier1.context = Context.local modifier1.sourceAttributeId = attr1.id modifier1.operator = Operator.postMul modifier1.targetAttributeId = attr2.id modifier1.location = Location.ship modifier1.filterType = None modifier1.filterValue = None effect1 = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect1.modifiers = (modifier1,) holder1 = CharacterItem(self.ch.type_(typeId=1, effects=(effect1,), attributes={attr1.id: 5})) modifier2 = Modifier() modifier2.state = State.offline modifier2.context = Context.local modifier2.sourceAttributeId = attr2.id modifier2.operator = Operator.postPercent modifier2.targetAttributeId = attr3.id modifier2.location = Location.ship modifier2.filterType = FilterType.all_ modifier2.filterValue = None effect2 = self.ch.effect(effectId=2, categoryId=EffectCategory.passive) effect2.modifiers = (modifier2,) holder2 = IndependentItem(self.ch.type_(typeId=2, effects=(effect2,), attributes={attr2.id: 7.5})) holder3 = ShipItem(self.ch.type_(typeId=3, attributes={attr3.id: 0.5})) self.fit.ship = holder2 self.fit.items.add(holder3) self.assertAlmostEqual(holder3.attributes[attr3.id], 0.5375) self.fit.items.add(holder1) # Added holder must clean all already calculated attributes # which are now affected by it, to allow recalculation self.assertAlmostEqual(holder3.attributes[attr3.id], 0.6875) self.fit.items.remove(holder1) self.fit.ship = None self.fit.items.remove(holder3) self.assertEqual(len(self.log), 0) self.assertLinkBuffersEmpty(self.fit)
def setUp(self): AttrCalcTestCase.setUp(self) self.tgtAttr = self.ch.attribute(attributeId=1, stackable=0) self.srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = self.srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = self.tgtAttr.id modifier.location = Location.ship modifier.filterType = FilterType.all_ modifier.filterValue = None self.effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) self.effect.modifiers = (modifier,)
def testLogUnorderableCombination(self): # Check how non-orderable operator value influences # attribute calculator. Previously, bug in calculation # method made it to crash tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) invalidModifier = Modifier() invalidModifier.state = State.offline invalidModifier.context = Context.local invalidModifier.sourceAttributeId = srcAttr.id invalidModifier.operator = None invalidModifier.targetAttributeId = tgtAttr.id invalidModifier.location = Location.self_ invalidModifier.filterType = None invalidModifier.filterValue = None validModifier = Modifier() validModifier.state = State.offline validModifier.context = Context.local validModifier.sourceAttributeId = srcAttr.id validModifier.operator = Operator.postMul validModifier.targetAttributeId = tgtAttr.id validModifier.location = Location.self_ validModifier.filterType = None validModifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (invalidModifier, validModifier) holder = IndependentItem(self.ch.type_(typeId=83, effects=(effect,), attributes={srcAttr.id: 1.2, tgtAttr.id: 100})) self.fit.items.add(holder) self.assertAlmostEqual(holder.attributes[tgtAttr.id], 120) self.assertEqual(len(self.log), 1) logRecord = self.log[0] self.assertEqual(logRecord.name, 'eos_test.attributeCalculator') self.assertEqual(logRecord.levelno, Logger.WARNING) self.assertEqual(logRecord.msg, 'malformed modifier on item 83: unknown operator None') self.fit.items.remove(holder) self.assertLinkBuffersEmpty(self.fit)
def setUp(self): AttrCalcTestCase.setUp(self) self.tgtAttr = self.ch.attribute(attributeId=1) self.srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = self.srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = self.tgtAttr.id modifier.location = Location.self_ modifier.filterType = None modifier.filterValue = None self.effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) self.effect.modifiers = (modifier,)
def setUp(self): AttrCalcTestCase.setUp(self) self.tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = self.tgtAttr.id modifier.location = Location.self_ modifier.filterType = FilterType.all_ modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier,) self.influenceSource = IndependentItem(self.ch.type_(typeId=1061, effects=(effect,), attributes={srcAttr.id: 20}))
def setUp(self): AttrCalcTestCase.setUp(self) self.tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = self.tgtAttr.id modifier.location = Location.character modifier.filterType = None modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier,) self.influenceSource = IndependentItem(self.ch.type_(typeId=11, effects=(effect,), attributes={srcAttr.id: 20})) self.fit.items.add(self.influenceSource)
def setUp(self): AttrCalcTestCase.setUp(self) self.cappedAttr = self.ch.attribute(attributeId=1, maxAttributeId=2) self.cappingAttr = self.ch.attribute(attributeId=2, defaultValue=5) self.sourceAttr = self.ch.attribute(attributeId=3) # Just to make sure cap is applied to final value, not # base, make some basic modification modifier modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = self.sourceAttr.id modifier.operator = Operator.postMul modifier.targetAttributeId = self.cappedAttr.id modifier.location = Location.self_ modifier.filterType = None modifier.filterValue = None self.effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) self.effect.modifiers = (modifier,)
def testCombination(self): validModifier = Modifier() validModifier.state = State.offline validModifier.context = Context.local validModifier.sourceAttributeId = self.srcAttr.id validModifier.operator = Operator.postPercent validModifier.targetAttributeId = self.tgtAttr.id validModifier.location = Location.self_ validModifier.filterType = None validModifier.filterValue = None self.effect.modifiers = (self.invalidModifier, validModifier) holder = IndependentItem(self.ch.type_(typeId=1, effects=(self.effect,), attributes={self.srcAttr.id: 20, self.tgtAttr.id: 100})) self.fit.items.add(holder) # Invalid location in modifier should prevent proper processing of other modifiers self.assertNotAlmostEqual(holder.attributes[self.tgtAttr.id], 100) self.fit.items.remove(holder) self.assertEqual(len(self.log), 1) self.assertBuffersEmpty(self.fit)
def setUp(self): AttrCalcTestCase.setUp(self) self.tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = self.tgtAttr.id modifier.location = Location.character modifier.filterType = FilterType.all_ modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier,) # It doesn't matter holder of which type we're using, # the only thing which matters is its position in fit self.influenceSource = IndependentItem(self.ch.type_(typeId=1, effects=(effect,), attributes={srcAttr.id: 20})) self.fit.items.add(self.influenceSource)
def testFitAttrUpdate(self): # Here we create 2 separate fits with ships affecting it; # each ship affects module with different strength. When we # pass module from one fit to another, its internal attribute # storage should be cleared. If it wasn't cleared, we wouldn't # be able to get refreshed value of attribute srcAttr = self.ch.attribute(attributeId=1) tgtAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = tgtAttr.id modifier.location = Location.ship modifier.filterType = FilterType.all_ modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier, ) ship1 = IndependentItem( self.ch.type_(typeId=1, effects=(effect, ), attributes={srcAttr.id: 10})) ship2 = IndependentItem( self.ch.type_(typeId=2, effects=(effect, ), attributes={srcAttr.id: 20})) module = ShipItem(self.ch.type_(typeId=3, attributes={tgtAttr.id: 50})) fit1 = Fit(self.ch) fit1.ship = ship1 fit2 = Fit(self.ch) fit2.ship = ship2 fit1.items.add(module) self.assertAlmostEqual(module.attributes.get(tgtAttr.id), 55) fit1.items.remove(module) fit1.ship = None self.assertLinkBuffersEmpty(fit1) fit2.items.add(module) self.assertAlmostEqual(module.attributes.get(tgtAttr.id), 60) fit2.ship = None fit2.items.remove(module) self.assertLinkBuffersEmpty(fit2)
def setUp(self): AttrCalcTestCase.setUp(self) self.tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = self.tgtAttr.id modifier.location = Location.other modifier.filterType = None modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier,) # We added target attribute to influence source for testSelf; # currently, eos cannot calculate attributes which are originally # missing on item self.influenceSource = ItemWithOther(self.ch.type_(typeId=1, effects=(effect,), attributes={self.tgtAttr.id: 100, srcAttr.id: 20})) self.fit.items.add(self.influenceSource)
def testCapModified(self): # Make sure that holder's own specified attribute # value is taken as cap, and it's taken with all # modifications applied onto it modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = self.sourceAttr.id modifier.operator = Operator.postMul modifier.targetAttributeId = self.cappingAttr.id modifier.location = Location.self_ modifier.filterType = None modifier.filterValue = None effect = self.ch.effect(effectId=2, categoryId=EffectCategory.passive) effect.modifiers = (modifier,) holder = IndependentItem(self.ch.type_(typeId=1, effects=(self.effect, effect), attributes={self.cappedAttr.id: 3, self.sourceAttr.id: 6, self.cappingAttr.id: 0.1})) self.fit.items.add(holder) # Attr value is 3 * 6 = 18, but cap value is 0.1 * 6 = 0.6 self.assertAlmostEqual(holder.attributes[self.cappedAttr.id], 0.6) self.fit.items.remove(holder) self.assertEqual(len(self.log), 0) self.assertLinkBuffersEmpty(self.fit)
def testFitAttrUpdate(self): # Here we create 2 separate fits with ships affecting it; # each ship affects module with different strength. When we # pass module from one fit to another, its internal attribute # storage should be cleared. If it wasn't cleared, we wouldn't # be able to get refreshed value of attribute srcAttr = self.ch.attribute(attributeId=1) tgtAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = tgtAttr.id modifier.location = Location.ship modifier.filterType = FilterType.all_ modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier,) ship1 = IndependentItem(self.ch.type_(typeId=1, effects=(effect,), attributes={srcAttr.id: 10})) ship2 = IndependentItem(self.ch.type_(typeId=2, effects=(effect,), attributes={srcAttr.id: 20})) module = ShipItem(self.ch.type_(typeId=3, attributes={tgtAttr.id: 50})) fit1 = Fit(self.ch) fit1.ship = ship1 fit2 = Fit(self.ch) fit2.ship = ship2 fit1.items.add(module) self.assertAlmostEqual(module.attributes.get(tgtAttr.id), 55) fit1.items.remove(module) fit1.ship = None self.assertLinkBuffersEmpty(fit1) fit2.items.add(module) self.assertAlmostEqual(module.attributes.get(tgtAttr.id), 60) fit2.ship = None fit2.items.remove(module) self.assertLinkBuffersEmpty(fit2)
def testError(self): tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = srcAttr.id modifier.operator = Operator.postPercent modifier.targetAttributeId = tgtAttr.id modifier.location = Location.target modifier.filterType = None modifier.filterValue = None effect = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect.modifiers = (modifier,) influenceSource = IndependentItem(self.ch.type_(typeId=102, effects=(effect,), attributes={srcAttr.id: 20})) # This functionality isn't implemented for now self.fit.items.add(influenceSource) self.assertEqual(len(self.log), 1) logRecord = self.log[0] self.assertEqual(logRecord.name, 'eos_test.attributeCalculator') self.assertEqual(logRecord.levelno, Logger.WARNING) self.assertEqual(logRecord.msg, 'malformed modifier on item 102: unsupported target location {} for direct modification'.format(Location.target)) self.fit.items.remove(influenceSource) self.assertLinkBuffersEmpty(self.fit)
def testCalculation(self): attr1 = self.ch.attribute(attributeId=1) attr2 = self.ch.attribute(attributeId=2) attr3 = self.ch.attribute(attributeId=3) attr4 = self.ch.attribute(attributeId=4) modifier1 = Modifier() modifier1.state = State.offline modifier1.context = Context.local modifier1.sourceAttributeId = attr1.id modifier1.operator = Operator.postMul modifier1.targetAttributeId = attr2.id modifier1.location = Location.self_ modifier1.filterType = None modifier1.filterValue = None effect1 = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effect1.modifiers = (modifier1, ) modifier2 = Modifier() modifier2.state = State.offline modifier2.context = Context.local modifier2.sourceAttributeId = attr2.id modifier2.operator = Operator.postPercent modifier2.targetAttributeId = attr3.id modifier2.location = Location.ship modifier2.filterType = None modifier2.filterValue = None effect2 = self.ch.effect(effectId=2, categoryId=EffectCategory.passive) effect2.modifiers = (modifier2, ) holder1 = CharacterItem( self.ch.type_(typeId=1, effects=(effect1, effect2), attributes={ attr1.id: 5, attr2.id: 20 })) modifier3 = Modifier() modifier3.state = State.offline modifier3.context = Context.local modifier3.sourceAttributeId = attr3.id modifier3.operator = Operator.postPercent modifier3.targetAttributeId = attr4.id modifier3.location = Location.ship modifier3.filterType = FilterType.all_ modifier3.filterValue = None effect3 = self.ch.effect(effectId=3, categoryId=EffectCategory.passive) effect3.modifiers = (modifier3, ) holder2 = IndependentItem( self.ch.type_(typeId=2, effects=(effect3, ), attributes={attr3.id: 150})) holder3 = ShipItem(self.ch.type_(typeId=3, attributes={attr4.id: 12.5})) self.fit.items.add(holder1) self.fit.ship = holder2 self.fit.items.add(holder3) # If everything is processed properly, holder1 will multiply attr2 by attr1 # on self, resulting in 20 * 5 = 100, then apply it as percentage modifier # on ship's (holder2) attr3, resulting in 150 + 100% = 300, then it is applied # to all entities assigned to ship, including holder3, to theirs attr4 as # percentage modifier again - so final result is 12.5 + 300% = 50 self.assertAlmostEqual(holder3.attributes[attr4.id], 50) self.fit.items.remove(holder1) self.fit.ship = None self.fit.items.remove(holder3) self.assertEqual(len(self.log), 0) self.assertLinkBuffersEmpty(self.fit)
def testForcedValue(self): tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifierPreAss = Modifier() modifierPreAss.state = State.offline modifierPreAss.context = Context.local modifierPreAss.sourceAttributeId = srcAttr.id modifierPreAss.operator = Operator.preAssignment modifierPreAss.targetAttributeId = tgtAttr.id modifierPreAss.location = Location.ship modifierPreAss.filterType = FilterType.all_ modifierPreAss.filterValue = None effectPreAss = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effectPreAss.modifiers = (modifierPreAss, ) influenceSourcePreAss = IndependentItem( self.ch.type_(typeId=1, effects=(effectPreAss, ), attributes={srcAttr.id: 5})) self.fit.items.add(influenceSourcePreAss) modifierPreMul = Modifier() modifierPreMul.state = State.offline modifierPreMul.context = Context.local modifierPreMul.sourceAttributeId = srcAttr.id modifierPreMul.operator = Operator.preMul modifierPreMul.targetAttributeId = tgtAttr.id modifierPreMul.location = Location.ship modifierPreMul.filterType = FilterType.all_ modifierPreMul.filterValue = None effectPreMul = self.ch.effect(effectId=2, categoryId=EffectCategory.passive) effectPreMul.modifiers = (modifierPreMul, ) influenceSourcePreMul = IndependentItem( self.ch.type_(typeId=2, effects=(effectPreMul, ), attributes={srcAttr.id: 50})) self.fit.items.add(influenceSourcePreMul) modifierPreDiv = Modifier() modifierPreDiv.state = State.offline modifierPreDiv.context = Context.local modifierPreDiv.sourceAttributeId = srcAttr.id modifierPreDiv.operator = Operator.preDiv modifierPreDiv.targetAttributeId = tgtAttr.id modifierPreDiv.location = Location.ship modifierPreDiv.filterType = FilterType.all_ modifierPreDiv.filterValue = None effectPreDiv = self.ch.effect(effectId=3, categoryId=EffectCategory.passive) effectPreDiv.modifiers = (modifierPreDiv, ) influenceSourcePreDiv = IndependentItem( self.ch.type_(typeId=3, effects=(effectPreDiv, ), attributes={srcAttr.id: 0.5})) self.fit.items.add(influenceSourcePreDiv) modifierModAdd = Modifier() modifierModAdd.state = State.offline modifierModAdd.context = Context.local modifierModAdd.sourceAttributeId = srcAttr.id modifierModAdd.operator = Operator.modAdd modifierModAdd.targetAttributeId = tgtAttr.id modifierModAdd.location = Location.ship modifierModAdd.filterType = FilterType.all_ modifierModAdd.filterValue = None effectModAdd = self.ch.effect(effectId=4, categoryId=EffectCategory.passive) effectModAdd.modifiers = (modifierModAdd, ) influenceSourceModAdd = IndependentItem( self.ch.type_(typeId=4, effects=(effectModAdd, ), attributes={srcAttr.id: 10})) self.fit.items.add(influenceSourceModAdd) modifierModSub = Modifier() modifierModSub.state = State.offline modifierModSub.context = Context.local modifierModSub.sourceAttributeId = srcAttr.id modifierModSub.operator = Operator.modSub modifierModSub.targetAttributeId = tgtAttr.id modifierModSub.location = Location.ship modifierModSub.filterType = FilterType.all_ modifierModSub.filterValue = None effectModSub = self.ch.effect(effectId=5, categoryId=EffectCategory.passive) effectModSub.modifiers = (modifierModSub, ) influenceSourceModSub = IndependentItem( self.ch.type_(typeId=5, effects=(effectModSub, ), attributes={srcAttr.id: 63})) self.fit.items.add(influenceSourceModSub) modifierPostMul = Modifier() modifierPostMul.state = State.offline modifierPostMul.context = Context.local modifierPostMul.sourceAttributeId = srcAttr.id modifierPostMul.operator = Operator.postMul modifierPostMul.targetAttributeId = tgtAttr.id modifierPostMul.location = Location.ship modifierPostMul.filterType = FilterType.all_ modifierPostMul.filterValue = None effectPostMul = self.ch.effect(effectId=6, categoryId=EffectCategory.passive) effectPostMul.modifiers = (modifierPostMul, ) influenceSourcePostMul = IndependentItem( self.ch.type_(typeId=6, effects=(effectPostMul, ), attributes={srcAttr.id: 1.35})) self.fit.items.add(influenceSourcePostMul) modifierPostDiv = Modifier() modifierPostDiv.state = State.offline modifierPostDiv.context = Context.local modifierPostDiv.sourceAttributeId = srcAttr.id modifierPostDiv.operator = Operator.postDiv modifierPostDiv.targetAttributeId = tgtAttr.id modifierPostDiv.location = Location.ship modifierPostDiv.filterType = FilterType.all_ modifierPostDiv.filterValue = None effectPostDiv = self.ch.effect(effectId=7, categoryId=EffectCategory.passive) effectPostDiv.modifiers = (modifierPostDiv, ) influenceSourcePostDiv = IndependentItem( self.ch.type_(typeId=7, effects=(effectPostDiv, ), attributes={srcAttr.id: 2.7})) self.fit.items.add(influenceSourcePostDiv) modifierPostPerc = Modifier() modifierPostPerc.state = State.offline modifierPostPerc.context = Context.local modifierPostPerc.sourceAttributeId = srcAttr.id modifierPostPerc.operator = Operator.postPercent modifierPostPerc.targetAttributeId = tgtAttr.id modifierPostPerc.location = Location.ship modifierPostPerc.filterType = FilterType.all_ modifierPostPerc.filterValue = None effectPostPerc = self.ch.effect(effectId=8, categoryId=EffectCategory.passive) effectPostPerc.modifiers = (modifierPostPerc, ) influenceSourcePostPerc = IndependentItem( self.ch.type_(typeId=8, effects=(effectPostPerc, ), attributes={srcAttr.id: 15})) self.fit.items.add(influenceSourcePostPerc) modifierPostAss = Modifier() modifierPostAss.state = State.offline modifierPostAss.context = Context.local modifierPostAss.sourceAttributeId = srcAttr.id modifierPostAss.operator = Operator.postAssignment modifierPostAss.targetAttributeId = tgtAttr.id modifierPostAss.location = Location.ship modifierPostAss.filterType = FilterType.all_ modifierPostAss.filterValue = None effectPostAss = self.ch.effect(effectId=9, categoryId=EffectCategory.passive) effectPostAss.modifiers = (modifierPostAss, ) influenceSourcePostAss = IndependentItem( self.ch.type_(typeId=9, effects=(effectPostAss, ), attributes={srcAttr.id: 68})) self.fit.items.add(influenceSourcePostAss) influenceTarget = ShipItem( self.ch.type_(typeId=10, attributes={tgtAttr.id: 100})) self.fit.items.add(influenceTarget) # Post-assignment value must override all other modifications self.assertAlmostEqual(influenceTarget.attributes[tgtAttr.id], 68) self.fit.items.remove(influenceSourcePreAss) self.fit.items.remove(influenceSourcePreMul) self.fit.items.remove(influenceSourcePreDiv) self.fit.items.remove(influenceSourceModAdd) self.fit.items.remove(influenceSourceModSub) self.fit.items.remove(influenceSourcePostMul) self.fit.items.remove(influenceSourcePostDiv) self.fit.items.remove(influenceSourcePostPerc) self.fit.items.remove(influenceSourcePostAss) self.fit.items.remove(influenceTarget) self.assertEqual(len(self.log), 0) self.assertLinkBuffersEmpty(self.fit)
def testEosAttrUpdate(self): # Here we check if attributes are updated if fit changes # eos' instance; we do not actually switch eos instance, # but we switch cacheHandler, and it should be enough cacheHandler1 = CacheHandler() cacheHandler2 = CacheHandler() srcAttr1 = cacheHandler1.attribute(attributeId=1) tgtAttr1 = cacheHandler1.attribute(attributeId=2, maxAttributeId=33) cacheHandler1.attribute(attributeId=33, defaultValue=100) srcAttr2 = cacheHandler2.attribute(attributeId=1) tgtAttr2 = cacheHandler2.attribute(attributeId=2, maxAttributeId=333) cacheHandler2.attribute(attributeId=333, defaultValue=500) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = 1 modifier.operator = Operator.postPercent modifier.targetAttributeId = 2 modifier.location = Location.ship modifier.filterType = FilterType.all_ modifier.filterValue = None effect1 = cacheHandler1.effect(effectId=1, categoryId=EffectCategory.passive) effect1.modifiers = (modifier,) effect2 = cacheHandler1.effect(effectId=111, categoryId=EffectCategory.passive) effect2.modifiers = (modifier,) # Our holders from test environment fo not update undelying # item automatically when eos instance is switched, thus we # do it manually shipItem1 = cacheHandler1.type_(typeId=8, effects=(effect1,), attributes={srcAttr1.id: 10}) shipItem2 = cacheHandler2.type_(typeId=8, effects=(effect2,), attributes={srcAttr2.id: 20}) moduleItem1 = cacheHandler1.type_(typeId=4, attributes={tgtAttr1.id: 50}) moduleItem2 = cacheHandler2.type_(typeId=4, attributes={tgtAttr2.id: 75}) fit = Fit(cacheHandler1) ship = IndependentItem(shipItem1) module = ShipItem(moduleItem1) fit.ship = ship fit.items.add(module) self.assertAlmostEqual(module.attributes.get(tgtAttr1.id), 55) # As we have capped attr, this auxiliary map shouldn't be None self.assertIsNotNone(module.attributes._capMap) # Make an 'eos switch': remove holders from attributeCalculator for holder in (ship, module): disabledStates = set(filter(lambda s: s <= holder.state, State)) fit._linkTracker.disableStates(holder, disabledStates) fit._linkTracker.removeHolder(holder) # Refresh holders and replace eos fit.eos._cacheHandler = cacheHandler2 ship.attributes.clear() ship.item = shipItem2 module.attributes.clear() module.item = moduleItem2 # When we cleared holders, auxiliary map for capped attrs should be None. # Using data in this map, attributes which depend on capping attribute will # be cleared. If we don't clear it, there're chances that in new data this # capping-capped attribute pair won't exist, thus if attribute with ID which # used to cap is changed, it will clear attribute which used to be capped - # and we do not want it within scope of new data. self.assertIsNone(module.attributes._capMap) # Add holders again, when new items are in holders for holder in (ship, module): fit._linkTracker.addHolder(holder) enabledStates = set(filter(lambda s: s <= holder.state, State)) fit._linkTracker.enableStates(holder, enabledStates) # Now we should have calculated value based on both updated attribs # if attribs weren't refreshed, we would use old value for modification # (10 instead of 20) self.assertAlmostEqual(module.attributes.get(tgtAttr2.id), 90) fit.ship = None fit.items.remove(module) self.assertLinkBuffersEmpty(fit)
def testEosAttrUpdate(self): # Here we check if attributes are updated if fit changes # eos' instance; we do not actually switch eos instance, # but we switch cacheHandler, and it should be enough cacheHandler1 = CacheHandler() cacheHandler2 = CacheHandler() srcAttr1 = cacheHandler1.attribute(attributeId=1) tgtAttr1 = cacheHandler1.attribute(attributeId=2, maxAttributeId=33) cacheHandler1.attribute(attributeId=33, defaultValue=100) srcAttr2 = cacheHandler2.attribute(attributeId=1) tgtAttr2 = cacheHandler2.attribute(attributeId=2, maxAttributeId=333) cacheHandler2.attribute(attributeId=333, defaultValue=500) modifier = Modifier() modifier.state = State.offline modifier.context = Context.local modifier.sourceAttributeId = 1 modifier.operator = Operator.postPercent modifier.targetAttributeId = 2 modifier.location = Location.ship modifier.filterType = FilterType.all_ modifier.filterValue = None effect1 = cacheHandler1.effect(effectId=1, categoryId=EffectCategory.passive) effect1.modifiers = (modifier, ) effect2 = cacheHandler1.effect(effectId=111, categoryId=EffectCategory.passive) effect2.modifiers = (modifier, ) # Our holders from test environment fo not update undelying # item automatically when eos instance is switched, thus we # do it manually shipItem1 = cacheHandler1.type_(typeId=8, effects=(effect1, ), attributes={srcAttr1.id: 10}) shipItem2 = cacheHandler2.type_(typeId=8, effects=(effect2, ), attributes={srcAttr2.id: 20}) moduleItem1 = cacheHandler1.type_(typeId=4, attributes={tgtAttr1.id: 50}) moduleItem2 = cacheHandler2.type_(typeId=4, attributes={tgtAttr2.id: 75}) fit = Fit(cacheHandler1) ship = IndependentItem(shipItem1) module = ShipItem(moduleItem1) fit.ship = ship fit.items.add(module) self.assertAlmostEqual(module.attributes.get(tgtAttr1.id), 55) # As we have capped attr, this auxiliary map shouldn't be None self.assertIsNotNone(module.attributes._capMap) # Make an 'eos switch': remove holders from attributeCalculator for holder in (ship, module): disabledStates = set(filter(lambda s: s <= holder.state, State)) fit._linkTracker.disableStates(holder, disabledStates) fit._linkTracker.removeHolder(holder) # Refresh holders and replace eos fit.eos._cacheHandler = cacheHandler2 ship.attributes.clear() ship.item = shipItem2 module.attributes.clear() module.item = moduleItem2 # When we cleared holders, auxiliary map for capped attrs should be None. # Using data in this map, attributes which depend on capping attribute will # be cleared. If we don't clear it, there're chances that in new data this # capping-capped attribute pair won't exist, thus if attribute with ID which # used to cap is changed, it will clear attribute which used to be capped - # and we do not want it within scope of new data. self.assertIsNone(module.attributes._capMap) # Add holders again, when new items are in holders for holder in (ship, module): fit._linkTracker.addHolder(holder) enabledStates = set(filter(lambda s: s <= holder.state, State)) fit._linkTracker.enableStates(holder, enabledStates) # Now we should have calculated value based on both updated attribs # if attribs weren't refreshed, we would use old value for modification # (10 instead of 20) self.assertAlmostEqual(module.attributes.get(tgtAttr2.id), 90) fit.ship = None fit.items.remove(module) self.assertLinkBuffersEmpty(fit)
def testAllIn(self): tgtAttr = self.ch.attribute(attributeId=1, stackable=0) srcAttr = self.ch.attribute(attributeId=2) modifierPreAss = Modifier() modifierPreAss.state = State.offline modifierPreAss.context = Context.local modifierPreAss.sourceAttributeId = srcAttr.id modifierPreAss.operator = Operator.preAssignment modifierPreAss.targetAttributeId = tgtAttr.id modifierPreAss.location = Location.ship modifierPreAss.filterType = FilterType.all_ modifierPreAss.filterValue = None effectPreAss = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effectPreAss.modifiers = (modifierPreAss, ) valuePreAss = 5 influenceSourcePreAss = IndependentItem( self.ch.type_(typeId=1, effects=(effectPreAss, ), attributes={srcAttr.id: valuePreAss})) self.fit.items.add(influenceSourcePreAss) modifierPreMul = Modifier() modifierPreMul.state = State.offline modifierPreMul.context = Context.local modifierPreMul.sourceAttributeId = srcAttr.id modifierPreMul.operator = Operator.preMul modifierPreMul.targetAttributeId = tgtAttr.id modifierPreMul.location = Location.ship modifierPreMul.filterType = FilterType.all_ modifierPreMul.filterValue = None effectPreMul = self.ch.effect(effectId=2, categoryId=EffectCategory.passive) effectPreMul.modifiers = (modifierPreMul, ) valuePreMul = 50 influenceSourcePreMul = IndependentItem( self.ch.type_(typeId=2, effects=(effectPreMul, ), attributes={srcAttr.id: valuePreMul})) self.fit.items.add(influenceSourcePreMul) modifierPreDiv = Modifier() modifierPreDiv.state = State.offline modifierPreDiv.context = Context.local modifierPreDiv.sourceAttributeId = srcAttr.id modifierPreDiv.operator = Operator.preDiv modifierPreDiv.targetAttributeId = tgtAttr.id modifierPreDiv.location = Location.ship modifierPreDiv.filterType = FilterType.all_ modifierPreDiv.filterValue = None effectPreDiv = self.ch.effect(effectId=3, categoryId=EffectCategory.passive) effectPreDiv.modifiers = (modifierPreDiv, ) valuePreDiv = 0.5 influenceSourcePreDiv = IndependentItem( self.ch.type_(typeId=3, effects=(effectPreDiv, ), attributes={srcAttr.id: valuePreDiv})) self.fit.items.add(influenceSourcePreDiv) modifierModAdd = Modifier() modifierModAdd.state = State.offline modifierModAdd.context = Context.local modifierModAdd.sourceAttributeId = srcAttr.id modifierModAdd.operator = Operator.modAdd modifierModAdd.targetAttributeId = tgtAttr.id modifierModAdd.location = Location.ship modifierModAdd.filterType = FilterType.all_ modifierModAdd.filterValue = None effectModAdd = self.ch.effect(effectId=4, categoryId=EffectCategory.passive) effectModAdd.modifiers = (modifierModAdd, ) valueModAdd = 10 influenceSourceModAdd = IndependentItem( self.ch.type_(typeId=4, effects=(effectModAdd, ), attributes={srcAttr.id: valueModAdd})) self.fit.items.add(influenceSourceModAdd) modifierModSub = Modifier() modifierModSub.state = State.offline modifierModSub.context = Context.local modifierModSub.sourceAttributeId = srcAttr.id modifierModSub.operator = Operator.modSub modifierModSub.targetAttributeId = tgtAttr.id modifierModSub.location = Location.ship modifierModSub.filterType = FilterType.all_ modifierModSub.filterValue = None effectModSub = self.ch.effect(effectId=5, categoryId=EffectCategory.passive) effectModSub.modifiers = (modifierModSub, ) valueModSub = 63 influenceSourceModSub = IndependentItem( self.ch.type_(typeId=5, effects=(effectModSub, ), attributes={srcAttr.id: valueModSub})) self.fit.items.add(influenceSourceModSub) modifierPostMul = Modifier() modifierPostMul.state = State.offline modifierPostMul.context = Context.local modifierPostMul.sourceAttributeId = srcAttr.id modifierPostMul.operator = Operator.postMul modifierPostMul.targetAttributeId = tgtAttr.id modifierPostMul.location = Location.ship modifierPostMul.filterType = FilterType.all_ modifierPostMul.filterValue = None effectPostMul = self.ch.effect(effectId=6, categoryId=EffectCategory.passive) effectPostMul.modifiers = (modifierPostMul, ) valuePostMul = 1.35 influenceSourcePostMul = IndependentItem( self.ch.type_(typeId=6, effects=(effectPostMul, ), attributes={srcAttr.id: valuePostMul})) self.fit.items.add(influenceSourcePostMul) modifierPostDiv = Modifier() modifierPostDiv.state = State.offline modifierPostDiv.context = Context.local modifierPostDiv.sourceAttributeId = srcAttr.id modifierPostDiv.operator = Operator.postDiv modifierPostDiv.targetAttributeId = tgtAttr.id modifierPostDiv.location = Location.ship modifierPostDiv.filterType = FilterType.all_ modifierPostDiv.filterValue = None effectPostDiv = self.ch.effect(effectId=7, categoryId=EffectCategory.passive) effectPostDiv.modifiers = (modifierPostDiv, ) valuePostDiv = 2.7 influenceSourcePostDiv = IndependentItem( self.ch.type_(typeId=7, effects=(effectPostDiv, ), attributes={srcAttr.id: valuePostDiv})) self.fit.items.add(influenceSourcePostDiv) modifierPostPerc = Modifier() modifierPostPerc.state = State.offline modifierPostPerc.context = Context.local modifierPostPerc.sourceAttributeId = srcAttr.id modifierPostPerc.operator = Operator.postPercent modifierPostPerc.targetAttributeId = tgtAttr.id modifierPostPerc.location = Location.ship modifierPostPerc.filterType = FilterType.all_ modifierPostPerc.filterValue = None effectPostPerc = self.ch.effect(effectId=8, categoryId=EffectCategory.passive) effectPostPerc.modifiers = (modifierPostPerc, ) valuePostPerc = 15 influenceSourcePostPerc = IndependentItem( self.ch.type_(typeId=8, effects=(effectPostPerc, ), attributes={srcAttr.id: valuePostPerc})) self.fit.items.add(influenceSourcePostPerc) influenceTarget = ShipItem( self.ch.type_(typeId=9, attributes={tgtAttr.id: 100})) self.fit.items.add(influenceTarget) # Operators shouldn't be penalized and should go in this order expValue = ((valuePreAss * valuePreMul / valuePreDiv) + valueModAdd - valueModSub) * valuePostMul / valuePostDiv * ( 1 + valuePostPerc / 100) self.assertAlmostEqual(influenceTarget.attributes[tgtAttr.id], expValue) self.fit.items.remove(influenceSourcePreAss) self.fit.items.remove(influenceSourcePreMul) self.fit.items.remove(influenceSourcePreDiv) self.fit.items.remove(influenceSourceModAdd) self.fit.items.remove(influenceSourceModSub) self.fit.items.remove(influenceSourcePostMul) self.fit.items.remove(influenceSourcePostDiv) self.fit.items.remove(influenceSourcePostPerc) self.fit.items.remove(influenceTarget) self.assertEqual(len(self.log), 0) self.assertLinkBuffersEmpty(self.fit)
def testForcedValue(self): tgtAttr = self.ch.attribute(attributeId=1) srcAttr = self.ch.attribute(attributeId=2) modifierPreAss = Modifier() modifierPreAss.state = State.offline modifierPreAss.context = Context.local modifierPreAss.sourceAttributeId = srcAttr.id modifierPreAss.operator = Operator.preAssignment modifierPreAss.targetAttributeId = tgtAttr.id modifierPreAss.location = Location.ship modifierPreAss.filterType = FilterType.all_ modifierPreAss.filterValue = None effectPreAss = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effectPreAss.modifiers = (modifierPreAss,) influenceSourcePreAss = IndependentItem(self.ch.type_(typeId=1, effects=(effectPreAss,), attributes={srcAttr.id: 5})) self.fit.items.add(influenceSourcePreAss) modifierPreMul = Modifier() modifierPreMul.state = State.offline modifierPreMul.context = Context.local modifierPreMul.sourceAttributeId = srcAttr.id modifierPreMul.operator = Operator.preMul modifierPreMul.targetAttributeId = tgtAttr.id modifierPreMul.location = Location.ship modifierPreMul.filterType = FilterType.all_ modifierPreMul.filterValue = None effectPreMul = self.ch.effect(effectId=2, categoryId=EffectCategory.passive) effectPreMul.modifiers = (modifierPreMul,) influenceSourcePreMul = IndependentItem(self.ch.type_(typeId=2, effects=(effectPreMul,), attributes={srcAttr.id: 50})) self.fit.items.add(influenceSourcePreMul) modifierPreDiv = Modifier() modifierPreDiv.state = State.offline modifierPreDiv.context = Context.local modifierPreDiv.sourceAttributeId = srcAttr.id modifierPreDiv.operator = Operator.preDiv modifierPreDiv.targetAttributeId = tgtAttr.id modifierPreDiv.location = Location.ship modifierPreDiv.filterType = FilterType.all_ modifierPreDiv.filterValue = None effectPreDiv = self.ch.effect(effectId=3, categoryId=EffectCategory.passive) effectPreDiv.modifiers = (modifierPreDiv,) influenceSourcePreDiv = IndependentItem(self.ch.type_(typeId=3, effects=(effectPreDiv,), attributes={srcAttr.id: 0.5})) self.fit.items.add(influenceSourcePreDiv) modifierModAdd = Modifier() modifierModAdd.state = State.offline modifierModAdd.context = Context.local modifierModAdd.sourceAttributeId = srcAttr.id modifierModAdd.operator = Operator.modAdd modifierModAdd.targetAttributeId = tgtAttr.id modifierModAdd.location = Location.ship modifierModAdd.filterType = FilterType.all_ modifierModAdd.filterValue = None effectModAdd = self.ch.effect(effectId=4, categoryId=EffectCategory.passive) effectModAdd.modifiers = (modifierModAdd,) influenceSourceModAdd = IndependentItem(self.ch.type_(typeId=4, effects=(effectModAdd,), attributes={srcAttr.id: 10})) self.fit.items.add(influenceSourceModAdd) modifierModSub = Modifier() modifierModSub.state = State.offline modifierModSub.context = Context.local modifierModSub.sourceAttributeId = srcAttr.id modifierModSub.operator = Operator.modSub modifierModSub.targetAttributeId = tgtAttr.id modifierModSub.location = Location.ship modifierModSub.filterType = FilterType.all_ modifierModSub.filterValue = None effectModSub = self.ch.effect(effectId=5, categoryId=EffectCategory.passive) effectModSub.modifiers = (modifierModSub,) influenceSourceModSub = IndependentItem(self.ch.type_(typeId=5, effects=(effectModSub,), attributes={srcAttr.id: 63})) self.fit.items.add(influenceSourceModSub) modifierPostMul = Modifier() modifierPostMul.state = State.offline modifierPostMul.context = Context.local modifierPostMul.sourceAttributeId = srcAttr.id modifierPostMul.operator = Operator.postMul modifierPostMul.targetAttributeId = tgtAttr.id modifierPostMul.location = Location.ship modifierPostMul.filterType = FilterType.all_ modifierPostMul.filterValue = None effectPostMul = self.ch.effect(effectId=6, categoryId=EffectCategory.passive) effectPostMul.modifiers = (modifierPostMul,) influenceSourcePostMul = IndependentItem(self.ch.type_(typeId=6, effects=(effectPostMul,), attributes={srcAttr.id: 1.35})) self.fit.items.add(influenceSourcePostMul) modifierPostDiv = Modifier() modifierPostDiv.state = State.offline modifierPostDiv.context = Context.local modifierPostDiv.sourceAttributeId = srcAttr.id modifierPostDiv.operator = Operator.postDiv modifierPostDiv.targetAttributeId = tgtAttr.id modifierPostDiv.location = Location.ship modifierPostDiv.filterType = FilterType.all_ modifierPostDiv.filterValue = None effectPostDiv = self.ch.effect(effectId=7, categoryId=EffectCategory.passive) effectPostDiv.modifiers = (modifierPostDiv,) influenceSourcePostDiv = IndependentItem(self.ch.type_(typeId=7, effects=(effectPostDiv,), attributes={srcAttr.id: 2.7})) self.fit.items.add(influenceSourcePostDiv) modifierPostPerc = Modifier() modifierPostPerc.state = State.offline modifierPostPerc.context = Context.local modifierPostPerc.sourceAttributeId = srcAttr.id modifierPostPerc.operator = Operator.postPercent modifierPostPerc.targetAttributeId = tgtAttr.id modifierPostPerc.location = Location.ship modifierPostPerc.filterType = FilterType.all_ modifierPostPerc.filterValue = None effectPostPerc = self.ch.effect(effectId=8, categoryId=EffectCategory.passive) effectPostPerc.modifiers = (modifierPostPerc,) influenceSourcePostPerc = IndependentItem(self.ch.type_(typeId=8, effects=(effectPostPerc,), attributes={srcAttr.id: 15})) self.fit.items.add(influenceSourcePostPerc) modifierPostAss = Modifier() modifierPostAss.state = State.offline modifierPostAss.context = Context.local modifierPostAss.sourceAttributeId = srcAttr.id modifierPostAss.operator = Operator.postAssignment modifierPostAss.targetAttributeId = tgtAttr.id modifierPostAss.location = Location.ship modifierPostAss.filterType = FilterType.all_ modifierPostAss.filterValue = None effectPostAss = self.ch.effect(effectId=9, categoryId=EffectCategory.passive) effectPostAss.modifiers = (modifierPostAss,) influenceSourcePostAss = IndependentItem(self.ch.type_(typeId=9, effects=(effectPostAss,), attributes={srcAttr.id: 68})) self.fit.items.add(influenceSourcePostAss) influenceTarget = ShipItem(self.ch.type_(typeId=10, attributes={tgtAttr.id: 100})) self.fit.items.add(influenceTarget) # Post-assignment value must override all other modifications self.assertAlmostEqual(influenceTarget.attributes[tgtAttr.id], 68) self.fit.items.remove(influenceSourcePreAss) self.fit.items.remove(influenceSourcePreMul) self.fit.items.remove(influenceSourcePreDiv) self.fit.items.remove(influenceSourceModAdd) self.fit.items.remove(influenceSourceModSub) self.fit.items.remove(influenceSourcePostMul) self.fit.items.remove(influenceSourcePostDiv) self.fit.items.remove(influenceSourcePostPerc) self.fit.items.remove(influenceSourcePostAss) self.fit.items.remove(influenceTarget) self.assertEqual(len(self.log), 0) self.assertBuffersEmpty(self.fit)
def testAllIn(self): tgtAttr = self.ch.attribute(attributeId=1, stackable=0) srcAttr = self.ch.attribute(attributeId=2) modifierPreAss = Modifier() modifierPreAss.state = State.offline modifierPreAss.context = Context.local modifierPreAss.sourceAttributeId = srcAttr.id modifierPreAss.operator = Operator.preAssignment modifierPreAss.targetAttributeId = tgtAttr.id modifierPreAss.location = Location.ship modifierPreAss.filterType = FilterType.all_ modifierPreAss.filterValue = None effectPreAss = self.ch.effect(effectId=1, categoryId=EffectCategory.passive) effectPreAss.modifiers = (modifierPreAss,) valuePreAss = 5 influenceSourcePreAss = IndependentItem(self.ch.type_(typeId=1, effects=(effectPreAss,), attributes={srcAttr.id: valuePreAss})) self.fit.items.add(influenceSourcePreAss) modifierPreMul = Modifier() modifierPreMul.state = State.offline modifierPreMul.context = Context.local modifierPreMul.sourceAttributeId = srcAttr.id modifierPreMul.operator = Operator.preMul modifierPreMul.targetAttributeId = tgtAttr.id modifierPreMul.location = Location.ship modifierPreMul.filterType = FilterType.all_ modifierPreMul.filterValue = None effectPreMul = self.ch.effect(effectId=2, categoryId=EffectCategory.passive) effectPreMul.modifiers = (modifierPreMul,) valuePreMul = 50 influenceSourcePreMul = IndependentItem(self.ch.type_(typeId=2, effects=(effectPreMul,), attributes={srcAttr.id: valuePreMul})) self.fit.items.add(influenceSourcePreMul) modifierPreDiv = Modifier() modifierPreDiv.state = State.offline modifierPreDiv.context = Context.local modifierPreDiv.sourceAttributeId = srcAttr.id modifierPreDiv.operator = Operator.preDiv modifierPreDiv.targetAttributeId = tgtAttr.id modifierPreDiv.location = Location.ship modifierPreDiv.filterType = FilterType.all_ modifierPreDiv.filterValue = None effectPreDiv = self.ch.effect(effectId=3, categoryId=EffectCategory.passive) effectPreDiv.modifiers = (modifierPreDiv,) valuePreDiv = 0.5 influenceSourcePreDiv = IndependentItem(self.ch.type_(typeId=3, effects=(effectPreDiv,), attributes={srcAttr.id: valuePreDiv})) self.fit.items.add(influenceSourcePreDiv) modifierModAdd = Modifier() modifierModAdd.state = State.offline modifierModAdd.context = Context.local modifierModAdd.sourceAttributeId = srcAttr.id modifierModAdd.operator = Operator.modAdd modifierModAdd.targetAttributeId = tgtAttr.id modifierModAdd.location = Location.ship modifierModAdd.filterType = FilterType.all_ modifierModAdd.filterValue = None effectModAdd = self.ch.effect(effectId=4, categoryId=EffectCategory.passive) effectModAdd.modifiers = (modifierModAdd,) valueModAdd = 10 influenceSourceModAdd = IndependentItem(self.ch.type_(typeId=4, effects=(effectModAdd,), attributes={srcAttr.id: valueModAdd})) self.fit.items.add(influenceSourceModAdd) modifierModSub = Modifier() modifierModSub.state = State.offline modifierModSub.context = Context.local modifierModSub.sourceAttributeId = srcAttr.id modifierModSub.operator = Operator.modSub modifierModSub.targetAttributeId = tgtAttr.id modifierModSub.location = Location.ship modifierModSub.filterType = FilterType.all_ modifierModSub.filterValue = None effectModSub = self.ch.effect(effectId=5, categoryId=EffectCategory.passive) effectModSub.modifiers = (modifierModSub,) valueModSub = 63 influenceSourceModSub = IndependentItem(self.ch.type_(typeId=5, effects=(effectModSub,), attributes={srcAttr.id: valueModSub})) self.fit.items.add(influenceSourceModSub) modifierPostMul = Modifier() modifierPostMul.state = State.offline modifierPostMul.context = Context.local modifierPostMul.sourceAttributeId = srcAttr.id modifierPostMul.operator = Operator.postMul modifierPostMul.targetAttributeId = tgtAttr.id modifierPostMul.location = Location.ship modifierPostMul.filterType = FilterType.all_ modifierPostMul.filterValue = None effectPostMul = self.ch.effect(effectId=6, categoryId=EffectCategory.passive) effectPostMul.modifiers = (modifierPostMul,) valuePostMul = 1.35 influenceSourcePostMul = IndependentItem(self.ch.type_(typeId=6, effects=(effectPostMul,), attributes={srcAttr.id: valuePostMul})) self.fit.items.add(influenceSourcePostMul) modifierPostDiv = Modifier() modifierPostDiv.state = State.offline modifierPostDiv.context = Context.local modifierPostDiv.sourceAttributeId = srcAttr.id modifierPostDiv.operator = Operator.postDiv modifierPostDiv.targetAttributeId = tgtAttr.id modifierPostDiv.location = Location.ship modifierPostDiv.filterType = FilterType.all_ modifierPostDiv.filterValue = None effectPostDiv = self.ch.effect(effectId=7, categoryId=EffectCategory.passive) effectPostDiv.modifiers = (modifierPostDiv,) valuePostDiv = 2.7 influenceSourcePostDiv = IndependentItem(self.ch.type_(typeId=7, effects=(effectPostDiv,), attributes={srcAttr.id: valuePostDiv})) self.fit.items.add(influenceSourcePostDiv) modifierPostPerc = Modifier() modifierPostPerc.state = State.offline modifierPostPerc.context = Context.local modifierPostPerc.sourceAttributeId = srcAttr.id modifierPostPerc.operator = Operator.postPercent modifierPostPerc.targetAttributeId = tgtAttr.id modifierPostPerc.location = Location.ship modifierPostPerc.filterType = FilterType.all_ modifierPostPerc.filterValue = None effectPostPerc = self.ch.effect(effectId=8, categoryId=EffectCategory.passive) effectPostPerc.modifiers = (modifierPostPerc,) valuePostPerc = 15 influenceSourcePostPerc = IndependentItem(self.ch.type_(typeId=8, effects=(effectPostPerc,), attributes={srcAttr.id: valuePostPerc})) self.fit.items.add(influenceSourcePostPerc) influenceTarget = ShipItem(self.ch.type_(typeId=9, attributes={tgtAttr.id: 100})) self.fit.items.add(influenceTarget) # Operators shouldn't be penalized and should go in this order expValue = ((valuePreAss * valuePreMul / valuePreDiv) + valueModAdd - valueModSub) * valuePostMul / valuePostDiv * (1 + valuePostPerc / 100) self.assertAlmostEqual(influenceTarget.attributes[tgtAttr.id], expValue) self.fit.items.remove(influenceSourcePreAss) self.fit.items.remove(influenceSourcePreMul) self.fit.items.remove(influenceSourcePreDiv) self.fit.items.remove(influenceSourceModAdd) self.fit.items.remove(influenceSourceModSub) self.fit.items.remove(influenceSourcePostMul) self.fit.items.remove(influenceSourcePostDiv) self.fit.items.remove(influenceSourcePostPerc) self.fit.items.remove(influenceTarget) self.assertEqual(len(self.log), 0) self.assertLinkBuffersEmpty(self.fit)