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:
parent
a7cb235f2f
commit
6f99d49435
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user