Compare commits
3 Commits
3ae3f152ad
...
0df30cce57
Author | SHA1 | Date |
---|---|---|
j | 0df30cce57 | |
j | b437d518c9 | |
j | 203cba4a3e |
|
@ -1,6 +1,8 @@
|
|||
import GameState, { DEATH_REASON_ENUM, PHASE_ENUM } from './gameState';
|
||||
import { MessageService, MessageFileName } from '../utils/MessageService'
|
||||
import { CommentPoster } from '../rdrama/services/CommentPoster';
|
||||
import { RidersPhase } from './phases/riders';
|
||||
import { HuntPhase } from './phases/hunt';
|
||||
|
||||
class GameFlow {
|
||||
gameState: GameState;
|
||||
|
@ -33,11 +35,11 @@ class GameFlow {
|
|||
break;
|
||||
case PHASE_ENUM.HUNT:
|
||||
// Handle hunting logic
|
||||
await this.handleHunt(userInput);
|
||||
await HuntPhase.handleHunt(this.gameState, this, userInput);
|
||||
break;
|
||||
case PHASE_ENUM.RIDERS_ATTACK:
|
||||
// Handle a riders attack phase
|
||||
await this.handleRidersAttack(userInput);
|
||||
await RidersPhase.handleRidersAttack(this.gameState, this, userInput);
|
||||
break;
|
||||
case PHASE_ENUM.EVENT:
|
||||
// Handle random events that can occur
|
||||
|
@ -517,185 +519,6 @@ class GameFlow {
|
|||
this.executeCurrentPhase();
|
||||
}
|
||||
|
||||
|
||||
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 0: //Initial Logic
|
||||
// Check for random encounter
|
||||
// Calculate a factor based on total mileage to adjust encounter likelihood.
|
||||
const mileageFactor = this.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) {
|
||||
this.gameState.phase = PHASE_ENUM.EVENT;
|
||||
this.gameState.save();
|
||||
return this.executeCurrentPhase();
|
||||
}
|
||||
this.gameState.hostileRiders = false;
|
||||
if (Math.random() < 0.8) this.gameState.hostileRiders = true;
|
||||
responseMessage += `RIDERS AHEAD. THEY`
|
||||
if (!this.gameState.hostileRiders) responseMessage += ` DON'T`
|
||||
responseMessage += ` LOOK HOSTILE`;
|
||||
responseMessage += "\n\nTACTICS\n(1) RUN\n(2) ATTACK\n(3) CONTINUE\n(4) CIRCLE WAGONS";
|
||||
|
||||
this.gameState.tacticsChoiceWhenAttacked = 0
|
||||
this.gameState.lastPrompt = responseMessage;
|
||||
this.gameState.subPhase = 1;
|
||||
this.gameState.save();
|
||||
await this.statusUpdate(responseMessage);
|
||||
break;
|
||||
case 1: // Choice
|
||||
if (!userInput || isNaN(Number(userInput)) || +userInput < 1 && +userInput > 4) {
|
||||
|
||||
responseMessage = "Invalid input. Please enter a number between 1-4.\n\n";
|
||||
responseMessage += this.gameState.lastPrompt;
|
||||
await this.statusUpdate(responseMessage);
|
||||
return;
|
||||
}
|
||||
// Convert to integer in case it's not
|
||||
this.gameState.tacticsChoiceWhenAttacked = Math.floor(+userInput);
|
||||
// Random chance to flip hostility
|
||||
if (Math.random() > 0.2) this.gameState.hostileRiders = !this.gameState.hostileRiders;
|
||||
|
||||
// Handle tactics choice
|
||||
switch (this.gameState.tacticsChoiceWhenAttacked) {
|
||||
case 1: // RUN
|
||||
this.gameState.totalMileageWholeTrip += this.gameState.hostileRiders ? 20 : 15;
|
||||
this.gameState.amountSpentOnAnimals -= this.gameState.hostileRiders ? 40 : 10;
|
||||
this.gameState.amountSpentOnMiscellaneousSupplies -= this.gameState.hostileRiders ? 15 : 0;
|
||||
this.gameState.amountSpentOnAmmunition -= this.gameState.hostileRiders ? 150 : 0;
|
||||
|
||||
this.gameState.phase = PHASE_ENUM.EVENT;
|
||||
this.gameState.subPhase = 0;
|
||||
this.gameState.save();
|
||||
return this.executeCurrentPhase();
|
||||
case 2: // ATTACK
|
||||
this.gameState.subPhase = 2;
|
||||
this.gameState.save()
|
||||
return this.executeCurrentPhase()
|
||||
case 3: // CONTINUE
|
||||
if (this.gameState.hostileRiders) {
|
||||
//Penalize lost initiative if riders are hostile
|
||||
this.gameState.lastPrompt = "You continue on cautiously, keeping your guard up. THE RIDERS ATTACK!\n\n";
|
||||
this.gameState.totalMileageWholeTrip -= 5;
|
||||
this.gameState.amountSpentOnAmmunition -= 100;
|
||||
this.gameState.subPhase = 2;
|
||||
this.gameState.save()
|
||||
return this.executeCurrentPhase()
|
||||
}
|
||||
// No additional action if riders are friendly
|
||||
this.gameState.lastPrompt = "The riders continue on their way without incident.\n\n";
|
||||
this.gameState.phase = PHASE_ENUM.EVENT;
|
||||
this.gameState.subPhase = 0;
|
||||
this.gameState.save();
|
||||
return this.executeCurrentPhase();
|
||||
case 4: // CIRCLE WAGONS
|
||||
if (!this.gameState.hostileRiders) {
|
||||
this.gameState.totalMileageWholeTrip -= 20;
|
||||
this.gameState.lastPrompt = "You formed a defensive circle with your wagons. The riders continue on their way without incident.\n\n";
|
||||
this.gameState.phase = PHASE_ENUM.EVENT;
|
||||
this.gameState.subPhase = 0;
|
||||
this.gameState.save();
|
||||
return this.executeCurrentPhase()
|
||||
}
|
||||
this.gameState.subPhase = 4;
|
||||
this.gameState.lastPrompt = "You formed a defensive circle with your wagons.THE RIDERS ATTACK!\n\n"
|
||||
this.gameState.save()
|
||||
return this.executeCurrentPhase()
|
||||
default:
|
||||
// Handle unexpected input (should be unreachable due to prior validation)
|
||||
console.log("Unexpected tactics choice.");
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private async handleHunt(userInput?: string | number): Promise<void> {
|
||||
// Logic for the hunt phase, determining success based on gameState attributes
|
||||
let responseMessage = "";
|
||||
if (!userInput || userInput.toString().toLowerCase() === "start") {
|
||||
responseMessage += this.handleShooting()
|
||||
await this.statusUpdate(responseMessage)
|
||||
await this.gameState.save();
|
||||
} else {
|
||||
responseMessage += this.handleShooting(userInput.toString());
|
||||
if (this.gameState.shootResponseTime <= 1) {
|
||||
responseMessage += `RIGHT BETWEEN THE EYES---YOU GOT A BIG ONE!!!!\n\n`
|
||||
responseMessage += `FULL BELLIES TONIGHT!\n\n`
|
||||
this.gameState.amountSpentOnFood += 52 + (Math.random() * 6)
|
||||
this.gameState.amountSpentOnAmmunition -= 10 - (Math.random() * 4)
|
||||
} else if (100 * Math.random() > (13 * this.gameState.shootResponseTime)) {
|
||||
responseMessage += `NICE SHOT--RIGHT ON TARGET--GOOD EATIN' TONIGHT!!\n\n`
|
||||
this.gameState.amountSpentOnFood += 48 - (2 * this.gameState.shootResponseTime)
|
||||
this.gameState.amountSpentOnAmmunition -= 10 - (3 * this.gameState.shootResponseTime)
|
||||
} else {
|
||||
responseMessage += `Better luck next time! Maybe practice your aim some more.\n\n`
|
||||
this.gameState.amountSpentOnAmmunition -= 50
|
||||
}
|
||||
this.gameState.lastPrompt = responseMessage;
|
||||
this.gameState.phase = PHASE_ENUM.ACTION_CHOICE;
|
||||
await this.gameState.save();
|
||||
await this.executeCurrentPhase();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private async handleEncounter(): Promise<void> {
|
||||
// Logic for handling encounters
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
import GameState, { PHASE_ENUM } from '../gameState';
|
||||
import GameFlow from '../gameFlow';
|
||||
|
||||
export class HuntPhase {
|
||||
static async handleHunt(gameState: GameState, gameFlow: GameFlow, userInput?: string): Promise<void> {
|
||||
switch (gameState.subPhase) {
|
||||
case 0: // Initial Logic
|
||||
await HuntPhase.initialLogic(gameState, gameFlow);
|
||||
break;
|
||||
case 1: // Shooting Logic
|
||||
await HuntPhase.shootingLogic(gameState, gameFlow, userInput);
|
||||
break;
|
||||
case 2: // Outcome Logic
|
||||
await HuntPhase.outcomeLogic(gameState, gameFlow);
|
||||
break;
|
||||
default:
|
||||
console.error("Unknown subphase in HuntPhase");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static async initialLogic(gameState: GameState, gameFlow: GameFlow,): Promise<void> {
|
||||
let responseMessage = '';
|
||||
responseMessage += gameFlow.handleShooting();
|
||||
gameState.subPhase = 1;
|
||||
gameState.lastPrompt = responseMessage;
|
||||
await gameFlow.statusUpdate(responseMessage);
|
||||
await gameState.save();
|
||||
}
|
||||
|
||||
static async shootingLogic(gameState: GameState, gameFlow: GameFlow, userInput?: string): Promise<void> {
|
||||
let responseMessage = '';
|
||||
if (!userInput) {
|
||||
responseMessage = "Invalid input.\n\n";
|
||||
responseMessage += gameState.lastPrompt;
|
||||
await gameFlow.statusUpdate(responseMessage);
|
||||
return;
|
||||
}
|
||||
if (userInput.toLowerCase() === "start") {
|
||||
responseMessage += gameState.lastPrompt;
|
||||
await gameFlow.statusUpdate(responseMessage);
|
||||
return;
|
||||
}
|
||||
responseMessage += gameFlow.handleShooting(userInput.toString());
|
||||
gameState.lastPrompt = responseMessage;
|
||||
gameState.subPhase = 2;
|
||||
await gameState.save();
|
||||
await gameFlow.executeCurrentPhase();
|
||||
return;
|
||||
}
|
||||
|
||||
static async outcomeLogic(gameState: GameState, gameFlow: GameFlow): Promise<void> {
|
||||
let responseMessage = gameState.lastPrompt;
|
||||
if (gameState.shootResponseTime <= 1) {
|
||||
responseMessage += `RIGHT BETWEEN THE EYES---YOU GOT A BIG ONE!!!!\n\n`;
|
||||
responseMessage += `FULL BELLIES TONIGHT!\n\n`;
|
||||
gameState.amountSpentOnFood += 52 + (Math.random() * 6);
|
||||
gameState.amountSpentOnAmmunition -= 10 - (Math.random() * 4);
|
||||
} else if (100 * Math.random() > (13 * gameState.shootResponseTime)) {
|
||||
responseMessage += `NICE SHOT--RIGHT ON TARGET--GOOD EATIN' TONIGHT!!\n\n`;
|
||||
gameState.amountSpentOnFood += 48 - (2 * gameState.shootResponseTime);
|
||||
gameState.amountSpentOnAmmunition -= 10 - (3 * gameState.shootResponseTime);
|
||||
} else {
|
||||
responseMessage += `Better luck next time! Maybe practice your aim some more.\n\n`;
|
||||
gameState.amountSpentOnAmmunition -= 50;
|
||||
}
|
||||
gameState.lastPrompt = responseMessage;
|
||||
gameState.phase = PHASE_ENUM.ACTION_CHOICE;
|
||||
gameState.subPhase = 0;
|
||||
await gameState.save();
|
||||
await gameFlow.executeCurrentPhase();
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ export class RidersPhase {
|
|||
gameState.lastPrompt = responseMessage;
|
||||
switch (gameState.subPhase) {
|
||||
case 0: // Initial Logic
|
||||
await RidersPhase.initalLogic(gameState, gameFlow);
|
||||
await RidersPhase.initialLogic(gameState, gameFlow);
|
||||
break;
|
||||
case 1: // Choice Logic
|
||||
await RidersPhase.choiceLogic(gameState, gameFlow, userInput);
|
||||
|
@ -38,6 +38,7 @@ export class RidersPhase {
|
|||
}
|
||||
gameState.lastPrompt = responseMessage;
|
||||
gameState.phase = PHASE_ENUM.EVENT;
|
||||
gameState.subPhase = 0
|
||||
await gameState.save();
|
||||
await gameFlow.executeCurrentPhase();
|
||||
return;
|
||||
|
@ -61,13 +62,14 @@ export class RidersPhase {
|
|||
gameState.totalMileageWholeTrip -= 25
|
||||
gameState.lastPrompt = responseMessage;
|
||||
gameState.phase = PHASE_ENUM.EVENT;
|
||||
gameState.subPhase = 0
|
||||
await gameState.save();
|
||||
await gameFlow.executeCurrentPhase();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static async initalLogic(gameState: GameState, gameFlow: GameFlow): Promise<void> {
|
||||
static async initialLogic(gameState: GameState, gameFlow: GameFlow): Promise<void> {
|
||||
let responseMessage = '';
|
||||
gameState.lastPrompt = responseMessage;
|
||||
// Check for random encounter
|
||||
|
@ -83,6 +85,7 @@ export class RidersPhase {
|
|||
// 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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue