This commit is contained in:
cha0s 2020-12-31 18:35:06 -06:00
parent ec0487d49c
commit 156e7c7f47
140 changed files with 37223 additions and 2085 deletions

View File

@ -18,13 +18,21 @@ module.exports = {
const {files = [], name} = neutrino.options.packageJson;
files
.filter((file) => {
const {source} = neutrino.options;
try {
require.resolve(`${neutrino.options.source}/${file}`);
require.resolve(`${source}/${file}`);
return true;
}
catch (error) {
const ext = extname(file);
try {
require.resolve(`${source}/${dirname(file)}/${basename(file, ext)}/index${ext}`);
return true;
}
catch (error) {
return false;
}
}
})
.forEach((file) => {
const isIndex = 'index.js' === file;

View File

@ -20,9 +20,9 @@
"index.js.map"
],
"dependencies": {
"@avocado/core": "^2.0.0",
"@avocado/entity": "^2.0.0",
"@latus/core": "^2.0.0",
"@avocado/core": "2.0.0",
"@avocado/traits": "^2.0.0",
"@latus/core": "2.0.0",
"debug": "4.3.1",
"deepmerge": "^4.2.2",
"lodash.mapvalues": "^4.6.0"

View File

@ -1,4 +1,4 @@
import {StateProperty, Trait} from '@avocado/entity';
import {StateProperty, Trait} from '@avocado/traits';
import {compose} from '@latus/core';
import mapValues from 'lodash.mapvalues';

File diff suppressed because it is too large Load Diff

View File

@ -20,14 +20,15 @@
"index.js.map"
],
"dependencies": {
"@avocado/behavior": "^2.0.0",
"@avocado/behavior": "2.0.0",
"@avocado/core": "2.0.0",
"@avocado/math": "2.0.0",
"@avocado/resource": "2.0.0",
"@avocado/s13n": "^2.0.0",
"@avocado/timing": "^2.0.0",
"@latus/core": "^2.0.0",
"@latus/socket": "^2.0.0",
"@avocado/s13n": "2.0.0",
"@avocado/timing": "2.0.0",
"@avocado/traits": "^2.0.0",
"@latus/core": "2.0.0",
"@latus/socket": "2.0.0",
"debug": "4.3.1",
"deepmerge": "^4.2.2",
"lodash.without": "^4.4.0"

View File

@ -3,7 +3,7 @@ import merge from 'deepmerge';
import without from 'lodash.without';
import {fastApply} from '@avocado/core';
import {Synchronized} from '@avocado/s13n';
import {normalize, Synchronized} from '@avocado/s13n';
import Resource from '@avocado/resource';
import {
compose,
@ -25,7 +25,6 @@ const decorate = compose(
);
let numericUid = AVOCADO_SERVER ? 1 : 1000000000;
export default (latus) => class Entity extends decorate(Resource) {
constructor(json, jsonext) {
@ -85,7 +84,7 @@ export default (latus) => class Entity extends decorate(Resource) {
debug(`Tried to add trait "${type}" when it already exists!`);
return;
}
const {type: Trait} = traitFromType(latus);
const {[type]: Trait} = traitFromType(latus);
if (!Trait) {
debug(`Tried to add trait "${type}" which isn't registered!`);
return;
@ -222,7 +221,7 @@ export default (latus) => class Entity extends decorate(Resource) {
const traits = Object.entries(json.traits);
for (let i = 0; i < traits.length; i++) {
const [type, trait] = traits[i];
const {type: Trait} = traitFromType(latus);
const {[type]: Trait} = traitFromType(latus);
if (Trait) {
pristine.traits[type] = merge(Trait.defaultJSON(), trait);
}
@ -243,11 +242,7 @@ export default (latus) => class Entity extends decorate(Resource) {
const traits = Object.entries(this._traits);
for (let i = 0; i < traits.length; i++) {
const [type, trait] = traits[i];
let traitPackets = trait.packets(informed);
if (traitPackets) {
if (!Array.isArray(traitPackets)) {
traitPackets = [traitPackets];
}
const traitPackets = normalize(latus, trait.packets(informed));
if (traitPackets.length > 0) {
updates.push({
type,
@ -255,7 +250,6 @@ export default (latus) => class Entity extends decorate(Resource) {
});
}
}
}
if (updates.length > 0) {
packets.push(['EntityUpdateTraitPacket', {traits: updates}]);
}
@ -293,7 +287,7 @@ export default (latus) => class Entity extends decorate(Resource) {
const implementation = this._hooks[hook].find(({type: hookType}) => hookType === type);
this._hooks[hook].splice(this._hooks[hook].indexOf(implementation), 1);
}
const {type: Trait} = traitFromType(latus);
const {[type]: Trait} = traitFromType(latus);
const properties = enumerateTraitAccessorKeys(Trait.prototype);
for (let i = 0; i < properties.length; ++i) {
const property = properties[i];

View File

@ -1,24 +1,13 @@
import {gather} from '@latus/core';
import Entity from './entity';
import Packets from './packets';
import Traits from './traits';
export default {
hooks: {
'@avocado/entity/traits': Traits,
'@avocado/traits': Traits,
'@avocado/s13n/synchronized': (latus) => ({
Entity: Entity(latus),
}),
'@latus/core/starting': (latus) => {
// eslint-disable-next-line no-param-reassign
latus.config['%traits'] = gather(
latus,
'@avocado/entity/traits',
'id',
'type',
);
},
'@latus/socket/packets': Packets,
},
};

View File

@ -0,0 +1,2 @@
export {EntityList} from './list';
export {EntityListView} from './view';

View File

@ -0,0 +1,268 @@
import {Class, compose, EventEmitter} from '@latus/core';
import {QuadTree, Rectangle} from '@avocado/math';
import {
normalize,
synchronized,
SynchronizedCreatePacket,
SynchronizedDestroyPacket,
} from '@avocado/s13n';
const decorate = compose(
EventEmitter,
);
export default (latus) => class EntityList extends decorate(Class) {
constructor(entities = []) {
super();
this._afterDestructionTickers = [];
this._entities = {};
this._entityTickers = [];
this._flatEntities = [];
this._informedEntities = new Map();
this._quadTree = new QuadTree();
const {fromName: {Entity}} = synchronized(latus);
const entities = await Promise.all(entities.map(Entity.load));
for (let i = 0; i < entities.length; i++) {
const entityJSON = entities[i];
if (entityJSON.uri) {
Entity.read(entityJSON.uri).then((readJSON) => {
this.addEntity(new Entity(readJSON, entityJSON));
});
}
else {
this.addEntity(new Entity(json[i]));
}
}
}
async acceptPacket(packet) {
if ('EntityListUpdateEntityPacket' === packet.constructor.name) {
for (let i = 0; i < packet.data.length; i++) {
const {uuid, packets} = packet.data[i];
for (let j = 0; j < packets.length; j++) {
if (this._entities[uuid]) {
this._entities[uuid].acceptPacket(packets[j]);
}
}
}
}
if (packet instanceof SynchronizedCreatePacket) {
const {fromName: {Entity}} = synchronized(latus);
this.addEntity(await Entity.load(packet.data.spec));
}
if (packet instanceof SynchronizedDestroyPacket) {
const uuid = packet.data.synchronized.id;
if (this._entities[uuid]) {
this._entities[uuid].destroy();
}
}
}
addEntity(entity) {
const uuid = entity.instanceUuid;
// Already exists?
if (this._entities[uuid]) {
return;
}
this._entities[uuid] = entity;
this._flatEntities.push(entity);
this._entityTickers.push(entity.tick);
if (AVOCADO_SERVER) {
this._informedEntities.set(entity, []);
}
entity.hydrate();
entity.attachToList(this);
entity.once('destroy', () => {
this.removeEntity(entity);
// In the process of destroying, allow entities to specify tickers that
// must live on past destruction.
const tickers = entity.invokeHookFlat('afterDestructionTickers');
for (let i = 0; i < tickers.length; i++) {
const ticker = tickers[i];
this._afterDestructionTickers.push(ticker);
}
});
this.emit('entityAdded', entity);
}
cleanPackets() {
for (let i = 0; i < this._flatEntities.length; i++) {
this._flatEntities[i].cleanPackets();
}
}
destroy() {
for (let i = 0; i < this._flatEntities.length; i++) {
this._flatEntities[i].destroy();
}
}
// static async extendJson(json) {
// const extended = await super.extendJson(json);
// if (extended)
// extended.sound = new Howl(json);
// await new Promise((resolve) => {
// extended.sound.once('load', resolve);
// });
// return extended;
// }
findEntity(uuid) {
return uuid in this._entities
? this._entities[uuid]
: undefined;
}
fromJSON(json) {
for (let i = 0; i < json.length; i++) {
const entityJSON = json[i];
if (entityJSON.uri) {
Entity.read(entityJSON.uri).then((readJSON) => {
this.addEntity(new Entity(readJSON, entityJSON));
});
}
else {
this.addEntity(new Entity(json[i]));
}
}
}
packets(informed) {
const packets = [];
// Visible entities.
const {areaToInform} = informed;
const previousVisibleEntities = this._informedEntities.get(informed);
const visibleEntities = this.visibleEntities(areaToInform);
const updates = [];
for (let i = 0; i < visibleEntities.length; i++) {
const entity = visibleEntities[i];
// Newly visible entity.
const index = previousVisibleEntities.indexOf(entity);
if (-1 === index) {
packets.push(entity.createPacket(informed));
}
// Still visible entity.
else {
const entityPackets = normalize(entity.packets(informed));
if (entityPackets.length > 0) {
updates.push({
uuid: entity.instanceUuid,
packets: entityPackets,
});
}
previousVisibleEntities.splice(index, 1);
}
}
// Send updates.
this._informedEntities.set(informed, visibleEntities);
if (updates.length > 0) {
packets.push([
'EntityListUpdateEntityPacket',
updates,
]);
}
// Send destroys.
for (let i = 0; i < previousVisibleEntities.length; i++) {
const entity = previousVisibleEntities[i];
// Newly removed entity.
if (-1 === visibleEntities.indexOf(entity)) {
packets.push(entity.destroyPacket(informed));
}
}
return packets;
}
get quadTree() {
return this._quadTree;
}
removeEntity(entity) {
const uuid = entity.instanceUuid;
if (!(uuid in this._entities)) {
return;
}
if (AVOCADO_SERVER) {
this._informedEntities.delete(entity);
}
entity.detachFromList();
delete this._entities[uuid];
this._flatEntities.splice(this._flatEntities.indexOf(entity), 1);
this._entityTickers.splice(this._entityTickers.indexOf(entity.tick), 1);
this.emit('entityRemoved', entity);
}
tick(elapsed) {
// Run after destruction tickers.
if (this._afterDestructionTickers.length > 0) {
this.tickAfterDestructionTickers(elapsed);
}
// Run normal tickers.
this.tickEntities(elapsed);
}
tickAfterDestructionTickers(elapsed) {
const finishedTickers = [];
for (let i = 0; i < this._afterDestructionTickers.length; ++i) {
const ticker = this._afterDestructionTickers[i];
if (ticker(elapsed)) {
finishedTickers.push(ticker);
}
}
for (let i = 0; i < finishedTickers.length; ++i) {
const ticker = finishedTickers[i];
const index = this._afterDestructionTickers.indexOf(ticker);
this._afterDestructionTickers.splice(index, 1);
}
}
tickEntities(elapsed) {
for (let i = 0; i < this._entityTickers.length; i++) {
this._entityTickers[i](elapsed);
}
}
toNetwork(informed) {
const {areaToInform} = informed;
const visibleEntities = this.visibleEntities(areaToInform);
// Mark as notified.
this._informedEntities.set(informed, visibleEntities);
return visibleEntities.map((entity) => entity.toNetwork(informed));
}
toJSON() {
const json = [];
for (let i = 0; i < this._flatEntities.length; i++) {
const entity = this._flatEntities[i];
json.push(entity.mergeDiff(entity.toJSON()));
}
return json;
}
visibleEntities(query) {
const entities = [];
const entitiesChecked = [];
const quadTree = this._quadTree;
const nodes = quadTree.search(query);
// Check all nodes.
for (let i = 0; i < nodes.length; ++i) {
const node = nodes[i];
const entity = node.data[2];
const aabb = node.data[3];
if (-1 === entitiesChecked.indexOf(entity)) {
entitiesChecked.push(entity);
// Make sure the AABB is actually in the query due to expansion.
if (entity.isVisible && Rectangle.intersects(query, aabb)) {
entities.push(entity);
}
}
}
return entities;
}
visibleEntitiesWithUri(query, uri) {
return this.visibleEntities(query).filter((entity) => entity.uri === uri);
}
};

View File

@ -0,0 +1,35 @@
import {Container, Sprite} from '@avocado/graphics';
export class EntityListView extends Container {
constructor(entityList) {
super();
this.entityList = entityList;
entityList.on('entityAdded', this.onListEntityAdded, this);
entityList.on('entityRemoved', this.onListEntityRemoved, this);
for (const entity of entityList) {
this.onListEntityAdded(entity);
}
}
onListEntityAdded(entity) {
entity.hydrate();
if (entity.is('visible')) {
this.addChild(entity.container);
}
}
onListEntityRemoved(entity) {
if (entity.is('visible')) {
this.removeChild(entity.container);
}
}
renderTick(elapsed) {
for (const entity of this.entityList) {
entity.renderTick(elapsed);
}
super.renderTick(elapsed);
}
}

View File

@ -0,0 +1,3 @@
import {Packet} from '@latus/socket';
export default class DiedPacket extends Packet {}

View File

@ -0,0 +1,35 @@
import {packetFromName, Packet} from '@latus/socket';
export default (latus) => class EntityListUpdateEntityPacket extends Packet {
static pack(packet) {
const {BundlePacket} = packetFromName(latus);
const data = packet.data[1];
for (let i = 0; i < data.length; i++) {
data[i].packets = BundlePacket.packPacket(
new BundlePacket(data[i].packets),
);
}
return super.pack(packet);
}
static get data() {
return [
{
uuid: 'uint32',
packets: 'buffer',
},
];
}
static unpack(packet) {
const {BundlePacket} = packetFromName(latus);
const unpacked = super.unpack(packet);
const {data} = unpacked;
for (let i = 0; i < data.length; i++) {
data[i].packets = BundlePacket.unpack(data[i].packets).data;
}
return unpacked;
}
};

View File

@ -1,5 +1,15 @@
import Died from './died';
import EntityListUpdateEntity from './entity-list-update-entity';
import EntityUpdateTrait from './entity-update-trait';
import TraitUpdateAlive from './trait-update-alive';
import TraitUpdateDirectionalDirection from './trait-update-directional-direction';
import TraitUpdatePositionedPosition from './trait-update-positioned-position';
export default (latus) => ({
Died,
EntityListUpdateEntity: EntityListUpdateEntity(latus),
EntityUpdateTrait: EntityUpdateTrait(latus),
TraitUpdateAlive,
TraitUpdateDirectionalDirection,
TraitUpdatePositionedPosition,
});

View File

@ -0,0 +1,12 @@
import {Packet} from '@latus/socket';
export default class TraitUpdateAlivePacket extends Packet {
static get data() {
return {
life: 'uint16',
maxLife: 'uint16',
};
}
}

View File

@ -0,0 +1,9 @@
import {Packet} from '@latus/socket';
export default class TraitUpdateDirectionalDirectionPacket extends Packet {
static get data() {
return 'uint8';
}
}

View File

@ -0,0 +1,28 @@
import {Vector} from '@avocado/math';
import {Packet} from '@latus/socket';
export default class TraitUpdatePositionedPositionPacket extends Packet {
static pack(packet) {
const data = packet.data[1];
data.position = Vector.packToUint32(data.position);
return super.pack(packet);
}
static get schema() {
return {
...super.schema,
data: {
position: 'uint32',
},
};
}
static unpack(packet) {
const unpacked = super.unpack(packet);
const {data} = unpacked;
data.position = Vector.unpackFromUint32(data.position);
return unpacked;
}
}

View File

@ -0,0 +1,22 @@
import {gather} from '@latus/core';
export {default as Trait} from './trait';
export {default as StateProperty} from './state-property';
export const traitFromId = (latus) => latus.config['%traits'].fromId;
export const traitFromType = (latus) => latus.config['%traits'].fromType;
export default {
hooks: {
'@latus/core/starting': (latus) => {
// eslint-disable-next-line no-param-reassign
latus.config['%traits'] = gather(
latus,
'@avocado/traits',
'id',
'type',
);
},
},
};

View File

@ -0,0 +1,26 @@
import {Property} from '@avocado/core';
export default function StateProperty(key, meta = {}) {
const transformedKey = `$$avocado_state_property_${key}`;
return (Superclass) => {
/* eslint-disable func-names, no-new-func, no-param-reassign */
meta.emit = meta.emit || function (...args) {
this.entity.emit(...args);
};
meta.initialize = meta.initialize || function () {
this[transformedKey] = this.state[key];
};
meta.get = meta.get || new Function(`
return this.${transformedKey};
`);
meta.set = meta.set || new Function('value', `
if (value !== this.${transformedKey}) {
this.setDirty();
}
this.${transformedKey} = value;
this.state['${key}'] = value;
`);
/* eslint-enable func-names, no-new-func, no-param-reassign */
return Property(key, meta)(Superclass);
};
}

View File

@ -1,4 +1,3 @@
import {Property} from '@avocado/core';
import {Synchronized} from '@avocado/s13n';
import {compose, Class} from '@latus/core';
@ -6,10 +5,6 @@ const decorate = compose(
Synchronized,
);
export const traitFromId = (latus) => latus.config['%traits'].fromId;
export const traitFromType = (latus) => latus.config['%traits'].fromType;
export default class Trait extends decorate(Class) {
constructor(entity, params, state) {
@ -160,28 +155,3 @@ export default class Trait extends decorate(Class) {
}
}
export function StateProperty(key, meta = {}) {
const transformedKey = `$$avocado_state_property_${key}`;
return (Superclass) => {
/* eslint-disable func-names, no-new-func, no-param-reassign */
meta.emit = meta.emit || function (...args) {
this.entity.emit(...args);
};
meta.initialize = meta.initialize || function () {
this[transformedKey] = this.state[key];
};
meta.get = meta.get || new Function(`
return this.${transformedKey};
`);
meta.set = meta.set || new Function('value', `
if (value !== this.${transformedKey}) {
this.setDirty();
}
this.${transformedKey} = value;
this.state['${key}'] = value;
`);
/* eslint-enable func-names, no-new-func, no-param-reassign */
return Property(key, meta)(Superclass);
};
}

View File

@ -6,9 +6,8 @@ import {
compile,
Context,
} from '@avocado/behavior';
import {compose} from '@avocado/core';
import Trait, {StateProperty} from '../trait';
import {StateProperty, Trait} from '@avocado/traits';
import {compose} from '@latus/core';
const decorate = compose(
StateProperty('isDying', {

View File

@ -1,7 +1,6 @@
import {compose} from '@avocado/core';
import {Vector} from '@avocado/math';
import Trait, {StateProperty} from '../trait';
import {StateProperty, Trait} from '@avocado/traits';
import {compose} from '@latus/core';
const decorate = compose(
StateProperty('direction', {

View File

@ -1,7 +1,7 @@
import {compose, TickingPromise} from '@avocado/core';
import {TickingPromise} from '@avocado/core';
import {TransitionResult} from '@avocado/timing';
import Trait, {StateProperty} from '../trait';
import {StateProperty, Trait} from '@avocado/traits';
import {compose} from '@latus/core';
const decorate = compose(
StateProperty('name'),

View File

@ -1,6 +1,6 @@
import {Rectangle} from '@avocado/math';
import Trait from '../trait';
import {Trait} from '../trait';
export default class Listed extends Trait {

View File

@ -1,7 +1,7 @@
import {compose, TickingPromise} from '@avocado/core';
import {TickingPromise} from '@avocado/core';
import {Vector} from '@avocado/math';
import Trait, {StateProperty} from '../trait';
import {StateProperty, Trait} from '@avocado/traits';
import {compose} from '@latus/core';
const decorate = compose(
StateProperty('isMobile'),

View File

@ -1,6 +1,6 @@
import {compose} from '@avocado/core';
import {compose} from '@latus/core';
import Trait from '../trait';
import {Trait} from '../trait';
const decorate = compose(
);

View File

@ -1,7 +1,7 @@
import {compose, EventEmitter} from '@avocado/core';
import {Vector} from '@avocado/math';
import {compose, EventEmitter} from '@latus/core';
import Trait from '../trait';
import {Trait} from '../trait';
const decorate = compose(
EventEmitter,

View File

@ -1,9 +1,8 @@
import {compose} from '@latus/core';
import {synchronized} from '@avocado/s13n';
import {StateProperty, Trait} from '@avocado/traits';
import merge from 'deepmerge';
import Trait, {StateProperty} from '../trait';
const decorate = compose(
StateProperty('isSpawning', {
track: true,

View File

@ -4,12 +4,12 @@
"@avocado/behavior@2.0.0", "@avocado/behavior@^2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2fbehavior/-/behavior-2.0.0.tgz#6478ca2f16957c3a010f792e013f4688583bf033"
integrity sha512-psHGbLG/EVaY6/9FwCvnNYA7LLXYVUQUiDbXZAyhkPNV5dAEmcQX8LdYUxDJ2Q32upow15+t8Np8u0XHcOHc4g==
resolved "http://172.18.0.8:4873/@avocado%2fbehavior/-/behavior-2.0.0.tgz#5a59518aa2dadb24dcc7a81dfad3a544a0131e15"
integrity sha512-AUrVcrNUNTDLrKa9PsxuvnCuRm+n1yKtDXjoXYzJ4NgHBT0//A6Jp6S0odURTprVsd1Ef77U8WpAj8GdU7ekQQ==
dependencies:
"@avocado/core" "^2.0.0"
"@avocado/core" "2.0.0"
"@avocado/entity" "2.0.0"
"@latus/core" "^2.0.0"
"@latus/core" "2.0.0"
debug "4.3.1"
deepmerge "^4.2.2"
lodash.mapvalues "^4.6.0"
@ -23,14 +23,15 @@
"@avocado/entity@2.0.0", "@avocado/entity@^2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2fentity/-/entity-2.0.0.tgz#b2bf5e249949a7dd0d67a39c0748ff318ffbc5ec"
integrity sha512-ywhhF/8w8ofBcmoBFIcTAfbn4EgabH9JrwlPqCwUbNfhPNAFPeetUeilPcgEMd4F47CtyoQcqKOgagJzKN1ocQ==
resolved "https://npm.i12e.cha0s.io/@avocado%2fentity/-/entity-2.0.0.tgz#935d667171b849d5764728ab1af30fe4a017c7b3"
integrity sha512-F/yDjVQbBnZEQPQ29ZKO0x8dgPiqM1VUnAr4qLekxIvIgQt6Vn7n7AOaIZZLsHy5yjZI0JzjoaELqUlT3NHi2w==
dependencies:
"@avocado/behavior" "2.0.0"
"@avocado/behavior" "^2.0.0"
"@avocado/core" "2.0.0"
"@avocado/math" "2.0.0"
"@avocado/resource" "2.0.0"
"@avocado/s13n" "2.0.0"
"@avocado/s13n" "^2.0.0"
"@avocado/timing" "^2.0.0"
"@latus/core" "^2.0.0"
"@latus/socket" "^2.0.0"
debug "4.3.1"
@ -39,13 +40,14 @@
"@avocado/graphics@^2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2fgraphics/-/graphics-2.0.0.tgz#411b06aeada19698eac275d5ae30348e6a5bfad9"
integrity sha512-zhxqAMOPzXeN4rd4Bv5u/7MsOBf5YX4p78znIpjrI/69QycYu+KSSBpgksQEwx0JwYWRNWcNw+5a4Q72nPVJuQ==
resolved "https://npm.i12e.cha0s.io/@avocado%2fgraphics/-/graphics-2.0.0.tgz#cc83b17a13ba5baf4bc1ed5345ead5090bb41fff"
integrity sha512-aHpkLHaeR9Ujd1sxLCALKK79BV1CGau8MilqZxucc9JbnXllXhACBKrvHjRg33OT9NKlXLDF87svATJsrFqwGQ==
dependencies:
"@avocado/core" "2.0.0"
"@avocado/entity" "2.0.0"
"@avocado/input" "2.0.0"
"@avocado/math" "2.0.0"
"@avocado/resource" "^2.0.0"
"@avocado/resource" "2.0.0"
"@latus/core" "^2.0.0"
"@latus/socket" "^2.0.0"
"@pixi/constants" "^5.3.6"
@ -58,6 +60,7 @@
"@pixi/sprite" "^5.3.6"
"@pixi/text" "^5.3.6"
debug "4.3.1"
image-size "^0.9.3"
"@avocado/input@2.0.0":
version "2.0.0"
@ -79,8 +82,8 @@
"@avocado/resource@2.0.0", "@avocado/resource@^2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2fresource/-/resource-2.0.0.tgz#a7b594584c172cff472d9a298bcd9d62c27186f2"
integrity sha512-q7MacbQl1ozA5Z3ZOKyUcMRBJAhly19dCtrNxYCki7mXIe1DoP0VvipFIgMlquLhkmtxxT2uMzVvHeJxhDxsgw==
resolved "https://npm.i12e.cha0s.io/@avocado%2fresource/-/resource-2.0.0.tgz#2eb014c2c876f3f51bc71d6594d93091b22013c8"
integrity sha512-3dks0rsuY1twlLm+vTrsqfV9anXR/0ZdQfe2YAJIdmiVQ7QEB2mQhUgMvqjgsuhI7ad1ygxD/I9hXBjl6CvyjA==
dependencies:
"@avocado/core" "^2.0.0"
"@latus/core" "^2.0.0"
@ -88,17 +91,7 @@
deepmerge "^4.2.2"
uuid "^8.3.2"
"@avocado/s13n@2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2fs13n/-/s13n-2.0.0.tgz#73804668f5744dffb358d14a4ee486250a79b222"
integrity sha512-Hy0U7PWHVUhpDFFyOD20xKVNUP5FEgjJWkDS0WQHYwtQFi4FysHl80POxxNDvGEsQ4kkgNBwvudmOKoOORe9SA==
dependencies:
"@latus/core" "^2.0.0"
"@latus/socket" "^2.0.0"
debug "4.3.1"
msgpack-lite "^0.1.26"
"@avocado/s13n@^2.0.0":
"@avocado/s13n@2.0.0", "@avocado/s13n@^2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2fs13n/-/s13n-2.0.0.tgz#ec6b7c9d28753c21c5fe265a5d2f2be5bc752d69"
integrity sha512-b+eTosKoNIh4Mhd5HEbCJ366sXMsYgnqFYHHHRDWGScOnr+RvYI4aa8gIqDRQ+F0WMfXs03R9sEGB/fmoFYCtg==
@ -108,7 +101,7 @@
debug "4.3.1"
msgpack-lite "^0.1.26"
"@avocado/timing@^2.0.0":
"@avocado/timing@2.0.0", "@avocado/timing@^2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2ftiming/-/timing-2.0.0.tgz#de76571519cb835a7f45528e91bdb9a18f1947fa"
integrity sha512-pJITg7q3kX9H2XEFP+jHPMiY317o4rCb/zzBdUbqC1RY5z5Et/LeTkQa/pd4IPqXeUK9omW4eM24jdCp8uH1tg==
@ -122,6 +115,16 @@
"@latus/socket" "^2.0.0"
debug "4.3.1"
"@avocado/traits@^2.0.0":
version "2.0.0"
resolved "http://172.18.0.8:4873/@avocado%2ftraits/-/traits-2.0.0.tgz#4717919e101a4fa81469bc5efe7c5478bb293a4e"
integrity sha512-7siD4XME3NzhTholUPndRYloHowV8z/s+FnzqG7p2/idNHrXURXsVBeYBI9lcM0SX1ONY+9OVdH0ykiu5qBScg==
dependencies:
"@avocado/core" "^2.0.0"
"@avocado/s13n" "^2.0.0"
"@latus/core" "^2.0.0"
debug "4.3.1"
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.11":
version "7.12.11"
resolved "https://npm.i12e.cha0s.io/@babel%2fcode-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
@ -1012,7 +1015,7 @@
minimatch "^3.0.4"
strip-json-comments "^3.1.1"
"@latus/core@^2.0.0":
"@latus/core@2.0.0", "@latus/core@^2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@latus%2fcore/-/core-2.0.0.tgz#4447b4bba265b684035be1dacefd6ba4913a47d4"
integrity sha512-OSsbO4wvVJFPZTMRDX5LAXOA+MQY8FOSK7PcTEJKeiRqOMeMIVkZc6q6KNlUIYivE+87rlM7S/CctHoA7uvQvg==
@ -1040,10 +1043,10 @@
webpack-hot-middleware "^2.25.0"
webpack-virtual-modules "^0.4.1"
"@latus/socket@^2.0.0":
"@latus/socket@2.0.0", "@latus/socket@^2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@latus%2fsocket/-/socket-2.0.0.tgz#2a35bba0db3542ab18a913320f7f6d24228ab5f1"
integrity sha512-qAWV/+3GI/GNyu/Ls6EFZpZr+2Q288YtgyjOzCNm6nRwy9N+JGJs1Y7yhJlLuao0K5EzHuYif3Vpo4DeRIVqNw==
resolved "https://npm.i12e.cha0s.io/@latus%2fsocket/-/socket-2.0.0.tgz#3dc0f02ec3e24e515ba6fc9302e7ac4a63351e25"
integrity sha512-0NlEYCBPkxtFX0utLhMacqGhd6rtSaQTudMXTtwuWxqRdkzJb4aC5BJ2BtDj0iH5KGCdbcQ4kE1cGGKdOk5mMA==
dependencies:
"@latus/core" "^2.0.0"
"@latus/http" "^2.0.0"
@ -1183,31 +1186,31 @@
babel-merge "^3.0.0"
deepmerge "^1.5.2"
"@pixi/constants@5.3.6", "@pixi/constants@^5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2fconstants/-/constants-5.3.6.tgz#b3b61b5d5047d022df3b8bed82eeb2b052457ded"
integrity sha512-4FF6GIj88/rddqMJeVlbxKUDgSpb6vSX9yWR1S17Urn4B3RCZErlfSEcTIuSOpLbs0F1h9K7UdIrzbJp2aefzw==
"@pixi/constants@5.3.7", "@pixi/constants@^5.3.6":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2fconstants/-/constants-5.3.7.tgz#a2e1789a98deb3713cfcb3eba3db84588bc9161e"
integrity sha512-MBcgIM/mSqonFezkCI9080IqNlc0wb8S9QJ5otBdseOWUQa/ua2jF7Jd1sCBGmi0IzS9/NOHFXzZVTdS7AC7Ow==
"@pixi/core@5.3.6", "@pixi/core@^5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2fcore/-/core-5.3.6.tgz#85559a71fd35c459c094ff30899f85cbcf8d2f81"
integrity sha512-Q5myUdcaJH5dtWbxerLn6YSFR3AjIgk58o7x7CzymJ7U5kdBjNB0yNdMVSbDQpf+lK4edtWYpuelot7SAthk+g==
"@pixi/core@5.3.7", "@pixi/core@^5.3.6":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2fcore/-/core-5.3.7.tgz#a8d65ca17f0c4ef8c0c5a22d31b9e02a4ab73b93"
integrity sha512-WBhU2f5aJSVVaFP55FFBFKjKlRf5fYGxgA/U3kD4yD4Y3d3d6V3MIZv+o0VX+kBs1Eq7ePZqEv2smDrlzzMEjQ==
dependencies:
"@pixi/constants" "5.3.6"
"@pixi/math" "5.3.6"
"@pixi/runner" "5.3.6"
"@pixi/settings" "5.3.6"
"@pixi/ticker" "5.3.6"
"@pixi/utils" "5.3.6"
"@pixi/constants" "5.3.7"
"@pixi/math" "5.3.7"
"@pixi/runner" "5.3.7"
"@pixi/settings" "5.3.7"
"@pixi/ticker" "5.3.7"
"@pixi/utils" "5.3.7"
"@pixi/display@5.3.6", "@pixi/display@^5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2fdisplay/-/display-5.3.6.tgz#90a629c4d9b7a118b7b8cc0ea4b843d1b93026f3"
integrity sha512-cbUaWz2R2vNO5BD9Ic6hYyazQQV8ndQfPonbBcehQQhNC+aZjuYgarHqiUb4Z7/GKkRQzB9WyoT8P5V5LppufQ==
"@pixi/display@5.3.7", "@pixi/display@^5.3.6":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2fdisplay/-/display-5.3.7.tgz#b661d2ecfd2a67f213665a0698acd29e17eee8fe"
integrity sha512-ma1JyLe5vaEgmaOR+anvj5YOKqT9OEWnboIe7NVmwGF1CZ7JFnB12rsRulHUsSaFG9bP5xjvroAZjFg/WvyGLw==
dependencies:
"@pixi/math" "5.3.6"
"@pixi/settings" "5.3.6"
"@pixi/utils" "5.3.6"
"@pixi/math" "5.3.7"
"@pixi/settings" "5.3.7"
"@pixi/utils" "5.3.7"
"@pixi/filter-advanced-bloom@^3.2.0":
version "3.2.0"
@ -1217,11 +1220,11 @@
"@pixi/filter-kawase-blur" "3.2.0"
"@pixi/filter-color-matrix@^5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2ffilter-color-matrix/-/filter-color-matrix-5.3.6.tgz#466f563e20721900b202a87c8d47a5ea8e31c741"
integrity sha512-u/OZEPhdMT2rzCNZZXBsIwVyp79X4rM029JMioJdYrFEPDnAuDIBKrY5//gOHFdQlYsjRIaW0IcykCPqUvBs3A==
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2ffilter-color-matrix/-/filter-color-matrix-5.3.7.tgz#230cafe46bde36e25441b13f3ac5dd8e8fee4311"
integrity sha512-Z12cxoHx9uMh3CZ0PLVRzsaFHHF/CfU3J83KI9k+Bg/DFOh/J/5EToCd44jYJbMKp3nvXcO1EJyZ3wwC/IsyfQ==
dependencies:
"@pixi/core" "5.3.6"
"@pixi/core" "5.3.7"
"@pixi/filter-kawase-blur@3.2.0":
version "3.2.0"
@ -1229,71 +1232,71 @@
integrity sha512-IO1UKn/XLvnV+ya4r1UOC9fTfXZjWvH9m6eQ/U+moBsQN5I5FihQfXCu586X4jb9VHNu3gFl7SUzirobhBfgtA==
"@pixi/graphics@^5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2fgraphics/-/graphics-5.3.6.tgz#1d38359926d174cccd3219936285140b715344e7"
integrity sha512-FDZlAkxrbCZTjzNMWW6q6N/GAfyfftwHOGb67oLJ+NCG2wagOGUPQYRRGBK5f45dgDdM+1is7UwbhdQ8Rvg9ig==
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2fgraphics/-/graphics-5.3.7.tgz#36ae80e2508e0a9c61ce454807d517d370d90a74"
integrity sha512-+6+bT/AC29a1Hw5XDxsH1UqBsXSqcna7wNTTrBQ02owotIJtyRc6w48f5qxzhxycumyVCR87IV5tAtdwX3xhag==
dependencies:
"@pixi/constants" "5.3.6"
"@pixi/core" "5.3.6"
"@pixi/display" "5.3.6"
"@pixi/math" "5.3.6"
"@pixi/sprite" "5.3.6"
"@pixi/utils" "5.3.6"
"@pixi/constants" "5.3.7"
"@pixi/core" "5.3.7"
"@pixi/display" "5.3.7"
"@pixi/math" "5.3.7"
"@pixi/sprite" "5.3.7"
"@pixi/utils" "5.3.7"
"@pixi/math@5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2fmath/-/math-5.3.6.tgz#3933bae1a0af912b4384389b63ceffdcf108723a"
integrity sha512-ccW/LrSsLaHunj1ztfp2UpxKGftiaK/nURZa51CFhbGYQBrYZBk27x1fgwGAs4ualTtqZOeyaLhv4nY0ljm5Qw==
"@pixi/math@5.3.7":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2fmath/-/math-5.3.7.tgz#066e7ea149fd38db8d8a9584aac5f41d02b36bdd"
integrity sha512-WnjUwX7rkxR36F0xknpsNd9BsfQosV0BbyFE0Il88IURBM3Tu9X4tC7RGJDgWU+aXw23HgHu0j+MWJrCVCM2fA==
"@pixi/runner@5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2frunner/-/runner-5.3.6.tgz#b123f1a674aa249e4067ff00f9a3027d01ac69a8"
integrity sha512-qiGoMVk0P0p3IfH5LTIH/dKyiNUzIHMxoykPODWni648hFa4CEFpG3bHJorcyYvmALCFgHjH2hhrqQexK3T6Kw==
"@pixi/runner@5.3.7":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2frunner/-/runner-5.3.7.tgz#78ed2c92b392b8c099d2e4557dded7faa921446b"
integrity sha512-kt5apNb21HAvpBaDaPRs33k2O0VzrKe13w4we8iftCpXX8w68ErAY1lH68vmtDNrxnlHg4M9nRgEoMeiHlo2RA==
"@pixi/settings@5.3.6", "@pixi/settings@^5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2fsettings/-/settings-5.3.6.tgz#d138ba2180557174c3f942fc9656de35f1a77026"
integrity sha512-hWMC1KwB2InFoJPdnI97ckHX0Z7912aaB2oQUJwKv0hhSrc8vxq9Dg6UofVY+wGMHDVCvqJPnvCsTYuKUmwRxw==
"@pixi/settings@5.3.7", "@pixi/settings@^5.3.6":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2fsettings/-/settings-5.3.7.tgz#b661883231bf2a1ff5260c214bd0c4b438759841"
integrity sha512-g6AoRSGWxU34gtKSQwX2AMQoLUv86L/5iIXRsqo+X4bfUSCenTci1X7ueVrSIbo39dxh6IOpriZF2Yk3TeHG5w==
dependencies:
ismobilejs "^1.1.0"
"@pixi/sprite@5.3.6", "@pixi/sprite@^5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2fsprite/-/sprite-5.3.6.tgz#04c13b0ce1c7379a2f570d28db58d1f54ce44c55"
integrity sha512-Q5nRj7mhWuVHvn2rMtlf+6CdTjdovxX0R9ANffPcY7EODn5m7F4GpXEwBOjDICtVyHXrXhz2k4Gi2XWPFeeZ7A==
"@pixi/sprite@5.3.7", "@pixi/sprite@^5.3.6":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2fsprite/-/sprite-5.3.7.tgz#c6edf3d4a9928868696b62e35a60ded27d167058"
integrity sha512-Bjl+NOOvigEzUsm1cDr1KmBUpPSWO8pDXpUPTi+v2N75gwRfTycmj5f2TU0QmMW3Gc6sv0CB0AkL7dkMPwPb8g==
dependencies:
"@pixi/constants" "5.3.6"
"@pixi/core" "5.3.6"
"@pixi/display" "5.3.6"
"@pixi/math" "5.3.6"
"@pixi/settings" "5.3.6"
"@pixi/utils" "5.3.6"
"@pixi/constants" "5.3.7"
"@pixi/core" "5.3.7"
"@pixi/display" "5.3.7"
"@pixi/math" "5.3.7"
"@pixi/settings" "5.3.7"
"@pixi/utils" "5.3.7"
"@pixi/text@^5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2ftext/-/text-5.3.6.tgz#55b45c8968a28304f5b7aef289e6f062772a060a"
integrity sha512-maEZoIysPOuzzSH+TN2cGnqDDMdTVtFNY9dJdKgmMleY9oCPES/iiNkcdki40S9JfaM7GM3ywn2xbJruJ5aZCg==
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2ftext/-/text-5.3.7.tgz#cb71b2576bdc1f66fb79977d281f9575dd06d3d5"
integrity sha512-WVAc31MDgHTvP0dJNWsvLVJhjeVGZ3NrLpHcH9iIAd6HVO5Z+i+fk4zvodD+Y7jWU0psx8ZD8xe1wy8ECfbCBA==
dependencies:
"@pixi/core" "5.3.6"
"@pixi/math" "5.3.6"
"@pixi/settings" "5.3.6"
"@pixi/sprite" "5.3.6"
"@pixi/utils" "5.3.6"
"@pixi/core" "5.3.7"
"@pixi/math" "5.3.7"
"@pixi/settings" "5.3.7"
"@pixi/sprite" "5.3.7"
"@pixi/utils" "5.3.7"
"@pixi/ticker@5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2fticker/-/ticker-5.3.6.tgz#022416047199ae1ac875f750efddfb0a0ba20abd"
integrity sha512-3BHDrFyI5aHcAlo9fdQ5pd4U1pwt5QwGpbM9EshFL2NeNdumAeZQJ850DXFhVfFAXhhNljEQTFNZ44sTIsAy6Q==
"@pixi/ticker@5.3.7":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2fticker/-/ticker-5.3.7.tgz#c331b270042d507fe18543ae435a9a857a8fd5ae"
integrity sha512-ZEXiJwPtuPeWa0QmRODF5qK0+ugZu/xeq7QxCvFOCc3NFVBeGms4g92HPucOju9R7jcODIoJxtICALsuwLAr9w==
dependencies:
"@pixi/settings" "5.3.6"
"@pixi/settings" "5.3.7"
"@pixi/utils@5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2futils/-/utils-5.3.6.tgz#63ada7f024884390324b430ad19b6e031791c319"
integrity sha512-Ilix2qpF89SSyoUpPsjH2RB7Os6ceQ+gts55zpMbLyxMyuMH6GlZ9WgUEhAakkUEtQ6imi3ZZAxCNLAEWNB+cw==
"@pixi/utils@5.3.7":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2futils/-/utils-5.3.7.tgz#55fe2a2fbf0fba842da5a602576ce68c498e7e16"
integrity sha512-f8zAeHHURxfwBr8MZiXEIwY2h9wbS6vN0ypvapGvKFOexZ1EInTs35FhEiRWzLEPLHyn1RgCdKzR2zl++E4tIw==
dependencies:
"@pixi/constants" "5.3.6"
"@pixi/settings" "5.3.6"
"@pixi/constants" "5.3.7"
"@pixi/settings" "5.3.7"
earcut "^2.1.5"
eventemitter3 "^3.1.0"
url "^0.11.0"
@ -2214,9 +2217,9 @@ camelcase@^6.0.0:
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
caniuse-lite@^1.0.30001165:
version "1.0.30001170"
resolved "https://npm.i12e.cha0s.io/caniuse-lite/-/caniuse-lite-1.0.30001170.tgz#0088bfecc6a14694969e391cc29d7eb6362ca6a7"
integrity sha512-Dd4d/+0tsK0UNLrZs3CvNukqalnVTRrxb5mcQm8rHL49t7V5ZaTygwXkrq+FB+dVDf++4ri8eJnFEJAB8332PA==
version "1.0.30001171"
resolved "https://npm.i12e.cha0s.io/caniuse-lite/-/caniuse-lite-1.0.30001171.tgz#3291e11e02699ad0a29e69b8d407666fc843eba7"
integrity sha512-5Alrh8TTYPG9IH4UkRqEBZoEToWRLvPbSQokvzSz0lii8/FOWKG4keO1HoYfPWs8IF/NH/dyNPg1cmJGvV3Zlg==
chai@4.2.0:
version "4.2.0"
@ -2702,7 +2705,7 @@ debug@4.3.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
dependencies:
ms "2.1.2"
debug@^3.1.1, debug@^3.2.5:
debug@^3.1.1, debug@^3.2.6:
version "3.2.7"
resolved "https://npm.i12e.cha0s.io/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
@ -3150,7 +3153,7 @@ es-abstract@^1.17.0-next.1:
string.prototype.trimend "^1.0.1"
string.prototype.trimstart "^1.0.1"
es-abstract@^1.18.0-next.0, es-abstract@^1.18.0-next.1:
es-abstract@^1.18.0-next.1:
version "1.18.0-next.1"
resolved "https://npm.i12e.cha0s.io/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68"
integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==
@ -3289,9 +3292,9 @@ eslint-plugin-react-hooks@^4.2.0:
integrity sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==
eslint-plugin-react@^7.21.5:
version "7.21.5"
resolved "https://npm.i12e.cha0s.io/eslint-plugin-react/-/eslint-plugin-react-7.21.5.tgz#50b21a412b9574bfe05b21db176e8b7b3b15bff3"
integrity sha512-8MaEggC2et0wSF6bUeywF7qQ46ER81irOdWS4QWxnnlAEsnzeBevk1sWh7fhpCghPpXb+8Ks7hvaft6L/xsR6g==
version "7.22.0"
resolved "https://npm.i12e.cha0s.io/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz#3d1c542d1d3169c45421c1215d9470e341707269"
integrity sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA==
dependencies:
array-includes "^3.1.1"
array.prototype.flatmap "^1.2.3"
@ -3592,14 +3595,7 @@ fastparse@^1.1.1:
resolved "https://npm.i12e.cha0s.io/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9"
integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==
faye-websocket@^0.10.0:
version "0.10.0"
resolved "https://npm.i12e.cha0s.io/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=
dependencies:
websocket-driver ">=0.5.1"
faye-websocket@~0.11.1:
faye-websocket@^0.11.3:
version "0.11.3"
resolved "https://npm.i12e.cha0s.io/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e"
integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==
@ -3852,7 +3848,7 @@ get-func-name@^2.0.0:
resolved "https://npm.i12e.cha0s.io/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=
get-intrinsic@^1.0.0, get-intrinsic@^1.0.1:
get-intrinsic@^1.0.0, get-intrinsic@^1.0.1, get-intrinsic@^1.0.2:
version "1.0.2"
resolved "https://npm.i12e.cha0s.io/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49"
integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==
@ -4273,6 +4269,13 @@ ignore@^4.0.6:
resolved "https://npm.i12e.cha0s.io/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
image-size@^0.9.3:
version "0.9.3"
resolved "https://npm.i12e.cha0s.io/image-size/-/image-size-0.9.3.tgz#f7efce6b0a1649b44b9bc43b9d9a5acf272264b6"
integrity sha512-5SakFa79uhUVSjKeQE30GVzzLJ0QNzB53+I+/VD1vIesD6GP6uatWIlgU0uisFNLt1u0d6kBydp7yfk+lLJhLQ==
dependencies:
queue "6.0.1"
import-fresh@^3.0.0, import-fresh@^3.2.1:
version "3.3.0"
resolved "https://npm.i12e.cha0s.io/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
@ -4689,7 +4692,7 @@ json-stable-stringify-without-jsonify@^1.0.1:
resolved "https://npm.i12e.cha0s.io/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
json3@^3.3.2:
json3@^3.3.3:
version "3.3.3"
resolved "https://npm.i12e.cha0s.io/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==
@ -5401,7 +5404,7 @@ object-hash@^2.0.3:
resolved "https://npm.i12e.cha0s.io/object-hash/-/object-hash-2.1.1.tgz#9447d0279b4fcf80cff3259bf66a1dc73afabe09"
integrity sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==
object-inspect@^1.8.0:
object-inspect@^1.8.0, object-inspect@^1.9.0:
version "1.9.0"
resolved "https://npm.i12e.cha0s.io/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a"
integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==
@ -6082,6 +6085,13 @@ querystringify@^2.1.1:
resolved "https://npm.i12e.cha0s.io/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
queue@6.0.1:
version "6.0.1"
resolved "https://npm.i12e.cha0s.io/queue/-/queue-6.0.1.tgz#abd5a5b0376912f070a25729e0b6a7d565683791"
integrity sha512-AJBQabRCCNr9ANq8v77RJEv73DPbn55cdTb+Giq4X0AVnNVZvMHlYp7XlQiN+1npCZj1DuSmaA2hYVUUDgxFDg==
dependencies:
inherits "~2.0.3"
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
version "2.1.0"
resolved "https://npm.i12e.cha0s.io/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
@ -6433,7 +6443,7 @@ select-hose@^2.0.0:
resolved "https://npm.i12e.cha0s.io/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
selfsigned@^1.10.7:
selfsigned@^1.10.8:
version "1.10.8"
resolved "https://npm.i12e.cha0s.io/selfsigned/-/selfsigned-1.10.8.tgz#0d17208b7d12c33f8eac85c41835f27fc3d81a30"
integrity sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==
@ -6581,12 +6591,13 @@ shebang-regex@^3.0.0:
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
side-channel@^1.0.2, side-channel@^1.0.3:
version "1.0.3"
resolved "https://npm.i12e.cha0s.io/side-channel/-/side-channel-1.0.3.tgz#cdc46b057550bbab63706210838df5d4c19519c3"
integrity sha512-A6+ByhlLkksFoUepsGxfj5x1gTSrs+OydsRptUxeNCabQpCFUvcwIczgOigI8vhY/OJCnPnyE9rGiwgvr9cS1g==
version "1.0.4"
resolved "https://npm.i12e.cha0s.io/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
dependencies:
es-abstract "^1.18.0-next.0"
object-inspect "^1.8.0"
call-bind "^1.0.0"
get-intrinsic "^1.0.2"
object-inspect "^1.9.0"
signal-exit@^3.0.0:
version "3.0.3"
@ -6692,26 +6703,26 @@ socket.io@2.3.0:
socket.io-client "2.3.0"
socket.io-parser "~3.4.0"
sockjs-client@1.4.0:
version "1.4.0"
resolved "https://npm.i12e.cha0s.io/sockjs-client/-/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5"
integrity sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==
sockjs-client@^1.5.0:
version "1.5.0"
resolved "https://npm.i12e.cha0s.io/sockjs-client/-/sockjs-client-1.5.0.tgz#2f8ff5d4b659e0d092f7aba0b7c386bd2aa20add"
integrity sha512-8Dt3BDi4FYNrCFGTL/HtwVzkARrENdwOUf1ZoW/9p3M8lZdFT35jVdrHza+qgxuG9H3/shR4cuX/X9umUrjP8Q==
dependencies:
debug "^3.2.5"
debug "^3.2.6"
eventsource "^1.0.7"
faye-websocket "~0.11.1"
inherits "^2.0.3"
json3 "^3.3.2"
url-parse "^1.4.3"
faye-websocket "^0.11.3"
inherits "^2.0.4"
json3 "^3.3.3"
url-parse "^1.4.7"
sockjs@0.3.20:
version "0.3.20"
resolved "https://npm.i12e.cha0s.io/sockjs/-/sockjs-0.3.20.tgz#b26a283ec562ef8b2687b44033a4eeceac75d855"
integrity sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==
sockjs@^0.3.21:
version "0.3.21"
resolved "https://npm.i12e.cha0s.io/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417"
integrity sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==
dependencies:
faye-websocket "^0.10.0"
faye-websocket "^0.11.3"
uuid "^3.4.0"
websocket-driver "0.6.5"
websocket-driver "^0.7.4"
sort-keys@^1.0.0:
version "1.1.2"
@ -7313,7 +7324,7 @@ url-loader@^4.1.1:
mime-types "^2.1.27"
schema-utils "^3.0.0"
url-parse@^1.4.3:
url-parse@^1.4.3, url-parse@^1.4.7:
version "1.4.7"
resolved "https://npm.i12e.cha0s.io/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278"
integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==
@ -7477,9 +7488,9 @@ webpack-dev-middleware@^4.0.2:
schema-utils "^3.0.0"
webpack-dev-server@^3.11.0:
version "3.11.0"
resolved "https://npm.i12e.cha0s.io/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz#8f154a3bce1bcfd1cc618ef4e703278855e7ff8c"
integrity sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==
version "3.11.1"
resolved "https://npm.i12e.cha0s.io/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz#c74028bf5ba8885aaf230e48a20e8936ab8511f0"
integrity sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ==
dependencies:
ansi-html "0.0.7"
bonjour "^3.5.0"
@ -7501,11 +7512,11 @@ webpack-dev-server@^3.11.0:
p-retry "^3.0.1"
portfinder "^1.0.26"
schema-utils "^1.0.0"
selfsigned "^1.10.7"
selfsigned "^1.10.8"
semver "^6.3.0"
serve-index "^1.9.1"
sockjs "0.3.20"
sockjs-client "1.4.0"
sockjs "^0.3.21"
sockjs-client "^1.5.0"
spdy "^4.0.2"
strip-ansi "^3.0.1"
supports-color "^6.1.0"
@ -7580,14 +7591,7 @@ webpack@^4:
watchpack "^1.7.4"
webpack-sources "^1.4.1"
websocket-driver@0.6.5:
version "0.6.5"
resolved "https://npm.i12e.cha0s.io/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36"
integrity sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=
dependencies:
websocket-extensions ">=0.1.1"
websocket-driver@>=0.5.1:
websocket-driver@>=0.5.1, websocket-driver@^0.7.4:
version "0.7.4"
resolved "https://npm.i12e.cha0s.io/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760"
integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==
@ -7666,9 +7670,9 @@ ws@^6.2.1:
async-limiter "~1.0.0"
ws@^7.1.2:
version "7.4.1"
resolved "https://npm.i12e.cha0s.io/ws/-/ws-7.4.1.tgz#a333be02696bd0e54cea0434e21dcc8a9ac294bb"
integrity sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==
version "7.4.2"
resolved "https://npm.i12e.cha0s.io/ws/-/ws-7.4.2.tgz#782100048e54eb36fe9843363ab1c68672b261dd"
integrity sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==
ws@~6.1.0:
version "6.1.4"

View File

@ -1 +1,19 @@
const banner = require('@neutrinojs/banner');
module.exports = require('../../config/.neutrinorc');
const code = [
"if (process && 'client' !== process.env.SIDE) {",
"require('pirates').addHook(",
"(code, filename) => '',",
"{",
"ignoreNodeModules: false,",
"matcher: (filename) => filename.match('@pixi')",
"}",
")",
"}",
].join('');
module.exports.use.push(banner({
banner: code,
}))

View File

@ -21,12 +21,12 @@
],
"dependencies": {
"@avocado/core": "2.0.0",
"@avocado/entity": "2.0.0",
"@avocado/input": "2.0.0",
"@avocado/math": "2.0.0",
"@avocado/resource": "^2.0.0",
"@avocado/resource": "2.0.0",
"@avocado/traits": "^2.0.0",
"@latus/core": "^2.0.0",
"@latus/socket": "^2.0.0",
"@latus/socket": "2.0.0",
"@pixi/constants": "^5.3.6",
"@pixi/core": "^5.3.6",
"@pixi/display": "^5.3.6",
@ -36,10 +36,12 @@
"@pixi/settings": "^5.3.6",
"@pixi/sprite": "^5.3.6",
"@pixi/text": "^5.3.6",
"debug": "4.3.1"
"debug": "4.3.1",
"image-size": "^0.9.3"
},
"devDependencies": {
"@neutrinojs/airbnb-base": "^9.4.0",
"@neutrinojs/banner": "9.4.0",
"@neutrinojs/copy": "9.4.0",
"@neutrinojs/mocha": "^9.4.0",
"@neutrinojs/react": "^9.4.0",

View File

@ -1,9 +1,12 @@
import {Vector} from '@avocado/math';
import {Class, compose} from '@avocado/core';
import {RenderTexture} from '@pixi/core';
import {Class, compose} from '@latus/core';
import Image from './image';
const {
SIDE,
} = process.env;
const decorate = compose(
Vector.Mixin('size', 'width', 'height', {
default: [0, 0],
@ -14,12 +17,26 @@ export default class Canvas extends decorate(Class) {
constructor(size = [0, 0]) {
super();
this.renderTexture = RenderTexture.create(size[0], size[1]);
if ('client' === SIDE) {
// eslint-disable-next-line global-require
const {RenderTexture} = require('@pixi/core');
this.renderTexture = RenderTexture.create();
}
else {
this.renderTexture = {
height: 0,
isFake: true,
width: 0,
};
}
this.size = size;
}
destroy() {
if (!this.renderTexture.isFake) {
this.renderTexture.destroy();
}
}
get internal() {
return this.renderTexture;
@ -34,13 +51,20 @@ export default class Canvas extends decorate(Class) {
}
set size(size) {
if (this.renderTexture.isFake) {
[this.renderTexture.width, this.renderTexture.height] = size;
}
else {
this.renderTexture.resize(size[0], size[1]);
}
super.size = size;
}
toImage() {
const image = new Image();
if (!this.renderTexture.isFake) {
image.texture = this.renderTexture.clone();
}
return image;
}

View File

@ -1,19 +1,34 @@
import {Container as PIXIContainer} from '@pixi/display';
import {AdvancedBloomFilter} from '@pixi/filter-advanced-bloom';
import {ColorMatrixFilter} from '@pixi/filter-color-matrix';
// import {AdvancedBloomFilter} from '@pixi/filter-advanced-bloom';
// import {ColorMatrixFilter} from '@pixi/filter-color-matrix';
import Renderable from './renderable';
const {
SIDE,
} = process.env;
export default class Container extends Renderable {
constructor() {
super();
this._children = [];
this._childrenIndexes = new Map();
if ('client' === SIDE) {
// eslint-disable-next-line global-require
const {Container: PIXIContainer} = require('@pixi/display');
this.container = new PIXIContainer();
}
else {
this.container = {
isFake: true,
};
}
}
addChild(child) {
if (this.container.isFake) {
return;
}
// eslint-disable-next-line no-param-reassign
child.parent = this;
this.isDirty = true;
@ -26,14 +41,16 @@ export default class Container extends Renderable {
return this._children;
}
desaturate() {
const filter = new ColorMatrixFilter();
filter.desaturate();
this.container.filters = [filter];
}
// desaturate() {
// const filter = new ColorMatrixFilter();
// filter.desaturate();
// this.container.filters = [filter];
// }
destroy() {
if (!this.container.isFake) {
this.container.filters = [];
}
this.children.forEach((child) => {
this.removeChild(child);
child.destroy();
@ -45,41 +62,43 @@ export default class Container extends Renderable {
return this.container;
}
night(intensity = 1) {
let filter;
const {filters} = this.container;
if (filters && filters.length > 0 && filters[0] instanceof ColorMatrixFilter) {
[filter] = filters;
}
else {
filter = new ColorMatrixFilter();
}
const nightness = 0.1;
const double = nightness * 2;
const half = nightness / 2;
const redDown = 1 - (intensity * (1 + double));
const blueUp = 1 - (intensity * (1 - half));
const scale = intensity * nightness;
const matrix = [
redDown, -scale, 0, 0, 0,
-scale, (1 - intensity), scale, 0, 0,
0, scale, blueUp, 0, 0,
0, 0, 0, 1, 0,
];
filter._loadMatrix(matrix);
this.container.filters = [filter];
}
// night(intensity = 1) {
// let filter;
// const {filters} = this.container;
// if (filters && filters.length > 0 && filters[0] instanceof ColorMatrixFilter) {
// [filter] = filters;
// }
// else {
// filter = new ColorMatrixFilter();
// }
// const nightness = 0.1;
// const double = nightness * 2;
// const half = nightness / 2;
// const redDown = 1 - (intensity * (1 + double));
// const blueUp = 1 - (intensity * (1 - half));
// const scale = intensity * nightness;
// const matrix = [
// redDown, -scale, 0, 0, 0,
// -scale, (1 - intensity), scale, 0, 0,
// 0, scale, blueUp, 0, 0,
// 0, 0, 0, 1, 0,
// ];
// filter._loadMatrix(matrix);
// this.container.filters = [filter];
// }
paused(intensity = 1) {
const filter = new ColorMatrixFilter();
filter.sepia();
filter.brightness(1 - intensity, true);
this.container.filters = [filter];
}
// paused(intensity = 1) {
// const filter = new ColorMatrixFilter();
// filter.sepia();
// filter.brightness(1 - intensity, true);
// this.container.filters = [filter];
// }
removeAllFilters() {
if (!this.container.isFake) {
this.container.filters = [];
}
}
_removeChild(child) {
const index = this._children.indexOf(child);
@ -87,8 +106,10 @@ export default class Container extends Renderable {
return;
}
this._children.splice(index, 1);
if (!this.container.isFake) {
this.container.removeChild(child.internal);
}
}
removeChild(child) {
this._removeChild(child);
@ -130,7 +151,9 @@ export default class Container extends Renderable {
const rIndex = this._childrenIndexes.get(r);
return lIndex - rIndex;
});
if (!this.container.isFake) {
this.container.children = this._children.map((child) => child.internal);
}
this._resetChildrenIndexes();
}
@ -141,27 +164,27 @@ export default class Container extends Renderable {
}
}
sepia() {
const filter = new ColorMatrixFilter();
filter.sepia();
this.container.filters = [filter];
}
// sepia() {
// const filter = new ColorMatrixFilter();
// filter.sepia();
// this.container.filters = [filter];
// }
setFilter(filter) {
switch (filter) {
case 'bloom':
this.container.filters = [
new AdvancedBloomFilter({
threshold: 0.5,
bloomScale: 0.8,
brightness: 0.7,
blur: 2,
quality: 6,
}),
];
break;
default:
}
}
// setFilter(filter) {
// switch (filter) {
// case 'bloom':
// this.container.filters = [
// new AdvancedBloomFilter({
// threshold: 0.5,
// bloomScale: 0.8,
// brightness: 0.7,
// blur: 2,
// quality: 6,
// }),
// ];
// break;
// default:
// }
// }
}

View File

@ -1,60 +1,46 @@
import {BaseTexture, Texture} from '@pixi/core';
import {SCALE_MODES} from '@pixi/constants';
import {Resource} from '@avocado/resource';
const {
SIDE,
} = process.env;
export default class Image extends Resource {
constructor() {
constructor(buffer) {
super();
this.texture = null;
if (buffer) {
if ('client' === SIDE) {
// eslint-disable-next-line global-require
const {Texture} = require('@pixi/core');
this.texture = Texture.fromBuffer(buffer);
}
else {
// eslint-disable-next-line global-require
const imageSize = require('image-size');
const {height, width} = imageSize(buffer);
this.texture = {
height,
isFake: true,
width,
};
}
}
else {
this.texture = {
height: 0,
isFake: true,
width: 0,
};
}
}
destroy() {
if (!this.texture.isFake) {
this.texture.destroy();
}
static fromHtmlCanvas(htmlCanvas) {
const baseTexture = BaseTexture.from(
htmlCanvas,
SCALE_MODES.NEAREST,
);
const image = new Image();
image.texture = new Texture(baseTexture);
return image;
}
static load(uri) {
return this.loadBaseTexture(uri).then((baseTexture) => {
const image = new Image();
image.uri = uri;
image.texture = new Texture(baseTexture);
return image;
});
}
static loadBaseTexture(uri) {
if (!this.baseTextureCache) {
this.baseTextureCache = {};
}
if (this.baseTextureCache[uri]) {
return Promise.resolve(this.baseTextureCache[uri]);
}
return new Promise((resolve, reject) => {
const baseTexture = BaseTexture.from(uri);
baseTexture.once('error', () => {
reject(new Error(`Couldn't load image "${uri}"`));
});
baseTexture.once('loaded', () => {
resolve(this.baseTextureCache[uri] = baseTexture);
});
});
}
get height() {
if (!this.texture) {
return 0;
}
return this.texture.height;
}
@ -63,27 +49,25 @@ export default class Image extends Resource {
}
subimage(rectangle) {
const subimage = new Image();
if (this.texture.isFake) {
[, , subimage.texture.width, subimage.texture.height] = rectangle;
}
else {
const frame = {
x: rectangle[0],
y: rectangle[1],
width: rectangle[2],
height: rectangle[3],
};
const subimage = new Image();
// eslint-disable-next-line global-require
const {Texture} = require('@pixi/core');
subimage.texture = new Texture(this.texture, frame);
}
return subimage;
}
updateBaseTexture() {
if (this.texture && this.texture.baseTexture) {
this.texture.baseTexture.update();
}
}
get width() {
if (!this.texture) {
return 0;
}
return this.texture.width;
}

View File

@ -1,6 +1,9 @@
import {SCALE_MODES} from '@pixi/constants';
import {Renderer, BatchRenderer} from '@pixi/core';
import {settings} from '@pixi/settings';
import packets from './packets';
import traits from './traits';
const {
SIDE,
} = process.env;
export {default as Canvas} from './canvas';
export {default as Color} from './color';
@ -12,7 +15,23 @@ export {default as Renderer} from './renderer';
export {default as Sprite} from './sprite';
export {default as Stage} from './stage';
export {default as Text} from './text';
if ('client' === SIDE) {
const [
{SCALE_MODES}, {Renderer, BatchRenderer}, {settings},
] = [
// eslint-disable-next-line global-require
require('@pixi/constants'), require('@pixi/core'), require('@pixi/settings'),
];
// Pixelly!
settings.SCALE_MODE = SCALE_MODES.NEAREST;
// Lil pixi management.
Renderer.registerPlugin('batch', BatchRenderer);
}
export default {
hooks: {
'@avocado/traits': traits,
'@latus/socket/packets': packets,
},
};

View File

@ -0,0 +1,5 @@
import TraitUpdateVisible from './trait-update-visible';
export default () => ({
TraitUpdateVisible,
});

View File

@ -1,7 +1,9 @@
import {Graphics} from '@pixi/graphics';
import Renderable from './renderable';
const {
SIDE,
} = process.env;
export default class Primitives extends Renderable {
static fillStyle(color) {
@ -14,27 +16,43 @@ export default class Primitives extends Renderable {
constructor() {
super();
if ('client' === SIDE) {
// eslint-disable-next-line global-require
const {Graphics} = require('@pixi/graphics');
this.primitives = new Graphics();
}
else {
this.primitives = {
isFake: true,
};
}
}
clear() {
if (!this.primitives.isFake) {
this.primitives.clear();
}
}
drawCircle(position, radius, lineStyle, fillStyle) {
if (!this.primitives.isFake) {
this._wrapStyle('drawCircle', '3rd', lineStyle, fillStyle, () => {
this.primitives.drawCircle(position[0], position[1], radius);
});
}
}
drawLine(p1, p2, lineStyle, fillStyle) {
if (!this.primitives.isFake) {
this._wrapStyle('drawLine', '3rd', lineStyle, fillStyle, () => {
this.primitives.moveTo(p1[0], p1[1]);
this.primitives.lineTo(p2[0], p2[1]);
});
}
}
drawRectangle(rectangle, lineStyle, fillStyle) {
if (!this.primitives.isFake) {
this._wrapStyle('drawLine', '2nd', lineStyle, fillStyle, () => {
this.primitives.drawRect(
rectangle[0],
@ -44,6 +62,7 @@ export default class Primitives extends Renderable {
);
});
}
}
get internal() {
return this.primitives;

View File

@ -1,9 +1,22 @@
import {Renderer as PIXIRenderer} from '@pixi/core';
const {
SIDE,
} = process.env;
export default class Renderer {
constructor(size = [0, 0]) {
if ('client' === SIDE) {
// eslint-disable-next-line global-require
const {Renderer: PIXIRenderer} = require('@pixi/core');
this.renderer = new PIXIRenderer({width: size[0], height: size[1]});
}
else {
this.renderer = {
height: 0,
isFake: true,
width: 0,
};
}
[this.renderer.view.width, this.renderer.view.height] = size;
}
@ -12,24 +25,26 @@ export default class Renderer {
}
get element() {
return this.renderer.view;
return this.renderer.isFake ? undefined : this.renderer.view;
}
get height() {
return this.element.height;
return this.renderer.isFake ? 0 : this.element.height;
}
render(item, canvas) {
if (!this.renderer.isFake) {
const canvasInternal = canvas ? canvas.internal : undefined;
this.renderer.render(item.internal, canvasInternal);
}
}
get size() {
return [this.width, this.height];
}
get width() {
return this.element.width;
return this.renderer.isFake ? 0 : this.element.width;
}
}

View File

@ -1,13 +1,24 @@
import {Sprite as PIXISprite} from '@pixi/sprite';
import Renderable from './renderable';
const {
SIDE,
} = process.env;
export default class Sprite extends Renderable {
constructor(image) {
super();
this._image = image;
if ('client' === SIDE) {
// eslint-disable-next-line global-require
const {Sprite: PIXISprite} = require('@pixi/sprite');
this.sprite = new PIXISprite(image.texture);
}
else {
this.sprite = {
isFake: true,
};
}
this.anchor = [0.5, 0.5];
}

View File

@ -1,6 +1,7 @@
import {compose, Property} from '@avocado/core';
import {Property} from '@avocado/core';
import {InputNormalizer} from '@avocado/input';
import {Vector} from '@avocado/math';
import {compose} from '@latus/core';
import Container from './container';
import Renderer from './renderer';

View File

@ -1,12 +1,23 @@
import {Text as PIXIText} from '@pixi/text';
import Renderable from './renderable';
const {
SIDE,
} = process.env;
export default class Text extends Renderable {
constructor(text, style) {
super();
if ('client' === SIDE) {
// eslint-disable-next-line global-require
const {Text: PIXIText} = require('@pixi/text');
this.text = new PIXIText(text, style);
}
else {
this.text = {
isFake: true,
};
}
this.anchor = [0.5, 0.5];
}

View File

@ -0,0 +1,13 @@
import Pictured from './pictured';
import Primitive from './primitive';
import Staged from './staged';
import Textual from './textual';
import Visible from './visible';
export default () => ({
Pictured,
Primitive,
Staged,
Textual,
Visible,
});

View File

@ -1,4 +1,4 @@
import {StateProperty, Trait} from '@avocado/entity';
import {StateProperty, Trait} from '@avocado/traits';
import {Rectangle, Vector} from '@avocado/math';
import {compose} from '@latus/core';

View File

@ -1,4 +1,4 @@
import {Trait} from '@avocado/entity';
import {Trait} from '@avocado/traits';
import Color from '../color';
import Primitives from '../primitives';

View File

@ -1,5 +1,6 @@
import {compose, Property} from '@avocado/core';
import {Trait} from '@avocado/entity';
import {Property} from '@avocado/core';
import {Trait} from '@avocado/traits';
import {compose} from '@latus/core';
const decorate = compose(
Property('stage', {

View File

@ -1,5 +1,5 @@
import {compose} from '@avocado/core';
import {StateProperty, Trait} from '@avocado/entity';
import {StateProperty, Trait} from '@avocado/traits';
import {compose} from '@latus/core';
import Text from '../text';

View File

@ -1,6 +1,6 @@
import {compose} from '@avocado/core';
import {StateProperty, Trait} from '@avocado/entity';
import {StateProperty, Trait} from '@avocado/traits';
import {Rectangle} from '@avocado/math';
import {compose} from '@latus/core';
import Container from '../container';

BIN
packages/graphics/test/fixtures/test.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

View File

@ -2,18 +2,6 @@
# yarn lockfile v1
"@avocado/behavior@^2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2fbehavior/-/behavior-2.0.0.tgz#6478ca2f16957c3a010f792e013f4688583bf033"
integrity sha512-psHGbLG/EVaY6/9FwCvnNYA7LLXYVUQUiDbXZAyhkPNV5dAEmcQX8LdYUxDJ2Q32upow15+t8Np8u0XHcOHc4g==
dependencies:
"@avocado/core" "^2.0.0"
"@avocado/entity" "2.0.0"
"@latus/core" "^2.0.0"
debug "4.3.1"
deepmerge "^4.2.2"
lodash.mapvalues "^4.6.0"
"@avocado/core@2.0.0", "@avocado/core@^2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2fcore/-/core-2.0.0.tgz#636ea3c3b54a38538c59485080f6a0e48f1798e7"
@ -21,45 +9,6 @@
dependencies:
debug "4.3.1"
"@avocado/entity@2.0.0", "@avocado/entity@^2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2fentity/-/entity-2.0.0.tgz#30339ca125508848056d158817f7f02ab12384e6"
integrity sha512-XE+pYl9C6SrknSrOM7Lge0scG3O5v26OjO6mjcnandl66BkPKHKQveJBAEhEf4Gx5hlPObkDiY+QMJ4YzRBHcQ==
dependencies:
"@avocado/behavior" "^2.0.0"
"@avocado/core" "2.0.0"
"@avocado/math" "2.0.0"
"@avocado/resource" "2.0.0"
"@avocado/s13n" "^2.0.0"
"@avocado/timing" "^2.0.0"
"@latus/core" "^2.0.0"
"@latus/socket" "^2.0.0"
debug "4.3.1"
deepmerge "^4.2.2"
lodash.without "^4.4.0"
"@avocado/graphics@^2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2fgraphics/-/graphics-2.0.0.tgz#7a136ed9448be44eeec291cb546c847e04d3cf92"
integrity sha512-yfgug627SeIMrTqxWDZOEuu6J9/nRzyPWoOaIvqFvtlzvBf6C+mlfdhcc5FW2J/9g2LbLvk4XYN4OINBd50DsA==
dependencies:
"@avocado/core" "2.0.0"
"@avocado/input" "2.0.0"
"@avocado/math" "2.0.0"
"@avocado/resource" "^2.0.0"
"@latus/core" "^2.0.0"
"@latus/socket" "^2.0.0"
"@pixi/constants" "^5.3.6"
"@pixi/core" "^5.3.6"
"@pixi/display" "^5.3.6"
"@pixi/filter-advanced-bloom" "^3.2.0"
"@pixi/filter-color-matrix" "^5.3.6"
"@pixi/graphics" "^5.3.6"
"@pixi/settings" "^5.3.6"
"@pixi/sprite" "^5.3.6"
"@pixi/text" "^5.3.6"
debug "4.3.1"
"@avocado/input@2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2finput/-/input-2.0.0.tgz#fd6c9eb436416a008f5502cf6bba3f9277256021"
@ -69,7 +18,7 @@
"@latus/socket" "^2.0.0"
debug "4.3.1"
"@avocado/math@2.0.0", "@avocado/math@^2.0.0":
"@avocado/math@2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2fmath/-/math-2.0.0.tgz#8c1a04a08a1085c646029c21e7e49798227bee35"
integrity sha512-SvF3pEYkg6L082ydxHNS/TMOrdC1d55fiYIsocX7y8ym7ySO2lH2pzoOo4/1AndQjkU5zpw3ENAm+FCDT0goug==
@ -78,10 +27,10 @@
d3-quadtree "^2.0.0"
debug "4.3.1"
"@avocado/resource@2.0.0", "@avocado/resource@^2.0.0":
"@avocado/resource@2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2fresource/-/resource-2.0.0.tgz#a7b594584c172cff472d9a298bcd9d62c27186f2"
integrity sha512-q7MacbQl1ozA5Z3ZOKyUcMRBJAhly19dCtrNxYCki7mXIe1DoP0VvipFIgMlquLhkmtxxT2uMzVvHeJxhDxsgw==
resolved "https://npm.i12e.cha0s.io/@avocado%2fresource/-/resource-2.0.0.tgz#2eb014c2c876f3f51bc71d6594d93091b22013c8"
integrity sha512-3dks0rsuY1twlLm+vTrsqfV9anXR/0ZdQfe2YAJIdmiVQ7QEB2mQhUgMvqjgsuhI7ad1ygxD/I9hXBjl6CvyjA==
dependencies:
"@avocado/core" "^2.0.0"
"@latus/core" "^2.0.0"
@ -99,18 +48,14 @@
debug "4.3.1"
msgpack-lite "^0.1.26"
"@avocado/timing@^2.0.0":
"@avocado/traits@^2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2ftiming/-/timing-2.0.0.tgz#de76571519cb835a7f45528e91bdb9a18f1947fa"
integrity sha512-pJITg7q3kX9H2XEFP+jHPMiY317o4rCb/zzBdUbqC1RY5z5Et/LeTkQa/pd4IPqXeUK9omW4eM24jdCp8uH1tg==
resolved "http://172.18.0.8:4873/@avocado%2ftraits/-/traits-2.0.0.tgz#4717919e101a4fa81469bc5efe7c5478bb293a4e"
integrity sha512-7siD4XME3NzhTholUPndRYloHowV8z/s+FnzqG7p2/idNHrXURXsVBeYBI9lcM0SX1ONY+9OVdH0ykiu5qBScg==
dependencies:
"@avocado/core" "^2.0.0"
"@avocado/entity" "^2.0.0"
"@avocado/graphics" "^2.0.0"
"@avocado/math" "^2.0.0"
"@avocado/resource" "^2.0.0"
"@avocado/s13n" "^2.0.0"
"@latus/core" "^2.0.0"
"@latus/socket" "^2.0.0"
debug "4.3.1"
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.11":
@ -1031,7 +976,7 @@
webpack-hot-middleware "^2.25.0"
webpack-virtual-modules "^0.4.1"
"@latus/socket@^2.0.0":
"@latus/socket@2.0.0", "@latus/socket@^2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@latus%2fsocket/-/socket-2.0.0.tgz#2a35bba0db3542ab18a913320f7f6d24228ab5f1"
integrity sha512-qAWV/+3GI/GNyu/Ls6EFZpZr+2Q288YtgyjOzCNm6nRwy9N+JGJs1Y7yhJlLuao0K5EzHuYif3Vpo4DeRIVqNw==
@ -1054,6 +999,11 @@
eslint-config-airbnb-base "^14.2.1"
eslint-plugin-import "^2.22.1"
"@neutrinojs/banner@9.4.0":
version "9.4.0"
resolved "https://npm.i12e.cha0s.io/@neutrinojs%2fbanner/-/banner-9.4.0.tgz#897308ba73bf530f9f0eaa412a8f7596d76249e9"
integrity sha512-ZpAmGbpexGEwoHQV2B4lbK2cCUcCR5ImF9mxs3Bs6wXgRJLI9nCzxp/eBGgl1hhv5Zwi8AwdUGfP1Uno/HlZcw==
"@neutrinojs/clean@9.5.0":
version "9.5.0"
resolved "https://npm.i12e.cha0s.io/@neutrinojs%2fclean/-/clean-9.5.0.tgz#77cfb0add1584741c7501f5e12ad206b67f216bf"
@ -1174,31 +1124,31 @@
babel-merge "^3.0.0"
deepmerge "^1.5.2"
"@pixi/constants@5.3.6", "@pixi/constants@^5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2fconstants/-/constants-5.3.6.tgz#b3b61b5d5047d022df3b8bed82eeb2b052457ded"
integrity sha512-4FF6GIj88/rddqMJeVlbxKUDgSpb6vSX9yWR1S17Urn4B3RCZErlfSEcTIuSOpLbs0F1h9K7UdIrzbJp2aefzw==
"@pixi/constants@5.3.7", "@pixi/constants@^5.3.6":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2fconstants/-/constants-5.3.7.tgz#a2e1789a98deb3713cfcb3eba3db84588bc9161e"
integrity sha512-MBcgIM/mSqonFezkCI9080IqNlc0wb8S9QJ5otBdseOWUQa/ua2jF7Jd1sCBGmi0IzS9/NOHFXzZVTdS7AC7Ow==
"@pixi/core@5.3.6", "@pixi/core@^5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2fcore/-/core-5.3.6.tgz#85559a71fd35c459c094ff30899f85cbcf8d2f81"
integrity sha512-Q5myUdcaJH5dtWbxerLn6YSFR3AjIgk58o7x7CzymJ7U5kdBjNB0yNdMVSbDQpf+lK4edtWYpuelot7SAthk+g==
"@pixi/core@5.3.7", "@pixi/core@^5.3.6":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2fcore/-/core-5.3.7.tgz#a8d65ca17f0c4ef8c0c5a22d31b9e02a4ab73b93"
integrity sha512-WBhU2f5aJSVVaFP55FFBFKjKlRf5fYGxgA/U3kD4yD4Y3d3d6V3MIZv+o0VX+kBs1Eq7ePZqEv2smDrlzzMEjQ==
dependencies:
"@pixi/constants" "5.3.6"
"@pixi/math" "5.3.6"
"@pixi/runner" "5.3.6"
"@pixi/settings" "5.3.6"
"@pixi/ticker" "5.3.6"
"@pixi/utils" "5.3.6"
"@pixi/constants" "5.3.7"
"@pixi/math" "5.3.7"
"@pixi/runner" "5.3.7"
"@pixi/settings" "5.3.7"
"@pixi/ticker" "5.3.7"
"@pixi/utils" "5.3.7"
"@pixi/display@5.3.6", "@pixi/display@^5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2fdisplay/-/display-5.3.6.tgz#90a629c4d9b7a118b7b8cc0ea4b843d1b93026f3"
integrity sha512-cbUaWz2R2vNO5BD9Ic6hYyazQQV8ndQfPonbBcehQQhNC+aZjuYgarHqiUb4Z7/GKkRQzB9WyoT8P5V5LppufQ==
"@pixi/display@5.3.7", "@pixi/display@^5.3.6":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2fdisplay/-/display-5.3.7.tgz#b661d2ecfd2a67f213665a0698acd29e17eee8fe"
integrity sha512-ma1JyLe5vaEgmaOR+anvj5YOKqT9OEWnboIe7NVmwGF1CZ7JFnB12rsRulHUsSaFG9bP5xjvroAZjFg/WvyGLw==
dependencies:
"@pixi/math" "5.3.6"
"@pixi/settings" "5.3.6"
"@pixi/utils" "5.3.6"
"@pixi/math" "5.3.7"
"@pixi/settings" "5.3.7"
"@pixi/utils" "5.3.7"
"@pixi/filter-advanced-bloom@^3.2.0":
version "3.2.0"
@ -1208,11 +1158,11 @@
"@pixi/filter-kawase-blur" "3.2.0"
"@pixi/filter-color-matrix@^5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2ffilter-color-matrix/-/filter-color-matrix-5.3.6.tgz#466f563e20721900b202a87c8d47a5ea8e31c741"
integrity sha512-u/OZEPhdMT2rzCNZZXBsIwVyp79X4rM029JMioJdYrFEPDnAuDIBKrY5//gOHFdQlYsjRIaW0IcykCPqUvBs3A==
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2ffilter-color-matrix/-/filter-color-matrix-5.3.7.tgz#230cafe46bde36e25441b13f3ac5dd8e8fee4311"
integrity sha512-Z12cxoHx9uMh3CZ0PLVRzsaFHHF/CfU3J83KI9k+Bg/DFOh/J/5EToCd44jYJbMKp3nvXcO1EJyZ3wwC/IsyfQ==
dependencies:
"@pixi/core" "5.3.6"
"@pixi/core" "5.3.7"
"@pixi/filter-kawase-blur@3.2.0":
version "3.2.0"
@ -1220,71 +1170,71 @@
integrity sha512-IO1UKn/XLvnV+ya4r1UOC9fTfXZjWvH9m6eQ/U+moBsQN5I5FihQfXCu586X4jb9VHNu3gFl7SUzirobhBfgtA==
"@pixi/graphics@^5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2fgraphics/-/graphics-5.3.6.tgz#1d38359926d174cccd3219936285140b715344e7"
integrity sha512-FDZlAkxrbCZTjzNMWW6q6N/GAfyfftwHOGb67oLJ+NCG2wagOGUPQYRRGBK5f45dgDdM+1is7UwbhdQ8Rvg9ig==
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2fgraphics/-/graphics-5.3.7.tgz#36ae80e2508e0a9c61ce454807d517d370d90a74"
integrity sha512-+6+bT/AC29a1Hw5XDxsH1UqBsXSqcna7wNTTrBQ02owotIJtyRc6w48f5qxzhxycumyVCR87IV5tAtdwX3xhag==
dependencies:
"@pixi/constants" "5.3.6"
"@pixi/core" "5.3.6"
"@pixi/display" "5.3.6"
"@pixi/math" "5.3.6"
"@pixi/sprite" "5.3.6"
"@pixi/utils" "5.3.6"
"@pixi/constants" "5.3.7"
"@pixi/core" "5.3.7"
"@pixi/display" "5.3.7"
"@pixi/math" "5.3.7"
"@pixi/sprite" "5.3.7"
"@pixi/utils" "5.3.7"
"@pixi/math@5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2fmath/-/math-5.3.6.tgz#3933bae1a0af912b4384389b63ceffdcf108723a"
integrity sha512-ccW/LrSsLaHunj1ztfp2UpxKGftiaK/nURZa51CFhbGYQBrYZBk27x1fgwGAs4ualTtqZOeyaLhv4nY0ljm5Qw==
"@pixi/math@5.3.7":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2fmath/-/math-5.3.7.tgz#066e7ea149fd38db8d8a9584aac5f41d02b36bdd"
integrity sha512-WnjUwX7rkxR36F0xknpsNd9BsfQosV0BbyFE0Il88IURBM3Tu9X4tC7RGJDgWU+aXw23HgHu0j+MWJrCVCM2fA==
"@pixi/runner@5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2frunner/-/runner-5.3.6.tgz#b123f1a674aa249e4067ff00f9a3027d01ac69a8"
integrity sha512-qiGoMVk0P0p3IfH5LTIH/dKyiNUzIHMxoykPODWni648hFa4CEFpG3bHJorcyYvmALCFgHjH2hhrqQexK3T6Kw==
"@pixi/runner@5.3.7":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2frunner/-/runner-5.3.7.tgz#78ed2c92b392b8c099d2e4557dded7faa921446b"
integrity sha512-kt5apNb21HAvpBaDaPRs33k2O0VzrKe13w4we8iftCpXX8w68ErAY1lH68vmtDNrxnlHg4M9nRgEoMeiHlo2RA==
"@pixi/settings@5.3.6", "@pixi/settings@^5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2fsettings/-/settings-5.3.6.tgz#d138ba2180557174c3f942fc9656de35f1a77026"
integrity sha512-hWMC1KwB2InFoJPdnI97ckHX0Z7912aaB2oQUJwKv0hhSrc8vxq9Dg6UofVY+wGMHDVCvqJPnvCsTYuKUmwRxw==
"@pixi/settings@5.3.7", "@pixi/settings@^5.3.6":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2fsettings/-/settings-5.3.7.tgz#b661883231bf2a1ff5260c214bd0c4b438759841"
integrity sha512-g6AoRSGWxU34gtKSQwX2AMQoLUv86L/5iIXRsqo+X4bfUSCenTci1X7ueVrSIbo39dxh6IOpriZF2Yk3TeHG5w==
dependencies:
ismobilejs "^1.1.0"
"@pixi/sprite@5.3.6", "@pixi/sprite@^5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2fsprite/-/sprite-5.3.6.tgz#04c13b0ce1c7379a2f570d28db58d1f54ce44c55"
integrity sha512-Q5nRj7mhWuVHvn2rMtlf+6CdTjdovxX0R9ANffPcY7EODn5m7F4GpXEwBOjDICtVyHXrXhz2k4Gi2XWPFeeZ7A==
"@pixi/sprite@5.3.7", "@pixi/sprite@^5.3.6":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2fsprite/-/sprite-5.3.7.tgz#c6edf3d4a9928868696b62e35a60ded27d167058"
integrity sha512-Bjl+NOOvigEzUsm1cDr1KmBUpPSWO8pDXpUPTi+v2N75gwRfTycmj5f2TU0QmMW3Gc6sv0CB0AkL7dkMPwPb8g==
dependencies:
"@pixi/constants" "5.3.6"
"@pixi/core" "5.3.6"
"@pixi/display" "5.3.6"
"@pixi/math" "5.3.6"
"@pixi/settings" "5.3.6"
"@pixi/utils" "5.3.6"
"@pixi/constants" "5.3.7"
"@pixi/core" "5.3.7"
"@pixi/display" "5.3.7"
"@pixi/math" "5.3.7"
"@pixi/settings" "5.3.7"
"@pixi/utils" "5.3.7"
"@pixi/text@^5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2ftext/-/text-5.3.6.tgz#55b45c8968a28304f5b7aef289e6f062772a060a"
integrity sha512-maEZoIysPOuzzSH+TN2cGnqDDMdTVtFNY9dJdKgmMleY9oCPES/iiNkcdki40S9JfaM7GM3ywn2xbJruJ5aZCg==
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2ftext/-/text-5.3.7.tgz#cb71b2576bdc1f66fb79977d281f9575dd06d3d5"
integrity sha512-WVAc31MDgHTvP0dJNWsvLVJhjeVGZ3NrLpHcH9iIAd6HVO5Z+i+fk4zvodD+Y7jWU0psx8ZD8xe1wy8ECfbCBA==
dependencies:
"@pixi/core" "5.3.6"
"@pixi/math" "5.3.6"
"@pixi/settings" "5.3.6"
"@pixi/sprite" "5.3.6"
"@pixi/utils" "5.3.6"
"@pixi/core" "5.3.7"
"@pixi/math" "5.3.7"
"@pixi/settings" "5.3.7"
"@pixi/sprite" "5.3.7"
"@pixi/utils" "5.3.7"
"@pixi/ticker@5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2fticker/-/ticker-5.3.6.tgz#022416047199ae1ac875f750efddfb0a0ba20abd"
integrity sha512-3BHDrFyI5aHcAlo9fdQ5pd4U1pwt5QwGpbM9EshFL2NeNdumAeZQJ850DXFhVfFAXhhNljEQTFNZ44sTIsAy6Q==
"@pixi/ticker@5.3.7":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2fticker/-/ticker-5.3.7.tgz#c331b270042d507fe18543ae435a9a857a8fd5ae"
integrity sha512-ZEXiJwPtuPeWa0QmRODF5qK0+ugZu/xeq7QxCvFOCc3NFVBeGms4g92HPucOju9R7jcODIoJxtICALsuwLAr9w==
dependencies:
"@pixi/settings" "5.3.6"
"@pixi/settings" "5.3.7"
"@pixi/utils@5.3.6":
version "5.3.6"
resolved "https://npm.i12e.cha0s.io/@pixi%2futils/-/utils-5.3.6.tgz#63ada7f024884390324b430ad19b6e031791c319"
integrity sha512-Ilix2qpF89SSyoUpPsjH2RB7Os6ceQ+gts55zpMbLyxMyuMH6GlZ9WgUEhAakkUEtQ6imi3ZZAxCNLAEWNB+cw==
"@pixi/utils@5.3.7":
version "5.3.7"
resolved "https://npm.i12e.cha0s.io/@pixi%2futils/-/utils-5.3.7.tgz#55fe2a2fbf0fba842da5a602576ce68c498e7e16"
integrity sha512-f8zAeHHURxfwBr8MZiXEIwY2h9wbS6vN0ypvapGvKFOexZ1EInTs35FhEiRWzLEPLHyn1RgCdKzR2zl++E4tIw==
dependencies:
"@pixi/constants" "5.3.6"
"@pixi/settings" "5.3.6"
"@pixi/constants" "5.3.7"
"@pixi/settings" "5.3.7"
earcut "^2.1.5"
eventemitter3 "^3.1.0"
url "^0.11.0"
@ -2205,9 +2155,9 @@ camelcase@^6.0.0:
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
caniuse-lite@^1.0.30001165:
version "1.0.30001170"
resolved "https://npm.i12e.cha0s.io/caniuse-lite/-/caniuse-lite-1.0.30001170.tgz#0088bfecc6a14694969e391cc29d7eb6362ca6a7"
integrity sha512-Dd4d/+0tsK0UNLrZs3CvNukqalnVTRrxb5mcQm8rHL49t7V5ZaTygwXkrq+FB+dVDf++4ri8eJnFEJAB8332PA==
version "1.0.30001171"
resolved "https://npm.i12e.cha0s.io/caniuse-lite/-/caniuse-lite-1.0.30001171.tgz#3291e11e02699ad0a29e69b8d407666fc843eba7"
integrity sha512-5Alrh8TTYPG9IH4UkRqEBZoEToWRLvPbSQokvzSz0lii8/FOWKG4keO1HoYfPWs8IF/NH/dyNPg1cmJGvV3Zlg==
chai@4.2.0:
version "4.2.0"
@ -2693,7 +2643,7 @@ debug@4.3.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
dependencies:
ms "2.1.2"
debug@^3.1.1, debug@^3.2.5:
debug@^3.1.1, debug@^3.2.6:
version "3.2.7"
resolved "https://npm.i12e.cha0s.io/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
@ -3141,7 +3091,7 @@ es-abstract@^1.17.0-next.1:
string.prototype.trimend "^1.0.1"
string.prototype.trimstart "^1.0.1"
es-abstract@^1.18.0-next.0, es-abstract@^1.18.0-next.1:
es-abstract@^1.18.0-next.1:
version "1.18.0-next.1"
resolved "https://npm.i12e.cha0s.io/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68"
integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==
@ -3583,14 +3533,7 @@ fastparse@^1.1.1:
resolved "https://npm.i12e.cha0s.io/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9"
integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==
faye-websocket@^0.10.0:
version "0.10.0"
resolved "https://npm.i12e.cha0s.io/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=
dependencies:
websocket-driver ">=0.5.1"
faye-websocket@~0.11.1:
faye-websocket@^0.11.3:
version "0.11.3"
resolved "https://npm.i12e.cha0s.io/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e"
integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==
@ -3843,7 +3786,7 @@ get-func-name@^2.0.0:
resolved "https://npm.i12e.cha0s.io/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=
get-intrinsic@^1.0.0, get-intrinsic@^1.0.1:
get-intrinsic@^1.0.0, get-intrinsic@^1.0.1, get-intrinsic@^1.0.2:
version "1.0.2"
resolved "https://npm.i12e.cha0s.io/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49"
integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==
@ -4264,6 +4207,13 @@ ignore@^4.0.6:
resolved "https://npm.i12e.cha0s.io/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
image-size@^0.9.3:
version "0.9.3"
resolved "https://npm.i12e.cha0s.io/image-size/-/image-size-0.9.3.tgz#f7efce6b0a1649b44b9bc43b9d9a5acf272264b6"
integrity sha512-5SakFa79uhUVSjKeQE30GVzzLJ0QNzB53+I+/VD1vIesD6GP6uatWIlgU0uisFNLt1u0d6kBydp7yfk+lLJhLQ==
dependencies:
queue "6.0.1"
import-fresh@^3.0.0, import-fresh@^3.2.1:
version "3.3.0"
resolved "https://npm.i12e.cha0s.io/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
@ -4680,7 +4630,7 @@ json-stable-stringify-without-jsonify@^1.0.1:
resolved "https://npm.i12e.cha0s.io/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
json3@^3.3.2:
json3@^3.3.3:
version "3.3.3"
resolved "https://npm.i12e.cha0s.io/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==
@ -4829,21 +4779,11 @@ lodash.flatten@^4.4.0:
resolved "https://npm.i12e.cha0s.io/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
lodash.mapvalues@^4.6.0:
version "4.6.0"
resolved "https://npm.i12e.cha0s.io/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c"
integrity sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=
lodash.omit@^4.5.0:
version "4.5.0"
resolved "https://npm.i12e.cha0s.io/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60"
integrity sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=
lodash.without@^4.4.0:
version "4.4.0"
resolved "https://npm.i12e.cha0s.io/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac"
integrity sha1-PNRXSgC2e643OpS3SHcmQFB7eqw=
lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20:
version "4.17.20"
resolved "https://npm.i12e.cha0s.io/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
@ -5392,7 +5332,7 @@ object-hash@^2.0.3:
resolved "https://npm.i12e.cha0s.io/object-hash/-/object-hash-2.1.1.tgz#9447d0279b4fcf80cff3259bf66a1dc73afabe09"
integrity sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==
object-inspect@^1.8.0:
object-inspect@^1.8.0, object-inspect@^1.9.0:
version "1.9.0"
resolved "https://npm.i12e.cha0s.io/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a"
integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==
@ -6073,6 +6013,13 @@ querystringify@^2.1.1:
resolved "https://npm.i12e.cha0s.io/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
queue@6.0.1:
version "6.0.1"
resolved "https://npm.i12e.cha0s.io/queue/-/queue-6.0.1.tgz#abd5a5b0376912f070a25729e0b6a7d565683791"
integrity sha512-AJBQabRCCNr9ANq8v77RJEv73DPbn55cdTb+Giq4X0AVnNVZvMHlYp7XlQiN+1npCZj1DuSmaA2hYVUUDgxFDg==
dependencies:
inherits "~2.0.3"
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
version "2.1.0"
resolved "https://npm.i12e.cha0s.io/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
@ -6424,7 +6371,7 @@ select-hose@^2.0.0:
resolved "https://npm.i12e.cha0s.io/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
selfsigned@^1.10.7:
selfsigned@^1.10.8:
version "1.10.8"
resolved "https://npm.i12e.cha0s.io/selfsigned/-/selfsigned-1.10.8.tgz#0d17208b7d12c33f8eac85c41835f27fc3d81a30"
integrity sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==
@ -6572,12 +6519,13 @@ shebang-regex@^3.0.0:
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
side-channel@^1.0.2, side-channel@^1.0.3:
version "1.0.3"
resolved "https://npm.i12e.cha0s.io/side-channel/-/side-channel-1.0.3.tgz#cdc46b057550bbab63706210838df5d4c19519c3"
integrity sha512-A6+ByhlLkksFoUepsGxfj5x1gTSrs+OydsRptUxeNCabQpCFUvcwIczgOigI8vhY/OJCnPnyE9rGiwgvr9cS1g==
version "1.0.4"
resolved "https://npm.i12e.cha0s.io/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
dependencies:
es-abstract "^1.18.0-next.0"
object-inspect "^1.8.0"
call-bind "^1.0.0"
get-intrinsic "^1.0.2"
object-inspect "^1.9.0"
signal-exit@^3.0.0:
version "3.0.3"
@ -6683,26 +6631,26 @@ socket.io@2.3.0:
socket.io-client "2.3.0"
socket.io-parser "~3.4.0"
sockjs-client@1.4.0:
version "1.4.0"
resolved "https://npm.i12e.cha0s.io/sockjs-client/-/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5"
integrity sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==
sockjs-client@^1.5.0:
version "1.5.0"
resolved "https://npm.i12e.cha0s.io/sockjs-client/-/sockjs-client-1.5.0.tgz#2f8ff5d4b659e0d092f7aba0b7c386bd2aa20add"
integrity sha512-8Dt3BDi4FYNrCFGTL/HtwVzkARrENdwOUf1ZoW/9p3M8lZdFT35jVdrHza+qgxuG9H3/shR4cuX/X9umUrjP8Q==
dependencies:
debug "^3.2.5"
debug "^3.2.6"
eventsource "^1.0.7"
faye-websocket "~0.11.1"
inherits "^2.0.3"
json3 "^3.3.2"
url-parse "^1.4.3"
faye-websocket "^0.11.3"
inherits "^2.0.4"
json3 "^3.3.3"
url-parse "^1.4.7"
sockjs@0.3.20:
version "0.3.20"
resolved "https://npm.i12e.cha0s.io/sockjs/-/sockjs-0.3.20.tgz#b26a283ec562ef8b2687b44033a4eeceac75d855"
integrity sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==
sockjs@^0.3.21:
version "0.3.21"
resolved "https://npm.i12e.cha0s.io/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417"
integrity sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==
dependencies:
faye-websocket "^0.10.0"
faye-websocket "^0.11.3"
uuid "^3.4.0"
websocket-driver "0.6.5"
websocket-driver "^0.7.4"
sort-keys@^1.0.0:
version "1.1.2"
@ -7304,7 +7252,7 @@ url-loader@^4.1.1:
mime-types "^2.1.27"
schema-utils "^3.0.0"
url-parse@^1.4.3:
url-parse@^1.4.3, url-parse@^1.4.7:
version "1.4.7"
resolved "https://npm.i12e.cha0s.io/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278"
integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==
@ -7468,9 +7416,9 @@ webpack-dev-middleware@^4.0.2:
schema-utils "^3.0.0"
webpack-dev-server@^3.11.0:
version "3.11.0"
resolved "https://npm.i12e.cha0s.io/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz#8f154a3bce1bcfd1cc618ef4e703278855e7ff8c"
integrity sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==
version "3.11.1"
resolved "https://npm.i12e.cha0s.io/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz#c74028bf5ba8885aaf230e48a20e8936ab8511f0"
integrity sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ==
dependencies:
ansi-html "0.0.7"
bonjour "^3.5.0"
@ -7492,11 +7440,11 @@ webpack-dev-server@^3.11.0:
p-retry "^3.0.1"
portfinder "^1.0.26"
schema-utils "^1.0.0"
selfsigned "^1.10.7"
selfsigned "^1.10.8"
semver "^6.3.0"
serve-index "^1.9.1"
sockjs "0.3.20"
sockjs-client "1.4.0"
sockjs "^0.3.21"
sockjs-client "^1.5.0"
spdy "^4.0.2"
strip-ansi "^3.0.1"
supports-color "^6.1.0"
@ -7571,14 +7519,7 @@ webpack@^4:
watchpack "^1.7.4"
webpack-sources "^1.4.1"
websocket-driver@0.6.5:
version "0.6.5"
resolved "https://npm.i12e.cha0s.io/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36"
integrity sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=
dependencies:
websocket-extensions ">=0.1.1"
websocket-driver@>=0.5.1:
websocket-driver@>=0.5.1, websocket-driver@^0.7.4:
version "0.7.4"
resolved "https://npm.i12e.cha0s.io/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760"
integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==
@ -7657,9 +7598,9 @@ ws@^6.2.1:
async-limiter "~1.0.0"
ws@^7.1.2:
version "7.4.1"
resolved "https://npm.i12e.cha0s.io/ws/-/ws-7.4.1.tgz#a333be02696bd0e54cea0434e21dcc8a9ac294bb"
integrity sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==
version "7.4.2"
resolved "https://npm.i12e.cha0s.io/ws/-/ws-7.4.2.tgz#782100048e54eb36fe9843363ab1c68672b261dd"
integrity sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==
ws@~6.1.0:
version "6.1.4"

View File

@ -20,8 +20,8 @@
"index.js.map"
],
"dependencies": {
"@latus/core": "^2.0.0",
"@latus/socket": "^2.0.0",
"@latus/core": "2.0.0",
"@latus/socket": "2.0.0",
"debug": "4.3.1"
},
"devDependencies": {

View File

@ -20,7 +20,8 @@
"index.js.map"
],
"dependencies": {
"@avocado/core": "^2.0.0",
"@avocado/core": "2.0.0",
"@latus/core": "^2.0.0",
"d3-quadtree": "^2.0.0",
"debug": "4.3.1"
},

View File

@ -1,4 +1,5 @@
import {compose, Property} from '@avocado/core';
import {Property} from '@avocado/core';
import {compose} from '@latus/core';
import * as Vector from './vector';
@ -15,7 +16,8 @@ export default function VectorMixin(
...meta,
};
const transformedKey = `$$avocado_property_${vectorKey}`;
meta.initialize = () => {
// eslint-disable-next-line func-names
meta.initialize = function () {
this[transformedKey] = Vector.copy(meta.default);
};
const bypass = `${transformedKey}$bypassChangedEvent`;

View File

@ -2,10 +2,10 @@
# yarn lockfile v1
"@avocado/core@^2.0.0":
"@avocado/core@2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2fcore/-/core-2.0.0.tgz#636ea3c3b54a38538c59485080f6a0e48f1798e7"
integrity sha512-VW+ygRHaQQwaL5rKZGm0n0DNfvj+H89qQx+67veCUmUuRav3XAeE0iYs8Lgfc3CJLPz/alqt/dVPMXd5QDR+Mg==
resolved "https://npm.i12e.cha0s.io/@avocado%2fcore/-/core-2.0.0.tgz#ac7f912135c1cbb433b825c0fd1aa9a14b91ffed"
integrity sha512-PX6UVuhcmUaf2yzhTEd+dUle/Z3JRWJXm7NwGN63oL3w5QqUVOEzqUQNkKem2b+mlyJl56UnWzZJYYLixTOzvQ==
dependencies:
debug "4.3.1"
@ -899,6 +899,16 @@
minimatch "^3.0.4"
strip-json-comments "^3.1.1"
"@latus/core@^2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@latus%2fcore/-/core-2.0.0.tgz#4447b4bba265b684035be1dacefd6ba4913a47d4"
integrity sha512-OSsbO4wvVJFPZTMRDX5LAXOA+MQY8FOSK7PcTEJKeiRqOMeMIVkZc6q6KNlUIYivE+87rlM7S/CctHoA7uvQvg==
dependencies:
debug "4.3.1"
js-yaml "3.14.0"
lodash.capitalize "^4.2.1"
lodash.flatten "^4.4.0"
"@neutrinojs/airbnb-base@^9.4.0":
version "9.5.0"
resolved "https://npm.i12e.cha0s.io/@neutrinojs%2fairbnb-base/-/airbnb-base-9.5.0.tgz#d47fe0d927aa56814e70e1228af08918c5190808"
@ -3907,11 +3917,21 @@ locate-path@^6.0.0:
dependencies:
p-locate "^5.0.0"
lodash.capitalize@^4.2.1:
version "4.2.1"
resolved "https://npm.i12e.cha0s.io/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz#f826c9b4e2a8511d84e3aca29db05e1a4f3b72a9"
integrity sha1-+CbJtOKoUR2E46yinbBeGk87cqk=
lodash.clonedeep@^4.5.0:
version "4.5.0"
resolved "https://npm.i12e.cha0s.io/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
lodash.flatten@^4.4.0:
version "4.4.0"
resolved "https://npm.i12e.cha0s.io/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
lodash.omit@^4.5.0:
version "4.5.0"
resolved "https://npm.i12e.cha0s.io/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60"

View File

@ -0,0 +1 @@
module.exports = require('../../config/.eslintrc');

5
packages/physics/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
**/*.js
**/*.map
!/.*
!/webpack.config.js
!src/**/*.js

View File

@ -0,0 +1 @@
module.exports = require('../../config/.neutrinorc');

View File

@ -0,0 +1,54 @@
{
"name": "@avocado/package",
"version": "1.0.0",
"main": "index.js",
"author": "cha0s",
"license": "MIT",
"scripts": {
"build": "NODE_PATH=./node_modules webpack --mode production",
"clean": "rm -rf yarn.lock node_modules && yarn",
"dev": "NODE_PATH=./node_modules webpack --mode development",
"forcepub": "npm unpublish --force $(node -e 'const {name, version} = require(`./package.json`); process.stdout.write(`${name}@${version}`)') && npm publish",
"link": "node -e \"Object.keys(require('./package.json').dependencies).filter((m) => 0 === m.indexOf('@latus/')).forEach((m) => require('child_process').spawn('yarn', ['link', m]));\"",
"lint": "NODE_PATH=./node_modules eslint --format codeframe --ext mjs,js .",
"test": "NODE_PATH=./node_modules mocha --config ../../config/.mocharc.js",
"unlink": "node -e \"Object.keys(require('./package.json').dependencies).filter((m) => 0 === m.indexOf('@latus/')).forEach((m) => require('child_process').spawn('yarn', ['unlink', m]));\" && yarn install --force",
"watch": "NODE_PATH=./node_modules webpack --watch --mode development"
},
"files": [
"index.js",
"index.js.map"
],
"dependencies": {
"@avocado/behavior": "^2.0.0",
"@avocado/core": "^2.0.0",
"@avocado/entity": "^2.0.0",
"@avocado/graphics": "^2.0.0",
"@avocado/math": "^2.0.0",
"@avocado/s13n": "^2.0.0",
"@avocado/timing": "^2.0.0",
"@avocado/traits": "^2.0.0",
"@latus/core": "^2.0.0",
"debug": "4.3.1",
"deepmerge": "^4.2.2",
"immutable": "^4.0.0-rc.12",
"kefir": "^3.8.8",
"matter-js": "0.14.2",
"poly-decomp": "0.3.0",
"proton-js": "^3.1.2"
},
"devDependencies": {
"@neutrinojs/airbnb-base": "^9.4.0",
"@neutrinojs/copy": "9.4.0",
"@neutrinojs/mocha": "^9.4.0",
"@neutrinojs/react": "^9.4.0",
"chai": "4.2.0",
"eslint": "^7",
"eslint-import-resolver-webpack": "0.13.0",
"mocha": "^8",
"neutrino": "^9.4.0",
"webpack": "^4",
"webpack-cli": "^3",
"webpack-node-externals": "2.5.2"
}
}

View File

@ -0,0 +1,21 @@
import {virtualize} from '@avocado/core';
import {Class, compose} from '@latus/core';
const decorate = compose(
virtualize([
'applyForce',
'applyImpulse',
'vertices',
]),
);
export default class AbstractBody extends decorate(Class) {
constructor(world, shape) {
super();
this.impulse = [0, 0];
this.shape = shape;
this.world = world;
}
}

View File

@ -0,0 +1,66 @@
import {Property, virtualize} from '@avocado/core';
import {Class, compose} from '@latus/core';
const decorate = compose(
Property('stepTime', {
default: 1 / 60,
}),
virtualize([
'addBody',
'createBody',
]),
);
export default class AbstractWorld extends decorate(Class) {
constructor() {
super();
this.entities = new Map();
this.entitiesList = [];
}
associateBodyWithEntity(body, entity) {
this.entities.set(body, entity);
this.entitiesList.push(entity);
// eslint-disable-next-line no-param-reassign
body.position = entity.position;
}
removeBody(body) {
if (this.entities.has(body)) {
const entity = this.entities.get(body);
this.entities.delete(body);
const index = this.entitiesList.indexOf(entity);
if (-1 !== index) {
this.entitiesList.splice(index, 1);
}
}
// eslint-disable-next-line no-param-reassign
body.world = null;
}
tick(elapsed) {
this.tickPhysics(elapsed);
}
tickPhysics() {
// Propagate position updates.
const it = this.entities.entries();
for (let value = it.next(); value.done !== true; value = it.next()) {
const body = value.value[0];
const entity = value.value[1];
const entityPosition = entity.position;
const bodyPosition = body.position;
// Hot.
if (
/* eslint-disable no-bitwise */
(entityPosition[0] << 0) !== (bodyPosition[0] << 0)
|| (entityPosition[1] << 0) !== (bodyPosition[1] << 0)
/* eslint-enable no-bitwise */
) {
entity.setPosition(body.position);
}
}
}
}

View File

@ -0,0 +1,43 @@
import {Color, Primitives, Renderable} from '@avocado/graphics';
export default class BodyView extends Renderable {
constructor(body) {
super();
this.body = body;
this.primitives = new Primitives();
this.redraw();
}
get internal() {
return this.primitives.internal;
}
redraw() {
const {primitives} = this;
const {vertices} = this.body;
primitives.clear();
let firstVertice;
let lastVertice;
for (let i = 0; i < vertices.length; i++) {
const vertice = vertices[i];
if (!firstVertice) {
firstVertice = vertice;
}
if (lastVertice) {
primitives.drawLine(
lastVertice,
vertice,
Primitives.lineStyle(new Color(255, 255, 0), 1),
);
}
lastVertice = vertice;
}
primitives.drawLine(
lastVertice,
firstVertice,
Primitives.lineStyle(new Color(255, 255, 0), 1),
);
}
}

View File

@ -0,0 +1,36 @@
import * as I from 'immutable';
import {compose, EventEmitter} from '@avocado/core';
import {Rectangle, Vector} from '@avocado/math';
import AbstractBody from '../abstract/body';
const decorate = compose(
EventEmitter,
Vector.Mixin('position', 'x', 'y', {
default: [0, 0],
track: true,
}),
);
export default class Body extends decorate(AbstractBody) {
constructor(world, shape) {
super(world, shape);
this.force = [0, 0];
this.contacts = I.Set();
}
get aabb() {
return Rectangle.translated(this.shape.aabb, this.position);
}
applyForce(vector) {
this.force = Vector.add(this.force, vector);
}
applyImpulse(vector) {
this.impulse = Vector.add(this.impulse, vector);
}
}

View File

@ -0,0 +1,190 @@
import * as I from 'immutable';
import {arrayUnique} from '@avocado/core';
import {Rectangle, QuadTree, Vector} from '@avocado/math';
import Body from './body';
import AbstractWorld from '../abstract/world';
export default class World extends AbstractWorld {
constructor() {
super();
this.bodies = [];
this.quadTree = new QuadTree();
this.quadTreeNodes = new Map();
}
addBody(body) {
this.bodies.push(body);
// Add to quad tree.
this.addQuadTreeNodes(body);
body.on('positionChanged', () => {
this.removeQuadTreeNodes(body);
this.addQuadTreeNodes(body);
});
}
addQuadTreeNodes(body) {
// 4 points.
const {aabb} = body;
const points = Rectangle.toPoints(aabb);
const nodes = points.map((point) => [...point, body]);
this.quadTreeNodes.set(body, nodes);
for (let i = 0; i < nodes.length; i++) {
this.quadTree.add(nodes[i]);
}
}
createBody(shape) {
return new Body(this, shape);
}
removeBody(body) {
super.removeBody(body);
const index = this.bodies.indexOf(body);
if (-1 === index) {
return;
}
this.removeQuadTreeNodes(body);
this.bodies.splice(index, 1);
}
removeQuadTreeNodes(body) {
const nodes = this.quadTreeNodes.get(body);
if (!nodes) {
return;
}
for (let i = 0; i < nodes.length; i++) {
this.quadTree.remove(nodes[i]);
}
}
tick(elapsed) {
let entities;
// Apply.
entities = this.entities.values();
for (let i = 0; i < entities.length; i++) {
const {body} = entities[i];
const translation = Vector.add(
Vector.mul(body.impulse, elapsed),
body.force,
);
body.position = Vector.add(body.position, translation);
}
// Contact checks.
const allContacts = new Map();
const checkedSoFar = new Map();
entities = this.entities.values();
for (let i = 0; i < entities.length; i++) {
const entity = entities[i];
const {body} = entity;
// Find bodies in AABB.
const {aabb} = body;
let otherBodies = this.quadTree.search(aabb).map((node) => node.data[2]);
// Not self.
otherBodies = otherBodies.filter((otherBody) => otherBody !== body);
// Uniques only.
otherBodies = arrayUnique(otherBodies);
// TODO: full collision check
const checkSet = new Set();
checkedSoFar.set(entity, checkSet);
for (let j = 0; j < otherBodies.length; j++) {
const otherBody = otherBodies[j];
const otherEntity = this.entities.get(otherBody);
if (otherEntity) {
// Only one check per pair.
const otherCheckSet = checkedSoFar.get(otherEntity);
if (otherCheckSet) {
if (otherCheckSet.has(entity)) {
// eslint-disable-next-line no-continue
continue;
}
}
// Self contacts.
let contacts = allContacts.get(entity);
if (!contacts) {
contacts = I.Set();
}
contacts = contacts.add(otherEntity);
allContacts.set(entity, contacts);
// Other contacts.
let otherContacts = allContacts.get(otherEntity);
if (!otherContacts) {
otherContacts = I.Set();
}
otherContacts = otherContacts.add(entity);
allContacts.set(otherEntity, otherContacts);
// Mark as checked.
checkSet.add(otherEntity);
}
}
if (!allContacts.get(entity)) {
allContacts.set(entity, I.Set());
}
}
// Report collisions.
entities = this.entities.values();
for (let i = 0; i < entities.length; i++) {
const entity = entities[i];
const oldContacts = entity.body.contacts;
const newContacts = allContacts.get(entity);
const newValues = newContacts.values();
for (let j = 0; j < newValues.length; j++) {
const contact = newValues[j];
if (!oldContacts.has(contact)) {
entity.emit('collisionStart', contact);
}
}
const oldValues = oldContacts.values();
for (let j = 0; j < oldValues.length; j++) {
const contact = oldValues[j];
if (!oldContacts.has(contact)) {
entity.emit('collisionEnd', contact);
}
}
entity.body.contacts = newContacts;
}
// Super rudimentary resolving.
entities = this.entities.values();
for (let i = 0; i < entities.length; i++) {
const {body} = entities[i];
// Contact? Undo impulse.
const {contacts} = body;
if (contacts.size > 0) {
const translation = Vector.add(
Vector.mul(body.impulse, elapsed),
body.force,
);
body.position = Vector.sub(body.position, translation);
// Check all contacts and see if impulse vector can be fixed.
for (let axe = 0; axe < 2; axe++) {
let anyContact = false;
const potentialTranslation = [0, 0];
potentialTranslation[axe] = translation[axe];
body.position = Vector.add(body.position, potentialTranslation);
for (let j = 0; j < contacts.length; j++) {
const contact = contacts[j];
const contactBody = contact.body;
if (Rectangle.intersects(body.aabb, contactBody.aabb)) {
anyContact = true;
break;
}
}
if (anyContact) {
body.position = Vector.sub(body.position, potentialTranslation);
}
}
}
}
// Drop transforms.
entities = this.entities.values();
for (let i = 0; i < entities.length; i++) {
const {body} = entities[i];
body.force = [0, 0];
body.impulse = [0, 0];
}
super.tick(elapsed);
}
}

View File

@ -0,0 +1,8 @@
export {default as BodyView} from './body-view';
export {default as Proton} from './proton';
export {default as CircleShape} from './shape/circle';
export {default as shapeFromJSON} from './shape/from-json';
export {default as ShapeList} from './shape/list';
export {default as PolygonShape} from './shape/polygon';
export {default as RectangleShape} from './shape/rectangle';
export {default as ShapeView} from './shape/view';

View File

@ -0,0 +1,190 @@
import {Vector} from '@avocado/math';
import {
Bodies,
Body as MatterBody,
Vertices,
} from 'matter-js';
import AbstractBody from '../abstract/body';
import ShapeList from '../shape/list';
import CircleShape from '../shape/circle';
import RectangleShape from '../shape/rectangle';
// Keep matter from grasping for decomp.
let g;
if ('undefined' !== typeof window) {
g = window;
}
else if ('undefined' !== typeof global) {
g = global;
}
if (g) {
// eslint-disable-next-line global-require
g.decomp = require('poly-decomp');
}
// Translate "real" coordinates to physics coordinates.
const SCALE = 1;
export default class Body extends AbstractBody {
static collisionCategory(group) {
if (!('filterCategoryBit' in this)) {
this.filterCategoryBit = 0;
}
if (!('filterCategories' in this)) {
this.filterCategories = {};
}
if (!this.filterCategories[group]) {
// eslint-disable-next-line no-bitwise
this.filterCategories[group] = 1 << this.filterCategoryBit;
this.filterCategoryBit += 1;
}
return this.filterCategories[group];
}
static lookupBody(matterBody) {
return this.bodies
? this.bodies.get(matterBody)
: undefined;
}
static associateBody(matterBody, avocadoBody) {
if (!this.bodies) {
this.bodies = new WeakMap();
}
this.bodies.set(matterBody, avocadoBody);
}
constructor(world, shape) {
super(world, shape);
const [body, position, origin] = this.constructor.bodyFromShape(shape);
// Set body first, then origin, then position. Order important.
this.matterBody = body;
this.origin = origin;
this.position = Vector.scale(position, SCALE);
this.constructor.associateBody(this.matterBody, this);
}
get aabb() {
const {bounds} = this.matterBody;
return [
bounds.min.x,
bounds.min.y,
bounds.max.x - bounds.min.x,
bounds.max.y - bounds.min.y,
].map((p) => p * SCALE);
}
applyForce(force) {
// eslint-disable-next-line no-param-reassign
force = Vector.scale(force, 1 / SCALE);
const [x, y] = force;
MatterBody.applyForce(this.matterBody, this.matterBody.position, {x, y});
}
applyImpulse(impulse) {
this.impulse = Vector.add(this.impulse, Vector.scale(impulse, 1 / SCALE));
}
static bodyFromShape(shape) {
const shapePosition = Vector.scale(shape.position, 1 / SCALE);
if (shape instanceof ShapeList) {
const children = [];
for (let i = 0; i < shape.children.length; i++) {
const child = shape.children[i];
const [body, position, origin] = this.bodyFromShape(child);
const [x, y] = Vector.add(position, origin);
MatterBody.setPosition(body, {x, y});
children.push(body);
}
let body = MatterBody.create({parts: children});
const {vertices} = body;
body = Bodies.fromVertices(0, 0, vertices);
MatterBody.setPosition(body, Vertices.centre(vertices));
const {x, y} = body.position;
return [body, shapePosition, [x, y]];
}
if (shape instanceof RectangleShape) {
const [width, height] = Vector.scale(shape.size, 1 / SCALE);
const body = Bodies.rectangle(0, 0, width, height);
return [body, shapePosition, [0, 0]];
}
if (shape instanceof CircleShape) {
const body = Bodies.circle(0, 0, shape.radius / SCALE);
return [body, shapePosition, [0, 0]];
}
const vectors = [];
for (let i = 0; i < shape._translatedVertices.length; i++) {
const vertice = shape._translatedVertices[i];
const [x, y] = Vector.scale(vertice, 1 / SCALE);
vectors.push({x, y});
}
const {x, y} = Vertices.centre(vectors);
const body = Bodies.fromVertices(0, 0, vectors);
return [body, shapePosition, [x, y]];
}
get position() {
const {x, y} = this.matterBody.position;
return Vector.sub(Vector.scale([x, y], SCALE), this.origin);
}
set position(position) {
/* eslint-disable no-param-reassign */
position = Vector.scale(position, 1 / SCALE);
position = Vector.add(position, this.origin);
/* eslint-enable no-param-reassign */
if (Vector.equalsClose(this.position, position)) {
return;
}
const [x, y] = position;
MatterBody.setPosition(this.matterBody, {x, y});
}
setCollision(category, mask, group = 0) {
MatterBody.set(this.matterBody, 'collisionFilter', {
category,
group,
mask,
});
}
setCollisionForEntity(entity) {
if (entity.is('collider')) {
const ctor = this.constructor;
const category = ctor.collisionCategory(entity.collisionGroup);
let mask = 0;
const collidesWithGroups = {entity};
for (let i = 0; i < collidesWithGroups.length; i++) {
const group = collidesWithGroups[i];
// eslint-disable-next-line no-bitwise
mask |= ctor.collisionCategory(group);
}
this.setCollision(category, mask);
if (entity.isSensor) {
MatterBody.set(this.matterBody, 'isSensor', true);
}
}
else {
this.setCollision(0, 0, -1);
}
}
get static() {
return this.matterBody.isStatic;
}
set static(isStatic) {
MatterBody.setStatic(this.matterBody, isStatic);
}
get vertices() {
const vertices = [];
for (let i = 0; i < this.matterBody.vertices.length; i++) {
const {x, y} = this.matterBody.vertices[i];
vertices.push(Vector.scale([x, y], SCALE));
}
return vertices;
}
}

View File

@ -0,0 +1,94 @@
import {
Body as MatterBody,
Engine,
Events,
World as MatterWorld,
} from 'matter-js';
import {Vector} from '@avocado/math';
import Body from './body';
import AbstractWorld from '../abstract/world';
export default class World extends AbstractWorld {
constructor() {
super();
const world = MatterWorld.create({
gravity: {
x: 0,
y: 0,
scale: 0,
},
});
this.engine = Engine.create({
world,
});
this.handleCollisions('collisionStart');
this.handleCollisions('collisionEnd');
this.elapsedRemainder = 0;
}
addBody(body) {
MatterWorld.add(this.engine.world, body.matterBody);
}
createBody(shape) {
return new Body(this, shape);
}
handleCollisions(eventName) {
Events.on(this.engine, eventName, (event) => {
event.pairs.forEach((pair) => {
const {bodyA, bodyB} = pair;
const entityA = this.entities.get(Body.lookupBody(bodyA));
const entityB = this.entities.get(Body.lookupBody(bodyB));
if (
entityA && entityA.is('collider')
&& entityB && entityB.is('collider')
) {
if (entityA.collidesWith(entityB)) {
entityA.emit(eventName, entityB);
}
if (entityB.collidesWith(entityA)) {
entityB.emit(eventName, entityA);
}
}
});
});
}
removeBody(body) {
super.removeBody(body);
MatterWorld.remove(this.engine.world, body.matterBody);
}
tick(elapsed) {
// Update simulation.
// eslint-disable-next-line no-param-reassign
elapsed += this.elapsedRemainder;
const {stepTime} = this;
const stepTimeInMs = stepTime * 1000;
while (elapsed >= stepTime) {
// Apply impulses.
const it = this.entities.entries();
for (let value = it.next(); value.done !== true; value = it.next()) {
const body = value.value[0];
const [x, y] = Vector.scale(body.impulse, stepTime);
MatterBody.translate(body.matterBody, {x, y});
}
Engine.update(this.engine, stepTimeInMs);
// eslint-disable-next-line no-param-reassign
elapsed -= stepTime;
}
this.elapsedRemainder = elapsed;
// Reset impulses.
const it = this.entities.entries();
for (let value = it.next(); value.done !== true; value = it.next()) {
value.value[0].impulse = [0, 0];
}
// Propagate.
super.tick(elapsed);
}
}

View File

@ -0,0 +1 @@
export {default} from './proton';

View File

@ -0,0 +1,9 @@
import Proton_ from 'proton-js';
export default class Proton extends Proton_ {
tick(elapsed) {
this.update(elapsed);
}
}

View File

@ -0,0 +1,41 @@
import {compose, Property} from '@avocado/core';
import Shape from './shape';
const decorate = compose(
Property('radius', {
track: true,
}),
);
export default class CircleShape extends decorate(Shape) {
constructor(shape) {
super(shape);
if (shape.radius) {
this.radius = shape.radius;
}
this.on('radiusChanged', this.onAabbChanged, this);
}
get aabb() {
const [x, y] = this.position;
const halfRadius = this.radius / 2;
return [
x - halfRadius,
y - halfRadius,
x + halfRadius,
y + halfRadius,
];
}
destroy() {
super.destroy();
this.off('radiusChanged', this.onAabbChanged);
}
onAabbChanged() {
this.emit('aabbChanged');
}
}

View File

@ -0,0 +1,17 @@
import PolygonShape from './polygon';
import CircleShape from './circle';
import RectangleShape from './rectangle';
import ShapeList from './list';
export default function shapeFromJSON(json) {
switch (json.type) {
case 'circle':
return new CircleShape(json);
case 'list':
return new ShapeList(json);
default:
return new PolygonShape(json);
case 'rectangle':
return new RectangleShape(json);
}
}

View File

@ -0,0 +1,130 @@
import {Rectangle} from '@avocado/math';
import PolygonShape from './polygon';
import CircleShape from './circle';
import RectangleShape from './rectangle';
import Shape from './shape';
export default class ShapeList extends Shape {
constructor({children} = {}) {
super();
this.on('childrenChanged', this.onChildrenChanged, this);
this.on('originChanged', this.onOriginChanged, this);
this.on('rotationChanged', this.onRotationChanged, this);
this.on('scaleChanged', this.onScaleChanged, this);
const _children = [];
if (children) {
_children.push(...children.map((shape) => {
switch (shape.type) {
case 'circle':
return new CircleShape(shape);
case 'list':
return new ShapeList(shape);
default:
return new PolygonShape(shape);
case 'rectangle':
return new RectangleShape(shape);
}
}));
const oldShapes = this.children;
this.children = _children;
this.emit('childrenChanged', oldShapes, this.children);
}
else {
this.children = [];
}
}
destroy() {
super.destroy();
this.off('childrenChanged', this.onChildrenChanged);
this.off('originChanged', this.onOriginChanged);
this.off('rotationChanged', this.onRotationChanged);
this.off('scaleChanged', this.onScaleChanged);
for (let i = 0; i < this.children.length; i++) {
const shape = this.children[i];
shape.destroy();
}
}
get aabb() {
if (0 === this.children.length) {
return [0, 0, 0, 0];
}
const min = [Infinity, Infinity];
const max = [-Infinity, -Infinity];
for (let i = 0; i < this.children.length; i++) {
const {aabb} = this.children[i];
min[0] = aabb[0] < min[0] ? aabb[0] : min[0];
min[1] = aabb[1] < min[1] ? aabb[1] : min[1];
max[0] = aabb[0] > max[0] ? aabb[0] : max[0];
max[1] = aabb[1] > max[1] ? aabb[1] : max[1];
}
return Rectangle.translated(
[min[0], min[1], max[0] - min[0], max[1] - min[1]],
this.position,
);
}
addChild(shape) {
const oldShapes = [...this.children];
this.children.push(shape);
this.emit('childrenChanged', oldShapes, this.children);
}
intersects(list) {
if (0 === this.children.length) {
return false;
}
if (!Rectangle.intersects(this.aabb, list.aabb)) {
return false;
}
// TODO: Quadtrees?
for (let i = 0; i < this.children.length; i++) {
const lchild = this.children[i];
for (let j = 0; j < this.children.length; j++) {
const rchild = list.children[j];
if (Rectangle.intersects(
Rectangle.translated(lchild.aabb, this.position),
Rectangle.translated(rchild.aabb, list.position),
)) {
return true;
}
}
}
return false;
}
onChildAabbChanged() {
this.emit('aabbChanged');
}
onOriginChanged(oldOrigin) {
this.children.forEach((shape) => {
shape.emit('parentOriginChanged', oldOrigin, this.origin);
});
}
onRotationChanged(oldRotation) {
this.children.forEach((shape) => {
shape.emit('parentRotationChanged', oldRotation, this.rotation);
});
}
onScaleChanged(oldScale) {
this.children.forEach((shape) => {
shape.emit('parentScaleChanged', oldScale, this.scale);
});
}
onChildrenChanged(oldShapes) {
oldShapes.forEach((shape) => {
shape.off('aabbChanged');
});
this.children.forEach((shape) => {
shape.on('aabbChanged', this.onChildAabbChanged, this);
});
}
}

View File

@ -0,0 +1,79 @@
import {Rectangle, Vector, Vertice} from '@avocado/math';
import Shape from './shape';
export default class PolygonShape extends Shape {
constructor(shape) {
super(shape);
this._translatedVertices = [];
this._vertices = [];
this.on([
'parentOriginChanged',
'parentRotationChanged',
'parentScaleChanged',
'originChanged',
'rotationChanged',
'scaleChanged',
'verticesChanged',
], this.onRecalculateVertices, this);
if (shape.vertices) {
this.vertices = shape.vertices;
}
}
destroy() {
super.destroy();
this.off([
'parentOriginChanged',
'parentRotationChanged',
'parentScaleChanged',
'originChanged',
'rotationChanged',
'scaleChanged',
'verticesChanged',
], this.onRecalculateVertices);
}
get aabb() {
if (0 === this._vertices.length) {
return [0, 0, 0, 0];
}
const min = [Infinity, Infinity];
const max = [-Infinity, -Infinity];
for (let i = 0; i < this._translatedVertices.length; i++) {
const vertice = this._translatedVertices[i];
min[0] = vertice[0] < min[0] ? vertice[0] : min[0];
min[1] = vertice[1] < min[1] ? vertice[1] : min[1];
max[0] = vertice[0] > max[0] ? vertice[0] : max[0];
max[1] = vertice[1] > max[1] ? vertice[1] : max[1];
}
return Rectangle.translated(
[min[0], min[1], max[0] - min[0], max[1] - min[1]],
this.position,
);
}
onRecalculateVertices() {
const parentOrigin = this.parent ? this.parent.origin : [0, 0];
const origin = Vector.add(this.origin, parentOrigin);
const parentRotation = this.parent ? this.parent.rotation : 0;
const rotation = this.rotation + parentRotation;
const parentScale = this.parent ? this.parent.scale : 1;
const scale = this.scale * parentScale;
this._translatedVertices = this._vertices.map((vertice) => (
Vertice.translate(vertice, origin, rotation, scale)
));
this.emit('aabbChanged');
}
get vertices() {
return this._vertices;
}
set vertices(vertices) {
this._vertices = [...vertices];
this.emit('verticesChanged');
}
}

View File

@ -0,0 +1,41 @@
import {compose} from '@avocado/core';
import {Vector} from '@avocado/math';
import PolygonShape from './polygon';
const decorate = compose(
Vector.Mixin('size', 'width', 'height', {
default: [0, 0],
track: true,
}),
);
export default class RectangleShape extends decorate(PolygonShape) {
constructor(shape) {
super(shape);
this.on(['positionChanged', 'sizeChanged'], this.onVerticesChanged, this);
if (shape.size) {
this.size = shape.size;
}
}
destroy() {
super.destroy();
this.off(['positionChanged', 'sizeChanged'], this.onVerticesChanged);
}
onVerticesChanged() {
const halfSize = Vector.scale(this.size, 0.5);
const width = this.width - 0.001;
const height = this.height - 0.001;
const position = Vector.add(this.position, Vector.scale(halfSize, -1));
this.vertices = [
position,
Vector.add(position, [width, 0]),
Vector.add(position, [width, height]),
Vector.add(position, [0, height]),
];
}
}

View File

@ -0,0 +1,71 @@
import {Property} from '@avocado/core';
import {Vector} from '@avocado/math';
import {Class, compose, EventEmitter} from '@latus/core';
const decorate = compose(
EventEmitter,
Property('parent'),
Property('rotation', {
default: 0,
track: true,
}),
Property('scale', {
default: 1,
track: true,
}),
Vector.Mixin('origin', 'originX', 'originY', {
default: [0, 0],
track: true,
}),
Vector.Mixin('position', 'x', 'y', {
default: [0, 0],
track: true,
}),
);
export default class Shape extends decorate(Class) {
constructor({
origin,
position,
rotation,
scale,
} = {}) {
super();
this.on([
'originChanged',
'rotationChanged',
'scaleChanged',
], this.onAabbChanged, this);
if (origin) {
this.origin = origin;
}
if (position) {
this.position = position;
}
if (rotation) {
this.rotation = rotation;
}
if (scale) {
this.scale = scale;
}
}
// eslint-disable-next-line class-methods-use-this
get aabb() {
return [0, 0, 0, 0];
}
destroy() {
this.off([
'originChanged',
'rotationChanged',
'scaleChanged',
], this.onAabbChanged);
}
onAabbChanged() {
this.emit('aabbChanged');
}
}

View File

@ -0,0 +1,102 @@
import {
Color,
Container,
Primitives,
Renderable,
} from '@avocado/graphics';
import ShapeList from './list';
import CircleShape from './circle';
import PolygonShape from './polygon';
export default class ShapeView extends Renderable {
constructor(shape) {
super();
this.container = new Container();
this.shape = shape;
if (shape instanceof PolygonShape) {
this.redrawPolygonLines();
shape.on('aabbChanged', this.onPolygonShapeAabbChanged, this);
}
if (shape instanceof CircleShape) {
this.redrawCircle();
shape.on('aabbChanged', this.onCircleShapeAabbChanged, this);
}
if (shape instanceof ShapeList) {
for (let i = 0; i < shape.children.length; i++) {
const child = shape.children[i];
const childShapeView = new ShapeView(child);
this.container.addChild(childShapeView);
}
}
this.container.position = shape.position;
shape.on('positionChanged', this.onShapePositionChanged, this);
}
destroy() {
super.destroy();
if (this.shape instanceof PolygonShape) {
this.shape.off('aabbChanged', this.onPolygonShapeAabbChanged);
}
if (this.shape instanceof CircleShape) {
this.shape.off('aabbChanged', this.onCircleShapeAabbChanged);
}
this.shape.off('aabbChanged', this.onShapePositionChanged);
}
get internal() {
return this.container.internal;
}
onPolygonShapeAabbChanged() {
this.redrawPolygonLines();
}
onCircleShapeAabbChanged() {
this.redrawCircle();
}
onShapePositionChanged() {
this.container.position = this.shape.position;
}
redrawCircle() {
const primitives = new Primitives();
primitives.drawCircle(
this.shape.position,
this.shape.radius,
Primitives.lineStyle(new Color(255, 0, 255), 1),
);
this.container.removeAllChildren();
this.container.addChild(primitives);
}
redrawPolygonLines() {
const primitives = new Primitives();
let firstVertice;
let lastVertice;
for (let i = 0; i < this.shape._translatedVertices.length; i++) {
const vertice = this.shape._translatedVertices[i];
if (!firstVertice) {
firstVertice = vertice;
}
if (lastVertice) {
primitives.drawLine(
lastVertice,
vertice,
Primitives.lineStyle(new Color(255, 0, 255), 1),
);
}
lastVertice = vertice;
}
primitives.drawLine(
lastVertice,
firstVertice,
Primitives.lineStyle(new Color(255, 0, 255), 1),
);
this.container.removeAllChildren();
this.container.addChild(primitives);
}
}

View File

@ -0,0 +1,313 @@
import {Actions, compile, Context} from '@avocado/behavior';
import {StateProperty, Trait} from '@avocado/entity';
import {Rectangle, Vector} from '@avocado/math';
import {compose} from '@latus/core';
const decorate = compose(
StateProperty('isCheckingCollisions'),
StateProperty('isColliding'),
);
export default class Collider extends decorate(Trait) {
static behaviorTypes() {
return {
collidesWith: {
advanced: true,
type: 'bool',
label: 'I would collide with $1.',
args: [
['other', {
type: 'entity',
}],
],
},
doesNotCollideWith: {
advanced: true,
type: 'bool',
label: 'I would not collide with $1.',
args: [
['other', {
type: 'entity',
}],
],
},
setDoesCollideWith: {
advanced: true,
type: 'void',
label: 'Set $1 as colliding with myself.',
args: [
['other', {
type: 'entity',
}],
],
},
setDoesNotCollideWith: {
advanced: true,
type: 'void',
label: 'Set $1 as not colliding with myself.',
args: [
['other', {
type: 'entity',
}],
],
},
};
}
static defaultParams() {
return {
activeCollision: false,
collidesWithGroups: [
'default',
],
collisionEndActions: {
type: 'expressions',
expressions: [],
},
collisionStartActions: {
type: 'expressions',
expressions: [],
},
collisionGroup: 'default',
isSensor: false,
};
}
static defaultState() {
return {
isCheckingCollisions: true,
isColliding: true,
};
}
static describeParams() {
return {
activeCollision: {
type: 'bool',
label: 'Actively check collisions',
},
collidesWithGroups: {
type: 'object',
label: 'Collides with groups',
},
collisionEndActions: {
type: 'expressions',
label: 'Collision ending actions',
},
collisionStartActions: {
type: 'expressions',
label: 'Collision starting actions',
},
collisionGroup: {
type: 'string',
label: 'Collision group',
},
isSensor: {
type: 'bool',
label: 'Is sensor',
},
};
}
static describeState() {
return {
isCheckingCollisions: {
type: 'bool',
label: 'Is checking collisions',
},
isColliding: {
type: 'bool',
label: 'Is able to collide',
},
};
}
static type() {
return 'collider';
}
constructor(entity, params, state) {
super(entity, params, state);
const {
collidesWithGroups,
collisionEndActions,
collisionGroup,
collisionStartActions,
isSensor,
} = this.params;
this._collidesWithGroups = collidesWithGroups;
this._collisionEndActions = collisionEndActions.length > 0
? new Actions(compile(collisionEndActions))
: undefined;
this._collisionStartActions = collisionStartActions.length > 0
? new Actions(compile(collisionStartActions))
: undefined;
this._collisionGroup = collisionGroup;
this._doesNotCollideWith = [];
this._isCollidingWith = [];
this._isSensor = isSensor;
}
destroy() {
this.releaseAllCollisions();
}
checkActiveCollision() {
if (!this.params.activeCollision) {
return;
}
const {layer} = this.entity;
if (!layer) {
return;
}
const query = Rectangle.compose(
Vector.sub(this.entity.position, [32, 32]),
[64, 64],
);
const thisAabb = Rectangle.translated(
this.entity.shape.aabb,
this.entity.position,
);
const entities = layer.visibleEntities(query);
for (let i = 0; i < entities.length; ++i) {
const entity = entities[i];
if (
entity === this.entity
|| !entity.is('collider')
|| !entity.is('shaped')
|| entity.is('physical')
) {
// eslint-disable-next-line no-continue
continue;
}
const otherAabb = Rectangle.translated(
entity.shape.aabb,
entity.position,
);
if (Rectangle.intersects(thisAabb, otherAabb)) {
if (!this.isCollidingWithEntity(entity)) {
this.entity.emit('collisionStart', entity);
entity.emit('collisionStart', this.entity);
}
}
else if (this.isCollidingWithEntity(entity)) {
this.entity.emit('collisionEnd', entity);
entity.emit('collisionEnd', this.entity);
}
}
}
get collisionGroup() {
return this._collisionGroup;
}
get collidesWithGroups() {
return this._collidesWithGroups;
}
get isCollidingWith() {
return this._isCollidingWith;
}
isCollidingWithEntity(entity) {
return -1 !== this._isCollidingWith.indexOf(entity);
}
get isSensor() {
return this._isSensor;
}
pushCollisionTickingPromise(actions, other) {
const context = new Context({
entity: [this.entity, 'entity'],
other: [other, 'entity'],
});
this.entity.addTickingPromise(actions.tickingPromise(context));
}
releaseAllCollisions() {
for (let i = 0; i < this._isCollidingWith.length; i++) {
const entity = this._isCollidingWith[i];
entity.emit('collisionEnd', this.entity);
}
this._isCollidingWith = [];
}
// eslint-disable-next-line class-methods-use-this
hooks() {
return {
contextTypeHints: () => [['other', 'entity']],
};
}
listeners() {
return {
collisionEnd: (other) => {
const index = this._isCollidingWith.indexOf(other);
if (-1 !== index) {
this._isCollidingWith.splice(index, 1);
if (this._collisionEndActions) {
this.pushCollisionTickingPromise(this._collisionEndActions, other);
}
}
},
collisionStart: (other) => {
const index = this._isCollidingWith.indexOf(other);
if (-1 === index) {
this._isCollidingWith.push(other);
if (this._collisionStartActions) {
this.pushCollisionTickingPromise(this._collisionStartActions, other);
}
}
},
removedFromRoom: () => {
this.releaseAllCollisions();
},
};
}
methods() {
return {
collidesWith: (entity) => {
if (!this.entity.isColliding || !entity.isColliding) {
return false;
}
if (-1 !== this._doesNotCollideWith.indexOf(entity)) {
return false;
}
const {collisionGroup} = entity;
return -1 !== this._collidesWithGroups.indexOf(collisionGroup);
},
doesNotCollideWith: (entity) => !this.entity.collidesWith(entity),
setDoesCollideWith: (entity) => {
const index = this._doesNotCollideWith.indexOf(entity);
if (-1 !== index) {
this._doesNotCollideWith.splice(index, 1);
}
},
setDoesNotCollideWith: (entity) => {
if (-1 === this._doesNotCollideWith.indexOf(entity)) {
this._doesNotCollideWith.push(entity);
}
},
};
}
tick() {
if (AVOCADO_SERVER) {
this.checkActiveCollision();
}
}
}

View File

@ -0,0 +1,154 @@
import {Range, Vector} from '@avocado/math';
import {Trait} from '@avocado/traits';
import {compose} from '@latus/core';
const decorate = compose(
);
export default class Emitted extends decorate(Trait) {
static behaviorTypes() {
return {
particle: {
type: 'particle',
label: 'Create particle.',
},
};
}
static defaultParams() {
return {
alpha: {
start: 1,
end: 1,
},
force: [0, 0],
listed: true,
mass: 1,
position: null,
rotation: {
start: 0,
add: 0,
},
scale: {
start: 1,
end: 1,
},
transient: true,
ttl: 2,
velocity: {
angle: 0,
magnitude: 0,
},
};
}
static describeParams() {
return {
alpha: {
type: 'object',
label: 'Alpha',
},
force: {
type: 'vector',
label: 'Force',
},
listed: {
type: 'bool',
label: 'Is listed',
},
mass: {
type: 'number',
label: 'Mass',
},
position: {
type: 'vector',
label: 'Position',
},
rotation: {
type: 'object',
label: 'Rotation',
},
scale: {
type: 'object',
label: 'Scale',
},
transient: {
type: 'bool',
label: 'Kill entity after particle finishes',
},
ttl: {
type: 'number',
label: 'Time to live in seconds',
},
velocity: {
type: 'object',
label: 'Velocity',
},
};
}
static type() {
return 'emitted';
}
constructor(entity, params, state) {
super(entity, params, state);
this.alphaStart = new Range(this.params.alpha.start);
this.alphaEnd = new Range(this.params.alpha.end);
this.force = new Vector.Range(this.params.force);
this.mass = this.params.mass;
if (null !== this.params.position) {
this.position = new Vector.Range(this.params.position);
}
else {
this.position = null;
}
this.rotationStart = new Range(this.params.rotation.start);
this.rotationAdd = new Range(this.params.rotation.add);
this.scaleStart = new Range(this.params.scale.start);
this.scaleEnd = new Range(this.params.scale.end);
this.ttl = this.params.ttl;
this.velocityAngle = new Range(this.params.velocity.angle);
this.velocityMagnitude = new Range(this.params.velocity.magnitude);
}
get isTransientParticle() {
return !!this.params.transient;
}
methods() {
return {
particle: () => {
const position = null === this.position ? null : this.position.value();
const force = this.force.value();
return {
alpha: {
start: this.alphaStart.value(),
end: this.alphaEnd.value(),
},
force,
listed: this.params.listed,
mass: this.mass,
position,
rotation: {
start: this.rotationStart.value(),
add: this.rotationAdd.value(),
},
scale: {
start: this.scaleStart.value(),
end: this.scaleEnd.value(),
},
ttl: this.ttl,
velocity: {
angle: this.velocityAngle.value(),
magnitude: this.velocityMagnitude.value(),
},
};
},
};
}
}

View File

@ -0,0 +1,272 @@
import {PI_180} from '@avocado/math';
import {synchronized} from '@avocado/s13n';
import {Ticker} from '@avocado/timing';
import {Trait} from '@avocado/traits';
import {compose} from '@latus/core';
import merge from 'deepmerge';
import K from 'kefir';
import Proton from '../proton';
const decorate = compose(
);
export default (latus) => class Emitter extends decorate(Trait) {
static behaviorTypes() {
return {
emitParticleEntity: {
cycle: true,
type: 'entity',
label: 'Create particle.',
args: [
['entity', {
type: 'entity',
}],
],
},
emitParticleJson: {
type: 'stream',
label: 'Create particle.',
args: [
['json', {
type: 'object',
}],
],
},
emitParticle: {
type: 'stream',
label: 'Create particle.',
args: [
['key', {
type: 'string',
options: (entity) => (
Object.keys(entity.traitInstance('emitter').particles)
.reduce((r, key) => ({...r, [key]: key}), {})
),
}],
['json', {
type: 'object',
}],
],
},
};
}
static defaultParams() {
return {
particles: {},
};
}
static describeParams() {
return {
particles: {
type: 'object',
label: 'Particles',
},
};
}
static type() {
return 'emitter';
}
constructor(entity, params, state) {
super(entity, params, state);
this.emissions = [];
this.emitter = new Proton.Emitter();
this.particles = {};
this.proton = new Proton();
this.proton.addEmitter(this.emitter);
this.onParticleDead = this.onParticleDead.bind(this);
this.onParticleUpdate = this.onParticleUpdate.bind(this);
this.emitter.bindEvent = true;
this.emitter.addEventListener('PARTICLE_DEAD', this.onParticleDead);
this.emitter.addEventListener('PARTICLE_UPDATE', this.onParticleUpdate);
}
gatherParticles() {
const particles = {};
const hookParticles = this.entity.invokeHookFlat('particles');
for (let i = 0; i < hookParticles.length; i++) {
const traitParticles = Object.entries(hookParticles[i]);
for (let j = 0; j < traitParticles.length; j++) {
const [key, particle] = traitParticles[j];
particles[key] = particle;
}
}
const paramParticles = Object.entries(this.params.particles);
for (let i = 0; i < paramParticles.length; i++) {
const [key, particle] = paramParticles[i];
particles[key] = merge(particles[key] || {}, particle);
}
this.particles = particles;
}
// eslint-disable-next-line class-methods-use-this
onParticleDead(particle) {
if (particle.body.isTransientParticle) {
particle.body.destroy();
}
}
// eslint-disable-next-line class-methods-use-this
onParticleUpdate(particle) {
particle.body.setPosition([particle.p.x, particle.p.y]);
/* eslint-disable no-param-reassign */
particle.body.opacity = particle.alpha;
particle.body.visibleScale = [particle.scale, particle.scale];
particle.body.rotation = particle.rotation * PI_180;
/* eslint-enable no-param-reassign */
}
hooks() {
const hooks = {};
hooks.afterDestructionTickers = () => (elapsed) => {
this.tick(elapsed);
if (0 === this.emitter.particles.length) {
this.emitter.destroy();
return true;
}
return false;
};
return hooks;
}
emitParticleJson(json, emitter) {
const {fromName: {Entity}} = synchronized(latus);
Entity.loadOrInstance(json).then((particle) => {
this.entity.emitParticleEntity(particle);
emitter.emit(particle);
});
}
listeners() {
return {
traitAdded: () => {
this.gatherParticles();
},
};
}
methods() {
return {
emitParticleEntity: (entity) => {
const particle = entity.particle();
const position = particle.position
? particle.position
: this.entity.position;
const initializers = [
new Proton.Body(entity),
new Proton.Position(new Proton.PointZone(
position[0],
position[1],
)),
new Proton.Mass(particle.mass),
new Proton.Life(particle.ttl),
new Proton.Velocity(
particle.velocity.magnitude,
particle.velocity.angle,
'polar',
),
];
const behaviors = [
new Proton.Alpha(
particle.alpha.start,
particle.alpha.end,
),
new Proton.Force(
particle.force[0],
particle.force[1],
),
new Proton.Rotate(
particle.rotation.start,
particle.rotation.add,
'add',
),
new Proton.Scale(
particle.scale.start,
particle.scale.end,
),
];
const protonParticle = this.emitter.createParticle(
initializers,
behaviors,
);
entity.on('destroy', () => {
this.emitter.removeParticle(protonParticle);
});
if (particle.listed) {
this.entity.list.addEntity(entity);
}
// Prime.
this.onParticleUpdate(protonParticle);
return entity;
},
emitParticleJson: (json) => {
let {
count = 1,
// eslint-disable-next-line prefer-const
rate = 0,
} = json;
const stream = K.stream((emitter) => {
if (0 === rate) {
for (let i = 0; i < count; ++i) {
this.emitParticleJson(json, emitter);
}
}
else {
const ticker = new Ticker(rate);
this.emitParticleJson(json, emitter);
count -= 1;
if (count > 0) {
const removeEmission = () => {
const index = this.emissions.indexOf(ticker);
if (-1 !== index) {
this.emissions.splice(index, 1);
}
emitter.end();
};
this.entity.on('destroy', removeEmission);
ticker.on('tick', () => {
this.emitParticleJson(json, emitter);
if (0 >= --count) {
removeEmission();
}
});
this.emissions.push(ticker);
return;
}
}
emitter.end();
});
// Always make sure something listens...
stream.onEnd(() => {});
return stream;
},
emitParticle: (key, json = {}) => {
const particleJson = this.particles[key];
if (!particleJson) {
return undefined;
}
const mergedJson = merge({}, particleJson, json);
return this.entity.emitParticleJson(mergedJson);
},
};
}
tick(elapsed) {
this.emitter.update(elapsed);
for (let i = 0; i < this.emissions.length; i++) {
this.emissions[i].tick(elapsed);
}
}
};

View File

@ -0,0 +1,169 @@
import {StateProperty} from '@avocado/entity';
import {Vector} from '@avocado/math';
import {Trait} from '@avocado/traits';
import {compose} from '@latus/core';
import {BodyView} from '../body-view';
const decorate = compose(
StateProperty('addedToPhysics', {
track: true,
}),
);
export default class Physical extends decorate(Trait) {
static behaviorTypes() {
return {
applyForce: {
type: 'void',
label: 'Apply force.',
args: [
['force', {
type: 'vector',
}],
],
},
applyImpulse: {
type: 'void',
label: 'Apply impulse.',
args: [
['impulse', {
type: 'vector',
}],
],
},
};
}
static defaultState() {
return {
addedToPhysics: true,
};
}
static describeState() {
return {
addedToPhysics: {
type: 'bool',
label: 'Added to physics',
},
};
}
static type() {
return 'physical';
}
constructor(entity, params, state) {
super(entity, params, state);
this._body = undefined;
this.bodyView = undefined;
this._world = undefined;
}
destroy() {
this.world = undefined;
}
addToWorld() {
const world = this._world;
if (world) {
const body = world.createBody(this.entity.shape);
world.associateBodyWithEntity(body, this.entity);
body.setCollisionForEntity(this.entity);
world.addBody(body);
this._body = body;
if (AVOCADO_CLIENT) {
if (this.entity.is('visible') && this.entity.is('debuggable')) {
this.bodyView = new BodyView(body);
this.bodyView.position = Vector.scale(this.entity.position, -1);
this.bodyView.visible = this.entity.isDebugging;
this.bodyView.zIndex = 101;
this.entity.container.addChild(this.bodyView);
}
}
}
}
get body() {
return this._body;
}
removeFromWorld() {
if (this._world && this._body) {
this._world.removeBody(this._body);
}
this._body = undefined;
if (this.bodyView) {
if (this.entity.is('visible')) {
this.entity.container.removeChild(this.bodyView);
}
this.bodyView.destroy();
}
this.bodyView = undefined;
}
set world(world) {
this.removeFromWorld();
this._world = world;
this.addToWorld();
}
listeners() {
return {
addedToRoom: () => {
this.entity.world = this.entity.room.world;
},
addedToPhysicsChanged: () => {
if (this.entity.addedToPhysics) {
if (!this._body) {
this.addToWorld();
}
}
else if (this._body) {
this.removeFromWorld();
}
},
isDyingChanged: (_, isDying) => {
this.entity.addedToPhysics = !isDying;
},
positionChanged: () => {
if (this._body) {
const {position} = this.entity;
this._body.position = position;
}
},
removedFromRoom: () => {
if (this._body) {
this.removeFromWorld();
}
},
};
}
methods() {
return {
applyForce: (force) => {
if (this._world && this._body) {
this._body.applyForce(force);
}
},
applyImpulse: (impulse) => {
if (this._world && this._body) {
this._body.applyImpulse(impulse);
}
},
};
}
}

View File

@ -0,0 +1,68 @@
import {compose} from '@avocado/core';
import {Trait} from '@avocado/entity';
import shapeFromJSON from '../shape/from-json';
import ShapeView from '../shape/view';
const decorate = compose(
);
export default class Shaped extends decorate(Trait) {
static defaultParams() {
return {
shape: undefined,
};
}
static describeParams() {
return {
shape: {
type: 'object',
label: 'Shape',
},
};
}
static type() {
return 'shaped';
}
constructor(entity, params, state) {
super(entity, params, state);
this._shape = shapeFromJSON(this.params.shape);
this.shapeView = undefined;
}
destroy() {
this._shape.destroy();
if (this.shapeView) {
this.shapeView.destroy();
this.shapeView = undefined;
}
}
get shape() {
return this._shape;
}
listeners() {
return {
traitAdded: () => {
if (AVOCADO_CLIENT) {
if (this.entity.is('visible') && this.entity.is('debuggable')) {
if (!this.shapeView) {
this.shapeView = new ShapeView(this.entity.shape);
this.shapeView.visible = this.entity.isDebugging;
this.shapeView.zIndex = 100;
this.entity.container.addChild(this.shapeView);
}
}
}
},
};
}
}

View File

@ -0,0 +1,3 @@
const neutrino = require('neutrino');
module.exports = neutrino(require(`${__dirname}/.neutrinorc`)).webpack();

7788
packages/physics/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@ -20,8 +20,8 @@
"index.js.map"
],
"dependencies": {
"@avocado/core": "^2.0.0",
"@latus/core": "^2.0.0",
"@avocado/core": "2.0.0",
"@latus/core": "2.0.0",
"debug": "4.3.1",
"deepmerge": "^4.2.2",
"uuid": "^8.3.2"

View File

@ -1 +1,2 @@
export {default} from './resource';
export {default as Resource} from './resource';
export {default as JsonResource} from './json-resource';

View File

@ -0,0 +1,57 @@
import merge from 'deepmerge';
import Resource from './resource';
const {
SIDE,
} = process.env;
export default class JsonResource extends Resource {
static async extendJson(json) {
if (json.extends) {
// eslint-disable-next-line no-param-reassign
json.extends = await this.read(json.extends);
}
return this.mergeJson(json);
}
static async load(json) {
const {extends: uri} = json;
const resource = new this(await this.extendJson(json));
resource.uri = uri;
return resource;
}
static mergeJson(json) {
let result = JSON.parse(JSON.stringify(json));
if (result.extends) {
const {extends: xtends, ...rest} = result;
result = merge(
this.mergeJson(xtends),
rest,
{
arrayMerge: (l, r) => r,
},
);
}
return result;
}
static async read(uri) {
const buffer = await super.read(uri);
let string;
if ('client' === SIDE) {
const decoder = new TextDecoder();
string = decoder.decode(buffer);
}
else {
// eslint-disable-next-line global-require
const {StringDecoder} = require('string_decoder');
const decoder = new StringDecoder();
string = decoder.end(buffer);
}
return this.extendJson(JSON.parse(string));
}
}

View File

@ -1,4 +1,3 @@
import merge from 'deepmerge';
import {v4 as uuid} from 'uuid';
import {Property} from '@avocado/core';
@ -20,59 +19,31 @@ export default class Resource extends decorate(Class) {
this.instanceUuid = uuid();
}
static baseUri = 'resource';
fromJSON({uri}) {
if (uri) {
this.uri = uri;
}
return this;
}
static load(uri) {
return this.read(uri).then((json) => new this({uri, ...json}));
}
static async loadOrInstance(json) {
if (json.uri) {
const loaded = await this.read(json.uri);
return new this(loaded, json);
}
return new this(json);
static async load(uri) {
const buffer = await this.read(uri);
const resource = new this(buffer);
resource.uri = uri;
return resource;
}
static async read(uri) {
if (!this.readCache) {
this.readCache = {};
}
if (this.readCache[uri]) {
return JSON.parse(JSON.stringify(await this.readCache[uri]));
}
if ('client' === SIDE) {
const response = await fetch(uri);
this.readCache[uri] = response.json();
return response.arrayBuffer();
}
else {
this.readCache[uri] = new Promise((resolve, reject) => {
return new Promise((resolve, reject) => {
// eslint-disable-next-line global-require
const [fs, path] = [require('fs'), require('path')];
fs.readFile(path.join(process.cwd(), this.baseUri, uri), (error, buffer) => {
fs.readFile(path.join(process.cwd(), this.root, uri), (error, buffer) => {
if (error) {
reject(error);
return;
}
resolve(JSON.parse(buffer.toString('utf8')));
resolve(buffer);
});
});
}
const json = await this.readCache[uri];
return json.extends ? merge(await this.read(json.extends), json) : json;
}
toJSON() {
return {
uri: this.uri,
};
}
static root = 'resource';
}

View File

@ -2,10 +2,10 @@
# yarn lockfile v1
"@avocado/core@^2.0.0":
"@avocado/core@2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@avocado%2fcore/-/core-2.0.0.tgz#636ea3c3b54a38538c59485080f6a0e48f1798e7"
integrity sha512-VW+ygRHaQQwaL5rKZGm0n0DNfvj+H89qQx+67veCUmUuRav3XAeE0iYs8Lgfc3CJLPz/alqt/dVPMXd5QDR+Mg==
resolved "https://npm.i12e.cha0s.io/@avocado%2fcore/-/core-2.0.0.tgz#ac7f912135c1cbb433b825c0fd1aa9a14b91ffed"
integrity sha512-PX6UVuhcmUaf2yzhTEd+dUle/Z3JRWJXm7NwGN63oL3w5QqUVOEzqUQNkKem2b+mlyJl56UnWzZJYYLixTOzvQ==
dependencies:
debug "4.3.1"
@ -899,7 +899,7 @@
minimatch "^3.0.4"
strip-json-comments "^3.1.1"
"@latus/core@^2.0.0":
"@latus/core@2.0.0":
version "2.0.0"
resolved "https://npm.i12e.cha0s.io/@latus%2fcore/-/core-2.0.0.tgz#4447b4bba265b684035be1dacefd6ba4913a47d4"
integrity sha512-OSsbO4wvVJFPZTMRDX5LAXOA+MQY8FOSK7PcTEJKeiRqOMeMIVkZc6q6KNlUIYivE+87rlM7S/CctHoA7uvQvg==

View File

@ -20,8 +20,8 @@
"index.js.map"
],
"dependencies": {
"@latus/core": "^2.0.0",
"@latus/socket": "^2.0.0",
"@latus/core": "2.0.0",
"@latus/socket": "2.0.0",
"debug": "4.3.1",
"msgpack-lite": "^0.1.26"
},

View File

@ -1,5 +1,6 @@
import {gather} from '@latus/core';
export {default as normalize} from './normalize';
export * from './packets';
export {default as Synchronized} from './synchronized';

View File

@ -0,0 +1,23 @@
import {normalize, Packet} from '@latus/socket';
export default (latus, packets) => {
if (!packets) {
return [];
}
// Packet
if (!Array.isArray(packets)) {
// eslint-disable-next-line no-param-reassign
packets = [packets];
}
if (
// [Packet, ...]
!(packets[0] instanceof Packet)
// [name, data]
&& !Array.isArray(packets[0])
) {
// [[name, data...], ...]
// eslint-disable-next-line no-param-reassign
packets = [packets];
}
return packets.map((packet) => normalize(latus, packet));
};

View File

@ -1,5 +1,4 @@
import {normalize, Packet} from '@latus/socket';
import normalize from './normalize';
import SynchronizedCreatePacket from './packets/synchronized-create';
import SynchronizedDestroyPacket from './packets/synchronized-destroy';
@ -58,36 +57,19 @@ export default function SynchronizedMixin(Superclass) {
if (this._idempotentPackets.length > 0) {
return this._idempotentPackets;
}
let packets = this.packets(informed);
if (!packets) {
return [];
}
// Packet
if (!Array.isArray(packets)) {
packets = [packets];
}
if (
// [Packet, ...]
!(packets[0] instanceof Packet)
// [name, data]
&& !Array.isArray(packets[0])
) {
// [[name, data...], ...]
packets = [packets];
}
const normalized = packets.map((packet) => normalize(latus, packet));
const packets = normalize(latus, this.packets(informed));
// Embed synchronization info.
const id = this.synchronizationId();
for (let i = 0; i < normalized.length; i++) {
normalized[i].data.synchronized = {
for (let i = 0; i < packets.length; i++) {
packets[i].data.synchronized = {
id,
type: this.constructor.s13nType,
};
}
if (this.packetsAreIdempotent()) {
this._idempotentPackets = normalized;
this._idempotentPackets = packets;
}
return normalized;
return packets;
}
// eslint-disable-next-line class-methods-use-this

View File

@ -0,0 +1 @@
module.exports = require('../../config/.eslintrc');

5
packages/sound/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
**/*.js
**/*.map
!/.*
!/webpack.config.js
!src/**/*.js

View File

@ -0,0 +1 @@
module.exports = require('../../config/.neutrinorc');

View File

@ -0,0 +1,42 @@
{
"name": "@avocado/package",
"version": "1.0.0",
"main": "index.js",
"author": "cha0s",
"license": "MIT",
"scripts": {
"build": "NODE_PATH=./node_modules webpack --mode production",
"clean": "rm -rf yarn.lock node_modules && yarn",
"dev": "NODE_PATH=./node_modules webpack --mode development",
"forcepub": "npm unpublish --force $(node -e 'const {name, version} = require(`./package.json`); process.stdout.write(`${name}@${version}`)') && npm publish",
"link": "node -e \"Object.keys(require('./package.json').dependencies).filter((m) => 0 === m.indexOf('@latus/')).forEach((m) => require('child_process').spawn('yarn', ['link', m]));\"",
"lint": "NODE_PATH=./node_modules eslint --format codeframe --ext mjs,js .",
"test": "NODE_PATH=./node_modules mocha --config ../../config/.mocharc.js",
"unlink": "node -e \"Object.keys(require('./package.json').dependencies).filter((m) => 0 === m.indexOf('@latus/')).forEach((m) => require('child_process').spawn('yarn', ['unlink', m]));\" && yarn install --force",
"watch": "NODE_PATH=./node_modules webpack --watch --mode development"
},
"files": [
"index.js",
"index.js.map"
],
"dependencies": {
"@avocado/resource": "^2.0.0",
"@avocado/traits": "^2.0.0",
"debug": "4.3.1",
"howler": "2.1.2"
},
"devDependencies": {
"@neutrinojs/airbnb-base": "^9.4.0",
"@neutrinojs/copy": "9.4.0",
"@neutrinojs/mocha": "^9.4.0",
"@neutrinojs/react": "^9.4.0",
"chai": "4.2.0",
"eslint": "^7",
"eslint-import-resolver-webpack": "0.13.0",
"mocha": "^8",
"neutrino": "^9.4.0",
"webpack": "^4",
"webpack-cli": "^3",
"webpack-node-externals": "2.5.2"
}
}

View File

@ -0,0 +1 @@
export {default} from './sound';

View File

@ -0,0 +1,48 @@
import {Howl} from 'howler';
import {JsonResource} from '@avocado/resource';
export default class Sound extends JsonResource {
constructor({interval = 0, volume = 1, sound} = {}) {
super();
this.handle = undefined;
this.interval = interval;
this.originalVolume = volume;
this.sound = sound;
this.timestamp = 0;
}
destroy() {
if (this.sound) {
this.sound.unload();
}
}
static async extendJson(json) {
const extended = await super.extendJson(json);
extended.sound = new Howl(json);
await new Promise((resolve) => {
extended.sound.once('load', resolve);
});
return extended;
}
play() {
if (this.interval > 0 && this.timestamp > 0) {
if ((Date.now() - this.timestamp) < this.interval) {
const volume = this.sound.volume(this.handle);
this.sound.volume(
Math.min(1, Math.min(volume, this.originalVolume * 20)),
this.handle,
);
return;
}
}
this.handle = this.sound.play();
if (this.interval > 0) {
this.timestamp = Date.now();
}
}
}

View File

@ -0,0 +1,108 @@
import {Trait} from '@avocado/traits';
import Sound from '../sound';
export default class Audible extends Trait {
static behaviorTypes() {
return {
hasSound: {
type: 'bool',
label: 'Has $1 sound',
args: [
['key', {
type: 'string',
}],
],
},
playSound: {
type: 'void',
label: 'Play the $1 sound.',
args: [
['key', {
type: 'string',
options: (entity) => this.optionsForSounds(entity),
}],
],
},
};
}
static defaultParams() {
return {
sounds: {},
};
}
static describeParams() {
return {
sounds: {
type: 'object',
label: 'Sounds',
},
};
}
static type() {
return 'audible';
}
hydrate() {
if (AVOCADO_CLIENT) {
this.loadSounds();
}
}
constructor(entity, params, state) {
super(entity, params, state);
this._sounds = this.params.sounds;
this.sounds = {};
}
destroy() {
const sounds = Object.values(this.sounds);
for (let i = 0; i < sounds.length; i++) {
sounds[i].destroy();
}
}
loadSounds() {
const keys = Object.keys(this._sounds);
const soundPromises = [];
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const soundJSON = this._sounds[key];
soundPromises.push(Sound.load(soundJSON.uri));
}
const soundsPromise = Promise.all(soundPromises);
soundsPromise.then((sounds) => {
for (let i = 0; i < sounds.length; i++) {
const key = keys[i];
const sound = sounds[i];
this.sounds[key] = sound;
}
});
}
methods() {
return {
hasSound: (key) => !!this.sounds[key],
playSound: (key) => {
const sound = this.sounds[key];
if (!sound) {
return;
}
sound.play();
},
};
}
static optionsForSounds(entity) {
return Object.keys(entity.traitInstance('audible').params.sounds)
.reduce((r, key) => ({...r, [key]: key}), {});
}
}

View File

@ -0,0 +1,3 @@
const neutrino = require('neutrino');
module.exports = neutrino(require(`${__dirname}/.neutrinorc`)).webpack();

7522
packages/sound/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@ -20,13 +20,13 @@
"index.js.map"
],
"dependencies": {
"@avocado/core": "^2.0.0",
"@avocado/entity": "^2.0.0",
"@avocado/graphics": "^2.0.0",
"@avocado/math": "^2.0.0",
"@avocado/resource": "^2.0.0",
"@latus/core": "^2.0.0",
"@latus/socket": "^2.0.0",
"@avocado/core": "2.0.0",
"@avocado/graphics": "2.0.0",
"@avocado/math": "2.0.0",
"@avocado/resource": "2.0.0",
"@avocado/traits": "^2.0.0",
"@latus/core": "2.0.0",
"@latus/socket": "2.0.0",
"debug": "4.3.1"
},
"devDependencies": {

View File

@ -1,6 +1,7 @@
import {compose, EventEmitter, Property} from '@avocado/core';
import {Property} from '@avocado/core';
import {Rectangle, Vector} from '@avocado/math';
import {Resource} from '@avocado/resource';
import {compose, EventEmitter} from '@latus/core';
import TimedIndex from './timed-index';

Some files were not shown because too many files have changed in this diff Show More