-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathitem_transport_beans_extend.mdtlbl
153 lines (133 loc) · 4.19 KB
/
item_transport_beans_extend.mdtlbl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#**
* 多功能搬运豆
*
* 连接首个为分类器时会将核心做为源, 将其余作为目标
* 否则会将核心做为目标, 其余作为源
*
* 搬运的物品有连接的首个目标的config来决定
*
* 如果除了分类器以外只有一个, 那么将会始终一对一
* 否则会选择未满/拥有的进行搬运
*
* 因为将多个功能集成到了一个, 并且考虑了众多情况,
* 在效率方面比单一功能、速度专精那些要差
*#
:logic_start
const BuildXY = (__:
#**
* 给Target的绑定量[x,y]构建为其sensor的@x和@y
*#
take Target = _0;
sensor Target.x Target @x;
sensor Target.y Target @y;
);
const UnitBind = (
#**
* 文明的长绑定一个单位,
* 参数为单位要绑定到的量与其类型
* 需要绑定后控制
*#
take MyUnit = _0;
take UnitType = _1;
setres MyUnit;
# 当目前单位未死亡 未被控制或者由这控制 未被玩家控制 则不循环
gwhile (sensor $ MyUnit @dead;)
|| (ctrler: sensor $ MyUnit @controller;) != @this && ctrler != @unit
|| (sensor $ MyUnit @controlled;) == @ctrlPlayer
{
# 寻找一个未被控制的单位
while (@unit: ubind UnitType;) === null || (sensor $ @unit @controlled;) {}
MyUnit = @unit;
}
);
while (links: $ = @links;) < 2 { wait 0.2; }
# 这里使用非内联方便游戏中手动设置
# 反正速度也不是特别重要了
unit_type = @flare;
approach_range = 3;
getlink sorter 0;
sensor my_item sorter @config;
is_invert = (sorter_ty: sensor $ sorter @type;) != @sorter;
goto :logic_start my_item === null; # 没选物品的话, 直接跳回
const GetSource = (
#**
* 获取需要拿物品的目标,
* 会给其构建绑定量x和y
*#
take Return = $;
if is_invert {
# 如果是反转的, 那么寻找一个有目标物品的容器
i = 1;
while i < links
&& (sensor $ (Return: getlink $ i;) my_item;) == 0
{
op i i + 1;
}
if i == links {
# 如果没找到那就选首个了
getlink Return 1;
}
take[Return] BuildXY;
} else ulocate building core false 0 $.x $.y 0 $;
);
const GetTarget = (
#**
* 获取物品放到哪,
* 会给其构建绑定量x和y
*#
take Return = $;
if !is_invert {
# 不是反转模式, 选择随机一个放
# 连接一个时也就是总链接数为2时直接返回它
if links == 2 {
getlink Return 1;
} else {
getlink Return (?max(1, rand(links)));
}
take[Return] BuildXY;
} else ulocate building core false 0 $.x $.y 0 $;
);
const CatchException = (__:
#**
* 发生以下事件时, 跳回处理器头部
* 1. 链接数变更
* 2. 选择物品变更
* 3. 分类器类型变更
* 4. 单位控制方不是自己了
*#
goto :logic_start @links != links
|| (sensor $ sorter @config;) != my_item
|| (sensor $ (getlink $ 0;) @type;) != sorter_ty
|| (sensor $ @unit @controller;) != @this
;
);
take[my_unit unit_type] UnitBind;
ubind my_unit;
sensor unit_item @unit @firstItem;
sensor unit_item_cap @unit @itemCapacity;
if unit_item != null && unit_item != my_item {
# 携带物品不为空且类型错误
take Source = GetSource;
ucontrol approach Source.x Source.y approach_range 0 0;
do {
# 轮询尝试丢弃无效物品
ucontrol itemDrop @air unit_item_cap 0 0 0;
take CatchException;
} while (sensor $ @unit @firstItem;) != null;
} elif unit_item === null || !(sensor $ @unit my_item;) {
# 没有携带物品或物品为零时从源拿取
do {
take Source = GetSource;
ucontrol approach Source.x Source.y approach_range 0 0;
ucontrol itemTake Source my_item unit_item_cap 0 0;
take CatchException;
} while (sensor $ @unit my_item;) < unit_item_cap;
# 成功拿到物品, 直接跳转省去一轮
goto :goto_target (sensor $ @unit my_item;);
} else {
:goto_target
# 携带满物品且种类正确
take Target = GetTarget;
ucontrol approach Target.x Target.y approach_range 0 0;
ucontrol itemDrop Target unit_item_cap 0 0 0;
}