示例#1
0
    def main(self):
        self.set_config(os.path.join(os.path.dirname(os.path.realpath(__file__)), "SuperchargedBots.cfg"))

        self.teams = []

        if self.get_bool_from_config("Options", "help_blue_team"):
            self.teams.append(0)
        print(f"SuperchargedBots: help_blue_team = {0 in self.teams}")

        if self.get_bool_from_config("Options", "help_orange_team"):
            self.teams.append(1)
        print(f"SuperchargedBots: help_orange_team = {1 in self.teams}")

        self.bots_only = self.get_bool_from_config("Options", "bots_only")
        print(f"SuperchargedBots: bots_only = {self.bots_only}")

        self.bonus_boost_accel_percent = self.get_float_from_config("Options", "bonus_boost_accel_percent") / 100
        print(f"SuperchargedBots: bonus_boost_accel_percent = {self.bonus_boost_accel_percent * 100}%")

        self.bonus_boost_tank = self.get_int_from_config("Options", "bonus_boost_tank")
        print(f"SuperchargedBots: bonus_boost_tank = {self.bonus_boost_tank}")

        self.minimum_boost = self.get_int_from_config("Options", "minimum_boost")
        print(f"SuperchargedBots: minimum_boost = {self.minimum_boost}")

        self.bonus_hit_percent = self.get_int_from_config("Options", "bonus_hit_percent")
        print(f"SuperchargedBots: bonus_hit_percent = {self.bonus_hit_percent}")

        self.demo_helper = self.get_bool_from_config("Options", "demo_helper")
        print(f"SuperchargedBots: demo_helper = {self.demo_helper}")

        self.socket_relay = SocketRelay()
        self.socket_relay.player_input_change_handlers.append(self.input_change)

        self.non_blocking_socket_relay = Thread(target=self.socket_relay.connect_and_run, args=(False, True, False))
        self.non_blocking_socket_relay.start()

        while 1:
            try:
                self.packet: GameTickPacket = self.wait_game_tick_packet()
                
                time = self.packet.game_info.seconds_elapsed
                self.delta_time = time - self.time
                self.time = time

                supercharged_bots = []
                cars = dict()

                for car_index in range(self.packet.num_cars):
                    car = self.packet.game_cars[car_index]

                    if (self.bots_only and not car.is_bot) or car.team not in self.teams:
                        continue

                    if car.name not in self.tracker:
                        self.tracker[car.name] = DEFAULT_CAR.copy()

                    supercharged_bots.append(car.name)

                    if not self.packet.game_info.is_round_active:
                        continue

                    if self.packet.game_info.is_kickoff_pause:
                        self.tracker[car.name]['total_boost'] = BOOST_CONSUMPTION
                        self.tracker[car.name]['last_boost'] = BOOST_CONSUMPTION
                        continue

                    velocity = None

                    if self.demo_helper:
                        for other_car_index in range(self.packet.num_cars):
                            other_car = self.packet.game_cars[other_car_index]

                            if car.team == other_car.team:
                                continue

                            car_location = Vector.from_vector(car.physics.location)
                            other_car_location = Vector.from_vector(other_car.physics.location)

                            if car_location.flat_dist(other_car_location) < 200 and abs(Vector.from_vector(car.physics.velocity).angle(other_car_location - car_location)) < 0.5:
                                velocity = Vector.from_vector(car.physics.velocity).flatten().scale(2300)

                    if self.tracker[car.name]['boosting']:
                        if not self.tracker[car.name]['steering'] and (car.boost > self.minimum_boost):
                            CP = math.cos(car.physics.rotation.pitch)
                            SP = math.sin(car.physics.rotation.pitch)
                            CY = math.cos(car.physics.rotation.yaw)
                            SY = math.sin(car.physics.rotation.yaw)
                            forward = Vector(CP*CY, CP*SY, SP)
                            if velocity is None:
                                velocity = Vector.from_vector(car.physics.velocity) + forward * (BOOST_ACCEL * self.delta_time * self.bonus_boost_accel_percent)

                        self.tracker[car.name]['total_boost'] -= BOOST_CONSUMPTION * self.delta_time * (100 / self.bonus_boost_tank)

                    boost_amount = None

                    if car.boost > self.minimum_boost and car.boost > self.tracker[car.name]['last_boost']:
                        self.tracker[car.name]['total_boost'] += car.boost - self.tracker[car.name]['last_boost']
                    elif car.boost < self.minimum_boost:
                        self.tracker[car.name]['total_boost'] = self.minimum_boost
                    
                    self.tracker[car.name]['total_boost'] = cap(self.tracker[car.name]['total_boost'], 0, 100)
                    floored_boost = math.floor(self.tracker[car.name]['total_boost'])
                    if floored_boost != car.boost:
                        boost_amount = floored_boost
                    self.tracker[car.name]['last_boost'] = car.boost if boost_amount is None else boost_amount

                    if velocity is None and boost_amount is None:
                        continue

                    cars[car_index] = CarState(
                        Physics(
                            velocity=None if velocity is None else Vector3(*velocity)
                        ),
                        boost_amount=boost_amount
                    )

                last_ball_touch = self.packet.game_ball.latest_touch
                ball = None

                if last_ball_touch.time_seconds > self.last_ball_touch_time:
                    if (last_ball_touch.time_seconds - self.last_ball_touch_time) > 0.5:
                        if not self.bots_only or self.packet.game_cars[last_ball_touch.player_index].is_bot:
                            if last_ball_touch.team in self.teams:
                                bonus_hit_multiplier = self.bonus_hit_percent / 100 + 1
                                ball_velocity = Vector.from_vector(self.packet.game_ball.physics.velocity) * Vector(bonus_hit_multiplier, bonus_hit_multiplier, 1 / bonus_hit_multiplier)
                                ball = BallState(physics=Physics(
                                    velocity=Vector3(*ball_velocity)
                                ))

                    self.last_ball_touch_time = last_ball_touch.time_seconds

                game_state = GameState()

                if cars:
                    game_state.cars = cars

                if ball is not None:
                    game_state.ball = ball    

                self.set_game_state(game_state)

                if self.last_packet_time == -1 or self.time - self.last_packet_time >= 0.1:
                    self.matchcomms.outgoing_broadcast.put_nowait({
                        "supercharged_bots": supercharged_bots,
                        "supercharged_config": {
                            "bonus_boost_accel_percent": self.bonus_boost_accel_percent,
                            "bonus_boost_tank": self.bonus_boost_tank,
                            "minimum_boost": self.minimum_boost,
                            "bonus_hit_percent": self.bonus_hit_percent,
                            "demo_helper": self.demo_helper,
                        }
                    })
            except Exception:
                print_exc()
示例#2
0
def manage_game_state(challenge: dict, upgrades: dict,
                      setup_manager: SetupManager) -> Tuple[bool, dict]:
    """
    Continuously track the game and adjust state to respect challenge rules and
    upgrades.
    At the end of the game, calculate results and the challenge completion
    and return that
    """
    early_failure = False, {}

    expected_player_count = challenge["humanTeamSize"] + len(
        challenge["opponentBots"])
    # Wait for everything to be initialized
    packet = wait_till_cars_spawned(setup_manager, expected_player_count)

    if packet.num_cars == 0:
        print("The game was initialized with no cars")
        return early_failure

    tick_rate = 120
    results = None
    max_boost = 0
    if "boost-100" in upgrades:
        max_boost = 100
    elif "boost-33" in upgrades:
        max_boost = 33

    half_field = challenge.get("limitations", []).count("half-field") > 0

    stats_tracker = ManualStatsTracker(challenge)
    last_boost_bump_time = time.monotonic()
    while True:
        try:
            eel.sleep(0)  # yield to allow other gui threads to operate.
            packet = GameTickPacket()
            setup_manager.game_interface.fresh_live_data_packet(
                packet, 1000, WITNESS_ID)

            if packet.num_cars == 0:
                # User seems to have ended the match
                print("User ended the match")
                return early_failure

            stats_tracker.updateStats(packet)
            results = packet_to_game_results(packet)

            if has_user_perma_failed(challenge, stats_tracker.stats):
                time.sleep(1)
                setup_failure_freeplay(setup_manager,
                                       "You failed the challenge!")
                return early_failure

            if end_by_mercy(challenge, stats_tracker.stats, results):
                time.sleep(3)
                setup_failure_freeplay(setup_manager,
                                       "Challenge completed by mercy rule!",
                                       "green")
                return True, results

            human_info = packet.game_cars[0]
            game_state = GameState()
            human_desired_state = CarState()
            game_state.cars = {0: human_desired_state}

            changed = False
            # adjust boost
            if human_info.boost > max_boost and not half_field:
                # Adjust boost, unless in heatseeker mode
                human_desired_state.boost_amount = max_boost
                changed = True

            if "boost-recharge" in upgrades:
                # increase boost at 10% per second
                now = time.monotonic()
                if human_info.boost < max_boost and (now - last_boost_bump_time
                                                     > 0.1):
                    changed = True
                    last_boost_bump_time = now
                    human_desired_state.boost_amount = min(
                        human_info.boost + 1, max_boost)

            if changed:
                setup_manager.game_interface.set_game_state(game_state)

            if packet.game_info.is_match_ended:
                break

        except KeyError:
            traceback.print_exc()
            # it means that the game was interrupted by the user
            print("Looks like the game is in a bad state")
            setup_failure_freeplay(setup_manager, "The game was interrupted.")
            return early_failure

    return calculate_completion(challenge, stats_tracker.stats,
                                results), results