diff --git a/backend/src/main/java/cz/jzitnik/chronos/controllers/CharacterController.java b/backend/src/main/java/cz/jzitnik/chronos/controllers/CharacterController.java index 44f02f2..1b53d42 100644 --- a/backend/src/main/java/cz/jzitnik/chronos/controllers/CharacterController.java +++ b/backend/src/main/java/cz/jzitnik/chronos/controllers/CharacterController.java @@ -83,10 +83,10 @@ public class CharacterController { var characterOptional = characterRepository.findById(interactionRequest.getCharacterId()); if (characterOptional.isEmpty()) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(UnifiedResponse.failure(null)); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(UnifiedResponse.empty(false)); } if (!characterOptional.get().getRoom().equals(player.getCurrentRoom())) { - return ResponseEntity.badRequest().body(UnifiedResponse.failure(null)); + return ResponseEntity.badRequest().body(UnifiedResponse.empty(false)); } if (characterOptional.get().isInteractedWith()) { return ResponseEntity.noContent().build(); @@ -133,4 +133,4 @@ public class CharacterController { return ResponseEntity.ok(UnifiedResponse.success(TakeItemsResponse.DONE)); } -} \ No newline at end of file +} diff --git a/backend/src/main/java/cz/jzitnik/chronos/controllers/PlayerController.java b/backend/src/main/java/cz/jzitnik/chronos/controllers/PlayerController.java index c4a5515..974af19 100644 --- a/backend/src/main/java/cz/jzitnik/chronos/controllers/PlayerController.java +++ b/backend/src/main/java/cz/jzitnik/chronos/controllers/PlayerController.java @@ -176,4 +176,27 @@ public class PlayerController { throw new RuntimeException(e); } } + + @PostMapping("/drop_item") + @CheckUser + public ResponseEntity> dropItem(@RequestParam String playerKey, @RequestParam Long itemId) { + var player = playerRepository.findByPlayerKey(playerKey).get(); + + var itemOptional = itemRepository.findById(itemId); + if (itemOptional.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(UnifiedResponse.failure(new NotFoundError("Item with id " + itemId + " was not found!"))); + } + var item = itemOptional.get(); + if (!item.getOwner().getId().equals(player.getId())) { + return ResponseEntity.status(HttpStatus.FORBIDDEN).body(UnifiedResponse.failure(new Error("You do not own this item!"))); + } + + var room = player.getCurrentRoom(); + item.setOwner(null); + item.setRoom(room); + + itemRepository.save(item); + + return ResponseEntity.ok(UnifiedResponse.empty(true)); + } } diff --git a/backend/src/main/java/cz/jzitnik/chronos/payload/responses/UnifiedResponse.java b/backend/src/main/java/cz/jzitnik/chronos/payload/responses/UnifiedResponse.java index 60e077c..7e93f71 100644 --- a/backend/src/main/java/cz/jzitnik/chronos/payload/responses/UnifiedResponse.java +++ b/backend/src/main/java/cz/jzitnik/chronos/payload/responses/UnifiedResponse.java @@ -29,7 +29,7 @@ public class UnifiedResponse { } // Static factory method for empty response - public static UnifiedResponse empty() { - return new UnifiedResponse<>(Optional.empty(), Optional.empty(), false); + public static UnifiedResponse empty(boolean success) { + return new UnifiedResponse<>(Optional.empty(), Optional.empty(), success); } } diff --git a/frontend/src/main/java/cz/jzitnik/api/ApiService.java b/frontend/src/main/java/cz/jzitnik/api/ApiService.java index cb96c6a..46cb407 100644 --- a/frontend/src/main/java/cz/jzitnik/api/ApiService.java +++ b/frontend/src/main/java/cz/jzitnik/api/ApiService.java @@ -150,4 +150,10 @@ public interface ApiService { @Query("itemId") Long itemId, @Query("playerId") Long playerId ); + + @POST("game/players/drop_item") + Call> dropItem( + @Query("playerKey") String playerKey, + @Query("itemId") Long itemId + ); } diff --git a/frontend/src/main/java/cz/jzitnik/game/CommandPalette.java b/frontend/src/main/java/cz/jzitnik/game/CommandPalette.java index 22db564..476a3b0 100644 --- a/frontend/src/main/java/cz/jzitnik/game/CommandPalette.java +++ b/frontend/src/main/java/cz/jzitnik/game/CommandPalette.java @@ -1,6 +1,7 @@ package cz.jzitnik.game; import cz.jzitnik.api.ApiService; +import cz.jzitnik.api.types.Item; import cz.jzitnik.utils.Cli; import cz.jzitnik.utils.ConfigPathProvider; import lombok.AllArgsConstructor; @@ -23,6 +24,7 @@ public class CommandPalette { CHAT_OPEN, CHAT_SEND, PLAYER_LIST_OPEN, + DROP_ITEM, CHECK_WINNABLE, EXIT, } @@ -84,6 +86,7 @@ public class CommandPalette { allCommands.add(new Command("Otevřít chat", CommandType.CHAT_OPEN)); allCommands.add(new Command("Odeslat zprávu do chatu", CommandType.CHAT_SEND)); allCommands.add(new Command("Zobrazit list všech hráčů", CommandType.PLAYER_LIST_OPEN)); + allCommands.add(new Command("Vyhodit item z inventáře", CommandType.DROP_ITEM)); allCommands.add(new Command("Zkontrolovat vyhratelnost hry", CommandType.CHECK_WINNABLE)); allCommands.add(new Command("Odejít ze hry", CommandType.EXIT)); @@ -157,6 +160,32 @@ public class CommandPalette { var playerList = new PlayerList(apiService, playerKey); playerList.display(); + yield displayIndex(); + } + case DROP_ITEM -> { + var response = apiService.getMe(playerKey).execute(); + var me = response.body().getData().get(); + var inventory = me.getInventory(); + + if (inventory.isEmpty()) { + Cli.error("Máš prázdný inventář!"); + + yield displayIndex(); + } + + var options = inventory.stream().map(Item::toString).toList(); + var selectedOptionIndex = Cli.selectOptionIndex(options); + + var selectedItem = inventory.get(selectedOptionIndex); + + var response2 = apiService.dropItem(playerKey, selectedItem.getId()).execute(); + + if (response2.code() != 200) { + Cli.error("Nastala chyba při vyhazování itemu!"); + } else { + Cli.success("Item byl vyhozen!"); + } + yield displayIndex(); } };