feat: One step ahead for interactions implementation

This commit is contained in:
jzitnik-dev 2024-12-20 19:00:14 +01:00
parent acb0cf2164
commit 6786eb1be8
Signed by: jzitnik
GPG Key ID: C577A802A6AF4EF3
10 changed files with 202 additions and 11 deletions

View File

@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List;
@CrossOrigin(origins = "*", maxAge = 3600) @CrossOrigin(origins = "*", maxAge = 3600)
@RestController @RestController
@ -24,6 +25,16 @@ public class RoomController {
@Autowired @Autowired
private GameService gameService; private GameService gameService;
@GetMapping
@CheckUser
public ResponseEntity<UnifiedResponse<List<Room>, Error>> getAllRooms(@RequestParam("playerKey") String playerKey) {
var player = playerRepository.findByPlayerKey(playerKey).get();
return ResponseEntity.ok(
UnifiedResponse.success(player.getGame().getRooms())
);
}
@GetMapping("/current_room") @GetMapping("/current_room")
@CheckUser @CheckUser
public ResponseEntity<UnifiedResponse<Room, Error>> getCurrentRoom(@RequestParam("playerKey") String playerKey) { public ResponseEntity<UnifiedResponse<Room, Error>> getCurrentRoom(@RequestParam("playerKey") String playerKey) {

View File

@ -10,8 +10,6 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@RequestMapping("/status") @RequestMapping("/status")
public class StatusController { public class StatusController {
// Don't decode this base64, just go to /status endpoint, you'll be surprised
@GetMapping @GetMapping
public UnifiedResponse<String, Error> getStatus() { public UnifiedResponse<String, Error> getStatus() {
return UnifiedResponse.success("working"); return UnifiedResponse.success("working");

View File

@ -42,6 +42,10 @@ public class Character {
@JsonIgnore @JsonIgnore
private List<Player> playersWhoSaw = new ArrayList<>(); private List<Player> playersWhoSaw = new ArrayList<>();
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "interaction_data_id", referencedColumnName = "id")
private cz.jzitnik.chronos.entities.Interaction interactionData;
private String dialog; private String dialog;
public Character(String name, Room room, String dialog) { public Character(String name, Room room, String dialog) {

View File

@ -0,0 +1,27 @@
package cz.jzitnik.chronos.entities;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Interaction {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "start_text")
private String startText;
@Column(name = "interacted_with_text")
private String interactedWithText;
@OneToOne(mappedBy = "interactionData")
@JsonIgnore
private Character character;
}

View File

@ -12,6 +12,8 @@ import retrofit2.http.GET;
import retrofit2.http.POST; import retrofit2.http.POST;
import retrofit2.http.Query; import retrofit2.http.Query;
import java.util.List;
public interface ApiService { public interface ApiService {
@GET("status") @GET("status")
Call<UnifiedResponse<String, Error>> status(); Call<UnifiedResponse<String, Error>> status();
@ -36,6 +38,11 @@ public interface ApiService {
@Query("gameKey") String gameKey @Query("gameKey") String gameKey
); );
@GET("game/rooms")
Call<UnifiedResponse<List<Room>, Error>> getAllRooms(
@Query("playerKey") String playerKey
);
@GET("game/rooms/current_room") @GET("game/rooms/current_room")
Call<UnifiedResponse<Room, Error>> getCurrentRoom( Call<UnifiedResponse<Room, Error>> getCurrentRoom(
@Query("playerKey") String playerKey @Query("playerKey") String playerKey

View File

@ -21,4 +21,6 @@ public class Character {
private boolean interactedWith; private boolean interactedWith;
private String dialog; private String dialog;
private InteractionData interactionData;
} }

View File

@ -0,0 +1,16 @@
package cz.jzitnik.api.types;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
public class InteractionData {
private Long id;
private String startText;
private String interactedWithText;
}

View File

@ -6,6 +6,7 @@ import cz.jzitnik.api.types.Character;
import cz.jzitnik.api.types.Room; import cz.jzitnik.api.types.Room;
import cz.jzitnik.api.types.TakeItemsResponse; import cz.jzitnik.api.types.TakeItemsResponse;
import cz.jzitnik.api.types.TestGameKeyResponse; import cz.jzitnik.api.types.TestGameKeyResponse;
import cz.jzitnik.game.interactions.Interactions;
import cz.jzitnik.utils.Cli; import cz.jzitnik.utils.Cli;
import cz.jzitnik.utils.ConfigPathProvider; import cz.jzitnik.utils.ConfigPathProvider;
import lombok.Getter; import lombok.Getter;
@ -17,13 +18,13 @@ import java.io.IOException;
import java.net.ConnectException; import java.net.ConnectException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Arrays; import java.util.ArrayList;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import retrofit2.Retrofit; import retrofit2.Retrofit;
import retrofit2.converter.jackson.JacksonConverterFactory; import retrofit2.converter.jackson.JacksonConverterFactory;
import retrofit2.http.GET;
@NoArgsConstructor @NoArgsConstructor
@Getter @Getter
@ -202,17 +203,22 @@ public class Chronos {
public void visit() throws IOException { public void visit() throws IOException {
var res = apiService.getCurrentRoom(localData.getUserSecret()).execute(); var res = apiService.getCurrentRoom(localData.getUserSecret()).execute();
var room = res.body().getData().get(); var room = res.body().getData().get();
visit(room, false); visit(room);
} }
public void visit(Room room) throws IOException { public void visit(Long roomId, boolean changeRoom) throws IOException {
visit(room, true);
}
public void visit(Room room, boolean changeRoom) throws IOException {
if (changeRoom) { if (changeRoom) {
apiService.moveToRoom(localData.getUserSecret(), room.getId()); apiService.moveToRoom(localData.getUserSecret(), roomId).execute();
} }
visit();
}
public void visit(Room room) throws IOException {
System.out.println("\n");
if (room.getName().equals("Outside")) {
Cli.info("Nyní jste venku");
} else {
Cli.info("Nyní se nacházíte v místnosti " + room.getName()); Cli.info("Nyní se nacházíte v místnosti " + room.getName());
}
if (room.getCharacters().isEmpty()) { if (room.getCharacters().isEmpty()) {
Cli.type("V místnosti je prázno... Ani jedna duše."); Cli.type("V místnosti je prázno... Ani jedna duše.");
@ -220,8 +226,52 @@ public class Chronos {
for (Character character : room.getCharacters()) { for (Character character : room.getCharacters()) {
talkWith(character); talkWith(character);
} }
if (!room.getCharacters().isEmpty()) {
interactWithAny(room.getCharacters());
} }
var responseRooms = apiService.getAllRooms(localData.getUserSecret()).execute();
var rooms = responseRooms.body().getData().get().stream().filter(rm -> !rm.getId().equals(room.getId())).toList();
System.out.println();
Cli.info("Nyni si vyberte do jaké místnosti chcete jít.");
int selectedIndex = Cli.selectOptionIndex(rooms.stream().map(Room::getName).toList());
visit(rooms.get(selectedIndex).getId(), true);
}
private void interactWithAny(List<Character> characters) throws IOException {
if (characters.stream().anyMatch(character -> character.getInteraction() != null)) {
List<Character> interactablePostavy = characters.stream().filter(
character -> character.getInteraction() != null &&
!character.isInteractedWith()
).toList();
if (interactablePostavy.isEmpty()) {
return;
}
List<String> options = new ArrayList<>(interactablePostavy.stream().map(Character::getName).toList());
options.add("Neinteragovat s nikým");
Cli.info("Můžete interagovat s následujícími postavami:");
int selectedIndex = Cli.selectOptionIndex(options);
if (selectedIndex == options.size() - 1) {
return;
}
var character = characters.get(selectedIndex);
Interactions.runInteraction(character);
var currentRoom = apiService.getCurrentRoom(localData.getUserSecret()).execute().body().getData();
interactWithAny(currentRoom.get().getCharacters().stream().filter(chachar -> !chachar.isInteractedWith()).toList());
}
}
public void talkWith(Character character) throws IOException { public void talkWith(Character character) throws IOException {
Cli.type("V místnosti je " + character.getName()); Cli.type("V místnosti je " + character.getName());

View File

@ -0,0 +1,13 @@
package cz.jzitnik.game.interactions;
import cz.jzitnik.api.types.Character;
public class Interactions {
public static void runInteraction(Character character) {
switch (character.getInteraction()) {
case Farmer -> {
System.out.println("Inplement interaction with farmer");
}
}
}
}

View File

@ -1,5 +1,6 @@
package cz.jzitnik.utils; package cz.jzitnik.utils;
import java.util.List;
import java.util.Scanner; import java.util.Scanner;
public class Cli { public class Cli {
@ -169,4 +170,66 @@ public class Cli {
} }
} }
} }
/**
* Displays a menu with the provided options and returns the selected option.
*
* @param options Array of options to display to the user.
* @return The selected option as a String.
*/
public static int selectOptionIndex(String[] options) {
Scanner scanner = new Scanner(System.in);
int choice;
System.out.println("Vyberte možnost:");
for (int i = 0; i < options.length; i++) {
System.out.println((i + 1) + ". " + options[i]);
}
while (true) {
System.out.print("Vložte číslo možnosti: ");
if (scanner.hasNextInt()) {
choice = scanner.nextInt();
if (choice >= 1 && choice <= options.length) {
return choice - 1;
} else {
System.out.println("Neplatní možnost, vyberte číslo mezi 1 a " + options.length);
}
} else {
System.out.println("Neplatný vstup, vložte číslo.");
scanner.next();
}
}
}
/**
* Displays a menu with the provided options and returns the selected option.
*
* @param options Array of options to display to the user.
* @return The selected option as a String.
*/
public static int selectOptionIndex(List<String> options) {
Scanner scanner = new Scanner(System.in);
int choice;
System.out.println("Vyberte možnost:");
for (int i = 0; i < options.size(); i++) {
System.out.println((i + 1) + ". " + options.get(i));
}
while (true) {
System.out.print("Vložte číslo možnosti: ");
if (scanner.hasNextInt()) {
choice = scanner.nextInt();
if (choice >= 1 && choice <= options.size()) {
return choice - 1;
} else {
System.out.println("Neplatní možnost, vyberte číslo mezi 1 a " + options.size());
}
} else {
System.out.println("Neplatný vstup, vložte číslo.");
scanner.next();
}
}
}
} }