feat: Mayor and taking items from room

This commit is contained in:
2024-12-31 14:22:10 +01:00
parent 910808eb6e
commit c47df0d609
20 changed files with 270 additions and 38 deletions

View File

@ -1,5 +1,6 @@
package cz.jzitnik.chronos.controllers;
import cz.jzitnik.chronos.entities.Item;
import cz.jzitnik.chronos.entities.Message;
import cz.jzitnik.chronos.entities.MessageType;
import cz.jzitnik.chronos.entities.Room;
@ -8,11 +9,14 @@ import cz.jzitnik.chronos.payload.responses.UnifiedResponse;
import cz.jzitnik.chronos.repository.PlayerRepository;
import cz.jzitnik.chronos.repository.RoomRepository;
import cz.jzitnik.chronos.services.GameService;
import cz.jzitnik.chronos.services.ItemService;
import cz.jzitnik.chronos.utils.anotations.CheckUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@CrossOrigin(origins = "*", maxAge = 3600)
@ -28,9 +32,12 @@ public class RoomController {
@Autowired
private GameService gameService;
@Autowired
private ItemService itemService;
@GetMapping
@CheckUser
public ResponseEntity<UnifiedResponse<List<Room>, Error>> getAllRooms(@RequestParam("playerKey") String playerKey) {
public ResponseEntity<UnifiedResponse<List<Room>, Error>> getAllRooms(@RequestParam String playerKey) {
var player = playerRepository.findByPlayerKey(playerKey).get();
return ResponseEntity.ok(
@ -40,7 +47,7 @@ public class RoomController {
@GetMapping("/room")
@CheckUser
public ResponseEntity<UnifiedResponse<Room, Error>> getRoom(@RequestParam("playerKey") String playerKey, @RequestParam("roomId") Long roomId) {
public ResponseEntity<UnifiedResponse<Room, Error>> getRoom(@RequestParam String playerKey, @RequestParam Long roomId) {
var player = playerRepository.findByPlayerKey(playerKey).get();
var roomOptional = roomRepository.findById(roomId);
@ -64,7 +71,7 @@ public class RoomController {
@GetMapping("/current_room")
@CheckUser
public ResponseEntity<UnifiedResponse<Room, Error>> getCurrentRoom(@RequestParam("playerKey") String playerKey) {
public ResponseEntity<UnifiedResponse<Room, Error>> getCurrentRoom(@RequestParam String playerKey) {
var player = playerRepository.findByPlayerKey(playerKey).get();
return ResponseEntity.ok(
@ -74,7 +81,7 @@ public class RoomController {
@PostMapping("/move")
@CheckUser
public ResponseEntity<UnifiedResponse<Object, Error>> moveToRoom(@RequestParam("playerKey") String playerKey, @RequestParam("roomId") Long roomId) {
public ResponseEntity<UnifiedResponse<Object, Error>> moveToRoom(@RequestParam String playerKey, @RequestParam Long roomId) {
var player = playerRepository.findByPlayerKey(playerKey).get();
var roomOptional = roomRepository.findById(roomId);
@ -83,21 +90,50 @@ public class RoomController {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(UnifiedResponse.failure(null));
}
var fromThisGame = gameService.isFromThisGame(player.getGame(), roomOptional.get());
var room = roomOptional.get();
var fromThisGame = gameService.isFromThisGame(player.getGame(), room);
if (!fromThisGame) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(UnifiedResponse.failure(new Error("Invalid roomId")));
}
player.setCurrentRoom(roomOptional.get());
player.setCurrentRoom(room);
// Send message to chat
var message = new Message(player, String.valueOf(roomId), MessageType.MOVE_TO_ROOM);
player.getMessages().add(message);
playerRepository.save(player);
return ResponseEntity.ok(UnifiedResponse.success(null));
}
@PostMapping("/take_items")
@CheckUser
public ResponseEntity<UnifiedResponse<List<Item>, Error>> takeItems(@RequestParam String playerKey) {
var player = playerRepository.findByPlayerKey(playerKey).get();
var room = player.getCurrentRoom();
if (room.getItems().isEmpty()) {
return ResponseEntity.status(HttpStatus.NO_CONTENT).body(UnifiedResponse.failure(new Error("No items in this room!")));
}
var items = room.getItems();
var availableSlots = player.getInventorySize() - player.getInventory().size();
System.out.println(availableSlots);
var playerGotItems = new ArrayList<Item>();
for (var i = 0; i <= Math.min(items.size(), availableSlots) - 1; i++) {
var item = items.get(i);
item.setRoom(null);
item.setOwner(player);
itemService.addItem(player, item);
playerGotItems.add(item);
}
return ResponseEntity.ok(UnifiedResponse.success(playerGotItems));
}
}

View File

@ -39,4 +39,9 @@ public class Item {
this.itemType = itemType;
this.owner = owner;
}
public Item(ItemType itemType, Room room) {
this.itemType = itemType;
this.room = room;
}
}

View File

@ -4,7 +4,8 @@ import cz.jzitnik.chronos.payload.errors.ItemNotUsableException;
public enum ItemType {
KEY_FRAGMENT,
LUCK_POTION;
LUCK_POTION,
GOLDEN_WATCH;
public void useItem(Player player) throws ItemNotUsableException {
switch (this) {

View File

@ -9,6 +9,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
@ -66,4 +67,18 @@ public class Player {
public void addItem(Item item) {
inventory.add(item);
}
@JsonIgnore
public int getInventorySize() {
try {
Field field = this.getClass().getDeclaredField("inventory");
if (field.isAnnotationPresent(Size.class)) {
Size size = field.getAnnotation(Size.class);
return size.max();
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return Integer.MAX_VALUE;
}
}

View File

@ -5,4 +5,5 @@ public enum Interaction {
Cashier,
Librarian,
Innkeeper,
Mayor
}

View File

@ -3,6 +3,7 @@ package cz.jzitnik.chronos.interactions;
import cz.jzitnik.chronos.entities.Player;
import cz.jzitnik.chronos.entities.Character;
import cz.jzitnik.chronos.interactions.list.Hangman;
import cz.jzitnik.chronos.interactions.list.Mayor;
import cz.jzitnik.chronos.interactions.list.RockPaperScissors;
import cz.jzitnik.chronos.interactions.list.TicTacToe;
import cz.jzitnik.chronos.interactions.list.wordle.Wordle;
@ -20,6 +21,8 @@ public class InteractionService {
private Wordle wordle;
@Autowired
private TicTacToe ticTacToe;
@Autowired
private Mayor mayor;
@FunctionalInterface
public interface Function3<T, U, V, W> {
@ -32,6 +35,7 @@ public class InteractionService {
case Cashier -> hangman::play;
case Librarian -> wordle::play;
case Innkeeper -> ticTacToe::play;
case Mayor -> mayor::play;
};
}
}

View File

@ -0,0 +1,46 @@
package cz.jzitnik.chronos.interactions.list;
import cz.jzitnik.chronos.entities.Character;
import cz.jzitnik.chronos.entities.Item;
import cz.jzitnik.chronos.entities.ItemType;
import cz.jzitnik.chronos.entities.Player;
import cz.jzitnik.chronos.interactions.InteractionPlayer;
import cz.jzitnik.chronos.payload.responses.InteractionResponse;
import cz.jzitnik.chronos.repository.CharacterRepository;
import cz.jzitnik.chronos.services.ItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@Service
public class Mayor implements InteractionPlayer {
@Autowired
private ItemService itemService;
@Autowired
private CharacterRepository characterRepository;
@Override
public InteractionResponse play(Player player, Character character, String data) {
var playerItems = player.getInventory();
var golderWatches = playerItems.stream().filter(item -> item.getItemType().equals(ItemType.GOLDEN_WATCH)).toList();
if (golderWatches.isEmpty()) {
return new InteractionResponse(false, "Golden watch is not present in your inventory!", new ArrayList<>());
}
var golderWatch = golderWatches.getFirst();
playerItems.remove(golderWatch);
var item = new Item(ItemType.KEY_FRAGMENT, player);
itemService.addItem(player, item); // itemRepository.save is ran by this function so we don't need to save the player when we removed the item from his inv
character.setInteractedWith(true);
characterRepository.save(character);
var items = new ArrayList<Item>();
items.add(item);
return new InteractionResponse(false, "Díky moc za mé ztracené zlaté hodinky... Doplnit dialog!!!", items);
}
}

View File

@ -14,7 +14,7 @@ public class InitGameService {
// Outside
var outside = new Room(
"Outside", // Name
"Outside", // Náměstí
game
);
var outside_characters = new ArrayList<Character>();
@ -109,12 +109,42 @@ public class InitGameService {
inn_characters.add(innkeeper);
inn.setCharacters(inn_characters);
// Dům starosty
var mayor_house = new Room(
"Dům starosty",
game
);
var mayor_house_characters = new ArrayList<Character>();
var mayor = new Character(
"Starosta",
mayor_house,
"Ahoj já jsem starosta. Dej mi moje ztracené zlaté hodinky a dám ti fragment klíče."
);
mayor.setInteraction(Interaction.Mayor);
mayor.setInteractionData(new cz.jzitnik.chronos.entities.Interaction(
"",
"Zlaté hodinky už mám. Děkuji za nalezení.",
mayor
));
mayor_house_characters.add(mayor);
mayor_house.setCharacters(mayor_house_characters);
// Zarostlá zahrada
var garden = new Room(
"Zarostlá zahrada",
game
);
// Zlaté hodinky pro starostu
garden.getItems().add(new Item(ItemType.GOLDEN_WATCH, garden));
rooms.add(outside);
rooms.add(stodola);
rooms.add(shop);
rooms.add(library);
rooms.add(inn);
rooms.add(mayor_house);
rooms.add(garden);
game.setRooms(rooms);