refactor: restructure code and fix some events not being applied
This commit is contained in:
parent
e0af4cf01c
commit
3bb6d81b27
@ -27,7 +27,7 @@ public class GameInstance {
|
|||||||
/** Constructs a new {@link GameInstance}. */
|
/** Constructs a new {@link GameInstance}. */
|
||||||
public GameInstance(PartyConfig partyConfig, CharacterConfig characterConfig, ScenarioConfig scenarioConfig) {
|
public GameInstance(PartyConfig partyConfig, CharacterConfig characterConfig, ScenarioConfig scenarioConfig) {
|
||||||
_state = new GameState(partyConfig, characterConfig, scenarioConfig);
|
_state = new GameState(partyConfig, characterConfig, scenarioConfig);
|
||||||
this.state = new GameStateView(_state);
|
state = new GameStateView(_state);
|
||||||
manager = new GameStateManager(_state);
|
manager = new GameStateManager(_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,16 +36,11 @@ public class GameInstance {
|
|||||||
* @param requests The requests to check
|
* @param requests The requests to check
|
||||||
* @return The list of resulting {@link Event}s or `null` if the check failed
|
* @return The list of resulting {@link Event}s or `null` if the check failed
|
||||||
*/
|
*/
|
||||||
public Optional<List<Event>> checkRequestsAndApply(Request... requests) {
|
public Optional<List<Event>> checkRequestsAndApply(ArrayList<Request> requests) {
|
||||||
if(manager.processRequests(requests, true)) {
|
if(manager.processRequests(requests, true)) {
|
||||||
ArrayList<Event> result = manager.apply();
|
ArrayList<Event> result = manager.apply();
|
||||||
|
|
||||||
ArrayList<Event> result2 = manager.checkPostPhase();
|
result.addAll(manager.checkPostPhase());
|
||||||
manager.applyEvents(result2);
|
|
||||||
|
|
||||||
result.addAll(result2);
|
|
||||||
|
|
||||||
result.add(GameLogic.buildGameStateEvent(_state));
|
|
||||||
|
|
||||||
return Optional.of(result);
|
return Optional.of(result);
|
||||||
}
|
}
|
||||||
@ -58,44 +53,10 @@ public class GameInstance {
|
|||||||
* @param requests The requests to check
|
* @param requests The requests to check
|
||||||
* @return Whether or not the given set of requests is valid
|
* @return Whether or not the given set of requests is valid
|
||||||
*/
|
*/
|
||||||
public boolean checkRequests(Request... requests) {
|
public boolean checkRequests(ArrayList<Request> requests) {
|
||||||
return manager.processRequests(requests, false);
|
return manager.processRequests(requests, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes and starts the game. Selected characters are given as a list of indices from the {@link CharacterConfig#characters} array.
|
|
||||||
* @param selectedCharacters1 The characters selected by player 1
|
|
||||||
* @param selectedCharacters2 The characters selected by player 2
|
|
||||||
* @return The list of resulting {@link Event}s
|
|
||||||
*/
|
|
||||||
public ArrayList<Event> startGame(ArrayList<Integer> selectedCharacters1, ArrayList<Integer> selectedCharacters2) {
|
|
||||||
ArrayList<Event> result = manager.initGame(selectedCharacters1, selectedCharacters2);
|
|
||||||
manager.applyEvents(result);
|
|
||||||
|
|
||||||
ArrayList<Event> result2 = manager.startGame();
|
|
||||||
manager.applyEvents(result2);
|
|
||||||
|
|
||||||
result.addAll(result2); //do not merge this, result needs to be applied before startGame is called
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Produces a {@link EventType#GamestateEvent} for the current {@link GameState}.
|
|
||||||
* @return The resulting event
|
|
||||||
*/
|
|
||||||
public Event getGameStateEvent() {
|
|
||||||
return GameLogic.buildGameStateEvent(_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Restores the current {@link GameState} based on the given one.
|
|
||||||
* @param state The state to restore from
|
|
||||||
*/
|
|
||||||
public void setGameState(GameState state) {
|
|
||||||
_state.restore(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies an array of {@link Event}s to the game state.
|
* Applies an array of {@link Event}s to the game state.
|
||||||
* @param events The events to apply.
|
* @param events The events to apply.
|
||||||
@ -104,8 +65,30 @@ public class GameInstance {
|
|||||||
manager.applyEvents(events);
|
manager.applyEvents(events);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected GameState getState() {
|
/**
|
||||||
return _state;
|
* Initializes and starts the game. Selected characters are given as a list of indices from the {@link CharacterConfig#characters} array.
|
||||||
|
* @param selectedCharacters1 The characters selected by player 1
|
||||||
|
* @param selectedCharacters2 The characters selected by player 2
|
||||||
|
* @return The list of resulting {@link Event}s
|
||||||
|
*/
|
||||||
|
public ArrayList<Event> startGame(ArrayList<Integer> selectedCharacters1, ArrayList<Integer> selectedCharacters2) {
|
||||||
|
return manager.startGame(selectedCharacters1, selectedCharacters2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produces a {@link EventType#GamestateEvent} for the current {@link GameState}.
|
||||||
|
* @return The resulting event
|
||||||
|
*/
|
||||||
|
public Event getGameStateEvent() {
|
||||||
|
return manager.getGameStateEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the current {@link GameState} based on the given {@link EventType#GamestateEvent}.
|
||||||
|
* @param gameStateEvent The event to restore from
|
||||||
|
*/
|
||||||
|
public void applyGameStateEvent(Event gameStateEvent) {
|
||||||
|
manager.applyEvent(gameStateEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,199 +19,16 @@ import java.util.HashSet;
|
|||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
/** Contains game logic handling. */
|
/** Contains game logic handling. */
|
||||||
class GameLogic {
|
public class GameLogic {
|
||||||
private static final Random rand = new Random();
|
private static final Random rand = new Random();
|
||||||
|
|
||||||
/**
|
|
||||||
* Produces resulting {@link Event}s from a given {@link Request}.
|
|
||||||
* @param state The game state to execute on
|
|
||||||
* @param request The request to execute
|
|
||||||
* @return The list of resulting events
|
|
||||||
*/
|
|
||||||
public static ArrayList<Event> executeRequest(GameState state, Request request) {
|
|
||||||
ArrayList<Event> result = new ArrayList<>();
|
|
||||||
|
|
||||||
switch(request.type) {
|
|
||||||
case MeleeAttackRequest, RangedAttackRequest -> {
|
|
||||||
CharacterRequest data = (CharacterRequest)request;
|
|
||||||
result.add(new EventBuilder(request.type == RequestType.MeleeAttackRequest ? EventType.MeleeAttackEvent : EventType.RangedAttackEvent)
|
|
||||||
.withOriginEntity(data.originEntity)
|
|
||||||
.withTargetEntity(data.targetEntity)
|
|
||||||
.withOriginField(data.originField)
|
|
||||||
.withTargetField(data.targetField)
|
|
||||||
.withAmount(data.value)
|
|
||||||
.buildCharacterEvent());
|
|
||||||
result.add(new EventBuilder(EventType.ConsumedAPEvent)
|
|
||||||
.withTargetEntity(data.originEntity)
|
|
||||||
.withTargetField(data.originField)
|
|
||||||
.withAmount(1)
|
|
||||||
.buildEntityEvent());
|
|
||||||
result.add(new EventBuilder(EventType.TakenDamageEvent)
|
|
||||||
.withTargetEntity(data.targetEntity)
|
|
||||||
.withTargetField(data.targetField)
|
|
||||||
.withAmount(data.value)
|
|
||||||
.buildEntityEvent());
|
|
||||||
}
|
|
||||||
case MoveRequest -> {
|
|
||||||
CharacterRequest data = (CharacterRequest)request;
|
|
||||||
result.add(new EventBuilder(EventType.MoveEvent)
|
|
||||||
.withOriginEntity(data.originEntity)
|
|
||||||
.withOriginField(data.originField)
|
|
||||||
.withTargetField(data.targetField)
|
|
||||||
.buildCharacterEvent());
|
|
||||||
result.add(new EventBuilder(EventType.ConsumedMPEvent)
|
|
||||||
.withTargetEntity(data.originEntity)
|
|
||||||
.withTargetField(data.targetField) //when this event gets handled, the character already moved to the target field
|
|
||||||
.withAmount(1)
|
|
||||||
.buildEntityEvent());
|
|
||||||
for(Entity entity: state.entities.findByPosition(data.targetField)) {
|
|
||||||
if(entity instanceof Character) {
|
|
||||||
result.add(new EventBuilder(EventType.MoveEvent)
|
|
||||||
.withOriginEntity(entity.id)
|
|
||||||
.withOriginField(data.targetField)
|
|
||||||
.withTargetField(data.originField)
|
|
||||||
.buildCharacterEvent());
|
|
||||||
break; //we should only have one entity per field anyways
|
|
||||||
}else if(entity instanceof InfinityStone) {
|
|
||||||
result.add(new EventBuilder(EventType.DestroyedEntityEvent)
|
|
||||||
.withTargetField(data.targetField)
|
|
||||||
.withTargetEntity(entity.id)
|
|
||||||
.buildEntityEvent());
|
|
||||||
break; //we should only have one entity per field anyways
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case ExchangeInfinityStoneRequest, UseInfinityStoneRequest -> {
|
|
||||||
CharacterRequest data = (CharacterRequest)request;
|
|
||||||
result.add(new EventBuilder(request.type == RequestType.ExchangeInfinityStoneRequest ? EventType.ExchangeInfinityStoneEvent : EventType.UseInfinityStoneEvent)
|
|
||||||
.withOriginEntity(data.originEntity)
|
|
||||||
.withOriginField(data.originField)
|
|
||||||
.withTargetEntity(data.targetEntity)
|
|
||||||
.withTargetField(data.targetField)
|
|
||||||
.withStoneType(data.stoneType)
|
|
||||||
.buildCharacterEvent());
|
|
||||||
result.add(new EventBuilder(EventType.ConsumedAPEvent)
|
|
||||||
.withTargetEntity(data.originEntity)
|
|
||||||
.withTargetField(data.originField)
|
|
||||||
.withAmount(1)
|
|
||||||
.buildEntityEvent());
|
|
||||||
|
|
||||||
if(request.type == RequestType.UseInfinityStoneRequest) {
|
|
||||||
switch(((CharacterRequest) request).stoneType) {
|
|
||||||
case SpaceStone -> {
|
|
||||||
result.add(new EventBuilder(EventType.MoveEvent)
|
|
||||||
.withOriginEntity(data.originEntity)
|
|
||||||
.withOriginField(data.originField)
|
|
||||||
.withTargetField(data.targetField)
|
|
||||||
.buildCharacterEvent());
|
|
||||||
}
|
|
||||||
case MindStone -> {
|
|
||||||
EntityType target = data.originEntity.type == EntityType.P1 ? EntityType.P2 : EntityType.P1;
|
|
||||||
for(IntVector2 pos: rasterize(data.originField, data.targetField, false, true)) {
|
|
||||||
for(Entity entity: state.entities.findByPosition(pos)) {
|
|
||||||
if(entity.id.isSameType(target)) {
|
|
||||||
result.add(new EventBuilder(EventType.TakenDamageEvent)
|
|
||||||
.withTargetEntity(entity.id)
|
|
||||||
.withTargetField(pos)
|
|
||||||
.withAmount(data.value)
|
|
||||||
.buildEntityEvent());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case RealityStone -> {
|
|
||||||
if(data.originEntity == data.targetEntity) { // => place stone
|
|
||||||
result.add(new EventBuilder(EventType.SpawnEntityEvent)
|
|
||||||
.withTargetField(data.targetField)
|
|
||||||
.withEntity(new Rock(new EntityID(EntityType.Rocks, state.entities.findFreeRockSlot()), data.targetField, 100))
|
|
||||||
.buildEntityEvent());
|
|
||||||
}else { // => destroy stone
|
|
||||||
result.add(new EventBuilder(EventType.DestroyedEntityEvent)
|
|
||||||
.withTargetField(data.targetField)
|
|
||||||
.withTargetEntity(data.targetEntity)
|
|
||||||
.buildEntityEvent());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case PowerStone -> {
|
|
||||||
Character origin = (Character)state.entities.findEntity(data.originEntity);
|
|
||||||
int dmg = (int)Math.round(origin.hp.getMax() * 0.1);
|
|
||||||
if(origin.hp.getValue() != 1 && dmg > 0) {
|
|
||||||
result.add(new EventBuilder(EventType.TakenDamageEvent)
|
|
||||||
.withTargetEntity(data.originEntity)
|
|
||||||
.withTargetField(data.originField)
|
|
||||||
.withAmount(dmg)
|
|
||||||
.buildEntityEvent());
|
|
||||||
}
|
|
||||||
result.add(new EventBuilder(EventType.TakenDamageEvent)
|
|
||||||
.withTargetEntity(data.targetEntity)
|
|
||||||
.withTargetField(data.targetField)
|
|
||||||
.withAmount(data.value)
|
|
||||||
.buildEntityEvent());
|
|
||||||
}
|
|
||||||
case TimeStone -> {
|
|
||||||
Character origin = (Character)state.entities.findEntity(data.originEntity);
|
|
||||||
int ap = origin.ap.getValue() - origin.ap.getMax();
|
|
||||||
if(ap < 0) {
|
|
||||||
result.add(new EventBuilder(EventType.ConsumedAPEvent)
|
|
||||||
.withTargetEntity(data.originEntity)
|
|
||||||
.withTargetField(data.originField)
|
|
||||||
.withAmount(ap)
|
|
||||||
.buildEntityEvent());
|
|
||||||
}
|
|
||||||
int mp = origin.mp.getValue() - origin.mp.getMax();
|
|
||||||
if(mp < 0) {
|
|
||||||
result.add(new EventBuilder(EventType.ConsumedMPEvent)
|
|
||||||
.withTargetEntity(data.originEntity)
|
|
||||||
.withTargetField(data.originField)
|
|
||||||
.withAmount(mp)
|
|
||||||
.buildEntityEvent());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case SoulStone -> {
|
|
||||||
Character target = (Character)state.entities.findEntity(data.targetEntity);
|
|
||||||
result.add(new EventBuilder(EventType.HealedEvent)
|
|
||||||
.withTargetEntity(data.targetEntity)
|
|
||||||
.withTargetField(data.targetField)
|
|
||||||
.withAmount(target.hp.getMax())
|
|
||||||
.buildEntityEvent());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case EndRoundRequest -> {
|
|
||||||
result.addAll(handleTurnEnd(state)); //why is it called end round request when it ends a turn...
|
|
||||||
}
|
|
||||||
case Req -> {
|
|
||||||
result.add(buildGameStateEvent(state));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds a {@link EventType#GamestateEvent} for the given {@link GameState}.
|
|
||||||
* @param state The game state to use
|
|
||||||
* @return The resulting event
|
|
||||||
*/
|
|
||||||
public static Event buildGameStateEvent(GameState state) {
|
|
||||||
return new EventBuilder(EventType.GamestateEvent)
|
|
||||||
.withEntities(state.entities.export())
|
|
||||||
.withTurnOrder(state.turnOrder.toArray(new EntityID[0]))
|
|
||||||
.withMapSize(state.mapSize)
|
|
||||||
.withActiveCharacter(state.activeCharacter)
|
|
||||||
.withStoneCooldowns(state.stoneCooldown.export())
|
|
||||||
.withWinCondition(state.won)
|
|
||||||
.buildGameStateEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks a {@link Request} for validity for a {@link GameState}.
|
* Checks a {@link Request} for validity for a {@link GameState}.
|
||||||
* @param state The game state to check on
|
* @param state The game state to check on
|
||||||
* @param request The request to validate
|
* @param request The request to validate
|
||||||
* @return Whether or not the request is valid
|
* @return Whether or not the request is valid
|
||||||
*/
|
*/
|
||||||
public static boolean checkRequest(GameState state, Request request) {
|
protected static boolean checkRequest(GameState state, Request request) {
|
||||||
try {
|
try {
|
||||||
switch(request.type) {
|
switch(request.type) {
|
||||||
case MeleeAttackRequest, RangedAttackRequest -> {
|
case MeleeAttackRequest, RangedAttackRequest -> {
|
||||||
@ -478,74 +295,181 @@ class GameLogic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a line of sight exists between the two positions
|
* Produces resulting {@link Event}s from a given {@link Request}.
|
||||||
* @param state The game state to work on
|
* @param state The game state to execute on
|
||||||
* @param start The first position
|
* @param request The request to execute
|
||||||
* @param end The second position
|
* @return The list of resulting events
|
||||||
* @return Whether or not the light of sight exists
|
|
||||||
*/
|
*/
|
||||||
private static boolean checkLineOfSight(GameState state, IntVector2 start, IntVector2 end) {
|
protected static ArrayList<Event> executeRequest(GameState state, Request request) {
|
||||||
for(IntVector2 pos: rasterize(start, end, false, false)) {
|
ArrayList<Event> result = new ArrayList<>();
|
||||||
if(state.entities.blocksVision(pos)) {
|
|
||||||
return false;
|
switch(request.type) {
|
||||||
|
case MeleeAttackRequest, RangedAttackRequest -> {
|
||||||
|
CharacterRequest data = (CharacterRequest)request;
|
||||||
|
result.add(new EventBuilder(request.type == RequestType.MeleeAttackRequest ? EventType.MeleeAttackEvent : EventType.RangedAttackEvent)
|
||||||
|
.withOriginEntity(data.originEntity)
|
||||||
|
.withTargetEntity(data.targetEntity)
|
||||||
|
.withOriginField(data.originField)
|
||||||
|
.withTargetField(data.targetField)
|
||||||
|
.withAmount(data.value)
|
||||||
|
.buildCharacterEvent());
|
||||||
|
result.add(new EventBuilder(EventType.ConsumedAPEvent)
|
||||||
|
.withTargetEntity(data.originEntity)
|
||||||
|
.withTargetField(data.originField)
|
||||||
|
.withAmount(1)
|
||||||
|
.buildEntityEvent());
|
||||||
|
result.add(new EventBuilder(EventType.TakenDamageEvent)
|
||||||
|
.withTargetEntity(data.targetEntity)
|
||||||
|
.withTargetField(data.targetField)
|
||||||
|
.withAmount(data.value)
|
||||||
|
.buildEntityEvent());
|
||||||
}
|
}
|
||||||
}
|
case MoveRequest -> {
|
||||||
return true;
|
CharacterRequest data = (CharacterRequest)request;
|
||||||
}
|
result.add(new EventBuilder(EventType.MoveEvent)
|
||||||
|
.withOriginEntity(data.originEntity)
|
||||||
/**
|
.withOriginField(data.originField)
|
||||||
* Finds free neighbour options from a starting field.
|
.withTargetField(data.targetField)
|
||||||
* @param state The game state to work on
|
.buildCharacterEvent());
|
||||||
* @param start The starting position
|
result.add(new EventBuilder(EventType.ConsumedMPEvent)
|
||||||
* @return A list of free neighbour field options
|
.withTargetEntity(data.originEntity)
|
||||||
*/
|
.withTargetField(data.targetField) //when this event gets handled, the character already moved to the target field
|
||||||
private static ArrayList<IntVector2> getFreeNeighbour(GameState state, IntVector2 start) {
|
.withAmount(1)
|
||||||
ArrayList<IntVector2> options = new ArrayList<>();
|
.buildEntityEvent());
|
||||||
|
for(Entity entity: state.entities.findByPosition(data.targetField)) {
|
||||||
if(start.getX() < 0 || start.getX() >= state.mapSize.getX() || start.getY() < 0 || start.getY() >= state.mapSize.getY()) {
|
if(entity instanceof Character) {
|
||||||
return options;
|
result.add(new EventBuilder(EventType.MoveEvent)
|
||||||
}
|
.withOriginEntity(entity.id)
|
||||||
|
.withOriginField(data.targetField)
|
||||||
for(IntVector2 dir: IntVector2.CardinalDirections) {
|
.withTargetField(data.originField)
|
||||||
if(state.entities.findByPosition(start.add(dir)).size() == 0) {
|
.buildCharacterEvent());
|
||||||
options.add(start.add(dir));
|
break; //we should only have one entity per field anyways
|
||||||
}
|
}else if(entity instanceof InfinityStone) {
|
||||||
}
|
result.add(new EventBuilder(EventType.DestroyedEntityEvent)
|
||||||
|
.withTargetField(data.targetField)
|
||||||
if(options.size() == 0) {
|
.withTargetEntity(entity.id)
|
||||||
return getFreeNeighbour(state, start.add(IntVector2.CardinalDirections[rand.nextInt(IntVector2.CardinalDirections.length)]));
|
.buildEntityEvent());
|
||||||
}else {
|
break; //we should only have one entity per field anyways
|
||||||
return options;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds free field options.
|
|
||||||
* @param state The game state to work on
|
|
||||||
* @return A list of free field options
|
|
||||||
*/
|
|
||||||
private static ArrayList<IntVector2> getFreeFields(GameState state) {
|
|
||||||
ArrayList<IntVector2> options = new ArrayList<>();
|
|
||||||
|
|
||||||
for(int x = 0; x < state.mapSize.getX(); x++) {
|
|
||||||
for(int y = 0; y < state.mapSize.getY(); y++) {
|
|
||||||
IntVector2 pos = new IntVector2(x, y);
|
|
||||||
if(state.entities.findByPosition(pos).size() == 0) {
|
|
||||||
options.add(pos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case ExchangeInfinityStoneRequest, UseInfinityStoneRequest -> {
|
||||||
|
CharacterRequest data = (CharacterRequest)request;
|
||||||
|
result.add(new EventBuilder(request.type == RequestType.ExchangeInfinityStoneRequest ? EventType.ExchangeInfinityStoneEvent : EventType.UseInfinityStoneEvent)
|
||||||
|
.withOriginEntity(data.originEntity)
|
||||||
|
.withOriginField(data.originField)
|
||||||
|
.withTargetEntity(data.targetEntity)
|
||||||
|
.withTargetField(data.targetField)
|
||||||
|
.withStoneType(data.stoneType)
|
||||||
|
.buildCharacterEvent());
|
||||||
|
result.add(new EventBuilder(EventType.ConsumedAPEvent)
|
||||||
|
.withTargetEntity(data.originEntity)
|
||||||
|
.withTargetField(data.originField)
|
||||||
|
.withAmount(1)
|
||||||
|
.buildEntityEvent());
|
||||||
|
|
||||||
|
if(request.type == RequestType.UseInfinityStoneRequest) {
|
||||||
|
switch(((CharacterRequest) request).stoneType) {
|
||||||
|
case SpaceStone -> {
|
||||||
|
result.add(new EventBuilder(EventType.MoveEvent)
|
||||||
|
.withOriginEntity(data.originEntity)
|
||||||
|
.withOriginField(data.originField)
|
||||||
|
.withTargetField(data.targetField)
|
||||||
|
.buildCharacterEvent());
|
||||||
|
}
|
||||||
|
case MindStone -> {
|
||||||
|
EntityType target = data.originEntity.type == EntityType.P1 ? EntityType.P2 : EntityType.P1;
|
||||||
|
for(IntVector2 pos: rasterize(data.originField, data.targetField, false, true)) {
|
||||||
|
for(Entity entity: state.entities.findByPosition(pos)) {
|
||||||
|
if(entity.id.isSameType(target)) {
|
||||||
|
result.add(new EventBuilder(EventType.TakenDamageEvent)
|
||||||
|
.withTargetEntity(entity.id)
|
||||||
|
.withTargetField(pos)
|
||||||
|
.withAmount(data.value)
|
||||||
|
.buildEntityEvent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case RealityStone -> {
|
||||||
|
if(data.originEntity == data.targetEntity) { // => place stone
|
||||||
|
result.add(new EventBuilder(EventType.SpawnEntityEvent)
|
||||||
|
.withTargetField(data.targetField)
|
||||||
|
.withEntity(new Rock(new EntityID(EntityType.Rocks, state.entities.findFreeRockSlot()), data.targetField, 100))
|
||||||
|
.buildEntityEvent());
|
||||||
|
}else { // => destroy stone
|
||||||
|
result.add(new EventBuilder(EventType.DestroyedEntityEvent)
|
||||||
|
.withTargetField(data.targetField)
|
||||||
|
.withTargetEntity(data.targetEntity)
|
||||||
|
.buildEntityEvent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case PowerStone -> {
|
||||||
|
Character origin = (Character)state.entities.findEntity(data.originEntity);
|
||||||
|
int dmg = (int)Math.round(origin.hp.getMax() * 0.1);
|
||||||
|
if(origin.hp.getValue() != 1 && dmg > 0) {
|
||||||
|
result.add(new EventBuilder(EventType.TakenDamageEvent)
|
||||||
|
.withTargetEntity(data.originEntity)
|
||||||
|
.withTargetField(data.originField)
|
||||||
|
.withAmount(dmg)
|
||||||
|
.buildEntityEvent());
|
||||||
|
}
|
||||||
|
result.add(new EventBuilder(EventType.TakenDamageEvent)
|
||||||
|
.withTargetEntity(data.targetEntity)
|
||||||
|
.withTargetField(data.targetField)
|
||||||
|
.withAmount(data.value)
|
||||||
|
.buildEntityEvent());
|
||||||
|
}
|
||||||
|
case TimeStone -> {
|
||||||
|
Character origin = (Character)state.entities.findEntity(data.originEntity);
|
||||||
|
int ap = origin.ap.getValue() - origin.ap.getMax();
|
||||||
|
if(ap < 0) {
|
||||||
|
result.add(new EventBuilder(EventType.ConsumedAPEvent)
|
||||||
|
.withTargetEntity(data.originEntity)
|
||||||
|
.withTargetField(data.originField)
|
||||||
|
.withAmount(ap)
|
||||||
|
.buildEntityEvent());
|
||||||
|
}
|
||||||
|
int mp = origin.mp.getValue() - origin.mp.getMax();
|
||||||
|
if(mp < 0) {
|
||||||
|
result.add(new EventBuilder(EventType.ConsumedMPEvent)
|
||||||
|
.withTargetEntity(data.originEntity)
|
||||||
|
.withTargetField(data.originField)
|
||||||
|
.withAmount(mp)
|
||||||
|
.buildEntityEvent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case SoulStone -> {
|
||||||
|
Character target = (Character)state.entities.findEntity(data.targetEntity);
|
||||||
|
result.add(new EventBuilder(EventType.HealedEvent)
|
||||||
|
.withTargetEntity(data.targetEntity)
|
||||||
|
.withTargetField(data.targetField)
|
||||||
|
.withAmount(target.hp.getMax())
|
||||||
|
.buildEntityEvent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case EndRoundRequest -> {
|
||||||
|
result.addAll(handleTurnEnd(state)); //why is it called end round request when it ends a turn...
|
||||||
|
}
|
||||||
|
case Req -> {
|
||||||
|
result.add(buildGameStateEvent(state));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return options;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies an {@link Event} to a {@link GameState}.
|
* Applies an {@link Event} to a {@link GameState}.
|
||||||
* @param state The game state to apply to
|
* @param state The game state to apply to
|
||||||
* @param event The event to apply
|
* @param event The event to apply
|
||||||
*/
|
*/
|
||||||
public static void applyEvent(GameState state, Event event) {
|
protected static void applyEvent(GameState state, Event event) {
|
||||||
switch(event.type) {
|
switch(event.type) {
|
||||||
case DestroyedEntityEvent -> {
|
case DestroyedEntityEvent -> {
|
||||||
state.entities.removeEntity(((EntityEvent)event).targetEntity);
|
state.entities.removeEntity(((EntityEvent)event).targetEntity);
|
||||||
@ -596,6 +520,87 @@ class GameLogic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a {@link EventType#GamestateEvent} for the given {@link GameState}.
|
||||||
|
* @param state The game state to use
|
||||||
|
* @return The resulting event
|
||||||
|
*/
|
||||||
|
public static Event buildGameStateEvent(GameState state) {
|
||||||
|
return new EventBuilder(EventType.GamestateEvent)
|
||||||
|
.withEntities(state.entities.export())
|
||||||
|
.withTurnOrder(state.turnOrder.toArray(new EntityID[0]))
|
||||||
|
.withMapSize(state.mapSize)
|
||||||
|
.withActiveCharacter(state.activeCharacter)
|
||||||
|
.withStoneCooldowns(state.stoneCooldown.export())
|
||||||
|
.withWinCondition(state.won)
|
||||||
|
.buildGameStateEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a line of sight exists between the two positions
|
||||||
|
* @param state The game state to work on
|
||||||
|
* @param start The first position
|
||||||
|
* @param end The second position
|
||||||
|
* @return Whether or not the light of sight exists
|
||||||
|
*/
|
||||||
|
public static boolean checkLineOfSight(GameState state, IntVector2 start, IntVector2 end) {
|
||||||
|
for(IntVector2 pos: rasterize(start, end, false, false)) {
|
||||||
|
if(state.entities.blocksVision(pos)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds free neighbour options from a starting field.
|
||||||
|
* @param state The game state to work on
|
||||||
|
* @param start The starting position
|
||||||
|
* @return A list of free neighbour field options
|
||||||
|
*/
|
||||||
|
public static ArrayList<IntVector2> getFreeNeighbour(GameState state, IntVector2 start) {
|
||||||
|
ArrayList<IntVector2> options = new ArrayList<>();
|
||||||
|
|
||||||
|
if(start.getX() < 0 || start.getX() >= state.mapSize.getX() || start.getY() < 0 || start.getY() >= state.mapSize.getY()) {
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(IntVector2 dir: IntVector2.CardinalDirections) {
|
||||||
|
if(state.entities.findByPosition(start.add(dir)).size() == 0) {
|
||||||
|
options.add(start.add(dir));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(options.size() == 0) {
|
||||||
|
return getFreeNeighbour(state, start.add(IntVector2.CardinalDirections[rand.nextInt(IntVector2.CardinalDirections.length)]));
|
||||||
|
}else {
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds free field options.
|
||||||
|
* @param state The game state to work on
|
||||||
|
* @return A list of free field options
|
||||||
|
*/
|
||||||
|
public static ArrayList<IntVector2> getFreeFields(GameState state) {
|
||||||
|
ArrayList<IntVector2> options = new ArrayList<>();
|
||||||
|
|
||||||
|
for(int x = 0; x < state.mapSize.getX(); x++) {
|
||||||
|
for(int y = 0; y < state.mapSize.getY(); y++) {
|
||||||
|
IntVector2 pos = new IntVector2(x, y);
|
||||||
|
if(state.entities.findByPosition(pos).size() == 0) {
|
||||||
|
options.add(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the game and initializes all entities.
|
* Starts the game and initializes all entities.
|
||||||
* @param state The game state to work on
|
* @param state The game state to work on
|
||||||
@ -603,7 +608,7 @@ class GameLogic {
|
|||||||
* @param selectedCharacters2 The characters selected by player 2
|
* @param selectedCharacters2 The characters selected by player 2
|
||||||
* @return The list of resulting {@link Event}s
|
* @return The list of resulting {@link Event}s
|
||||||
*/
|
*/
|
||||||
public static ArrayList<Event> startGame(GameState state, ArrayList<Integer> selectedCharacters1, ArrayList<Integer> selectedCharacters2) {
|
protected static ArrayList<Event> startGame(GameState state, ArrayList<Integer> selectedCharacters1, ArrayList<Integer> selectedCharacters2) {
|
||||||
ArrayList<Event> result = new ArrayList<>();
|
ArrayList<Event> result = new ArrayList<>();
|
||||||
|
|
||||||
ArrayList<IntVector2> free = new ArrayList<>();
|
ArrayList<IntVector2> free = new ArrayList<>();
|
||||||
@ -652,12 +657,21 @@ class GameLogic {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forcefully starts the next round.
|
||||||
|
* @param state The game state to work on
|
||||||
|
* @return The list of resulting {@link Event}s
|
||||||
|
*/
|
||||||
|
protected static ArrayList<Event> startRound(GameState state) {
|
||||||
|
return handleRoundStart(state);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts end of round handling if necessary.
|
* Starts end of round handling if necessary.
|
||||||
* @param state The game state to work on
|
* @param state The game state to work on
|
||||||
* @return The list of resulting {@link Event}s
|
* @return The list of resulting {@link Event}s
|
||||||
*/
|
*/
|
||||||
public static ArrayList<Event> checkTurnEnd(GameState state) {
|
protected static ArrayList<Event> checkTurnEnd(GameState state) {
|
||||||
if(
|
if(
|
||||||
((Character) state.entities.findEntity(state.activeCharacter)).ap.getValue() <= 0 &&
|
((Character) state.entities.findEntity(state.activeCharacter)).ap.getValue() <= 0 &&
|
||||||
((Character) state.entities.findEntity(state.activeCharacter)).mp.getValue() <= 0
|
((Character) state.entities.findEntity(state.activeCharacter)).mp.getValue() <= 0
|
||||||
@ -668,12 +682,22 @@ class GameLogic {
|
|||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forcefully ends the current turn.
|
||||||
|
* @param state The game state to work on
|
||||||
|
* @return The list of resulting {@link Event}s
|
||||||
|
*/
|
||||||
|
protected static ArrayList<Event> endTurn(GameState state) {
|
||||||
|
return handleTurnEnd(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles everything that happens at the end of a turn, including new rounds.
|
* Handles everything that happens at the end of a turn, including new rounds.
|
||||||
* @param state The game state to work on
|
* @param state The game state to work on
|
||||||
* @return The list of resulting {@link Event}s
|
* @return The list of resulting {@link Event}s
|
||||||
*/
|
*/
|
||||||
public static ArrayList<Event> handleTurnEnd(GameState state) {
|
private static ArrayList<Event> handleTurnEnd(GameState state) {
|
||||||
ArrayList<Event> result = new ArrayList<>();
|
ArrayList<Event> result = new ArrayList<>();
|
||||||
|
|
||||||
ArrayList<EntityID> alive = new ArrayList<>();
|
ArrayList<EntityID> alive = new ArrayList<>();
|
||||||
@ -721,7 +745,7 @@ class GameLogic {
|
|||||||
* @param state The game state to work on
|
* @param state The game state to work on
|
||||||
* @return The list of resulting {@link Event}s
|
* @return The list of resulting {@link Event}s
|
||||||
*/
|
*/
|
||||||
public static ArrayList<Event> handleRoundStart(GameState state) {
|
private static ArrayList<Event> handleRoundStart(GameState state) {
|
||||||
ArrayList<Event> result = new ArrayList<>();
|
ArrayList<Event> result = new ArrayList<>();
|
||||||
|
|
||||||
state.roundNumber++;
|
state.roundNumber++;
|
||||||
@ -764,7 +788,7 @@ class GameLogic {
|
|||||||
* @param state The game state to work on
|
* @param state The game state to work on
|
||||||
* @return The list of resulting {@link Event}s
|
* @return The list of resulting {@link Event}s
|
||||||
*/
|
*/
|
||||||
public static ArrayList<Event> handleGoose(GameState state) {
|
private static ArrayList<Event> handleGoose(GameState state) {
|
||||||
ArrayList<Event> result = new ArrayList<>();
|
ArrayList<Event> result = new ArrayList<>();
|
||||||
|
|
||||||
ArrayList<StoneType> inventory = new ArrayList<>(state.unvomitedStones);
|
ArrayList<StoneType> inventory = new ArrayList<>(state.unvomitedStones);
|
||||||
@ -804,7 +828,7 @@ class GameLogic {
|
|||||||
* @param state The game state to work on
|
* @param state The game state to work on
|
||||||
* @return The list of resulting {@link Event}s
|
* @return The list of resulting {@link Event}s
|
||||||
*/
|
*/
|
||||||
public static ArrayList<Event> handleStan(GameState state, HashSet<EntityID> revived) {
|
private static ArrayList<Event> handleStan(GameState state, HashSet<EntityID> revived) {
|
||||||
ArrayList<Event> result = new ArrayList<>();
|
ArrayList<Event> result = new ArrayList<>();
|
||||||
|
|
||||||
ArrayList<Character> characters = new ArrayList<>();
|
ArrayList<Character> characters = new ArrayList<>();
|
||||||
@ -864,7 +888,7 @@ class GameLogic {
|
|||||||
* @param state The game state to work on
|
* @param state The game state to work on
|
||||||
* @return The list of resulting {@link Event}s
|
* @return The list of resulting {@link Event}s
|
||||||
*/
|
*/
|
||||||
public static ArrayList<Event> spawnThanos(GameState state) {
|
private static ArrayList<Event> spawnThanos(GameState state) {
|
||||||
ArrayList<Event> result = new ArrayList<>();
|
ArrayList<Event> result = new ArrayList<>();
|
||||||
|
|
||||||
ArrayList<IntVector2> free = getFreeFields(state);
|
ArrayList<IntVector2> free = getFreeFields(state);
|
||||||
@ -894,7 +918,7 @@ class GameLogic {
|
|||||||
* @param state The game state to work on
|
* @param state The game state to work on
|
||||||
* @return The list of resulting {@link Event}s
|
* @return The list of resulting {@link Event}s
|
||||||
*/
|
*/
|
||||||
public static ArrayList<Event> handleThanos(GameState state, NPC thanos) {
|
private static ArrayList<Event> handleThanos(GameState state, NPC thanos) {
|
||||||
ArrayList<Event> result = new ArrayList<>();
|
ArrayList<Event> result = new ArrayList<>();
|
||||||
|
|
||||||
if(thanos.inventory.getFreeSlots() > 0) {
|
if(thanos.inventory.getFreeSlots() > 0) {
|
||||||
@ -1009,7 +1033,7 @@ class GameLogic {
|
|||||||
* @param state The game state to work on
|
* @param state The game state to work on
|
||||||
* @return The list of resulting {@link Event}s
|
* @return The list of resulting {@link Event}s
|
||||||
*/
|
*/
|
||||||
public static ArrayList<Event> handleTurnStart(GameState state) {
|
private static ArrayList<Event> handleTurnStart(GameState state) {
|
||||||
ArrayList<Event> result = new ArrayList<>();
|
ArrayList<Event> result = new ArrayList<>();
|
||||||
|
|
||||||
state.turnNumber++;
|
state.turnNumber++;
|
||||||
@ -1068,7 +1092,7 @@ class GameLogic {
|
|||||||
* @param winner The winning character
|
* @param winner The winning character
|
||||||
* @return The list of resulting {@link Event}s
|
* @return The list of resulting {@link Event}s
|
||||||
*/
|
*/
|
||||||
public static ArrayList<Event> handlePlayerWin(GameState state, EntityType winner) {
|
private static ArrayList<Event> handlePlayerWin(GameState state, EntityType winner) {
|
||||||
ArrayList<Event> result = new ArrayList<>();
|
ArrayList<Event> result = new ArrayList<>();
|
||||||
|
|
||||||
state.won = true;
|
state.won = true;
|
||||||
@ -1080,6 +1104,7 @@ class GameLogic {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes all fields which intersect the line between the center points of the given two fields including the two defining points.
|
* Computes all fields which intersect the line between the center points of the given two fields including the two defining points.
|
||||||
* @return The list of intersecting positions
|
* @return The list of intersecting positions
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package uulm.teamname.marvelous.gamelibrary.gamelogic;
|
package uulm.teamname.marvelous.gamelibrary.gamelogic;
|
||||||
|
|
||||||
import uulm.teamname.marvelous.gamelibrary.events.Event;
|
import uulm.teamname.marvelous.gamelibrary.events.Event;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.events.EventType;
|
||||||
import uulm.teamname.marvelous.gamelibrary.requests.Request;
|
import uulm.teamname.marvelous.gamelibrary.requests.Request;
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/** Represents manager for a game state. */
|
/** Represents manager for a game state. */
|
||||||
@ -12,7 +12,7 @@ class GameStateManager {
|
|||||||
private final GameState state;
|
private final GameState state;
|
||||||
|
|
||||||
/** The queue of {@link Event}s to be applied during {@link Request} processing */
|
/** The queue of {@link Event}s to be applied during {@link Request} processing */
|
||||||
private final ArrayDeque<Event> queue = new ArrayDeque<>();
|
private final ArrayList<Event> queue = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link GameStateManager}.
|
* Constructs a new {@link GameStateManager}.
|
||||||
@ -26,13 +26,17 @@ class GameStateManager {
|
|||||||
* Checks a list of {@link Request}s for validity and optionally produces resulting {@link Event}s.
|
* Checks a list of {@link Request}s for validity and optionally produces resulting {@link Event}s.
|
||||||
* @param requests The requests to check
|
* @param requests The requests to check
|
||||||
* @param apply True if resulting events should be stored for later application
|
* @param apply True if resulting events should be stored for later application
|
||||||
|
* @return Whether the requests are valid
|
||||||
*/
|
*/
|
||||||
public boolean processRequests(Request[] requests, boolean apply) {
|
public boolean processRequests(ArrayList<Request> requests, boolean apply) {
|
||||||
GameState snapshot = state.snapshot();
|
GameState snapshot = state.snapshot();
|
||||||
|
|
||||||
for(Request request: requests) {
|
for(Request request: requests) {
|
||||||
if (GameLogic.checkRequest(snapshot, request)) {
|
if (GameLogic.checkRequest(snapshot, request)) {
|
||||||
ArrayList<Event> result = GameLogic.executeRequest(snapshot, request);
|
ArrayList<Event> result = GameLogic.executeRequest(snapshot, request);
|
||||||
|
for(Event event: result) {
|
||||||
|
GameLogic.applyEvent(snapshot, event);
|
||||||
|
}
|
||||||
if(apply) {
|
if(apply) {
|
||||||
queue.addAll(result);
|
queue.addAll(result);
|
||||||
}
|
}
|
||||||
@ -45,32 +49,6 @@ class GameStateManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles events that happen after a turn phase.
|
|
||||||
* @return The optionally resulting {@link Event}s
|
|
||||||
*/
|
|
||||||
public ArrayList<Event> checkPostPhase() {
|
|
||||||
return GameLogic.checkTurnEnd(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the game.
|
|
||||||
* @param selectedCharacters1 The characters selected by player 1
|
|
||||||
* @param selectedCharacters2 The characters selected by player 2
|
|
||||||
* @return The resulting {@link Event}s
|
|
||||||
*/
|
|
||||||
public ArrayList<Event> initGame(ArrayList<Integer> selectedCharacters1, ArrayList<Integer> selectedCharacters2) {
|
|
||||||
return GameLogic.startGame(state, selectedCharacters1, selectedCharacters2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the game.
|
|
||||||
* @return The resulting {@link Event}s
|
|
||||||
*/
|
|
||||||
public ArrayList<Event> startGame() {
|
|
||||||
return GameLogic.handleRoundStart(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies an array of {@link Event}s to the game state.
|
* Applies an array of {@link Event}s to the game state.
|
||||||
* @param events The events to apply
|
* @param events The events to apply
|
||||||
@ -81,17 +59,64 @@ class GameStateManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies an {@link Event} to the game state.
|
||||||
|
* @param event The event to apply
|
||||||
|
*/
|
||||||
|
public void applyEvent(Event event) {
|
||||||
|
GameLogic.applyEvent(state, event);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies the result of the last processRequests call.
|
* Applies the result of the last processRequests call.
|
||||||
* @return A list of applied events
|
* @return A list of applied events
|
||||||
*/
|
*/
|
||||||
public ArrayList<Event> apply() {
|
public ArrayList<Event> apply() {
|
||||||
ArrayList<Event> toReturn = new ArrayList<>(queue.size());
|
for(Event event: queue) {
|
||||||
Event current;
|
GameLogic.applyEvent(state, event);
|
||||||
while ((current = queue.poll()) != null) {
|
|
||||||
GameLogic.applyEvent(state, current);
|
|
||||||
toReturn.add(current);
|
|
||||||
}
|
}
|
||||||
return toReturn;
|
|
||||||
|
// i feel so smart for remembering this trick
|
||||||
|
try {
|
||||||
|
return new ArrayList<>(queue);
|
||||||
|
}finally {
|
||||||
|
queue.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles events that happen after a turn phase.
|
||||||
|
* @return The optionally resulting {@link Event}s
|
||||||
|
*/
|
||||||
|
public ArrayList<Event> checkPostPhase() {
|
||||||
|
ArrayList<Event> result = GameLogic.checkTurnEnd(state);
|
||||||
|
applyEvents(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes and starts the game.
|
||||||
|
* @param selectedCharacters1 The characters selected by player 1
|
||||||
|
* @param selectedCharacters2 The characters selected by player 2
|
||||||
|
* @return The resulting {@link Event}s
|
||||||
|
*/
|
||||||
|
public ArrayList<Event> startGame(ArrayList<Integer> selectedCharacters1, ArrayList<Integer> selectedCharacters2) {
|
||||||
|
ArrayList<Event> result = GameLogic.startGame(state, selectedCharacters1, selectedCharacters2);
|
||||||
|
applyEvents(result);
|
||||||
|
|
||||||
|
ArrayList<Event> result2 = GameLogic.startRound(state);
|
||||||
|
applyEvents(result2);
|
||||||
|
|
||||||
|
result.addAll(result2);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produces a {@link EventType#GamestateEvent} for the current {@link GameState}.
|
||||||
|
* @return The resulting event
|
||||||
|
*/
|
||||||
|
public Event getGameStateEvent() {
|
||||||
|
return GameLogic.buildGameStateEvent(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,6 @@ import uulm.teamname.marvelous.gamelibrary.IntVector2;
|
|||||||
import uulm.teamname.marvelous.gamelibrary.config.*;
|
import uulm.teamname.marvelous.gamelibrary.config.*;
|
||||||
import uulm.teamname.marvelous.gamelibrary.entities.*;
|
import uulm.teamname.marvelous.gamelibrary.entities.*;
|
||||||
import uulm.teamname.marvelous.gamelibrary.entities.Character;
|
import uulm.teamname.marvelous.gamelibrary.entities.Character;
|
||||||
import uulm.teamname.marvelous.gamelibrary.events.Event;
|
|
||||||
import uulm.teamname.marvelous.gamelibrary.events.EventType;
|
|
||||||
import uulm.teamname.marvelous.gamelibrary.requests.*;
|
import uulm.teamname.marvelous.gamelibrary.requests.*;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -79,12 +77,12 @@ class GameLogicTest {
|
|||||||
|
|
||||||
props.name = generateName(10);
|
props.name = generateName(10);
|
||||||
|
|
||||||
props.HP = Math.abs(randomIntegers.next() % 20);
|
props.HP = Math.abs(randomIntegers.next() % 15 + 5);
|
||||||
props.MP = Math.abs(randomIntegers.next() % 7);
|
props.MP = Math.abs(randomIntegers.next() % 5 + 2);
|
||||||
props.AP = Math.abs(randomIntegers.next() % 7);
|
props.AP = Math.abs(randomIntegers.next() % 5 + 2);
|
||||||
props.meleeDamage = Math.abs(randomIntegers.next() % 7);
|
props.meleeDamage = Math.abs(randomIntegers.next() % 5 + 2);
|
||||||
props.rangedDamage = Math.abs(randomIntegers.next() % 7);
|
props.rangedDamage = Math.abs(randomIntegers.next() % 5 + 2);
|
||||||
props.attackRange = Math.abs(randomIntegers.next() % 7);
|
props.attackRange = Math.abs(randomIntegers.next() % 5 + 2);
|
||||||
|
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
@ -161,35 +159,11 @@ class GameLogicTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGame() {
|
void testGame() {
|
||||||
GameInstance game = new GameInstance(partyConfig, characterConfig, scenarioConfig);
|
GameInstance server = new GameInstance(partyConfig, characterConfig, scenarioConfig);
|
||||||
|
|
||||||
ArrayList<Event> result = game.startGame(player1Selection, player2Selection);
|
server.startGame(player1Selection, player2Selection);
|
||||||
|
|
||||||
assertTrue(result.size() > 0, "Start game should return at least one event");
|
System.out.println(server.toString());
|
||||||
|
|
||||||
Event actual = result.get(0);
|
|
||||||
|
|
||||||
assertEquals(EventType.GamestateEvent, actual.type, "First event should be a GameStateEvent");
|
|
||||||
|
|
||||||
System.out.println(game.toString());
|
|
||||||
|
|
||||||
game.applyEvents(GameLogic.spawnThanos(game.getState()));
|
|
||||||
|
|
||||||
System.out.println(game.toString());
|
|
||||||
|
|
||||||
NPC thanos = (NPC)game.state.getEntities().findEntity(new EntityID(EntityType.NPC, 2));
|
|
||||||
|
|
||||||
game.applyEvents(GameLogic.handleThanos(game.getState(), thanos));
|
|
||||||
|
|
||||||
System.out.println(game.toString());
|
|
||||||
|
|
||||||
game.applyEvents(GameLogic.handleThanos(game.getState(), thanos));
|
|
||||||
|
|
||||||
System.out.println(game.toString());
|
|
||||||
|
|
||||||
game.applyEvents(GameLogic.handleThanos(game.getState(), thanos));
|
|
||||||
|
|
||||||
System.out.println(game.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user