last commit from radzathan

main
Mari 4 months ago
parent 9328ec2f74
commit c1963f6f10
  1. 18
      src/game/gameEvent.ts
  2. 57
      src/game/handleEvent.ts

@ -131,6 +131,8 @@ export interface OutgoingBaseTargetedEvent extends OutgoingBaseEvent {
| OutgoingEventType.StartRoll
| OutgoingEventType.StartTurn
| OutgoingEventType.StartRound
| OutgoingEventType.FailTurn
| OutgoingEventType.AbandonTurn
readonly target: PlayerSide
}
@ -140,6 +142,8 @@ export interface OutgoingSimpleTargetedEvent extends OutgoingBaseTargetedEvent {
| OutgoingEventType.StartTurn
| OutgoingEventType.StartRound
| OutgoingEventType.PassTurn
| OutgoingEventType.FailTurn
| OutgoingEventType.AbandonTurn
}
export interface OutgoingDamageEvent extends OutgoingBaseTargetedEvent {
@ -172,16 +176,20 @@ export type OutgoingEvent =
| OutgoingStartRollEvent
| OutgoingScoreDiceEvent
export interface BaseEventResult<T> {
readonly newState: T
export enum EventResultClass {
SUCCESS = 'success',
FAILURE = 'failure',
}
export interface SuccessResult<T> extends BaseEventResult<T> {
export interface SuccessResult<T> {
readonly type: EventResultClass.SUCCESS
readonly newState: T
readonly events: readonly OutgoingEvent[]
}
export interface FailedResult<T> extends BaseEventResult<T> {
export interface FailedResult {
readonly type: EventResultClass.FAILURE
readonly error: GameError
}
export type EventResult<T> = SuccessResult<T> | FailedResult<T>
export type EventResult<T> = SuccessResult<T> | FailedResult

@ -1,4 +1,12 @@
import { ErrorType, EventResult, IncomingEvent, IncomingEventType, OutgoingEventType } from './gameEvent'
import {
ErrorType,
EventResult,
EventResultClass,
IncomingEvent,
IncomingEventType,
OutgoingEvent,
OutgoingEventType,
} from './gameEvent'
import { GamePhase, GameState, oppositePlayer, PlayerSide, PlayerState, RoundStarter } from './gameState'
import {
DieFace,
@ -41,7 +49,7 @@ export function handleEvent(state: GameState, event: IncomingEvent): EventResult
return handleAbortEvent<GameState>(state, event)
default:
return {
newState: state,
type: EventResultClass.FAILURE,
error: {
type: ErrorType.UnexpectedError,
message: 'Event type not yet implemented',
@ -50,7 +58,7 @@ export function handleEvent(state: GameState, event: IncomingEvent): EventResult
}
} catch (e) {
return {
newState: state,
type: EventResultClass.FAILURE,
error: {
type: ErrorType.UnexpectedError,
message: `Failed handling event: ${e}`,
@ -73,23 +81,24 @@ export function handleSelectActionEvent<T extends SelectActionState<unknown>>(
): EventResult<T> {
if (state.gamePhase !== GamePhase.ROUND_START) {
return {
type: EventResultClass.FAILURE,
error: {
type: ErrorType.NotValidRightNow,
message: `You can only change actions when the turn has not started yet.`,
},
newState: state,
}
}
if (index < 0 || index >= state.theme.actions.length || index !== Math.floor(index)) {
return {
type: EventResultClass.FAILURE,
error: {
type: ErrorType.InvalidIndex,
message: `Select an integer action index between 0 (inclusive) and ${state.theme.actions.length} (exclusive)`,
},
newState: state,
}
}
return {
type: EventResultClass.SUCCESS,
newState: {
...state,
action: state.theme.actions[index],
@ -109,16 +118,16 @@ export function handleToggleSelectIndexEvent<D extends { readonly state: DieStat
): EventResult<T> {
if (state.gamePhase !== GamePhase.TURN_ROLLED) {
return {
type: EventResultClass.FAILURE,
error: {
type: ErrorType.NotValidRightNow,
message: `You can only toggle the selected state of a die when dice have been rolled.`,
},
newState: state,
}
}
if (!isValidIndex(index, state.lastRoll.length)) {
return {
newState: state,
type: EventResultClass.FAILURE,
error: {
type: ErrorType.InvalidIndex,
message: `Select an integer action index between 0 (inclusive) and ${state.lastRoll.length} (exclusive)`,
@ -126,6 +135,7 @@ export function handleToggleSelectIndexEvent<D extends { readonly state: DieStat
}
}
return {
type: EventResultClass.SUCCESS,
newState: {
...state,
lastRoll: [
@ -147,14 +157,15 @@ function handleSelectAllEvent<D extends { readonly state: DieState }, T extends
): EventResult<T> {
if (state.gamePhase !== GamePhase.TURN_ROLLED) {
return {
type: EventResultClass.FAILURE,
error: {
type: ErrorType.NotValidRightNow,
message: `You can only change the selected state of the dice when dice have been rolled.`,
},
newState: state,
}
}
return {
type: EventResultClass.SUCCESS,
newState: {
...state,
lastRoll: state.lastRoll.map<D>((x) => ({
@ -172,14 +183,15 @@ function handleHoldDiceEvent<D extends { readonly state: DieState }, T extends D
): EventResult<T> {
if (state.gamePhase !== GamePhase.TURN_ROLLED) {
return {
type: EventResultClass.FAILURE,
error: {
type: ErrorType.NotValidRightNow,
message: `You can only toggle the hold state of dice when dice have been rolled.`,
},
newState: state,
}
}
return {
type: EventResultClass.SUCCESS,
newState: {
...state,
lastRoll: state.lastRoll.map<D>((v) => {
@ -249,11 +261,11 @@ export interface EndTurnState<P extends EndTurnPlayer> {
function handleEndTurnEvent<P extends EndTurnPlayer, T extends EndTurnState<P>>(state: T): EventResult<T> {
if (state.gamePhase !== GamePhase.TURN_ROLLED && state.gamePhase !== GamePhase.TURN_FAILED) {
return {
type: EventResultClass.FAILURE,
error: {
type: ErrorType.NotValidRightNow,
message: `You can only end your turn when it's in progress.`,
},
newState: state,
}
}
const failed = state.gamePhase === GamePhase.TURN_FAILED || !state.currentDiceEndTurn
@ -262,6 +274,7 @@ function handleEndTurnEvent<P extends EndTurnPlayer, T extends EndTurnState<P>>(
// The winner of this round has not yet been decided; this is better than the last turn this round.
// Moving on to the next turn...
return {
type: EventResultClass.SUCCESS,
newState: {
...state,
lastTurnTotal: state.currentTurnTotal,
@ -324,7 +337,12 @@ function handleEndTurnEvent<P extends EndTurnPlayer, T extends EndTurnState<P>>(
newPhase === GamePhase.VICTORY
? oppositePlayer(state.phaseOwner)
: determineNextRoundStarter(state, state.difficulty)
const events: OutgoingEvent[] = []
const endRoundEvent =
state.gamePhase === GamePhase.TURN_FAILED ? OutgoingEventType.FailTurn : OutgoingEventType.AbandonTurn
return {
type: EventResultClass.SUCCESS,
newState: {
...state,
players,
@ -338,7 +356,24 @@ function handleEndTurnEvent<P extends EndTurnPlayer, T extends EndTurnState<P>>(
countedFails: 0,
selectedDiceValue: 0,
},
events: [],
events: [
{
type: OutgoingEventType.PassTurn,
target: state.phaseOwner,
},
...(newPhase === GamePhase.VICTORY
? []
: [
{
type: endRoundEvent,
target: state.phaseOwner,
},
{
type: OutgoingEventType.StartRound,
target: newRoundOwner,
},
]),
],
}
}
}

Loading…
Cancel
Save