From 436cbde19d2c0676b3464ba8e4f808b6498413c6 Mon Sep 17 00:00:00 2001 From: loplkc Date: Tue, 12 Apr 2022 21:23:33 -0400 Subject: [PATCH] Minor refactoring across several modules ~ InputHandler action types made more logical and easy to maintain ~ "entity" type renamed to "entityController" in anticipation of another entity interface for use by modules that damage and apply statuses to entities ~ Entities' CanUseAbility function changed to fall back to false rather than true --- src/client/InputHandler.ts | 26 ++++++------------ src/shared/AbilityManager.ts | 3 +- src/shared/EntityManager.ts | 53 ++++++++++++++++-------------------- src/shared/EventManager.ts | 5 ++-- src/shared/PlayerManager.ts | 6 ++-- 5 files changed, 40 insertions(+), 53 deletions(-) diff --git a/src/client/InputHandler.ts b/src/client/InputHandler.ts index 404d776..a73d57d 100644 --- a/src/client/InputHandler.ts +++ b/src/client/InputHandler.ts @@ -16,7 +16,7 @@ type validInput = Enum.KeyCode; // + Include controller "keys" function isValidInput(value: unknown): value is validInput { return enumTypeIs(value, Enum.KeyCode); } -const actionAssignmentsReference: string[] = [ +const actionList = [ "clicker1", // What is used to click on things (enemies in game, UI elements) "diamond1", // Diamond controls "diamond2", @@ -24,21 +24,11 @@ const actionAssignmentsReference: string[] = [ "diamond4", "special1", // Special controls "special2", -]; -export interface actionAssignments { - // Based on the reference array - clicker1?: validInput; // What is used to click on things (enemies in game, UI elements) - diamond1?: validInput; // Diamond controls - diamond2?: validInput; - diamond3?: validInput; - diamond4?: validInput; - special1?: validInput; // Special controls - special2?: validInput; -} -type action = keyof actionAssignments; -function isValidAction(value: string): value is keyof actionAssignments { - return value in actionAssignmentsReference; // uh oh -} +] as const; +type action = typeof actionList[number] +export type actionAssignments = { + [actionName in action]?: validInput; +}; type actionBinding = [action, (actionName: string, state: Enum.UserInputState, inputObject: InputObject) => void]; function getMouseLocation(filterDescendantsInstances: Instance[]): [Vector3, Vector3, Instance | undefined] { @@ -82,9 +72,9 @@ class actionHandler implements actionBinder { } assignInputsToActions(actionAssignments: unknownTable) { const newActionAssignments: actionAssignments = {}; - actionAssignmentsReference.forEach((action) => { + actionList.forEach((action) => { const input: unknown = actionAssignments[action]; - if (isValidAction(action) && isValidInput(input)) { + if (isValidInput(input)) { newActionAssignments[action] = input; } }); diff --git a/src/shared/AbilityManager.ts b/src/shared/AbilityManager.ts index 9c1d3b4..6a36b03 100644 --- a/src/shared/AbilityManager.ts +++ b/src/shared/AbilityManager.ts @@ -1,4 +1,5 @@ +import { entityModifier } from "./EntityManager" export interface ability { - use: () => void; // ? Does it pass back information to the entity manager that it does something with? Is an ability really just a transform of entities? + use: (entities?: entityModifier[]) => void; // ? Does it pass back information to the entity manager that it does something with? Is an ability really just a transform of entities? // ... this transform would need the positions and stats of the entities involved as well as potential obstacles } diff --git a/src/shared/EntityManager.ts b/src/shared/EntityManager.ts index f9700ad..cbea573 100644 --- a/src/shared/EntityManager.ts +++ b/src/shared/EntityManager.ts @@ -5,12 +5,14 @@ import { ability } from "./AbilityManager"; type stats = [maxHealth: number, attack: number, speed: number, defense: number]; // values used for calculation, only modified by buffs and debuffs type amounts = [health: number, barrier: number]; // values used to store an entity's current status (more existential than stats) -export interface entity { +export interface entityController { setPosition: (location: Vector3) => void; - ability: (ability: string, state: boolean) => void; + useAbility: (abilityName: string, activating: boolean) => void; } -class entityHandler implements entity { +export interface entityModifier {} + +class entityHandler implements entityController { constructor(baseStats: stats, baseAmounts: amounts, puppetEntry: puppetEntry) { this.baseStats = baseStats; this.baseAmounts = baseAmounts; @@ -22,46 +24,39 @@ class entityHandler implements entity { canUseAbility(abilityName: string): boolean { // ! Not concurrency safe // + buncha status checks - for (let i = 1; i <= 2; i++) { - const cooldown = this.cooldowns[abilityName]; - if (cooldown !== undefined) { - const now = os.clock(); - if (now - cooldown[0] >= cooldown[1]) { - this.cooldowns[abilityName] = undefined; - } - } else { - return true; + const cooldown = this.cooldowns[abilityName]; + if (cooldown) { + const now = os.clock(); + if (now - cooldown[0] < cooldown[1]) { + return false } } - return false; + return true; } - ability(abilityName: string, activated: boolean) { + useAbility(abilityName: string, activating: boolean) { const abilities = this.abilities; - if (abilities) { - if (activated) { - if (this.canUseAbility(abilityName)) { - const ability = abilities[abilityName]; - if (ability !== undefined) { - ability.use(); - } + if (activating) { + if (this.canUseAbility(abilityName)) { + const ability = abilities[abilityName]; + if (ability != undefined) { + const abilityResult = ability.use(); } - } else { - // + Ability cancellation - perhaps the useAbility inside the entity returns a function to store that the ability watches that ceases the ability when executed } + } else { + // + Ability cancellation - perhaps the useAbility inside the entity returns a function to store that the ability watches that ceases the ability when executed } // Blah blah blah } - baseStats: stats; - baseAmounts: amounts; puppet: puppet; - abilities?: { - [key: string]: ability; - }; - + abilities: { + [key: string]: ability | undefined; + } = {}; cooldowns: { [key: string]: [start: number, length: number] | undefined; } = {}; + baseStats: stats; + baseAmounts: amounts; } export function makeEntity( diff --git a/src/shared/EventManager.ts b/src/shared/EventManager.ts index ebccc90..416ec6c 100644 --- a/src/shared/EventManager.ts +++ b/src/shared/EventManager.ts @@ -1,9 +1,10 @@ // "The": Handle events. // WORST CONDITION RigHT NOW -import { makeEntity, entity } from "./EntityManager"; +// Consider that this is the second module coupled to the EntityManager +import { makeEntity, entityController } from "./EntityManager"; interface event { winEvents?: event[]; // A list of events that need to return true (in sequence) to complete this event - winEntities?: entity[]; // A list of entities that need to die to complete the event + winEntities?: entityController[]; // A list of entities that need to die to complete the event timeout?: number; // A timeout for the event; passes a lose condition if there are other completion requirements that have not been satisfied } export function runEvent(event: event) { diff --git a/src/shared/PlayerManager.ts b/src/shared/PlayerManager.ts index 3651edf..f389073 100644 --- a/src/shared/PlayerManager.ts +++ b/src/shared/PlayerManager.ts @@ -1,5 +1,5 @@ // "PlayerManager": Handle the data of players. This involves receiving them when they arrive, cleaning up after they exit, teleporting them, etc. -import { makeEntity, entity } from "./EntityManager"; +import { makeEntity, entityController } from "./EntityManager"; interface saveDataEntry { // + May need to move this to archiver @@ -29,7 +29,7 @@ class storedPlayerHandler implements storedPlayer { } ability(ability: string, state: boolean) { if (this.entity) { - this.entity.ability(ability, state); + this.entity.useAbility(ability, state); } } loadIn() { @@ -40,7 +40,7 @@ class storedPlayerHandler implements storedPlayer { inMainMenu: boolean; // + Other data that is unique to players but does not persist between sessions saveData: saveDataEntry; // This gets synced with the actual datastore - entity?: entity; + entity?: entityController; } export interface playerStorage {