diff --git a/overcooked_simulator/counters.py b/overcooked_simulator/counters.py index 3d930aa54e15a4c6ad9f187b3766eee34f96cc07..40779e5cb228c993a65b5264f684225ea1ff78bc 100644 --- a/overcooked_simulator/counters.py +++ b/overcooked_simulator/counters.py @@ -623,7 +623,7 @@ class Trashcan(Counter): return None def can_drop_off(self, item: Item) -> bool: - return True + return item.name != "Extinguisher" class CookingCounter(Counter): diff --git a/overcooked_simulator/game_content/environment_config.yaml b/overcooked_simulator/game_content/environment_config.yaml index fdbe1db23264984fa1521d2641c1b49dc2915b41..96b6660b50523f0caa5481c18d9edefebd317da3 100644 --- a/overcooked_simulator/game_content/environment_config.yaml +++ b/overcooked_simulator/game_content/environment_config.yaml @@ -88,7 +88,8 @@ player_config: player_speed_units_per_seconds: 6 interaction_range: 1.6 restricted_view: False - view_angle: 95 + view_angle: 60 + view_range: 3 # in grid units, can be "null" effect_manager: FireManager: diff --git a/overcooked_simulator/gui_2d_vis/drawing.py b/overcooked_simulator/gui_2d_vis/drawing.py index d9e5e8e22b0c3ad16df665e496c759178cd26262..64f05f4513139b1c405ccf23afa04bc82342b5eb 100644 --- a/overcooked_simulator/gui_2d_vis/drawing.py +++ b/overcooked_simulator/gui_2d_vis/drawing.py @@ -153,20 +153,23 @@ class Visualizer: direction = pygame.math.Vector2(state["view_restriction"]["direction"]) pos = pygame.math.Vector2(state["view_restriction"]["position"]) angle = state["view_restriction"]["angle"] / 2 + range = state["view_restriction"]["range"] pos = pos * grid_size + pygame.math.Vector2([grid_size / 2, grid_size / 2]) rect_scale = max(width, height) + # rect_scale = 2 * grid_size left_beam = pos + (direction.rotate(angle) * rect_scale * 2) right_beam = pos + (direction.rotate(-angle) * rect_scale * 2) + offset_front = direction * grid_size * 0.2 pygame.draw.polygon( screen, colors["black"], ( - pos - (direction * grid_size * 0.6), - left_beam - (direction * grid_size * 0.6), + pos - offset_front, + left_beam - offset_front, left_beam + (direction.rotate(90) * rect_scale), pos - (direction * rect_scale * 2) @@ -175,9 +178,28 @@ class Visualizer: - (direction * rect_scale * 2) + (direction.rotate(-90) * rect_scale), right_beam + (direction.rotate(-90) * rect_scale), - right_beam - (direction * grid_size * 0.6), + right_beam - offset_front, ), ) + if range: + pygame.draw.polygon( + screen, + colors["black"], + ( + pos + + (direction.rotate(90) * rect_scale) + + (direction * range * grid_size), + pos + + (direction.rotate(-90) * rect_scale) + + (direction * range * grid_size), + pos + + (direction.rotate(-90) * rect_scale) + + (direction * rect_scale), + pos + + (direction.rotate(90) * rect_scale) + + (direction * rect_scale), + ), + ) def draw_background( self, surface: pygame.Surface, width: int, height: int, grid_size: int diff --git a/overcooked_simulator/overcooked_environment.py b/overcooked_simulator/overcooked_environment.py index 5302f55a72d1270649efbac5324a94db791c9f6a..624121caeef30e0426c1546b290a08ae86eba162 100644 --- a/overcooked_simulator/overcooked_environment.py +++ b/overcooked_simulator/overcooked_environment.py @@ -167,6 +167,9 @@ class Environment: self.player_view_angle = self.environment_config["player_config"][ "view_angle" ] + self.player_view_range = self.environment_config["player_config"][ + "view_range" + ] self.extra_setup_functions() @@ -236,8 +239,6 @@ class Environment: ) = self.parse_layout_file() self.hook(LAYOUT_FILE_PARSED) - self.counter_positions = np.array([c.pos for c in self.counters]) - self.world_borders = np.array( [[-0.5, self.kitchen_width - 0.5], [-0.5, self.kitchen_height - 0.5]], dtype=float, @@ -247,6 +248,9 @@ class Environment: "player_speed_units_per_seconds" ] self.player_radius = self.environment_config["player_config"]["radius"] + self.player_interaction_range = self.environment_config["player_config"][ + "interaction_range" + ] progress_counter_classes = list( filter( @@ -266,6 +270,8 @@ class Environment: ) """Counters that needs to be called in the step function via the `progress` method.""" + self.counter_positions = np.array([c.pos for c in self.counters]) + self.order_and_score.create_init_orders(self.env_time) self.start_time = self.env_time """The relative env time when it started.""" @@ -287,6 +293,27 @@ class Environment: env_start_time_worldtime=datetime.now(), ) + def overwrite_counters(self, counters): + self.counters = counters + self.counter_positions = np.array([c.pos for c in self.counters]) + + progress_counter_classes = list( + filter( + lambda cl: hasattr(cl, "progress"), + dict( + inspect.getmembers( + sys.modules["overcooked_simulator.counters"], inspect.isclass + ) + ).values(), + ) + ) + self.progressing_counters = list( + filter( + lambda c: c.__class__ in progress_counter_classes, + self.counters, + ) + ) + @property def game_ended(self) -> bool: """Whether the game is over or not based on the calculated `Environment.env_time_end`""" @@ -663,8 +690,20 @@ class Environment: for idx, p in enumerate(self.players.values()): if not (new_positions[idx] == player_positions[idx]).all(): - p.turn(player_movement_vectors[idx]) - p.move_abs(new_positions[idx]) + p.pos = new_positions[idx] + p.perform_interact_stop() + + p.turn(player_movement_vectors[idx]) + + facing_distances = np.linalg.norm( + p.facing_point - self.counter_positions, axis=1 + ) + closest_counter = self.counters[facing_distances.argmin()] + p.current_nearest_counter = ( + closest_counter + if facing_distances.min() <= self.player_interaction_range + else None + ) def add_player(self, player_name: str, pos: npt.NDArray = None): """Add a player to the environment. @@ -780,6 +819,7 @@ class Environment: "position": self.players[player_id].pos.tolist(), "angle": self.player_view_angle, "counter_mask": None, + "range": self.player_view_range, } if self.player_view_restricted else None, diff --git a/overcooked_simulator/player.py b/overcooked_simulator/player.py index c367561e98862425ecc1590087ef7deb982e608e..638bc4cd5c0d537aa5823af96543a008b43c3300 100644 --- a/overcooked_simulator/player.py +++ b/overcooked_simulator/player.py @@ -37,6 +37,9 @@ class PlayerConfig: """Whether or not the player can see the entire map at once or just a view frustrum.""" view_angle: int | None = None """Angle of the players view if restricted.""" + view_range: float | None = None + """Range of the players view if restricted. In grid units.""" + class Player: """Class representing a player in the game environment. A player consists of a name, their position and what @@ -88,19 +91,7 @@ class Player: function of the environment""" self.current_movement = move_vector self.movement_until = move_until - - def move(self, movement: npt.NDArray[float]): - """Moves the player position by the given movement vector. - A unit direction vector multiplied by move_dist is added to the player position. - - Args: - movement: 2D-Vector of length 1 - """ - if self.interacting and np.any(movement): - self.perform_interact_stop() - self.pos += movement - if np.linalg.norm(movement) != 0: - self.turn(movement) + self.perform_interact_stop() def move_abs(self, new_pos: npt.NDArray[float]): """Overwrites the player location by the new_pos 2d-vector. Absolute movement. @@ -165,7 +156,7 @@ class Player: self.holding.combine(returned_by_counter) log.debug( - f"Self: {self.holding}, {counter.__class__.__name__}: {counter.occupied_by}" + f"Self: {self.holding.__class__.__name__}: {self.holding}, {counter.__class__.__name__}: {counter.occupied_by}" ) # if isinstance(self.holding, Plate): # log.debug(self.holding.clean) diff --git a/overcooked_simulator/state_representation.py b/overcooked_simulator/state_representation.py index 9d4e7427f092fb77769873dd570988e1e3c94f4d..2faa1a1932035342e57b27df9865d673efdcc8cb 100644 --- a/overcooked_simulator/state_representation.py +++ b/overcooked_simulator/state_representation.py @@ -71,6 +71,7 @@ class ViewRestriction(BaseModel): position: list[float] angle: int # degrees counter_mask: None | list[bool] + range: float | None class StateRepresentation(BaseModel): diff --git a/tests/test_start.py b/tests/test_start.py index 8efe8da9ecf1c67974f88a18b1bcdb0b1cd3786a..8531f9d81dc52cb4327c98e641406ad2d45bdec2 100644 --- a/tests/test_start.py +++ b/tests/test_start.py @@ -124,7 +124,7 @@ def test_player_reach(env_config, layout_empty_config, item_info): counter_pos = np.array([2, 2]) counter = Counter(pos=counter_pos, hook=Hooks(env)) - env.counters = [counter] + env.overwrite_counters([counter]) env.add_player("1", np.array([2, 4])) env.player_movement_speed = 1 player = env.players["1"] @@ -144,7 +144,7 @@ def test_pickup(env_config, layout_config, item_info): counter_pos = np.array([2, 2]) counter = Counter(pos=counter_pos, hook=Hooks(env)) counter.occupied_by = Item(name="Tomato", item_info=None) - env.counters = [counter] + env.overwrite_counters([counter]) env.add_player("1", np.array([2, 3])) player = env.players["1"]