Compare commits
4 Commits
375fb9bd18
...
5b97b4b219
Author | SHA1 | Date |
---|---|---|
j | 5b97b4b219 | |
j | 94cb64f37a | |
j | 78c36d1b77 | |
j | b0e7d1051c |
|
@ -1,5 +1,6 @@
|
||||||
import GameState, { PHASE_ENUM } from './gameState';
|
import GameState, { PHASE_ENUM } from './gameState';
|
||||||
import { MessageService, MessageFileName } from '../utils/MessageService'
|
import { MessageService, MessageFileName } from '../utils/MessageService'
|
||||||
|
import { CommentPoster } from '../rdrama/services/CommentPoster';
|
||||||
|
|
||||||
class GameFlow {
|
class GameFlow {
|
||||||
gameState: GameState;
|
gameState: GameState;
|
||||||
|
@ -52,7 +53,56 @@ class GameFlow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async handleSetupPhase(userInput?: string): Promise<string> {
|
formatDate(date: Date): string {
|
||||||
|
return date.toLocaleDateString("en-US", {
|
||||||
|
weekday: 'long',
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric',
|
||||||
|
}).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
async statusUpdate(message: string): Promise<void> {
|
||||||
|
const placeholders: { [key: string]: string } = {
|
||||||
|
playerName: this.gameState.authorName,
|
||||||
|
message: message,
|
||||||
|
date: this.gameState.currentDate,
|
||||||
|
money: this.gameState.cashLeftAfterInitialPurchases.toString(),
|
||||||
|
totalMileage: this.gameState.totalMileageWholeTrip.toString(),
|
||||||
|
oxen: this.describeOxenQuality(),
|
||||||
|
food: this.gameState.amountSpentOnFood.toString(),
|
||||||
|
ammo: this.gameState.amountSpentOnAmmunition.toString(),
|
||||||
|
clothing: this.gameState.amountSpentOnClothing.toString(),
|
||||||
|
supplies: this.gameState.amountSpentOnMiscellaneousSupplies.toString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const parsedMessage = `${MessageService.getRandomMessage(MessageFileName.Oregon_Template, placeholders)}`
|
||||||
|
|
||||||
|
await CommentPoster.postComment(`c_${this.gameState.comment.id}`, parsedMessage)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
describeOxenQuality(): string {
|
||||||
|
const spent = this.gameState.amountSpentOnAnimals;
|
||||||
|
const qualityLevels = [
|
||||||
|
{ max: 220, description: 'Basic Quality' },
|
||||||
|
{ max: 240, description: 'Moderate Quality' },
|
||||||
|
{ max: 260, description: 'Good Quality' },
|
||||||
|
{ max: 280, description: 'High Quality' },
|
||||||
|
{ max: 300, description: 'Exceptional Quality' }
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const level of qualityLevels) {
|
||||||
|
if (spent <= level.max) {
|
||||||
|
return level.description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default to the lowest quality if for some reason the amount doesn't fit the expected range
|
||||||
|
return 'Unknown Quality';
|
||||||
|
}
|
||||||
|
|
||||||
|
private async handleSetupPhase(userInput?: string): Promise<void> {
|
||||||
let responseMessage = "";
|
let responseMessage = "";
|
||||||
// Logic to handle initial setup
|
// Logic to handle initial setup
|
||||||
switch (this.gameState.subPhase) {
|
switch (this.gameState.subPhase) {
|
||||||
|
@ -71,7 +121,6 @@ class GameFlow {
|
||||||
if (purchaseResult.success) {
|
if (purchaseResult.success) {
|
||||||
// If the purchase was successful, advance to the next subphase and recursively call handleSetupPhase without userInput to get the next set of instructions
|
// If the purchase was successful, advance to the next subphase and recursively call handleSetupPhase without userInput to get the next set of instructions
|
||||||
this.gameState.subPhase++;
|
this.gameState.subPhase++;
|
||||||
//TODO next we will need to add a wrapper methood that will dump the game object and the message back to the player
|
|
||||||
return this.handleSetupPhase();
|
return this.handleSetupPhase();
|
||||||
} else {
|
} else {
|
||||||
// If there was an error, include the error message in responseMessage
|
// If there was an error, include the error message in responseMessage
|
||||||
|
@ -91,7 +140,6 @@ class GameFlow {
|
||||||
const purchaseResult = this.handleGenericPurchase(PurchaseOption.OXEN, userInput, 200, 300);
|
const purchaseResult = this.handleGenericPurchase(PurchaseOption.OXEN, userInput, 200, 300);
|
||||||
if (purchaseResult.success) {
|
if (purchaseResult.success) {
|
||||||
this.gameState.subPhase++;
|
this.gameState.subPhase++;
|
||||||
//TODO next we will need to add a wrapper methood that will dump the game object and the message back to the player
|
|
||||||
return this.handleSetupPhase(); // Call setup phase again for next subphase
|
return this.handleSetupPhase(); // Call setup phase again for next subphase
|
||||||
} else {
|
} else {
|
||||||
responseMessage = purchaseResult.errorMessage || '';
|
responseMessage = purchaseResult.errorMessage || '';
|
||||||
|
@ -109,7 +157,6 @@ class GameFlow {
|
||||||
const purchaseResult = this.handleGenericPurchase(PurchaseOption.FOOD, userInput);
|
const purchaseResult = this.handleGenericPurchase(PurchaseOption.FOOD, userInput);
|
||||||
if (purchaseResult.success) {
|
if (purchaseResult.success) {
|
||||||
this.gameState.subPhase++;
|
this.gameState.subPhase++;
|
||||||
//TODO next we will need to add a wrapper methood that will dump the game object and the message back to the player
|
|
||||||
return this.handleSetupPhase(); // Call setup phase again for next subphase
|
return this.handleSetupPhase(); // Call setup phase again for next subphase
|
||||||
} else {
|
} else {
|
||||||
responseMessage = purchaseResult.errorMessage || '';
|
responseMessage = purchaseResult.errorMessage || '';
|
||||||
|
@ -127,7 +174,6 @@ class GameFlow {
|
||||||
const purchaseResult = this.handleGenericPurchase(PurchaseOption.AMMO, userInput);
|
const purchaseResult = this.handleGenericPurchase(PurchaseOption.AMMO, userInput);
|
||||||
if (purchaseResult.success) {
|
if (purchaseResult.success) {
|
||||||
this.gameState.subPhase++;
|
this.gameState.subPhase++;
|
||||||
//TODO next we will need to add a wrapper methood that will dump the game object and the message back to the player
|
|
||||||
return this.handleSetupPhase(); // Call setup phase again for next subphase
|
return this.handleSetupPhase(); // Call setup phase again for next subphase
|
||||||
} else {
|
} else {
|
||||||
responseMessage = purchaseResult.errorMessage || '';
|
responseMessage = purchaseResult.errorMessage || '';
|
||||||
|
@ -145,7 +191,6 @@ class GameFlow {
|
||||||
const purchaseResult = this.handleGenericPurchase(PurchaseOption.CLOTHING, userInput);
|
const purchaseResult = this.handleGenericPurchase(PurchaseOption.CLOTHING, userInput);
|
||||||
if (purchaseResult.success) {
|
if (purchaseResult.success) {
|
||||||
this.gameState.subPhase++;
|
this.gameState.subPhase++;
|
||||||
//TODO next we will need to add a wrapper methood that will dump the game object and the message back to the player
|
|
||||||
return this.handleSetupPhase(); // Call setup phase again for next subphase
|
return this.handleSetupPhase(); // Call setup phase again for next subphase
|
||||||
} else {
|
} else {
|
||||||
responseMessage = purchaseResult.errorMessage || '';
|
responseMessage = purchaseResult.errorMessage || '';
|
||||||
|
@ -163,7 +208,6 @@ class GameFlow {
|
||||||
const purchaseResult = this.handleGenericPurchase(PurchaseOption.MISC, userInput);
|
const purchaseResult = this.handleGenericPurchase(PurchaseOption.MISC, userInput);
|
||||||
if (purchaseResult.success) {
|
if (purchaseResult.success) {
|
||||||
this.gameState.subPhase++;
|
this.gameState.subPhase++;
|
||||||
//TODO next we will need to add a wrapper methood that will dump the game object and the message back to the player
|
|
||||||
return this.handleSetupPhase(); // Call setup phase again for next subphase
|
return this.handleSetupPhase(); // Call setup phase again for next subphase
|
||||||
} else {
|
} else {
|
||||||
responseMessage = purchaseResult.errorMessage || '';
|
responseMessage = purchaseResult.errorMessage || '';
|
||||||
|
@ -174,7 +218,9 @@ class GameFlow {
|
||||||
//Advance Phase
|
//Advance Phase
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return responseMessage;
|
|
||||||
|
await this.statusUpdate(responseMessage)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleWeaponPurchase(userInput: string): { success: boolean; errorMessage?: string } {
|
handleWeaponPurchase(userInput: string): { success: boolean; errorMessage?: string } {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { DatabaseService } from "../db/services/Database";
|
import { DatabaseService } from "../db/services/Database";
|
||||||
|
import { Comment } from "../rdrama/models/Comment";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the state of a game session for an Oregon Trail-style game.
|
* Represents the state of a game session for an Oregon Trail-style game.
|
||||||
|
@ -6,7 +7,9 @@ import { DatabaseService } from "../db/services/Database";
|
||||||
* to load from and save to a database.
|
* to load from and save to a database.
|
||||||
*/
|
*/
|
||||||
class GameState {
|
class GameState {
|
||||||
authorId: number = 0;
|
comment: Comment;
|
||||||
|
authorId: number;
|
||||||
|
authorName: string;
|
||||||
amountSpentOnAnimals: number = 0;
|
amountSpentOnAnimals: number = 0;
|
||||||
amountSpentOnAmmunition: number = 0;
|
amountSpentOnAmmunition: number = 0;
|
||||||
actualResponseTimeForBang: number = 0;
|
actualResponseTimeForBang: number = 0;
|
||||||
|
@ -16,7 +19,7 @@ class GameState {
|
||||||
yesNoResponseToQuestions: string = '';
|
yesNoResponseToQuestions: string = '';
|
||||||
eventCounter: number = 0;
|
eventCounter: number = 0;
|
||||||
turnNumberForSettingDate: number = 0;
|
turnNumberForSettingDate: number = 0;
|
||||||
currentDate: string = '';
|
currentDate: string = 'MONDAY MARCH 29 1847';
|
||||||
shootingExpertiseLevelChoice: number = 0;
|
shootingExpertiseLevelChoice: number = 0;
|
||||||
eatingChoice: number = 0;
|
eatingChoice: number = 0;
|
||||||
amountSpentOnFood: number = 0;
|
amountSpentOnFood: number = 0;
|
||||||
|
@ -43,8 +46,10 @@ class GameState {
|
||||||
phase: PHASE_ENUM = PHASE_ENUM.SETUP;
|
phase: PHASE_ENUM = PHASE_ENUM.SETUP;
|
||||||
subPhase: number = 0;
|
subPhase: number = 0;
|
||||||
|
|
||||||
private constructor(authorId: number, state?: Partial<GameState>) {
|
private constructor(comment: Comment, state?: Partial<GameState>) {
|
||||||
this.authorId = authorId;
|
this.comment = comment
|
||||||
|
this.authorId = comment.author_id;
|
||||||
|
this.authorName = comment.author_name;
|
||||||
Object.assign(this, state); // Initialize with loaded state or undefined
|
Object.assign(this, state); // Initialize with loaded state or undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,20 +62,21 @@ class GameState {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads an existing game state from the database or creates a new one if it doesn't exist.
|
* Loads an existing game state from the database or creates a new one if it doesn't exist.
|
||||||
* @param {number} authorId - The ID of the author/player.
|
* @param {Comment} comment - The invoking comment of the author/player.
|
||||||
* @returns {Promise<GameState>} - The loaded or newly created game state.
|
* @returns {Promise<GameState>} - The loaded or newly created game state.
|
||||||
*/
|
*/
|
||||||
public static async load(authorId: number): Promise<GameState> {
|
public static async load(comment: Comment): Promise<GameState> {
|
||||||
const loadedState = await DatabaseService.loadGameState(authorId);
|
const loadedState = await DatabaseService.loadGameState(comment.author_id);
|
||||||
if (loadedState) {
|
if (loadedState) {
|
||||||
return new GameState(authorId, loadedState);
|
return new GameState(comment, loadedState);
|
||||||
} else {
|
} else {
|
||||||
// Create a new GameState with default values
|
// Create a new GameState with default values
|
||||||
const newState = new GameState(authorId);
|
const newState = new GameState(comment);
|
||||||
await newState.save(); // Optionally save the new state to the database
|
await newState.save(); // Optionally save the new state to the database
|
||||||
return newState;
|
return newState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default GameState
|
export default GameState
|
||||||
|
|
|
@ -9,22 +9,22 @@
|
||||||
<details>
|
<details>
|
||||||
<summary>π Current Supplies</summary>
|
<summary>π Current Supplies</summary>
|
||||||
|
|
||||||
- **Oxen:** {oxen} teams (Essential for travel speed)
|
- **Oxen:** {oxen} (Essential for travel speed; higher quality means faster travel)
|
||||||
- **Food:** {food} lbs (Vital for health)
|
- **Food:** {food} lbs (Vital for sustaining health and energy)
|
||||||
- **Ammunition:** {ammo} boxes (Needed for hunting)
|
- **Ammunition:** {ammo} bullets (Critical for hunting and defense against threats)
|
||||||
- **Clothing:** {clothing} set(s) (Important for health in bad weather)
|
- **Clothing Supplies:** {clothing} (Important for protection against the elements)
|
||||||
- **Misc. Supplies:** {supplies} items (Useful for various challenges along the way)
|
- **Misc. Supplies:** {supplies} lbs (Useful for various challenges along the way)
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>β¨ Actions Available</summary>
|
<summary>β¨ Actions Available</summary>
|
||||||
|
|
||||||
- **Start Over:** Begin a new game.
|
- **Restart:** Begin a new game.
|
||||||
- **Status:** Get the current game state.
|
- **Status:** Get the current game state.
|
||||||
- **Help:** Show game instructions and tips.
|
- **Help:** Show game instructions and tips.
|
||||||
- **Buy Supplies:** Make purchases at the current location (Available at forts).
|
- **Fort:** Make purchases at the current location (Available at forts).
|
||||||
- **Continue on Trail:** Move forward with your journey.
|
- **Continue:** Move forward with your journey.
|
||||||
- **Hunt:** Spend a day hunting for food.
|
- **Hunt:** Spend a day hunting for food.
|
||||||
- **Rest:** Rest for a day to improve health.
|
- **Rest:** Rest for a day to improve health.
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
### π To Make a Choice
|
### π To Make a Choice
|
||||||
Please reply with **!!Oregon** followed by one of the actions above. For example:
|
Please reply with **!!Oregon** followed by one of the actions above. For example:
|
||||||
```
|
```
|
||||||
!!Oregon Buy Supplies
|
!!Oregon Fort
|
||||||
```
|
```
|
||||||
|
|
||||||
Remember, wise choices and preparation are key to a successful journey on the Oregon Trail. Good luck, traveler! ππ¨
|
Remember, wise choices and preparation are key to a successful journey on the Oregon Trail. Good luck, traveler! ππ¨
|
|
@ -9,6 +9,7 @@ export enum MessageFileName {
|
||||||
Oregon_AmmoPurchase = 'oregon_AmmoPurchase.txt',
|
Oregon_AmmoPurchase = 'oregon_AmmoPurchase.txt',
|
||||||
Oregon_ClothingPurchase = 'oregon_ClothingPurchase.txt',
|
Oregon_ClothingPurchase = 'oregon_ClothingPurchase.txt',
|
||||||
Oregon_MiscSuppliesPurchase = 'oregon_MiscSuppliesPurchase.txt',
|
Oregon_MiscSuppliesPurchase = 'oregon_MiscSuppliesPurchase.txt',
|
||||||
|
Oregon_Template = 'oregon_Template.txt',
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MessageService {
|
export class MessageService {
|
||||||
|
|
Loadingβ¦
Reference in New Issue