def test_clock_hook(self): class TestHook: def __init__(self): self.tocked = 0 def tock(self): self.tocked += 1 clock = Clock(ticks=0) testhook = TestHook() clock.hook(testhook) clock.tick() self.assertEqual(testhook.tocked, 1) clock.unhook(testhook) clock.tick() self.assertEqual(testhook.tocked, 1)
def test_player_executing_fireIV(self): clock = Clock() player = Player('John', clock) player.receive_buff(buffs.EnochianBuff()) dummy = TargetDummy() self.assertTrue(player.cast('Fire IV', dummy)) self.assertFalse(player.cast('Fire IV', dummy))
def test_skill_swiftcast(self): skill = skills.Swiftcast() clock = Clock() player = Player('John', clock) self.assertTrue(skill.execute(player, player)) self.assertFalse(skill.execute(player, player)) self.assertEqual(player.buffed['cast_time_multiplier'], 0) self.assertEqual(player.buffed['gcd'], player.base['gcd'])
def test_skill_ley_line(self): skill = skills.LeyLine() clock = Clock() player = Player('John', clock) self.assertTrue(skill.execute(player, player)) self.assertFalse(skill.execute(player, player)) self.assertNotEqual(player.buffed['cast_time_multiplier'], 1) self.assertNotEqual(player.buffed['gcd'], player.base['gcd'])
def test_skill_gcd(self): gcd_clock = Clock(default=2.5) gcd_skill = skillmeta.GCD('FIRE TEN', gcd_clock, cast_time=2.8) gcd_clock.set_time(1) self.assertFalse(gcd_skill.execute(None, None)) gcd_clock.set_time(0) self.assertTrue(gcd_skill.execute(None, None)) self.assertEqual(gcd_clock, Clock(2.5))
def __init__(self): super().__init__( name='Polyglot', duration=0, charge=0, charge_limit=1, ) self.exhausted = False self.gain_charge_timer = Clock(default=30) self.skills_that_reduces_charge = ['Foul']
def test_player_use_swiftcast(self): clock = Clock() player = Player('John', clock) dummy = TargetDummy() self.assertTrue(player.cast('Swiftcast', player)) self.assertTrue(player.casting) tick_to_complete = Clock(player.skills['Swiftcast'].cast_time).ticks self.assertEqual(len(player.buffs), 1) self.assertEqual(player.buffed['cast_time_multiplier'], 0) for _ in range(tick_to_complete): clock.tick() clock.tick() player.cast('Blizzard I', dummy) clock.tick() # trigger cast Blizzard I self.assertFalse('Swiftcast' in player.buffs) self.assertNotEqual(player.buffed['cast_time_multiplier'], 0)
def test_buff_polyglot_no_expire_max_charge(self): polyglot = buffs.PolyglotBuff() polyglot.duration = Clock(0) self.assertFalse(polyglot.is_exhausted()) self.assertEqual(polyglot.charge, 0) polyglot.gain_charge() self.assertEqual(polyglot.charge, 1) polyglot.gain_charge() self.assertEqual(polyglot.charge, 1) polyglot.renew(polyglot) self.assertEqual(polyglot.charge, 1)
class DurationBuff: def __init__(self, name, duration): self.name = name self.duration = Clock(default=duration) def is_exhausted(self): return self.duration.is_zero() def buff(self, target): pass def renew(self, new): self.duration.reset() def __str__(self): return self.name def __eq__(self, other): return str(self) == str(other) def __hash__(self): return hash(str(self))
def test_skill_apply_buff_after_gcd_casted(self): clock = Clock() player = Player('John', clock) dummy = TargetDummy() player.cast('Blizzard I', dummy) tick_to_complete = Clock(player.skills['Blizzard I'].cast_time).ticks for _ in range(tick_to_complete): clock.tick() self.assertFalse('Umbral Ice' in player.buffs) clock.tick() self.assertTrue('Umbral Ice' in player.buffs)
def test_player_gcd(self): clock = Clock() player = Player('John', clock) dummy = TargetDummy() self.assertTrue(player.cast('Blizzard I', dummy)) self.assertTrue(player.casting) tick_to_complete = Clock(player.skills['Blizzard I'].cast_time).ticks for _ in range(tick_to_complete): clock.tick() self.assertTrue(player.casting) clock.tick() self.assertFalse(player.casting)
def __init__(self, name, clock): self.name = name # stats self.base = { 'gcd': 2.5, 'cast_time_multiplier': 1, 'damage_modifier': 1, } self.buffed = dict(self.base) self.buffs = {} self.charge_buffs = [] # cooldown attribute self.gcd = Clock(0, default=self.base['gcd']) self.casting_time = Clock(0) self.casting = False self.clock = clock self.clock.hook(self) # skills self.skills = {} for k, skill in skillmeta.GCD_DICT.items(): self.skills[k] = skill(self.gcd) for k, skill in skillmeta.OGCD_DICT.items(): self.skills[k] = skill() self.on_cd_ogcds = []
def test_player_enochian_validity(self): clock = Clock() player = Player('John', clock) player.receive_buff(buffs.AstralFireBuff(1)) player.cast('Enochian', player) clock.tick() self.assertTrue('Enochian' in player.buffs) for _ in range(buffs.AstralFireBuff(1).duration.ticks): clock.tick() self.assertFalse('Astral Fire' in player.buffs) self.assertFalse('Enochian' in player.buffs)
def main(): """ main """ clock = Clock() player = Player('Tomoyo', clock) dummy = TargetDummy() observer = TargetObserver() observer.eyes_on(dummy) rotation = Rotation(['b1', 'Enochian'], ['b1', 'sc', 'b1']) while clock < Time(20): if not player.casting: next_skill = player.skills[rotation.next()] if isinstance(next_skill, skillmeta.GCD): while not player.gcd.is_zero(): clock.tick() player.cast(next_skill.name, dummy) print(f"Total damage: {observer.observe_total_damage_taken()}") else: if next_skill.clock.is_zero(): player.cast(next_skill.name, player) clock.tick()
def test_player_foul_and_polyglot(self): clock = Clock() player = Player('John', clock) dummy = TargetDummy() player.receive_buff(buffs.AstralFireBuff(1)) self.assertTrue(player.cast('Enochian', player)) clock.tick() player.casting_time.set_time(0) self.assertTrue('Polyglot' in player.buffs) self.assertEqual(player.buffs['Polyglot'].charge, 0) self.assertFalse(player.cast('Foul', dummy)) player.buffs['Polyglot'].gain_charge_timer.set_time(0) clock.tick() self.assertEqual(player.buffs['Polyglot'].charge, 1) self.assertTrue(player.cast('Foul', dummy)) clock.tick() tick_to_complete = Clock(player.skills['Foul'].cast_time).ticks for _ in range(tick_to_complete): clock.tick() self.assertEqual(player.buffs['Polyglot'].charge, 0) self.assertTrue('Polyglot' in player.buffs)
def __init__(self, name, duration): self.name = name self.duration = Clock(default=duration)
class Player: """ Player class """ def __init__(self, name, clock): self.name = name # stats self.base = { 'gcd': 2.5, 'cast_time_multiplier': 1, 'damage_modifier': 1, } self.buffed = dict(self.base) self.buffs = {} self.charge_buffs = [] # cooldown attribute self.gcd = Clock(0, default=self.base['gcd']) self.casting_time = Clock(0) self.casting = False self.clock = clock self.clock.hook(self) # skills self.skills = {} for k, skill in skillmeta.GCD_DICT.items(): self.skills[k] = skill(self.gcd) for k, skill in skillmeta.OGCD_DICT.items(): self.skills[k] = skill() self.on_cd_ogcds = [] def calc_cast_time(self, cast_time): return cast_time * self.buffed['cast_time_multiplier'] def cast(self, skill_name, target=None): skill = self.skills[skill_name] if not self.casting and skill.is_ready(): self.casting = skill if isinstance(skill, skillmeta.OGCD): self.on_cd_ogcds.append(skill) BLMLOG.info("-----------------------") self.me(f"begins to cast {self.casting}.") self.casting_time.set_time(self.calc_cast_time(skill.cast_time)) self.gcd.default = self.buffed['gcd'] return skill.execute(self, target) print(f"[{self.clock}] {skill} is not yet ready !!") return False def on_casted(self): self.me(f"casted {self.casting} !") if isinstance(self.casting, skillmeta.GCD): self.casting.process() if self.charge_buffs: for buff in self.charge_buffs: if buff.deduct_charge_for_skill(self.casting): self.me(f'loses 1 charge of {buff}') if buff.is_exhausted(): self.charge_buffs.remove(buff) self.remove_buff(buff) break self.casting = False def tock(self): for ogcd in self.on_cd_ogcds: if ogcd.clock.is_zero(): self.on_cd_ogcds.remove(ogcd) ogcd.clock.tock() for buff in list(self.buffs.values()): if buff.is_exhausted(): self.remove_buff(buff) buff.duration.tock() self.check_enochian() if self.casting_time.is_zero() and self.casting: self.on_casted() self.gcd.tock() self.casting_time.tock() def receive_buff(self, buff): if isinstance(buff, buffs.ChargeBuff): self.charge_buffs.append(buff) if buff.name in self.buffs: self.buffs[buff.name].renew(buff) buff = self.buffs[buff.name] else: self.buffs[buff.name] = buff self.apply_buffs() self.me(f"received {buff} !") def check_enochian(self): if 'Enochian' in self.buffs: if 'Polyglot' in self.buffs: polyglot = self.buffs['Polyglot'] if polyglot.gain_charge_timer.is_zero(): polyglot.gain_charge() polyglot.gain_charge_timer.reset() else: polyglot.gain_charge_timer.tock() if 'Astral or Umbral' in self.buffs.values(): return True self.buffs.pop('Enochian') return False def remove_buff(self, buff): self.me(f"loses {buff}.") self.buffs.pop(buff.name) self.apply_buffs() def apply_buffs(self): self.buffed = dict(self.base) for current_buff in self.buffs.values(): current_buff.buff(self) def me(self, text): BLMLOG.info(f"[{self.clock}] {self.name} {text}")
def test_clock_reset(self): clock = Clock(ticks=30) clock.reset() self.assertEqual(clock, Clock(ticks=0)) clock = Clock(default=10) for _ in range(5): clock.tock() clock.reset() self.assertEqual(clock, Clock(10))
def test_clock_negative_tock(self): clock = Clock(ticks=0) clock.tock() self.assertGreaterEqual(clock.ticks, 0)
def test_clock_tick(self): clock = Clock(ticks=20) clock.tick() self.assertEqual(clock, Clock(ticks=21))
def __init__(self, name, cooldown): super().__init__(name, Clock(0, default=cooldown), 0.75)
def test_buff_enochian_no_exipire(self): enochian = buffs.EnochianBuff() enochian.duration = Clock(0) self.assertFalse(enochian.is_exhausted())