package com.bernard.nodecames.game; import java.util.Arrays; import java.util.concurrent.CompletableFuture; import java.util.stream.IntStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.bernard.nodecames.model.Game; import io.github.archipelagomw.APResult.ResultCode; import io.github.archipelagomw.Client; import io.github.archipelagomw.ClientStatus; import io.github.archipelagomw.events.ArchipelagoEventListener; import io.github.archipelagomw.events.ConnectionResultEvent; import io.github.archipelagomw.events.ReceiveItemEvent; import io.github.archipelagomw.flags.ItemsHandling; import io.github.archipelagomw.network.ConnectionResult; import lombok.Getter; public class ArchipelagoClient extends Client { Game game; GameManager gm; private static final Logger log = LoggerFactory.getLogger(ArchipelagoClient.class); public ArchipelagoClient(Game game, GameManager gm, String slot) { super(); this.gm = gm; this.game = game; this.setGame("nodecames"); this.setName(slot); client.setItemsHandlingFlags(ItemsHandling.SEND_ITEMS | ItemsHandling.SEND_OWN_ITEMS); this.getEventManager().registerListener(this); } @ArchipelagoEventListener public void onReceiveItem(ReceiveItemEvent e) { log.debug("Received item : {}", e.getItemName()); if(e.getIndex() > game.getInventory().getReceivedItems().size()) gm.giveItem(game, e.getItemName()); // Else, the item has already been received } @Getter private CompletableFuture connectionResult = new CompletableFuture<>(); @ArchipelagoEventListener public void onConnectResult(ConnectionResultEvent e) { connectionResult.complete(e.getResult()); if(e.getResult() != ConnectionResult.Success) { throw new IllegalStateException("Could not connect to archipelago : %s".formatted(e.getResult().name())); } else { if(this.setGameState(ClientStatus.CLIENT_PLAYING).getCode() != ResultCode.SUCCESS) throw new IllegalStateException("Colud not set state to playing"); else { client.sendChat("Hello, here is Nodecames AP client, nice to meet you"); } } } public static int[] GREEN_COUNT_PER_WORLD = new int[]{6, 9, 9, 12, 16, 16, 20, 25, 25, 30, 36, 36}; public static String[] WORLDS = new String[]{"1-1","1-2","1-3","2-1","2-2","2-3","3-1","3-2","3-3","4-1","4-2","4-3"}; public void checkWordInWorld(String worldName, int wordIndex) { //TODO binarySearch is okay for now, but we'll have to remove this at some point int worldIndex = Arrays.binarySearch(WORLDS, 0, WORLDS.length, worldName); if(wordIndex>GREEN_COUNT_PER_WORLD[wordIndex]-1)return;//We don't have that many checks //TODO this should be stored, not computed, in archipelagoconfig long locationId = IntStream.range(0, worldIndex).map(w -> GREEN_COUNT_PER_WORLD[w]).sum()+1+wordIndex; this.checkLocation(locationId); } public void checkWorldComplete(String worldName) { //TODO binarySearch is okay for now, but we'll have to remove this at some point int worldIndex = Arrays.binarySearch(WORLDS, 0, WORLDS.length, worldName); long locationId = IntStream.range(0, worldIndex+1).map(w -> GREEN_COUNT_PER_WORLD[w]).sum()+1; this.checkLocation(locationId); } @Override public void onError(Exception e) { //TODO make a real handler throw new IllegalStateException("Archipelago error :", e); } @Override public void onClose(String Reason, int attemptingReconnect) { // TODO Auto-generated method stub throw new UnsupportedOperationException("Unimplemented method 'onClose'"); } }