def test_derivating_the_propagated_value(self): player = Player() player.attributes[Attributes.ATK] = 200 equipment = Equipment() equipment.attributes[Attributes.ATK] = 100 equipment.owner = player # 50% of equipment attack goes to player DEF equipment_buff_2 = BuffBuilder().modify("%", 0.5, Attributes.ATK)\ .propagates_to_attribute(Attributes.DEF).propagates_to(Player).build() add_buff(equipment, equipment_buff_2, CompleteBuildingEvent()) # Atk should not be modified assert player.attributes[Attributes.ATK] == 200 # 50% of the EQUIPMENT ATK (100) should have gone to player DEF assert player.attributes[ Attributes.DEF] == equipment.attributes[Attributes.ATK] * 0.5 # Equipment should not be affected assert equipment.attributes[Attributes.ATK] == 100 assert equipment.attributes[Attributes.DEF] == 0 # Derivation should be stored in the target, not the propagator assert len(equipment.attributes.get_data( Attributes.ATK).derivations) == 0 assert len(player.attributes.get_data(Attributes.ATK).derivations) == 1
def test_increasing_propagation_source_attribute_repropagates_derivation( self): player = Player() player.attributes[Attributes.ATK] = 200 equipment = Equipment() equipment.attributes[Attributes.ATK] = 100 equipment.owner = player # 50% of equipment attack goes to player DEF add_buff(equipment, BuffBuilder().modify("%", 0.5, Attributes.ATK)\ .propagates_to_attribute(Attributes.DEF).propagates_to(Player).build(), CompleteBuildingEvent() ) # 50% of the EQUIPMENT ATK (100) should have gone to player DEF assert equipment.attributes[Attributes.ATK] == 100 assert player.attributes[ Attributes.DEF] == equipment.attributes[Attributes.ATK] * 0.5 # +100 to Equipment ATTACK, it should propagate 50% of it to player DEF add_buff(equipment, BuffBuilder().modify("+", 100, Attributes.ATK).build(), CompleteBuildingEvent()) assert equipment.attributes[Attributes.ATK] == 200 assert player.attributes[ Attributes.DEF] == equipment.attributes[Attributes.ATK] * 0.5
def test_propagation_registering_triggers_properly(self): player = Player() player.attributes[Attributes.ATK] = 50 player.attributes[Attributes.DEF] = 75 equipment = Equipment() equipment.attributes[Attributes.ATK] = 100 equipment.owner = player castle = Castle() castle.players = [player] # 50% of player def becomes player HP add_buff(equipment, BuffBuilder(1).modify("%", 0.5, Attributes.DEF).to_attribute(Attributes.HP) \ .propagates_to(Player).build(), CompleteBuildingEvent() ) assert len(equipment.activation_triggers) == 0 assert len(player.activation_triggers) == 0 assert len(equipment.propagation_triggers) == 0 add_buff(equipment, BuffBuilder(2).modify("%", 0.5, Attributes.ATK).propagates_to_attribute(Attributes.HP) \ .propagates_to(Player).build(), CompleteBuildingEvent() ) assert len(equipment.propagation_triggers) == 0 assert len(player.activation_triggers) == 0
def test_removing_propagation_source(self): player = Player() player.attributes[Attributes.ATK] = 200 equipment = Equipment() equipment.attributes[Attributes.ATK] = 100 equipment.owner = player # 50% of equipment attack goes to player DEF equipment_buff_2 = BuffBuilder().modify("%", 0.5, Attributes.ATK) \ .propagates_to_attribute(Attributes.DEF).propagates_to(Player).build() add_buff(equipment, equipment_buff_2, CompleteBuildingEvent()) # 50% of the EQUIPMENT ATK (100) should have gone to player DEF assert player.attributes[ Attributes.DEF] == equipment.attributes[Attributes.ATK] * 0.5 # If we remove the propagation source, the propagation targets attributes needs to be updated remove_buff(equipment, equipment_buff_2.buff_id) assert player.attributes[Attributes.DEF] == 0
def test_propagating_a_derivation_buff(self): player = Player() player.attributes[Attributes.ATK] = 50 player.attributes[Attributes.DEF] = 75 equipment = Equipment() equipment.attributes[Attributes.ATK] = 100 equipment.owner = player castle = Castle() castle.players = [player] # 50% of player def becomes player HP add_buff(equipment, BuffBuilder(1).modify("%", 0.5, Attributes.DEF).to_attribute(Attributes.HP) \ .propagates_to(Player).build(), CompleteBuildingEvent() ) assert player.attributes[Attributes.DEF] == 75 assert player.attributes[Attributes.HP] == 75 / 2 # 50% of equipment attack goes to player DEF add_buff(equipment, BuffBuilder(2).modify("%", 0.5, Attributes.ATK).propagates_to_attribute(Attributes.DEF) \ .propagates_to(Player).build(), CompleteBuildingEvent() ) assert player.attributes[Attributes.DEF] == 125 assert player.attributes[Attributes.HP] == 125 / 2 # Remove the player DEF -> HP derivation remove_buff(equipment, 1) foka = (125 + 40 + 40 + 50) / 2 asd = player.attributes[Attributes.HP] assert player.attributes[Attributes.DEF] == 125 assert player.attributes[Attributes.HP] == 0
def test_double_propagation(self): player = Player() player.attributes[Attributes.ATK] = 100 castle = Castle() castle.players.append(player) equipment = Equipment() equipment.owner = player # A global castle buff of 50% ATK castle_buff = BuffBuilder().modify( "%", 0.5, Attributes.ATK).propagates_to(Player).build() # Equipment buff of 100% bonus atk equipment_buff = BuffBuilder().modify( "%", 1, Attributes.ATK).propagates_to(Player).build() add_buff(castle, castle_buff, CompleteBuildingEvent()) add_buff(equipment, equipment_buff, CompleteBuildingEvent()) assert len(player.active_buffs) == 2 # flat bonus = 100, 250% total bonus from propagations, so 250 final value assert player.attributes[Attributes.ATK] == 250
def test_chaining_propagation(self): player = Player() player.attributes[Attributes.ATK] = 100 equipment = Equipment() equipment.attributes[Attributes.ATK] = 100 equipment.owner = player # 50% of player DEF becomes player HP add_buff(equipment, BuffBuilder().modify("%", 0.5, Attributes.DEF).to_attribute(Attributes.HP) \ .propagates_to(Player).build(), CompleteBuildingEvent() ) # 50% of equipment attack goes to player DEF add_buff(equipment, BuffBuilder().modify("%", 0.5, Attributes.ATK).propagates_to_attribute(Attributes.DEF) \ .propagates_to(Player).build(), CompleteBuildingEvent() ) assert player.attributes[Attributes.DEF] == 50 assert player.attributes[Attributes.HP] == 25
def test_performance(self): player1 = Player() player1_equips = [] for i in range(10): equip = Equipment() equip.owner = player1 player1_equips.append(equip) player2 = Player() player2_equips = [] for i in range(10): equip = Equipment() equip.owner = player2 player2_equips.append(equip) castle = Castle() castle.players = [player1, player2] seed = 1234 random.seed(seed) buff_targets = {} for i in range(10): builder = BuffBuilder() modifier = random_modifier() builder.modify(*modifier) propagates = False apply_to, propagate_to = random_targets() if chance_pct(25): builder.to_attribute(random_attribute(exlude=modifier[2])) if chance_pct(25): propagates = True builder.propagates_to_attribute(random_attribute())
def test_propagating_a_derivation_buff(self): player = Player() player.attributes[Attributes.ATK] = 50 player.attributes[Attributes.DEF] = 75 equipment = Equipment() equipment.attributes[Attributes.ATK] = 100 equipment.owner = player castle = Castle() castle.players = [player] # 50% of player def becomes player HP add_buff(equipment, BuffBuilder(1).modify("%", 0.5, Attributes.DEF).to_attribute(Attributes.HP) \ .propagates_to(Player).build(), CompleteBuildingEvent() ) assert player.attributes[Attributes.HP] == 75 / 2 # 50% of equipment attack goes to player DEF add_buff(equipment, BuffBuilder(2).modify("%", 0.5, Attributes.ATK).propagates_to_attribute(Attributes.DEF)\ .propagates_to(Player).build(), CompleteBuildingEvent() ) assert player.attributes[Attributes.DEF] == 125 assert player.attributes[Attributes.HP] == 125 / 2 # 25% of castle DEF becomes player DEF add_buff(castle, BuffBuilder(3).modify("%", 0.5, Attributes.DEF).propagates_to_attribute(Attributes.DEF) \ .propagates_to(Player).build(), CompleteBuildingEvent() ) assert castle.attributes[Attributes.DEF] == 0 assert player.attributes[Attributes.DEF] == 125 assert player.attributes[Attributes.HP] == 125 / 2 # Castle buff of +80 DEF, 50% should derivate to player add_buff(castle, BuffBuilder(4).modify("+", 80, Attributes.DEF).build(), CompleteBuildingEvent()) assert castle.attributes[Attributes.DEF] == 80 assert player.attributes[Attributes.DEF] == 125 + 40 assert player.attributes[Attributes.HP] == (125 + 40) / 2 # Another Castle buff of +80 DEF, 50% should derivate to player add_buff(castle, BuffBuilder(5).modify("+", 80, Attributes.DEF).build(), CompleteBuildingEvent()) assert castle.attributes[Attributes.DEF] == 80 + 80 assert player.attributes[Attributes.DEF] == 125 + 40 + 40 assert player.attributes[Attributes.HP] == (125 + 40 + 40) / 2 # Just bumping player + 100 ATK. To remember: add_buff(equipment, BuffBuilder(6).modify("+", 100, Attributes.ATK).build(), CompleteBuildingEvent()) assert castle.attributes[Attributes.DEF] == 80 + 80 assert player.attributes[Attributes.DEF] == 125 + 40 + 40 + 50 assert player.attributes[Attributes.HP] == (125 + 40 + 40 + 50) / 2 # 100% of castle DEF goes to player HP add_buff( castle, BuffBuilder(7).modify( "%", 1, Attributes.DEF).propagates_to_attribute( Attributes.HP).propagates_to(Player).build(), CompleteBuildingEvent()) assert castle.attributes[Attributes.DEF] == 80 + 80 assert player.attributes[Attributes.DEF] == 125 + 40 + 40 + 50 assert player.attributes[Attributes.HP] == ( (125 + 40 + 40 + 50) / 2) + castle.attributes[Attributes.DEF] # 50% of HP to CRIT_DAMAGE on player add_buff( player, BuffBuilder(8).modify("%", 0.5, Attributes.HP).to_attribute( Attributes.CRIT_DAMAGE).build(), CompleteBuildingEvent()) assert player.attributes[Attributes.HP] == ( (125 + 40 + 40 + 50) / 2) + castle.attributes[Attributes.DEF] assert player.attributes[ Attributes.CRIT_DAMAGE] == player.attributes[Attributes.HP] / 2 assert castle.attributes[Attributes.DEF] == 80 + 80 assert player.attributes[Attributes.DEF] == 125 + 40 + 40 + 50 with TrackStack() as track: # 50% of castle def to player def add_buff(castle, BuffBuilder(9).modify("%", 0.5, Attributes.DEF).propagates_to_attribute(Attributes.DEF) \ .propagates_to(Player).build(), CompleteBuildingEvent() ) # Printing the stack, this buff should trigger a 4 step derivation chain track.print_stack() assert player.attributes[Attributes.DEF] == 125 + 40 + 40 + 50 + 80 assert player.attributes[Attributes.HP] == ( (125 + 40 + 40 + 50 + 80) / 2) + castle.attributes[Attributes.DEF] assert player.attributes[ Attributes.CRIT_DAMAGE] == player.attributes[Attributes.HP] / 2 assert castle.attributes[Attributes.DEF] == 80 + 80