XFEstudio/MCIndustry
优化磁铜传送带的连接逻辑
e94629c
代码差异
3 个文件
+168
-3
@@ -12,6 +12,9 @@
12
12
outputRouter: true
13
13
canOverdrive: false
14
14
hasPower: true
15
// 像电池/电力导体一样与相邻的有电建筑自动合并电网。
16
outputsPower: true
17
conductivePower: true
15
18
consumes: {
16
19
power: 0.2
17
20
}
@@ -2,6 +2,6 @@
2
2
name:磁铜工业
3
3
author:XFEstudio
4
4
"description":"[purple]磁铜工业,适合度过前期,以及为后期增加各类工厂工业制造模块,方便传输,增加新炮塔及工厂,全工业基于磁铜,持续测试中"
5
version:"2.52"
5
version:"2.53"
6
6
minGameVersion:136
7
7
}
@@ -41,8 +41,7 @@ function pullFrom(magneticConveyor, build, source, room){
41
41
}
42
42
43
43
function fillLoadingDock(magneticConveyor, build){
44
// stateLoad == 1;该常量在 Java 中是 protected,脚本侧不能直接读取。
45
if(build.state !== 1 || build.items.total() >= magneticConveyor.itemCapacity){
44
if(build.items.total() >= magneticConveyor.itemCapacity){
46
45
return;
47
46
}
48
47
@@ -52,6 +51,112 @@ function fillLoadingDock(magneticConveyor, build){
52
51
}
53
52
}
54
53
54
function sideNeighbors(build){
55
return [
56
build.nearby(Mathf.mod(build.rotation + 1, 4)),
57
build.nearby(Mathf.mod(build.rotation + 3, 4))
58
];
59
}
60
61
function canOutputToSide(magneticConveyor, build, target, item){
62
if(target == null || target.team != build.team || item == null){
63
return false;
64
}
65
66
// 磁铜传送带分支必须背对当前传送带,即真正从主线向侧面延伸。
67
if(target.block == magneticConveyor){
68
return target.back() == build && target.link == -1 && target.items.empty();
69
}
70
71
// 普通有方向的物流方块也必须背对主线,防止把物品倒灌进输入支线。
72
if(target.block.rotate && target.back() != build){
73
return false;
74
}
75
76
return target.acceptStack(item, build.items.get(item), build) > 0;
77
}
78
79
function chooseSideOutput(magneticConveyor, build){
80
if(build.link == -1 || !build.enabled || build.state == 2 || build.items.empty()){
81
return null;
82
}
83
84
const eff = build.enabled ? build.efficiency + magneticConveyor.baseEfficiency : 1;
85
const nextCooldown = Math.max(
86
0,
87
build.cooldown - magneticConveyor.speed * eff * build.delta()
88
);
89
if(nextCooldown > 0){
90
return null;
91
}
92
93
const item = build.lastItem != null && build.items.has(build.lastItem)
94
? build.lastItem
95
: build.items.first();
96
97
// 装载端仍然等到一整组再发送;中间节点可以转发侧面刚送来的整组。
98
if(build.state == 1 && build.items.total() < magneticConveyor.itemCapacity){
99
return null;
100
}
101
102
const sides = sideNeighbors(build).filter(target =>
103
canOutputToSide(magneticConveyor, build, target, item)
104
);
105
if(sides.length == 0){
106
return null;
107
}
108
109
// 正前方算一路,与有效的左右支路轮流分配整组物品。
110
const route = build.cdump % (sides.length + 1);
111
build.cdump++;
112
return route == 0 ? null : sides[route - 1];
113
}
114
115
function moveToSide(magneticConveyor, build, target){
116
const item = build.lastItem != null && build.items.has(build.lastItem)
117
? build.lastItem
118
: build.items.first();
119
if(item == null){
120
return false;
121
}
122
123
if(target.block == magneticConveyor){
124
if(target.link != -1 || !target.items.empty()){
125
return false;
126
}
127
128
// 与原版 StackConveyor 的正向交接一致:整组和动画来源一起交给支路。
129
target.items.add(build.items);
130
target.lastItem = item;
131
target.link = build.tile.pos();
132
target.cooldown = 1;
133
134
build.items.clear();
135
build.lastItem = null;
136
build.link = -1;
137
build.cooldown = magneticConveyor.recharge;
138
return true;
139
}
140
141
const accepted = Math.min(
142
build.items.get(item),
143
target.acceptStack(item, build.items.get(item), build)
144
);
145
if(accepted <= 0){
146
return false;
147
}
148
149
build.items.remove(item, accepted);
150
target.handleStack(item, accepted, build);
151
build.cooldown = magneticConveyor.recharge;
152
153
if(!build.items.has(item)){
154
build.lastItem = null;
155
build.link = -1;
156
}
157
return true;
158
}
159
55
160
Events.on(ContentInitEvent, cons(() => {
56
161
const magneticConveyor = Vars.content.getByName(
57
162
ContentType.block,
@@ -67,9 +172,66 @@ Events.on(ContentInitEvent, cons(() => {
67
172
StackConveyor.StackConveyorBuild,
68
173
magneticConveyor,
69
174
{
175
// 原版只允许 stateLoad 装载端收货。这里改为普通传送带式规则:
176
// 后方和左右两侧均可输入,只有正前方禁止反向输入。
177
acceptItem(source, item){
178
if(this == source){
179
return this.items.total() < magneticConveyor.itemCapacity &&
180
(!this.items.any() || this.items.has(item));
181
}
182
if(source == this.front() || this.cooldown > magneticConveyor.recharge - 1){
183
return false;
184
}
185
return this.items.total() < magneticConveyor.itemCapacity &&
186
(!this.items.any() || this.items.has(item));
187
},
188
189
acceptStack(item, amount, source){
190
if(source == this.front() || (this.items.any() && !this.items.has(item))){
191
return 0;
192
}
193
return Math.min(
194
amount,
195
magneticConveyor.itemCapacity - this.items.total()
196
);
197
},
198
70
199
updateTile(){
200
const side = chooseSideOutput(magneticConveyor, this);
201
if(side != null){
202
// 暂时阻止父类在同一 tick 把这一组送往正前方;父类仍负责
203
// 更新冷却、供电状态和其他内部字段。
204
this.cooldown = magneticConveyor.recharge;
205
this.super$updateTile();
206
this.cooldown = 0;
207
208
if(moveToSide(magneticConveyor, this, side)){
209
fillLoadingDock(magneticConveyor, this);
210
return;
211
}
212
}
213
71
214
this.super$updateTile();
72
215
fillLoadingDock(magneticConveyor, this);
216
},
217
218
onProximityUpdate(){
219
this.super$onProximityUpdate();
220
221
// 补上原版 StackConveyor 没有绘制的左右磁铜支路拼接。
222
const oldBlend = this.blendprox;
223
for(let i = 1; i <= 3; i += 2){
224
const dir = Mathf.mod(this.rotation - i, 4);
225
const near = this.nearby(dir);
226
if(near != null && near.team == this.team &&
227
near.block == magneticConveyor &&
228
(near.front() == this || near.back() == this)){
229
this.blendprox |= 1 << i;
230
}
231
}
232
if(this.blendprox != oldBlend){
233
this.recache();
234
}
73
235
}
74
236
}
75
237
));