import GameState, { PHASE_ENUM } from '../game/gameState'; import GameFlow from '../game/gameFlow'; import { HandleShooting } from './shooting'; import { MessageService } from '../utils/MessageService'; 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.initialLogic(gameState, gameFlow); break; case 1: // Choice Logic await RidersPhase.choiceLogic(gameState, gameFlow, userInput); break; case 2: //Fight Logic responseMessage = gameState.lastPrompt responseMessage += HandleShooting.handleShooting(gameState); gameState.lastPrompt = responseMessage gameState.subPhase = 3 await MessageService.statusUpdate(gameState, responseMessage) await gameState.save() break; case 3: //Fight Outcome if (!userInput) { responseMessage = "Invalid input.\n\n" responseMessage += gameState.lastPrompt await MessageService.statusUpdate(gameState, responseMessage) return; } responseMessage += HandleShooting.handleShooting(gameState, userInput.toString()); if (gameState.shootResponseTime <= 1) { responseMessage += `NICE SHOOTING---YOU DROVE THEM OFF!!!\n\n` await MessageService.statusUpdate(gameState, responseMessage) } else if (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` gameState.injuryFlag = true } gameState.lastPrompt = responseMessage; gameState.phase = PHASE_ENUM.EVENT; gameState.subPhase = 0 await gameState.save(); await gameFlow.executeCurrentPhase(); return; case 4: // wagon fight logic responseMessage = gameState.lastPrompt responseMessage += HandleShooting.handleShooting(gameState); gameState.lastPrompt = responseMessage gameState.subPhase = 5 await MessageService.statusUpdate(gameState, responseMessage) await gameState.save() break; case 5: // wagon fight outcome logic if (!userInput) { responseMessage = "Invalid input.\n\n" responseMessage += gameState.lastPrompt await MessageService.statusUpdate(gameState, responseMessage) return; } responseMessage += HandleShooting.handleShooting(gameState, userInput.toString()); gameState.amountSpentOnAmmunition -= gameState.shootResponseTime * 30 - 80 gameState.totalMileageWholeTrip -= 25 gameState.lastPrompt = responseMessage; gameState.phase = PHASE_ENUM.EVENT; gameState.subPhase = 0 await gameState.save(); await gameFlow.executeCurrentPhase(); return; } } static async initialLogic(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.subPhase = 0 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 MessageService.statusUpdate(gameState, responseMessage); } static async choiceLogic(gameState: GameState, gameFlow: GameFlow, userInput?: string): Promise { let 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 MessageService.statusUpdate(gameState, 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) else RidersPhase.friendlyRidersLogic(gameState, gameFlow); } static async hostileRidersLogic(gameState: GameState, gameFlow: GameFlow): Promise { gameState.lastPrompt = ""; switch (gameState.tacticsChoiceWhenAttacked) { case 1: // RUN away gameState.lastPrompt = `You decided to run away from the hostile riders. While you escaped unharmed, the riders stole some of your supplies. \n\n` gameState.totalMileageWholeTrip += 20 gameState.amountSpentOnAnimals -= 40 gameState.amountSpentOnMiscellaneousSupplies -= 15 gameState.amountSpentOnAmmunition -= 150 gameState.phase = PHASE_ENUM.EVENT; gameState.subPhase = 0; gameState.save(); return gameFlow.executeCurrentPhase(); case 2: // ATTACK gameState.lastPrompt = "You decide to attack the hostile riders.\n\n"; gameState.subPhase = 2; gameState.save() return gameFlow.executeCurrentPhase() 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"; gameState.totalMileageWholeTrip -= 5; gameState.amountSpentOnAmmunition -= 100; gameState.subPhase = 2; gameState.save() return gameFlow.executeCurrentPhase() 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() default: // Handle unexpected input (should be unreachable due to prior validation) console.log("Unexpected tactics choice."); break; } } static async friendlyRidersLogic(gameState: GameState, gameFlow: GameFlow): Promise { gameState.lastPrompt = ""; switch (gameState.tacticsChoiceWhenAttacked) { case 1: // RUN Away gameState.lastPrompt = "You run away from the friendly riders. They watch you go, confused but unharmed.\n\n"; gameState.totalMileageWholeTrip += 15; gameState.amountSpentOnAnimals -= 10; gameState.amountSpentOnMiscellaneousSupplies -= 0; gameState.amountSpentOnAmmunition -= 0; gameState.phase = PHASE_ENUM.EVENT; gameState.subPhase = 0; gameState.save(); return gameFlow.executeCurrentPhase(); 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() 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(); 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() default: // Handle unexpected input (should be unreachable due to prior validation) console.log("Unexpected tactics choice."); break; } } }