Refactored gameflow to a static method, Updated All code. Refactored existing phases to seperate classes
parent
399fdfbe38
commit
8b630c45c9
|
@ -3,224 +3,88 @@ import { MessageService, MessageFileName } from '../utils/MessageService'
|
|||
import { CommentPoster } from '../rdrama/services/CommentPoster';
|
||||
import { RidersPhase } from '../phases/riders';
|
||||
import { HuntPhase } from '../phases/hunt';
|
||||
import { HandleSetup } from '../phases/setup';
|
||||
import { HandleSetup as SetupPhase } from '../phases/setup';
|
||||
import { travelPhase as TravelPhase } from '../phases/travel';
|
||||
import { ActionPhase } from '../phases/action';
|
||||
|
||||
class GameFlow {
|
||||
gameState: GameState;
|
||||
|
||||
constructor(gameState: GameState) {
|
||||
this.gameState = gameState;
|
||||
}
|
||||
static async executeCurrentPhase(gameState: GameState, userInput?: string) {
|
||||
GameFlow.cleanupGameState(gameState);
|
||||
|
||||
async executeCurrentPhase(userInput?: string) {
|
||||
this.cleanupGameState();
|
||||
|
||||
switch (this.gameState.phase) {
|
||||
switch (gameState.phase) {
|
||||
case PHASE_ENUM.SETUP:
|
||||
// Handle the setup phase, e.g., initial purchases
|
||||
await HandleSetup.handleSetupPhase(this.gameState, this, userInput);
|
||||
await SetupPhase.handleSetupPhase(gameState, userInput);
|
||||
break;
|
||||
case PHASE_ENUM.START_TURN:
|
||||
await this.startTurn();
|
||||
await GameFlow.startTurn(gameState);
|
||||
break;
|
||||
case PHASE_ENUM.ACTION_CHOICE:
|
||||
await this.actionChoice(userInput)
|
||||
await ActionPhase.actionChoice(gameState, userInput)
|
||||
break;
|
||||
case PHASE_ENUM.TRAVEL:
|
||||
// Handle travel logic
|
||||
await this.handleTravel();
|
||||
await TravelPhase.handleTravel(gameState, userInput);
|
||||
break;
|
||||
case PHASE_ENUM.FORT:
|
||||
// Handle interactions at the fort
|
||||
await HandleSetup.handleSetupPhase(this.gameState, this, userInput);
|
||||
await SetupPhase.handleSetupPhase(gameState, userInput);
|
||||
break;
|
||||
case PHASE_ENUM.HUNT:
|
||||
// Handle hunting logic
|
||||
await HuntPhase.handleHunt(this.gameState, this, userInput);
|
||||
await HuntPhase.handleHunt(gameState, userInput);
|
||||
break;
|
||||
case PHASE_ENUM.RIDERS_ATTACK:
|
||||
// Handle a riders attack phase
|
||||
await RidersPhase.handleRidersAttack(this.gameState, this, userInput);
|
||||
await RidersPhase.handleRidersAttack(gameState, userInput);
|
||||
break;
|
||||
case PHASE_ENUM.EVENT:
|
||||
// Handle random events that can occur
|
||||
await this.handleRandomEvent();
|
||||
break;
|
||||
case PHASE_ENUM.MOUNTAIN:
|
||||
// Handle mountain traversal challenges
|
||||
await this.handleMountain();
|
||||
break;
|
||||
case PHASE_ENUM.DEATH:
|
||||
// Check if conditions leading to the player's death have been met
|
||||
|
||||
break;
|
||||
default:
|
||||
console.error("Unknown game phase:", this.gameState.phase);
|
||||
console.error("Unknown game phase:", gameState.phase);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private cleanupGameState(): void {
|
||||
static cleanupGameState(gameState: GameState): void {
|
||||
// Ensure all expenditures are non-negative
|
||||
this.gameState.amountSpentOnFood = Math.max(0, this.gameState.amountSpentOnFood);
|
||||
this.gameState.amountSpentOnAmmunition = Math.max(0, this.gameState.amountSpentOnAmmunition);
|
||||
this.gameState.amountSpentOnClothing = Math.max(0, this.gameState.amountSpentOnClothing);
|
||||
this.gameState.amountSpentOnMiscellaneousSupplies = Math.max(0, this.gameState.amountSpentOnMiscellaneousSupplies);
|
||||
gameState.amountSpentOnFood = Math.max(0, gameState.amountSpentOnFood);
|
||||
gameState.amountSpentOnAmmunition = Math.max(0, gameState.amountSpentOnAmmunition);
|
||||
gameState.amountSpentOnClothing = Math.max(0, gameState.amountSpentOnClothing);
|
||||
gameState.amountSpentOnMiscellaneousSupplies = Math.max(0, gameState.amountSpentOnMiscellaneousSupplies);
|
||||
|
||||
// Round expenditures and cash to integers
|
||||
this.gameState.amountSpentOnFood = Math.floor(this.gameState.amountSpentOnFood);
|
||||
this.gameState.amountSpentOnAmmunition = Math.floor(this.gameState.amountSpentOnAmmunition);
|
||||
this.gameState.amountSpentOnClothing = Math.floor(this.gameState.amountSpentOnClothing);
|
||||
this.gameState.amountSpentOnMiscellaneousSupplies = Math.floor(this.gameState.amountSpentOnMiscellaneousSupplies);
|
||||
this.gameState.totalMileageWholeTrip = Math.floor(this.gameState.totalMileageWholeTrip);
|
||||
gameState.amountSpentOnFood = Math.floor(gameState.amountSpentOnFood);
|
||||
gameState.amountSpentOnAmmunition = Math.floor(gameState.amountSpentOnAmmunition);
|
||||
gameState.amountSpentOnClothing = Math.floor(gameState.amountSpentOnClothing);
|
||||
gameState.amountSpentOnMiscellaneousSupplies = Math.floor(gameState.amountSpentOnMiscellaneousSupplies);
|
||||
gameState.totalMileageWholeTrip = Math.floor(gameState.totalMileageWholeTrip);
|
||||
//Round Cash to two digits
|
||||
this.gameState.cashLeftAfterInitialPurchases = Math.floor(this.gameState.cashLeftAfterInitialPurchases * 100) / 100;
|
||||
gameState.cashLeftAfterInitialPurchases = Math.floor(gameState.cashLeftAfterInitialPurchases * 100) / 100;
|
||||
}
|
||||
|
||||
private async startTurn(): Promise<void> {
|
||||
static async startTurn(gameState: GameState): Promise<void> {
|
||||
// Update total mileage up through the previous turn
|
||||
this.gameState.totalMileageUpThroughPreviousTurn = this.gameState.totalMileageWholeTrip;
|
||||
gameState.totalMileageUpThroughPreviousTurn = gameState.totalMileageWholeTrip;
|
||||
|
||||
// Toggle fort option flag
|
||||
this.gameState.fortOptionFlag = !this.gameState.fortOptionFlag;
|
||||
gameState.fortOptionFlag = !gameState.fortOptionFlag;
|
||||
|
||||
this.gameState.phase = PHASE_ENUM.ACTION_CHOICE;
|
||||
await this.gameState.save()
|
||||
gameState.phase = PHASE_ENUM.ACTION_CHOICE;
|
||||
await gameState.save()
|
||||
|
||||
this.executeCurrentPhase()
|
||||
}
|
||||
|
||||
private async actionChoice(userInput?: string): Promise<void> {
|
||||
let responseMessage = "";
|
||||
userInput = userInput?.toLowerCase()
|
||||
console.log("userInput", userInput);
|
||||
switch (userInput) {
|
||||
case "1": // Hunt
|
||||
if (this.gameState.amountSpentOnAmmunition < 40) {
|
||||
responseMessage = `You do not have enough ammunition to hunt. Purchase more ammunition first.\n\n`;
|
||||
if (this.gameState.fortOptionFlag) {
|
||||
responseMessage += `Do you want to:\n2. Continue\n3. Stop at the Next Fort\n\n`
|
||||
} else {
|
||||
responseMessage += `Do you want to:\n2. Continue\n\n`
|
||||
}
|
||||
await MessageService.statusUpdate(this.gameState, responseMessage)
|
||||
} else {
|
||||
this.gameState.phase = PHASE_ENUM.HUNT;
|
||||
this.gameState.totalMileageWholeTrip -= 45;
|
||||
await this.gameState.save()
|
||||
this.executeCurrentPhase()
|
||||
}
|
||||
|
||||
return;
|
||||
break;
|
||||
case "2": // Continue
|
||||
this.gameState.phase = PHASE_ENUM.TRAVEL;
|
||||
await this.gameState.save()
|
||||
this.executeCurrentPhase()
|
||||
return;
|
||||
break;
|
||||
case "3": // Stop at the Next Fort (if applicable)
|
||||
if (this.gameState.fortOptionFlag) {
|
||||
this.gameState.subPhase = 2
|
||||
this.gameState.totalMileageWholeTrip -= 45;
|
||||
this.gameState.phase = PHASE_ENUM.FORT;
|
||||
await this.gameState.save()
|
||||
this.executeCurrentPhase()
|
||||
return;
|
||||
} else {
|
||||
responseMessage += "⚠️ There is no fort option available at this time.\n\n"
|
||||
responseMessage += `Do you want to:\n1. Hunt\n2. Continue\n\n`
|
||||
await MessageService.statusUpdate(this.gameState, responseMessage)
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.log("Starting turn...");
|
||||
if (userInput !== undefined || userInput === "" || userInput === "start") {
|
||||
responseMessage += "⚠️ Invalid Selection.\n\n"
|
||||
}
|
||||
//check for illness or injury
|
||||
if (this.gameState.illnessFlag || this.gameState.injuryFlag) {
|
||||
responseMessage += this.handleDoctor();
|
||||
if (this.gameState.phase === PHASE_ENUM.DEATH) {
|
||||
this.executeCurrentPhase()
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Warn the player if food is low
|
||||
if (this.gameState.amountSpentOnFood < 13) {
|
||||
responseMessage += `You only have ${this.gameState.amountSpentOnFood} pounds of food.\n\n YOU'D BETTER DO SOME HUNTING OR BUY FOOD AND SOON!!!!\n\n`;
|
||||
}
|
||||
|
||||
if (this.gameState.fortOptionFlag) {
|
||||
responseMessage += `Do you want to:\n1. Hunt\n2. Continue\n3. Stop at the Next Fort\n\n`
|
||||
} else {
|
||||
responseMessage += `Do you want to:\n1. Hunt\n2. Continue\n\n`
|
||||
}
|
||||
await MessageService.statusUpdate(this.gameState, this.gameState.lastPrompt + responseMessage)
|
||||
this.gameState.lastPrompt = responseMessage;
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private async handleTravel(userInput?: string | number): Promise<void> {
|
||||
let responseMessage = "";
|
||||
|
||||
if (!userInput || userInput?.toString().toLowerCase() === "start") {
|
||||
responseMessage = "DO YOU WANT TO EAT\n(1) POORLY\n(2) MODERATELY\n(3) WELL: ";
|
||||
await MessageService.statusUpdate(this.gameState, responseMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if userInput is a number or can be converted to a valid number
|
||||
if (isNaN(Number(userInput))) {
|
||||
responseMessage = "Invalid input. Please enter a number.\n\n"
|
||||
responseMessage += "DO YOU WANT TO EAT\n(1) POORLY\n(2) MODERATELY\n(3) WELL: ";
|
||||
await MessageService.statusUpdate(this.gameState, responseMessage);
|
||||
return; // Exit if input is not a valid number
|
||||
}
|
||||
|
||||
let eatingChoice: number = parseInt(userInput.toString(), 10);
|
||||
|
||||
// Validate eating choice
|
||||
if (eatingChoice < 1 || eatingChoice > 3) {
|
||||
responseMessage = "Invalid choice.\n\n"
|
||||
responseMessage += "DO YOU WANT TO EAT\n(1) POORLY\n(2) MODERATELY\n(3) WELL: ";
|
||||
await MessageService.statusUpdate(this.gameState, responseMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate potential food consumption without updating the game state yet
|
||||
let potentialAmountSpentOnFood = this.gameState.amountSpentOnFood - (8 + 5 * eatingChoice);
|
||||
|
||||
// Check if the potential amount spent on food is negative
|
||||
if (potentialAmountSpentOnFood < 0) {
|
||||
// If it would result in a negative value, inform the user they can't eat that well
|
||||
responseMessage = "YOU CAN'T EAT THAT WELL\n\n";
|
||||
responseMessage += "DO YOU WANT TO EAT\n(1) POORLY\n(2) MODERATELY\n(3) WELL: ";
|
||||
await MessageService.statusUpdate(this.gameState, responseMessage);
|
||||
return; // Exit the method to prevent further execution
|
||||
} else {
|
||||
// If the amount is sufficient, update the game state with the new amount
|
||||
this.gameState.amountSpentOnFood = potentialAmountSpentOnFood;
|
||||
}
|
||||
|
||||
// Calculate total mileage
|
||||
this.gameState.totalMileageWholeTrip += 200 + (this.gameState.amountSpentOnAnimals - 220) / 5 + 10 * Math.random();
|
||||
this.gameState.blizzardFlag = this.gameState.insufficientClothingFlag = false;
|
||||
|
||||
this.gameState.phase = PHASE_ENUM.RIDERS_ATTACK;
|
||||
|
||||
// Save the game state after making changes
|
||||
await this.gameState.save();
|
||||
|
||||
// Continue with the game flow
|
||||
this.executeCurrentPhase();
|
||||
GameFlow.executeCurrentPhase(gameState)
|
||||
}
|
||||
|
||||
private async handleEncounter(): Promise<void> {
|
||||
|
@ -236,29 +100,29 @@ class GameFlow {
|
|||
}
|
||||
|
||||
|
||||
private handleDoctor(): string {
|
||||
static handleDoctor(gameState: GameState): string {
|
||||
let responseMessage: string = ""
|
||||
// Handle illness and injury
|
||||
|
||||
if (this.gameState.illnessFlag && this.gameState.injuryFlag) {
|
||||
if (gameState.illnessFlag && gameState.injuryFlag) {
|
||||
responseMessage += `You were sick and and injured `
|
||||
} else if (this.gameState.illnessFlag) {
|
||||
} else if (gameState.illnessFlag) {
|
||||
responseMessage += `You were sick and `
|
||||
} else {
|
||||
responseMessage += `You were injured and `
|
||||
}
|
||||
this.gameState.cashLeftAfterInitialPurchases -= 20;
|
||||
if (this.gameState.cashLeftAfterInitialPurchases < 0) {
|
||||
if (this.gameState.illnessFlag) this.gameState.death = DEATH_REASON_ENUM.ILLNESS
|
||||
if (this.gameState.injuryFlag) this.gameState.death = DEATH_REASON_ENUM.INJURY
|
||||
this.gameState.phase = PHASE_ENUM.DEATH
|
||||
gameState.cashLeftAfterInitialPurchases -= 20;
|
||||
if (gameState.cashLeftAfterInitialPurchases < 0) {
|
||||
if (gameState.illnessFlag) gameState.death = DEATH_REASON_ENUM.ILLNESS
|
||||
if (gameState.injuryFlag) gameState.death = DEATH_REASON_ENUM.INJURY
|
||||
gameState.phase = PHASE_ENUM.DEATH
|
||||
return "";
|
||||
} else {
|
||||
|
||||
responseMessage += `The Doctors bill was $20\n\n`
|
||||
}
|
||||
this.gameState.injuryFlag = false;
|
||||
this.gameState.illnessFlag = false;
|
||||
gameState.injuryFlag = false;
|
||||
gameState.illnessFlag = false;
|
||||
|
||||
return responseMessage;
|
||||
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
import GameState, { PHASE_ENUM } from '../game/gameState';
|
||||
import GameFlow from '../game/gameFlow';
|
||||
import { MessageService } from '../utils/MessageService';
|
||||
|
||||
export class ActionPhase {
|
||||
static async actionChoice(gameState: GameState, userInput?: string): Promise<void> {
|
||||
let responseMessage = "";
|
||||
userInput = userInput?.toLowerCase()
|
||||
console.log("userInput", userInput);
|
||||
switch (userInput) {
|
||||
case "1": // Hunt
|
||||
if (gameState.amountSpentOnAmmunition < 40) {
|
||||
responseMessage = `You do not have enough ammunition to hunt. Purchase more ammunition first.\n\n`;
|
||||
if (gameState.fortOptionFlag) {
|
||||
responseMessage += `Do you want to:\n2. Continue\n3. Stop at the Next Fort\n\n`
|
||||
} else {
|
||||
responseMessage += `Do you want to:\n2. Continue\n\n`
|
||||
}
|
||||
await MessageService.statusUpdate(gameState, responseMessage)
|
||||
} else {
|
||||
gameState.phase = PHASE_ENUM.HUNT;
|
||||
gameState.totalMileageWholeTrip -= 45;
|
||||
await gameState.save()
|
||||
GameFlow.executeCurrentPhase(gameState)
|
||||
}
|
||||
|
||||
return;
|
||||
break;
|
||||
case "2": // Continue
|
||||
gameState.phase = PHASE_ENUM.TRAVEL;
|
||||
await gameState.save()
|
||||
GameFlow.executeCurrentPhase(gameState)
|
||||
return;
|
||||
break;
|
||||
case "3": // Stop at the Next Fort (if applicable)
|
||||
if (gameState.fortOptionFlag) {
|
||||
gameState.subPhase = 2
|
||||
gameState.totalMileageWholeTrip -= 45;
|
||||
gameState.phase = PHASE_ENUM.FORT;
|
||||
await gameState.save()
|
||||
GameFlow.executeCurrentPhase(gameState)
|
||||
return;
|
||||
} else {
|
||||
responseMessage += "⚠️ There is no fort option available at this time.\n\n"
|
||||
responseMessage += `Do you want to:\n1. Hunt\n2. Continue\n\n`
|
||||
await MessageService.statusUpdate(gameState, responseMessage)
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.log("Starting turn...");
|
||||
if (userInput !== undefined || userInput === "" || userInput === "start") {
|
||||
responseMessage += "⚠️ Invalid Selection.\n\n"
|
||||
}
|
||||
//check for illness or injury
|
||||
if (gameState.illnessFlag || gameState.injuryFlag) {
|
||||
responseMessage += GameFlow.handleDoctor(gameState);
|
||||
if (gameState.phase === PHASE_ENUM.DEATH) {
|
||||
GameFlow.executeCurrentPhase(gameState)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Warn the player if food is low
|
||||
if (gameState.amountSpentOnFood < 13) {
|
||||
responseMessage += `You only have ${gameState.amountSpentOnFood} pounds of food.\n\n YOU'D BETTER DO SOME HUNTING OR BUY FOOD AND SOON!!!!\n\n`;
|
||||
}
|
||||
|
||||
if (gameState.fortOptionFlag) {
|
||||
responseMessage += `Do you want to:\n1. Hunt\n2. Continue\n3. Stop at the Next Fort\n\n`
|
||||
} else {
|
||||
responseMessage += `Do you want to:\n1. Hunt\n2. Continue\n\n`
|
||||
}
|
||||
await MessageService.statusUpdate(gameState, gameState.lastPrompt + responseMessage)
|
||||
gameState.lastPrompt = responseMessage;
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -4,16 +4,16 @@ import { HandleShooting } from './shooting';
|
|||
import { MessageService } from '../utils/MessageService';
|
||||
|
||||
export class HuntPhase {
|
||||
static async handleHunt(gameState: GameState, gameFlow: GameFlow, userInput?: string): Promise<void> {
|
||||
static async handleHunt(gameState: GameState, userInput?: string): Promise<void> {
|
||||
switch (gameState.subPhase) {
|
||||
case 0: // Initial Logic
|
||||
await HuntPhase.initialLogic(gameState, gameFlow);
|
||||
await HuntPhase.initialLogic(gameState);
|
||||
break;
|
||||
case 1: // Shooting Logic
|
||||
await HuntPhase.shootingLogic(gameState, gameFlow, userInput);
|
||||
await HuntPhase.shootingLogic(gameState, userInput);
|
||||
break;
|
||||
case 2: // Outcome Logic
|
||||
await HuntPhase.outcomeLogic(gameState, gameFlow);
|
||||
await HuntPhase.outcomeLogic(gameState);
|
||||
break;
|
||||
default:
|
||||
console.error("Unknown subphase in HuntPhase");
|
||||
|
@ -22,7 +22,7 @@ export class HuntPhase {
|
|||
}
|
||||
|
||||
|
||||
static async initialLogic(gameState: GameState, gameFlow: GameFlow,): Promise<void> {
|
||||
static async initialLogic(gameState: GameState): Promise<void> {
|
||||
let responseMessage = '';
|
||||
responseMessage += HandleShooting.handleShooting(gameState);
|
||||
gameState.subPhase = 1;
|
||||
|
@ -31,7 +31,7 @@ export class HuntPhase {
|
|||
await gameState.save();
|
||||
}
|
||||
|
||||
static async shootingLogic(gameState: GameState, gameFlow: GameFlow, userInput?: string): Promise<void> {
|
||||
static async shootingLogic(gameState: GameState, userInput?: string): Promise<void> {
|
||||
let responseMessage = '';
|
||||
if (!userInput) {
|
||||
responseMessage = "Invalid input.\n\n";
|
||||
|
@ -48,11 +48,11 @@ export class HuntPhase {
|
|||
gameState.lastPrompt = responseMessage;
|
||||
gameState.subPhase = 2;
|
||||
await gameState.save();
|
||||
await gameFlow.executeCurrentPhase();
|
||||
await GameFlow.executeCurrentPhase(gameState);
|
||||
return;
|
||||
}
|
||||
|
||||
static async outcomeLogic(gameState: GameState, gameFlow: GameFlow): Promise<void> {
|
||||
static async outcomeLogic(gameState: GameState): Promise<void> {
|
||||
let responseMessage = gameState.lastPrompt;
|
||||
if (gameState.shootResponseTime <= 1) {
|
||||
responseMessage += `RIGHT BETWEEN THE EYES---YOU GOT A BIG ONE!!!!\n\n`;
|
||||
|
@ -71,7 +71,7 @@ export class HuntPhase {
|
|||
gameState.phase = PHASE_ENUM.ACTION_CHOICE;
|
||||
gameState.subPhase = 0;
|
||||
await gameState.save();
|
||||
await gameFlow.executeCurrentPhase();
|
||||
await GameFlow.executeCurrentPhase(gameState);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,15 +4,15 @@ import { HandleShooting } from './shooting';
|
|||
import { MessageService } from '../utils/MessageService';
|
||||
|
||||
export class RidersPhase {
|
||||
static async handleRidersAttack(gameState: GameState, gameFlow: GameFlow, userInput?: string): Promise<void> {
|
||||
static async handleRidersAttack(gameState: GameState, userInput?: string): Promise<void> {
|
||||
let responseMessage = '';
|
||||
gameState.lastPrompt = responseMessage;
|
||||
switch (gameState.subPhase) {
|
||||
case 0: // Initial Logic
|
||||
await RidersPhase.initialLogic(gameState, gameFlow);
|
||||
await RidersPhase.initialLogic(gameState);
|
||||
break;
|
||||
case 1: // Choice Logic
|
||||
await RidersPhase.choiceLogic(gameState, gameFlow, userInput);
|
||||
await RidersPhase.choiceLogic(gameState, userInput);
|
||||
break;
|
||||
case 2: //Fight Logic
|
||||
responseMessage = gameState.lastPrompt
|
||||
|
@ -43,7 +43,7 @@ export class RidersPhase {
|
|||
gameState.phase = PHASE_ENUM.EVENT;
|
||||
gameState.subPhase = 0
|
||||
await gameState.save();
|
||||
await gameFlow.executeCurrentPhase();
|
||||
await GameFlow.executeCurrentPhase(gameState);
|
||||
return;
|
||||
case 4: // wagon fight logic
|
||||
responseMessage = gameState.lastPrompt
|
||||
|
@ -67,12 +67,12 @@ export class RidersPhase {
|
|||
gameState.phase = PHASE_ENUM.EVENT;
|
||||
gameState.subPhase = 0
|
||||
await gameState.save();
|
||||
await gameFlow.executeCurrentPhase();
|
||||
await GameFlow.executeCurrentPhase(gameState);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static async initialLogic(gameState: GameState, gameFlow: GameFlow): Promise<void> {
|
||||
static async initialLogic(gameState: GameState): Promise<void> {
|
||||
let responseMessage = '';
|
||||
gameState.lastPrompt = responseMessage;
|
||||
// Check for random encounter
|
||||
|
@ -90,7 +90,7 @@ export class RidersPhase {
|
|||
gameState.phase = PHASE_ENUM.EVENT;
|
||||
gameState.subPhase = 0
|
||||
gameState.save();
|
||||
return gameFlow.executeCurrentPhase();
|
||||
return GameFlow.executeCurrentPhase(gameState);
|
||||
}
|
||||
// If encounter occurs
|
||||
gameState.hostileRiders = false;
|
||||
|
@ -107,7 +107,7 @@ export class RidersPhase {
|
|||
await MessageService.statusUpdate(gameState, responseMessage);
|
||||
}
|
||||
|
||||
static async choiceLogic(gameState: GameState, gameFlow: GameFlow, userInput?: string): Promise<void> {
|
||||
static async choiceLogic(gameState: GameState, userInput?: string): Promise<void> {
|
||||
let responseMessage = '';
|
||||
if (!userInput || isNaN(Number(userInput)) || +userInput < 1 && +userInput > 4) {
|
||||
|
||||
|
@ -121,12 +121,12 @@ export class RidersPhase {
|
|||
// Random chance to flip hostility
|
||||
if (Math.random() > 0.2) gameState.hostileRiders = !gameState.hostileRiders;
|
||||
|
||||
if (gameState.hostileRiders) RidersPhase.hostileRidersLogic(gameState, gameFlow)
|
||||
else RidersPhase.friendlyRidersLogic(gameState, gameFlow);
|
||||
if (gameState.hostileRiders) RidersPhase.hostileRidersLogic(gameState)
|
||||
else RidersPhase.friendlyRidersLogic(gameState);
|
||||
|
||||
}
|
||||
|
||||
static async hostileRidersLogic(gameState: GameState, gameFlow: GameFlow): Promise<void> {
|
||||
static async hostileRidersLogic(gameState: GameState): Promise<void> {
|
||||
gameState.lastPrompt = "";
|
||||
switch (gameState.tacticsChoiceWhenAttacked) {
|
||||
case 1: // RUN away
|
||||
|
@ -139,12 +139,12 @@ export class RidersPhase {
|
|||
gameState.phase = PHASE_ENUM.EVENT;
|
||||
gameState.subPhase = 0;
|
||||
gameState.save();
|
||||
return gameFlow.executeCurrentPhase();
|
||||
return GameFlow.executeCurrentPhase(gameState);
|
||||
case 2: // ATTACK
|
||||
gameState.lastPrompt = "You decide to attack the hostile riders.\n\n";
|
||||
gameState.subPhase = 2;
|
||||
gameState.save()
|
||||
return gameFlow.executeCurrentPhase()
|
||||
return GameFlow.executeCurrentPhase(gameState)
|
||||
case 3: // CONTINUE
|
||||
//Penalize lost initiative if riders are hostile
|
||||
gameState.lastPrompt = "You continue on cautiously, keeping your guard up. THE RIDERS ATTACK!\n\n";
|
||||
|
@ -152,12 +152,12 @@ export class RidersPhase {
|
|||
gameState.amountSpentOnAmmunition -= 100;
|
||||
gameState.subPhase = 2;
|
||||
gameState.save()
|
||||
return gameFlow.executeCurrentPhase()
|
||||
return GameFlow.executeCurrentPhase(gameState)
|
||||
case 4: // CIRCLE WAGONS
|
||||
gameState.subPhase = 4;
|
||||
gameState.lastPrompt = "You formed a defensive circle with your wagons.THE RIDERS ATTACK!\n\n"
|
||||
gameState.save()
|
||||
return gameFlow.executeCurrentPhase()
|
||||
return GameFlow.executeCurrentPhase(gameState)
|
||||
default:
|
||||
// Handle unexpected input (should be unreachable due to prior validation)
|
||||
console.log("Unexpected tactics choice.");
|
||||
|
@ -165,7 +165,7 @@ export class RidersPhase {
|
|||
}
|
||||
}
|
||||
|
||||
static async friendlyRidersLogic(gameState: GameState, gameFlow: GameFlow): Promise<void> {
|
||||
static async friendlyRidersLogic(gameState: GameState): Promise<void> {
|
||||
gameState.lastPrompt = "";
|
||||
switch (gameState.tacticsChoiceWhenAttacked) {
|
||||
case 1: // RUN Away
|
||||
|
@ -178,25 +178,25 @@ export class RidersPhase {
|
|||
gameState.phase = PHASE_ENUM.EVENT;
|
||||
gameState.subPhase = 0;
|
||||
gameState.save();
|
||||
return gameFlow.executeCurrentPhase();
|
||||
return GameFlow.executeCurrentPhase(gameState);
|
||||
case 2: // ATTACK
|
||||
gameState.lastPrompt = "You decide to attack the friendly riders. They flee in confusion\n\n";
|
||||
gameState.subPhase = 2;
|
||||
gameState.save()
|
||||
return gameFlow.executeCurrentPhase()
|
||||
return GameFlow.executeCurrentPhase(gameState)
|
||||
case 3: // CONTINUE
|
||||
gameState.lastPrompt = "The riders share news from up ahead and wish you safe travels. Your party continues on.\n\n";
|
||||
gameState.phase = PHASE_ENUM.EVENT;
|
||||
gameState.subPhase = 0;
|
||||
gameState.save();
|
||||
return gameFlow.executeCurrentPhase();
|
||||
return GameFlow.executeCurrentPhase(gameState);
|
||||
case 4: // CIRCLE WAGONS
|
||||
gameState.totalMileageWholeTrip -= 20;
|
||||
gameState.lastPrompt = "You formed a defensive circle with your wagons. The riders continue on their way without incident.\n\n";
|
||||
gameState.phase = PHASE_ENUM.EVENT;
|
||||
gameState.subPhase = 0;
|
||||
gameState.save();
|
||||
return gameFlow.executeCurrentPhase()
|
||||
return GameFlow.executeCurrentPhase(gameState)
|
||||
|
||||
default:
|
||||
// Handle unexpected input (should be unreachable due to prior validation)
|
||||
|
|
|
@ -3,7 +3,7 @@ import GameFlow from '../game/gameFlow';
|
|||
import { MessageService, MessageFileName } from '../utils/MessageService'
|
||||
|
||||
export class HandleSetup {
|
||||
static async handleSetupPhase(gameState: GameState, gameFlow: GameFlow, userInput?: string): Promise<void> {
|
||||
static async handleSetupPhase(gameState: GameState, userInput?: string): Promise<void> {
|
||||
userInput = userInput?.toLowerCase()
|
||||
let responseMessage = "";
|
||||
// Logic to handle initial setup
|
||||
|
@ -23,7 +23,7 @@ export class HandleSetup {
|
|||
if (purchaseResult.success) {
|
||||
// If the purchase was successful, advance to the next subphase and recursively call handleSetupPhase without userInput to get the next set of instructions
|
||||
gameState.subPhase++;
|
||||
return HandleSetup.handleSetupPhase(gameState, gameFlow);
|
||||
return HandleSetup.handleSetupPhase(gameState);
|
||||
} else {
|
||||
// If there was an error, include the error message in responseMessage
|
||||
responseMessage = `${purchaseResult.errorMessage}`;
|
||||
|
@ -46,7 +46,7 @@ export class HandleSetup {
|
|||
const purchaseResult = HandleSetup.handleGenericPurchase(gameState, PurchaseOption.OXEN, userInput, 200, 300);
|
||||
if (purchaseResult.success) {
|
||||
gameState.subPhase++;
|
||||
return HandleSetup.handleSetupPhase(gameState, gameFlow); // Call setup phase again for next subphase
|
||||
return HandleSetup.handleSetupPhase(gameState); // Call setup phase again for next subphase
|
||||
} else {
|
||||
responseMessage = purchaseResult.errorMessage || '';
|
||||
responseMessage += `\n\n${MessageService.getRandomMessage(
|
||||
|
@ -67,7 +67,7 @@ export class HandleSetup {
|
|||
const purchaseResult = HandleSetup.handleGenericPurchase(gameState, PurchaseOption.FOOD, userInput);
|
||||
if (purchaseResult.success) {
|
||||
gameState.subPhase++;
|
||||
return HandleSetup.handleSetupPhase(gameState, gameFlow); // Call setup phase again for next subphase
|
||||
return HandleSetup.handleSetupPhase(gameState); // Call setup phase again for next subphase
|
||||
} else {
|
||||
responseMessage = purchaseResult.errorMessage || '';
|
||||
responseMessage += `\n\n${MessageService.getRandomMessage(
|
||||
|
@ -88,7 +88,7 @@ export class HandleSetup {
|
|||
const purchaseResult = HandleSetup.handleGenericPurchase(gameState, PurchaseOption.AMMO, userInput);
|
||||
if (purchaseResult.success) {
|
||||
gameState.subPhase++;
|
||||
return HandleSetup.handleSetupPhase(gameState, gameFlow); // Call setup phase again for next subphase
|
||||
return HandleSetup.handleSetupPhase(gameState); // Call setup phase again for next subphase
|
||||
} else {
|
||||
responseMessage = purchaseResult.errorMessage || '';
|
||||
responseMessage += `\n\n${MessageService.getRandomMessage(
|
||||
|
@ -109,7 +109,7 @@ export class HandleSetup {
|
|||
const purchaseResult = HandleSetup.handleGenericPurchase(gameState, PurchaseOption.CLOTHING, userInput);
|
||||
if (purchaseResult.success) {
|
||||
gameState.subPhase++;
|
||||
return HandleSetup.handleSetupPhase(gameState, gameFlow); // Call setup phase again for next subphase
|
||||
return HandleSetup.handleSetupPhase(gameState); // Call setup phase again for next subphase
|
||||
} else {
|
||||
responseMessage = purchaseResult.errorMessage || '';
|
||||
responseMessage += `\n\n${MessageService.getRandomMessage(
|
||||
|
@ -130,7 +130,7 @@ export class HandleSetup {
|
|||
const purchaseResult = HandleSetup.handleGenericPurchase(gameState, PurchaseOption.MISC, userInput);
|
||||
if (purchaseResult.success) {
|
||||
gameState.subPhase++;
|
||||
return HandleSetup.handleSetupPhase(gameState, gameFlow); // Call setup phase again for next subphase
|
||||
return HandleSetup.handleSetupPhase(gameState); // Call setup phase again for next subphase
|
||||
} else {
|
||||
responseMessage = purchaseResult.errorMessage || '';
|
||||
responseMessage += `\n\n${MessageService.getRandomMessage(
|
||||
|
@ -145,7 +145,7 @@ export class HandleSetup {
|
|||
gameState.subPhase = 0;
|
||||
gameState.phase === PHASE_ENUM.SETUP ? gameState.phase = PHASE_ENUM.START_TURN : gameState.phase = PHASE_ENUM.ACTION_CHOICE;
|
||||
await gameState.save()
|
||||
gameFlow.executeCurrentPhase()
|
||||
GameFlow.executeCurrentPhase(gameState)
|
||||
break;
|
||||
default:
|
||||
responseMessage = `@J something went wrong come and fix it.\n\n ${JSON.stringify(gameState, null, 4)}`
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
import GameState, { PHASE_ENUM } from '../game/gameState';
|
||||
import GameFlow from '../game/gameFlow';
|
||||
import { MessageService } from '../utils/MessageService';
|
||||
|
||||
export class travelPhase {
|
||||
static async handleTravel(gameState: GameState, userInput?: string | number): Promise<void> {
|
||||
let responseMessage = "";
|
||||
|
||||
if (!userInput || userInput?.toString().toLowerCase() === "start") {
|
||||
responseMessage = "DO YOU WANT TO EAT\n(1) POORLY\n(2) MODERATELY\n(3) WELL: ";
|
||||
await MessageService.statusUpdate(gameState, responseMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if userInput is a number or can be converted to a valid number
|
||||
if (isNaN(Number(userInput))) {
|
||||
responseMessage = "Invalid input. Please enter a number.\n\n"
|
||||
responseMessage += "DO YOU WANT TO EAT\n(1) POORLY\n(2) MODERATELY\n(3) WELL: ";
|
||||
await MessageService.statusUpdate(gameState, responseMessage);
|
||||
return; // Exit if input is not a valid number
|
||||
}
|
||||
|
||||
let eatingChoice: number = parseInt(userInput.toString(), 10);
|
||||
|
||||
// Validate eating choice
|
||||
if (eatingChoice < 1 || eatingChoice > 3) {
|
||||
responseMessage = "Invalid choice.\n\n"
|
||||
responseMessage += "DO YOU WANT TO EAT\n(1) POORLY\n(2) MODERATELY\n(3) WELL: ";
|
||||
await MessageService.statusUpdate(gameState, responseMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate potential food consumption without updating the game state yet
|
||||
let potentialAmountSpentOnFood = gameState.amountSpentOnFood - (8 + 5 * eatingChoice);
|
||||
|
||||
// Check if the potential amount spent on food is negative
|
||||
if (potentialAmountSpentOnFood < 0) {
|
||||
// If it would result in a negative value, inform the user they can't eat that well
|
||||
responseMessage = "YOU CAN'T EAT THAT WELL\n\n";
|
||||
responseMessage += "DO YOU WANT TO EAT\n(1) POORLY\n(2) MODERATELY\n(3) WELL: ";
|
||||
await MessageService.statusUpdate(gameState, responseMessage);
|
||||
return; // Exit the method to prevent further execution
|
||||
} else {
|
||||
// If the amount is sufficient, update the game state with the new amount
|
||||
gameState.amountSpentOnFood = potentialAmountSpentOnFood;
|
||||
}
|
||||
|
||||
// Calculate total mileage
|
||||
gameState.totalMileageWholeTrip += 200 + (gameState.amountSpentOnAnimals - 220) / 5 + 10 * Math.random();
|
||||
gameState.blizzardFlag = gameState.insufficientClothingFlag = false;
|
||||
|
||||
gameState.phase = PHASE_ENUM.RIDERS_ATTACK;
|
||||
|
||||
// Save the game state after making changes
|
||||
await gameState.save();
|
||||
|
||||
// Continue with the game flow
|
||||
GameFlow.executeCurrentPhase(gameState);
|
||||
}
|
||||
}
|
||||
|
|
@ -18,8 +18,7 @@ class WorkflowOrchestrator {
|
|||
let gameState = await GameState.load(comment)
|
||||
if (parsedComment.command === 'restart') gameState = await gameState.reset();
|
||||
|
||||
const gameFlow = new GameFlow(gameState)
|
||||
await gameFlow.executeCurrentPhase(parsedComment.command)
|
||||
await GameFlow.executeCurrentPhase(gameState, parsedComment.command)
|
||||
await gameState.save()
|
||||
|
||||
} catch (error) {
|
||||
|
|
Loading…
Reference in New Issue