def run( self, player_character: Actors.PlayerCharacter ) -> Iterator[GameSpace.PlayerActionResponse]: # Just mow the enemies down in order victory_response = GameSpace.PlayerActionResponse( source=player_character) for enemy in self.enemies: kill_response = GameSpace.PlayerActionResponse( source=player_character) while not enemy.is_dead: # WARN An infinite loop can appear here. attack_response = GameSpace.PlayerActionResponse( source=player_character) # Damage is always calculated at full power (min distance) assert player_character.has_weapon_equipped dmg = player_character.weapon.damage player_character.weapon.on_damage() enemy.take_damage(dmg) attack_response.is_successful = True attack_response.damage = dmg attack_response.target = enemy attack_response.text = f"{player_character.name} does {dmg} dmg to {enemy.name}." yield attack_response defense_response = GameSpace.PlayerActionResponse( source=player_character) dmg = enemy.base_attack player_character.take_damage(dmg) defense_response.damage = dmg defense_response.target = enemy defense_response.text = f"{player_character.name} takes {dmg} dmg from {enemy.name}." defense_response.is_successful = True yield defense_response if player_character.is_dead: break if not player_character.is_dead: kill_response.items += enemy.on_death() kill_response.is_successful = True player_character.inventory += kill_response.items kill_response.text = f"{player_character.name} kills {enemy.name}, " \ f"receiving {','.join([str(item) for item in kill_response.items])}" yield kill_response else: break if not player_character.is_dead: victory_response.is_successful = True victory_response.text = f"{player_character.name} has successfully slain their foes." else: victory_response.is_successful = False victory_response.text = f"{player_character.name} has fallen in combat. " \ f"They'll be revived in the starting town." yield victory_response
def main(): parser = argparse.ArgumentParser( description="Run an instance of a Discordia server", prog="Discordia") parser.add_argument( '-W --show_window', dest='show_window', action='store_const', const=True, default=False, help= "Show a window containing a live view of the entire world. WARNING: CPU-intensive." ) args = parser.parse_args() # Read in world file if found if os.path.isfile(r'./world.p'): world: GameSpace.World = pickle.load(open(r'./world.p', 'rb')) else: world = GameSpace.World(ConfigParser.WORLD_NAME, ConfigParser.WORLD_WIDTH, ConfigParser.WORLD_HEIGHT) adapter = WorldAdapter(world) display = WindowRenderer(adapter) threading.Thread(target=update_display, args=(display, args.show_window), daemon=True).start() discord_interface = DiscordInterface(adapter) # discord_interface.bot.loop.create_task(update_display(display)) # threading.Thread(target=discord_interface.bot.run, args=(ConfigParser.DISCORD_TOKEN,), daemon=True).start() LOG.info( "Discordia Server has successfully started. Press Ctrl+C to quit.") discord_interface.bot.run(ConfigParser.DISCORD_TOKEN)
def setUp(self) -> None: self.world = GameSpace.World("Test World", self.WORLD_WIDTH, self.WORLD_HEIGHT, seed=self.random_seed) self.adapter = WorldAdapter(self.world) self.display = WindowRenderer(self.adapter) for idx in range(self.NUM_USERS): self.adapter.register_player(idx, player_name=f"User{idx}") self.display.on_draw()
def test_astar_pathfinding(self): self.display.on_draw() self.display.get_world_view(title="astar_before") start = self.world.starting_town found_path = None end_index = 1 for end_index in range(end_index, len(self.world.towns) - 1): end = self.world.towns[end_index] found_path = GameSpace.AStarPathfinder(self.world).astar( start, end) if found_path: found_path = list(found_path) break if not found_path: self.fail("no path found") for space in found_path: self.world.map[space.y][space.x].terrain = GameSpace.NullTerrain() if end_index > 1: LOG.info(f"end_index: {end_index}") self.display.on_draw() self.display.get_world_view(title="astar_after")
def __init__(self, world_adapter: WorldAdapter): self.world_adapter = world_adapter self.world_adapter.add_renderer(self) self.terrain_map = [[ ph.Canvas().load(GameSpace.WaterTerrain().sprite_path_string) for x in range(self.world_adapter.width) ] for y in range(self.world_adapter.height)] self.rendered_canvas = ph.gridstack(self.terrain_map) self.rendered_canvas.name = WINDOW_NAME self.base_cell_width = self.terrain_map[0][0].width self.base_cell_height = self.terrain_map[0][0].height self._sprite_cache = keydefaultdict(lambda k: ph.Canvas().load(k))
def run(self, player_character): yield GameSpace.PlayerActionResponse(is_successful=True, text=self.flavor_text, source=player_character)