diff --git a/src/game/phases/riders.ts b/src/game/phases/riders.ts new file mode 100644 index 0000000..ce91d2b --- /dev/null +++ b/src/game/phases/riders.ts @@ -0,0 +1,187 @@ +import GameState, { PHASE_ENUM } from '../gameState'; +import GameFlow from '../gameFlow'; +export class RidersPhase { + static async handleRidersAttack(gameState: GameState, gameFlow: GameFlow, userInput?: string): Promise { + let responseMessage = ''; + gameState.lastPrompt = responseMessage; + switch (gameState.subPhase) { + case 0: // Initial Logic + await RidersPhase.initalLogic(gameState, gameFlow); + break; + case 1: // Choice Logic + await RidersPhase.choiceLogic(gameState, gameFlow, userInput); + break; + + } + } + + static async initalLogic(gameState: GameState, gameFlow: GameFlow): Promise { + let responseMessage = ''; + gameState.lastPrompt = responseMessage; + // Check for random encounter + // Calculate a factor based on total mileage to adjust encounter likelihood. + const mileageFactor = gameState.totalMileageWholeTrip / 100 - 4; + + // Calculate the chance of encountering riders, scaling non-linearly with mileage. + const encounterChance = ((mileageFactor ** 2) + 72) / ((mileageFactor ** 2) + 12) - 1; + + // Generate a random factor to determine if an encounter occurs. + const randomFactor = Math.random() * 10; + + // If the random factor exceeds the encounter chance, skip to the next phase. + if (randomFactor > encounterChance) { + gameState.phase = PHASE_ENUM.EVENT; + gameState.save(); + return gameFlow.executeCurrentPhase(); + } + // If encounter occurs + gameState.hostileRiders = false; + if (Math.random() < 0.8) gameState.hostileRiders = true; + responseMessage += `RIDERS AHEAD. THEY` + if (!gameState.hostileRiders) responseMessage += ` DON'T` + responseMessage += ` LOOK HOSTILE`; + responseMessage += "\n\nTACTICS\n(1) RUN\n(2) ATTACK\n(3) CONTINUE\n(4) CIRCLE WAGONS"; + + gameState.tacticsChoiceWhenAttacked = 0 + gameState.lastPrompt = responseMessage; + gameState.subPhase = 1; + gameState.save(); + await gameFlow.statusUpdate(responseMessage); + } + + static async choiceLogic(gameState: GameState, gameFlow: GameFlow, userInput?: string): Promise { + let responseMessage = ''; + gameState.lastPrompt = responseMessage; + if (!userInput || isNaN(Number(userInput)) || +userInput < 1 && +userInput > 4) { + + responseMessage = "Invalid input. Please enter a number between 1-4.\n\n"; + responseMessage += gameState.lastPrompt; + await gameFlow.statusUpdate(responseMessage); + return; + } + // Convert to integer in case it's not + gameState.tacticsChoiceWhenAttacked = Math.floor(+userInput); + // Random chance to flip hostility + if (Math.random() > 0.2) gameState.hostileRiders = !gameState.hostileRiders; + + if (gameState.hostileRiders) RidersPhase.hostileRidersLogic(gameState, gameFlow) + + // Handle tactics choice + switch (gameState.tacticsChoiceWhenAttacked) { + case 1: // RUN + gameState.totalMileageWholeTrip += gameState.hostileRiders ? 20 : 15; + gameState.amountSpentOnAnimals -= gameState.hostileRiders ? 40 : 10; + gameState.amountSpentOnMiscellaneousSupplies -= gameState.hostileRiders ? 15 : 0; + gameState.amountSpentOnAmmunition -= gameState.hostileRiders ? 150 : 0; + + gameState.phase = PHASE_ENUM.EVENT; + gameState.subPhase = 0; + gameState.save(); + return gameFlow.executeCurrentPhase(); + case 2: // ATTACK + gameState.subPhase = 2; + gameState.save() + return gameFlow.executeCurrentPhase() + case 3: // CONTINUE + if (gameState.hostileRiders) { + //Penalize lost initiative if riders are hostile + gameState.lastPrompt = "You continue on cautiously, keeping your guard up. THE RIDERS ATTACK!\n\n"; + gameState.totalMileageWholeTrip -= 5; + gameState.amountSpentOnAmmunition -= 100; + gameState.subPhase = 2; + gameState.save() + return gameFlow.executeCurrentPhase() + } + // No additional action if riders are friendly + gameState.lastPrompt = "The riders continue on their way without incident.\n\n"; + gameState.phase = PHASE_ENUM.EVENT; + gameState.subPhase = 0; + gameState.save(); + return gameFlow.executeCurrentPhase(); + case 4: // CIRCLE WAGONS + if (!gameState.hostileRiders) { + 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() + } + gameState.subPhase = 4; + gameState.lastPrompt = "You formed a defensive circle with your wagons.THE RIDERS ATTACK!\n\n" + gameState.save() + return gameFlow.executeCurrentPhase() + default: + // Handle unexpected input (should be unreachable due to prior validation) + console.log("Unexpected tactics choice."); + break; + } + } + + static async hostileRidersLogic(gameState: GameState, gameFlow: GameFlow): Promise { + + } + +} + + + + + + + + + +private async handleRidersAttack(userInput ?: string | number): Promise < void> { + // Logic for handling a riders attack + let responseMessage = '' + this.gameState.lastPrompt = responseMessage; + + switch(this.gameState.subPhase) { + + + case 1: // Choice + + break; + case 2: // Resolve fight logic + responseMessage = this.gameState.lastPrompt + responseMessage += this.handleShooting() + this.gameState.lastPrompt = responseMessage + this.gameState.subPhase = 3 + await this.statusUpdate(responseMessage) + await this.gameState.save() + break; + case 3: // Resolve fight outcome + if (!userInput) { + responseMessage = "Invalid input.\n\n" + responseMessage += this.gameState.lastPrompt + await this.statusUpdate(responseMessage) + return; + } + responseMessage += this.handleShooting(userInput.toString()); + if (this.gameState.shootResponseTime <= 1) { + responseMessage += `NICE SHOOTING---YOU DROVE THEM OFF!!!\n\n` + await this.statusUpdate(responseMessage) + } else if (this.gameState.shootResponseTime <= 4) { + responseMessage += `KINDA SLOW WITH YOUR GUN\n\n` + } else { + responseMessage += `LOUSY SHOT---YOU GOT KNIFED\nYOU HAVE TO SEE OL' DOC GARY CHESS\n\n` + this.gameState.injuryFlag = true + } + this.gameState.phase = PHASE_ENUM.ACTION_CHOICE; + await this.gameState.save(); + await this.executeCurrentPhase(); + return; + case 4: // Resolve wagon logic + responseMessage = this.gameState.lastPrompt + responseMessage += this.handleShooting() + this.gameState.lastPrompt = responseMessage + this.gameState.subPhase = 5 + await this.statusUpdate(responseMessage) + await this.gameState.save() + break; + case 5: // Resolve wagon outcome + break; +} + +}