208 lines
9.8 KiB
TypeScript
208 lines
9.8 KiB
TypeScript
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, userInput?: string): Promise<void> {
|
|
let responseMessage = '';
|
|
gameState.lastPrompt = responseMessage;
|
|
switch (gameState.subPhase) {
|
|
case 0: // Initial Logic
|
|
await RidersPhase.initialLogic(gameState);
|
|
break;
|
|
case 1: // Choice Logic
|
|
await RidersPhase.choiceLogic(gameState, 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(gameState);
|
|
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(gameState);
|
|
return;
|
|
}
|
|
}
|
|
|
|
static async initialLogic(gameState: GameState): Promise<void> {
|
|
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(gameState);
|
|
}
|
|
// 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, userInput?: string): Promise<void> {
|
|
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)
|
|
else RidersPhase.friendlyRidersLogic(gameState);
|
|
|
|
}
|
|
|
|
static async hostileRidersLogic(gameState: GameState): Promise<void> {
|
|
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(gameState);
|
|
case 2: // ATTACK
|
|
gameState.lastPrompt = "You decide to attack the hostile riders.\n\n";
|
|
gameState.subPhase = 2;
|
|
gameState.save()
|
|
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";
|
|
gameState.totalMileageWholeTrip -= 5;
|
|
gameState.amountSpentOnAmmunition -= 100;
|
|
gameState.subPhase = 2;
|
|
gameState.save()
|
|
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(gameState)
|
|
default:
|
|
// Handle unexpected input (should be unreachable due to prior validation)
|
|
console.log("Unexpected tactics choice.");
|
|
break;
|
|
}
|
|
}
|
|
|
|
static async friendlyRidersLogic(gameState: GameState): Promise<void> {
|
|
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(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(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(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(gameState)
|
|
|
|
default:
|
|
// Handle unexpected input (should be unreachable due to prior validation)
|
|
console.log("Unexpected tactics choice.");
|
|
break;
|
|
}
|
|
}
|
|
}
|