def handle_battle(self, delta, game): """Deals with updating the battle game loop""" delta_time = delta / 1000 # Update player for player in game.party.players: player.handle_battle(delta_time, game, self.game) # Update monster for monster in game.encounter: monster.handle_battle(delta_time, game, self.game) # Check for win or lose conditions if all(player.fallen for player in game.party.players): print("LOST") self.game.quit() if all(monster.fallen for monster in game.encounter): for player in game.party.players: player.cleanup_battle() shards, items = self.generate_loot(game) # Remove the encounter self.game.message("battle", Message("end")) self.game.message( "sound", Message("bg", "data/sound/background/Puzzle-Game.wav")) if not game.current_dialogue: self.game.message("ui", Message("layout", "loot")) self.game.message("game", Message("loot", items, shards)) else: self.game.message("ui", Message("layout", "scenario"))
def execute(self, game, system): """Initiates a battle. If no monsters are declared for the battle then a random set of monsters will be generated at the specified challenge rating. Otherwise monsters will override.""" monster_names = [] if self.monsters: monster_names = self.monsters else: challenge = self.challenge while challenge > 0 and len(monster_names) < 3: valid_monsters = [] # Get valid monsters for name, monster in Monster.MONSTERS.items(): if monster["rating"] <= challenge and \ monster["location"] == game.floor_type and \ not monster["unique"]: valid_monsters.append((name, monster["rating"])) # If no valid monsters break if not valid_monsters: break # Select monster name, rating = random.choice(valid_monsters) monster_names.append(name) challenge -= rating # If there are remaining challenge points to distribute if challenge: # Any rating left over # then we add the highest valid_monsters = [(name, monster["rating"]) for name, monster in Monster.MONSTERS.items() if monster["rating"] <= challenge and \ monster["location"] == game.floor_type and \ not monster["unique"]] highest_value = 0 for name, value in valid_monsters: if value > highest_value: highest_value = value valid_names = [ name for name, value in valid_monsters if value <= highest_value ] monster_names.append(random.choice(valid_names)) # Execute system.message( "battle", Message("start", [Monster(name) for name in monster_names])) system.message("ui", Message("layout", "battle")) system.message( "sound", Message("bg", "data/sound/background/Theyre-Closing-In_looping.wav"))
def level_up(self, game, system): if game.party.shards >= self.character.get_level_required_shard(): system.message("ui", Message("push-bg", (50, 50, 50))) system.message("ui", Message("layout", "level")) system.message( "game", Message("shard", -self.character.get_level_required_shard())) system.message("game", Message("level", self.character)) else: system.message( "animation", Message("message", "Insufficient shards to level up", (255, 0, 0)))
def on_click(self, game, system): # In no encounter state if not game.encounter and not game.current_dialogue: if game.current_player == self.character: system.message("ui", Message("layout", "default")) system.message("game", Message("select-player", None)) else: system.message("ui", Message("layout", "character")) system.message("game", Message("select-player", self.character)) # During an encounter elif game.encounter: if game.current_player: if game.current_player.selected_move: if game.current_player.selected_move.is_valid_cast( game.current_player.target, game.party.players, game.encounter): system.message( "game", Message("select-player", self.character)) elif game.current_player.selected_move.is_valid_target( game.current_player.target + [self.character], game.party.players, game.encounter): system.message( "battle", Message("select-target", self.character)) else: system.message("game", Message("select-player", self.character)) else: system.message("game", Message("select-player", self.character))
def update(self, delta, entities): """Game system also handles exiting of the game""" super().update(delta, entities) for e in pygame.event.get(): if e.type == pygame.QUIT: self.system.message("game", Message("quit"))
def dispatch(self, message, game, system): """Function for determining what action to call depending on the message""" if message.mtype == "travel": # Travels the part location = message.args[0] game.current_location = location game.current_location.generate() game.current_dialogue = game.current_location.get_event() game.loot = None elif message.mtype == "dialogue": dialogue = message.args[0] cur = game.current_location.get_dialogue(dialogue) while cur.fail: if randint(0, 99) > cur.chance: cur = game.current_location.get_dialogue(cur.fail) else: break game.current_dialogue = cur.name elif message.mtype == "action": dialogue = message.args[0] for action in dialogue.get_actions(): action.execute(game, system) elif message.mtype == "close-event": game.current_dialogue = None game.current_player = None elif message.mtype == "select-player": player = message.args[0] game.current_player = player elif message.mtype == "loot": items, shards = message.args game.loot = (items, shards) system.message("game", Message("shard", shards)) elif message.mtype == "shard": shards = message.args[0] game.party.shards += shards elif message.mtype == "level": player = message.args[0] player.roll_moves() system.message("ui", Message("load-moves", player.level_up_moves)) elif message.mtype == "level-player": move = message.args[0] game.current_player.level_up(move) elif message.mtype == "apply-effect": effect = message.args[0] for player in game.party.players: player.add_effect(effect)
def on_click(self, game, system): if game.current_player and game.current_player.selected_move and \ not self.monster.fallen: if game.current_player.selected_move.is_valid_target( game.current_player.target + [self.monster], game.party.players, game.encounter): system.message("battle", Message("select-target", self.monster))
def on_click(self, game, system): """When clicked on will send a message to the hover system and determine if self needs to be set""" if self.value is not None and self.on_set(game) and self.address: system.message("hover", Message("set", self.address, self, self.stype)) self.on_setted(game, system) if not self.cloneable: self.set_value(None) self.set_dirty(True)
def off_click(self, game, system): """This off_click needs to be validated by the validator the the object will be dropped off""" if game.hover_data is not None and self.address is not None: address, _, stype = game.hover_data other_container, other_key = address value = other_container[other_key] if stype == self.stype and self.on_drop(value): self.set_value(value) self.on_dropped(game, system) system.message("hover", Message("drop", self))
def update(self, delta, entities): super().update(delta, entities) keys = pygame.key.get_pressed() if keys[pygame.K_w]: self.system.message( "player", Message("move", Vector.up() * self.speed * delta)) elif keys[pygame.K_a]: self.system.message( "player", Message("move", Vector.left() * self.speed * delta)) elif keys[pygame.K_s]: self.system.message( "player", Message("move", Vector.down() * self.speed * delta)) elif keys[pygame.K_d]: self.system.message( "player", Message("move", Vector.right() * self.speed * delta))
def init(self, game): game.difficulty = "normal" game.current_dungeon = Dungeon("catacombs", game.difficulty) game.floor_type = game.current_dungeon.level self.message(Message("travel", game.current_dungeon.start)) game.party = Party([Player("Player " + str(i + 1)) for i in range(4)]) game.loot = None for player in game.party.players: if player is not None: player.add_move(self.move_dm.get_move("attack")) player.castbar[0] = player.moves[0] # temp
def init(self, entities): self.player = Entity("Player", Vector(100, 100), self.system) self.player.add_component( Shape( Polygon(Vector(-5, -5), Vector(5, -5), Vector(5, 5), Vector(-5, 5)), True)) # self.player.add_component(LightSource(Vector(0, 2), 100, 0.5)) # self.player.add_component(LightSource(Vector(2, 0), 100, 0.5)) # self.player.add_component(LightSource(Vector(0, -2), 100, 0.5)) # self.player.add_component(LightSource(Vector(-2, 0), 100, 0.5)) self.player.add_component(LightSource(Vector(0, 0), 100, 1)) self.system.message("game", Message("add_entity", self.player)) terrain = Entity("terrain", Vector(0, 0), self.system) terrain.add_component( Shape(Polygon(Vector(400, 400), Vector(450, 450), Vector(500, 420)))) terrain.add_component( Shape(Polygon(Vector(10, 10), Vector(200, 200), Vector(0, 300)))) self.system.message("game", Message("add_entity", terrain))
def on_cast(self, target, caster, players, monsters, system): """Order IMPORTANT in modifying damage: Suggested standard is additions, then multiplications""" damage = self.damage for mod in self.modifiers: damage = mod.modify(damage, target, caster) damage = target.deal_damage(caster, damage, self.dtype) system.message( "animation", Message("battle-message", target, str(damage), (255, 0, 0))) return "%s dealt %d %s damage to %s" % \ (caster.name, damage, self.dtype, target.name)
def update(self, delta, entities): messages = self.flush_messages() for message in messages: message_call = message.mtype.split('.') # Passing messages to subsystems if len(message_call) == 2: self.pipeline[message_call[0]].message( Message(message_call[1], *message.args)) else: getattr(self, message.mtype)(game, *message.args) surface = pygame.display.get_surface() surface.fill((0, 0, 0)) # Call systems for system in self.pipeline.values(): system.render(delta, entities, surface) pygame.display.flip()
def execute(self, game, system): """Creates a loot table If shard or items is declared the respective loot will be created. Otherwise reward_tier will override generating a random loot table.""" shards = 0 items = [] # Handle no shards or items if not self.shards and not self.items: # Generate shards if self.reward_tier == LootAction.LOW: shards = game.floor_level * random.randint(15, 20) elif self.reward_tier == LootAction.MEDUIM: shards = game.floor_level * random.randint(30, 35) elif self.reward_tier == LootAction.HIGH: shards = game.floor_level * random.randint(50, 70) # Generate items if self.reward_tier == LootAction.MEDUIM: # 30% change of getting an item of "medium" reward tier if random.randint(0, 99) < 30: items = [ItemFactory.generate( game.encounter, game.floor_type)] elif self.reward_tier == LootAction.HIGH: # 70% change of getting an item of "high" reward tier if random.randint(0, 99) < 70: items = [ItemFactory.generate( game.encounter, game.floor_type)] else: if self.shards: shards = self.shards if self.items: items = [ItemFactory.static_generate(name) for name in self.items] # Assign create loot table to the game system.message("game", Message("loot", items, shards))
def on_click(self, game, system): super().on_click(game, system) if game.encounter: system.message("sound", Message("ui", "data/sound/click.wav")) system.message("battle", Message("select-move", self.get()))
def on_clicked(self, game, system): system.message("sound", Message("ui", "data/sound/click.wav"))
def on_hovered(self, game, system): system.message("sound", Message("ui", "data/sound/menu_select_sfx.wav"))
def on_click(self, game, system): system.message("game", Message("level-player", self.move)) system.message("ui", Message("pop-bg", self.move)) system.message("ui", Message("layout", "character")) system.message("ui", Message("refresh-character"))
def execute(self, game, system): """Changes party shards by given amount tree.""" system.message("game", Message("apply-effect", self.effect))
def execute(self, game, system): """Starts a new dialogue tree.""" system.message("game", Message("dialogue", self.dialogue)) system.message("ui", Message("layout", "scenario"))
def on_setted(self, game, system): system.message("sound", Message("ui", "data/sound/pick-up.wav"))
def execute(self, game, system): """Changes party shards by given amount tree.""" system.message("game", Message("shard", self.shards))
def on_click_loot(self, game, system): system.message("ui", Message("layout", "loot")) system.message("game", Message("select-player", None))
def on_dropped(self, game, system): system.message("sound", Message("ui", "data/sound/drop-off.wav"))
def on_click(game, system): system.message("game", Message("dialogue", dialogue))
def on_click_travel(self, game, system): system.message("ui", Message("layout", "travel")) system.message("game", Message("select-player", None))
def on_click(game, system): system.message("ui", Message("layout", "default")) system.message("game", Message("close-event")) system.message("game", Message("action", dialogue)) self.dialogue = None
def on_click(self, game, system): if not self.disable: system.message("ui", Message("layout", "scenario")) system.message("game", Message("travel", self.location))