def run_state_setting(my_queue: Queue):
    """Controls state setting for tests."""
    message = my_queue.get()
    if message != Message.READY:
        raise Exception(f"Got {message} instead of READY")

    logger = get_logger("UTSS")  # Unit Test State Setting
    game_interface = GameInterface(logger)
    game_interface.load_interface()
    game_interface.wait_until_loaded()
    logger.info("Running!")

    # Get the first GameState.
    game_state, message = my_queue.get()
    game_interface.set_game_state(game_state)

    while True:
        while my_queue.qsize() == 0:
            # Sleep to prevent reset-spamming.
            time.sleep(0.1)

            if not keyboard.is_pressed(RESET_KEY):
                continue

            # Reset the GameState.
            logger.info("Resetting test.")
            game_interface.set_game_state(game_state)

        # Receive GameState.
        logger.info("Setting new test.")
        game_state, message = my_queue.get()
        if message == Message.DONE:
            print('Thread 2 closing.')
            exit()

        game_interface.set_game_state(game_state)
class Observer():
    def __init__(self):
        self.game_interface = GameInterface(get_logger("observer"))
        self.game_interface.load_interface()
        self.game_interface.wait_until_loaded()
        self.game_interface.set_game_state(GameState(console_commands=[f'Set WorldInfo WorldGravityZ {WORLD_GRAVITY}']))
        self.main()

    def main(self):
        # Create packet
        packet = GameTickPacket()
        last_game_time = 0.0

        while True:
            # Update packet
            self.game_interface.update_live_data_packet(packet)
            game_time = packet.game_info.seconds_elapsed

            # Sleep until a new packet is received.
            if last_game_time == game_time:
                time.sleep(0.001)

            else:
                if packet.game_info.is_round_active:

                    # Renders ball prediction.
                    ball_prediction = BallPrediction()
                    self.game_interface.update_ball_prediction(ball_prediction)
                    self.game_interface.renderer.begin_rendering()
                    self.game_interface.renderer.draw_polyline_3d([step.physics.location for step in ball_prediction.slices[::10]], self.game_interface.renderer.cyan())
                    self.game_interface.renderer.end_rendering()

                    car_states = {}

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

                        if STICK != 0 and car.has_wheel_contact:
                            # Makes cars stick by adding a velocity downwards.

                            pitch = car.physics.rotation.pitch
                            yaw = car.physics.rotation.yaw
                            roll = car.physics.rotation.roll

                            CP = cos(pitch) 
                            SP = sin(pitch)
                            CY = cos(yaw)
                            SY = sin(yaw)
                            CR = cos(roll)
                            SR = sin(roll)

                            x = car.physics.velocity.x - STICK*(-CR * CY * SP - SR * SY)
                            y = car.physics.velocity.y - STICK*(-CR * SY * SP + SR * CY)
                            z = car.physics.velocity.z - STICK*(CP * CR)

                            car_states.update({i: CarState(physics=Physics(velocity=Vector3(x,y,z)))})

                    
                    if packet.game_info.is_kickoff_pause and round(packet.game_ball.physics.location.z) != KICKOFF_BALL_HEIGHT:
                        # Places the ball in the air on kickoff.
                        ball_state = BallState(Physics(location=Vector3(z=KICKOFF_BALL_HEIGHT), velocity=Vector3(0,0,0)))

                        if len(car_states) > 0:
                            game_state = GameState(ball=ball_state, cars=car_states)
                        else:
                            game_state = GameState(ball=ball_state)

                    else:
                        if len(car_states) > 0:
                            game_state = GameState(cars=car_states)
                        else:
                            game_state = GameState()

                    # Uses state setting to set the game state.
                    self.game_interface.set_game_state(game_state)
Beispiel #3
0
class Commentator():
    def __init__(self):
        self.game_interface = GameInterface(get_logger("Commentator"))
        self.game_interface.load_interface()
        self.game_interface.wait_until_loaded()
        self.touchTimer = 0
        self.currentTime = 0
        self.firstIter = True
        self.overTime = False
        self.shotDetection = True
        self.ballHistory = []
        self.lastTouches = []
        self.teams = []
        self.joinTimer = 0
        self.q = Queue(maxsize=3)
        self.host = threading.Thread(target=host, args=(self.q,))
        self.host.start()
        self.main()
        self.host.join()

    def reset(self):
        self.touchTimer = 0
        self.currentTime = 0
        self.firstIter = True
        self.overTime = False
        self.shotDetection = True
        self.ballHistory = []
        self.lastTouches = []
        self.teams = []
        self.joinTimer = 0
        with self.q.mutex:
            self.q.queue.clear()

    def speak(self, phrase):
        if not self.q.full():
            self.q.put(Comment(phrase, random.randint(0, 1)))

    def timeCheck(self, newTime):
        if newTime - self.currentTime < -1:
            return True
        self.currentTime = newTime
        return False

    def overtimeCheck(self,packet):
        if not self.overTime:
            if packet.game_info.is_overtime:
                self.overTime = True
                self.speak(f"That's the end of regulation time, we're headed into over time with the score tied at {packet.teams[0].score}!")

    def gameWrapUp(self):
        if self.teams[0].score > self.teams[1].score:
            winner = "Blue"
        else:
            winner = "Orange"

        if abs(self.teams[0].score - self.teams[1].score) >=4:
            self.speak(f"Team {winner} has won today's match with a dominant performance.")
            #impressive victory
        else:
            #normal win message
            self.speak(f"Team {winner} clinched the victory this match")

        self.speak("Thank you all for watching today's game and never forget that Diablo is coming for you. G G everyone.")

    def stopHost(self):
        while self.q.full():
            pass
        self.q.put("exit")

    def handleShotDetection(self):
        if self.shotDetection:
            if len(self.ballHistory) > 0:
                shot,goal = shotDetection(self.ballHistory[-1],1)
                if shot:
                    if not self.q.full():
                        if self.lastTouches[-1].team == goal:
                            self.speak(f"That's a potential own goal from {self.lastTouches[-1].player_name}.")
                        else:
                            self.speak(f"{self.lastTouches[-1].player_name} takes a shot at the enemy net!")
                    self.shotDetection = False




    def updateTouches(self, packet):
        contactNames = ["hit","touch","contact"]

        try:
            touch = ballTouch(packet.game_ball.latest_touch)
        except Exception as e:
            touch = None
            print(e)

        if touch:
            if len(self.lastTouches) < 1 or self.lastTouches[-1] != touch:
                self.lastTouches.append(touch)
                self.shotDetection = True
                for team in self.teams:
                    team.update(touch)
                if self.currentTime - self.touchTimer >=4:
                    if self.q.empty():
                        if len(self.ballHistory) >0:
                            _ballHeading = ballHeading(self.ballHistory[-1])
                            if _ballHeading == 0:
                                if touch.team == 0:
                                    if self.ballHistory[-1].location[1] >= 0:
                                        self.speak(
                                            f"{touch.player_name}'s {contactNames[random.randint(0,2)]} pushes the ball back towards blue")
                                    else:
                                        self.speak(
                                            f"{touch.player_name}'s {contactNames[random.randint(0,2)]} moves the ball towards its own goal.")
                                else:
                                    if touch.team == 1:
                                        if self.ballHistory[-1].location[1] <= 0:
                                            self.speak(
                                                f"{touch.player_name}'s {contactNames[random.randint(0,2)]} puts the ball into a dangerous position for blue.")
                                        else:
                                            self.speak(
                                                f"{touch.player_name}'s {contactNames[random.randint(0,2)]} sends the ball towards blue side.")

                            elif _ballHeading == 1:
                                if touch.team == 0:
                                    if self.ballHistory[-1].location[1] >= 0:
                                        self.speak(
                                            f"{touch.player_name}'s {contactNames[random.randint(0,2)]} puts the ball into a dangerous position for orange.")
                                    else:
                                        self.speak(
                                            f"{touch.player_name}'s {contactNames[random.randint(0,2)]} sends the ball towards orange side.")
                                else:
                                    if touch.team == 1:
                                        if self.ballHistory[-1].location[1] >= 0:
                                            self.speak(
                                                f"{touch.player_name}'s {contactNames[random.randint(0,2)]} moves the ball towards its own goal.")
                                        else:
                                            self.speak(
                                                f"{touch.player_name}'s {contactNames[random.randint(0,2)]} pushes the ball back  towards orange")

                            else:
                                self.speak(f"{touch.player_name}'s {contactNames[random.randint(0,2)]} is neutral.")

                            self.touchTimer = self.currentTime


    def updateGameBall(self,packet):
        if packet.game_info.is_round_active:
            currentBall = ballObject(packet.game_ball)
            self.ballHistory.append(currentBall)
        if len(self.ballHistory) >1000:
            del self.ballHistory[0]

    def gatherMatchData(self, packet):
        members = [[], []]
        for i in range(packet.num_cars):
            _car = Car(packet.game_cars[i].name, packet.game_cars[i].team, i)
            members[_car.team].append(_car)

        self.teams.append(Team(0, members[0]))
        self.teams.append(Team(1, members[1]))
        self.speak(
            f"We have an exciting match in store for you today. On team blue We have {', '.join([x.name for x in self.teams[0].members])} ")
        self.speak(
            f" and facing off against them on orange team we have {', '.join([x.name for x in self.teams[1].members])} .")
        self.speak("Good luck everyone.")

    def scoreAnnouncement(self,teamIndex):
        try:
            scorer = self.teams[teamIndex].lastTouch.player_name
            speed = self.ballHistory[-1].getRealSpeed()
            if not self.q.full():
                if speed <= 20:
                    self.speak(f"{scorer} scores! It barely limped across the goal line at {speed} kilometers per hour, but a goal is a goal.")

                elif speed >= 100:
                    self.speak(f"{scorer} scores on a blazingly fast shot at  {speed} kilometers per hour! What a shot!")

                else:
                    self.speak(f"And {scorer}'s shot goes in at {speed} kilometers per hour!")

            if not self.q.full():
                self.speak(f"That goal brings the score to {self.teams[0].score} blue and {self.teams[1].score} orange.")
        except:
            pass

    def scoreCheck(self, packet):
        if self.teams[0].score != packet.teams[0].score:
            self.teams[0].score = packet.teams[0].score
            self.scoreAnnouncement(0)

        if self.teams[1].score != packet.teams[1].score:
            self.teams[1].score = packet.teams[1].score
            self.scoreAnnouncement(1)

    def main(self):
        while True:
            packet = GameTickPacket()
            self.game_interface.update_live_data_packet(packet)
            gametime = "{:.2f}".format(packet.game_info.seconds_elapsed)

            if packet.game_info.is_match_ended:
                print("Game is over, exiting.")
                self.gameWrapUp()
                self.stopHost()
                break

            if self.firstIter:
                if packet.num_cars >= 1:
                    if self.joinTimer <= 0:
                        self.joinTimer = time.time()
                    if time.time() - self.joinTimer >=1: #arbitrary timer to ensure all cars connected
                        self.firstIter = False
                        self.currentTime = float(gametime)
                        self.gatherMatchData(packet)

            if self.timeCheck(float(gametime)):
                print("framework reset, resetting announcerbot")
                self.reset()
            if not self.firstIter:
                self.updateGameBall(packet)
                self.updateTouches(packet)
                self.handleShotDetection()
                self.scoreCheck(packet)
                self.overtimeCheck(packet)