refactor: harm
This commit is contained in:
parent
b2b52b5414
commit
6c815e7749
31
app/ecs/components/harmful.js
Normal file
31
app/ecs/components/harmful.js
Normal 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'},
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
import Component from '@/ecs/component.js';
|
import Component from '@/ecs/component.js';
|
||||||
|
import * as Math from '@/util/math.js';
|
||||||
|
import Ticker from '@/util/ticker.js';
|
||||||
|
|
||||||
export const DamageTypes = {
|
export const DamageTypes = {
|
||||||
PAIN: 0,
|
PAIN: 0,
|
||||||
|
@ -21,12 +23,20 @@ export default class Vulnerable extends Component {
|
||||||
const Component = this;
|
const Component = this;
|
||||||
return class VulnerableInstance extends super.instanceFromSchema() {
|
return class VulnerableInstance extends super.instanceFromSchema() {
|
||||||
id = 0;
|
id = 0;
|
||||||
|
locked = new Set();
|
||||||
Types = DamageTypes;
|
Types = DamageTypes;
|
||||||
damage(specification) {
|
damage(fullSpecification) {
|
||||||
if (this.isInvulnerable) {
|
if (this.isInvulnerable) {
|
||||||
return;
|
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) {
|
if (Alive) {
|
||||||
switch (specification.type) {
|
switch (specification.type) {
|
||||||
case DamageTypes.HEALING:
|
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(
|
Component.markChange(
|
||||||
this.entity,
|
this.entity,
|
||||||
'damage',
|
'damage',
|
||||||
|
|
24
app/ecs/systems/harm.js
Normal file
24
app/ecs/systems/harm.js
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ export default function createEcs(Ecs) {
|
||||||
'Attract',
|
'Attract',
|
||||||
'ResetForces',
|
'ResetForces',
|
||||||
'ApplyControlMovement',
|
'ApplyControlMovement',
|
||||||
|
'Harm',
|
||||||
'IntegratePhysics',
|
'IntegratePhysics',
|
||||||
'ClampPositions',
|
'ClampPositions',
|
||||||
'PlantGrowth',
|
'PlantGrowth',
|
||||||
|
|
|
@ -3,12 +3,20 @@ import * as Math from '@/util/math.js';
|
||||||
export default function*({ecs, entity, other}) {
|
export default function*({ecs, entity, other}) {
|
||||||
const playerEntity = ecs.lookupPlayerEntity(entity.Owned.owner);
|
const playerEntity = ecs.lookupPlayerEntity(entity.Owned.owner);
|
||||||
if (playerEntity !== other && other.Vulnerable) {
|
if (playerEntity !== other && other.Vulnerable) {
|
||||||
const magnitude = Math.floor(Math.random() * 2)
|
const magnitude = Math.floor(Math.random() * 1);
|
||||||
other.Vulnerable.damage({
|
other.Vulnerable.damage({
|
||||||
amount: -Math.floor(
|
amount: -Math.floor(
|
||||||
Math.pow(10, magnitude)
|
Math.pow(10, magnitude)
|
||||||
+ Math.random() * (Math.pow(10, magnitude + 1) - 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(),
|
position: other.Position.toJSON(),
|
||||||
type: other.Vulnerable.Types.PAIN,
|
type: other.Vulnerable.Types.PAIN,
|
||||||
})
|
})
|
|
@ -28,11 +28,13 @@ export default function*(locals) {
|
||||||
unstoppable: 1,
|
unstoppable: 1,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
collisionStartScript: '/resources/magic-swords/collision-start.js',
|
|
||||||
},
|
},
|
||||||
Controlled: {},
|
Controlled: {},
|
||||||
Direction: {direction: offset + Math.TAU * (i / N)},
|
Direction: {direction: offset + Math.TAU * (i / N)},
|
||||||
Forces: {},
|
Forces: {},
|
||||||
|
Harmful: {
|
||||||
|
harmScript: '/resources/magic-swords/harm.js',
|
||||||
|
},
|
||||||
Light: {brightness: 0},
|
Light: {brightness: 0},
|
||||||
Owned: {owner: Player ? Player.id : 0},
|
Owned: {owner: Player ? Player.id : 0},
|
||||||
Position: {x: Position.x, y: Position.y},
|
Position: {x: Position.x, y: Position.y},
|
||||||
|
|
Loading…
Reference in New Issue
Block a user