diff --git a/src/shared/EntityManager.ts b/src/shared/EntityManager.ts index 8c58a2f..f5cea98 100644 --- a/src/shared/EntityManager.ts +++ b/src/shared/EntityManager.ts @@ -1,18 +1,54 @@ // "EntityManager": Create entity objects and apply transformations to them. -// + Functions are here, as to avoid storing unecessary data in the server store. +// A bold attempt at functional programming in a videogame entity system import { makePuppet, puppet, puppetEntry } from "./Puppetmaster"; // import { ability } from "./AbilityManager"; -// I spent a lot of time thinking about the names for these types and they still suck -type modifiers = readonly [power: number, speed: number, defense: number, resistance: number]; // values used for calculation, only modified by buffs and debuffs (the first group is additive, the second multiplicative) +const entityTags = ["minion"] as const +type modifiers = readonly [power: number, speed: number, defense: number, resistance: number]; // values used for calculation, only modified by buffs and debuffs type statuses = readonly [health: number, barrier: number]; // values used to store an entity's current status (more existential than stats) type statusEffect = readonly [string, modifiers, entityTransformTemplate, number]; +type entityTag = typeof entityTags[number] +export interface entityId { + readonly name: string; + readonly team: "players" | "enemies"; + readonly tags: { + [tagName in entityTag]: boolean; + }; +} +export interface entityProperties { + readonly id: entityId, + readonly baseModifiers: modifiers, + readonly maxStatuses: statuses, + readonly baseStatusEffects: statusEffect[],// Permanent immunities/status effects +} +export interface entityStatuses { + readonly statuses: statuses; // Health and stuff that change constantly + readonly statusEffects: statusEffect[]; // Burn, poison, etc. +} + +type entityTransformType = "support" | "attack"; +type healthTransformValue = [magnitude: number, affectsHealth: boolean, affectsBarrier: boolean] +interface entityTransformTemplate { + healthTransformValue: healthTransformValue, + statusEffectsGranted?: placeholder[]; // TBA (Stuff like burn, slow, stun, etc.) +} +type entityTransformDeterminer = ( + entityPerformingId: entityId, + entityReceivingId: entityId, + entityPerformingPuppet: puppet, + entityReceivingPuppet: puppet, +) => [entityTransformType, entityTransformTemplate] | false; +interface ability { + placeholder: entityTransformDeterminer; // TBA (Most abilities will not be a single instant of damage/heal) +} +// Immunities are just status effects that take the place of a damaging status effect (so ones of that type can't be added) but don't do anything +// Status effects have a strength value that determines whether they can override another status effect of the same type (holy inferno can replace burn but burn can't replace holy inferno) -export interface entityController { +export interface entityController {//Deprecated setPosition: (location: Vector3) => void; useAbility: (abilityName: string, activating: boolean) => void; } -export interface entityModifier {} +export interface entityModifier {}// Deprecated /* Prototype entityTransform(setOfAllEntities: entity[], actingEntity: entity, ability destructured to {hitBoxList, modificationList}) const entitiesEligible = getAffectedEntities(setOfAllEntities, actingEntity) @@ -31,25 +67,6 @@ export interface entityModifier {} const ableToUse = completeAbility ? canUseAbility(now, completeAbility) : completeAbility // canUseAbility should return the first abilityPart return resultOfFirstAbilityPart = ableToUse ? useAbilityPart(ability.firstPart, setOfAllEntities, thisEntity) : [ableToUse] */ -interface entityStats { - statuses: statuses; // Health and stuff that change constantly - /* immunities: { - [statusEffectName: string]: boolean | undefined; - };*/ - statusEffects: statusEffect[]; // Burn, poison, etc. -} -interface entityId { - readonly name: string; - readonly team: "players" | "enemies"; - readonly isMinion: boolean; -} -export interface entity { - readonly id: entityId; - stats: entityStats; - baseModifiers: modifiers; // Base modifiers that change only when the player switches weapons or something - maxStatuses: statuses; - puppet: puppet; -} // type entityTransform = (entity: entity) => entity; // interface entityTransformTemplate { @@ -65,22 +82,6 @@ export interface entity { excludesSelf: boolean, affectsSameTeam: boolean, */ //} -type entityTransformType = "heal" | "attack"; -interface entityTransformTemplate { - magnitude: number; - affectsHealth: boolean; - affectsBarrier: boolean; - statusEffectsGranted?: placeholder[]; // TBA (Stuff like burn, slow, stun, etc.) -} -type entityTransformDeterminer = ( - entityPerformingId: entityId, - entityReceivingId: entityId, - entityPerformingPuppet: puppet, - entityReceivingPuppet: puppet, -) => [entityTransformType, entityTransformTemplate] | false; -interface ability { - placeholder: entityTransformDeterminer; // TBA (Most abilities will not be a single instant of damage/heal) -} // type entityTransformTemplate = [entityTransformEligibilityTemplate, entityTransformApplicationTemplate] /*function isEligibleForTransform(entityPerformingTransform: entity, entityReceivingTransform: entity, eligibilityTemplate: entityTransformEligibilityTemplate): false | [boolean] { // This function sucks const entityReceivingId = entityReceivingTransform.id @@ -306,6 +307,9 @@ function getEntityByName(entityList: entity[], entityName: string): success boolean @@ -8,11 +8,16 @@ export interface sceneTemplate { readonly onCompletion: readonly playerManagerRequest[] // Requests to get sent out when the scene ends } export interface scene extends sceneTemplate { - containedScenes?: { + /*containedScenes?: { [sceneName: string]: scene | undefined - }; // Scenes within this scene that are isolated from each other and can be run in parallel + }; // Scenes within this scene that are isolated from each other and can be run in parallel // Not necessarily "A list of events that need to return true (in sequence) to complete this event", but such events would go there - containedEntities: entity[]; // A list of entities that need to die to complete the event + *///Scene nesting is currently cancelled + containedEntities: string[]; // "A list of entities that need to die to complete the event" (not really but kinda) + containedEntityProperties: { + [entityName: string]: entityProperties + } + containedEntityStatuses players: { [userId: number]: [inThisScene: true] | [inThisScene: false, subScene: string] | undefined } @@ -21,7 +26,7 @@ export interface scene extends sceneTemplate { export function runScene(scene: scene, now: number): success<[scene, playerManagerRequest[]]> { return [true, [scene, []]]; } -function getPlayerSceneName(scene: scene, userId: number): success { +/*function getPlayerSceneName(scene: scene, userId: number): success { let playerSceneLocation = scene.players[userId]; if (!playerSceneLocation) { return [false, "Player does not exist"]; // Some kind of error needs to go here @@ -30,9 +35,9 @@ function getPlayerSceneName(scene: scene, userId: number): success { try {