-
Notifications
You must be signed in to change notification settings - Fork 15
/
Util.gd
279 lines (239 loc) · 6.79 KB
/
Util.gd
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
extends Node
##############################################
# JSON de/serialization #
##############################################
static func load_position(v: Array) -> Vector2:
return Vector2(v[0], v[1])
static func load_color(v: Array) -> Color:
if len(v) == 3:
return Color(v[0], v[1], v[2])
elif len(v) == 4:
return Color(v[0], v[1], v[2], v[3])
else:
assert('Load color array size must be either 3 or 4.')
return Color(0, 0, 0)
static func save_position(v: Vector2) -> Array:
return [v.x, v.y]
static func save_color(c: Color) -> Array:
if c.a == 1:
return [c.r, c.g, c.b]
else:
return [c.r, c.g, c.b, c.a]
static func id_list(list: Array) -> Array:
var s = []
for item in list:
s.append(item.id)
return s
static func id_key_dict(dict: Dictionary) -> Dictionary:
var s = {}
for item in dict:
s[item.id] = dict[item]
return s
static func to_int_list(s: Array) -> Array:
var r = []
for i in s:
r.append(int(i))
return r
##############################################
# Formatting #
##############################################
static func nstr(n: int) -> String:
var s = str(n)
var negative_shift = 1 if n < 0 else 0
if s.length() > 3 + negative_shift:
s = s.insert(s.length() - 3 - negative_shift, ',')
if s.length() > 7 + negative_shift:
s = s.insert(s.length() - 7 - negative_shift, ',')
if s.length() > 12 + negative_shift:
s = s.insert(s.length() - 12 - negative_shift, ',')
if s.length() > 18 + negative_shift:
s = s.insert(s.length() - 18 - negative_shift, ',')
return s
static func snstr(n: int) -> String:
var s = nstr(n)
if n >= 0:
s = '+' + s
return s
static func current_date_str() -> String:
var now = Time.get_datetime_dict_from_system()
return str(now['year']) + '-' + str(now['month']) + '-' + str(now['day']) + " " + str(now['hour']) + ":" + str(now['minute'])
static func bstr(b: bool) -> String:
return "○" if b else "×"
##############################################
# Math #
##############################################
# float to integer with randomized component by remaining frac
static func f2ri(x: float) -> int:
var trunc = int(x)
var frac = abs(x - int(x))
if x > 0:
return trunc + (1 if randf() < frac else 0)
else:
return trunc - (1 if randf() < frac else 0)
# Mahattan Distance
static func m_dist(a: Vector2, b: Vector2):
return abs(a.x - b.x) + abs(a.y - b.y)
# Get all positions in range of given position
static func squares_in_range(position: Vector2, r: int) -> Array:
var result = []
for x in range(position.x - r, position.x + r + 1):
for y in range(position.y - r, position.y + r + 1):
if m_dist(Vector2(x,y), position) <= r:
result.append(Vector2(x, y))
return result
# Rounding with arbitrary precision
static func pround(n: float, precision: int):
return int(n + precision / 2.0) / precision * precision
# Shift position by 1 place at random
static func random_shift_position(pos: Vector2) -> Vector2:
if randf() < 0.5:
if randf() < 0.5:
return Vector2(pos.x - 1, pos.y)
else:
return Vector2(pos.x + 1, pos.y)
else:
if randf() < 0.5:
return Vector2(pos.x, pos.y - 1)
else:
return Vector2(pos.x, pos.y + 1)
static func gcd(a: int, b: int) -> int:
while b != 0:
var t = b
b = a % b
a = t
return a
static func lcm(a: int, b: int) -> int:
return a * b / gcd(a, b)
##############################################
# Collections #
##############################################
static func random_from(list: Array):
if list.size() > 0:
return list[randi() % list.size()]
else:
return null
static func append_all(list: Array, other: Array):
for i in other:
list.append(i)
static func remove_object(arr: Array, item):
var index = arr.find(item)
if index >= 0:
arr.remove_at(index)
static func dict_try_get(dict: Dictionary, key, default):
if dict.has(key):
return dict[key]
else:
return default
static func dict_inc(dict: Dictionary, key, value):
if dict.has(key):
dict[key] += value
else:
dict[key] = value
static func dict_min(dict: Dictionary):
var least = 9e99
var result
for k in dict:
if dict[k] < least:
result = k
least = dict[k]
return result
static func dict_max(dict: Dictionary):
var most = -9e99
var result
for k in dict:
if dict[k] > most:
result = k
most = dict[k]
return result
# Returns item and object
static func min_pos(list: Array) -> Array:
var value = list[0]
var result = list[0]
var index = 0
var result_index = 0
for item in list:
var i = item
if i < value:
value = i
result = item
result_index = index
index += 1
return [result_index, result]
# Returns item and object
static func max_pos(list: Array) -> Array:
var value = list[0]
var result = list[0]
var index = 0
var result_index = 0
for item in list:
var i = item
if i > value:
value = i
result = item
result_index = index
index += 1
return [result_index, result]
# Returns item and object and value
static func min_by(list: Array, criteria_func: String, params = null) -> Array:
var value = 9e99
var result = list[0]
var index = 0
var result_index = 0
for item in list:
var i
if params != null:
i = item.call(criteria_func, params)
else:
i = item.call(criteria_func)
if i < value:
value = i
result = item
result_index = index
index += 1
return [result_index, result, value]
# Returns item and object and value
static func max_by(list: Array, criteria_func: String, params = null) -> Array:
var value = -9e99
var result = list[0]
var index = 0
var result_index = 0
for item in list:
var i
if params != null:
i = item.call(criteria_func, params)
else:
i = item.call(criteria_func)
if i > value:
value = i
result = item
result_index = index
index += 1
return [result_index, result, value]
static func array_filter(list: Array, criteria_func: String) -> Array:
var result = []
for item in list:
if item.call(criteria_func):
result.append(item)
return result
static func convert_dict_to_int_key(dict):
var result = {}
for k in dict:
result[int(k)] = dict[k]
return result
##############################################
# Misc #
##############################################
static func delete_all_children(node: Node):
for n in node.get_children():
node.remove_child(n)
n.queue_free()
static func resize_texture(texture, old_size: Vector2, new_size: Vector2):
var sprite = Image.new()
sprite.create(old_size.x, old_size.y, false, texture.get_format())
sprite.blit_rect(texture, Rect2(0, 0, old_size.x, old_size.y), Vector2(0, 0))
sprite.resize(new_size.x, new_size.y, Image.INTERPOLATE_CUBIC)
var image = ImageTexture.new()
image.create_from_image(sprite)
return image
static func coalesce(a, b):
return a if a else b