1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2026-02-18 22:09:20 +00:00

Fixed momentary movement

This commit is contained in:
isaisstillalive 2020-06-30 16:11:34 +09:00
parent a7cb235f2f
commit 6f99d49435
2 changed files with 123 additions and 42 deletions

View File

@ -4,6 +4,8 @@ import { Component } from "../component";
import { BaseItem } from "../base_item";
import { gItemRegistry } from "../../core/global_registries";
const receivedSize = 3;
export class ChainableSplitterComponent extends Component {
static getId() {
return "ChainableSplitter";
@ -13,7 +15,13 @@ export class ChainableSplitterComponent extends Component {
return {
chainable: types.bool,
inputItem: types.nullable(types.obj(gItemRegistry)),
ejected: types.bool,
receivedItems: types.array(
types.structured({
item: types.obj(gItemRegistry),
distance: types.float,
})
),
received: types.bool,
};
}
@ -26,9 +34,17 @@ export class ChainableSplitterComponent extends Component {
constructor({ chainable = false }) {
super();
/** @type {boolean} */
this.chainable = chainable;
/** @type {BaseItem} */
this.inputItem = null;
this.ejected = false;
/** @type {Array<{ item: BaseItem, distance: number }>} */
this.receivedItems = [];
/** @type {boolean} */
this.received = false;
}
/**
@ -43,4 +59,27 @@ export class ChainableSplitterComponent extends Component {
this.inputItem = item;
return true;
}
/**
*
* @param {BaseItem} item
* @param {number} distance
*/
tryReceiveItem(item, distance) {
if (this.received || this.receivedItems.length > receivedSize) {
return false;
}
this.received = true;
this.receivedItems.push({
item: item,
distance: distance,
});
this.receivedItems.sort((a, b) => a.distance - b.distance);
return true;
}
resetReceived() {
this.received = false;
}
}

View File

@ -7,6 +7,7 @@ import { formatBigNumber, lerp } from "../../core/utils";
import { Loader } from "../../core/loader";
import { enumLayer } from "../root";
import { BaseItem } from "../base_item";
import { globalConfig } from "../../core/config";
export class ChainableSplitterSystem extends GameSystemWithFilter {
constructor(root) {
@ -14,63 +15,104 @@ export class ChainableSplitterSystem extends GameSystemWithFilter {
}
update() {
// Precompute effective belt speed
const effectiveBeltSpeed = this.root.hubGoals.getBeltBaseSpeed() * globalConfig.itemSpacingOnBelts;
let progressGrowth = (effectiveBeltSpeed / 0.5) * this.root.dynamicTickrate.deltaSeconds;
if (G_IS_DEV && globalConfig.debug.instantBelts) {
progressGrowth = 1;
}
for (let i = 0; i < this.allEntities.length; ++i) {
const entity = this.allEntities[i];
const splitterComp = entity.components.ChainableSplitter;
if (splitterComp.inputItem === null) {
// First, try to get rid of received item
this.tryEject(entity, progressGrowth);
const item = splitterComp.inputItem;
if (item === null) {
continue;
}
const leftEdgeEntity = this.getLeftEdgeEntity(entity);
if (this.tryEject(leftEdgeEntity, splitterComp.inputItem)) {
if (splitterComp.tryReceiveItem(item, 0)) {
splitterComp.inputItem = null;
continue;
}
}
}
/**
*
* @param {Entity} entity
* @returns {Entity}
*/
getLeftEdgeEntity(entity) {
const leftEntity = this.getAdjacentEntity(entity, enumDirection.left);
if (leftEntity === null || !leftEntity.components.ChainableSplitter) {
return entity;
}
let resetEntities = [entity.components.ChainableSplitter];
let sideEntities = [
{
direction: enumDirection.left,
entity: entity,
},
{
direction: enumDirection.right,
entity: entity,
},
];
send_loop: for (let distance = 1; ; distance++) {
for (let index = 0; index < sideEntities.length; index++) {
const sideEntity = sideEntities[index];
return this.getLeftEdgeEntity(leftEntity);
}
sideEntity.entity = this.getAdjacentEntity(sideEntity.entity, sideEntity.direction);
let sideSplitterComp;
if (
sideEntity.entity &&
(sideSplitterComp = sideEntity.entity.components.ChainableSplitter)
) {
if (sideSplitterComp.tryReceiveItem(item, distance)) {
splitterComp.inputItem = null;
break send_loop;
}
resetEntities.push(sideSplitterComp);
} else {
sideEntities.splice(index, 1);
index--;
}
}
/**
*
* @param {Entity} entity
* @param {BaseItem} item
* @returns {boolean}
*/
tryEject(entity, item) {
const splitterComp = entity.components.ChainableSplitter;
if (!splitterComp.ejected) {
const ejectComp = entity.components.ItemEjector;
if (ejectComp.canEjectOnSlot(0)) {
if (ejectComp.tryEject(0, item)) {
splitterComp.ejected = true;
return true;
if (sideEntities.length == 0) {
for (let index = 0; index < resetEntities.length; index++) {
resetEntities[index].resetReceived();
}
break;
}
}
}
}
const rightEntity = this.getAdjacentEntity(entity, enumDirection.right);
if (
rightEntity !== null &&
rightEntity.components.ChainableSplitter &&
this.tryEject(rightEntity, item)
) {
return true;
/**
*
* @param {Entity} entity
* @param {number} progressGrowth
* @returns {boolean}
*/
tryEject(entity, progressGrowth) {
const splitterComp = entity.components.ChainableSplitter;
if (!splitterComp || splitterComp.receivedItems.length == 0) {
return false;
}
for (let index = 0; index < splitterComp.receivedItems.length; index++) {
const item = splitterComp.receivedItems[index];
item.distance -= progressGrowth;
}
const item = splitterComp.receivedItems[0];
if (item.distance > 0) {
return false;
}
const ejectComp = entity.components.ItemEjector;
if (ejectComp.canEjectOnSlot(0)) {
if (ejectComp.tryEject(0, item.item)) {
splitterComp.receivedItems.shift();
return true;
}
}
splitterComp.ejected = false;
return false;
}
}