def cast(self, champion: Champion) -> simpy.events.ProcessGenerator: if champion.skill not in SKILL.keys(): champion.mp = 0 return skill = SKILL[champion.skill] if not skill or not skill.chk_condition(champion): yield self.env.timeout(0) return print(f'{champion}: Champion is cast at {self.env.now:f}') try: champion.action = self.field.env.process(skill(self.field).cast(champion)) yield champion.action except CancelSkillCasting: yield self.env.timeout(0) return champion.mp = 0
def search(self, champion: Champion) -> simpy.events.ProcessGenerator: distance, result = search.find_proximate(self.field.get_location(champion)) if result: champion.target = random.choice(result).champion yield self.env.timeout(0) else: yield self.env.timeout(0.01)
def select_action(self, champion: Champion) -> simpy.events.ProcessGenerator: champion.action = self.env.process(self.cast(champion)) yield champion.action if champion.target: distance = search.get_distance(self.field.get_location(champion), champion.target) if distance is None: champion.target = None elif distance <= champion.stat[Stat.RANGE]: champion.action = self.env.process(self.attack(champion)) yield champion.action else: yield self.env.process(self.search(champion)) champion.action = self.env.process(self.move(champion)) yield champion.action else: champion.action = self.env.process(self.search(champion)) yield champion.action
def test_projectile(): env = simpy.Environment() field = Field(env) team_1 = Team() team_2 = Team() a = Champion(champ_data, team_1) b = Champion(champ_data, team_2) c = Champion(champ_data, team_2) a.name = "a" b.name = "b" c.name = "c" field.assign(a, [0, 0]) field.assign(b, [5, 6]) a.target = b skill = JavelinToss(field) field.env.process(skill.cast(a)) field.env.run(until=10)
def create_champion(self, team: Team, champ_id, level): champ_data = preprocess_champ_data(CHAMPION_DATA[champ_id], level) c = Champion(champ_data, team) self.champion[team].append(c) for t in champ_data["traits"]: if t not in self.trait[team]: if t not in TRAIT.keys(): continue self.trait[team][t] = TRAIT[t](self.field, self.state_manager) self.trait[team][t].add_active_key(c) return c
def action(self, champion: Champion) -> simpy.events.ProcessGenerator: yield self.env.timeout(0) while True: if State.DEATH in champion.state: champion.action = self.env.process(self.death(champion)) yield champion.action if State.DEATH in champion.state: return try: r = self.select_action(champion) yield self.env.process(r) if r else self.env.timeout(0.01) except simpy.Interrupt: print(f'{champion}: action was interrupted')
def attack(self, champion: Champion) -> simpy.events.ProcessGenerator: target: Champion = champion.target damage_type = DamageType.PHYSICAL attack_speed = champion.get_stat(Stat.ATTACK_SPEED) LOGGER[self.env].info(make_battle_record(self.env.now, "BASIC_ATTACK", dict(champion), target=dict(target), attack_speed=attack_speed)) yield self.env.timeout(1 / attack_speed) if target.is_dead(): return print(f'{champion}: Attack {target} with speed {attack_speed:.2f} at {self.env.now:f}') champion.generate_mana(10) damage = Damage(champion, champion.get_stat(Stat.ATTACK), damage_type) damage.set_critical(champion.get_stat(Stat.CRITICAL_DAMAGE) if champion.is_critical() else None) damage.set_miss(target.is_dodge()) dmg: Union[int, float] = target.get_damage(damage) champion.cause_event(EventType.BASIC_ATTACK, damage=dmg, champion=champion, targets=[target])
def move(self, champion: Champion) -> simpy.events.ProcessGenerator: yield self.env.timeout(0) current_cell = self.field.get_location(champion) try: path: search.Path = search.get_path(current_cell, champion.target) except StuckChampion: return heist = champion.get_stat(Stat.HEIST) LOGGER[self.env].info(make_battle_record(self.env.now, "MOVE", dict(champion), start_cell=current_cell.id, target_cell=path[0].id, heist=heist)) yield self.env.timeout(180 / heist) try: self.field.transfer(champion, path[0]) LOGGER[self.env].info(make_battle_record(self.env.now, "ARRIVED", dict(champion), start_cell=current_cell.id, target_cell=path[0].id, heist=heist)) print(f'{champion}: Move to {path[0]} at {self.env.now:f}') except AlreadyExistChampion: LOGGER[self.env].info(make_battle_record(self.env.now, "MOVE_CANCELED", dict(champion), start_cell=current_cell.id, target_cell=path[0].id, heist=heist)) print(f'{champion}: Move action is canceled by already arrived champion at {self.env.now:f}')