Observer pattern & Archipelago
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
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 com.bernard.nodecames.model.GridConfig.MutableOption;
|
||||
|
||||
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) throws IllegalGameActionException {
|
||||
log.debug("Received item : {}", e.getItemName());
|
||||
switch(e.getItemName()) {
|
||||
case "progressive_hint_count":
|
||||
gm.unlockMoreHintCount(this.game);
|
||||
break;
|
||||
case "progressive_hint_word_length":
|
||||
gm.unlockMoreHintWordLengthCount(this.game);
|
||||
break;
|
||||
case "progressive_hint_word_count":
|
||||
gm.unlockMoreHintWordCount(this.game);
|
||||
break;
|
||||
case "zero_hint":
|
||||
gm.unlockHintWordCount(this.game, 0);
|
||||
break;
|
||||
case "infinity_hint":
|
||||
gm.unlockHintWordCount(this.game, -1);
|
||||
break;
|
||||
case "one_more_guess":
|
||||
gm.unlockMutable(game, MutableOption.ONE_MORE_GUESS, true);
|
||||
break;
|
||||
case "end_guessing":
|
||||
gm.unlockMutable(game, MutableOption.END_GUESSING, true);
|
||||
break;
|
||||
case "only_one_green_green":
|
||||
gm.unlockMutable(game, MutableOption.ONLY_ONE_GREEN_GREEN, true);
|
||||
break;
|
||||
case "sudden_death":
|
||||
gm.unlockMutable(game, MutableOption.SUDDEN_DEATH, true);
|
||||
break;
|
||||
case "structured_grid":
|
||||
gm.unlockStructuredGrid(game);
|
||||
break;
|
||||
case "hints_in_a_row":
|
||||
gm.unlockMutable(game, MutableOption.HINTS_IN_A_ROW, true);
|
||||
break;
|
||||
case "anyone_starts":
|
||||
gm.unlockAnyoneCanStart(game);
|
||||
break;
|
||||
case "filler":
|
||||
// We do nothing if we receive a filler item
|
||||
break;
|
||||
default:
|
||||
if (e.getItemName().startsWith("unlock_world_")) {
|
||||
int worldIndex = Integer.parseInt(e.getItemName().substring("unlock_world_".length()))-1;
|
||||
String worldName = "%d-%d".formatted((worldIndex/3)+1, (worldIndex%3)+1);
|
||||
gm.unlockWorld(game, worldName);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Received unknown item : "+e.getItemName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
private CompletableFuture<ConnectionResult> 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'");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user