def exit_stairs(x, y): """Exit stairs components.""" return [ c.Render("stairs-down"), c.TilePosition(x, y), c.ExitStairs(), ]
def stairs(x, y, direction="down"): """Stairs components.""" return [ c.Render("stairs-" + str(direction)), c.TilePosition(x, y), c.Stairs(direction=direction), ]
def item(**args): """Item components.""" return [ c.Describable(args["name"], args["desc"]), c.Render(args["image"]), c.TilePosition(args["x"], args["y"]), c.Item(consumable=args["consumable"]), ]
def process(self, **args): for entity, (pos, initiative, _) in self.world.get_components(c.TilePosition, c.Initiative, c.AIDodge): if initiative.nextturn > 1: continue for _, (o_pos, bump, _) in self.world.get_components(c.TilePosition, c.Bump, c.MyTurn): bump_pos = c.TilePosition(o_pos.x+bump.x, o_pos.y+bump.y) if bump_pos == pos: if self.world.get_system(GridSystem).can_move_in_direction(entity, (bump.x, bump.y)): self.world.get_system(GridSystem).move_entity(entity, (pos.x+bump.x, pos.y+bump.y)) initiative.nextturn += initiative.speed # would like to remove MyTurn component but the ai doesn't have it yet, should change
def handle_input(self, keypress): handled = False if keypress.has_action(key_input.Action.DOWN): handled = True self.cursorpos = min(self.cursorpos + 1, self.size-1) audio.play("click2", replace=True) if keypress.has_action(key_input.Action.UP): handled = True self.cursorpos = max(self.cursorpos - 1, 0) audio.play("click2", replace=True) if keypress.has_action(key_input.Action.BACK): handled = True self.remove_scene() audio.play("drop", replace=True) if keypress.has_action(key_input.Action.ACCEPT): handled = True audio.play("snap1", replace=True) selection = self.options[self.cursorpos] if selection == "use": self.remove_scene() use = self.world.entity_component(self.item, c.UseEffect) if self.world.has_component(self.world.tags.player, c.WeakPotions): for effect in use.effects: # Weak potions for mecha getattr(self.parent.parent, effect[0])(self.world.tags.player, int(effect[1]/2), *effect[2:]) else: for effect in use.effects: # Normal effect getattr(self.parent.parent, effect[0])(self.world.tags.player, *effect[1:]) if self.world.entity_component(self.item, c.Item).consumable: self.world.entity_component(self.world.tags.player, c.Inventory).contents.remove(self.item) self.world.delete_entity(self.item) if selection == "prime": self.world.entity_component(self.item, c.Explosive).primed = True if selection == "throw": self.visible = False throw_scene = self.parent.add_child_scene(ThrowOptions, self.item) self.game.set_focus(throw_scene) self.remove_scene() if selection == "drop": self.remove_scene() self.world.entity_component(self.world.tags.player, c.Inventory).contents.remove(self.item) self.world.remove_component(self.item, c.Stored) pos = self.world.entity_component(self.world.tags.player, c.TilePosition) self.world.add_component(self.item, c.TilePosition(pos.x, pos.y)) if keypress.has_action(key_input.Action.INVENTORY_CLOSE): self.remove_scene() return handled
def wall(x, y): """Wall components.""" return [ c.Render(choice(("wall1", "wall2"))), c.TilePosition(x, y), c.Blocker(), c.Destructible(), # For alive walls #c.Health(15), #c.Initiative(4), #c.AI(), #c.Movement(False), # c.Attack(5), ]
def creature(**args): """Creature components.""" if "image" not in args: args["image"] = None components = [ c.Render(args["image"]), c.TilePosition(args["x"], args["y"]), c.Movement(diagonal=args["diagonal"]), c.Blocker(), c.Health(args["health"]), c.Attack(args["attack"]), ] if "anim_idle" in args: components.append( c.Animation(idle=args["anim_idle"], ready=args["anim_ready"])) if "speed" in args: components.append(c.Initiative(args["speed"])) return components
def generate_level(self, properties): """Generate a level depending on how far the player is.""" g_sys = self.world.get_system(s.GridSystem) gridsize = (g_sys.gridwidth, g_sys.gridheight) if "boss" in properties: level = level_gen.generate_fly_boss_level(gridsize) else: level_type = "normal" if "fire" in properties: level_type = "fire" level = level_gen.generate_random_level(gridsize, self.level_num, level_type) for components in level.entities: self.world.create_entity(*components) self.world.add_component(self.world.tags.player, c.TilePosition(*level.player_start)) if self.level_num == 1: self.world.add_component( self.world.tags.player, c.FreeTurn(1)) # To fix off-by-one turn timing inv = self.world.entity_component(self.world.tags.player, c.Inventory) for _ in range(3): # This code will create the bomb, remove its tile position then # manually put it into the player's inventory. bomb = self.world.create_entity(*entity_templates.bomb(0, 0)) self.world.remove_component(bomb, c.TilePosition) self.world.add_component(bomb, c.Stored(self.world.tags.player)) inv.contents.append(bomb) else: self.world.remove_component( self.world.tags.player, c.MyTurn) # To fix off-by-one turn timing self.world.get_system(s.GridSystem).process( ) # Fixes glitch with no collision on first turn of level
def handle_input(self, keypress): handled = False if keypress.has_action(key_input.Action.BACK): self.game.set_focus( self.parent.add_child_scene(inventory_options.InventoryOptions, self.item)) self.remove_scene() handled = True if keypress.has_action(key_input.Action.DIRECTION): self.dir = keypress.get_direction() playerpos = self.world.entity_component(self.world.tags.player, c.TilePosition) self.targettile = [playerpos.x, playerpos.y] stopped = False distance = 0 while not stopped: self.targettile[0] += self.dir[0] self.targettile[1] += self.dir[1] distance += 1 if not self.world.get_system(s.GridSystem).on_grid( self.targettile): self.targettile[0] -= self.dir[0] self.targettile[1] -= self.dir[1] distance -= 1 stopped = True if self.world.get_system(s.GridSystem).get_blocker_at( self.targettile) != 0: distance -= 1 stopped = True if distance == 5: stopped = True self.droptile = [ playerpos.x + self.dir[0] * distance, playerpos.y + self.dir[1] * distance ] handled = True if keypress.has_action(key_input.Action.ACCEPT): if self.droptile is not None: self.world.entity_component(self.world.tags.player, c.Inventory).contents.remove( self.item) self.world.remove_component(self.item, c.Stored) self.world.add_component(self.item, c.TilePosition(*self.droptile)) if self.targettile is not None: target = self.world.get_system(s.GridSystem).get_blocker_at( self.targettile) if target: if self.world.has_component(self.item, c.UseEffect): use = self.world.entity_component( self.item, c.UseEffect) for effect in use.effects: getattr(self.parent.parent, effect[0])(target, *effect[1:]) if self.world.entity_component(self.item, c.Item).consumable: self.world.add_component(self.item, c.Dead()) self.remove_scene() handled = True if keypress.has_action(key_input.Action.INVENTORY_CLOSE): self.remove_scene() return handled