def initialize_game(player_name, game): game.turn = 1 game.cursor = Entity(0, 0, 'X', colors.white, 'Cursor', render_order=RenderOrder.CURSOR) game.projectile = Entity(0, 0, '*', colors.white, 'Projectile', render_order=RenderOrder.NONE) game.clean_logs() player = initialize_player(player_name) map = initialize_map(game) game.entities = [player] game.player = player player.x, player.y = map.rooms[0].center initialize_objects(game)
def gen_architecture_from_data(data: Dict, x: int, y: int): material = get_material_data( data) # atm material only affects architecture's name and color arguments = [x, y, *get_generic_args(data, material=material)] kwargs = get_generic_kwargs(data, default_render=RenderOrder.BOTTOM) container_room = data.get(Key.CONTAINER_ROOM, None) on_collision = data.get(Key.ON_COLLISION) on_interaction = data.get(Key.ON_INTERACTION) if container_room is not None: inventory_component = Inventory(capacity=randint(*container_room)) else: inventory_component = None architecture_component = Architecture(on_collision=on_collision, on_interaction=on_interaction) # create the static object using the arguments tuple arch = Entity(*arguments, **kwargs, material=material.get(Key.TYPE), inventory=inventory_component, architecture=architecture_component) return arch
def animate_multi_ray(center_x: int, center_y: int, game: Game, length: int = 2, dirs: Tuple[Tuple[int, int], ...] = ((0, 1), (0, -1)), anim_delay: float = 0.4, color=colors.flame): projectiles = [] for dir in dirs: for step in range(length): step += 1 x = center_x + (dir[0] * step) y = center_y + (dir[1] * step) projectile = Entity(x, y, '*', color, 'Projectile', render_order=RenderOrder.ALWAYS) projectiles.append(projectile) game.entities.append(projectile) render_animation(game, anim_delay) for p in projectiles: game.entities.remove(p)
def animate_sparkle(center_x: int, center_y: int, game: Game, ticks: int = 3, radius: int = 2, anim_delay: float = 0.5, color=colors.flame): """ Creates a 'sparkling' effect around the center, by rendering several randomly created projectiles at the same time. """ directions = DIRECTIONS_CIRCLE for _tick in range(ticks): projectiles = [] for dir in directions: for dist in range(radius): dist += 1 if randint(0, 100) <= 50: x = center_x + (dir[0] * dist) y = center_y + (dir[1] * dist) projectile = Entity(x, y, '*', color, 'Projectile', render_order=RenderOrder.ALWAYS) projectiles.append(projectile) game.entities.append(projectile) render_animation(game, anim_delay) for p in projectiles: game.entities.remove(p) time.sleep(anim_delay)
def animate_explosion(center_x: int, center_y: int, game: Game, spread: int = 3, ignore_walls=False, anim_delay=0.08, color=colors.flame): """ Creates a projectiles moving outward from the center position. TODO additonal switches: character to use for projectile TODO doesn't return anything atm. Add return as needed """ projectiles = [] directions = DIRECTIONS_CIRCLE for _dir in directions: projectile = Entity(center_x, center_y, '*', color, 'Projectile', render_order=RenderOrder.ALWAYS) projectiles.append(projectile) game.entities.append(projectile) for s in range(spread): for i, dir in enumerate(directions): projectile = projectiles[i] projectile.try_move(*dir, game, ignore_entities=True, ignore_walls=ignore_walls) render_animation(game, anim_delay) for p in projectiles: if p in game.entities: game.entities.remove(p)
def move_away_from(self, target: Entity, game: Game): """ Move Entity away from intended target """ # loop through available directions and pick one that is at least one square from the player # loop does not check for walls by design, so an entity can back up into walls (and thus fail/be cornered) dir_list = [] for dir in DIRECTIONS_CIRCLE: flee_pos = (self.x + dir[0], self.y + dir[1]) distance = target.distance_to_pos(*flee_pos) if distance > 1.5: dir_list.append(dir) if len(dir_list) > 0: dir = choice(dir_list) self.try_move(*dir, game)
def animate_projectile(start_x: int, start_y: int, target_x: int, target_y: int, game: Game, forced_distance: int = 0, homing=True, ignore_entities=True, anim_delay=0.05, char='*', color=colors.flame): """ Creates a temporary projectile and animates its movement from start position to target position. TODO additonal switches: character :returns: True if flew full path, False if it hit a wall and entity, if it hit an entity """ # distance = forced_distance if forced_distance > 0 else distance_between_pos(start_x, start_y, target_x, target_y) projectile = Entity(start_x, start_y, char, color, 'Projectile', render_order=RenderOrder.ALWAYS) game.entities.append(projectile) result = animate_move_to(projectile, target_x, target_y, game, anim_delay=anim_delay, ignore_entities=ignore_entities) game.entities.remove(projectile) if isinstance(result, Entity): return result else: return result
def gen_item_from_data(data: Dict, x: int, y: int, material=False, condition=False, craftsmanship=False, forced_moveset=None): material = get_material_data(data, forced=material) condition = get_condition_data(forced=condition) if material else {} craftsmanship = get_craftsmanship_data( forced=craftsmanship) if material else {} arguments = [ x, y, *get_generic_args(data, material=material, condition=condition, craftsmanship=craftsmanship) ] kwargs = get_generic_kwargs(data, default_render=RenderOrder.ITEM) on_use = data.get(Key.ON_USE_EFFECT) equip_to = data.get(Key.EQUIP_TO) useable_component = None if on_use is not None: useable_kwargs = { 'on_use_effect': on_use, 'on_use_msg': data.get(Key.ON_USE_MSG, ''), 'projectile': data.get(Key.ON_USE_PROJECTILE), 'charges': data.get(Key.ON_USE_CHARGES, 1), 'on_use_params': data[Key.ON_USE_PARAMS] } #useable_component = Useable(on_use_effect = on_use, on_use_msg=msg, projectile=projectile, charges=charges, on_use_params=params) useable_component = Useable(**useable_kwargs) equipment_component = None if equip_to is not None: dmg_potential = data.get(Key.DMG_POTENTIAL) if dmg_potential: mat_mod = material.get(Mod.DMG_FLAT, 0) craft_mod = craftsmanship.get(Mod.DMG_FLAT, 0) cond_mod = condition.get(Mod.COND_MULTIPL, 1) dmg_potential = (round( max((dmg_potential[0] + mat_mod + craft_mod) * cond_mod, 1)), round( max((dmg_potential[1] + mat_mod + craft_mod) * cond_mod, 1))) av = data.get(Key.AV) if av: mat_mod = material.get(Mod.AV_FLAT, 0) craft_mod = craftsmanship.get(Mod.AV_FLAT, 0) cond_mod = condition.get(Mod.COND_MULTIPL, 1) av += round((max(mat_mod + craft_mod, 1)) * cond_mod) block_def = data.get(Key.BLOCK_DEF) if block_def: mat_mod = material.get(Mod.AV_FLAT, 0) craft_mod = craftsmanship.get(Mod.AV_FLAT, 0) cond_mod = condition.get(Mod.COND_MULTIPL, 1) block_def += round((max(mat_mod + craft_mod, 1)) * cond_mod) #attack_type = forced_attacktype if forced_attacktype else data.get(Key.ATTACKTYPE, AttackType.NORMAL) if forced_moveset is None: moveset = data.get(Key.MOVESET) else: moveset = forced_moveset if moveset: moveset_component = Moveset(moveset.copy()) else: moveset_component = None equipment_kwargs = { 'e_to': equip_to, 'dmg_potential': dmg_potential, 'av': av, 'block_def': block_def, 'attack_range': data.get(Key.ATTACK_RANGE), 'qu_slots': data.get(Key.QU_SLOTS), 'l_radius': data.get(Key.L_RADIUS), 'moveset': moveset_component, 'two_handed': data.get(Key.TWO_HANDED), 'one_handed_penalty_mod': data.get(Key.ONE_HANDED_PENALTY_MOD) } equipment_component = Equipment(**equipment_kwargs) item_component = Item(condition=condition.get(Key.TYPE), craftsmanship=craftsmanship.get(Key.TYPE), useable=useable_component, equipment=equipment_component) # create the item using item_class and the arguments tuple i = Entity(*arguments, **kwargs, material=material.get(Key.TYPE), item=item_component) return i