Beispiel #1
0
 def deduct_resources(self, team, resource_deduction):
     self.resources[team] = max(self.resources[team] - resource_deduction,
                                0)
     publish_game_event(EventType.E_RESOURCES_LOST, {
         'team': team,
         'resources_lost': resource_deduction
     })
Beispiel #2
0
    def fill_team(self, team, nickname):
        if team in self.open_teams:
            self.open_teams.remove(team)
        self.filled_teams[team] = nickname

        if len(self.open_teams) == 0:
            publish_game_event(EventType.E_ALL_TEAMS_FILLED, {})
Beispiel #3
0
    def handle_phase_build(self, event):
        # Execute build orders
        if isinstance(self.current_order, BuildOrder):
            if self.is_contested():
                # Can't build if there's an enemy piece here
                self.abort_order()
            else:
                if self.current_order.new_piece_type in ALL_UNITS:
                    self.play_sound(SoundType.UNIT_CREATED)
                else:
                    self.play_sound(SoundType.BUILDING_BUILT)

                publish_game_event(
                    EventType.E_PIECE_BUILT, {
                        'tx': self.current_order.tx,
                        'ty': self.current_order.ty,
                        'team': self.team,
                        'new_piece_type': self.current_order.new_piece_type
                    })

                # Deduct unit price
                self.get_manager(Manager.TEAM).deduct_resources(
                    self.team,
                    self.get_manager(Manager.TEAM).attr(
                        self.team, self.current_order.new_piece_type,
                        Attribute.PRICE))
                # Pop orders once they're executed
                self.current_order = None
Beispiel #4
0
 def add_resources(self, team, new_resources):
     self.resources[team] = clamp(self.resources[team] + new_resources, 0,
                                  MAX_RESOURCES)
     publish_game_event(EventType.E_RESOURCES_GAINED, {
         'team': team,
         'new_resources': new_resources
     })
Beispiel #5
0
    def handle_phase_ranged(self, event):
        # Execute ranged attack orders
        if isinstance(self.current_order, RangedAttackOrder):
            if self.is_contested():
                # Can't conduct a ranged attack if there's an enemy on our tile
                publish_game_event(EventType.E_ORDER_CANCELED, {
                    'gx': self.gx,
                    'gy': self.gy,
                    'team': self.team
                })

                # Abort the order
                self.current_order = None
            else:
                self.play_sound(SoundType.RANGED_ATTACK)
                publish_game_event(
                    EventType.E_UNIT_RANGED_ATTACK, {
                        'gx': self.gx,
                        'gy': self.gy,
                        'team': self.team,
                        'tx': self.current_order.tx,
                        'ty': self.current_order.ty
                    })

                # Pop orders once they're executed
                self.current_order = None
Beispiel #6
0
    def remove_team(self, team, notify=True):
        self.open_teams.append(team)
        del self.filled_teams[team]

        publish_game_event(EventType.E_TEAM_LEFT, {'team': team})

        if notify:
            self.send_message(MessageCode.TEAM_EMPTIED, team, "")
Beispiel #7
0
 def cancel(self):
     super().cancel()
     publish_game_event(EventType.E_CLOSE_MENU, {
         'gx': self.tx,
         'gy': self.ty,
         'option': None,
         'team': self.team
     })
Beispiel #8
0
    def set_turn_submitted(self, team):
        self.turn_submitted[team] = True

        if self.check_if_ready_to_submit_turns():
            self.play_sound(SoundType.ALL_TURNS_SUBMITTED)
            publish_game_event(EventType.E_ALL_TURNS_SUBMITTED, {})
            for team in self.teams:
                self.turn_submitted[team] = False
Beispiel #9
0
    def disconnect_from_host(self, notify_host=True):
        if notify_host:
            self.send_message(MessageCode.DROP_CONNECTION, self.team,
                              self.nickname)

        self.connection.close()
        self.networked_game = False
        publish_game_event(EventType.NETWORK_DISCONNECTED_FROM_HOST,
                           {'team': self.team})
Beispiel #10
0
    def abort_order(self):
        self.play_sound(SoundType.ORDER_CANCELED)
        publish_game_event(EventType.E_ORDER_CANCELED, {
            'gx': self.gx,
            'gy': self.gy,
            'team': self.team
        })

        # Abort the order
        self.current_order = None
Beispiel #11
0
 def heal_hp(self, heal):
     max_hp = self.attr(Attribute.MAX_HP)
     if self.hp < max_hp:
         self.hp = min(self.hp + heal, max_hp)
         publish_game_event(EventType.E_PIECE_HEALED, {
             'gx': self.gx,
             'gy': self.gy,
             'team': self.team,
             'health': heal
         })
Beispiel #12
0
    def quit_network_game(self, notify_host=True):
        print("Exiting network game")
        if self.is_host:
            # Close down the game, notify clients
            self.send_message(MessageCode.END_CONNECTION, self.team, "")
        else:
            # Disconnect from the host
            self.disconnect_from_host(notify_host)

        self.networked_game = False
        publish_game_event(EventType.E_NETWORKING_ERROR, {})
Beispiel #13
0
 def do_all_planning(self, event=None):
     try:
         self.do_preplanning()
         self.act_on_planning()
     except Exception as exception:
         from sys import exc_info
         # Something's gone wrong, so re-raise this exception with an event in the main thread
         publish_game_event(EventType.AI_EXCEPTION, {
             'exception': exception,
             'exc_info': exc_info(),
         })
Beispiel #14
0
    def confirm(self):
        super().confirm()
        selected_option = self.options[self.menu_pos]

        publish_game_event(
            EventType.E_CLOSE_MENU, {
                'gx': self.tx,
                'gy': self.ty,
                'option': selected_option,
                'team': self.team
            })
Beispiel #15
0
    def remove_piece(self, piece=None):
        if not piece:
            piece = self.get_manager(Manager.PIECE).get_piece_at(
                self.gx, self.gy, self.team)

        if piece:
            publish_game_event(EventType.E_PIECE_DEAD, {
                'gx': self.gx,
                'gy': self.gy,
                'team': self.team,
                'piece': piece
            })
Beispiel #16
0
    def select(self, event):
        if event.gx == self.gx and event.gy == self.gy and event.team == self.team:
            available_actions = self.get_available_actions()

            if not event.selecting_movement and len(available_actions) > 0:
                publish_game_event(
                    EventType.E_OPEN_MENU, {
                        'gx': self.gx,
                        'gy': self.gy,
                        'team': self.team,
                        'options': available_actions
                    })
Beispiel #17
0
 def confirm(self, event):
     if (event.gx, event.gy) in self.coordinate_set and \
             event.team == self.team and event.selecting_movement:
         publish_game_event(
             EventType.E_SELECT_TILE, {
                 'gx': self.gx,
                 'gy': self.gy,
                 'option': self.option,
                 'team': self.team,
                 'dx': event.gx,
                 'dy': event.gy,
             })
Beispiel #18
0
 def handle_menu_selection(self, event):
     if event.option == Option.MENU_SAVE_MAP:
         SESSION.save_map_to_file()
     elif event.option == Option.MENU_QUIT_BATTLE:
         publish_game_event(EventType.E_QUIT_BATTLE, {})
     elif event.option == Option.MENU_FILL_WITH_CURRENT_TILE:
         self.fill_with_current_tile()
     elif event.option == Option.MENU_DESTROY_ALL_PIECES:
         self.clear_all_pieces()
     elif event.option == Option.MENU_MIRROR_X:
         self.mirror_map(mirror_x=True, mirror_y=False)
     elif event.option == Option.MENU_MIRROR_Y:
         self.mirror_map(mirror_x=False, mirror_y=True)
Beispiel #19
0
    def progress_phase(self, event=None):
        if not self.validate_phase():
            return

        # Publish an event for the end of the orders phase, if necessary
        if self.phase == BattlePhase.ORDERS:
            publish_game_event(EventType.END_PHASE_ORDERS, {})

        # Clean up at the end of turns
        if self.phase == BattlePhase.EXECUTE_SPECIAL:
            publish_game_event(EventType.E_CLEANUP, {})

        # Progress the phase
        new_phase = self.phase.value + 1
        if new_phase >= len(BattlePhase):
            new_phase = 0
        self.phase = BattlePhase(new_phase)

        # Log the start of a new round, if necessary
        if self.phase == BattlePhase.START_TURN:
            self.turn += 1

        # Publish events for the new phase
        publish_game_event(EventType.E_NEXT_PHASE, {'new_phase': self.phase})
        publish_game_event(self.phase_events[self.phase],
                           {"turn_number": self.turn})
Beispiel #20
0
    def handle_end_phase_move(self, event):
        # Apply buffs to allies on adjacent tiles, if necessary
        armor_share = self.attr(Attribute.ARMOR_SHARE)
        if armor_share > 0:
            adjacent_allies = self.get_manager(
                Manager.PIECE).get_adjacent_pieces(self.gx, self.gy, self.team)

            for ally in adjacent_allies:
                ally.temporary_armor += armor_share
                publish_game_event(EventType.E_ARMOR_GRANTED, {
                    'gx': ally.gx,
                    'gy': ally.gy,
                    'team': ally.team
                })
Beispiel #21
0
    def connect_to_host(self):
        self.send_message(MessageCode.NEW_CONNECTION, Team.NONE,
                          str(self.nickname))

        # Block until we receive the map information back from the host.
        while not self.map_data:
            try:
                self.network_step(blocking=True)
            except Exception as err:
                print("Failed to connect to host. Aborting.")
                ERROR_LOGGER.exception("Failed to connect to host", err)
                SESSION.reset()
                publish_game_event(EventType.E_QUIT_BATTLE, {})
                break
Beispiel #22
0
    def handle_phase_move(self, event):
        # Execute move orders
        if isinstance(self.current_order, MoveOrder):
            # Note: we don't change our own gx and gy-- the piece manager will do that when it changes our 'address'
            publish_game_event(
                EventType.E_UNIT_MOVED, {
                    'gx': self.gx,
                    'gy': self.gy,
                    'team': self.team,
                    'dx': self.current_order.dx,
                    'dy': self.current_order.dy
                })

            # Pop orders once they're executed
            self.current_order = None
Beispiel #23
0
 def confirm(self):
     super().confirm()
     if self.can_confirm_or_cancel():
         if not self.get_manager(Manager.TEAM).is_turn_submitted(self.team):
             if not self.get_manager(Manager.PIECE).get_piece_at(int(self.gx), int(self.gy), self.team) and \
                     not self.move_ui:
                 self.open_pause_menu()
             else:
                 publish_game_event(
                     EventType.E_SELECT, {
                         'gx': int(self.gx),
                         'gy': int(self.gy),
                         'team': self.team,
                         'selecting_movement': self.move_ui is not None
                     })
Beispiel #24
0
    def handle_text_input(self, event):
        self.text_input.destroy()
        self.text_input = None

        if event.input:
            if event.tag == Option.NEW_MAP:
                publish_game_event(EventType.MENU_SELECT_OPTION, {
                    'option': event.tag,
                    'mapname': event.input + ".map"
                })
            elif event.tag == Option.JOIN_GAME:
                publish_game_event(EventType.MENU_SELECT_OPTION, {
                    'option': event.tag,
                    'address': event.input
                })
            elif event.tag == Setting.NICKNAME:
                SETTINGS.set_nonnumeric_setting(Setting.NICKNAME, event.input)
Beispiel #25
0
    def try_submitting_turn(self, team):
        if not self.is_turn_submitted(team) and self.get_manager(
                Manager.PIECE).validate_orders(team):
            self.turn_submitted[team] = True
            self.play_sound(SoundType.TURN_SUBMITTED)
            publish_game_event(
                EventType.E_TURN_SUBMITTED, {
                    'team':
                    team,
                    'orders':
                    self.get_manager(Manager.PIECE).serialize_orders(team)
                })

            if self.check_if_ready_to_submit_turns():
                publish_game_event(EventType.E_ALL_TURNS_SUBMITTED, {})
                for team in self.teams:
                    self.turn_submitted[team] = False
Beispiel #26
0
    def remove_team(self, team):
        del self.resources[team]
        del self.owned_upgrades[team]
        del self.piece_attributes[team]

        self.phase_bars[team].destroy()
        del self.phase_bars[team]
        del self.turn_submitted[team]

        self.teams.remove(team)

        self.get_manager(Manager.PIECE).destroy_all_pieces_for_team(team)
        self.get_manager(Manager.PLAYER).handle_team_defeated(team)

        publish_game_event(EventType.E_TEAM_DEFEATED, {'team': team})

        self.check_for_remaining_teams()
Beispiel #27
0
    def swap_team(self, team):
        if team in self.ai_teams:
            ai = self.ais.pop(team)
            ai.destroy()
            self.cursors[team] = self.create_cursor(team)

            self.ai_teams.remove(team)
            self.human_teams.append(team)
        elif team in self.human_teams:
            self.ais[team] = AIPlayer(team)
            cursor = self.cursors.pop(team)
            cursor.destroy()

            self.ai_teams.append(team)
            self.human_teams.remove(team)

            # Prompt the new AI to plan its turn
            publish_game_event(EventType.AI_REPLAN_TURN, {})
Beispiel #28
0
    def place_piece(self, piece_type):
        piece = self.get_manager(Manager.PIECE).get_piece_at(
            self.gx, self.gy, self.team)
        if piece:
            # Delete existing pieces first
            self.remove_piece(piece)

        if piece_type in ALL_UNITS:
            self.play_sound(SoundType.UNIT_CREATED)
        else:
            self.play_sound(SoundType.BUILDING_BUILT)

        publish_game_event(
            EventType.E_PIECE_BUILT, {
                'tx': self.gx,
                'ty': self.gy,
                'team': self.team,
                'new_piece_type': piece_type,
            })
Beispiel #29
0
    def check_for_remaining_teams(self, event=None):
        if len(self.teams) <= 1:
            winning_team = self.get_teams()[0]

            results = {
                'winning_team':
                winning_team,
                'all_teams':
                self.get_all_teams(),
                'team_stats':
                self.get_manager(Manager.STAT).get_results(),
                'winning_pieces':
                self.get_manager(
                    Manager.PIECE).get_all_pieces_for_team(winning_team),
                'turn':
                self.get_manager(Manager.TURN).turn,
            }

            publish_game_event(EventType.E_BATTLE_OVER, {'results': results})
Beispiel #30
0
    def damage_hp(self, damage, source=None):
        self.hp -= damage

        # Add any additional effects or debuffs from the source
        if source and isinstance(source, Piece):
            self.last_attacker = source

            aoe_on_death_gained = source.attr(Attribute.AOE_ON_KILL)
            if aoe_on_death_gained > 0:
                self.temporary_aoe_on_death = aoe_on_death_gained

            money_lost_on_death_gained = source.attr(Attribute.STEAL)
            if money_lost_on_death_gained > 0:
                self.temporary_money_lost_on_death = money_lost_on_death_gained

        publish_game_event(EventType.E_PIECE_DAMAGED, {
            'piece': self,
            'damage': damage,
            'source': source,
        })