refactor: harm

This commit is contained in:
cha0s 2024-10-18 07:49:15 -05:00
parent b2b52b5414
commit 6c815e7749
6 changed files with 102 additions and 4 deletions

View File

@ -0,0 +1,31 @@
import Component from '@/ecs/component.js';
export default class Harmful extends Component {
instanceFromSchema() {
const {ecs} = this;
return class HarmfulInstance extends super.instanceFromSchema() {
harm(other) {
const entity = ecs.get(this.entity);
const script = this.$$harm.clone();
script.locals.other = other;
script.locals.entity = entity;
entity.Ticking.add(script.ticker());
}
}
}
load(instance) {
// heavy handed...
if ('undefined' !== typeof window) {
return;
}
instance.$$harm = this.ecs.readScript(
instance.harmScript,
{
ecs: this.ecs,
},
);
}
static properties = {
harmScript: {type: 'string'},
};
}

View File

@ -1,4 +1,6 @@
import Component from '@/ecs/component.js';
import * as Math from '@/util/math.js';
import Ticker from '@/util/ticker.js';
export const DamageTypes = {
PAIN: 0,
@ -21,12 +23,20 @@ export default class Vulnerable extends Component {
const Component = this;
return class VulnerableInstance extends super.instanceFromSchema() {
id = 0;
locked = new Set();
Types = DamageTypes;
damage(specification) {
damage(fullSpecification) {
if (this.isInvulnerable) {
return;
}
const {Alive} = Component.ecs.get(this.entity);
const {
lockout,
...specification
} = fullSpecification;
if (lockout && this.locked.has(lockout.subject)) {
return;
}
const {Alive, Forces, Position, Ticking} = Component.ecs.get(this.entity);
if (Alive) {
switch (specification.type) {
case DamageTypes.HEALING:
@ -35,6 +45,28 @@ export default class Vulnerable extends Component {
}
}
}
if (specification.knockback) {
const diff = Math.normalizeVector({
x: Position.x - specification.knockback.origin.x,
y: Position.y - specification.knockback.origin.y,
});
Forces.applyImpulse({
x: diff.x * specification.knockback.magnitude,
y: diff.y * specification.knockback.magnitude,
});
}
if (lockout) {
let {duration, subject} = lockout;
const self = this;
self.locked.add(subject);
Ticking.add(new Ticker(function*() {
while (duration > 0) {
const elapsed = yield;
duration -= elapsed;
}
self.locked.delete(subject);
}));
}
Component.markChange(
this.entity,
'damage',

24
app/ecs/systems/harm.js Normal file
View File

@ -0,0 +1,24 @@
import {System} from '@/ecs/index.js';
export default class Harm extends System {
static queries() {
return {
default: ['Collider', 'Harmful'],
};
}
tick() {
for (const entity of this.select('default')) {
const intersecting = new Set();
for (const [other] of entity.Collider.$$intersections) {
intersecting.add(this.ecs.get(other.entity));
}
for (const other of intersecting) {
entity.Harmful.harm(other);
}
}
}
}

View File

@ -9,6 +9,7 @@ export default function createEcs(Ecs) {
'Attract',
'ResetForces',
'ApplyControlMovement',
'Harm',
'IntegratePhysics',
'ClampPositions',
'PlantGrowth',

View File

@ -3,12 +3,20 @@ import * as Math from '@/util/math.js';
export default function*({ecs, entity, other}) {
const playerEntity = ecs.lookupPlayerEntity(entity.Owned.owner);
if (playerEntity !== other && other.Vulnerable) {
const magnitude = Math.floor(Math.random() * 2)
const magnitude = Math.floor(Math.random() * 1);
other.Vulnerable.damage({
amount: -Math.floor(
Math.pow(10, magnitude)
+ Math.random() * (Math.pow(10, magnitude + 1) - Math.pow(10, magnitude)),
),
knockback: {
magnitude: 150,
origin: entity.Position,
},
lockout: {
duration: 0.5,
subject: entity,
},
position: other.Position.toJSON(),
type: other.Vulnerable.Types.PAIN,
})

View File

@ -28,11 +28,13 @@ export default function*(locals) {
unstoppable: 1,
},
],
collisionStartScript: '/resources/magic-swords/collision-start.js',
},
Controlled: {},
Direction: {direction: offset + Math.TAU * (i / N)},
Forces: {},
Harmful: {
harmScript: '/resources/magic-swords/harm.js',
},
Light: {brightness: 0},
Owned: {owner: Player ? Player.id : 0},
Position: {x: Position.x, y: Position.y},