Compare commits
No commits in common. "4d0f4a758909d3c6c05afa1de42d1e80de2e8c84" and "8b630c45c915857f4db5ba9dd8f4e4d8a8d55712" have entirely different histories.
4d0f4a7589
...
8b630c45c9
|
@ -1,125 +1,185 @@
|
|||
import GameFlow from "./gameFlow";
|
||||
import GameState, { PHASE_ENUM } from "./gameState";
|
||||
import GameState from "./gameState";
|
||||
|
||||
export class EventPhase {
|
||||
private static randomEvents: OregonEvent[] = [
|
||||
{
|
||||
name: "Wagon Breakdown",
|
||||
threshold: 10, // Probability weight
|
||||
action: (gameState) => {
|
||||
gameState.totalMileageWholeTrip -= 15;
|
||||
gameState.amountSpentOnMiscellaneousSupplies -= 8;
|
||||
return "Wagon breaks down. Lose time and supplies fixing it.";
|
||||
class GameEvents {
|
||||
private randomEvents: OregonEvent[];
|
||||
private totalThreshold: number;
|
||||
constructor() {
|
||||
// Initialize the events and their thresholds.
|
||||
this.randomEvents = [
|
||||
{
|
||||
name: "Wagon Breakdown",
|
||||
threshold: 10, // Probability weight
|
||||
action: (gameState) => {
|
||||
gameState.totalMileageWholeTrip -= 15;
|
||||
gameState.amountSpentOnMiscellaneousSupplies -= 8;
|
||||
return "Wagon breaks down. Lose time and supplies fixing it.";
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Ox Injures Leg",
|
||||
threshold: 15,
|
||||
action: (gameState) => {
|
||||
gameState.totalMileageWholeTrip -= 25;
|
||||
gameState.amountSpentOnAnimals -= 20;
|
||||
return "Ox injures leg. Slows you down rest of the trip.";
|
||||
{
|
||||
name: "Ox Injures Leg",
|
||||
threshold: 15,
|
||||
action: (gameState) => {
|
||||
gameState.totalMileageWholeTrip -= 25;
|
||||
gameState.amountSpentOnAnimals -= 20;
|
||||
return "Ox injures leg. Slows you down rest of the trip.";
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Daughter Breaks Arm",
|
||||
threshold: 20,
|
||||
action: (gameState) => {
|
||||
gameState.totalMileageWholeTrip -= 5 + Math.floor(Math.random() * 4);
|
||||
gameState.amountSpentOnMiscellaneousSupplies -= 2 + Math.floor(Math.random() * 3);
|
||||
return "Bad luck--your daughter broke her arm. You had to stop and use supplies to make a sling.";
|
||||
{
|
||||
name: "Daughter Breaks Arm",
|
||||
threshold: 20,
|
||||
action: (gameState) => {
|
||||
gameState.totalMileageWholeTrip -= 5 + Math.floor(Math.random() * 4);
|
||||
gameState.amountSpentOnMiscellaneousSupplies -= 2 + Math.floor(Math.random() * 3);
|
||||
return "Bad luck--your daughter broke her arm. You had to stop and use supplies to make a sling.";
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Ox Wanders Off",
|
||||
threshold: 25,
|
||||
action: (gameState) => {
|
||||
gameState.totalMileageWholeTrip -= 17;
|
||||
return "Ox wanders off--spend time looking for it.";
|
||||
{
|
||||
name: "Ox Wanders Off",
|
||||
threshold: 25,
|
||||
action: (gameState) => {
|
||||
gameState.totalMileageWholeTrip -= 17;
|
||||
return "Ox wanders off--spend time looking for it.";
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Son Gets Lost",
|
||||
threshold: 30,
|
||||
action: (gameState) => {
|
||||
gameState.totalMileageWholeTrip -= 10;
|
||||
return "Your son gets lost---spend half the day looking for him.";
|
||||
{
|
||||
name: "Son Gets Lost",
|
||||
threshold: 30,
|
||||
action: (gameState) => {
|
||||
gameState.totalMileageWholeTrip -= 10;
|
||||
return "Your son gets lost---spend half the day looking for him.";
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Unsafe Water",
|
||||
threshold: 35,
|
||||
action: (gameState) => {
|
||||
gameState.totalMileageWholeTrip -= Math.floor(Math.random() * 10) + 2;
|
||||
return "Unsafe water--lose time looking for clean spring.";
|
||||
{
|
||||
name: "Unsafe Water",
|
||||
threshold: 35,
|
||||
action: (gameState) => {
|
||||
gameState.totalMileageWholeTrip -= Math.floor(Math.random() * 10) + 2;
|
||||
return "Unsafe water--lose time looking for clean spring.";
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Heavy Rains",
|
||||
threshold: 40,
|
||||
action: (gameState) => {
|
||||
gameState.amountSpentOnFood -= 10;
|
||||
gameState.amountSpentOnMiscellaneousSupplies -= 15;
|
||||
gameState.totalMileageWholeTrip -= Math.floor(Math.random() * 10) + 5;
|
||||
return "Heavy rains---time and supplies lost.";
|
||||
{
|
||||
name: "Heavy Rains",
|
||||
threshold: 40,
|
||||
action: (gameState) => {
|
||||
gameState.amountSpentOnFood -= 10;
|
||||
gameState.amountSpentOnMiscellaneousSupplies -= 15;
|
||||
gameState.totalMileageWholeTrip -= Math.floor(Math.random() * 10) + 5;
|
||||
return "Heavy rains---time and supplies lost.";
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Fire in Your Wagon",
|
||||
threshold: 45,
|
||||
action: (gameState) => {
|
||||
gameState.amountSpentOnFood -= 40;
|
||||
gameState.amountSpentOnAmmunition -= 400;
|
||||
gameState.amountSpentOnMiscellaneousSupplies -= Math.floor(Math.random() * 8) + 3;
|
||||
gameState.totalMileageWholeTrip -= 15;
|
||||
return "There was a fire in your wagon—food and supplies damaged!";
|
||||
{
|
||||
name: "Fire in Your Wagon",
|
||||
threshold: 45,
|
||||
action: (gameState) => {
|
||||
gameState.amountSpentOnFood -= 40;
|
||||
gameState.amountSpentOnAmmunition -= 400;
|
||||
gameState.amountSpentOnMiscellaneousSupplies -= Math.floor(Math.random() * 8) + 3;
|
||||
gameState.totalMileageWholeTrip -= 15;
|
||||
return "There was a fire in your wagon—food and supplies damaged!";
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Lose Your Way in Heavy Fog",
|
||||
threshold: 50,
|
||||
action: (gameState) => {
|
||||
gameState.totalMileageWholeTrip -= 10 + Math.floor(Math.random() * 5);
|
||||
return "Lose your way in heavy fog—time is lost.";
|
||||
{
|
||||
name: "Lose Your Way in Heavy Fog",
|
||||
threshold: 50,
|
||||
action: (gameState) => {
|
||||
gameState.totalMileageWholeTrip -= 10 + Math.floor(Math.random() * 5);
|
||||
return "Lose your way in heavy fog—time is lost.";
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Wagon Swamped Fording River",
|
||||
threshold: 55,
|
||||
action: (gameState) => {
|
||||
gameState.amountSpentOnFood -= 30;
|
||||
gameState.amountSpentOnClothing -= 20;
|
||||
gameState.totalMileageWholeTrip -= 20 + Math.floor(Math.random() * 20);
|
||||
return "Wagon gets swamped fording river—lose food and clothes.";
|
||||
},
|
||||
}
|
||||
// Add more events here...
|
||||
];
|
||||
{
|
||||
name: "Wagon Swamped Fording River",
|
||||
threshold: 55,
|
||||
action: (gameState) => {
|
||||
gameState.amountSpentOnFood -= 30;
|
||||
gameState.amountSpentOnClothing -= 20;
|
||||
gameState.totalMileageWholeTrip -= 20 + Math.floor(Math.random() * 20);
|
||||
return "Wagon gets swamped fording river—lose food and clothes.";
|
||||
},
|
||||
}
|
||||
// Add more events here...
|
||||
];
|
||||
|
||||
private static totalThreshold: number = EventPhase.randomEvents.reduce((acc, event) => acc + event.threshold, 0);
|
||||
this.totalThreshold = this.randomEvents.reduce((acc, event) => acc + event.threshold, 0);
|
||||
}
|
||||
|
||||
public static async handleRandomEvent(gameState: GameState): Promise<void> {
|
||||
const randomEventNumber = Math.random() * EventPhase.totalThreshold;
|
||||
generateRandomEvent(gameState: GameState): string {
|
||||
const randomEventNumber = Math.random() * this.totalThreshold;
|
||||
let cumulativeThreshold = 0;
|
||||
let responseMessage = "";
|
||||
for (let event of EventPhase.randomEvents) {
|
||||
|
||||
for (let event of this.randomEvents) {
|
||||
cumulativeThreshold += event.threshold;
|
||||
if (randomEventNumber < cumulativeThreshold) {
|
||||
console.log(`Event triggered: ${event.name}`);
|
||||
responseMessage = event.action(gameState);
|
||||
|
||||
return event.action(gameState);
|
||||
}
|
||||
}
|
||||
gameState.lastPrompt = responseMessage;
|
||||
gameState.phase = PHASE_ENUM.MOUNTAIN;
|
||||
gameState.subPhase = 0
|
||||
await gameState.save();
|
||||
await GameFlow.executeCurrentPhase(gameState);
|
||||
return "";
|
||||
}
|
||||
|
||||
mountains(gameState: GameState): string {
|
||||
if (gameState.totalMileageWholeTrip <= 950) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let message = "**🏔️ Mountain Passage 🏔️**\n";
|
||||
let encounter = false;
|
||||
|
||||
let randomFactor = Math.random() * 10;
|
||||
let mountainDifficulty = 9 - ((gameState.totalMileageWholeTrip / 100 - 15) ** 2 + 72) / ((gameState.totalMileageWholeTrip / 100 - 15) ** 2 + 12);
|
||||
|
||||
if (randomFactor > mountainDifficulty) {
|
||||
encounter = true;
|
||||
message += "Rugged mountains make your journey difficult.\n";
|
||||
|
||||
if (Math.random() > 0.1) {
|
||||
gameState.totalMileageWholeTrip -= 60;
|
||||
message += "🔍 You got lost—losing valuable time trying to find the trail!\n";
|
||||
} else if (Math.random() > 0.11) {
|
||||
gameState.amountSpentOnMiscellaneousSupplies -= 5;
|
||||
gameState.amountSpentOnAmmunition -= 200;
|
||||
gameState.totalMileageWholeTrip -= 20 + Math.random() * 30;
|
||||
message += "🛠️ Wagon damaged!—Lose time and supplies.\n";
|
||||
} else {
|
||||
gameState.totalMileageWholeTrip -= 45 + Math.random() / 0.02;
|
||||
message += "🐢 The going gets slow.\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!gameState.clearSouthPassFlag) {
|
||||
gameState.clearSouthPassFlag = true;
|
||||
if (Math.random() < 0.8) {
|
||||
encounter = true;
|
||||
message += "✅ You made it safely through South Pass—no snow.\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (gameState.totalMileageWholeTrip >= 1700 && !gameState.clearBlueMountainsFlag) {
|
||||
gameState.clearBlueMountainsFlag = true;
|
||||
if (Math.random() < 0.7) {
|
||||
encounter = true;
|
||||
gameState.blizzardFlag = true;
|
||||
gameState.amountSpentOnFood -= 25;
|
||||
gameState.amountSpentOnMiscellaneousSupplies -= 10;
|
||||
gameState.amountSpentOnAmmunition -= 300;
|
||||
gameState.totalMileageWholeTrip -= 30 + Math.random() * 40;
|
||||
message += "❄️ Blizzard in mountain pass—time and supplies lost.\n";
|
||||
|
||||
if (gameState.amountSpentOnClothing < 18 + Math.random() * 2) {
|
||||
message += "❄️🧣 Not enough clothing for the cold. This could be dire.\n";
|
||||
// Add logic to affect player health or trigger a death sequence.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return encounter ? message : "The mountains are distant... for now.\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default GameEvents;
|
||||
|
||||
interface OregonEvent {
|
||||
name: string;
|
||||
threshold: number;
|
||||
action: (gameState: GameState) => string;
|
||||
name: string,
|
||||
threshold: number,
|
||||
action: (gameState: GameState) => string
|
||||
}
|
|
@ -6,8 +6,6 @@ import { HuntPhase } from '../phases/hunt';
|
|||
import { HandleSetup as SetupPhase } from '../phases/setup';
|
||||
import { travelPhase as TravelPhase } from '../phases/travel';
|
||||
import { ActionPhase } from '../phases/action';
|
||||
import { EventPhase } from './gameEvents';
|
||||
import { MountainPhase } from '../phases/mountain';
|
||||
|
||||
class GameFlow {
|
||||
|
||||
|
@ -43,11 +41,9 @@ class GameFlow {
|
|||
break;
|
||||
case PHASE_ENUM.EVENT:
|
||||
// Handle random events that can occur
|
||||
await EventPhase.handleRandomEvent(gameState);
|
||||
break;
|
||||
case PHASE_ENUM.MOUNTAIN:
|
||||
// Handle mountain traversal challenges
|
||||
await MountainPhase.handleMountain(gameState);
|
||||
break;
|
||||
case PHASE_ENUM.DEATH:
|
||||
// Check if conditions leading to the player's death have been met
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
import GameFlow from '../game/gameFlow';
|
||||
import GameState, { PHASE_ENUM } from '../game/gameState';
|
||||
|
||||
export class MountainPhase {
|
||||
static async handleMountain(gameState: GameState): Promise<void> {
|
||||
// If the total mileage is less than 950, return an empty string (no mountain encounter)
|
||||
if (gameState.totalMileageWholeTrip <= 950) {
|
||||
return;
|
||||
}
|
||||
|
||||
let responseMessage = "**🏔️ Mountain Passage 🏔️**\n";
|
||||
let encounter = false;
|
||||
|
||||
let randomFactor = Math.random() * 10;
|
||||
// Calculate the mountain difficulty based on the total mileage traveled
|
||||
// The difficulty peaks around 1500 miles and decreases as you get closer or further away
|
||||
// Example: If totalMileageWholeTrip is 1500, mountainDifficulty will be 9
|
||||
|
||||
const milesFromPeak = gameState.totalMileageWholeTrip / 100 - 15;
|
||||
const numerator = milesFromPeak ** 2 + 72;
|
||||
const denominator = milesFromPeak ** 2 + 12;
|
||||
let mountainDifficulty = 9 - (numerator / denominator);
|
||||
|
||||
|
||||
// Check if a mountain encounter occurs based on the random factor and difficulty
|
||||
if (randomFactor > mountainDifficulty) {
|
||||
encounter = true;
|
||||
responseMessage += "Rugged mountains make your journey difficult.\n";
|
||||
|
||||
// Randomly determine the type of mountain encounter
|
||||
if (Math.random() > 0.1) {
|
||||
gameState.totalMileageWholeTrip -= 60;
|
||||
responseMessage += "🔍 You got lost—losing valuable time trying to find the trail!\n";
|
||||
} else if (Math.random() > 0.11) {
|
||||
gameState.amountSpentOnMiscellaneousSupplies -= 5;
|
||||
gameState.amountSpentOnAmmunition -= 200;
|
||||
gameState.totalMileageWholeTrip -= 20 + Math.random() * 30;
|
||||
responseMessage += "🛠️ Wagon damaged!—Lose time and supplies.\n";
|
||||
} else {
|
||||
gameState.totalMileageWholeTrip -= 45 + Math.random() / 0.02;
|
||||
responseMessage += "🐢 The going gets slow.\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the South Pass has been cleared
|
||||
if (!gameState.clearSouthPassFlag) {
|
||||
gameState.clearSouthPassFlag = true;
|
||||
if (Math.random() < 0.8) {
|
||||
encounter = true;
|
||||
responseMessage += "✅ You made it safely through South Pass—no snow.\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the Blue Mountains have been cleared
|
||||
if (gameState.totalMileageWholeTrip >= 1700 && !gameState.clearBlueMountainsFlag) {
|
||||
gameState.clearBlueMountainsFlag = true;
|
||||
if (Math.random() < 0.7) {
|
||||
encounter = true;
|
||||
gameState.blizzardFlag = true;
|
||||
gameState.amountSpentOnFood -= 25;
|
||||
gameState.amountSpentOnMiscellaneousSupplies -= 10;
|
||||
gameState.amountSpentOnAmmunition -= 300;
|
||||
gameState.totalMileageWholeTrip -= 30 + Math.random() * 40;
|
||||
responseMessage += "❄️ Blizzard in mountain pass—time and supplies lost.\n";
|
||||
|
||||
// Check if the player has enough clothing for the cold
|
||||
if (gameState.amountSpentOnClothing < 18 + Math.random() * 2) {
|
||||
responseMessage += "❄️🧣 Not enough clothing for the cold. This could be dire.\n";
|
||||
// Add logic to affect player health or trigger a death sequence.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the encounter message or a default message if no encounter occurred
|
||||
gameState.lastPrompt = encounter ? responseMessage : "The mountains are distant... for now.\n";
|
||||
gameState.phase = PHASE_ENUM.START_TURN;
|
||||
gameState.subPhase = 0
|
||||
await gameState.save();
|
||||
await GameFlow.executeCurrentPhase(gameState);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue