返回提交历史

XFEstudio/MCIndustry

优化磁铜传送带的连接逻辑

e94629c
X
XFEstudio <mail@xfegzs.com>
提交于

代码差异

3 个文件 +168 -3
Modified content/blocks/磁铜传送带.hjson +3 -0
@@ -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 }
Modified mod.hjson +1 -1
@@ -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 }
Modified scripts/blocks/磁铜传送带.js +164 -2
@@ -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 ));