-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathutil.js
More file actions
258 lines (225 loc) · 10.1 KB
/
util.js
File metadata and controls
258 lines (225 loc) · 10.1 KB
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
class ModernUtil {
/* CONSTANTS */
REQUIREMENTS = {
sword: {},
archer: { research: 'archer' },
hoplite: { research: 'hoplite' },
slinger: { research: 'slinger' },
catapult: { research: 'catapult' },
rider: { research: 'rider', building: 'barracks', level: 10 },
chariot: { research: 'chariot', building: 'barracks', level: 15 },
big_transporter: { building: 'docks', level: 1 },
small_transporter: { research: 'small_transporter', building: 'docks', level: 1 },
bireme: { research: 'bireme', building: 'docks', level: 1 },
attack_ship: { research: 'attack_ship', building: 'docks', level: 1 },
trireme: { research: 'trireme', building: 'docks', level: 1 },
colonize_ship: { research: 'colonize_ship', building: 'docks', level: 10 },
};
constructor(console, storage) {
this.console = console;
this.storage = storage;
}
/* Usage async this.sleep(ms) -> stop the code for ms */
sleep = (ms, stdDev) => {
// Check if a standard deviation is not provided
if (typeof stdDev === 'undefined') return new Promise(resolve => setTimeout(resolve, ms));
const mean = ms;
let u = 0, v = 0;
while (u === 0) u = Math.random(); // Converting [0,1) to (0,1)
while (v === 0) v = Math.random();
let num = Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
num = num * stdDev + mean; // Scale and translate to desired mean and stdDev
return new Promise(resolve => setTimeout(resolve, num));
};
/**
* Generate a list of town IDs that are located on large islands.
* A large island is defined as an island that has at least one town that is not on a small island.
* @returns {Array} - Array of town IDs.
*/
generateList = () => {
const townList = uw.MM.getOnlyCollectionByName('Town').models;
const islandsList = [];
const polisList = [];
for (const town of townList) {
const { island_id, id, on_small_island } = town.attributes;
if (on_small_island) continue; // Skip towns on small islands
if (!islandsList.includes(island_id)) {
islandsList.push(island_id);
polisList.push(id);
}
}
return polisList;
};
/**
* Returns HTML code for a button with a specified ID, text, function, and optional properties.
*
* @param {string} id - The ID for the button.
* @param {string} text - The text to display on the button.
* @param {Function} fn - The function to call when the button is clicked.
* @param {string} [props] - Optional properties to pass to the function.
* @returns {string} - The HTML code for the button.
*/
getButtonHtml(id, text, fn, props) {
const name = this.constructor.name.charAt(0).toLowerCase() + this.constructor.name.slice(1);
props = isNaN(parseInt(props)) ? `'${props}'` : props;
const click = `window.modernBot.${name}.${fn.name}(${props || ''})`;
return `
<div id="${id}" style="cursor: pointer" class="button_new" onclick="${click}">
<div class="left"></div>
<div class="right"></div>
<div class="caption js-caption"> ${text} <div class="effect js-effect"></div></div>
</div>`;
}
/**
* Returns the HTML for a game title with a clickable header that toggles a function.
*
* @param {string} id - The ID for the HTML element.
* @param {string} text - The text to display in the title.
* @param {function} fn - The function to toggle.
* @param {string|number} props - The properties to pass to the function.
* @param {boolean} enable - Whether the title is enabled or not.
* @param {string} [desc='(click to toggle)'] - The description to display.
* @returns {string} The HTML for the game title.
*/
getTitleHtml(id, text, fn, props, enable, desc = '(click to toggle)') {
const name = this.constructor.name.charAt(0).toLowerCase() + this.constructor.name.slice(1);
props = isNaN(parseInt(props)) && props ? `"${props}"` : props;
const click = `window.modernBot.${name}.${fn.name}(${props || ''})`;
const filter = 'brightness(100%) saturate(186%) hue-rotate(241deg)';
return `
<div class="game_border_top"></div>
<div class="game_border_bottom"></div>
<div class="game_border_left"></div>
<div class="game_border_right"></div>
<div class="game_border_corner corner1"></div>
<div class="game_border_corner corner2"></div>
<div class="game_border_corner corner3"></div>
<div class="game_border_corner corner4"></div>
<div id="${id}" style="cursor: pointer; filter: ${enable ? filter : ''}" class="game_header bold" onclick="${click}">
${text}
<span class="command_count"></span>
<div style="position: absolute; right: 10px; top: 4px; font-size: 10px;"> ${desc} </div>
</div>`;
}
/**
* Calculates the total population of a collection of units.
*
* @param {Object} units - The collection of units to count population for.
* @returns {number} - The total population of all units in the collection.
*/
countPopulation(obj) {
const data = GameData.units;
let total = 0;
for (let key in obj) {
total += data[key].population * obj[key];
}
return total;
}
isActive(type) {
return uw.GameDataPremium.isAdvisorActivated(type);
}
/**
* const button = elements.createButton('id', 'text', fn);
* $('body').append(button);
* To disable/enable the button:
* button.addClass('disabled'); button.removeClass('disabled');
* $('#id').addClass('disabled'); $('#id').removeClass('disabled');
* NOTE: Even when the button is disabled, the click event will still be triggered.
*/
createButton = (id, text, fn) => {
const $button = $('<div>', {
'id': id,
'class': 'button_new',
});
// Add the left and right divs to the button
$button.append($('<div>', { 'class': 'left' }));
$button.append($('<div>', { 'class': 'right' }));
$button.append($('<div>', {
'class': 'caption js-caption',
'html': `${text} <div class="effect js-effect"></div>`
}));
// Add the click event to the button if a function is provided
if (fn) $(document).on('click', `#${id}`, fn);
return $button;
}
/**
* const title = elements.createTitle('id', 'text', fn, description);
* $('body').append(title);
* To disable/enable the title:
* title.addClass('disabled'); title.removeClass('disabled');
* $('#id').addClass('disabled'); $('#id').removeClass('disabled');
* NOTE: Even when the title is disabled, the click event will still be triggered.
*/
createTitle = (id, text, fn, desc = '(click to toggle)') => {
const $div = $('<div>').addClass('game_header bold').attr('id', id).css({
cursor: 'pointer',
position: 'relative',
}).html(text);
const $span = $('<span>').addClass('command_count');
const $descDiv = $('<div>').css({
position: 'absolute',
right: '10px',
top: '4px',
fontSize: '10px'
}).text(desc);
$div.append($span).append($descDiv);
if (fn) $(document).on('click', `#${id}`, fn);
return $('<div>')
.append('<div class="game_border_top"></div>')
.append('<div class="game_border_bottom"></div>')
.append('<div class="game_border_left"></div>')
.append('<div class="game_border_right"></div>')
.append('<div class="game_border_corner corner1"></div>')
.append('<div class="game_border_corner corner2"></div>')
.append('<div class="game_border_corner corner3"></div>')
.append('<div class="game_border_corner corner4"></div>')
.append($div);
}
createActivity = (background) => {
const $activity_wrap = $('<div class="activity_wrap"></div>');
const $activity = $('<div class="activity"></div>');
const $icon = $('<div class="icon"></div>').css({
"background": background,
"position": "absolute",
"top": "-1px",
"left": "-1px",
});
const $count = $('<div class="count js-caption"></div>').text(0);
$icon.append($count);
$activity.append($icon);
$activity_wrap.append($activity);
return { $activity, $count };
}
createPopup = (left, width, height, $content) => {
const $box = $('<div class="sandy-box js-dropdown-list" id="toolbar_activity_recruits_list"></div>').css({
"left": `${left}px`,
"position": "absolute",
"width": `${width}px`,
"height": `${height}px`,
"top": "29px",
"margin-left": "0px",
"display": "none",
});
// Make all the corners
const $corner_tl = $('<div class="corner_tl"></div>');
const $corner_tr = $('<div class="corner_tr"></div>');
const $corner_bl = $('<div class="corner_bl"></div>');
const $corner_br = $('<div class="corner_br"></div>');
// Make all the borders
const $border_t = $('<div class="border_t"></div>');
const $border_b = $('<div class="border_b"></div>');
const $border_l = $('<div class="border_l"></div>');
const $border_r = $('<div class="border_r"></div>');
// Make the middle
const $middle = $('<div class="middle"></div>').css({
"left": "10px",
"right": "20px",
"top": "14px",
"bottom": "20px",
});
const $middle_content = $('<div class="content js-dropdown-item-list"></div>').append($content);
$middle.append($middle_content);
$box.append($corner_tl, $corner_tr, $corner_bl, $corner_br, $border_t, $border_b, $border_l, $border_r, $middle);
return $box;
}
}