diff --git a/game/models.py b/game/models.py index 428351f..4b5175f 100644 --- a/game/models.py +++ b/game/models.py @@ -168,7 +168,7 @@ class HeroInDeck(models.Model): verbose_name = "Hero in deck" verbose_name_plural = "Heroes in decks" ordering = ["y", "x"] - unique_together = ["deck", "x", "y"] + unique_together = ["hero", "x", "y"] class PlayerAuthSession(models.Model): diff --git a/room/consumers.py b/room/consumers.py index 7728faa..8455b62 100644 --- a/room/consumers.py +++ b/room/consumers.py @@ -234,6 +234,10 @@ class RoomConsumer(BaseConsumer): # Join room group await self.channel_layer.group_add(self.room_group_name, self.channel_name) + # load and send board + await self.load_board() + await self.send_board() + @sync_to_async def get_state(self): state = self.scope["player_in_room"].get_state() @@ -250,7 +254,7 @@ class RoomConsumer(BaseConsumer): if not room: return False - self.scope["room"] = room + self.scope["room"] = room.first() # check if player can be in a room p_ids = [x.player.id for x in room.first().players.all()] @@ -264,6 +268,7 @@ class RoomConsumer(BaseConsumer): self.scope["first"] = player.first self.scope["score"] = player.score self.scope["deck"] = player.deck.id + self.scope["state"] = room.first().states.last().round p_ids.remove(player.player.id) opponent = PlayerInRoom.objects.get(player_id=p_ids[0]) @@ -332,14 +337,15 @@ class RoomConsumer(BaseConsumer): return False async def perform_move(self, data): - await move_handler( + if await move_handler( data["px"], data["py"], data["x"], data["y"], self.room_name, self.scope["player_in_room"], - ) + ): + await self.send_board() if self.scope["opponent_channel"] and self.scope["opponent_online"]: await self.channel_layer.send( self.scope["opponent_channel"], @@ -354,6 +360,33 @@ class RoomConsumer(BaseConsumer): return True return False + @sync_to_async + def load_board(self): + # loads bord from db to scope + room = self.scope["room"] + board = [ + [None, None, None, None, None, None, None, None], + [None, None, None, None, None, None, None, None], + [None, None, None, None, None, None, None, None], + [None, None, None, None, None, None, None, None], + [None, None, None, None, None, None, None, None], + [None, None, None, None, None, None, None, None], + [None, None, None, None, None, None, None, None], + [None, None, None, None, None, None, None, None], + ] + for el in room.heroes.all(): + board[el.y - 1][el.x - 1] = [el.hero.type, el.health] + + self.scope["board"] = board + + async def send_board(self): + # sends board to client + await self.send_message( + "INFO", + message=f"game's board for round {self.scope['state']}", + board=self.scope["board"], + ) + # info type group message handler async def info(self, event): message = event["message"] diff --git a/room/models.py b/room/models.py index fcdb2c1..5e64bec 100644 --- a/room/models.py +++ b/room/models.py @@ -42,7 +42,7 @@ class PlayerInRoom(models.Model): class GameState(models.Model): - room = models.ForeignKey(Room, on_delete=models.CASCADE) + room = models.ForeignKey(Room, related_name="states", on_delete=models.CASCADE) player = models.ForeignKey(Player, on_delete=models.CASCADE) round = models.IntegerField(blank=False) message = models.CharField(max_length=100, blank=False) @@ -54,7 +54,7 @@ class GameState(models.Model): class HeroInGame(models.Model): hero = models.ForeignKey(Hero, on_delete=models.CASCADE) player = models.ForeignKey(PlayerInRoom, on_delete=models.CASCADE) - room = models.ForeignKey(Room, on_delete=models.CASCADE) + room = models.ForeignKey(Room, related_name="heroes", on_delete=models.CASCADE) # state on board x = models.IntegerField( @@ -78,4 +78,4 @@ class HeroInGame(models.Model): super().save(force_insert, force_update, using, update_fields) class Meta: - unique_together = ["x", "y", "room"] + unique_together = ["x", "y", "hero"] diff --git a/room/services/game_logic.py b/room/services/game_logic.py index 96a5df1..ad8a776 100644 --- a/room/services/game_logic.py +++ b/room/services/game_logic.py @@ -101,4 +101,10 @@ def move_handler( h_t = hero.hero.type + if _validate_hero_movement(h_t, prev_x, prev_y, x, y, room, first=player.first): + hero.x = x + hero.y = y + hero.save(update_fields=["x", "y"]) + return True + _print_board(room) # TODO: Remove in production