From b02155762fe64845504d03b8e1fdb12735827e54 Mon Sep 17 00:00:00 2001 From: Cheuk Yin Ng Date: Sat, 7 Mar 2020 15:44:27 -0800 Subject: [PATCH 1/3] Add seasonal events without the seasonal events --- src/App.tsx | 18 ++++++++++++------ src/game-config.json | 24 ++++++++++++++++++++++++ src/trackers/EventTracker.ts | 26 +++++++++++++++++++++----- 3 files changed, 57 insertions(+), 11 deletions(-) create mode 100644 src/game-config.json diff --git a/src/App.tsx b/src/App.tsx index 83b8ecc..1572368 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,6 +8,7 @@ import ChoicesManager from "./events/ChoicesManager"; import EventsManager from "./events/EventsManager"; import events from "./events.json"; import choices from "./choices.json"; +import config from "./game-config.json"; import Hud from "./components/hud/Hud"; import GamePlayConsole from "./components/gamePlayConsole/GamePlayConsole"; import Choices from "./components/choices/Choices"; @@ -31,16 +32,21 @@ export default class App extends React.Component { super(props); const playerStats = new PlayerStats(); - const eventTracker = new EventTracker( - [events.BoomerGregorEvent, events.CuteGirlEvent, events.FratPartyEvent], - [events.LandingEvent, events.PickFacultyEvent, events.PickResidenceEvent] - ); - let firstEvent = eventTracker.getNextEvent(); //TODO: should we auto allocate a dummy player name or allow user to input their own? this.name = "P1"; this.choiceManager = new ChoicesManager(choices); this.eventManager = new EventsManager(events); + let seasons = []; + for (const w of config.events.seasonal) { + seasons.push(w.map(this.eventManager.get.bind(this.eventManager))); + } + const eventTracker = new EventTracker( + config.events.pool.map(this.eventManager.get.bind(this.eventManager)), + config.events.followUp.map(this.eventManager.get.bind(this.eventManager)), + seasons + ); + let firstEvent = eventTracker.getNextEvent(0); this.state = { // TODO: The week number may not be how we choose to track time, // we should create some abstraction for this similar to how @@ -60,7 +66,7 @@ export default class App extends React.Component { this.state.eventTracker.queueFollowUpEvent(this.eventManager.get(choice.followUp)); } - let nextEvent = this.state.eventTracker.getNextEvent(); + let nextEvent = this.state.eventTracker.getNextEvent(this.state.week); this.setState(prevState => { return { diff --git a/src/game-config.json b/src/game-config.json new file mode 100644 index 0000000..7178294 --- /dev/null +++ b/src/game-config.json @@ -0,0 +1,24 @@ +{ + "events": { + "pool": [ + "BoomerGregorEvent", "CuteGirlEvent", "FratPartyEvent" + ], + "followUp": [ + "LandingEvent", "PickFacultyEvent", "PickResidenceEvent" + ], + "seasonal": [ + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [] + ] + } +} diff --git a/src/trackers/EventTracker.ts b/src/trackers/EventTracker.ts index 43e051a..1c89159 100644 --- a/src/trackers/EventTracker.ts +++ b/src/trackers/EventTracker.ts @@ -2,26 +2,41 @@ import { IEvent } from "../events/core"; import { GamePlayMode } from "../events/core"; export default class EventTracker { + readonly SEASONAL_CHANCE = 30; private pool: IEvent[]; private queue: IEvent[]; + private seasonal: IEvent[][]; - constructor(eventPool: IEvent[], eventQueue: IEvent[]) { + constructor(eventPool: IEvent[], eventQueue: IEvent[], seasonalPool: IEvent[][]) { this.pool = eventPool; this.queue = eventQueue; + this.seasonal = seasonalPool; } - public getNextEvent(): IEvent { + public getNextEvent(week: number): IEvent { // The queue being non-empty indicates there is a follow up // event to go through, otherwise pick a random event if (this.queue.length > 0) return this.queue.shift() as IEvent; - else if (this.pool.length > 0){ + + const r = Math.random() * 100; + const month = Math.floor(week / 4) + 9; + if (this.pool.length > 0 && + (r > this.SEASONAL_CHANCE || this.seasonal[month].length === 0)) { + // If we roll a normal pool or if there are no seasonal events then + // use the normal pool (given that there are still things in the + // normal pool) let event = this.pool[Math.floor(Math.random() * this.pool.length)]; const index = this.pool.indexOf(event); this.pool.splice(index, 1); return event; - } - else + } else if (r <= this.SEASONAL_CHANCE && this.seasonal[month].length > 0) { + // Else we use the seasonal events pool + let event = this.seasonal[month][Math.floor(Math.random() * this.seasonal[month].length)]; + const index = this.seasonal[month].indexOf(event); + this.seasonal[month].splice(index, 1); + return event; + } else { return { "prompt": "Oops! No more events!", "imgPath": "", @@ -29,6 +44,7 @@ export default class EventTracker { "hasBottomBoxBorder": true, "gamePlayMode": GamePlayMode.Hide }; + } } public queueFollowUpEvent(event: IEvent) { From ddb62e2d4f4a701a22064f1559d73a8a06de460d Mon Sep 17 00:00:00 2001 From: Cheuk Yin Ng Date: Sat, 14 Mar 2020 17:19:34 -0700 Subject: [PATCH 2/3] Fix off-by-one error --- src/trackers/EventTracker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/trackers/EventTracker.ts b/src/trackers/EventTracker.ts index 1c89159..ed0eaca 100644 --- a/src/trackers/EventTracker.ts +++ b/src/trackers/EventTracker.ts @@ -20,7 +20,8 @@ export default class EventTracker { return this.queue.shift() as IEvent; const r = Math.random() * 100; - const month = Math.floor(week / 4) + 9; + // 0 to 11 + const month = (Math.floor(week / 4) + 8) % 12; if (this.pool.length > 0 && (r > this.SEASONAL_CHANCE || this.seasonal[month].length === 0)) { // If we roll a normal pool or if there are no seasonal events then From 4592d223617b9e13f711f55e9e417417863c62a5 Mon Sep 17 00:00:00 2001 From: Cheuk Yin Ng Date: Sun, 15 Mar 2020 17:44:51 -0700 Subject: [PATCH 3/3] Fix broken things after merge --- src/App.tsx | 5 ++--- src/game-config.json | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 14381e9..f488789 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -44,7 +44,6 @@ export default class App extends React.Component { super(props); const playerStats = new PlayerStats(); - let firstEvent = eventTracker.getNextEvent(); //TODO: should we auto allocate a dummy player name or allow user to input their own? this.name = "P1"; @@ -95,7 +94,7 @@ export default class App extends React.Component { ); } - let nextEvent = this.state.eventTracker.getNextEvent(); + let nextEvent = this.state.eventTracker.getNextEvent(this.state.week + 1); this.setState(prevState => { return { @@ -131,7 +130,7 @@ export default class App extends React.Component { finishMinigame = (statChanges: number[]) => { this.state.playerStats.applyStatChanges(statChanges, ""); - let nextEvent = this.state.eventTracker.getNextEvent(); + let nextEvent = this.state.eventTracker.getNextEvent(this.state.week + 1); this.setState(prevState => { return { week: prevState.week + 1, diff --git a/src/game-config.json b/src/game-config.json index 7178294..e0eb040 100644 --- a/src/game-config.json +++ b/src/game-config.json @@ -1,7 +1,7 @@ { "events": { "pool": [ - "BoomerGregorEvent", "CuteGirlEvent", "FratPartyEvent" + "BoomerGregorEvent", "CuteGirlEvent", "FratPartyEvent", "MidtermEvent", "SquirrelEvent" ], "followUp": [ "LandingEvent", "PickFacultyEvent", "PickResidenceEvent"