Further progress with Entity Manager
~ Made some changes to try to make it compile (doesn't compile yet)
This commit is contained in:
parent
052a37b36f
commit
894def692c
4 changed files with 965 additions and 209 deletions
|
@ -8,8 +8,11 @@
|
|||
"$className": "DataModel",
|
||||
"ServerScriptService": {
|
||||
"$className": "ServerScriptService",
|
||||
"TS": {
|
||||
"Server": {
|
||||
"$path": "out/server"
|
||||
},
|
||||
"Game": {
|
||||
"$path": "out/game"
|
||||
}
|
||||
},
|
||||
"StarterPlayer": {
|
||||
|
|
861
package-lock.json
generated
861
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -21,5 +21,8 @@
|
|||
"eslint-plugin-roblox-ts": "^0.0.31",
|
||||
"prettier": "^2.3.2",
|
||||
"typescript": "^4.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"roblox-ts": "^1.3.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
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 [[maxHealth: number, defense: number], [power: number, speed: number, resistance: number]]; // values used for calculation, only modified by buffs and debuffs (the first group is additive, the second multiplicative)
|
||||
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)
|
||||
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, (entity: entity) => entity];
|
||||
|
||||
type statusEffect = readonly [string, modifiers, entityTransformTemplate, number];
|
||||
|
||||
export interface entityController {
|
||||
setPosition: (location: Vector3) => void;
|
||||
useAbility: (abilityName: string, activating: boolean) => void;
|
||||
|
@ -32,27 +32,27 @@ export interface entityModifier {}
|
|||
return resultOfFirstAbilityPart = ableToUse ? useAbilityPart(ability.firstPart, setOfAllEntities, thisEntity) : [ableToUse]
|
||||
*/
|
||||
interface entityStats {
|
||||
statuses: statuses // Health and stuff that change constantly
|
||||
baseModifiers: modifiers // Base modifiers that change only when the player switches weapons or something
|
||||
immunities: {
|
||||
[statusEffectName: string]: boolean | undefined
|
||||
}
|
||||
statusEffects: statusEffect[] // Burn, poison, etc.
|
||||
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
|
||||
readonly name: string;
|
||||
readonly team: "players" | "enemies";
|
||||
readonly isMinion: boolean;
|
||||
}
|
||||
export interface entity {
|
||||
readonly id: entityId
|
||||
stats: entityStats
|
||||
puppet: puppet
|
||||
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
|
||||
// type entityTransform = (entity: entity) => entity;
|
||||
// interface entityTransformTemplate {
|
||||
type abuiloga = (entityPerformingId: entityId, entityReceivingId: entityId) => entityTransformTemplate | false
|
||||
/*
|
||||
allies: {
|
||||
minions: {
|
||||
|
@ -64,15 +64,23 @@ type abuiloga = (entityPerformingId: entityId, entityReceivingId: entityId) => e
|
|||
affectsMinions: boolean,
|
||||
excludesSelf: boolean,
|
||||
affectsSameTeam: boolean,
|
||||
*///}
|
||||
type entityTransformType = "heal" | "attack"
|
||||
*/ //}
|
||||
type entityTransformType = "heal" | "attack";
|
||||
interface entityTransformTemplate {
|
||||
extraFunction: (entityPerformingTransform: entity, entityReceivingTransform: entity) => boolean
|
||||
thingus: entityTransformType
|
||||
magnitude: number, // Positive for heal, negative for damage
|
||||
affectsHealth: boolean
|
||||
affectsBarrier: boolean
|
||||
statusEffectsGranted: placeholder[], // Stuff like burn, slow, stun, etc.*/
|
||||
thingus: entityTransformType;
|
||||
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,
|
||||
) => 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
|
||||
|
@ -92,31 +100,82 @@ interface entityTransformTemplate {
|
|||
}
|
||||
return [onSameTeam]
|
||||
}*/
|
||||
function applyEntityToAttack(entityModifiers: modifiers, entityStatusEffects: statusEffect[], magnitude: number): number {
|
||||
function applyEntityToAttack(
|
||||
entityModifiers: modifiers,
|
||||
entityStatusEffects: statusEffect[],
|
||||
magnitude: number,
|
||||
): number {
|
||||
const attack = applyModifiersToAttack(magnitude, entityModifiers);
|
||||
// + Apply status effects of performing entity to attack (e.g. weaken)
|
||||
return attack
|
||||
return attack;
|
||||
}
|
||||
function applyAttackToEntityStatuses(entityStatuses: statuses, entityModifiers: modifiers, entityStatusEffects: statusEffect[], attack: number, affectsHealth: boolean, affectsBarrier: boolean): statuses { // Not sure if this should return a whole entity
|
||||
function applyAttackToEntityStatuses(
|
||||
entityStatuses: statuses,
|
||||
entityModifiers: modifiers,
|
||||
entityStatusEffects: statusEffect[],
|
||||
attack: number,
|
||||
affectsHealth: boolean,
|
||||
affectsBarrier: boolean,
|
||||
): statuses {
|
||||
// Not sure if this should return a whole entity
|
||||
// + Apply status effects of receiving entity to damage (e.g. armor break)
|
||||
const damage = applyModifiersToAttack(attack, entityModifiers);
|
||||
const newStatuses = applyDamageToStatuses(entityStatuses, damage, affectsHealth, affectsBarrier);
|
||||
return entityStatuses
|
||||
return entityStatuses;
|
||||
}
|
||||
function makeEntityTransform(entityPerformingTransformId: entityId, abuiloga: abuiloga): (entityReceivingTransform: entity) => entityStats {
|
||||
return function(entityReceivingTransform: entity): entityStats {
|
||||
const entityTransformTemplate = abuiloga(entityPerformingTransformId, entityReceivingTransform.id);
|
||||
|
||||
const newStats = transformEntityStatuses( // All of this stuff should be packed into one object, maybe a new entityTransformTemplate
|
||||
entityReceivingTransform.stats.statuses,
|
||||
finalCalculatedMaxHealth,
|
||||
finalCalculatedMaxBarrier,
|
||||
entityTransformTemplate.thingus,
|
||||
finalCalculatedMagnitude,
|
||||
finalCalculatedAffectsHealth,
|
||||
finalCalculatedAffectsBarrier) // L
|
||||
// const newEntity = entityTransformTemplate ? applyEntityTransform(entityPerformingTransform, entityReceivingTransform, onSameTeam, template[1]) : entityReceivingTransform;
|
||||
return newStats
|
||||
// ? Are you meant to pipe determineEntityTransform into the resulting function?
|
||||
/*function determineEntityTransform(
|
||||
entityPerformingTransformId: entityId,
|
||||
entityReceivingTransform: entityId,
|
||||
): entityTransformTemplate | false {
|
||||
return false; // Placeholder
|
||||
}
|
||||
*/
|
||||
function transformEntityStats(
|
||||
entityPerformingTransform: entity,
|
||||
entityStats: entityStats,
|
||||
entityTransformTemplate: entityTransformTemplate,
|
||||
baseModifiers: modifiers,
|
||||
maxStatuses: statuses,
|
||||
): entityStats {
|
||||
const transformType = entityTransformTemplate.thingus;
|
||||
if (transformType === "attack") {
|
||||
const outgoingAttack = applyModifiersToAttack(
|
||||
entityTransformTemplate.magnitude,
|
||||
entityPerformingTransform.baseModifiers,
|
||||
);
|
||||
// Apply user's status effects to outgoing attack
|
||||
// Apply receiver's status effects to incoming damage
|
||||
const incomingDamage = applyModifiersToDamage(outgoingAttack, baseModifiers);
|
||||
const newEntityStatuses = applyDamageToStatuses(
|
||||
entityStats.statuses,
|
||||
incomingDamage,
|
||||
entityTransformTemplate.affectsHealth,
|
||||
entityTransformTemplate.affectsBarrier,
|
||||
);
|
||||
// Add or remove status effects
|
||||
return {
|
||||
statuses: newEntityStatuses,
|
||||
statusEffects: entityStats.statusEffects, // Placeholder
|
||||
};
|
||||
} else if (transformType === "heal") {
|
||||
const outgoingHeal = entityTransformTemplate.magnitude; // There could be a heal modifier later
|
||||
// Apply user's status effects to outgoing heal
|
||||
// Apply receiver's status effects to incoming heal
|
||||
const newEntityStatuses = applyHealToStatuses(
|
||||
entityStats.statuses, // DRY alert
|
||||
outgoingHeal,
|
||||
entityTransformTemplate.affectsHealth,
|
||||
entityTransformTemplate.affectsBarrier,
|
||||
maxStatuses,
|
||||
);
|
||||
// Add or remove status effects
|
||||
return {
|
||||
statuses: newEntityStatuses,
|
||||
statusEffects: entityStats.statusEffects, // Placeholder
|
||||
};
|
||||
} else {
|
||||
throw "Unknown entity transform type " + transformType; // Should be never
|
||||
}
|
||||
}
|
||||
/*interface entityTransform extends entityTransformTemplate {
|
||||
|
@ -124,8 +183,8 @@ function makeEntityTransform(entityPerformingTransformId: entityId, abuiloga: ab
|
|||
team: "players" | "enemies",
|
||||
}*/
|
||||
type abilityTemplate = [
|
||||
[entityTransformTemplate[], number] // I guess the number is a delay until the next part or something
|
||||
]
|
||||
[entityTransformTemplate[], number], // I guess the number is a delay until the next part or something
|
||||
];
|
||||
/*type ability = [
|
||||
[entityTransform[], number]
|
||||
]*/
|
||||
|
@ -133,95 +192,135 @@ type abilityTemplate = [
|
|||
// const ability = getAbility
|
||||
// const entities = applyAbilityToScene(scene, ability)
|
||||
|
||||
function applyDamageToHealth(health: number, damage: number): [newHealth: number, excessDamage: number] { // Needs testing
|
||||
const newHealth = health - damage
|
||||
function applyDamageToHealth(health: number, damage: number): [newHealth: number, excessDamage: number] {
|
||||
// Needs testing
|
||||
const newHealth = health - damage;
|
||||
if (newHealth < 0) {
|
||||
return [0, -newHealth]
|
||||
return [0, -newHealth];
|
||||
} else {
|
||||
return [newHealth, 0]
|
||||
return [newHealth, 0];
|
||||
}
|
||||
}
|
||||
const applyDamageToBarrier = applyDamageToHealth
|
||||
function applyDamageToStatuses(statuses: statuses, damage: number, affectsHealth: boolean, affectsBarrier: boolean): statuses {
|
||||
const applyDamageToBarrier = applyDamageToHealth;
|
||||
function applyDamageToStatuses(
|
||||
statuses: statuses,
|
||||
damage: number,
|
||||
affectsHealth: boolean,
|
||||
affectsBarrier: boolean,
|
||||
): statuses {
|
||||
if (affectsBarrier) {
|
||||
const [newBarrier, excessBarrierDamage] = applyDamageToBarrier(statuses[1], damage)
|
||||
const [newHealth, excessHealthDamage] = applyDamageToHealth(statuses[0], affectsHealth? excessBarrierDamage : 0)
|
||||
return [newHealth, newBarrier]
|
||||
const [newBarrier, excessBarrierDamage] = applyDamageToBarrier(statuses[1], damage);
|
||||
const [newHealth, excessHealthDamage] = applyDamageToHealth(
|
||||
statuses[0],
|
||||
affectsHealth ? excessBarrierDamage : 0,
|
||||
);
|
||||
return [newHealth, newBarrier];
|
||||
} else if (affectsHealth) {
|
||||
const [newHealth, excessHealthDamage] = applyDamageToHealth(statuses[0], damage)
|
||||
return [newHealth, statuses[1]]
|
||||
const [newHealth, excessHealthDamage] = applyDamageToHealth(statuses[0], damage);
|
||||
return [newHealth, statuses[1]];
|
||||
} else {
|
||||
return statuses
|
||||
return statuses;
|
||||
}
|
||||
}
|
||||
function applyHealToHealth(currentHealth: number, heal: number, maxHealth: number): [newHealth: number, excessHeal: number] {
|
||||
const newHealth = currentHealth + heal
|
||||
function applyHealToHealth(
|
||||
currentHealth: number,
|
||||
heal: number,
|
||||
maxHealth: number,
|
||||
): [newHealth: number, excessHeal: number] {
|
||||
const newHealth = currentHealth + heal;
|
||||
if (newHealth > maxHealth) {
|
||||
return [maxHealth, newHealth - maxHealth]
|
||||
return [maxHealth, newHealth - maxHealth];
|
||||
} else {
|
||||
return [newHealth, 0]
|
||||
return [newHealth, 0];
|
||||
}
|
||||
}
|
||||
const applyHealToBarrier = applyHealToHealth
|
||||
function applyHealToStatuses(statuses: statuses, heal: number, maxHealth: number, maxBarrier: number, affectsHealth: boolean, affectsBarrier: boolean): statuses {
|
||||
const applyHealToBarrier = applyHealToHealth;
|
||||
function applyHealToStatuses(
|
||||
statuses: statuses,
|
||||
heal: number,
|
||||
affectsHealth: boolean,
|
||||
affectsBarrier: boolean,
|
||||
maxStatuses: statuses,
|
||||
): statuses {
|
||||
if (affectsHealth) {
|
||||
const [newHealth, excessHealth] = applyHealToHealth(statuses[0], heal, maxHealth)
|
||||
const [newBarrier, excessBarrier] = applyHealToBarrier(statuses[1], affectsBarrier ? excessHealth : 0, maxBarrier)
|
||||
return [newHealth, newBarrier]
|
||||
} else if (affectsBarrier) { // Using a branch isn't optimal, but as of writing I can't think of a better solution
|
||||
const [newBarrier, excessBarrier] = applyHealToBarrier(statuses[1], heal, maxBarrier)
|
||||
return [statuses[0], newBarrier]
|
||||
const [newHealth, excessHealth] = applyHealToHealth(statuses[0], heal, maxStatuses[0]);
|
||||
const [newBarrier, excessBarrier] = applyHealToBarrier(
|
||||
statuses[1],
|
||||
affectsBarrier ? excessHealth : 0,
|
||||
maxStatuses[1],
|
||||
);
|
||||
return [newHealth, newBarrier];
|
||||
} else if (affectsBarrier) {
|
||||
// Using a branch isn't optimal, but as of writing I can't think of a better solution
|
||||
const [newBarrier, excessBarrier] = applyHealToBarrier(statuses[1], heal, maxStatuses[1]);
|
||||
return [statuses[0], newBarrier];
|
||||
} else {
|
||||
return statuses
|
||||
return statuses;
|
||||
}
|
||||
}
|
||||
function transformEntityStatuses(entityStatuses: statuses, maxHealth: number, maxBarrier: number, transformType: string, magnitude: number, affectsHealth: boolean, affectsBarrier: boolean): statuses {
|
||||
if (transformType == "heal") {
|
||||
const newStatuses = applyHealToStatuses(entityStatuses, magnitude, maxHealth, maxBarrier, affectsHealth, affectsBarrier) // More chaining method calls...
|
||||
return newStatuses
|
||||
} else if (transformType == "attack") {
|
||||
const newStatuses = applyDamageToStatuses(entityStatuses, magnitude, affectsHealth, affectsBarrier)
|
||||
return newStatuses
|
||||
} else {
|
||||
throw "Unimplemented transformType " + transformType
|
||||
}
|
||||
}// Damage should come before status effects are applied
|
||||
function applyPowerToAttack(attack: number, power: number) {
|
||||
return attack*power
|
||||
function applyPowerToAttack(attack: number, power: number) {
|
||||
return attack * power;
|
||||
}
|
||||
function applyModifiersToAttack(attack: number, modifiers: modifiers): number { // Get arguments they use (a bit sketchy)
|
||||
return applyPowerToAttack(attack, modifiers[1][0])
|
||||
function applyModifiersToAttack(attack: number, modifiers: modifiers): number {
|
||||
// Get arguments they use (a bit sketchy)
|
||||
return applyPowerToAttack(attack, modifiers[0]);
|
||||
}
|
||||
function applyResistanceToDamage(damage: number, resistance: number): number {
|
||||
return damage*(1 - resistance)
|
||||
return damage * (1 - resistance);
|
||||
}
|
||||
function applyDefenseToDamage(damage: number, defense: number): number {
|
||||
return damage - defense
|
||||
return damage - defense;
|
||||
}
|
||||
function applyModifiersToDamage(damage: number, modifiers: modifiers): number {
|
||||
return applyResistanceToDamage(applyDefenseToDamage(damage, modifiers[0][1]), modifiers[1][2])
|
||||
return applyResistanceToDamage(applyDefenseToDamage(damage, modifiers[2]), modifiers[3]);
|
||||
}
|
||||
function modifiersArrayFunction(applyModifiersToNumber: (number: number, modifiers: modifiers) => number): (number: number, modifiers: modifiers[]) => number {
|
||||
return function(number: number, modifiersArray: modifiers[]) {
|
||||
let newNumber = number
|
||||
modifiersArray.forEach(function(modifiers: modifiers) {
|
||||
newNumber = applyModifiersToNumber(newNumber, modifiers)
|
||||
})
|
||||
return newNumber
|
||||
}
|
||||
function modifiersArrayFunction(
|
||||
applyModifiersToNumber: (number: number, modifiers: modifiers) => number,
|
||||
): (number: number, modifiers: modifiers[]) => number {
|
||||
return function (number: number, modifiersArray: modifiers[]) {
|
||||
let newNumber = number;
|
||||
modifiersArray.forEach(function (modifiers: modifiers) {
|
||||
newNumber = applyModifiersToNumber(newNumber, modifiers);
|
||||
});
|
||||
return newNumber;
|
||||
};
|
||||
}
|
||||
const applyModifiersArrayToAttack = modifiersArrayFunction(applyModifiersToAttack);
|
||||
const applyModifiersArrayToDamage = modifiersArrayFunction(applyModifiersToDamage);
|
||||
function getEntityByName(entityList: entity[], entityName: string): success<entity> {
|
||||
entityList.forEach(function(entity: entity) {
|
||||
if (entity.id.name == entityName) { // Chained method calls are cringe
|
||||
return [true, entity]
|
||||
entityList.forEach(function (entity: entity) {
|
||||
if (entity.id.name === entityName) {
|
||||
// Chained method calls are cringe
|
||||
return [true, entity];
|
||||
}
|
||||
})
|
||||
return [false, "Entity not found"]
|
||||
});
|
||||
return [false, "Entity not found"];
|
||||
}
|
||||
function getAbility() {}
|
||||
function useAbility(entityList: entity[], entityUsing: entity, aim: Vector3): [entity[], placeholder[]] {
|
||||
function applyEntityTransformToEntityList(
|
||||
entityList: entity[],
|
||||
entityTransformDeterminer: entityTransformDeterminer,
|
||||
entityPerformingTransform: entity,
|
||||
aim: Vector3,
|
||||
): [entity[], placeholder[]?] {
|
||||
const newEntityList = entityList.map(function (entityReceivingTransform: entity): entity {
|
||||
const entityTransformTemplate = entityTransformDeterminer(
|
||||
entityPerformingTransform.id,
|
||||
entityReceivingTransform.id,
|
||||
entityPerformingTransform.puppet,
|
||||
entityReceivingTransform.puppet,
|
||||
);
|
||||
const newEntityStats = entityTransformTemplate
|
||||
? transformEntityStats(
|
||||
entityPerformingTransform,
|
||||
entityReceivingTransform.stats,
|
||||
entityTransformTemplate,
|
||||
entityReceivingTransform.baseModifiers,
|
||||
entityReceivingTransform.maxStatuses,
|
||||
)
|
||||
: entityReceivingTransform.stats;
|
||||
});
|
||||
return [newEntityList];
|
||||
}
|
||||
/*class entityHandler implements entityController {
|
||||
constructor(baseStats: stats, baseAmounts: amounts, puppetEntry: puppetEntry) {
|
||||
|
@ -287,4 +386,4 @@ class entityManager extends actorClass<entityManagerRequest> {
|
|||
export function initEntityManager() {
|
||||
return new entityManager();
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue