@phalanx-engine/abilities 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +564 -0
- package/dist/api/AbilitySystemFacade.d.ts +34 -0
- package/dist/api/AbilitySystemFacade.d.ts.map +1 -0
- package/dist/api/AbilitySystemFacade.js +213 -0
- package/dist/api/createAbilitySystem.d.ts +49 -0
- package/dist/api/createAbilitySystem.d.ts.map +1 -0
- package/dist/api/createAbilitySystem.js +205 -0
- package/dist/api/defineAbility.d.ts +3 -0
- package/dist/api/defineAbility.d.ts.map +1 -0
- package/dist/api/defineAbility.js +9 -0
- package/dist/api/defineAbilitySystem.d.ts +8 -0
- package/dist/api/defineAbilitySystem.d.ts.map +1 -0
- package/dist/api/defineAbilitySystem.js +7 -0
- package/dist/api/defineAttribute.d.ts +3 -0
- package/dist/api/defineAttribute.d.ts.map +1 -0
- package/dist/api/defineAttribute.js +3 -0
- package/dist/api/defineEffect.d.ts +6 -0
- package/dist/api/defineEffect.d.ts.map +1 -0
- package/dist/api/defineEffect.js +23 -0
- package/dist/api/index.d.ts +11 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +6 -0
- package/dist/components/AbilitiesComponentType.d.ts +7 -0
- package/dist/components/AbilitiesComponentType.d.ts.map +1 -0
- package/dist/components/AbilitiesComponentType.js +7 -0
- package/dist/components/AbilitySystemComponent.d.ts +17 -0
- package/dist/components/AbilitySystemComponent.d.ts.map +1 -0
- package/dist/components/AbilitySystemComponent.js +31 -0
- package/dist/components/ActiveEffectsComponent.d.ts +12 -0
- package/dist/components/ActiveEffectsComponent.d.ts.map +1 -0
- package/dist/components/ActiveEffectsComponent.js +6 -0
- package/dist/components/AttributesComponent.d.ts +9 -0
- package/dist/components/AttributesComponent.d.ts.map +1 -0
- package/dist/components/AttributesComponent.js +15 -0
- package/dist/components/GameplayTagsComponent.d.ts +8 -0
- package/dist/components/GameplayTagsComponent.d.ts.map +1 -0
- package/dist/components/GameplayTagsComponent.js +7 -0
- package/dist/components/index.d.ts +7 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +5 -0
- package/dist/cues/Cue.d.ts +15 -0
- package/dist/cues/Cue.d.ts.map +1 -0
- package/dist/cues/Cue.js +7 -0
- package/dist/cues/index.d.ts +3 -0
- package/dist/cues/index.d.ts.map +1 -0
- package/dist/cues/index.js +1 -0
- package/dist/events/AbilityEvents.d.ts +10 -0
- package/dist/events/AbilityEvents.d.ts.map +1 -0
- package/dist/events/AbilityEvents.js +1 -0
- package/dist/events/CueEvents.d.ts +5 -0
- package/dist/events/CueEvents.d.ts.map +1 -0
- package/dist/events/CueEvents.js +4 -0
- package/dist/events/index.d.ts +5 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +2 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/registry/AbilityHooksRegistry.d.ts +10 -0
- package/dist/registry/AbilityHooksRegistry.d.ts.map +1 -0
- package/dist/registry/AbilityHooksRegistry.js +25 -0
- package/dist/registry/AbilityRegistry.d.ts +6 -0
- package/dist/registry/AbilityRegistry.d.ts.map +1 -0
- package/dist/registry/AbilityRegistry.js +4 -0
- package/dist/registry/AbilitySystemRegistries.d.ts +12 -0
- package/dist/registry/AbilitySystemRegistries.d.ts.map +1 -0
- package/dist/registry/AbilitySystemRegistries.js +12 -0
- package/dist/registry/AttributeRegistry.d.ts +7 -0
- package/dist/registry/AttributeRegistry.d.ts.map +1 -0
- package/dist/registry/AttributeRegistry.js +11 -0
- package/dist/registry/DefinitionRegistry.d.ts +16 -0
- package/dist/registry/DefinitionRegistry.d.ts.map +1 -0
- package/dist/registry/DefinitionRegistry.js +37 -0
- package/dist/registry/EffectRegistry.d.ts +6 -0
- package/dist/registry/EffectRegistry.d.ts.map +1 -0
- package/dist/registry/EffectRegistry.js +4 -0
- package/dist/registry/index.d.ts +7 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +5 -0
- package/dist/runtime/AbilitySystemRuntime.d.ts +26 -0
- package/dist/runtime/AbilitySystemRuntime.d.ts.map +1 -0
- package/dist/runtime/AbilitySystemRuntime.js +11 -0
- package/dist/runtime/GameplayCueBuffer.d.ts +10 -0
- package/dist/runtime/GameplayCueBuffer.d.ts.map +1 -0
- package/dist/runtime/GameplayCueBuffer.js +16 -0
- package/dist/runtime/InstanceIdCounter.d.ts +6 -0
- package/dist/runtime/InstanceIdCounter.d.ts.map +1 -0
- package/dist/runtime/InstanceIdCounter.js +10 -0
- package/dist/runtime/index.d.ts +6 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +3 -0
- package/dist/systems/AbilityActivationSystem.d.ts +23 -0
- package/dist/systems/AbilityActivationSystem.d.ts.map +1 -0
- package/dist/systems/AbilityActivationSystem.js +277 -0
- package/dist/systems/AbilityHookExecutorSystem.d.ts +10 -0
- package/dist/systems/AbilityHookExecutorSystem.d.ts.map +1 -0
- package/dist/systems/AbilityHookExecutorSystem.js +35 -0
- package/dist/systems/AttributeAggregationSystem.d.ts +12 -0
- package/dist/systems/AttributeAggregationSystem.d.ts.map +1 -0
- package/dist/systems/AttributeAggregationSystem.js +117 -0
- package/dist/systems/CueBufferCleanupSystem.d.ts +8 -0
- package/dist/systems/CueBufferCleanupSystem.d.ts.map +1 -0
- package/dist/systems/CueBufferCleanupSystem.js +11 -0
- package/dist/systems/CueDispatchSystem.d.ts +8 -0
- package/dist/systems/CueDispatchSystem.d.ts.map +1 -0
- package/dist/systems/CueDispatchSystem.js +17 -0
- package/dist/systems/CuePresentationSystem.d.ts +14 -0
- package/dist/systems/CuePresentationSystem.d.ts.map +1 -0
- package/dist/systems/CuePresentationSystem.js +50 -0
- package/dist/systems/EffectApplicationSystem.d.ts +20 -0
- package/dist/systems/EffectApplicationSystem.d.ts.map +1 -0
- package/dist/systems/EffectApplicationSystem.js +174 -0
- package/dist/systems/EffectTickSystem.d.ts +16 -0
- package/dist/systems/EffectTickSystem.d.ts.map +1 -0
- package/dist/systems/EffectTickSystem.js +152 -0
- package/dist/systems/index.d.ts +9 -0
- package/dist/systems/index.d.ts.map +1 -0
- package/dist/systems/index.js +8 -0
- package/dist/targeting/TargetResolver.d.ts +19 -0
- package/dist/targeting/TargetResolver.d.ts.map +1 -0
- package/dist/targeting/TargetResolver.js +45 -0
- package/dist/targeting/index.d.ts +3 -0
- package/dist/targeting/index.d.ts.map +1 -0
- package/dist/targeting/index.js +1 -0
- package/dist/types/AbilityDef.d.ts +13 -0
- package/dist/types/AbilityDef.d.ts.map +1 -0
- package/dist/types/AbilityDef.js +1 -0
- package/dist/types/AbilityHook.d.ts +10 -0
- package/dist/types/AbilityHook.d.ts.map +1 -0
- package/dist/types/AbilityHook.js +1 -0
- package/dist/types/ActiveEffectInstance.d.ts +9 -0
- package/dist/types/ActiveEffectInstance.d.ts.map +1 -0
- package/dist/types/ActiveEffectInstance.js +1 -0
- package/dist/types/AttributeDef.d.ts +10 -0
- package/dist/types/AttributeDef.d.ts.map +1 -0
- package/dist/types/AttributeDef.js +1 -0
- package/dist/types/CueEvent.d.ts +9 -0
- package/dist/types/CueEvent.d.ts.map +1 -0
- package/dist/types/CueEvent.js +1 -0
- package/dist/types/EffectDef.d.ts +23 -0
- package/dist/types/EffectDef.d.ts.map +1 -0
- package/dist/types/EffectDef.js +17 -0
- package/dist/types/ModifierOp.d.ts +8 -0
- package/dist/types/ModifierOp.d.ts.map +1 -0
- package/dist/types/ModifierOp.js +1 -0
- package/dist/types/TargetSpec.d.ts +32 -0
- package/dist/types/TargetSpec.d.ts.map +1 -0
- package/dist/types/TargetSpec.js +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { FP } from '@phalanx-engine/math';
|
|
2
|
+
import { ActiveEffectsComponent, AttributesComponent, GameplayTagsComponent, getActiveEffectsComponent, getAttributesComponent, getGameplayTagsComponent, } from '../components';
|
|
3
|
+
export const NO_SOURCE_ENTITY_ID = -1;
|
|
4
|
+
export class AbilitySystemFacade {
|
|
5
|
+
entityManager;
|
|
6
|
+
registries;
|
|
7
|
+
runtime;
|
|
8
|
+
constructor(entityManager, registries, runtime) {
|
|
9
|
+
this.entityManager = entityManager;
|
|
10
|
+
this.registries = registries;
|
|
11
|
+
this.runtime = runtime;
|
|
12
|
+
}
|
|
13
|
+
initAttributesForEntity(entityId) {
|
|
14
|
+
const entity = this.requireEntity(entityId);
|
|
15
|
+
const existing = getAttributesComponent(entity);
|
|
16
|
+
if (existing) {
|
|
17
|
+
return existing;
|
|
18
|
+
}
|
|
19
|
+
const attributes = new AttributesComponent(this.registries.attributes.size);
|
|
20
|
+
const defs = this.registries.attributes.values();
|
|
21
|
+
for (let index = 0; index < defs.length; index++) {
|
|
22
|
+
const rawDefault = FP.ToRaw(defs[index].default);
|
|
23
|
+
attributes.base[index] = rawDefault;
|
|
24
|
+
attributes.current[index] = rawDefault;
|
|
25
|
+
attributes.dirty[index] = 1;
|
|
26
|
+
}
|
|
27
|
+
entity.addComponent(attributes);
|
|
28
|
+
this.entityManager.onComponentAdded(entity, attributes.type);
|
|
29
|
+
return attributes;
|
|
30
|
+
}
|
|
31
|
+
getAttribute(entityId, attrId) {
|
|
32
|
+
const value = this.tryGetAttribute(entityId, attrId);
|
|
33
|
+
if (!value) {
|
|
34
|
+
const entity = this.entityManager.getEntity(entityId);
|
|
35
|
+
if (!entity) {
|
|
36
|
+
throw new Error(`Entity ${entityId} does not exist`);
|
|
37
|
+
}
|
|
38
|
+
if (!getAttributesComponent(entity)) {
|
|
39
|
+
throw new Error(`Entity ${entityId} does not have AttributesComponent`);
|
|
40
|
+
}
|
|
41
|
+
throw new Error(`AttributeRegistry does not contain '${attrId}'`);
|
|
42
|
+
}
|
|
43
|
+
return value;
|
|
44
|
+
}
|
|
45
|
+
tryGetAttribute(entityId, attrId) {
|
|
46
|
+
const entity = this.entityManager.getEntity(entityId);
|
|
47
|
+
if (!entity) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
const attributes = getAttributesComponent(entity);
|
|
51
|
+
if (!attributes) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
const index = this.registries.attributes.indexOfOrMinusOne(attrId);
|
|
55
|
+
if (index === -1) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
base: FP.FromRaw(attributes.base[index]),
|
|
60
|
+
current: FP.FromRaw(attributes.current[index]),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
applyEffect(targetEntityId, effectId, sourceEntityId = NO_SOURCE_ENTITY_ID) {
|
|
64
|
+
const target = this.requireEntity(targetEntityId);
|
|
65
|
+
if (!this.registries.effects.has(effectId)) {
|
|
66
|
+
throw new Error(`EffectRegistry does not contain '${effectId}'`);
|
|
67
|
+
}
|
|
68
|
+
const activeEffects = this.getOrCreateActiveEffects(target);
|
|
69
|
+
activeEffects.pendingAdd.push({ defId: effectId, sourceEntityId });
|
|
70
|
+
}
|
|
71
|
+
removeEffectsByTag(entityId, grantedTag) {
|
|
72
|
+
const entity = this.entityManager.getEntity(entityId);
|
|
73
|
+
if (!entity) {
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
const activeEffects = getActiveEffectsComponent(entity);
|
|
77
|
+
if (!activeEffects) {
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
let flagged = 0;
|
|
81
|
+
for (let i = 0; i < activeEffects.queue.length; i++) {
|
|
82
|
+
const instance = activeEffects.queue[i];
|
|
83
|
+
const def = this.registries.effects.tryGet(instance.defId);
|
|
84
|
+
if (!def || !def.tagsGranted) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (def.tagsGranted.indexOf(grantedTag) === -1) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (instance.remainingTicks > 0) {
|
|
91
|
+
instance.remainingTicks = 0;
|
|
92
|
+
flagged += 1;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return flagged;
|
|
96
|
+
}
|
|
97
|
+
removeEffectsByDefId(entityId, effectId) {
|
|
98
|
+
const entity = this.entityManager.getEntity(entityId);
|
|
99
|
+
if (!entity) {
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
const activeEffects = getActiveEffectsComponent(entity);
|
|
103
|
+
if (!activeEffects) {
|
|
104
|
+
return 0;
|
|
105
|
+
}
|
|
106
|
+
let flagged = 0;
|
|
107
|
+
for (let i = 0; i < activeEffects.queue.length; i++) {
|
|
108
|
+
const instance = activeEffects.queue[i];
|
|
109
|
+
if (instance.defId !== effectId) {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (instance.remainingTicks > 0) {
|
|
113
|
+
instance.remainingTicks = 0;
|
|
114
|
+
flagged += 1;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return flagged;
|
|
118
|
+
}
|
|
119
|
+
activateAbility(casterEntityId, abilityId, providedTarget) {
|
|
120
|
+
if (!this.entityManager.getEntity(casterEntityId)) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
if (!this.registries.abilities.has(abilityId)) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
const snapshotTarget = providedTarget === undefined
|
|
127
|
+
? undefined
|
|
128
|
+
: {
|
|
129
|
+
entityId: providedTarget.entityId,
|
|
130
|
+
x: providedTarget.x,
|
|
131
|
+
z: providedTarget.z,
|
|
132
|
+
};
|
|
133
|
+
this.runtime.activationRequests.push({
|
|
134
|
+
casterEntityId,
|
|
135
|
+
abilityId,
|
|
136
|
+
providedTarget: snapshotTarget,
|
|
137
|
+
enqueueTick: this.runtime.currentTick,
|
|
138
|
+
});
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
registerHook(hookId, hook) {
|
|
142
|
+
this.registries.hooks.register(hookId, hook);
|
|
143
|
+
}
|
|
144
|
+
hasTag(entityId, tag) {
|
|
145
|
+
const entity = this.entityManager.getEntity(entityId);
|
|
146
|
+
if (!entity) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
const tags = getGameplayTagsComponent(entity);
|
|
150
|
+
if (!tags) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
return tags.tags.has(tag);
|
|
154
|
+
}
|
|
155
|
+
addTag(entityId, tag) {
|
|
156
|
+
const entity = this.requireEntity(entityId);
|
|
157
|
+
const tags = this.getOrCreateTags(entity);
|
|
158
|
+
tags.adHocTags.add(tag);
|
|
159
|
+
tags.tags.add(tag);
|
|
160
|
+
}
|
|
161
|
+
removeTag(entityId, tag) {
|
|
162
|
+
const entity = this.entityManager.getEntity(entityId);
|
|
163
|
+
if (!entity) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
const tags = getGameplayTagsComponent(entity);
|
|
167
|
+
if (!tags) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
const wasAdHoc = tags.adHocTags.delete(tag);
|
|
171
|
+
if (!wasAdHoc) {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
const grantCount = tags.effectGrantCounts.get(tag) ?? 0;
|
|
175
|
+
if (grantCount === 0) {
|
|
176
|
+
tags.tags.delete(tag);
|
|
177
|
+
}
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
get runtimeInternal() {
|
|
181
|
+
return this.runtime;
|
|
182
|
+
}
|
|
183
|
+
get gameplayCueBufferInternal() {
|
|
184
|
+
return this.runtime.gameplayCueBuffer;
|
|
185
|
+
}
|
|
186
|
+
requireEntity(entityId) {
|
|
187
|
+
const entity = this.entityManager.getEntity(entityId);
|
|
188
|
+
if (!entity) {
|
|
189
|
+
throw new Error(`Entity ${entityId} does not exist`);
|
|
190
|
+
}
|
|
191
|
+
return entity;
|
|
192
|
+
}
|
|
193
|
+
getOrCreateActiveEffects(entity) {
|
|
194
|
+
const existing = getActiveEffectsComponent(entity);
|
|
195
|
+
if (existing) {
|
|
196
|
+
return existing;
|
|
197
|
+
}
|
|
198
|
+
const component = new ActiveEffectsComponent();
|
|
199
|
+
entity.addComponent(component);
|
|
200
|
+
this.entityManager.onComponentAdded(entity, component.type);
|
|
201
|
+
return component;
|
|
202
|
+
}
|
|
203
|
+
getOrCreateTags(entity) {
|
|
204
|
+
const existing = getGameplayTagsComponent(entity);
|
|
205
|
+
if (existing) {
|
|
206
|
+
return existing;
|
|
207
|
+
}
|
|
208
|
+
const tags = new GameplayTagsComponent();
|
|
209
|
+
entity.addComponent(tags);
|
|
210
|
+
this.entityManager.onComponentAdded(entity, tags.type);
|
|
211
|
+
return tags;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { GameSystem, GameWorld, IAbilitySystem } from '@phalanx-engine/ecs';
|
|
2
|
+
import type { FixedPoint } from '@phalanx-engine/math';
|
|
3
|
+
import { AbilitySystemComponent } from '../components';
|
|
4
|
+
import type { CueConfig } from '../cues';
|
|
5
|
+
import type { GameplayCueBufferView } from '../runtime';
|
|
6
|
+
import type { AbilityHook, ProvidedTarget } from '../types';
|
|
7
|
+
import type { AttributeValue } from './AbilitySystemFacade';
|
|
8
|
+
import type { AbilitySystemDefinitions } from './defineAbilitySystem';
|
|
9
|
+
export type AbilitySystemPipeline = 'full' | 'activation' | 'effects' | 'effects-retain-cues' | 'attributes';
|
|
10
|
+
export type AttributeInitializer = FixedPoint | {
|
|
11
|
+
base: FixedPoint;
|
|
12
|
+
current?: FixedPoint;
|
|
13
|
+
};
|
|
14
|
+
export interface InitialEffect {
|
|
15
|
+
id: string;
|
|
16
|
+
sourceEntityId?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface AbilitySystemComponentInit {
|
|
19
|
+
attributes?: Record<string, AttributeInitializer>;
|
|
20
|
+
abilities?: readonly string[];
|
|
21
|
+
tags?: readonly string[];
|
|
22
|
+
effects?: readonly (string | InitialEffect)[];
|
|
23
|
+
}
|
|
24
|
+
export interface CreateAbilitySystemConfig {
|
|
25
|
+
definitions: AbilitySystemDefinitions;
|
|
26
|
+
hooks?: Record<string, AbilityHook>;
|
|
27
|
+
pipeline?: AbilitySystemPipeline;
|
|
28
|
+
cues?: CueConfig;
|
|
29
|
+
}
|
|
30
|
+
export interface AbilitySystem extends IAbilitySystem {
|
|
31
|
+
readonly tickSystems: readonly GameSystem[];
|
|
32
|
+
readonly gameplayCueBuffer: GameplayCueBufferView;
|
|
33
|
+
readonly instanceIdCounter: number;
|
|
34
|
+
readonly pendingActivationCount: number;
|
|
35
|
+
pendingActivationAbilityId(index: number): string | undefined;
|
|
36
|
+
initComponent(init?: AbilitySystemComponentInit): AbilitySystemComponent;
|
|
37
|
+
activateAbility(casterEntityId: number, abilityId: string, providedTarget?: ProvidedTarget): boolean;
|
|
38
|
+
applyEffect(targetEntityId: number, effectId: string, sourceEntityId?: number): void;
|
|
39
|
+
removeEffectsByTag(entityId: number, grantedTag: string): number;
|
|
40
|
+
removeEffectsByDefId(entityId: number, effectId: string): number;
|
|
41
|
+
getAttribute(entityId: number, attrId: string): AttributeValue;
|
|
42
|
+
tryGetAttribute(entityId: number, attrId: string): AttributeValue | undefined;
|
|
43
|
+
hasTag(entityId: number, tag: string): boolean;
|
|
44
|
+
addTag(entityId: number, tag: string): void;
|
|
45
|
+
removeTag(entityId: number, tag: string): boolean;
|
|
46
|
+
}
|
|
47
|
+
export declare function createAbilitySystem(world: GameWorld, config: CreateAbilitySystemConfig): AbilitySystem;
|
|
48
|
+
export declare const abilityComponentTypes: readonly symbol[];
|
|
49
|
+
//# sourceMappingURL=createAbilitySystem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createAbilitySystem.d.ts","sourceRoot":"","sources":["../../src/api/createAbilitySystem.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { FP } from '@phalanx-engine/math';
|
|
2
|
+
import { AbilitiesComponentType, AbilitySystemComponent, } from '../components';
|
|
3
|
+
import { AbilityActivationSystem, AbilityHookExecutorSystem, AttributeAggregationSystem, CueBufferCleanupSystem, CueDispatchSystem, CuePresentationSystem, EffectApplicationSystem, EffectTickSystem, } from '../systems';
|
|
4
|
+
import { createAbilitySystemRegistries } from '../registry';
|
|
5
|
+
import { createAbilitySystemRuntime } from '../runtime';
|
|
6
|
+
import { AbilitySystemFacade, NO_SOURCE_ENTITY_ID } from './AbilitySystemFacade';
|
|
7
|
+
export function createAbilitySystem(world, config) {
|
|
8
|
+
const registries = createAbilitySystemRegistries();
|
|
9
|
+
registerDefinitions(registries, config.definitions);
|
|
10
|
+
const runtime = createAbilitySystemRuntime();
|
|
11
|
+
const facade = new AbilitySystemFacade(world.entityManager, registries, runtime);
|
|
12
|
+
if (config.hooks) {
|
|
13
|
+
for (const [hookId, hook] of Object.entries(config.hooks)) {
|
|
14
|
+
facade.registerHook(hookId, hook);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
world.entityManager.registerComponentTypes(abilityComponentTypes);
|
|
18
|
+
const cues = config.cues ?? {};
|
|
19
|
+
const abilitySystem = new AbilitySystemImpl(registries, runtime, facade, config.pipeline ?? 'full', cues);
|
|
20
|
+
world.context.abilities = abilitySystem;
|
|
21
|
+
return abilitySystem;
|
|
22
|
+
}
|
|
23
|
+
export const abilityComponentTypes = [
|
|
24
|
+
AbilitiesComponentType.AbilitySystem,
|
|
25
|
+
AbilitiesComponentType.Attributes,
|
|
26
|
+
AbilitiesComponentType.ActiveEffects,
|
|
27
|
+
AbilitiesComponentType.GameplayTags,
|
|
28
|
+
];
|
|
29
|
+
class AbilitySystemImpl {
|
|
30
|
+
registries;
|
|
31
|
+
runtime;
|
|
32
|
+
facade;
|
|
33
|
+
tickSystems;
|
|
34
|
+
gameplayCueBuffer;
|
|
35
|
+
get instanceIdCounter() {
|
|
36
|
+
return this.runtime.instanceIdCounter.current;
|
|
37
|
+
}
|
|
38
|
+
get pendingActivationCount() {
|
|
39
|
+
return this.runtime.activationRequests.length;
|
|
40
|
+
}
|
|
41
|
+
pendingActivationAbilityId(index) {
|
|
42
|
+
return this.runtime.activationRequests[index]?.abilityId;
|
|
43
|
+
}
|
|
44
|
+
constructor(registries, runtime, facade, pipeline, cues) {
|
|
45
|
+
this.registries = registries;
|
|
46
|
+
this.runtime = runtime;
|
|
47
|
+
this.facade = facade;
|
|
48
|
+
this.gameplayCueBuffer = facade.gameplayCueBufferInternal;
|
|
49
|
+
this.tickSystems = buildTickSystems(registries, runtime, pipeline, cues);
|
|
50
|
+
}
|
|
51
|
+
initComponent(init = {}) {
|
|
52
|
+
const component = new AbilitySystemComponent(this.registries.attributes.size);
|
|
53
|
+
this.seedAttributes(component, init.attributes);
|
|
54
|
+
this.seedAbilities(component, init.abilities);
|
|
55
|
+
this.seedTags(component, init.tags);
|
|
56
|
+
this.seedEffects(component, init.effects);
|
|
57
|
+
return component;
|
|
58
|
+
}
|
|
59
|
+
activateAbility(casterEntityId, abilityId, providedTarget) {
|
|
60
|
+
return this.facade.activateAbility(casterEntityId, abilityId, providedTarget);
|
|
61
|
+
}
|
|
62
|
+
applyEffect(targetEntityId, effectId, sourceEntityId = NO_SOURCE_ENTITY_ID) {
|
|
63
|
+
this.facade.applyEffect(targetEntityId, effectId, sourceEntityId);
|
|
64
|
+
}
|
|
65
|
+
removeEffectsByTag(entityId, grantedTag) {
|
|
66
|
+
return this.facade.removeEffectsByTag(entityId, grantedTag);
|
|
67
|
+
}
|
|
68
|
+
removeEffectsByDefId(entityId, effectId) {
|
|
69
|
+
return this.facade.removeEffectsByDefId(entityId, effectId);
|
|
70
|
+
}
|
|
71
|
+
getAttribute(entityId, attrId) {
|
|
72
|
+
return this.facade.getAttribute(entityId, attrId);
|
|
73
|
+
}
|
|
74
|
+
tryGetAttribute(entityId, attrId) {
|
|
75
|
+
return this.facade.tryGetAttribute(entityId, attrId);
|
|
76
|
+
}
|
|
77
|
+
hasTag(entityId, tag) {
|
|
78
|
+
return this.facade.hasTag(entityId, tag);
|
|
79
|
+
}
|
|
80
|
+
addTag(entityId, tag) {
|
|
81
|
+
this.facade.addTag(entityId, tag);
|
|
82
|
+
}
|
|
83
|
+
removeTag(entityId, tag) {
|
|
84
|
+
return this.facade.removeTag(entityId, tag);
|
|
85
|
+
}
|
|
86
|
+
seedAttributes(component, overrides) {
|
|
87
|
+
const defs = this.registries.attributes.values();
|
|
88
|
+
for (let index = 0; index < defs.length; index++) {
|
|
89
|
+
const rawDefault = FP.ToRaw(defs[index].default);
|
|
90
|
+
component.attributes.base[index] = rawDefault;
|
|
91
|
+
component.attributes.current[index] = rawDefault;
|
|
92
|
+
component.attributes.dirty[index] = 1;
|
|
93
|
+
}
|
|
94
|
+
if (!overrides) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
for (const [attributeId, value] of Object.entries(overrides)) {
|
|
98
|
+
const index = this.registries.attributes.indexOf(attributeId);
|
|
99
|
+
const base = isAttributeValuePair(value) ? value.base : value;
|
|
100
|
+
const current = isAttributeValuePair(value) ? value.current ?? value.base : value;
|
|
101
|
+
component.attributes.base[index] = FP.ToRaw(base);
|
|
102
|
+
component.attributes.current[index] = FP.ToRaw(current);
|
|
103
|
+
component.attributes.dirty[index] = 1;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
seedAbilities(component, abilities) {
|
|
107
|
+
if (!abilities) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
for (const abilityId of abilities) {
|
|
111
|
+
if (!this.registries.abilities.has(abilityId)) {
|
|
112
|
+
throw new Error(`AbilityRegistry does not contain '${abilityId}'`);
|
|
113
|
+
}
|
|
114
|
+
component.abilities.add(abilityId);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
seedTags(component, tags) {
|
|
118
|
+
if (!tags) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
for (const tag of tags) {
|
|
122
|
+
component.tags.adHocTags.add(tag);
|
|
123
|
+
component.tags.tags.add(tag);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
seedEffects(component, effects) {
|
|
127
|
+
if (!effects) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
for (const entry of effects) {
|
|
131
|
+
const effectId = typeof entry === 'string' ? entry : entry.id;
|
|
132
|
+
if (!this.registries.effects.has(effectId)) {
|
|
133
|
+
throw new Error(`EffectRegistry does not contain '${effectId}'`);
|
|
134
|
+
}
|
|
135
|
+
component.activeEffects.pendingAdd.push({
|
|
136
|
+
defId: effectId,
|
|
137
|
+
sourceEntityId: typeof entry === 'string'
|
|
138
|
+
? NO_SOURCE_ENTITY_ID
|
|
139
|
+
: entry.sourceEntityId ?? NO_SOURCE_ENTITY_ID,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function registerDefinitions(registries, definitions) {
|
|
145
|
+
for (const attribute of definitions.attributes) {
|
|
146
|
+
registries.attributes.register(attribute);
|
|
147
|
+
}
|
|
148
|
+
for (const effect of definitions.effects ?? []) {
|
|
149
|
+
registries.effects.register(effect);
|
|
150
|
+
}
|
|
151
|
+
for (const ability of definitions.abilities ?? []) {
|
|
152
|
+
registries.abilities.register(ability);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function isAttributeValuePair(value) {
|
|
156
|
+
return (typeof value === 'object' &&
|
|
157
|
+
value !== null &&
|
|
158
|
+
'base' in value &&
|
|
159
|
+
!('precision' in value));
|
|
160
|
+
}
|
|
161
|
+
function buildTickSystems(registries, runtime, pipeline, cues) {
|
|
162
|
+
const effectApplication = new EffectApplicationSystem(registries, runtime);
|
|
163
|
+
const effectTick = new EffectTickSystem(registries, runtime);
|
|
164
|
+
const aggregation = new AttributeAggregationSystem(registries);
|
|
165
|
+
const cueCleanup = new CueBufferCleanupSystem(runtime);
|
|
166
|
+
const hasCues = Object.keys(cues).length > 0;
|
|
167
|
+
if (pipeline === 'effects-retain-cues' &&
|
|
168
|
+
!hasCues &&
|
|
169
|
+
process.env.NODE_ENV !== 'production') {
|
|
170
|
+
console.warn('[phalanx-abilities] pipeline "effects-retain-cues" with no cues registered: ' +
|
|
171
|
+
'the cue buffer is retained for manual inspection but nothing dispatches it.');
|
|
172
|
+
}
|
|
173
|
+
const systems = (() => {
|
|
174
|
+
switch (pipeline) {
|
|
175
|
+
case 'attributes':
|
|
176
|
+
return [aggregation];
|
|
177
|
+
case 'effects':
|
|
178
|
+
case 'effects-retain-cues': {
|
|
179
|
+
const base = [effectApplication, effectTick, aggregation];
|
|
180
|
+
if (hasCues) {
|
|
181
|
+
base.push(new CueDispatchSystem(runtime));
|
|
182
|
+
}
|
|
183
|
+
if (pipeline === 'effects') {
|
|
184
|
+
base.push(cueCleanup);
|
|
185
|
+
}
|
|
186
|
+
return base;
|
|
187
|
+
}
|
|
188
|
+
case 'activation':
|
|
189
|
+
case 'full':
|
|
190
|
+
return [
|
|
191
|
+
new AbilityActivationSystem(registries, runtime),
|
|
192
|
+
effectApplication,
|
|
193
|
+
new AbilityHookExecutorSystem(registries, runtime),
|
|
194
|
+
effectTick,
|
|
195
|
+
aggregation,
|
|
196
|
+
...(hasCues ? [new CueDispatchSystem(runtime)] : []),
|
|
197
|
+
cueCleanup,
|
|
198
|
+
];
|
|
199
|
+
}
|
|
200
|
+
})();
|
|
201
|
+
if (hasCues) {
|
|
202
|
+
systems.push(new CuePresentationSystem(cues));
|
|
203
|
+
}
|
|
204
|
+
return systems;
|
|
205
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineAbility.d.ts","sourceRoot":"","sources":["../../src/api/defineAbility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,UAAU,CAQzD"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function defineAbility(def) {
|
|
2
|
+
return {
|
|
3
|
+
...def,
|
|
4
|
+
tagsRequired: def.tagsRequired ? [...def.tagsRequired] : undefined,
|
|
5
|
+
activationBlockedTags: def.activationBlockedTags ? [...def.activationBlockedTags] : undefined,
|
|
6
|
+
selfEffectIds: def.selfEffectIds ? [...def.selfEffectIds] : undefined,
|
|
7
|
+
targetEffectIds: def.targetEffectIds ? [...def.targetEffectIds] : undefined,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AbilityDef, AttributeDef, EffectDef } from '../types';
|
|
2
|
+
export interface AbilitySystemDefinitions {
|
|
3
|
+
attributes: readonly AttributeDef[];
|
|
4
|
+
effects?: readonly EffectDef[];
|
|
5
|
+
abilities?: readonly AbilityDef[];
|
|
6
|
+
}
|
|
7
|
+
export declare function defineAbilitySystem(definitions: AbilitySystemDefinitions): AbilitySystemDefinitions;
|
|
8
|
+
//# sourceMappingURL=defineAbilitySystem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineAbilitySystem.d.ts","sourceRoot":"","sources":["../../src/api/defineAbilitySystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAEpE,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,SAAS,YAAY,EAAE,CAAC;IACpC,OAAO,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IAC/B,SAAS,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;CACnC;AAED,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,wBAAwB,GACpC,wBAAwB,CAM1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineAttribute.d.ts","sourceRoot":"","sources":["../../src/api/defineAttribute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,wBAAgB,eAAe,CAAC,GAAG,EAAE,YAAY,GAAG,YAAY,CAE/D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineEffect.d.ts","sourceRoot":"","sources":["../../src/api/defineEffect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,SAAS,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEnE,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,GAAG;IAC1D,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;CACxB,CAAC;AAEF,wBAAgB,YAAY,CAAC,GAAG,EAAE,cAAc,GAAG,SAAS,CAS3D"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function defineEffect(def) {
|
|
2
|
+
return {
|
|
3
|
+
...def,
|
|
4
|
+
modifiers: def.modifiers ? [...def.modifiers] : [],
|
|
5
|
+
tagsGranted: def.tagsGranted ? [...def.tagsGranted] : undefined,
|
|
6
|
+
tagsRequired: def.tagsRequired ? [...def.tagsRequired] : undefined,
|
|
7
|
+
tagsBlocked: def.tagsBlocked ? [...def.tagsBlocked] : undefined,
|
|
8
|
+
cues: cloneEffectCueSpec(def.cues),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function cloneEffectCueSpec(cues) {
|
|
12
|
+
if (!cues) {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
if (Array.isArray(cues)) {
|
|
16
|
+
return [...cues];
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
onApplied: cues.onApplied ? [...cues.onApplied] : undefined,
|
|
20
|
+
onPeriodic: cues.onPeriodic ? [...cues.onPeriodic] : undefined,
|
|
21
|
+
onExpired: cues.onExpired ? [...cues.onExpired] : undefined,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { defineAbility } from './defineAbility';
|
|
2
|
+
export { defineAttribute } from './defineAttribute';
|
|
3
|
+
export { defineAbilitySystem } from './defineAbilitySystem';
|
|
4
|
+
export { defineEffect } from './defineEffect';
|
|
5
|
+
export { createAbilitySystem, abilityComponentTypes } from './createAbilitySystem';
|
|
6
|
+
export { AbilitySystemFacade, NO_SOURCE_ENTITY_ID } from './AbilitySystemFacade';
|
|
7
|
+
export type { AttributeValue } from './AbilitySystemFacade';
|
|
8
|
+
export type { AbilitySystem, AbilitySystemComponentInit, AbilitySystemPipeline, AttributeInitializer, CreateAbilitySystemConfig, InitialEffect, } from './createAbilitySystem';
|
|
9
|
+
export type { AbilitySystemDefinitions } from './defineAbilitySystem';
|
|
10
|
+
export type { EffectDefInput } from './defineEffect';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACjF,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EACV,aAAa,EACb,0BAA0B,EAC1B,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,EACzB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACtE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { defineAbility } from './defineAbility';
|
|
2
|
+
export { defineAttribute } from './defineAttribute';
|
|
3
|
+
export { defineAbilitySystem } from './defineAbilitySystem';
|
|
4
|
+
export { defineEffect } from './defineEffect';
|
|
5
|
+
export { createAbilitySystem, abilityComponentTypes } from './createAbilitySystem';
|
|
6
|
+
export { AbilitySystemFacade, NO_SOURCE_ENTITY_ID } from './AbilitySystemFacade';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbilitiesComponentType.d.ts","sourceRoot":"","sources":["../../src/components/AbilitiesComponentType.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,sBAAsB;;;;;CAKjC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createComponentTypeRegistry } from '@phalanx-engine/ecs';
|
|
2
|
+
export const AbilitiesComponentType = createComponentTypeRegistry({
|
|
3
|
+
AbilitySystem: 'phalanx-abilities:AbilitySystem',
|
|
4
|
+
Attributes: 'phalanx-abilities:Attributes',
|
|
5
|
+
ActiveEffects: 'phalanx-abilities:ActiveEffects',
|
|
6
|
+
GameplayTags: 'phalanx-abilities:GameplayTags',
|
|
7
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Entity, IComponent } from '@phalanx-engine/ecs';
|
|
2
|
+
import { ActiveEffectsComponent } from './ActiveEffectsComponent';
|
|
3
|
+
import { AttributesComponent } from './AttributesComponent';
|
|
4
|
+
import { GameplayTagsComponent } from './GameplayTagsComponent';
|
|
5
|
+
export declare class AbilitySystemComponent implements IComponent {
|
|
6
|
+
readonly type: symbol;
|
|
7
|
+
readonly attributes: AttributesComponent;
|
|
8
|
+
readonly activeEffects: ActiveEffectsComponent;
|
|
9
|
+
readonly tags: GameplayTagsComponent;
|
|
10
|
+
readonly abilities: Set<string>;
|
|
11
|
+
constructor(attributeCount: number);
|
|
12
|
+
}
|
|
13
|
+
export declare function getAbilitySystemComponent(entity: Entity): AbilitySystemComponent | undefined;
|
|
14
|
+
export declare function getAttributesComponent(entity: Entity): AttributesComponent | undefined;
|
|
15
|
+
export declare function getActiveEffectsComponent(entity: Entity): ActiveEffectsComponent | undefined;
|
|
16
|
+
export declare function getGameplayTagsComponent(entity: Entity): GameplayTagsComponent | undefined;
|
|
17
|
+
//# sourceMappingURL=AbilitySystemComponent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbilitySystemComponent.d.ts","sourceRoot":"","sources":["../../src/components/AbilitySystemComponent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAQhE,qBAAa,sBAAuB,YAAW,UAAU;IACvD,SAAgB,IAAI,SAAwC;IAC5D,SAAgB,UAAU,EAAE,mBAAmB,CAAC;IAChD,SAAgB,aAAa,EAAE,sBAAsB,CAAC;IACtD,SAAgB,IAAI,EAAE,qBAAqB,CAAC;IAC5C,SAAgB,SAAS,cAAqB;gBAE3B,cAAc,EAAE,MAAM;CAK1C;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS,CAE5F;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAKtF;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS,CAK5F;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS,CAK1F"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { AbilitiesComponentType } from './AbilitiesComponentType';
|
|
2
|
+
import { ActiveEffectsComponent } from './ActiveEffectsComponent';
|
|
3
|
+
import { AttributesComponent } from './AttributesComponent';
|
|
4
|
+
import { GameplayTagsComponent } from './GameplayTagsComponent';
|
|
5
|
+
export class AbilitySystemComponent {
|
|
6
|
+
type = AbilitiesComponentType.AbilitySystem;
|
|
7
|
+
attributes;
|
|
8
|
+
activeEffects;
|
|
9
|
+
tags;
|
|
10
|
+
abilities = new Set();
|
|
11
|
+
constructor(attributeCount) {
|
|
12
|
+
this.attributes = new AttributesComponent(attributeCount);
|
|
13
|
+
this.activeEffects = new ActiveEffectsComponent();
|
|
14
|
+
this.tags = new GameplayTagsComponent();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function getAbilitySystemComponent(entity) {
|
|
18
|
+
return entity.getComponent(AbilitiesComponentType.AbilitySystem);
|
|
19
|
+
}
|
|
20
|
+
export function getAttributesComponent(entity) {
|
|
21
|
+
return (getAbilitySystemComponent(entity)?.attributes ??
|
|
22
|
+
entity.getComponent(AbilitiesComponentType.Attributes));
|
|
23
|
+
}
|
|
24
|
+
export function getActiveEffectsComponent(entity) {
|
|
25
|
+
return (getAbilitySystemComponent(entity)?.activeEffects ??
|
|
26
|
+
entity.getComponent(AbilitiesComponentType.ActiveEffects));
|
|
27
|
+
}
|
|
28
|
+
export function getGameplayTagsComponent(entity) {
|
|
29
|
+
return (getAbilitySystemComponent(entity)?.tags ??
|
|
30
|
+
entity.getComponent(AbilitiesComponentType.GameplayTags));
|
|
31
|
+
}
|