· 7 years ago · Oct 09, 2018, 12:06 PM
1//===========================================================================
2// Blizzard.j ( define Jass2 functions that need to be in every map script )
3//===========================================================================
4
5
6globals
7 //-----------------------------------------------------------------------
8 // Constants
9 //
10
11 // Misc constants
12 constant real bj_PI = 3.14159
13 constant real bj_E = 2.71828
14 constant real bj_CELLWIDTH = 128.0
15 constant real bj_CLIFFHEIGHT = 128.0
16 constant real bj_UNIT_FACING = 270.0
17 constant real bj_RADTODEG = 180.0/bj_PI
18 constant real bj_DEGTORAD = bj_PI/180.0
19 constant real bj_TEXT_DELAY_QUEST = 20.00
20 constant real bj_TEXT_DELAY_QUESTUPDATE = 20.00
21 constant real bj_TEXT_DELAY_QUESTDONE = 20.00
22 constant real bj_TEXT_DELAY_QUESTFAILED = 20.00
23 constant real bj_TEXT_DELAY_QUESTREQUIREMENT = 20.00
24 constant real bj_TEXT_DELAY_MISSIONFAILED = 20.00
25 constant real bj_TEXT_DELAY_ALWAYSHINT = 12.00
26 constant real bj_TEXT_DELAY_HINT = 12.00
27 constant real bj_TEXT_DELAY_SECRET = 10.00
28 constant real bj_TEXT_DELAY_UNITACQUIRED = 15.00
29 constant real bj_TEXT_DELAY_UNITAVAILABLE = 10.00
30 constant real bj_TEXT_DELAY_ITEMACQUIRED = 10.00
31 constant real bj_TEXT_DELAY_WARNING = 12.00
32 constant real bj_QUEUE_DELAY_QUEST = 5.00
33 constant real bj_QUEUE_DELAY_HINT = 5.00
34 constant real bj_QUEUE_DELAY_SECRET = 3.00
35 constant real bj_HANDICAP_EASY = 60.00
36 constant real bj_GAME_STARTED_THRESHOLD = 0.01
37 constant real bj_WAIT_FOR_COND_MIN_INTERVAL = 0.10
38 constant real bj_POLLED_WAIT_INTERVAL = 0.10
39 constant real bj_POLLED_WAIT_SKIP_THRESHOLD = 2.00
40
41 // Game constants
42 constant integer bj_MAX_INVENTORY = 6
43 constant integer bj_MAX_PLAYERS = GetBJMaxPlayers()
44 constant integer bj_PLAYER_NEUTRAL_VICTIM = GetBJPlayerNeutralVictim()
45 constant integer bj_PLAYER_NEUTRAL_EXTRA = GetBJPlayerNeutralExtra()
46 constant integer bj_MAX_PLAYER_SLOTS = GetBJMaxPlayerSlots()
47 constant integer bj_MAX_SKELETONS = 25
48 constant integer bj_MAX_STOCK_ITEM_SLOTS = 11
49 constant integer bj_MAX_STOCK_UNIT_SLOTS = 11
50 constant integer bj_MAX_ITEM_LEVEL = 10
51
52 // Ideally these would be looked up from Units/MiscData.txt,
53 // but there is currently no script functionality exposed to do that
54 constant real bj_TOD_DAWN = 6.00
55 constant real bj_TOD_DUSK = 18.00
56
57 // Melee game settings:
58 // - Starting Time of Day (TOD)
59 // - Starting Gold
60 // - Starting Lumber
61 // - Starting Hero Tokens (free heroes)
62 // - Max heroes allowed per player
63 // - Max heroes allowed per hero type
64 // - Distance from start loc to search for nearby mines
65 //
66 constant real bj_MELEE_STARTING_TOD = 8.00
67 constant integer bj_MELEE_STARTING_GOLD_V0 = 750
68 constant integer bj_MELEE_STARTING_GOLD_V1 = 500
69 constant integer bj_MELEE_STARTING_LUMBER_V0 = 200
70 constant integer bj_MELEE_STARTING_LUMBER_V1 = 150
71 constant integer bj_MELEE_STARTING_HERO_TOKENS = 1
72 constant integer bj_MELEE_HERO_LIMIT = 3
73 constant integer bj_MELEE_HERO_TYPE_LIMIT = 1
74 constant real bj_MELEE_MINE_SEARCH_RADIUS = 2000
75 constant real bj_MELEE_CLEAR_UNITS_RADIUS = 1500
76 constant real bj_MELEE_CRIPPLE_TIMEOUT = 120.00
77 constant real bj_MELEE_CRIPPLE_MSG_DURATION = 20.00
78 constant integer bj_MELEE_MAX_TWINKED_HEROES_V0 = 3
79 constant integer bj_MELEE_MAX_TWINKED_HEROES_V1 = 1
80
81 // Delay between a creep's death and the time it may drop an item.
82 constant real bj_CREEP_ITEM_DELAY = 0.50
83
84 // Timing settings for Marketplace inventories.
85 constant real bj_STOCK_RESTOCK_INITIAL_DELAY = 120
86 constant real bj_STOCK_RESTOCK_INTERVAL = 30
87 constant integer bj_STOCK_MAX_ITERATIONS = 20
88
89 // Max events registered by a single "dest dies in region" event.
90 constant integer bj_MAX_DEST_IN_REGION_EVENTS = 64
91
92 // Camera settings
93 constant integer bj_CAMERA_MIN_FARZ = 100
94 constant integer bj_CAMERA_DEFAULT_DISTANCE = 1650
95 constant integer bj_CAMERA_DEFAULT_FARZ = 5000
96 constant integer bj_CAMERA_DEFAULT_AOA = 304
97 constant integer bj_CAMERA_DEFAULT_FOV = 70
98 constant integer bj_CAMERA_DEFAULT_ROLL = 0
99 constant integer bj_CAMERA_DEFAULT_ROTATION = 90
100
101 // Rescue
102 constant real bj_RESCUE_PING_TIME = 2.00
103
104 // Transmission behavior settings
105 constant real bj_NOTHING_SOUND_DURATION = 5.00
106 constant real bj_TRANSMISSION_PING_TIME = 1.00
107 constant integer bj_TRANSMISSION_IND_RED = 255
108 constant integer bj_TRANSMISSION_IND_BLUE = 255
109 constant integer bj_TRANSMISSION_IND_GREEN = 255
110 constant integer bj_TRANSMISSION_IND_ALPHA = 255
111 constant real bj_TRANSMISSION_PORT_HANGTIME = 1.50
112
113 // Cinematic mode settings
114 constant real bj_CINEMODE_INTERFACEFADE = 0.50
115 constant gamespeed bj_CINEMODE_GAMESPEED = MAP_SPEED_NORMAL
116
117 // Cinematic mode volume levels
118 constant real bj_CINEMODE_VOLUME_UNITMOVEMENT = 0.40
119 constant real bj_CINEMODE_VOLUME_UNITSOUNDS = 0.00
120 constant real bj_CINEMODE_VOLUME_COMBAT = 0.40
121 constant real bj_CINEMODE_VOLUME_SPELLS = 0.40
122 constant real bj_CINEMODE_VOLUME_UI = 0.00
123 constant real bj_CINEMODE_VOLUME_MUSIC = 0.55
124 constant real bj_CINEMODE_VOLUME_AMBIENTSOUNDS = 1.00
125 constant real bj_CINEMODE_VOLUME_FIRE = 0.60
126
127 // Speech mode volume levels
128 constant real bj_SPEECH_VOLUME_UNITMOVEMENT = 0.25
129 constant real bj_SPEECH_VOLUME_UNITSOUNDS = 0.00
130 constant real bj_SPEECH_VOLUME_COMBAT = 0.25
131 constant real bj_SPEECH_VOLUME_SPELLS = 0.25
132 constant real bj_SPEECH_VOLUME_UI = 0.00
133 constant real bj_SPEECH_VOLUME_MUSIC = 0.55
134 constant real bj_SPEECH_VOLUME_AMBIENTSOUNDS = 1.00
135 constant real bj_SPEECH_VOLUME_FIRE = 0.60
136
137 // Smart pan settings
138 constant real bj_SMARTPAN_TRESHOLD_PAN = 500
139 constant real bj_SMARTPAN_TRESHOLD_SNAP = 3500
140
141 // QueuedTriggerExecute settings
142 constant integer bj_MAX_QUEUED_TRIGGERS = 100
143 constant real bj_QUEUED_TRIGGER_TIMEOUT = 180.00
144
145 // Campaign indexing constants
146 constant integer bj_CAMPAIGN_INDEX_T = 0
147 constant integer bj_CAMPAIGN_INDEX_H = 1
148 constant integer bj_CAMPAIGN_INDEX_U = 2
149 constant integer bj_CAMPAIGN_INDEX_O = 3
150 constant integer bj_CAMPAIGN_INDEX_N = 4
151 constant integer bj_CAMPAIGN_INDEX_XN = 5
152 constant integer bj_CAMPAIGN_INDEX_XH = 6
153 constant integer bj_CAMPAIGN_INDEX_XU = 7
154 constant integer bj_CAMPAIGN_INDEX_XO = 8
155
156 // Campaign offset constants (for mission indexing)
157 constant integer bj_CAMPAIGN_OFFSET_T = 0
158 constant integer bj_CAMPAIGN_OFFSET_H = 1
159 constant integer bj_CAMPAIGN_OFFSET_U = 2
160 constant integer bj_CAMPAIGN_OFFSET_O = 3
161 constant integer bj_CAMPAIGN_OFFSET_N = 4
162 constant integer bj_CAMPAIGN_OFFSET_XN = 0
163 constant integer bj_CAMPAIGN_OFFSET_XH = 1
164 constant integer bj_CAMPAIGN_OFFSET_XU = 2
165 constant integer bj_CAMPAIGN_OFFSET_XO = 3
166
167 // Mission indexing constants
168 // Tutorial
169 constant integer bj_MISSION_INDEX_T00 = bj_CAMPAIGN_OFFSET_T * 1000 + 0
170 constant integer bj_MISSION_INDEX_T01 = bj_CAMPAIGN_OFFSET_T * 1000 + 1
171 // Human
172 constant integer bj_MISSION_INDEX_H00 = bj_CAMPAIGN_OFFSET_H * 1000 + 0
173 constant integer bj_MISSION_INDEX_H01 = bj_CAMPAIGN_OFFSET_H * 1000 + 1
174 constant integer bj_MISSION_INDEX_H02 = bj_CAMPAIGN_OFFSET_H * 1000 + 2
175 constant integer bj_MISSION_INDEX_H03 = bj_CAMPAIGN_OFFSET_H * 1000 + 3
176 constant integer bj_MISSION_INDEX_H04 = bj_CAMPAIGN_OFFSET_H * 1000 + 4
177 constant integer bj_MISSION_INDEX_H05 = bj_CAMPAIGN_OFFSET_H * 1000 + 5
178 constant integer bj_MISSION_INDEX_H06 = bj_CAMPAIGN_OFFSET_H * 1000 + 6
179 constant integer bj_MISSION_INDEX_H07 = bj_CAMPAIGN_OFFSET_H * 1000 + 7
180 constant integer bj_MISSION_INDEX_H08 = bj_CAMPAIGN_OFFSET_H * 1000 + 8
181 constant integer bj_MISSION_INDEX_H09 = bj_CAMPAIGN_OFFSET_H * 1000 + 9
182 constant integer bj_MISSION_INDEX_H10 = bj_CAMPAIGN_OFFSET_H * 1000 + 10
183 constant integer bj_MISSION_INDEX_H11 = bj_CAMPAIGN_OFFSET_H * 1000 + 11
184 // Undead
185 constant integer bj_MISSION_INDEX_U00 = bj_CAMPAIGN_OFFSET_U * 1000 + 0
186 constant integer bj_MISSION_INDEX_U01 = bj_CAMPAIGN_OFFSET_U * 1000 + 1
187 constant integer bj_MISSION_INDEX_U02 = bj_CAMPAIGN_OFFSET_U * 1000 + 2
188 constant integer bj_MISSION_INDEX_U03 = bj_CAMPAIGN_OFFSET_U * 1000 + 3
189 constant integer bj_MISSION_INDEX_U05 = bj_CAMPAIGN_OFFSET_U * 1000 + 4
190 constant integer bj_MISSION_INDEX_U07 = bj_CAMPAIGN_OFFSET_U * 1000 + 5
191 constant integer bj_MISSION_INDEX_U08 = bj_CAMPAIGN_OFFSET_U * 1000 + 6
192 constant integer bj_MISSION_INDEX_U09 = bj_CAMPAIGN_OFFSET_U * 1000 + 7
193 constant integer bj_MISSION_INDEX_U10 = bj_CAMPAIGN_OFFSET_U * 1000 + 8
194 constant integer bj_MISSION_INDEX_U11 = bj_CAMPAIGN_OFFSET_U * 1000 + 9
195 // Orc
196 constant integer bj_MISSION_INDEX_O00 = bj_CAMPAIGN_OFFSET_O * 1000 + 0
197 constant integer bj_MISSION_INDEX_O01 = bj_CAMPAIGN_OFFSET_O * 1000 + 1
198 constant integer bj_MISSION_INDEX_O02 = bj_CAMPAIGN_OFFSET_O * 1000 + 2
199 constant integer bj_MISSION_INDEX_O03 = bj_CAMPAIGN_OFFSET_O * 1000 + 3
200 constant integer bj_MISSION_INDEX_O04 = bj_CAMPAIGN_OFFSET_O * 1000 + 4
201 constant integer bj_MISSION_INDEX_O05 = bj_CAMPAIGN_OFFSET_O * 1000 + 5
202 constant integer bj_MISSION_INDEX_O06 = bj_CAMPAIGN_OFFSET_O * 1000 + 6
203 constant integer bj_MISSION_INDEX_O07 = bj_CAMPAIGN_OFFSET_O * 1000 + 7
204 constant integer bj_MISSION_INDEX_O08 = bj_CAMPAIGN_OFFSET_O * 1000 + 8
205 constant integer bj_MISSION_INDEX_O09 = bj_CAMPAIGN_OFFSET_O * 1000 + 9
206 constant integer bj_MISSION_INDEX_O10 = bj_CAMPAIGN_OFFSET_O * 1000 + 10
207 // Night Elf
208 constant integer bj_MISSION_INDEX_N00 = bj_CAMPAIGN_OFFSET_N * 1000 + 0
209 constant integer bj_MISSION_INDEX_N01 = bj_CAMPAIGN_OFFSET_N * 1000 + 1
210 constant integer bj_MISSION_INDEX_N02 = bj_CAMPAIGN_OFFSET_N * 1000 + 2
211 constant integer bj_MISSION_INDEX_N03 = bj_CAMPAIGN_OFFSET_N * 1000 + 3
212 constant integer bj_MISSION_INDEX_N04 = bj_CAMPAIGN_OFFSET_N * 1000 + 4
213 constant integer bj_MISSION_INDEX_N05 = bj_CAMPAIGN_OFFSET_N * 1000 + 5
214 constant integer bj_MISSION_INDEX_N06 = bj_CAMPAIGN_OFFSET_N * 1000 + 6
215 constant integer bj_MISSION_INDEX_N07 = bj_CAMPAIGN_OFFSET_N * 1000 + 7
216 constant integer bj_MISSION_INDEX_N08 = bj_CAMPAIGN_OFFSET_N * 1000 + 8
217 constant integer bj_MISSION_INDEX_N09 = bj_CAMPAIGN_OFFSET_N * 1000 + 9
218 // Expansion Night Elf
219 constant integer bj_MISSION_INDEX_XN00 = bj_CAMPAIGN_OFFSET_XN * 1000 + 0
220 constant integer bj_MISSION_INDEX_XN01 = bj_CAMPAIGN_OFFSET_XN * 1000 + 1
221 constant integer bj_MISSION_INDEX_XN02 = bj_CAMPAIGN_OFFSET_XN * 1000 + 2
222 constant integer bj_MISSION_INDEX_XN03 = bj_CAMPAIGN_OFFSET_XN * 1000 + 3
223 constant integer bj_MISSION_INDEX_XN04 = bj_CAMPAIGN_OFFSET_XN * 1000 + 4
224 constant integer bj_MISSION_INDEX_XN05 = bj_CAMPAIGN_OFFSET_XN * 1000 + 5
225 constant integer bj_MISSION_INDEX_XN06 = bj_CAMPAIGN_OFFSET_XN * 1000 + 6
226 constant integer bj_MISSION_INDEX_XN07 = bj_CAMPAIGN_OFFSET_XN * 1000 + 7
227 constant integer bj_MISSION_INDEX_XN08 = bj_CAMPAIGN_OFFSET_XN * 1000 + 8
228 constant integer bj_MISSION_INDEX_XN09 = bj_CAMPAIGN_OFFSET_XN * 1000 + 9
229 constant integer bj_MISSION_INDEX_XN10 = bj_CAMPAIGN_OFFSET_XN * 1000 + 10
230 // Expansion Human
231 constant integer bj_MISSION_INDEX_XH00 = bj_CAMPAIGN_OFFSET_XH * 1000 + 0
232 constant integer bj_MISSION_INDEX_XH01 = bj_CAMPAIGN_OFFSET_XH * 1000 + 1
233 constant integer bj_MISSION_INDEX_XH02 = bj_CAMPAIGN_OFFSET_XH * 1000 + 2
234 constant integer bj_MISSION_INDEX_XH03 = bj_CAMPAIGN_OFFSET_XH * 1000 + 3
235 constant integer bj_MISSION_INDEX_XH04 = bj_CAMPAIGN_OFFSET_XH * 1000 + 4
236 constant integer bj_MISSION_INDEX_XH05 = bj_CAMPAIGN_OFFSET_XH * 1000 + 5
237 constant integer bj_MISSION_INDEX_XH06 = bj_CAMPAIGN_OFFSET_XH * 1000 + 6
238 constant integer bj_MISSION_INDEX_XH07 = bj_CAMPAIGN_OFFSET_XH * 1000 + 7
239 constant integer bj_MISSION_INDEX_XH08 = bj_CAMPAIGN_OFFSET_XH * 1000 + 8
240 constant integer bj_MISSION_INDEX_XH09 = bj_CAMPAIGN_OFFSET_XH * 1000 + 9
241 // Expansion Undead
242 constant integer bj_MISSION_INDEX_XU00 = bj_CAMPAIGN_OFFSET_XU * 1000 + 0
243 constant integer bj_MISSION_INDEX_XU01 = bj_CAMPAIGN_OFFSET_XU * 1000 + 1
244 constant integer bj_MISSION_INDEX_XU02 = bj_CAMPAIGN_OFFSET_XU * 1000 + 2
245 constant integer bj_MISSION_INDEX_XU03 = bj_CAMPAIGN_OFFSET_XU * 1000 + 3
246 constant integer bj_MISSION_INDEX_XU04 = bj_CAMPAIGN_OFFSET_XU * 1000 + 4
247 constant integer bj_MISSION_INDEX_XU05 = bj_CAMPAIGN_OFFSET_XU * 1000 + 5
248 constant integer bj_MISSION_INDEX_XU06 = bj_CAMPAIGN_OFFSET_XU * 1000 + 6
249 constant integer bj_MISSION_INDEX_XU07 = bj_CAMPAIGN_OFFSET_XU * 1000 + 7
250 constant integer bj_MISSION_INDEX_XU08 = bj_CAMPAIGN_OFFSET_XU * 1000 + 8
251 constant integer bj_MISSION_INDEX_XU09 = bj_CAMPAIGN_OFFSET_XU * 1000 + 9
252 constant integer bj_MISSION_INDEX_XU10 = bj_CAMPAIGN_OFFSET_XU * 1000 + 10
253 constant integer bj_MISSION_INDEX_XU11 = bj_CAMPAIGN_OFFSET_XU * 1000 + 11
254 constant integer bj_MISSION_INDEX_XU12 = bj_CAMPAIGN_OFFSET_XU * 1000 + 12
255 constant integer bj_MISSION_INDEX_XU13 = bj_CAMPAIGN_OFFSET_XU * 1000 + 13
256
257 // Expansion Orc
258 constant integer bj_MISSION_INDEX_XO00 = bj_CAMPAIGN_OFFSET_XO * 1000 + 0
259 constant integer bj_MISSION_INDEX_XO01 = bj_CAMPAIGN_OFFSET_XO * 1000 + 1
260 constant integer bj_MISSION_INDEX_XO02 = bj_CAMPAIGN_OFFSET_XO * 1000 + 2
261 constant integer bj_MISSION_INDEX_XO03 = bj_CAMPAIGN_OFFSET_XO * 1000 + 3
262
263 // Cinematic indexing constants
264 constant integer bj_CINEMATICINDEX_TOP = 0
265 constant integer bj_CINEMATICINDEX_HOP = 1
266 constant integer bj_CINEMATICINDEX_HED = 2
267 constant integer bj_CINEMATICINDEX_OOP = 3
268 constant integer bj_CINEMATICINDEX_OED = 4
269 constant integer bj_CINEMATICINDEX_UOP = 5
270 constant integer bj_CINEMATICINDEX_UED = 6
271 constant integer bj_CINEMATICINDEX_NOP = 7
272 constant integer bj_CINEMATICINDEX_NED = 8
273 constant integer bj_CINEMATICINDEX_XOP = 9
274 constant integer bj_CINEMATICINDEX_XED = 10
275
276 // Alliance settings
277 constant integer bj_ALLIANCE_UNALLIED = 0
278 constant integer bj_ALLIANCE_UNALLIED_VISION = 1
279 constant integer bj_ALLIANCE_ALLIED = 2
280 constant integer bj_ALLIANCE_ALLIED_VISION = 3
281 constant integer bj_ALLIANCE_ALLIED_UNITS = 4
282 constant integer bj_ALLIANCE_ALLIED_ADVUNITS = 5
283 constant integer bj_ALLIANCE_NEUTRAL = 6
284 constant integer bj_ALLIANCE_NEUTRAL_VISION = 7
285
286 // Keyboard Event Types
287 constant integer bj_KEYEVENTTYPE_DEPRESS = 0
288 constant integer bj_KEYEVENTTYPE_RELEASE = 1
289
290 // Keyboard Event Keys
291 constant integer bj_KEYEVENTKEY_LEFT = 0
292 constant integer bj_KEYEVENTKEY_RIGHT = 1
293 constant integer bj_KEYEVENTKEY_DOWN = 2
294 constant integer bj_KEYEVENTKEY_UP = 3
295
296 // Mouse Event Types
297 constant integer bj_MOUSEEVENTTYPE_DOWN = 0
298 constant integer bj_MOUSEEVENTTYPE_UP = 1
299 constant integer bj_MOUSEEVENTTYPE_MOVE = 2
300
301 // Transmission timing methods
302 constant integer bj_TIMETYPE_ADD = 0
303 constant integer bj_TIMETYPE_SET = 1
304 constant integer bj_TIMETYPE_SUB = 2
305
306 // Camera bounds adjustment methods
307 constant integer bj_CAMERABOUNDS_ADJUST_ADD = 0
308 constant integer bj_CAMERABOUNDS_ADJUST_SUB = 1
309
310 // Quest creation states
311 constant integer bj_QUESTTYPE_REQ_DISCOVERED = 0
312 constant integer bj_QUESTTYPE_REQ_UNDISCOVERED = 1
313 constant integer bj_QUESTTYPE_OPT_DISCOVERED = 2
314 constant integer bj_QUESTTYPE_OPT_UNDISCOVERED = 3
315
316 // Quest message types
317 constant integer bj_QUESTMESSAGE_DISCOVERED = 0
318 constant integer bj_QUESTMESSAGE_UPDATED = 1
319 constant integer bj_QUESTMESSAGE_COMPLETED = 2
320 constant integer bj_QUESTMESSAGE_FAILED = 3
321 constant integer bj_QUESTMESSAGE_REQUIREMENT = 4
322 constant integer bj_QUESTMESSAGE_MISSIONFAILED = 5
323 constant integer bj_QUESTMESSAGE_ALWAYSHINT = 6
324 constant integer bj_QUESTMESSAGE_HINT = 7
325 constant integer bj_QUESTMESSAGE_SECRET = 8
326 constant integer bj_QUESTMESSAGE_UNITACQUIRED = 9
327 constant integer bj_QUESTMESSAGE_UNITAVAILABLE = 10
328 constant integer bj_QUESTMESSAGE_ITEMACQUIRED = 11
329 constant integer bj_QUESTMESSAGE_WARNING = 12
330
331 // Leaderboard sorting methods
332 constant integer bj_SORTTYPE_SORTBYVALUE = 0
333 constant integer bj_SORTTYPE_SORTBYPLAYER = 1
334 constant integer bj_SORTTYPE_SORTBYLABEL = 2
335
336 // Cinematic fade filter methods
337 constant integer bj_CINEFADETYPE_FADEIN = 0
338 constant integer bj_CINEFADETYPE_FADEOUT = 1
339 constant integer bj_CINEFADETYPE_FADEOUTIN = 2
340
341 // Buff removal methods
342 constant integer bj_REMOVEBUFFS_POSITIVE = 0
343 constant integer bj_REMOVEBUFFS_NEGATIVE = 1
344 constant integer bj_REMOVEBUFFS_ALL = 2
345 constant integer bj_REMOVEBUFFS_NONTLIFE = 3
346
347 // Buff properties - polarity
348 constant integer bj_BUFF_POLARITY_POSITIVE = 0
349 constant integer bj_BUFF_POLARITY_NEGATIVE = 1
350 constant integer bj_BUFF_POLARITY_EITHER = 2
351
352 // Buff properties - resist type
353 constant integer bj_BUFF_RESIST_MAGIC = 0
354 constant integer bj_BUFF_RESIST_PHYSICAL = 1
355 constant integer bj_BUFF_RESIST_EITHER = 2
356 constant integer bj_BUFF_RESIST_BOTH = 3
357
358 // Hero stats
359 constant integer bj_HEROSTAT_STR = 0
360 constant integer bj_HEROSTAT_AGI = 1
361 constant integer bj_HEROSTAT_INT = 2
362
363 // Hero skill point modification methods
364 constant integer bj_MODIFYMETHOD_ADD = 0
365 constant integer bj_MODIFYMETHOD_SUB = 1
366 constant integer bj_MODIFYMETHOD_SET = 2
367
368 // Unit state adjustment methods (for replaced units)
369 constant integer bj_UNIT_STATE_METHOD_ABSOLUTE = 0
370 constant integer bj_UNIT_STATE_METHOD_RELATIVE = 1
371 constant integer bj_UNIT_STATE_METHOD_DEFAULTS = 2
372 constant integer bj_UNIT_STATE_METHOD_MAXIMUM = 3
373
374 // Gate operations
375 constant integer bj_GATEOPERATION_CLOSE = 0
376 constant integer bj_GATEOPERATION_OPEN = 1
377 constant integer bj_GATEOPERATION_DESTROY = 2
378
379 // Game cache value types
380 constant integer bj_GAMECACHE_BOOLEAN = 0
381 constant integer bj_GAMECACHE_INTEGER = 1
382 constant integer bj_GAMECACHE_REAL = 2
383 constant integer bj_GAMECACHE_UNIT = 3
384 constant integer bj_GAMECACHE_STRING = 4
385
386 // Hashtable value types
387 constant integer bj_HASHTABLE_BOOLEAN = 0
388 constant integer bj_HASHTABLE_INTEGER = 1
389 constant integer bj_HASHTABLE_REAL = 2
390 constant integer bj_HASHTABLE_STRING = 3
391 constant integer bj_HASHTABLE_HANDLE = 4
392
393 // Item status types
394 constant integer bj_ITEM_STATUS_HIDDEN = 0
395 constant integer bj_ITEM_STATUS_OWNED = 1
396 constant integer bj_ITEM_STATUS_INVULNERABLE = 2
397 constant integer bj_ITEM_STATUS_POWERUP = 3
398 constant integer bj_ITEM_STATUS_SELLABLE = 4
399 constant integer bj_ITEM_STATUS_PAWNABLE = 5
400
401 // Itemcode status types
402 constant integer bj_ITEMCODE_STATUS_POWERUP = 0
403 constant integer bj_ITEMCODE_STATUS_SELLABLE = 1
404 constant integer bj_ITEMCODE_STATUS_PAWNABLE = 2
405
406 // Minimap ping styles
407 constant integer bj_MINIMAPPINGSTYLE_SIMPLE = 0
408 constant integer bj_MINIMAPPINGSTYLE_FLASHY = 1
409 constant integer bj_MINIMAPPINGSTYLE_ATTACK = 2
410
411 // Corpse creation settings
412 constant real bj_CORPSE_MAX_DEATH_TIME = 8.00
413
414 // Corpse creation styles
415 constant integer bj_CORPSETYPE_FLESH = 0
416 constant integer bj_CORPSETYPE_BONE = 1
417
418 // Elevator pathing-blocker destructable code
419 constant integer bj_ELEVATOR_BLOCKER_CODE = 'DTep'
420 constant integer bj_ELEVATOR_CODE01 = 'DTrf'
421 constant integer bj_ELEVATOR_CODE02 = 'DTrx'
422
423 // Elevator wall codes
424 constant integer bj_ELEVATOR_WALL_TYPE_ALL = 0
425 constant integer bj_ELEVATOR_WALL_TYPE_EAST = 1
426 constant integer bj_ELEVATOR_WALL_TYPE_NORTH = 2
427 constant integer bj_ELEVATOR_WALL_TYPE_SOUTH = 3
428 constant integer bj_ELEVATOR_WALL_TYPE_WEST = 4
429
430 //-----------------------------------------------------------------------
431 // Variables
432 //
433
434 // Force predefs
435 force bj_FORCE_ALL_PLAYERS = null
436 force array bj_FORCE_PLAYER
437
438 integer bj_MELEE_MAX_TWINKED_HEROES = 0
439
440 // Map area rects
441 rect bj_mapInitialPlayableArea = null
442 rect bj_mapInitialCameraBounds = null
443
444 // Utility function vars
445 integer bj_forLoopAIndex = 0
446 integer bj_forLoopBIndex = 0
447 integer bj_forLoopAIndexEnd = 0
448 integer bj_forLoopBIndexEnd = 0
449
450 boolean bj_slotControlReady = false
451 boolean array bj_slotControlUsed
452 mapcontrol array bj_slotControl
453
454 // Game started detection vars
455 timer bj_gameStartedTimer = null
456 boolean bj_gameStarted = false
457 timer bj_volumeGroupsTimer = CreateTimer()
458
459 // Singleplayer check
460 boolean bj_isSinglePlayer = false
461
462 // Day/Night Cycle vars
463 trigger bj_dncSoundsDay = null
464 trigger bj_dncSoundsNight = null
465 sound bj_dayAmbientSound = null
466 sound bj_nightAmbientSound = null
467 trigger bj_dncSoundsDawn = null
468 trigger bj_dncSoundsDusk = null
469 sound bj_dawnSound = null
470 sound bj_duskSound = null
471 boolean bj_useDawnDuskSounds = true
472 boolean bj_dncIsDaytime = false
473
474 // Triggered sounds
475 //sound bj_pingMinimapSound = null
476 sound bj_rescueSound = null
477 sound bj_questDiscoveredSound = null
478 sound bj_questUpdatedSound = null
479 sound bj_questCompletedSound = null
480 sound bj_questFailedSound = null
481 sound bj_questHintSound = null
482 sound bj_questSecretSound = null
483 sound bj_questItemAcquiredSound = null
484 sound bj_questWarningSound = null
485 sound bj_victoryDialogSound = null
486 sound bj_defeatDialogSound = null
487
488 // Marketplace vars
489 trigger bj_stockItemPurchased = null
490 timer bj_stockUpdateTimer = null
491 boolean array bj_stockAllowedPermanent
492 boolean array bj_stockAllowedCharged
493 boolean array bj_stockAllowedArtifact
494 integer bj_stockPickedItemLevel = 0
495 itemtype bj_stockPickedItemType
496
497 // Melee vars
498 trigger bj_meleeVisibilityTrained = null
499 boolean bj_meleeVisibilityIsDay = true
500 boolean bj_meleeGrantHeroItems = false
501 location bj_meleeNearestMineToLoc = null
502 unit bj_meleeNearestMine = null
503 real bj_meleeNearestMineDist = 0.00
504 boolean bj_meleeGameOver = false
505 boolean array bj_meleeDefeated
506 boolean array bj_meleeVictoried
507 unit array bj_ghoul
508 timer array bj_crippledTimer
509 timerdialog array bj_crippledTimerWindows
510 boolean array bj_playerIsCrippled
511 boolean array bj_playerIsExposed
512 boolean bj_finishSoonAllExposed = false
513 timerdialog bj_finishSoonTimerDialog = null
514 integer array bj_meleeTwinkedHeroes
515
516 // Rescue behavior vars
517 trigger bj_rescueUnitBehavior = null
518 boolean bj_rescueChangeColorUnit = true
519 boolean bj_rescueChangeColorBldg = true
520
521 // Transmission vars
522 timer bj_cineSceneEndingTimer = null
523 sound bj_cineSceneLastSound = null
524 trigger bj_cineSceneBeingSkipped = null
525
526 // Cinematic mode vars
527 gamespeed bj_cineModePriorSpeed = MAP_SPEED_NORMAL
528 boolean bj_cineModePriorFogSetting = false
529 boolean bj_cineModePriorMaskSetting = false
530 boolean bj_cineModeAlreadyIn = false
531 boolean bj_cineModePriorDawnDusk = false
532 integer bj_cineModeSavedSeed = 0
533
534 // Cinematic fade vars
535 timer bj_cineFadeFinishTimer = null
536 timer bj_cineFadeContinueTimer = null
537 real bj_cineFadeContinueRed = 0
538 real bj_cineFadeContinueGreen = 0
539 real bj_cineFadeContinueBlue = 0
540 real bj_cineFadeContinueTrans = 0
541 real bj_cineFadeContinueDuration = 0
542 string bj_cineFadeContinueTex = ""
543
544 // QueuedTriggerExecute vars
545 integer bj_queuedExecTotal = 0
546 trigger array bj_queuedExecTriggers
547 boolean array bj_queuedExecUseConds
548 timer bj_queuedExecTimeoutTimer = CreateTimer()
549 trigger bj_queuedExecTimeout = null
550
551 // Helper vars (for Filter and Enum funcs)
552 integer bj_destInRegionDiesCount = 0
553 trigger bj_destInRegionDiesTrig = null
554 integer bj_groupCountUnits = 0
555 integer bj_forceCountPlayers = 0
556 integer bj_groupEnumTypeId = 0
557 player bj_groupEnumOwningPlayer = null
558 group bj_groupAddGroupDest = null
559 group bj_groupRemoveGroupDest = null
560 integer bj_groupRandomConsidered = 0
561 unit bj_groupRandomCurrentPick = null
562 group bj_groupLastCreatedDest = null
563 group bj_randomSubGroupGroup = null
564 integer bj_randomSubGroupWant = 0
565 integer bj_randomSubGroupTotal = 0
566 real bj_randomSubGroupChance = 0
567 integer bj_destRandomConsidered = 0
568 destructable bj_destRandomCurrentPick = null
569 destructable bj_elevatorWallBlocker = null
570 destructable bj_elevatorNeighbor = null
571 integer bj_itemRandomConsidered = 0
572 item bj_itemRandomCurrentPick = null
573 integer bj_forceRandomConsidered = 0
574 player bj_forceRandomCurrentPick = null
575 unit bj_makeUnitRescuableUnit = null
576 boolean bj_makeUnitRescuableFlag = true
577 boolean bj_pauseAllUnitsFlag = true
578 location bj_enumDestructableCenter = null
579 real bj_enumDestructableRadius = 0
580 playercolor bj_setPlayerTargetColor = null
581 boolean bj_isUnitGroupDeadResult = true
582 boolean bj_isUnitGroupEmptyResult = true
583 boolean bj_isUnitGroupInRectResult = true
584 rect bj_isUnitGroupInRectRect = null
585 boolean bj_changeLevelShowScores = false
586 string bj_changeLevelMapName = null
587 group bj_suspendDecayFleshGroup = CreateGroup()
588 group bj_suspendDecayBoneGroup = CreateGroup()
589 timer bj_delayedSuspendDecayTimer = CreateTimer()
590 trigger bj_delayedSuspendDecayTrig = null
591 integer bj_livingPlayerUnitsTypeId = 0
592 widget bj_lastDyingWidget = null
593
594 // Random distribution vars
595 integer bj_randDistCount = 0
596 integer array bj_randDistID
597 integer array bj_randDistChance
598
599 // Last X'd vars
600 unit bj_lastCreatedUnit = null
601 item bj_lastCreatedItem = null
602 item bj_lastRemovedItem = null
603 unit bj_lastHauntedGoldMine = null
604 destructable bj_lastCreatedDestructable = null
605 group bj_lastCreatedGroup = CreateGroup()
606 fogmodifier bj_lastCreatedFogModifier = null
607 effect bj_lastCreatedEffect = null
608 weathereffect bj_lastCreatedWeatherEffect = null
609 terraindeformation bj_lastCreatedTerrainDeformation = null
610 quest bj_lastCreatedQuest = null
611 questitem bj_lastCreatedQuestItem = null
612 defeatcondition bj_lastCreatedDefeatCondition = null
613 timer bj_lastStartedTimer = CreateTimer()
614 timerdialog bj_lastCreatedTimerDialog = null
615 leaderboard bj_lastCreatedLeaderboard = null
616 multiboard bj_lastCreatedMultiboard = null
617 sound bj_lastPlayedSound = null
618 string bj_lastPlayedMusic = ""
619 real bj_lastTransmissionDuration = 0
620 gamecache bj_lastCreatedGameCache = null
621 hashtable bj_lastCreatedHashtable = null
622 unit bj_lastLoadedUnit = null
623 button bj_lastCreatedButton = null
624 unit bj_lastReplacedUnit = null
625 texttag bj_lastCreatedTextTag = null
626 lightning bj_lastCreatedLightning = null
627 image bj_lastCreatedImage = null
628 ubersplat bj_lastCreatedUbersplat = null
629
630 // Filter function vars
631 boolexpr filterIssueHauntOrderAtLocBJ = null
632 boolexpr filterEnumDestructablesInCircleBJ = null
633 boolexpr filterGetUnitsInRectOfPlayer = null
634 boolexpr filterGetUnitsOfTypeIdAll = null
635 boolexpr filterGetUnitsOfPlayerAndTypeId = null
636 boolexpr filterMeleeTrainedUnitIsHeroBJ = null
637 boolexpr filterLivingPlayerUnitsOfTypeId = null
638
639 // Memory cleanup vars
640 boolean bj_wantDestroyGroup = false
641endglobals
642
643
644
645//***************************************************************************
646//*
647//* Debugging Functions
648//*
649//***************************************************************************
650
651//===========================================================================
652function BJDebugMsg takes string msg returns nothing
653 local integer i = 0
654 loop
655 call DisplayTimedTextToPlayer(Player(i),0,0,60,msg)
656 set i = i + 1
657 exitwhen i == bj_MAX_PLAYERS
658 endloop
659endfunction
660
661
662
663//***************************************************************************
664//*
665//* Math Utility Functions
666//*
667//***************************************************************************
668
669//===========================================================================
670function RMinBJ takes real a, real b returns real
671 if (a < b) then
672 return a
673 else
674 return b
675 endif
676endfunction
677
678//===========================================================================
679function RMaxBJ takes real a, real b returns real
680 if (a < b) then
681 return b
682 else
683 return a
684 endif
685endfunction
686
687//===========================================================================
688function RAbsBJ takes real a returns real
689 if (a >= 0) then
690 return a
691 else
692 return -a
693 endif
694endfunction
695
696//===========================================================================
697function RSignBJ takes real a returns real
698 if (a >= 0.0) then
699 return 1.0
700 else
701 return -1.0
702 endif
703endfunction
704
705//===========================================================================
706function IMinBJ takes integer a, integer b returns integer
707 if (a < b) then
708 return a
709 else
710 return b
711 endif
712endfunction
713
714//===========================================================================
715function IMaxBJ takes integer a, integer b returns integer
716 if (a < b) then
717 return b
718 else
719 return a
720 endif
721endfunction
722
723//===========================================================================
724function IAbsBJ takes integer a returns integer
725 if (a >= 0) then
726 return a
727 else
728 return -a
729 endif
730endfunction
731
732//===========================================================================
733function ISignBJ takes integer a returns integer
734 if (a >= 0) then
735 return 1
736 else
737 return -1
738 endif
739endfunction
740
741//===========================================================================
742function SinBJ takes real degrees returns real
743 return Sin(degrees * bj_DEGTORAD)
744endfunction
745
746//===========================================================================
747function CosBJ takes real degrees returns real
748 return Cos(degrees * bj_DEGTORAD)
749endfunction
750
751//===========================================================================
752function TanBJ takes real degrees returns real
753 return Tan(degrees * bj_DEGTORAD)
754endfunction
755
756//===========================================================================
757function AsinBJ takes real degrees returns real
758 return Asin(degrees) * bj_RADTODEG
759endfunction
760
761//===========================================================================
762function AcosBJ takes real degrees returns real
763 return Acos(degrees) * bj_RADTODEG
764endfunction
765
766//===========================================================================
767function AtanBJ takes real degrees returns real
768 return Atan(degrees) * bj_RADTODEG
769endfunction
770
771//===========================================================================
772function Atan2BJ takes real y, real x returns real
773 return Atan2(y, x) * bj_RADTODEG
774endfunction
775
776//===========================================================================
777function AngleBetweenPoints takes location locA, location locB returns real
778 return bj_RADTODEG * Atan2(GetLocationY(locB) - GetLocationY(locA), GetLocationX(locB) - GetLocationX(locA))
779endfunction
780
781//===========================================================================
782function DistanceBetweenPoints takes location locA, location locB returns real
783 local real dx = GetLocationX(locB) - GetLocationX(locA)
784 local real dy = GetLocationY(locB) - GetLocationY(locA)
785 return SquareRoot(dx * dx + dy * dy)
786endfunction
787
788//===========================================================================
789function PolarProjectionBJ takes location source, real dist, real angle returns location
790 local real x = GetLocationX(source) + dist * Cos(angle * bj_DEGTORAD)
791 local real y = GetLocationY(source) + dist * Sin(angle * bj_DEGTORAD)
792 return Location(x, y)
793endfunction
794
795//===========================================================================
796function GetRandomDirectionDeg takes nothing returns real
797 return GetRandomReal(0, 360)
798endfunction
799
800//===========================================================================
801function GetRandomPercentageBJ takes nothing returns real
802 return GetRandomReal(0, 100)
803endfunction
804
805//===========================================================================
806function GetRandomLocInRect takes rect whichRect returns location
807 return Location(GetRandomReal(GetRectMinX(whichRect), GetRectMaxX(whichRect)), GetRandomReal(GetRectMinY(whichRect), GetRectMaxY(whichRect)))
808endfunction
809
810//===========================================================================
811// Calculate the modulus/remainder of (dividend) divided by (divisor).
812// Examples: 18 mod 5 = 3. 15 mod 5 = 0. -8 mod 5 = 2.
813//
814function ModuloInteger takes integer dividend, integer divisor returns integer
815 local integer modulus = dividend - (dividend / divisor) * divisor
816
817 // If the dividend was negative, the above modulus calculation will
818 // be negative, but within (-divisor..0). We can add (divisor) to
819 // shift this result into the desired range of (0..divisor).
820 if (modulus < 0) then
821 set modulus = modulus + divisor
822 endif
823
824 return modulus
825endfunction
826
827//===========================================================================
828// Calculate the modulus/remainder of (dividend) divided by (divisor).
829// Examples: 13.000 mod 2.500 = 0.500. -6.000 mod 2.500 = 1.500.
830//
831function ModuloReal takes real dividend, real divisor returns real
832 local real modulus = dividend - I2R(R2I(dividend / divisor)) * divisor
833
834 // If the dividend was negative, the above modulus calculation will
835 // be negative, but within (-divisor..0). We can add (divisor) to
836 // shift this result into the desired range of (0..divisor).
837 if (modulus < 0) then
838 set modulus = modulus + divisor
839 endif
840
841 return modulus
842endfunction
843
844//===========================================================================
845function OffsetLocation takes location loc, real dx, real dy returns location
846 return Location(GetLocationX(loc) + dx, GetLocationY(loc) + dy)
847endfunction
848
849//===========================================================================
850function OffsetRectBJ takes rect r, real dx, real dy returns rect
851 return Rect( GetRectMinX(r) + dx, GetRectMinY(r) + dy, GetRectMaxX(r) + dx, GetRectMaxY(r) + dy )
852endfunction
853
854//===========================================================================
855function RectFromCenterSizeBJ takes location center, real width, real height returns rect
856 local real x = GetLocationX( center )
857 local real y = GetLocationY( center )
858 return Rect( x - width*0.5, y - height*0.5, x + width*0.5, y + height*0.5 )
859endfunction
860
861//===========================================================================
862function RectContainsCoords takes rect r, real x, real y returns boolean
863 return (GetRectMinX(r) <= x) and (x <= GetRectMaxX(r)) and (GetRectMinY(r) <= y) and (y <= GetRectMaxY(r))
864endfunction
865
866//===========================================================================
867function RectContainsLoc takes rect r, location loc returns boolean
868 return RectContainsCoords(r, GetLocationX(loc), GetLocationY(loc))
869endfunction
870
871//===========================================================================
872function RectContainsUnit takes rect r, unit whichUnit returns boolean
873 return RectContainsCoords(r, GetUnitX(whichUnit), GetUnitY(whichUnit))
874endfunction
875
876//===========================================================================
877function RectContainsItem takes item whichItem, rect r returns boolean
878 if (whichItem == null) then
879 return false
880 endif
881
882 if (IsItemOwned(whichItem)) then
883 return false
884 endif
885
886 return RectContainsCoords(r, GetItemX(whichItem), GetItemY(whichItem))
887endfunction
888
889
890
891//***************************************************************************
892//*
893//* Utility Constructs
894//*
895//***************************************************************************
896
897//===========================================================================
898// Runs the trigger's actions if the trigger's conditions evaluate to true.
899//
900function ConditionalTriggerExecute takes trigger trig returns nothing
901 if TriggerEvaluate(trig) then
902 call TriggerExecute(trig)
903 endif
904endfunction
905
906//===========================================================================
907// Runs the trigger's actions if the trigger's conditions evaluate to true.
908//
909function TriggerExecuteBJ takes trigger trig, boolean checkConditions returns boolean
910 if checkConditions then
911 if not (TriggerEvaluate(trig)) then
912 return false
913 endif
914 endif
915 call TriggerExecute(trig)
916 return true
917endfunction
918
919//===========================================================================
920// Arranges for a trigger to fire almost immediately, except that the calling
921// trigger is not interrupted as is the case with a TriggerExecute call.
922// Since the trigger executes normally, its conditions are still evaluated.
923//
924function PostTriggerExecuteBJ takes trigger trig, boolean checkConditions returns boolean
925 if checkConditions then
926 if not (TriggerEvaluate(trig)) then
927 return false
928 endif
929 endif
930 call TriggerRegisterTimerEvent(trig, 0, false)
931 return true
932endfunction
933
934//===========================================================================
935// Debug - Display the contents of the trigger queue (as either null or "x"
936// for each entry).
937function QueuedTriggerCheck takes nothing returns nothing
938 local string s = "TrigQueue Check "
939 local integer i
940
941 set i = 0
942 loop
943 exitwhen i >= bj_queuedExecTotal
944 set s = s + "q[" + I2S(i) + "]="
945 if (bj_queuedExecTriggers[i] == null) then
946 set s = s + "null "
947 else
948 set s = s + "x "
949 endif
950 set i = i + 1
951 endloop
952 set s = s + "(" + I2S(bj_queuedExecTotal) + " total)"
953 call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,600,s)
954endfunction
955
956//===========================================================================
957// Searches the queue for a given trigger, returning the index of the
958// trigger within the queue if it is found, or -1 if it is not found.
959//
960function QueuedTriggerGetIndex takes trigger trig returns integer
961 // Determine which, if any, of the queued triggers is being removed.
962 local integer index = 0
963 loop
964 exitwhen index >= bj_queuedExecTotal
965 if (bj_queuedExecTriggers[index] == trig) then
966 return index
967 endif
968 set index = index + 1
969 endloop
970 return -1
971endfunction
972
973//===========================================================================
974// Removes a trigger from the trigger queue, shifting other triggers down
975// to fill the unused space. If the currently running trigger is removed
976// in this manner, this function does NOT attempt to run the next trigger.
977//
978function QueuedTriggerRemoveByIndex takes integer trigIndex returns boolean
979 local integer index
980
981 // If the to-be-removed index is out of range, fail.
982 if (trigIndex >= bj_queuedExecTotal) then
983 return false
984 endif
985
986 // Shift all queue entries down to fill in the gap.
987 set bj_queuedExecTotal = bj_queuedExecTotal - 1
988 set index = trigIndex
989 loop
990 exitwhen index >= bj_queuedExecTotal
991 set bj_queuedExecTriggers[index] = bj_queuedExecTriggers[index + 1]
992 set bj_queuedExecUseConds[index] = bj_queuedExecUseConds[index + 1]
993 set index = index + 1
994 endloop
995 return true
996endfunction
997
998//===========================================================================
999// Attempt to execute the first trigger in the queue. If it fails, remove
1000// it and execute the next one. Continue this cycle until a trigger runs,
1001// or until the queue is empty.
1002//
1003function QueuedTriggerAttemptExec takes nothing returns boolean
1004 loop
1005 exitwhen bj_queuedExecTotal == 0
1006
1007 if TriggerExecuteBJ(bj_queuedExecTriggers[0], bj_queuedExecUseConds[0]) then
1008 // Timeout the queue if it sits at the front of the queue for too long.
1009 call TimerStart(bj_queuedExecTimeoutTimer, bj_QUEUED_TRIGGER_TIMEOUT, false, null)
1010 return true
1011 endif
1012
1013 call QueuedTriggerRemoveByIndex(0)
1014 endloop
1015 return false
1016endfunction
1017
1018//===========================================================================
1019// Queues a trigger to be executed, assuring that such triggers are not
1020// executed at the same time.
1021//
1022function QueuedTriggerAddBJ takes trigger trig, boolean checkConditions returns boolean
1023 // Make sure our queue isn't full. If it is, return failure.
1024 if (bj_queuedExecTotal >= bj_MAX_QUEUED_TRIGGERS) then
1025 return false
1026 endif
1027
1028 // Add the trigger to an array of to-be-executed triggers.
1029 set bj_queuedExecTriggers[bj_queuedExecTotal] = trig
1030 set bj_queuedExecUseConds[bj_queuedExecTotal] = checkConditions
1031 set bj_queuedExecTotal = bj_queuedExecTotal + 1
1032
1033 // If this is the only trigger in the queue, run it.
1034 if (bj_queuedExecTotal == 1) then
1035 call QueuedTriggerAttemptExec()
1036 endif
1037 return true
1038endfunction
1039
1040//===========================================================================
1041// Denotes the end of a queued trigger. Be sure to call this only once per
1042// queued trigger, or risk stepping on the toes of other queued triggers.
1043//
1044function QueuedTriggerRemoveBJ takes trigger trig returns nothing
1045 local integer index
1046 local integer trigIndex
1047 local boolean trigExecuted
1048
1049 // Find the trigger's index.
1050 set trigIndex = QueuedTriggerGetIndex(trig)
1051 if (trigIndex == -1) then
1052 return
1053 endif
1054
1055 // Shuffle the other trigger entries down to fill in the gap.
1056 call QueuedTriggerRemoveByIndex(trigIndex)
1057
1058 // If we just axed the currently running trigger, run the next one.
1059 if (trigIndex == 0) then
1060 call PauseTimer(bj_queuedExecTimeoutTimer)
1061 call QueuedTriggerAttemptExec()
1062 endif
1063endfunction
1064
1065//===========================================================================
1066// Denotes the end of a queued trigger. Be sure to call this only once per
1067// queued trigger, lest you step on the toes of other queued triggers.
1068//
1069function QueuedTriggerDoneBJ takes nothing returns nothing
1070 local integer index
1071
1072 // Make sure there's something on the queue to remove.
1073 if (bj_queuedExecTotal <= 0) then
1074 return
1075 endif
1076
1077 // Remove the currently running trigger from the array.
1078 call QueuedTriggerRemoveByIndex(0)
1079
1080 // If other triggers are waiting to run, run one of them.
1081 call PauseTimer(bj_queuedExecTimeoutTimer)
1082 call QueuedTriggerAttemptExec()
1083endfunction
1084
1085//===========================================================================
1086// Empty the trigger queue.
1087//
1088function QueuedTriggerClearBJ takes nothing returns nothing
1089 call PauseTimer(bj_queuedExecTimeoutTimer)
1090 set bj_queuedExecTotal = 0
1091endfunction
1092
1093//===========================================================================
1094// Remove all but the currently executing trigger from the trigger queue.
1095//
1096function QueuedTriggerClearInactiveBJ takes nothing returns nothing
1097 set bj_queuedExecTotal = IMinBJ(bj_queuedExecTotal, 1)
1098endfunction
1099
1100//===========================================================================
1101function QueuedTriggerCountBJ takes nothing returns integer
1102 return bj_queuedExecTotal
1103endfunction
1104
1105//===========================================================================
1106function IsTriggerQueueEmptyBJ takes nothing returns boolean
1107 return bj_queuedExecTotal <= 0
1108endfunction
1109
1110//===========================================================================
1111function IsTriggerQueuedBJ takes trigger trig returns boolean
1112 return QueuedTriggerGetIndex(trig) != -1
1113endfunction
1114
1115//===========================================================================
1116function GetForLoopIndexA takes nothing returns integer
1117 return bj_forLoopAIndex
1118endfunction
1119
1120//===========================================================================
1121function SetForLoopIndexA takes integer newIndex returns nothing
1122 set bj_forLoopAIndex = newIndex
1123endfunction
1124
1125//===========================================================================
1126function GetForLoopIndexB takes nothing returns integer
1127 return bj_forLoopBIndex
1128endfunction
1129
1130//===========================================================================
1131function SetForLoopIndexB takes integer newIndex returns nothing
1132 set bj_forLoopBIndex = newIndex
1133endfunction
1134
1135//===========================================================================
1136// We can't do game-time waits, so this simulates one by starting a timer
1137// and polling until the timer expires.
1138function PolledWait takes real duration returns nothing
1139 local timer t
1140 local real timeRemaining
1141
1142 if (duration > 0) then
1143 set t = CreateTimer()
1144 call TimerStart(t, duration, false, null)
1145 loop
1146 set timeRemaining = TimerGetRemaining(t)
1147 exitwhen timeRemaining <= 0
1148
1149 // If we have a bit of time left, skip past 10% of the remaining
1150 // duration instead of checking every interval, to minimize the
1151 // polling on long waits.
1152 if (timeRemaining > bj_POLLED_WAIT_SKIP_THRESHOLD) then
1153 call TriggerSleepAction(0.1 * timeRemaining)
1154 else
1155 call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL)
1156 endif
1157 endloop
1158 call DestroyTimer(t)
1159 endif
1160endfunction
1161
1162//===========================================================================
1163function IntegerTertiaryOp takes boolean flag, integer valueA, integer valueB returns integer
1164 if flag then
1165 return valueA
1166 else
1167 return valueB
1168 endif
1169endfunction
1170
1171
1172//***************************************************************************
1173//*
1174//* General Utility Functions
1175//* These functions exist purely to make the trigger dialogs cleaner and
1176//* more comprehensible.
1177//*
1178//***************************************************************************
1179
1180//===========================================================================
1181function DoNothing takes nothing returns nothing
1182endfunction
1183
1184//===========================================================================
1185// This function does nothing. WorldEdit should should eventually ignore
1186// CommentString triggers during script generation, but until such a time,
1187// this function will serve as a stub.
1188//
1189function CommentString takes string commentString returns nothing
1190endfunction
1191
1192//===========================================================================
1193// This function returns the input string, converting it from the localized text, if necessary
1194//
1195function StringIdentity takes string theString returns string
1196 return GetLocalizedString(theString)
1197endfunction
1198
1199//===========================================================================
1200function GetBooleanAnd takes boolean valueA, boolean valueB returns boolean
1201 return valueA and valueB
1202endfunction
1203
1204//===========================================================================
1205function GetBooleanOr takes boolean valueA, boolean valueB returns boolean
1206 return valueA or valueB
1207endfunction
1208
1209//===========================================================================
1210// Converts a percentage (real, 0..100) into a scaled integer (0..max),
1211// clipping the result to 0..max in case the input is invalid.
1212//
1213function PercentToInt takes real percentage, integer max returns integer
1214 local integer result = R2I(percentage * I2R(max) * 0.01)
1215
1216 if (result < 0) then
1217 set result = 0
1218 elseif (result > max) then
1219 set result = max
1220 endif
1221
1222 return result
1223endfunction
1224
1225//===========================================================================
1226function PercentTo255 takes real percentage returns integer
1227 return PercentToInt(percentage, 255)
1228endfunction
1229
1230//===========================================================================
1231function GetTimeOfDay takes nothing returns real
1232 return GetFloatGameState(GAME_STATE_TIME_OF_DAY)
1233endfunction
1234
1235//===========================================================================
1236function SetTimeOfDay takes real whatTime returns nothing
1237 call SetFloatGameState(GAME_STATE_TIME_OF_DAY, whatTime)
1238endfunction
1239
1240//===========================================================================
1241function SetTimeOfDayScalePercentBJ takes real scalePercent returns nothing
1242 call SetTimeOfDayScale(scalePercent * 0.01)
1243endfunction
1244
1245//===========================================================================
1246function GetTimeOfDayScalePercentBJ takes nothing returns real
1247 return GetTimeOfDayScale() * 100
1248endfunction
1249
1250//===========================================================================
1251function PlaySound takes string soundName returns nothing
1252 local sound soundHandle = CreateSound(soundName, false, false, true, 12700, 12700, "")
1253 call StartSound(soundHandle)
1254 call KillSoundWhenDone(soundHandle)
1255endfunction
1256
1257//===========================================================================
1258function CompareLocationsBJ takes location A, location B returns boolean
1259 return GetLocationX(A) == GetLocationX(B) and GetLocationY(A) == GetLocationY(B)
1260endfunction
1261
1262//===========================================================================
1263function CompareRectsBJ takes rect A, rect B returns boolean
1264 return GetRectMinX(A) == GetRectMinX(B) and GetRectMinY(A) == GetRectMinY(B) and GetRectMaxX(A) == GetRectMaxX(B) and GetRectMaxY(A) == GetRectMaxY(B)
1265endfunction
1266
1267//===========================================================================
1268// Returns a square rect that exactly encompasses the specified circle.
1269//
1270function GetRectFromCircleBJ takes location center, real radius returns rect
1271 local real centerX = GetLocationX(center)
1272 local real centerY = GetLocationY(center)
1273 return Rect(centerX - radius, centerY - radius, centerX + radius, centerY + radius)
1274endfunction
1275
1276
1277
1278//***************************************************************************
1279//*
1280//* Camera Utility Functions
1281//*
1282//***************************************************************************
1283
1284//===========================================================================
1285function GetCurrentCameraSetup takes nothing returns camerasetup
1286 local camerasetup theCam = CreateCameraSetup()
1287 local real duration = 0
1288 call CameraSetupSetField(theCam, CAMERA_FIELD_TARGET_DISTANCE, GetCameraField(CAMERA_FIELD_TARGET_DISTANCE), duration)
1289 call CameraSetupSetField(theCam, CAMERA_FIELD_FARZ, GetCameraField(CAMERA_FIELD_FARZ), duration)
1290 call CameraSetupSetField(theCam, CAMERA_FIELD_ZOFFSET, GetCameraField(CAMERA_FIELD_ZOFFSET), duration)
1291 call CameraSetupSetField(theCam, CAMERA_FIELD_ANGLE_OF_ATTACK, bj_RADTODEG * GetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK), duration)
1292 call CameraSetupSetField(theCam, CAMERA_FIELD_FIELD_OF_VIEW, bj_RADTODEG * GetCameraField(CAMERA_FIELD_FIELD_OF_VIEW), duration)
1293 call CameraSetupSetField(theCam, CAMERA_FIELD_ROLL, bj_RADTODEG * GetCameraField(CAMERA_FIELD_ROLL), duration)
1294 call CameraSetupSetField(theCam, CAMERA_FIELD_ROTATION, bj_RADTODEG * GetCameraField(CAMERA_FIELD_ROTATION), duration)
1295 call CameraSetupSetDestPosition(theCam, GetCameraTargetPositionX(), GetCameraTargetPositionY(), duration)
1296 return theCam
1297endfunction
1298
1299//===========================================================================
1300function CameraSetupApplyForPlayer takes boolean doPan, camerasetup whichSetup, player whichPlayer, real duration returns nothing
1301 if (GetLocalPlayer() == whichPlayer) then
1302 // Use only local code (no net traffic) within this block to avoid desyncs.
1303 call CameraSetupApplyForceDuration(whichSetup, doPan, duration)
1304 endif
1305endfunction
1306
1307//===========================================================================
1308function CameraSetupGetFieldSwap takes camerafield whichField, camerasetup whichSetup returns real
1309 return CameraSetupGetField(whichSetup, whichField)
1310endfunction
1311
1312//===========================================================================
1313function SetCameraFieldForPlayer takes player whichPlayer, camerafield whichField, real value, real duration returns nothing
1314 if (GetLocalPlayer() == whichPlayer) then
1315 // Use only local code (no net traffic) within this block to avoid desyncs.
1316 call SetCameraField(whichField, value, duration)
1317 endif
1318endfunction
1319
1320//===========================================================================
1321function SetCameraTargetControllerNoZForPlayer takes player whichPlayer, unit whichUnit, real xoffset, real yoffset, boolean inheritOrientation returns nothing
1322 if (GetLocalPlayer() == whichPlayer) then
1323 // Use only local code (no net traffic) within this block to avoid desyncs.
1324 call SetCameraTargetController(whichUnit, xoffset, yoffset, inheritOrientation)
1325 endif
1326endfunction
1327
1328//===========================================================================
1329function SetCameraPositionForPlayer takes player whichPlayer, real x, real y returns nothing
1330 if (GetLocalPlayer() == whichPlayer) then
1331 // Use only local code (no net traffic) within this block to avoid desyncs.
1332 call SetCameraPosition(x, y)
1333 endif
1334endfunction
1335
1336//===========================================================================
1337function SetCameraPositionLocForPlayer takes player whichPlayer, location loc returns nothing
1338 if (GetLocalPlayer() == whichPlayer) then
1339 // Use only local code (no net traffic) within this block to avoid desyncs.
1340 call SetCameraPosition(GetLocationX(loc), GetLocationY(loc))
1341 endif
1342endfunction
1343
1344//===========================================================================
1345function RotateCameraAroundLocBJ takes real degrees, location loc, player whichPlayer, real duration returns nothing
1346 if (GetLocalPlayer() == whichPlayer) then
1347 // Use only local code (no net traffic) within this block to avoid desyncs.
1348 call SetCameraRotateMode(GetLocationX(loc), GetLocationY(loc), bj_DEGTORAD * degrees, duration)
1349 endif
1350endfunction
1351
1352//===========================================================================
1353function PanCameraToForPlayer takes player whichPlayer, real x, real y returns nothing
1354 if (GetLocalPlayer() == whichPlayer) then
1355 // Use only local code (no net traffic) within this block to avoid desyncs.
1356 call PanCameraTo(x, y)
1357 endif
1358endfunction
1359
1360//===========================================================================
1361function PanCameraToLocForPlayer takes player whichPlayer, location loc returns nothing
1362 if (GetLocalPlayer() == whichPlayer) then
1363 // Use only local code (no net traffic) within this block to avoid desyncs.
1364 call PanCameraTo(GetLocationX(loc), GetLocationY(loc))
1365 endif
1366endfunction
1367
1368//===========================================================================
1369function PanCameraToTimedForPlayer takes player whichPlayer, real x, real y, real duration returns nothing
1370 if (GetLocalPlayer() == whichPlayer) then
1371 // Use only local code (no net traffic) within this block to avoid desyncs.
1372 call PanCameraToTimed(x, y, duration)
1373 endif
1374endfunction
1375
1376//===========================================================================
1377function PanCameraToTimedLocForPlayer takes player whichPlayer, location loc, real duration returns nothing
1378 if (GetLocalPlayer() == whichPlayer) then
1379 // Use only local code (no net traffic) within this block to avoid desyncs.
1380 call PanCameraToTimed(GetLocationX(loc), GetLocationY(loc), duration)
1381 endif
1382endfunction
1383
1384//===========================================================================
1385function PanCameraToTimedLocWithZForPlayer takes player whichPlayer, location loc, real zOffset, real duration returns nothing
1386 if (GetLocalPlayer() == whichPlayer) then
1387 // Use only local code (no net traffic) within this block to avoid desyncs.
1388 call PanCameraToTimedWithZ(GetLocationX(loc), GetLocationY(loc), zOffset, duration)
1389 endif
1390endfunction
1391
1392//===========================================================================
1393function SmartCameraPanBJ takes player whichPlayer, location loc, real duration returns nothing
1394 local real dist
1395 if (GetLocalPlayer() == whichPlayer) then
1396 // Use only local code (no net traffic) within this block to avoid desyncs.
1397
1398 set dist = DistanceBetweenPoints(loc, GetCameraTargetPositionLoc())
1399 if (dist >= bj_SMARTPAN_TRESHOLD_SNAP) then
1400 // If the user is too far away, snap the camera.
1401 call PanCameraToTimed(GetLocationX(loc), GetLocationY(loc), 0)
1402 elseif (dist >= bj_SMARTPAN_TRESHOLD_PAN) then
1403 // If the user is moderately close, pan the camera.
1404 call PanCameraToTimed(GetLocationX(loc), GetLocationY(loc), duration)
1405 else
1406 // User is close enough, so don't touch the camera.
1407 endif
1408 endif
1409endfunction
1410
1411//===========================================================================
1412function SetCinematicCameraForPlayer takes player whichPlayer, string cameraModelFile returns nothing
1413 if (GetLocalPlayer() == whichPlayer) then
1414 // Use only local code (no net traffic) within this block to avoid desyncs.
1415 call SetCinematicCamera(cameraModelFile)
1416 endif
1417endfunction
1418
1419//===========================================================================
1420function ResetToGameCameraForPlayer takes player whichPlayer, real duration returns nothing
1421 if (GetLocalPlayer() == whichPlayer) then
1422 // Use only local code (no net traffic) within this block to avoid desyncs.
1423 call ResetToGameCamera(duration)
1424 endif
1425endfunction
1426
1427//===========================================================================
1428function CameraSetSourceNoiseForPlayer takes player whichPlayer, real magnitude, real velocity returns nothing
1429 if (GetLocalPlayer() == whichPlayer) then
1430 // Use only local code (no net traffic) within this block to avoid desyncs.
1431 call CameraSetSourceNoise(magnitude, velocity)
1432 endif
1433endfunction
1434
1435//===========================================================================
1436function CameraSetTargetNoiseForPlayer takes player whichPlayer, real magnitude, real velocity returns nothing
1437 if (GetLocalPlayer() == whichPlayer) then
1438 // Use only local code (no net traffic) within this block to avoid desyncs.
1439 call CameraSetTargetNoise(magnitude, velocity)
1440 endif
1441endfunction
1442
1443//===========================================================================
1444function CameraSetEQNoiseForPlayer takes player whichPlayer, real magnitude returns nothing
1445 local real richter = magnitude
1446 if (richter > 5.0) then
1447 set richter = 5.0
1448 endif
1449 if (richter < 2.0) then
1450 set richter = 2.0
1451 endif
1452 if (GetLocalPlayer() == whichPlayer) then
1453 // Use only local code (no net traffic) within this block to avoid desyncs.
1454 call CameraSetTargetNoiseEx(magnitude*2.0, magnitude*Pow(10,richter),true)
1455 call CameraSetSourceNoiseEx(magnitude*2.0, magnitude*Pow(10,richter),true)
1456 endif
1457endfunction
1458
1459//===========================================================================
1460function CameraClearNoiseForPlayer takes player whichPlayer returns nothing
1461 if (GetLocalPlayer() == whichPlayer) then
1462 // Use only local code (no net traffic) within this block to avoid desyncs.
1463 call CameraSetSourceNoise(0, 0)
1464 call CameraSetTargetNoise(0, 0)
1465 endif
1466endfunction
1467
1468//===========================================================================
1469// Query the current camera bounds.
1470//
1471function GetCurrentCameraBoundsMapRectBJ takes nothing returns rect
1472 return Rect(GetCameraBoundMinX(), GetCameraBoundMinY(), GetCameraBoundMaxX(), GetCameraBoundMaxY())
1473endfunction
1474
1475//===========================================================================
1476// Query the initial camera bounds, as defined at map init.
1477//
1478function GetCameraBoundsMapRect takes nothing returns rect
1479 return bj_mapInitialCameraBounds
1480endfunction
1481
1482//===========================================================================
1483// Query the playable map area, as defined at map init.
1484//
1485function GetPlayableMapRect takes nothing returns rect
1486 return bj_mapInitialPlayableArea
1487endfunction
1488
1489//===========================================================================
1490// Query the entire map area, as defined at map init.
1491//
1492function GetEntireMapRect takes nothing returns rect
1493 return GetWorldBounds()
1494endfunction
1495
1496//===========================================================================
1497function SetCameraBoundsToRect takes rect r returns nothing
1498 local real minX = GetRectMinX(r)
1499 local real minY = GetRectMinY(r)
1500 local real maxX = GetRectMaxX(r)
1501 local real maxY = GetRectMaxY(r)
1502 call SetCameraBounds(minX, minY, minX, maxY, maxX, maxY, maxX, minY)
1503endfunction
1504
1505//===========================================================================
1506function SetCameraBoundsToRectForPlayerBJ takes player whichPlayer, rect r returns nothing
1507 if (GetLocalPlayer() == whichPlayer) then
1508 // Use only local code (no net traffic) within this block to avoid desyncs.
1509 call SetCameraBoundsToRect(r)
1510 endif
1511endfunction
1512
1513//===========================================================================
1514function AdjustCameraBoundsBJ takes integer adjustMethod, real dxWest, real dxEast, real dyNorth, real dySouth returns nothing
1515 local real minX = 0
1516 local real minY = 0
1517 local real maxX = 0
1518 local real maxY = 0
1519 local real scale = 0
1520
1521 if (adjustMethod == bj_CAMERABOUNDS_ADJUST_ADD) then
1522 set scale = 1
1523 elseif (adjustMethod == bj_CAMERABOUNDS_ADJUST_SUB) then
1524 set scale = -1
1525 else
1526 // Unrecognized adjustment method - ignore the request.
1527 return
1528 endif
1529
1530 // Adjust the actual camera values
1531 set minX = GetCameraBoundMinX() - scale * dxWest
1532 set maxX = GetCameraBoundMaxX() + scale * dxEast
1533 set minY = GetCameraBoundMinY() - scale * dySouth
1534 set maxY = GetCameraBoundMaxY() + scale * dyNorth
1535
1536 // Make sure the camera bounds are still valid.
1537 if (maxX < minX) then
1538 set minX = (minX + maxX) * 0.5
1539 set maxX = minX
1540 endif
1541 if (maxY < minY) then
1542 set minY = (minY + maxY) * 0.5
1543 set maxY = minY
1544 endif
1545
1546 // Apply the new camera values.
1547 call SetCameraBounds(minX, minY, minX, maxY, maxX, maxY, maxX, minY)
1548endfunction
1549
1550//===========================================================================
1551function AdjustCameraBoundsForPlayerBJ takes integer adjustMethod, player whichPlayer, real dxWest, real dxEast, real dyNorth, real dySouth returns nothing
1552 if (GetLocalPlayer() == whichPlayer) then
1553 // Use only local code (no net traffic) within this block to avoid desyncs.
1554 call AdjustCameraBoundsBJ(adjustMethod, dxWest, dxEast, dyNorth, dySouth)
1555 endif
1556endfunction
1557
1558//===========================================================================
1559function SetCameraQuickPositionForPlayer takes player whichPlayer, real x, real y returns nothing
1560 if (GetLocalPlayer() == whichPlayer) then
1561 // Use only local code (no net traffic) within this block to avoid desyncs.
1562 call SetCameraQuickPosition(x, y)
1563 endif
1564endfunction
1565
1566//===========================================================================
1567function SetCameraQuickPositionLocForPlayer takes player whichPlayer, location loc returns nothing
1568 if (GetLocalPlayer() == whichPlayer) then
1569 // Use only local code (no net traffic) within this block to avoid desyncs.
1570 call SetCameraQuickPosition(GetLocationX(loc), GetLocationY(loc))
1571 endif
1572endfunction
1573
1574//===========================================================================
1575function SetCameraQuickPositionLoc takes location loc returns nothing
1576 call SetCameraQuickPosition(GetLocationX(loc), GetLocationY(loc))
1577endfunction
1578
1579//===========================================================================
1580function StopCameraForPlayerBJ takes player whichPlayer returns nothing
1581 if (GetLocalPlayer() == whichPlayer) then
1582 // Use only local code (no net traffic) within this block to avoid desyncs.
1583 call StopCamera()
1584 endif
1585endfunction
1586
1587//===========================================================================
1588function SetCameraOrientControllerForPlayerBJ takes player whichPlayer, unit whichUnit, real xoffset, real yoffset returns nothing
1589 if (GetLocalPlayer() == whichPlayer) then
1590 // Use only local code (no net traffic) within this block to avoid desyncs.
1591 call SetCameraOrientController(whichUnit, xoffset, yoffset)
1592 endif
1593endfunction
1594
1595//===========================================================================
1596function CameraSetSmoothingFactorBJ takes real factor returns nothing
1597 call CameraSetSmoothingFactor(factor)
1598endfunction
1599
1600//===========================================================================
1601function CameraResetSmoothingFactorBJ takes nothing returns nothing
1602 call CameraSetSmoothingFactor(0)
1603endfunction
1604
1605
1606
1607//***************************************************************************
1608//*
1609//* Text Utility Functions
1610//*
1611//***************************************************************************
1612
1613//===========================================================================
1614function DisplayTextToForce takes force toForce, string message returns nothing
1615 if (IsPlayerInForce(GetLocalPlayer(), toForce)) then
1616 // Use only local code (no net traffic) within this block to avoid desyncs.
1617 call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, message)
1618 endif
1619endfunction
1620
1621//===========================================================================
1622function DisplayTimedTextToForce takes force toForce, real duration, string message returns nothing
1623 if (IsPlayerInForce(GetLocalPlayer(), toForce)) then
1624 // Use only local code (no net traffic) within this block to avoid desyncs.
1625 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, duration, message)
1626 endif
1627endfunction
1628
1629//===========================================================================
1630function ClearTextMessagesBJ takes force toForce returns nothing
1631 if (IsPlayerInForce(GetLocalPlayer(), toForce)) then
1632 // Use only local code (no net traffic) within this block to avoid desyncs.
1633 call ClearTextMessages()
1634 endif
1635endfunction
1636
1637//===========================================================================
1638// The parameters for the API Substring function are unintuitive, so this
1639// merely performs a translation for the starting index.
1640//
1641function SubStringBJ takes string source, integer start, integer end returns string
1642 return SubString(source, start-1, end)
1643endfunction
1644
1645function GetHandleIdBJ takes handle h returns integer
1646 return GetHandleId(h)
1647endfunction
1648
1649function StringHashBJ takes string s returns integer
1650 return StringHash(s)
1651endfunction
1652
1653
1654
1655//***************************************************************************
1656//*
1657//* Event Registration Utility Functions
1658//*
1659//***************************************************************************
1660
1661//===========================================================================
1662function TriggerRegisterTimerEventPeriodic takes trigger trig, real timeout returns event
1663 return TriggerRegisterTimerEvent(trig, timeout, true)
1664endfunction
1665
1666//===========================================================================
1667function TriggerRegisterTimerEventSingle takes trigger trig, real timeout returns event
1668 return TriggerRegisterTimerEvent(trig, timeout, false)
1669endfunction
1670
1671//===========================================================================
1672function TriggerRegisterTimerExpireEventBJ takes trigger trig, timer t returns event
1673 return TriggerRegisterTimerExpireEvent(trig, t)
1674endfunction
1675
1676//===========================================================================
1677function TriggerRegisterPlayerUnitEventSimple takes trigger trig, player whichPlayer, playerunitevent whichEvent returns event
1678 return TriggerRegisterPlayerUnitEvent(trig, whichPlayer, whichEvent, null)
1679endfunction
1680
1681//===========================================================================
1682function TriggerRegisterAnyUnitEventBJ takes trigger trig, playerunitevent whichEvent returns nothing
1683 local integer index
1684
1685 set index = 0
1686 loop
1687 call TriggerRegisterPlayerUnitEvent(trig, Player(index), whichEvent, null)
1688
1689 set index = index + 1
1690 exitwhen index == bj_MAX_PLAYER_SLOTS
1691 endloop
1692endfunction
1693
1694//===========================================================================
1695function TriggerRegisterPlayerSelectionEventBJ takes trigger trig, player whichPlayer, boolean selected returns event
1696 if selected then
1697 return TriggerRegisterPlayerUnitEvent(trig, whichPlayer, EVENT_PLAYER_UNIT_SELECTED, null)
1698 else
1699 return TriggerRegisterPlayerUnitEvent(trig, whichPlayer, EVENT_PLAYER_UNIT_DESELECTED, null)
1700 endif
1701endfunction
1702
1703//===========================================================================
1704function TriggerRegisterPlayerKeyEventBJ takes trigger trig, player whichPlayer, integer keType, integer keKey returns event
1705 if (keType == bj_KEYEVENTTYPE_DEPRESS) then
1706 // Depress event - find out what key
1707 if (keKey == bj_KEYEVENTKEY_LEFT) then
1708 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ARROW_LEFT_DOWN)
1709 elseif (keKey == bj_KEYEVENTKEY_RIGHT) then
1710 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ARROW_RIGHT_DOWN)
1711 elseif (keKey == bj_KEYEVENTKEY_DOWN) then
1712 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ARROW_DOWN_DOWN)
1713 elseif (keKey == bj_KEYEVENTKEY_UP) then
1714 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ARROW_UP_DOWN)
1715 else
1716 // Unrecognized key - ignore the request and return failure.
1717 return null
1718 endif
1719 elseif (keType == bj_KEYEVENTTYPE_RELEASE) then
1720 // Release event - find out what key
1721 if (keKey == bj_KEYEVENTKEY_LEFT) then
1722 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ARROW_LEFT_UP)
1723 elseif (keKey == bj_KEYEVENTKEY_RIGHT) then
1724 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ARROW_RIGHT_UP)
1725 elseif (keKey == bj_KEYEVENTKEY_DOWN) then
1726 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ARROW_DOWN_UP)
1727 elseif (keKey == bj_KEYEVENTKEY_UP) then
1728 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ARROW_UP_UP)
1729 else
1730 // Unrecognized key - ignore the request and return failure.
1731 return null
1732 endif
1733 else
1734 // Unrecognized type - ignore the request and return failure.
1735 return null
1736 endif
1737endfunction
1738
1739//===========================================================================
1740function TriggerRegisterPlayerMouseEventBJ takes trigger trig, player whichPlayer, integer meType returns event
1741 if (meType == bj_MOUSEEVENTTYPE_DOWN) then
1742 // Mouse down event
1743 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_MOUSE_DOWN)
1744 elseif (meType == bj_MOUSEEVENTTYPE_UP) then
1745 // Mouse up event
1746 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_MOUSE_UP)
1747 elseif (meType == bj_MOUSEEVENTTYPE_MOVE) then
1748 // Mouse move event
1749 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_MOUSE_MOVE)
1750 else
1751 // Unrecognized type - ignore the request and return failure.
1752 return null
1753 endif
1754endfunction
1755
1756//===========================================================================
1757function TriggerRegisterPlayerEventVictory takes trigger trig, player whichPlayer returns event
1758 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_VICTORY)
1759endfunction
1760
1761//===========================================================================
1762function TriggerRegisterPlayerEventDefeat takes trigger trig, player whichPlayer returns event
1763 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_DEFEAT)
1764endfunction
1765
1766//===========================================================================
1767function TriggerRegisterPlayerEventLeave takes trigger trig, player whichPlayer returns event
1768 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_LEAVE)
1769endfunction
1770
1771//===========================================================================
1772function TriggerRegisterPlayerEventAllianceChanged takes trigger trig, player whichPlayer returns event
1773 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_ALLIANCE_CHANGED)
1774endfunction
1775
1776//===========================================================================
1777function TriggerRegisterPlayerEventEndCinematic takes trigger trig, player whichPlayer returns event
1778 return TriggerRegisterPlayerEvent(trig, whichPlayer, EVENT_PLAYER_END_CINEMATIC)
1779endfunction
1780
1781//===========================================================================
1782function TriggerRegisterGameStateEventTimeOfDay takes trigger trig, limitop opcode, real limitval returns event
1783 return TriggerRegisterGameStateEvent(trig, GAME_STATE_TIME_OF_DAY, opcode, limitval)
1784endfunction
1785
1786//===========================================================================
1787function TriggerRegisterEnterRegionSimple takes trigger trig, region whichRegion returns event
1788 return TriggerRegisterEnterRegion(trig, whichRegion, null)
1789endfunction
1790
1791//===========================================================================
1792function TriggerRegisterLeaveRegionSimple takes trigger trig, region whichRegion returns event
1793 return TriggerRegisterLeaveRegion(trig, whichRegion, null)
1794endfunction
1795
1796//===========================================================================
1797function TriggerRegisterEnterRectSimple takes trigger trig, rect r returns event
1798 local region rectRegion = CreateRegion()
1799 call RegionAddRect(rectRegion, r)
1800 return TriggerRegisterEnterRegion(trig, rectRegion, null)
1801endfunction
1802
1803//===========================================================================
1804function TriggerRegisterLeaveRectSimple takes trigger trig, rect r returns event
1805 local region rectRegion = CreateRegion()
1806 call RegionAddRect(rectRegion, r)
1807 return TriggerRegisterLeaveRegion(trig, rectRegion, null)
1808endfunction
1809
1810//===========================================================================
1811function TriggerRegisterDistanceBetweenUnits takes trigger trig, unit whichUnit, boolexpr condition, real range returns event
1812 return TriggerRegisterUnitInRange(trig, whichUnit, range, condition)
1813endfunction
1814
1815//===========================================================================
1816function TriggerRegisterUnitInRangeSimple takes trigger trig, real range, unit whichUnit returns event
1817 return TriggerRegisterUnitInRange(trig, whichUnit, range, null)
1818endfunction
1819
1820//===========================================================================
1821function TriggerRegisterUnitLifeEvent takes trigger trig, unit whichUnit, limitop opcode, real limitval returns event
1822 return TriggerRegisterUnitStateEvent(trig, whichUnit, UNIT_STATE_LIFE, opcode, limitval)
1823endfunction
1824
1825//===========================================================================
1826function TriggerRegisterUnitManaEvent takes trigger trig, unit whichUnit, limitop opcode, real limitval returns event
1827 return TriggerRegisterUnitStateEvent(trig, whichUnit, UNIT_STATE_MANA, opcode, limitval)
1828endfunction
1829
1830//===========================================================================
1831function TriggerRegisterDialogEventBJ takes trigger trig, dialog whichDialog returns event
1832 return TriggerRegisterDialogEvent(trig, whichDialog)
1833endfunction
1834
1835//===========================================================================
1836function TriggerRegisterShowSkillEventBJ takes trigger trig returns event
1837 return TriggerRegisterGameEvent(trig, EVENT_GAME_SHOW_SKILL)
1838endfunction
1839
1840//===========================================================================
1841function TriggerRegisterBuildSubmenuEventBJ takes trigger trig returns event
1842 return TriggerRegisterGameEvent(trig, EVENT_GAME_BUILD_SUBMENU)
1843endfunction
1844
1845//===========================================================================
1846function TriggerRegisterGameLoadedEventBJ takes trigger trig returns event
1847 return TriggerRegisterGameEvent(trig, EVENT_GAME_LOADED)
1848endfunction
1849
1850//===========================================================================
1851function TriggerRegisterGameSavedEventBJ takes trigger trig returns event
1852 return TriggerRegisterGameEvent(trig, EVENT_GAME_SAVE)
1853endfunction
1854
1855//===========================================================================
1856function RegisterDestDeathInRegionEnum takes nothing returns nothing
1857 set bj_destInRegionDiesCount = bj_destInRegionDiesCount + 1
1858 if (bj_destInRegionDiesCount <= bj_MAX_DEST_IN_REGION_EVENTS) then
1859 call TriggerRegisterDeathEvent(bj_destInRegionDiesTrig, GetEnumDestructable())
1860 endif
1861endfunction
1862
1863//===========================================================================
1864function TriggerRegisterDestDeathInRegionEvent takes trigger trig, rect r returns nothing
1865 set bj_destInRegionDiesTrig = trig
1866 set bj_destInRegionDiesCount = 0
1867 call EnumDestructablesInRect(r, null, function RegisterDestDeathInRegionEnum)
1868endfunction
1869
1870
1871
1872//***************************************************************************
1873//*
1874//* Environment Utility Functions
1875//*
1876//***************************************************************************
1877
1878//===========================================================================
1879function AddWeatherEffectSaveLast takes rect where, integer effectID returns weathereffect
1880 set bj_lastCreatedWeatherEffect = AddWeatherEffect(where, effectID)
1881 return bj_lastCreatedWeatherEffect
1882endfunction
1883
1884//===========================================================================
1885function GetLastCreatedWeatherEffect takes nothing returns weathereffect
1886 return bj_lastCreatedWeatherEffect
1887endfunction
1888
1889//===========================================================================
1890function RemoveWeatherEffectBJ takes weathereffect whichWeatherEffect returns nothing
1891 call RemoveWeatherEffect(whichWeatherEffect)
1892endfunction
1893
1894//===========================================================================
1895function TerrainDeformationCraterBJ takes real duration, boolean permanent, location where, real radius, real depth returns terraindeformation
1896 set bj_lastCreatedTerrainDeformation = TerrainDeformCrater(GetLocationX(where), GetLocationY(where), radius, depth, R2I(duration * 1000), permanent)
1897 return bj_lastCreatedTerrainDeformation
1898endfunction
1899
1900//===========================================================================
1901function TerrainDeformationRippleBJ takes real duration, boolean limitNeg, location where, real startRadius, real endRadius, real depth, real wavePeriod, real waveWidth returns terraindeformation
1902 local real spaceWave
1903 local real timeWave
1904 local real radiusRatio
1905
1906 if (endRadius <= 0 or waveWidth <= 0 or wavePeriod <= 0) then
1907 return null
1908 endif
1909
1910 set timeWave = 2.0 * duration / wavePeriod
1911 set spaceWave = 2.0 * endRadius / waveWidth
1912 set radiusRatio = startRadius / endRadius
1913
1914 set bj_lastCreatedTerrainDeformation = TerrainDeformRipple(GetLocationX(where), GetLocationY(where), endRadius, depth, R2I(duration * 1000), 1, spaceWave, timeWave, radiusRatio, limitNeg)
1915 return bj_lastCreatedTerrainDeformation
1916endfunction
1917
1918//===========================================================================
1919function TerrainDeformationWaveBJ takes real duration, location source, location target, real radius, real depth, real trailDelay returns terraindeformation
1920 local real distance
1921 local real dirX
1922 local real dirY
1923 local real speed
1924
1925 set distance = DistanceBetweenPoints(source, target)
1926 if (distance == 0 or duration <= 0) then
1927 return null
1928 endif
1929
1930 set dirX = (GetLocationX(target) - GetLocationX(source)) / distance
1931 set dirY = (GetLocationY(target) - GetLocationY(source)) / distance
1932 set speed = distance / duration
1933
1934 set bj_lastCreatedTerrainDeformation = TerrainDeformWave(GetLocationX(source), GetLocationY(source), dirX, dirY, distance, speed, radius, depth, R2I(trailDelay * 1000), 1)
1935 return bj_lastCreatedTerrainDeformation
1936endfunction
1937
1938//===========================================================================
1939function TerrainDeformationRandomBJ takes real duration, location where, real radius, real minDelta, real maxDelta, real updateInterval returns terraindeformation
1940 set bj_lastCreatedTerrainDeformation = TerrainDeformRandom(GetLocationX(where), GetLocationY(where), radius, minDelta, maxDelta, R2I(duration * 1000), R2I(updateInterval * 1000))
1941 return bj_lastCreatedTerrainDeformation
1942endfunction
1943
1944//===========================================================================
1945function TerrainDeformationStopBJ takes terraindeformation deformation, real duration returns nothing
1946 call TerrainDeformStop(deformation, R2I(duration * 1000))
1947endfunction
1948
1949//===========================================================================
1950function GetLastCreatedTerrainDeformation takes nothing returns terraindeformation
1951 return bj_lastCreatedTerrainDeformation
1952endfunction
1953
1954//===========================================================================
1955function AddLightningLoc takes string codeName, location where1, location where2 returns lightning
1956 set bj_lastCreatedLightning = AddLightningEx(codeName, true, GetLocationX(where1), GetLocationY(where1), GetLocationZ(where1), GetLocationX(where2), GetLocationY(where2), GetLocationZ(where2))
1957 return bj_lastCreatedLightning
1958endfunction
1959
1960//===========================================================================
1961function DestroyLightningBJ takes lightning whichBolt returns boolean
1962 return DestroyLightning(whichBolt)
1963endfunction
1964
1965//===========================================================================
1966function MoveLightningLoc takes lightning whichBolt, location where1, location where2 returns boolean
1967 return MoveLightningEx(whichBolt, true, GetLocationX(where1), GetLocationY(where1), GetLocationZ(where1), GetLocationX(where2), GetLocationY(where2), GetLocationZ(where2))
1968endfunction
1969
1970//===========================================================================
1971function GetLightningColorABJ takes lightning whichBolt returns real
1972 return GetLightningColorA(whichBolt)
1973endfunction
1974
1975//===========================================================================
1976function GetLightningColorRBJ takes lightning whichBolt returns real
1977 return GetLightningColorR(whichBolt)
1978endfunction
1979
1980//===========================================================================
1981function GetLightningColorGBJ takes lightning whichBolt returns real
1982 return GetLightningColorG(whichBolt)
1983endfunction
1984
1985//===========================================================================
1986function GetLightningColorBBJ takes lightning whichBolt returns real
1987 return GetLightningColorB(whichBolt)
1988endfunction
1989
1990//===========================================================================
1991function SetLightningColorBJ takes lightning whichBolt, real r, real g, real b, real a returns boolean
1992 return SetLightningColor(whichBolt, r, g, b, a)
1993endfunction
1994
1995//===========================================================================
1996function GetLastCreatedLightningBJ takes nothing returns lightning
1997 return bj_lastCreatedLightning
1998endfunction
1999
2000//===========================================================================
2001function GetAbilityEffectBJ takes integer abilcode, effecttype t, integer index returns string
2002 return GetAbilityEffectById(abilcode, t, index)
2003endfunction
2004
2005//===========================================================================
2006function GetAbilitySoundBJ takes integer abilcode, soundtype t returns string
2007 return GetAbilitySoundById(abilcode, t)
2008endfunction
2009
2010
2011//===========================================================================
2012function GetTerrainCliffLevelBJ takes location where returns integer
2013 return GetTerrainCliffLevel(GetLocationX(where), GetLocationY(where))
2014endfunction
2015
2016//===========================================================================
2017function GetTerrainTypeBJ takes location where returns integer
2018 return GetTerrainType(GetLocationX(where), GetLocationY(where))
2019endfunction
2020
2021//===========================================================================
2022function GetTerrainVarianceBJ takes location where returns integer
2023 return GetTerrainVariance(GetLocationX(where), GetLocationY(where))
2024endfunction
2025
2026//===========================================================================
2027function SetTerrainTypeBJ takes location where, integer terrainType, integer variation, integer area, integer shape returns nothing
2028 call SetTerrainType(GetLocationX(where), GetLocationY(where), terrainType, variation, area, shape)
2029endfunction
2030
2031//===========================================================================
2032function IsTerrainPathableBJ takes location where, pathingtype t returns boolean
2033 return IsTerrainPathable(GetLocationX(where), GetLocationY(where), t)
2034endfunction
2035
2036//===========================================================================
2037function SetTerrainPathableBJ takes location where, pathingtype t, boolean flag returns nothing
2038 call SetTerrainPathable(GetLocationX(where), GetLocationY(where), t, flag)
2039endfunction
2040
2041//===========================================================================
2042function SetWaterBaseColorBJ takes real red, real green, real blue, real transparency returns nothing
2043 call SetWaterBaseColor(PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
2044endfunction
2045
2046//===========================================================================
2047function CreateFogModifierRectSimple takes player whichPlayer, fogstate whichFogState, rect r, boolean afterUnits returns fogmodifier
2048 set bj_lastCreatedFogModifier = CreateFogModifierRect(whichPlayer, whichFogState, r, true, afterUnits)
2049 return bj_lastCreatedFogModifier
2050endfunction
2051
2052//===========================================================================
2053function CreateFogModifierRadiusLocSimple takes player whichPlayer, fogstate whichFogState, location center, real radius, boolean afterUnits returns fogmodifier
2054 set bj_lastCreatedFogModifier = CreateFogModifierRadiusLoc(whichPlayer, whichFogState, center, radius, true, afterUnits)
2055 return bj_lastCreatedFogModifier
2056endfunction
2057
2058//===========================================================================
2059// Version of CreateFogModifierRect that assumes use of sharedVision and
2060// gives the option of immediately enabling the modifier, so that triggers
2061// can default to modifiers that are immediately enabled.
2062//
2063function CreateFogModifierRectBJ takes boolean enabled, player whichPlayer, fogstate whichFogState, rect r returns fogmodifier
2064 set bj_lastCreatedFogModifier = CreateFogModifierRect(whichPlayer, whichFogState, r, true, false)
2065 if enabled then
2066 call FogModifierStart(bj_lastCreatedFogModifier)
2067 endif
2068 return bj_lastCreatedFogModifier
2069endfunction
2070
2071//===========================================================================
2072// Version of CreateFogModifierRadius that assumes use of sharedVision and
2073// gives the option of immediately enabling the modifier, so that triggers
2074// can default to modifiers that are immediately enabled.
2075//
2076function CreateFogModifierRadiusLocBJ takes boolean enabled, player whichPlayer, fogstate whichFogState, location center, real radius returns fogmodifier
2077 set bj_lastCreatedFogModifier = CreateFogModifierRadiusLoc(whichPlayer, whichFogState, center, radius, true, false)
2078 if enabled then
2079 call FogModifierStart(bj_lastCreatedFogModifier)
2080 endif
2081 return bj_lastCreatedFogModifier
2082endfunction
2083
2084//===========================================================================
2085function GetLastCreatedFogModifier takes nothing returns fogmodifier
2086 return bj_lastCreatedFogModifier
2087endfunction
2088
2089//===========================================================================
2090function FogEnableOn takes nothing returns nothing
2091 call FogEnable(true)
2092endfunction
2093
2094//===========================================================================
2095function FogEnableOff takes nothing returns nothing
2096 call FogEnable(false)
2097endfunction
2098
2099//===========================================================================
2100function FogMaskEnableOn takes nothing returns nothing
2101 call FogMaskEnable(true)
2102endfunction
2103
2104//===========================================================================
2105function FogMaskEnableOff takes nothing returns nothing
2106 call FogMaskEnable(false)
2107endfunction
2108
2109//===========================================================================
2110function UseTimeOfDayBJ takes boolean flag returns nothing
2111 call SuspendTimeOfDay(not flag)
2112endfunction
2113
2114//===========================================================================
2115function SetTerrainFogExBJ takes integer style, real zstart, real zend, real density, real red, real green, real blue returns nothing
2116 call SetTerrainFogEx(style, zstart, zend, density, red * 0.01, green * 0.01, blue * 0.01)
2117endfunction
2118
2119//===========================================================================
2120function ResetTerrainFogBJ takes nothing returns nothing
2121 call ResetTerrainFog()
2122endfunction
2123
2124//===========================================================================
2125function SetDoodadAnimationBJ takes string animName, integer doodadID, real radius, location center returns nothing
2126 call SetDoodadAnimation(GetLocationX(center), GetLocationY(center), radius, doodadID, false, animName, false)
2127endfunction
2128
2129//===========================================================================
2130function SetDoodadAnimationRectBJ takes string animName, integer doodadID, rect r returns nothing
2131 call SetDoodadAnimationRect(r, doodadID, animName, false)
2132endfunction
2133
2134//===========================================================================
2135function AddUnitAnimationPropertiesBJ takes boolean add, string animProperties, unit whichUnit returns nothing
2136 call AddUnitAnimationProperties(whichUnit, animProperties, add)
2137endfunction
2138
2139
2140//============================================================================
2141function CreateImageBJ takes string file, real size, location where, real zOffset, integer imageType returns image
2142 set bj_lastCreatedImage = CreateImage(file, size, size, size, GetLocationX(where), GetLocationY(where), zOffset, 0, 0, 0, imageType)
2143 return bj_lastCreatedImage
2144endfunction
2145
2146//============================================================================
2147function ShowImageBJ takes boolean flag, image whichImage returns nothing
2148 call ShowImage(whichImage, flag)
2149endfunction
2150
2151//============================================================================
2152function SetImagePositionBJ takes image whichImage, location where, real zOffset returns nothing
2153 call SetImagePosition(whichImage, GetLocationX(where), GetLocationY(where), zOffset)
2154endfunction
2155
2156//============================================================================
2157function SetImageColorBJ takes image whichImage, real red, real green, real blue, real alpha returns nothing
2158 call SetImageColor(whichImage, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-alpha))
2159endfunction
2160
2161//============================================================================
2162function GetLastCreatedImage takes nothing returns image
2163 return bj_lastCreatedImage
2164endfunction
2165
2166//============================================================================
2167function CreateUbersplatBJ takes location where, string name, real red, real green, real blue, real alpha, boolean forcePaused, boolean noBirthTime returns ubersplat
2168 set bj_lastCreatedUbersplat = CreateUbersplat(GetLocationX(where), GetLocationY(where), name, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-alpha), forcePaused, noBirthTime)
2169 return bj_lastCreatedUbersplat
2170endfunction
2171
2172//============================================================================
2173function ShowUbersplatBJ takes boolean flag, ubersplat whichSplat returns nothing
2174 call ShowUbersplat(whichSplat, flag)
2175endfunction
2176
2177//============================================================================
2178function GetLastCreatedUbersplat takes nothing returns ubersplat
2179 return bj_lastCreatedUbersplat
2180endfunction
2181
2182
2183//***************************************************************************
2184//*
2185//* Sound Utility Functions
2186//*
2187//***************************************************************************
2188
2189//===========================================================================
2190function PlaySoundBJ takes sound soundHandle returns nothing
2191 set bj_lastPlayedSound = soundHandle
2192 if (soundHandle != null) then
2193 call StartSound(soundHandle)
2194 endif
2195endfunction
2196
2197//===========================================================================
2198function StopSoundBJ takes sound soundHandle, boolean fadeOut returns nothing
2199 call StopSound(soundHandle, false, fadeOut)
2200endfunction
2201
2202//===========================================================================
2203function SetSoundVolumeBJ takes sound soundHandle, real volumePercent returns nothing
2204 call SetSoundVolume(soundHandle, PercentToInt(volumePercent, 127))
2205endfunction
2206
2207//===========================================================================
2208function SetSoundOffsetBJ takes real newOffset, sound soundHandle returns nothing
2209 call SetSoundPlayPosition(soundHandle, R2I(newOffset * 1000))
2210endfunction
2211
2212//===========================================================================
2213function SetSoundDistanceCutoffBJ takes sound soundHandle, real cutoff returns nothing
2214 call SetSoundDistanceCutoff(soundHandle, cutoff)
2215endfunction
2216
2217//===========================================================================
2218function SetSoundPitchBJ takes sound soundHandle, real pitch returns nothing
2219 call SetSoundPitch(soundHandle, pitch)
2220endfunction
2221
2222//===========================================================================
2223function SetSoundPositionLocBJ takes sound soundHandle, location loc, real z returns nothing
2224 call SetSoundPosition(soundHandle, GetLocationX(loc), GetLocationY(loc), z)
2225endfunction
2226
2227//===========================================================================
2228function AttachSoundToUnitBJ takes sound soundHandle, unit whichUnit returns nothing
2229 call AttachSoundToUnit(soundHandle, whichUnit)
2230endfunction
2231
2232//===========================================================================
2233function SetSoundConeAnglesBJ takes sound soundHandle, real inside, real outside, real outsideVolumePercent returns nothing
2234 call SetSoundConeAngles(soundHandle, inside, outside, PercentToInt(outsideVolumePercent, 127))
2235endfunction
2236
2237//===========================================================================
2238function KillSoundWhenDoneBJ takes sound soundHandle returns nothing
2239 call KillSoundWhenDone(soundHandle)
2240endfunction
2241
2242//===========================================================================
2243function PlaySoundAtPointBJ takes sound soundHandle, real volumePercent, location loc, real z returns nothing
2244 call SetSoundPositionLocBJ(soundHandle, loc, z)
2245 call SetSoundVolumeBJ(soundHandle, volumePercent)
2246 call PlaySoundBJ(soundHandle)
2247endfunction
2248
2249//===========================================================================
2250function PlaySoundOnUnitBJ takes sound soundHandle, real volumePercent, unit whichUnit returns nothing
2251 call AttachSoundToUnitBJ(soundHandle, whichUnit)
2252 call SetSoundVolumeBJ(soundHandle, volumePercent)
2253 call PlaySoundBJ(soundHandle)
2254endfunction
2255
2256//===========================================================================
2257function PlaySoundFromOffsetBJ takes sound soundHandle, real volumePercent, real startingOffset returns nothing
2258 call SetSoundVolumeBJ(soundHandle, volumePercent)
2259 call PlaySoundBJ(soundHandle)
2260 call SetSoundOffsetBJ(startingOffset, soundHandle)
2261endfunction
2262
2263//===========================================================================
2264function PlayMusicBJ takes string musicFileName returns nothing
2265 set bj_lastPlayedMusic = musicFileName
2266 call PlayMusic(musicFileName)
2267endfunction
2268
2269//===========================================================================
2270function PlayMusicExBJ takes string musicFileName, real startingOffset, real fadeInTime returns nothing
2271 set bj_lastPlayedMusic = musicFileName
2272 call PlayMusicEx(musicFileName, R2I(startingOffset * 1000), R2I(fadeInTime * 1000))
2273endfunction
2274
2275//===========================================================================
2276function SetMusicOffsetBJ takes real newOffset returns nothing
2277 call SetMusicPlayPosition(R2I(newOffset * 1000))
2278endfunction
2279
2280//===========================================================================
2281function PlayThematicMusicBJ takes string musicName returns nothing
2282 call PlayThematicMusic(musicName)
2283endfunction
2284
2285//===========================================================================
2286function PlayThematicMusicExBJ takes string musicName, real startingOffset returns nothing
2287 call PlayThematicMusicEx(musicName, R2I(startingOffset * 1000))
2288endfunction
2289
2290//===========================================================================
2291function SetThematicMusicOffsetBJ takes real newOffset returns nothing
2292 call SetThematicMusicPlayPosition(R2I(newOffset * 1000))
2293endfunction
2294
2295//===========================================================================
2296function EndThematicMusicBJ takes nothing returns nothing
2297 call EndThematicMusic()
2298endfunction
2299
2300//===========================================================================
2301function StopMusicBJ takes boolean fadeOut returns nothing
2302 call StopMusic(fadeOut)
2303endfunction
2304
2305//===========================================================================
2306function ResumeMusicBJ takes nothing returns nothing
2307 call ResumeMusic()
2308endfunction
2309
2310//===========================================================================
2311function SetMusicVolumeBJ takes real volumePercent returns nothing
2312 call SetMusicVolume(PercentToInt(volumePercent, 127))
2313endfunction
2314
2315//===========================================================================
2316function GetSoundDurationBJ takes sound soundHandle returns real
2317 if (soundHandle == null) then
2318 return bj_NOTHING_SOUND_DURATION
2319 else
2320 return I2R(GetSoundDuration(soundHandle)) * 0.001
2321 endif
2322endfunction
2323
2324//===========================================================================
2325function GetSoundFileDurationBJ takes string musicFileName returns real
2326 return I2R(GetSoundFileDuration(musicFileName)) * 0.001
2327endfunction
2328
2329//===========================================================================
2330function GetLastPlayedSound takes nothing returns sound
2331 return bj_lastPlayedSound
2332endfunction
2333
2334//===========================================================================
2335function GetLastPlayedMusic takes nothing returns string
2336 return bj_lastPlayedMusic
2337endfunction
2338
2339//===========================================================================
2340function VolumeGroupSetVolumeBJ takes volumegroup vgroup, real percent returns nothing
2341 call VolumeGroupSetVolume(vgroup, percent * 0.01)
2342endfunction
2343
2344//===========================================================================
2345function SetCineModeVolumeGroupsImmediateBJ takes nothing returns nothing
2346 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_UNITMOVEMENT, bj_CINEMODE_VOLUME_UNITMOVEMENT)
2347 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_UNITSOUNDS, bj_CINEMODE_VOLUME_UNITSOUNDS)
2348 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_COMBAT, bj_CINEMODE_VOLUME_COMBAT)
2349 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_SPELLS, bj_CINEMODE_VOLUME_SPELLS)
2350 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_UI, bj_CINEMODE_VOLUME_UI)
2351 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_MUSIC, bj_CINEMODE_VOLUME_MUSIC)
2352 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_AMBIENTSOUNDS, bj_CINEMODE_VOLUME_AMBIENTSOUNDS)
2353 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_FIRE, bj_CINEMODE_VOLUME_FIRE)
2354endfunction
2355
2356//===========================================================================
2357function SetCineModeVolumeGroupsBJ takes nothing returns nothing
2358 // Delay the request if it occurs at map init.
2359 if bj_gameStarted then
2360 call SetCineModeVolumeGroupsImmediateBJ()
2361 else
2362 call TimerStart(bj_volumeGroupsTimer, bj_GAME_STARTED_THRESHOLD, false, function SetCineModeVolumeGroupsImmediateBJ)
2363 endif
2364endfunction
2365
2366//===========================================================================
2367function SetSpeechVolumeGroupsImmediateBJ takes nothing returns nothing
2368 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_UNITMOVEMENT, bj_SPEECH_VOLUME_UNITMOVEMENT)
2369 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_UNITSOUNDS, bj_SPEECH_VOLUME_UNITSOUNDS)
2370 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_COMBAT, bj_SPEECH_VOLUME_COMBAT)
2371 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_SPELLS, bj_SPEECH_VOLUME_SPELLS)
2372 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_UI, bj_SPEECH_VOLUME_UI)
2373 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_MUSIC, bj_SPEECH_VOLUME_MUSIC)
2374 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_AMBIENTSOUNDS, bj_SPEECH_VOLUME_AMBIENTSOUNDS)
2375 call VolumeGroupSetVolume(SOUND_VOLUMEGROUP_FIRE, bj_SPEECH_VOLUME_FIRE)
2376endfunction
2377
2378//===========================================================================
2379function SetSpeechVolumeGroupsBJ takes nothing returns nothing
2380 // Delay the request if it occurs at map init.
2381 if bj_gameStarted then
2382 call SetSpeechVolumeGroupsImmediateBJ()
2383 else
2384 call TimerStart(bj_volumeGroupsTimer, bj_GAME_STARTED_THRESHOLD, false, function SetSpeechVolumeGroupsImmediateBJ)
2385 endif
2386endfunction
2387
2388//===========================================================================
2389function VolumeGroupResetImmediateBJ takes nothing returns nothing
2390 call VolumeGroupReset()
2391endfunction
2392
2393//===========================================================================
2394function VolumeGroupResetBJ takes nothing returns nothing
2395 // Delay the request if it occurs at map init.
2396 if bj_gameStarted then
2397 call VolumeGroupResetImmediateBJ()
2398 else
2399 call TimerStart(bj_volumeGroupsTimer, bj_GAME_STARTED_THRESHOLD, false, function VolumeGroupResetImmediateBJ)
2400 endif
2401endfunction
2402
2403//===========================================================================
2404function GetSoundIsPlayingBJ takes sound soundHandle returns boolean
2405 return GetSoundIsLoading(soundHandle) or GetSoundIsPlaying(soundHandle)
2406endfunction
2407
2408//===========================================================================
2409function WaitForSoundBJ takes sound soundHandle, real offset returns nothing
2410 call TriggerWaitForSound( soundHandle, offset )
2411endfunction
2412
2413//===========================================================================
2414function SetMapMusicIndexedBJ takes string musicName, integer index returns nothing
2415 call SetMapMusic(musicName, false, index)
2416endfunction
2417
2418//===========================================================================
2419function SetMapMusicRandomBJ takes string musicName returns nothing
2420 call SetMapMusic(musicName, true, 0)
2421endfunction
2422
2423//===========================================================================
2424function ClearMapMusicBJ takes nothing returns nothing
2425 call ClearMapMusic()
2426endfunction
2427
2428//===========================================================================
2429function SetStackedSoundBJ takes boolean add, sound soundHandle, rect r returns nothing
2430 local real width = GetRectMaxX(r) - GetRectMinX(r)
2431 local real height = GetRectMaxY(r) - GetRectMinY(r)
2432
2433 call SetSoundPosition(soundHandle, GetRectCenterX(r), GetRectCenterY(r), 0)
2434 if add then
2435 call RegisterStackedSound(soundHandle, true, width, height)
2436 else
2437 call UnregisterStackedSound(soundHandle, true, width, height)
2438 endif
2439endfunction
2440
2441//===========================================================================
2442function StartSoundForPlayerBJ takes player whichPlayer, sound soundHandle returns nothing
2443 if (whichPlayer == GetLocalPlayer()) then
2444 call StartSound(soundHandle)
2445 endif
2446endfunction
2447
2448//===========================================================================
2449function VolumeGroupSetVolumeForPlayerBJ takes player whichPlayer, volumegroup vgroup, real scale returns nothing
2450 if (GetLocalPlayer() == whichPlayer) then
2451 call VolumeGroupSetVolume(vgroup, scale)
2452 endif
2453endfunction
2454
2455//===========================================================================
2456function EnableDawnDusk takes boolean flag returns nothing
2457 set bj_useDawnDuskSounds = flag
2458endfunction
2459
2460//===========================================================================
2461function IsDawnDuskEnabled takes nothing returns boolean
2462 return bj_useDawnDuskSounds
2463endfunction
2464
2465
2466
2467//***************************************************************************
2468//*
2469//* Day/Night ambient sounds
2470//*
2471//***************************************************************************
2472
2473//===========================================================================
2474function SetAmbientDaySound takes string inLabel returns nothing
2475 local real ToD
2476
2477 // Stop old sound, if necessary
2478 if (bj_dayAmbientSound != null) then
2479 call StopSound(bj_dayAmbientSound, true, true)
2480 endif
2481
2482 // Create new sound
2483 set bj_dayAmbientSound = CreateMIDISound(inLabel, 20, 20)
2484
2485 // Start the sound if necessary, based on current time
2486 set ToD = GetTimeOfDay()
2487 if (ToD >= bj_TOD_DAWN and ToD < bj_TOD_DUSK) then
2488 call StartSound(bj_dayAmbientSound)
2489 endif
2490endfunction
2491
2492//===========================================================================
2493function SetAmbientNightSound takes string inLabel returns nothing
2494 local real ToD
2495
2496 // Stop old sound, if necessary
2497 if (bj_nightAmbientSound != null) then
2498 call StopSound(bj_nightAmbientSound, true, true)
2499 endif
2500
2501 // Create new sound
2502 set bj_nightAmbientSound = CreateMIDISound(inLabel, 20, 20)
2503
2504 // Start the sound if necessary, based on current time
2505 set ToD = GetTimeOfDay()
2506 if (ToD < bj_TOD_DAWN or ToD >= bj_TOD_DUSK) then
2507 call StartSound(bj_nightAmbientSound)
2508 endif
2509endfunction
2510
2511
2512
2513//***************************************************************************
2514//*
2515//* Special Effect Utility Functions
2516//*
2517//***************************************************************************
2518
2519//===========================================================================
2520function AddSpecialEffectLocBJ takes location where, string modelName returns effect
2521 set bj_lastCreatedEffect = AddSpecialEffectLoc(modelName, where)
2522 return bj_lastCreatedEffect
2523endfunction
2524
2525//===========================================================================
2526function AddSpecialEffectTargetUnitBJ takes string attachPointName, widget targetWidget, string modelName returns effect
2527 set bj_lastCreatedEffect = AddSpecialEffectTarget(modelName, targetWidget, attachPointName)
2528 return bj_lastCreatedEffect
2529endfunction
2530
2531//===========================================================================
2532// Two distinct trigger actions can't share the same function name, so this
2533// dummy function simply mimics the behavior of an existing call.
2534//
2535// Commented out - Destructibles have no attachment points.
2536//
2537//function AddSpecialEffectTargetDestructableBJ takes string attachPointName, widget targetWidget, string modelName returns effect
2538// return AddSpecialEffectTargetUnitBJ(attachPointName, targetWidget, modelName)
2539//endfunction
2540
2541//===========================================================================
2542// Two distinct trigger actions can't share the same function name, so this
2543// dummy function simply mimics the behavior of an existing call.
2544//
2545// Commented out - Items have no attachment points.
2546//
2547//function AddSpecialEffectTargetItemBJ takes string attachPointName, widget targetWidget, string modelName returns effect
2548// return AddSpecialEffectTargetUnitBJ(attachPointName, targetWidget, modelName)
2549//endfunction
2550
2551//===========================================================================
2552function DestroyEffectBJ takes effect whichEffect returns nothing
2553 call DestroyEffect(whichEffect)
2554endfunction
2555
2556//===========================================================================
2557function GetLastCreatedEffectBJ takes nothing returns effect
2558 return bj_lastCreatedEffect
2559endfunction
2560
2561
2562
2563//***************************************************************************
2564//*
2565//* Hero and Item Utility Functions
2566//*
2567//***************************************************************************
2568
2569//===========================================================================
2570function GetItemLoc takes item whichItem returns location
2571 return Location(GetItemX(whichItem), GetItemY(whichItem))
2572endfunction
2573
2574//===========================================================================
2575function GetItemLifeBJ takes widget whichWidget returns real
2576 return GetWidgetLife(whichWidget)
2577endfunction
2578
2579//===========================================================================
2580function SetItemLifeBJ takes widget whichWidget, real life returns nothing
2581 call SetWidgetLife(whichWidget, life)
2582endfunction
2583
2584//===========================================================================
2585function AddHeroXPSwapped takes integer xpToAdd, unit whichHero, boolean showEyeCandy returns nothing
2586 call AddHeroXP(whichHero, xpToAdd, showEyeCandy)
2587endfunction
2588
2589//===========================================================================
2590function SetHeroLevelBJ takes unit whichHero, integer newLevel, boolean showEyeCandy returns nothing
2591 local integer oldLevel = GetHeroLevel(whichHero)
2592
2593 if (newLevel > oldLevel) then
2594 call SetHeroLevel(whichHero, newLevel, showEyeCandy)
2595 elseif (newLevel < oldLevel) then
2596 call UnitStripHeroLevel(whichHero, oldLevel - newLevel)
2597 else
2598 // No change in level - ignore the request.
2599 endif
2600endfunction
2601
2602//===========================================================================
2603function DecUnitAbilityLevelSwapped takes integer abilcode, unit whichUnit returns integer
2604 return DecUnitAbilityLevel(whichUnit, abilcode)
2605endfunction
2606
2607//===========================================================================
2608function IncUnitAbilityLevelSwapped takes integer abilcode, unit whichUnit returns integer
2609 return IncUnitAbilityLevel(whichUnit, abilcode)
2610endfunction
2611
2612//===========================================================================
2613function SetUnitAbilityLevelSwapped takes integer abilcode, unit whichUnit, integer level returns integer
2614 return SetUnitAbilityLevel(whichUnit, abilcode, level)
2615endfunction
2616
2617//===========================================================================
2618function GetUnitAbilityLevelSwapped takes integer abilcode, unit whichUnit returns integer
2619 return GetUnitAbilityLevel(whichUnit, abilcode)
2620endfunction
2621
2622//===========================================================================
2623function UnitHasBuffBJ takes unit whichUnit, integer buffcode returns boolean
2624 return (GetUnitAbilityLevel(whichUnit, buffcode) > 0)
2625endfunction
2626
2627//===========================================================================
2628function UnitRemoveBuffBJ takes integer buffcode, unit whichUnit returns boolean
2629 return UnitRemoveAbility(whichUnit, buffcode)
2630endfunction
2631
2632//===========================================================================
2633function UnitAddItemSwapped takes item whichItem, unit whichHero returns boolean
2634 return UnitAddItem(whichHero, whichItem)
2635endfunction
2636
2637//===========================================================================
2638function UnitAddItemByIdSwapped takes integer itemId, unit whichHero returns item
2639 // Create the item at the hero's feet first, and then give it to him.
2640 // This is to ensure that the item will be left at the hero's feet if
2641 // his inventory is full.
2642 set bj_lastCreatedItem = CreateItem(itemId, GetUnitX(whichHero), GetUnitY(whichHero))
2643 call UnitAddItem(whichHero, bj_lastCreatedItem)
2644 return bj_lastCreatedItem
2645endfunction
2646
2647//===========================================================================
2648function UnitRemoveItemSwapped takes item whichItem, unit whichHero returns nothing
2649 set bj_lastRemovedItem = whichItem
2650 call UnitRemoveItem(whichHero, whichItem)
2651endfunction
2652
2653//===========================================================================
2654// Translates 0-based slot indices to 1-based slot indices.
2655//
2656function UnitRemoveItemFromSlotSwapped takes integer itemSlot, unit whichHero returns item
2657 set bj_lastRemovedItem = UnitRemoveItemFromSlot(whichHero, itemSlot-1)
2658 return bj_lastRemovedItem
2659endfunction
2660
2661//===========================================================================
2662function CreateItemLoc takes integer itemId, location loc returns item
2663 set bj_lastCreatedItem = CreateItem(itemId, GetLocationX(loc), GetLocationY(loc))
2664 return bj_lastCreatedItem
2665endfunction
2666
2667//===========================================================================
2668function GetLastCreatedItem takes nothing returns item
2669 return bj_lastCreatedItem
2670endfunction
2671
2672//===========================================================================
2673function GetLastRemovedItem takes nothing returns item
2674 return bj_lastRemovedItem
2675endfunction
2676
2677//===========================================================================
2678function SetItemPositionLoc takes item whichItem, location loc returns nothing
2679 call SetItemPosition(whichItem, GetLocationX(loc), GetLocationY(loc))
2680endfunction
2681
2682//===========================================================================
2683function GetLearnedSkillBJ takes nothing returns integer
2684 return GetLearnedSkill()
2685endfunction
2686
2687//===========================================================================
2688function SuspendHeroXPBJ takes boolean flag, unit whichHero returns nothing
2689 call SuspendHeroXP(whichHero, not flag)
2690endfunction
2691
2692//===========================================================================
2693function SetPlayerHandicapXPBJ takes player whichPlayer, real handicapPercent returns nothing
2694 call SetPlayerHandicapXP(whichPlayer, handicapPercent * 0.01)
2695endfunction
2696
2697//===========================================================================
2698function GetPlayerHandicapXPBJ takes player whichPlayer returns real
2699 return GetPlayerHandicapXP(whichPlayer) * 100
2700endfunction
2701
2702//===========================================================================
2703function SetPlayerHandicapBJ takes player whichPlayer, real handicapPercent returns nothing
2704 call SetPlayerHandicap(whichPlayer, handicapPercent * 0.01)
2705endfunction
2706
2707//===========================================================================
2708function GetPlayerHandicapBJ takes player whichPlayer returns real
2709 return GetPlayerHandicap(whichPlayer) * 100
2710endfunction
2711
2712//===========================================================================
2713function GetHeroStatBJ takes integer whichStat, unit whichHero, boolean includeBonuses returns integer
2714 if (whichStat == bj_HEROSTAT_STR) then
2715 return GetHeroStr(whichHero, includeBonuses)
2716 elseif (whichStat == bj_HEROSTAT_AGI) then
2717 return GetHeroAgi(whichHero, includeBonuses)
2718 elseif (whichStat == bj_HEROSTAT_INT) then
2719 return GetHeroInt(whichHero, includeBonuses)
2720 else
2721 // Unrecognized hero stat - return 0
2722 return 0
2723 endif
2724endfunction
2725
2726//===========================================================================
2727function SetHeroStat takes unit whichHero, integer whichStat, integer value returns nothing
2728 // Ignore requests for negative hero stats.
2729 if (value <= 0) then
2730 return
2731 endif
2732
2733 if (whichStat == bj_HEROSTAT_STR) then
2734 call SetHeroStr(whichHero, value, true)
2735 elseif (whichStat == bj_HEROSTAT_AGI) then
2736 call SetHeroAgi(whichHero, value, true)
2737 elseif (whichStat == bj_HEROSTAT_INT) then
2738 call SetHeroInt(whichHero, value, true)
2739 else
2740 // Unrecognized hero stat - ignore the request.
2741 endif
2742endfunction
2743
2744//===========================================================================
2745function ModifyHeroStat takes integer whichStat, unit whichHero, integer modifyMethod, integer value returns nothing
2746 if (modifyMethod == bj_MODIFYMETHOD_ADD) then
2747 call SetHeroStat(whichHero, whichStat, GetHeroStatBJ(whichStat, whichHero, false) + value)
2748 elseif (modifyMethod == bj_MODIFYMETHOD_SUB) then
2749 call SetHeroStat(whichHero, whichStat, GetHeroStatBJ(whichStat, whichHero, false) - value)
2750 elseif (modifyMethod == bj_MODIFYMETHOD_SET) then
2751 call SetHeroStat(whichHero, whichStat, value)
2752 else
2753 // Unrecognized modification method - ignore the request.
2754 endif
2755endfunction
2756
2757//===========================================================================
2758function ModifyHeroSkillPoints takes unit whichHero, integer modifyMethod, integer value returns boolean
2759 if (modifyMethod == bj_MODIFYMETHOD_ADD) then
2760 return UnitModifySkillPoints(whichHero, value)
2761 elseif (modifyMethod == bj_MODIFYMETHOD_SUB) then
2762 return UnitModifySkillPoints(whichHero, -value)
2763 elseif (modifyMethod == bj_MODIFYMETHOD_SET) then
2764 return UnitModifySkillPoints(whichHero, value - GetHeroSkillPoints(whichHero))
2765 else
2766 // Unrecognized modification method - ignore the request and return failure.
2767 return false
2768 endif
2769endfunction
2770
2771//===========================================================================
2772function UnitDropItemPointBJ takes unit whichUnit, item whichItem, real x, real y returns boolean
2773 return UnitDropItemPoint(whichUnit, whichItem, x, y)
2774endfunction
2775
2776//===========================================================================
2777function UnitDropItemPointLoc takes unit whichUnit, item whichItem, location loc returns boolean
2778 return UnitDropItemPoint(whichUnit, whichItem, GetLocationX(loc), GetLocationY(loc))
2779endfunction
2780
2781//===========================================================================
2782function UnitDropItemSlotBJ takes unit whichUnit, item whichItem, integer slot returns boolean
2783 return UnitDropItemSlot(whichUnit, whichItem, slot-1)
2784endfunction
2785
2786//===========================================================================
2787function UnitDropItemTargetBJ takes unit whichUnit, item whichItem, widget target returns boolean
2788 return UnitDropItemTarget(whichUnit, whichItem, target)
2789endfunction
2790
2791//===========================================================================
2792// Two distinct trigger actions can't share the same function name, so this
2793// dummy function simply mimics the behavior of an existing call.
2794//
2795function UnitUseItemDestructable takes unit whichUnit, item whichItem, widget target returns boolean
2796 return UnitUseItemTarget(whichUnit, whichItem, target)
2797endfunction
2798
2799//===========================================================================
2800function UnitUseItemPointLoc takes unit whichUnit, item whichItem, location loc returns boolean
2801 return UnitUseItemPoint(whichUnit, whichItem, GetLocationX(loc), GetLocationY(loc))
2802endfunction
2803
2804//===========================================================================
2805// Translates 0-based slot indices to 1-based slot indices.
2806//
2807function UnitItemInSlotBJ takes unit whichUnit, integer itemSlot returns item
2808 return UnitItemInSlot(whichUnit, itemSlot-1)
2809endfunction
2810
2811//===========================================================================
2812// Translates 0-based slot indices to 1-based slot indices.
2813//
2814function GetInventoryIndexOfItemTypeBJ takes unit whichUnit, integer itemId returns integer
2815 local integer index
2816 local item indexItem
2817
2818 set index = 0
2819 loop
2820 set indexItem = UnitItemInSlot(whichUnit, index)
2821 if (indexItem != null) and (GetItemTypeId(indexItem) == itemId) then
2822 return index + 1
2823 endif
2824
2825 set index = index + 1
2826 exitwhen index >= bj_MAX_INVENTORY
2827 endloop
2828 return 0
2829endfunction
2830
2831//===========================================================================
2832function GetItemOfTypeFromUnitBJ takes unit whichUnit, integer itemId returns item
2833 local integer index = GetInventoryIndexOfItemTypeBJ(whichUnit, itemId)
2834
2835 if (index == 0) then
2836 return null
2837 else
2838 return UnitItemInSlot(whichUnit, index - 1)
2839 endif
2840endfunction
2841
2842//===========================================================================
2843function UnitHasItemOfTypeBJ takes unit whichUnit, integer itemId returns boolean
2844 return GetInventoryIndexOfItemTypeBJ(whichUnit, itemId) > 0
2845endfunction
2846
2847//===========================================================================
2848function UnitInventoryCount takes unit whichUnit returns integer
2849 local integer index = 0
2850 local integer count = 0
2851
2852 loop
2853 if (UnitItemInSlot(whichUnit, index) != null) then
2854 set count = count + 1
2855 endif
2856
2857 set index = index + 1
2858 exitwhen index >= bj_MAX_INVENTORY
2859 endloop
2860
2861 return count
2862endfunction
2863
2864//===========================================================================
2865function UnitInventorySizeBJ takes unit whichUnit returns integer
2866 return UnitInventorySize(whichUnit)
2867endfunction
2868
2869//===========================================================================
2870function SetItemInvulnerableBJ takes item whichItem, boolean flag returns nothing
2871 call SetItemInvulnerable(whichItem, flag)
2872endfunction
2873
2874//===========================================================================
2875function SetItemDropOnDeathBJ takes item whichItem, boolean flag returns nothing
2876 call SetItemDropOnDeath(whichItem, flag)
2877endfunction
2878
2879//===========================================================================
2880function SetItemDroppableBJ takes item whichItem, boolean flag returns nothing
2881 call SetItemDroppable(whichItem, flag)
2882endfunction
2883
2884//===========================================================================
2885function SetItemPlayerBJ takes item whichItem, player whichPlayer, boolean changeColor returns nothing
2886 call SetItemPlayer(whichItem, whichPlayer, changeColor)
2887endfunction
2888
2889//===========================================================================
2890function SetItemVisibleBJ takes boolean show, item whichItem returns nothing
2891 call SetItemVisible(whichItem, show)
2892endfunction
2893
2894//===========================================================================
2895function IsItemHiddenBJ takes item whichItem returns boolean
2896 return not IsItemVisible(whichItem)
2897endfunction
2898
2899//===========================================================================
2900function ChooseRandomItemBJ takes integer level returns integer
2901 return ChooseRandomItem(level)
2902endfunction
2903
2904//===========================================================================
2905function ChooseRandomItemExBJ takes integer level, itemtype whichType returns integer
2906 return ChooseRandomItemEx(whichType, level)
2907endfunction
2908
2909//===========================================================================
2910function ChooseRandomNPBuildingBJ takes nothing returns integer
2911 return ChooseRandomNPBuilding()
2912endfunction
2913
2914//===========================================================================
2915function ChooseRandomCreepBJ takes integer level returns integer
2916 return ChooseRandomCreep(level)
2917endfunction
2918
2919//===========================================================================
2920function EnumItemsInRectBJ takes rect r, code actionFunc returns nothing
2921 call EnumItemsInRect(r, null, actionFunc)
2922endfunction
2923
2924//===========================================================================
2925// See GroupPickRandomUnitEnum for the details of this algorithm.
2926//
2927function RandomItemInRectBJEnum takes nothing returns nothing
2928 set bj_itemRandomConsidered = bj_itemRandomConsidered + 1
2929 if (GetRandomInt(1, bj_itemRandomConsidered) == 1) then
2930 set bj_itemRandomCurrentPick = GetEnumItem()
2931 endif
2932endfunction
2933
2934//===========================================================================
2935// Picks a random item from within a rect, matching a condition
2936//
2937function RandomItemInRectBJ takes rect r, boolexpr filter returns item
2938 set bj_itemRandomConsidered = 0
2939 set bj_itemRandomCurrentPick = null
2940 call EnumItemsInRect(r, filter, function RandomItemInRectBJEnum)
2941 call DestroyBoolExpr(filter)
2942 return bj_itemRandomCurrentPick
2943endfunction
2944
2945//===========================================================================
2946// Picks a random item from within a rect
2947//
2948function RandomItemInRectSimpleBJ takes rect r returns item
2949 return RandomItemInRectBJ(r, null)
2950endfunction
2951
2952//===========================================================================
2953function CheckItemStatus takes item whichItem, integer status returns boolean
2954 if (status == bj_ITEM_STATUS_HIDDEN) then
2955 return not IsItemVisible(whichItem)
2956 elseif (status == bj_ITEM_STATUS_OWNED) then
2957 return IsItemOwned(whichItem)
2958 elseif (status == bj_ITEM_STATUS_INVULNERABLE) then
2959 return IsItemInvulnerable(whichItem)
2960 elseif (status == bj_ITEM_STATUS_POWERUP) then
2961 return IsItemPowerup(whichItem)
2962 elseif (status == bj_ITEM_STATUS_SELLABLE) then
2963 return IsItemSellable(whichItem)
2964 elseif (status == bj_ITEM_STATUS_PAWNABLE) then
2965 return IsItemPawnable(whichItem)
2966 else
2967 // Unrecognized status - return false
2968 return false
2969 endif
2970endfunction
2971
2972//===========================================================================
2973function CheckItemcodeStatus takes integer itemId, integer status returns boolean
2974 if (status == bj_ITEMCODE_STATUS_POWERUP) then
2975 return IsItemIdPowerup(itemId)
2976 elseif (status == bj_ITEMCODE_STATUS_SELLABLE) then
2977 return IsItemIdSellable(itemId)
2978 elseif (status == bj_ITEMCODE_STATUS_PAWNABLE) then
2979 return IsItemIdPawnable(itemId)
2980 else
2981 // Unrecognized status - return false
2982 return false
2983 endif
2984endfunction
2985
2986
2987
2988//***************************************************************************
2989//*
2990//* Unit Utility Functions
2991//*
2992//***************************************************************************
2993
2994//===========================================================================
2995function UnitId2OrderIdBJ takes integer unitId returns integer
2996 return unitId
2997endfunction
2998
2999//===========================================================================
3000function String2UnitIdBJ takes string unitIdString returns integer
3001 return UnitId(unitIdString)
3002endfunction
3003
3004//===========================================================================
3005function UnitId2StringBJ takes integer unitId returns string
3006 local string unitString = UnitId2String(unitId)
3007
3008 if (unitString != null) then
3009 return unitString
3010 endif
3011
3012 // The unitId was not recognized - return an empty string.
3013 return ""
3014endfunction
3015
3016//===========================================================================
3017function String2OrderIdBJ takes string orderIdString returns integer
3018 local integer orderId
3019
3020 // Check to see if it's a generic order.
3021 set orderId = OrderId(orderIdString)
3022 if (orderId != 0) then
3023 return orderId
3024 endif
3025
3026 // Check to see if it's a (train) unit order.
3027 set orderId = UnitId(orderIdString)
3028 if (orderId != 0) then
3029 return orderId
3030 endif
3031
3032 // Unrecognized - return 0
3033 return 0
3034endfunction
3035
3036//===========================================================================
3037function OrderId2StringBJ takes integer orderId returns string
3038 local string orderString
3039
3040 // Check to see if it's a generic order.
3041 set orderString = OrderId2String(orderId)
3042 if (orderString != null) then
3043 return orderString
3044 endif
3045
3046 // Check to see if it's a (train) unit order.
3047 set orderString = UnitId2String(orderId)
3048 if (orderString != null) then
3049 return orderString
3050 endif
3051
3052 // Unrecognized - return an empty string.
3053 return ""
3054endfunction
3055
3056//===========================================================================
3057function GetIssuedOrderIdBJ takes nothing returns integer
3058 return GetIssuedOrderId()
3059endfunction
3060
3061//===========================================================================
3062function GetKillingUnitBJ takes nothing returns unit
3063 return GetKillingUnit()
3064endfunction
3065
3066//===========================================================================
3067function CreateUnitAtLocSaveLast takes player id, integer unitid, location loc, real face returns unit
3068 if (unitid == 'ugol') then
3069 set bj_lastCreatedUnit = CreateBlightedGoldmine(id, GetLocationX(loc), GetLocationY(loc), face)
3070 else
3071 set bj_lastCreatedUnit = CreateUnitAtLoc(id, unitid, loc, face)
3072 endif
3073
3074 return bj_lastCreatedUnit
3075endfunction
3076
3077//===========================================================================
3078function GetLastCreatedUnit takes nothing returns unit
3079 return bj_lastCreatedUnit
3080endfunction
3081
3082//===========================================================================
3083function CreateNUnitsAtLoc takes integer count, integer unitId, player whichPlayer, location loc, real face returns group
3084 call GroupClear(bj_lastCreatedGroup)
3085 loop
3086 set count = count - 1
3087 exitwhen count < 0
3088 call CreateUnitAtLocSaveLast(whichPlayer, unitId, loc, face)
3089 call GroupAddUnit(bj_lastCreatedGroup, bj_lastCreatedUnit)
3090 endloop
3091 return bj_lastCreatedGroup
3092endfunction
3093
3094//===========================================================================
3095function CreateNUnitsAtLocFacingLocBJ takes integer count, integer unitId, player whichPlayer, location loc, location lookAt returns group
3096 return CreateNUnitsAtLoc(count, unitId, whichPlayer, loc, AngleBetweenPoints(loc, lookAt))
3097endfunction
3098
3099//===========================================================================
3100function GetLastCreatedGroupEnum takes nothing returns nothing
3101 call GroupAddUnit(bj_groupLastCreatedDest, GetEnumUnit())
3102endfunction
3103
3104//===========================================================================
3105function GetLastCreatedGroup takes nothing returns group
3106 set bj_groupLastCreatedDest = CreateGroup()
3107 call ForGroup(bj_lastCreatedGroup, function GetLastCreatedGroupEnum)
3108 return bj_groupLastCreatedDest
3109endfunction
3110
3111//===========================================================================
3112function CreateCorpseLocBJ takes integer unitid, player whichPlayer, location loc returns unit
3113 set bj_lastCreatedUnit = CreateCorpse(whichPlayer, unitid, GetLocationX(loc), GetLocationY(loc), GetRandomReal(0, 360))
3114 return bj_lastCreatedUnit
3115endfunction
3116
3117//===========================================================================
3118function UnitSuspendDecayBJ takes boolean suspend, unit whichUnit returns nothing
3119 call UnitSuspendDecay(whichUnit, suspend)
3120endfunction
3121
3122//===========================================================================
3123function DelayedSuspendDecayStopAnimEnum takes nothing returns nothing
3124 local unit enumUnit = GetEnumUnit()
3125
3126 if (GetUnitState(enumUnit, UNIT_STATE_LIFE) <= 0) then
3127 call SetUnitTimeScale(enumUnit, 0.0001)
3128 endif
3129endfunction
3130
3131//===========================================================================
3132function DelayedSuspendDecayBoneEnum takes nothing returns nothing
3133 local unit enumUnit = GetEnumUnit()
3134
3135 if (GetUnitState(enumUnit, UNIT_STATE_LIFE) <= 0) then
3136 call UnitSuspendDecay(enumUnit, true)
3137 call SetUnitTimeScale(enumUnit, 0.0001)
3138 endif
3139endfunction
3140
3141//===========================================================================
3142// Game code explicitly sets the animation back to "decay bone" after the
3143// initial corpse fades away, so we reset it now. It's best not to show
3144// off corpses thus created until after this grace period has passed.
3145//
3146function DelayedSuspendDecayFleshEnum takes nothing returns nothing
3147 local unit enumUnit = GetEnumUnit()
3148
3149 if (GetUnitState(enumUnit, UNIT_STATE_LIFE) <= 0) then
3150 call UnitSuspendDecay(enumUnit, true)
3151 call SetUnitTimeScale(enumUnit, 10.0)
3152 call SetUnitAnimation(enumUnit, "decay flesh")
3153 endif
3154endfunction
3155
3156//===========================================================================
3157// Waits a short period of time to ensure that the corpse is decaying, and
3158// then suspend the animation and corpse decay.
3159//
3160function DelayedSuspendDecay takes nothing returns nothing
3161 local group boneGroup
3162 local group fleshGroup
3163
3164 // Switch the global unit groups over to local variables and recreate
3165 // the global versions, so that this function can handle overlapping
3166 // calls.
3167 set boneGroup = bj_suspendDecayBoneGroup
3168 set fleshGroup = bj_suspendDecayFleshGroup
3169 set bj_suspendDecayBoneGroup = CreateGroup()
3170 set bj_suspendDecayFleshGroup = CreateGroup()
3171
3172 call ForGroup(fleshGroup, function DelayedSuspendDecayStopAnimEnum)
3173 call ForGroup(boneGroup, function DelayedSuspendDecayStopAnimEnum)
3174
3175 call TriggerSleepAction(bj_CORPSE_MAX_DEATH_TIME)
3176 call ForGroup(fleshGroup, function DelayedSuspendDecayFleshEnum)
3177 call ForGroup(boneGroup, function DelayedSuspendDecayBoneEnum)
3178
3179 call TriggerSleepAction(0.05)
3180 call ForGroup(fleshGroup, function DelayedSuspendDecayStopAnimEnum)
3181
3182 call DestroyGroup(boneGroup)
3183 call DestroyGroup(fleshGroup)
3184endfunction
3185
3186//===========================================================================
3187function DelayedSuspendDecayCreate takes nothing returns nothing
3188 set bj_delayedSuspendDecayTrig = CreateTrigger()
3189 call TriggerRegisterTimerExpireEvent(bj_delayedSuspendDecayTrig, bj_delayedSuspendDecayTimer)
3190 call TriggerAddAction(bj_delayedSuspendDecayTrig, function DelayedSuspendDecay)
3191endfunction
3192
3193//===========================================================================
3194function CreatePermanentCorpseLocBJ takes integer style, integer unitid, player whichPlayer, location loc, real facing returns unit
3195 set bj_lastCreatedUnit = CreateCorpse(whichPlayer, unitid, GetLocationX(loc), GetLocationY(loc), facing)
3196 call SetUnitBlendTime(bj_lastCreatedUnit, 0)
3197
3198 if (style == bj_CORPSETYPE_FLESH) then
3199 call SetUnitAnimation(bj_lastCreatedUnit, "decay flesh")
3200 call GroupAddUnit(bj_suspendDecayFleshGroup, bj_lastCreatedUnit)
3201 elseif (style == bj_CORPSETYPE_BONE) then
3202 call SetUnitAnimation(bj_lastCreatedUnit, "decay bone")
3203 call GroupAddUnit(bj_suspendDecayBoneGroup, bj_lastCreatedUnit)
3204 else
3205 // Unknown decay style - treat as skeletal.
3206 call SetUnitAnimation(bj_lastCreatedUnit, "decay bone")
3207 call GroupAddUnit(bj_suspendDecayBoneGroup, bj_lastCreatedUnit)
3208 endif
3209
3210 call TimerStart(bj_delayedSuspendDecayTimer, 0.05, false, null)
3211 return bj_lastCreatedUnit
3212endfunction
3213
3214//===========================================================================
3215function GetUnitStateSwap takes unitstate whichState, unit whichUnit returns real
3216 return GetUnitState(whichUnit, whichState)
3217endfunction
3218
3219//===========================================================================
3220function GetUnitStatePercent takes unit whichUnit, unitstate whichState, unitstate whichMaxState returns real
3221 local real value = GetUnitState(whichUnit, whichState)
3222 local real maxValue = GetUnitState(whichUnit, whichMaxState)
3223
3224 // Return 0 for null units.
3225 if (whichUnit == null) or (maxValue == 0) then
3226 return 0.0
3227 endif
3228
3229 return value / maxValue * 100.0
3230endfunction
3231
3232//===========================================================================
3233function GetUnitLifePercent takes unit whichUnit returns real
3234 return GetUnitStatePercent(whichUnit, UNIT_STATE_LIFE, UNIT_STATE_MAX_LIFE)
3235endfunction
3236
3237//===========================================================================
3238function GetUnitManaPercent takes unit whichUnit returns real
3239 return GetUnitStatePercent(whichUnit, UNIT_STATE_MANA, UNIT_STATE_MAX_MANA)
3240endfunction
3241
3242//===========================================================================
3243function SelectUnitSingle takes unit whichUnit returns nothing
3244 call ClearSelection()
3245 call SelectUnit(whichUnit, true)
3246endfunction
3247
3248//===========================================================================
3249function SelectGroupBJEnum takes nothing returns nothing
3250 call SelectUnit( GetEnumUnit(), true )
3251endfunction
3252
3253//===========================================================================
3254function SelectGroupBJ takes group g returns nothing
3255 call ClearSelection()
3256 call ForGroup( g, function SelectGroupBJEnum )
3257endfunction
3258
3259//===========================================================================
3260function SelectUnitAdd takes unit whichUnit returns nothing
3261 call SelectUnit(whichUnit, true)
3262endfunction
3263
3264//===========================================================================
3265function SelectUnitRemove takes unit whichUnit returns nothing
3266 call SelectUnit(whichUnit, false)
3267endfunction
3268
3269//===========================================================================
3270function ClearSelectionForPlayer takes player whichPlayer returns nothing
3271 if (GetLocalPlayer() == whichPlayer) then
3272 // Use only local code (no net traffic) within this block to avoid desyncs.
3273 call ClearSelection()
3274 endif
3275endfunction
3276
3277//===========================================================================
3278function SelectUnitForPlayerSingle takes unit whichUnit, player whichPlayer returns nothing
3279 if (GetLocalPlayer() == whichPlayer) then
3280 // Use only local code (no net traffic) within this block to avoid desyncs.
3281 call ClearSelection()
3282 call SelectUnit(whichUnit, true)
3283 endif
3284endfunction
3285
3286//===========================================================================
3287function SelectGroupForPlayerBJ takes group g, player whichPlayer returns nothing
3288 if (GetLocalPlayer() == whichPlayer) then
3289 // Use only local code (no net traffic) within this block to avoid desyncs.
3290 call ClearSelection()
3291 call ForGroup( g, function SelectGroupBJEnum )
3292 endif
3293endfunction
3294
3295//===========================================================================
3296function SelectUnitAddForPlayer takes unit whichUnit, player whichPlayer returns nothing
3297 if (GetLocalPlayer() == whichPlayer) then
3298 // Use only local code (no net traffic) within this block to avoid desyncs.
3299 call SelectUnit(whichUnit, true)
3300 endif
3301endfunction
3302
3303//===========================================================================
3304function SelectUnitRemoveForPlayer takes unit whichUnit, player whichPlayer returns nothing
3305 if (GetLocalPlayer() == whichPlayer) then
3306 // Use only local code (no net traffic) within this block to avoid desyncs.
3307 call SelectUnit(whichUnit, false)
3308 endif
3309endfunction
3310
3311//===========================================================================
3312function SetUnitLifeBJ takes unit whichUnit, real newValue returns nothing
3313 call SetUnitState(whichUnit, UNIT_STATE_LIFE, RMaxBJ(0,newValue))
3314endfunction
3315
3316//===========================================================================
3317function SetUnitManaBJ takes unit whichUnit, real newValue returns nothing
3318 call SetUnitState(whichUnit, UNIT_STATE_MANA, RMaxBJ(0,newValue))
3319endfunction
3320
3321//===========================================================================
3322function SetUnitLifePercentBJ takes unit whichUnit, real percent returns nothing
3323 call SetUnitState(whichUnit, UNIT_STATE_LIFE, GetUnitState(whichUnit, UNIT_STATE_MAX_LIFE) * RMaxBJ(0,percent) * 0.01)
3324endfunction
3325
3326//===========================================================================
3327function SetUnitManaPercentBJ takes unit whichUnit, real percent returns nothing
3328 call SetUnitState(whichUnit, UNIT_STATE_MANA, GetUnitState(whichUnit, UNIT_STATE_MAX_MANA) * RMaxBJ(0,percent) * 0.01)
3329endfunction
3330
3331//===========================================================================
3332function IsUnitDeadBJ takes unit whichUnit returns boolean
3333 return GetUnitState(whichUnit, UNIT_STATE_LIFE) <= 0
3334endfunction
3335
3336//===========================================================================
3337function IsUnitAliveBJ takes unit whichUnit returns boolean
3338 return not IsUnitDeadBJ(whichUnit)
3339endfunction
3340
3341//===========================================================================
3342function IsUnitGroupDeadBJEnum takes nothing returns nothing
3343 if not IsUnitDeadBJ(GetEnumUnit()) then
3344 set bj_isUnitGroupDeadResult = false
3345 endif
3346endfunction
3347
3348//===========================================================================
3349// Returns true if every unit of the group is dead.
3350//
3351function IsUnitGroupDeadBJ takes group g returns boolean
3352 // If the user wants the group destroyed, remember that fact and clear
3353 // the flag, in case it is used again in the callback.
3354 local boolean wantDestroy = bj_wantDestroyGroup
3355 set bj_wantDestroyGroup = false
3356
3357 set bj_isUnitGroupDeadResult = true
3358 call ForGroup(g, function IsUnitGroupDeadBJEnum)
3359
3360 // If the user wants the group destroyed, do so now.
3361 if (wantDestroy) then
3362 call DestroyGroup(g)
3363 endif
3364 return bj_isUnitGroupDeadResult
3365endfunction
3366
3367//===========================================================================
3368function IsUnitGroupEmptyBJEnum takes nothing returns nothing
3369 set bj_isUnitGroupEmptyResult = false
3370endfunction
3371
3372//===========================================================================
3373// Returns true if the group contains no units.
3374//
3375function IsUnitGroupEmptyBJ takes group g returns boolean
3376 // If the user wants the group destroyed, remember that fact and clear
3377 // the flag, in case it is used again in the callback.
3378 local boolean wantDestroy = bj_wantDestroyGroup
3379 set bj_wantDestroyGroup = false
3380
3381 set bj_isUnitGroupEmptyResult = true
3382 call ForGroup(g, function IsUnitGroupEmptyBJEnum)
3383
3384 // If the user wants the group destroyed, do so now.
3385 if (wantDestroy) then
3386 call DestroyGroup(g)
3387 endif
3388 return bj_isUnitGroupEmptyResult
3389endfunction
3390
3391//===========================================================================
3392function IsUnitGroupInRectBJEnum takes nothing returns nothing
3393 if not RectContainsUnit(bj_isUnitGroupInRectRect, GetEnumUnit()) then
3394 set bj_isUnitGroupInRectResult = false
3395 endif
3396endfunction
3397
3398//===========================================================================
3399// Returns true if every unit of the group is within the given rect.
3400//
3401function IsUnitGroupInRectBJ takes group g, rect r returns boolean
3402 set bj_isUnitGroupInRectResult = true
3403 set bj_isUnitGroupInRectRect = r
3404 call ForGroup(g, function IsUnitGroupInRectBJEnum)
3405 return bj_isUnitGroupInRectResult
3406endfunction
3407
3408//===========================================================================
3409function IsUnitHiddenBJ takes unit whichUnit returns boolean
3410 return IsUnitHidden(whichUnit)
3411endfunction
3412
3413//===========================================================================
3414function ShowUnitHide takes unit whichUnit returns nothing
3415 call ShowUnit(whichUnit, false)
3416endfunction
3417
3418//===========================================================================
3419function ShowUnitShow takes unit whichUnit returns nothing
3420 // Prevent dead heroes from being unhidden.
3421 if (IsUnitType(whichUnit, UNIT_TYPE_HERO) and IsUnitDeadBJ(whichUnit)) then
3422 return
3423 endif
3424
3425 call ShowUnit(whichUnit, true)
3426endfunction
3427
3428//===========================================================================
3429function IssueHauntOrderAtLocBJFilter takes nothing returns boolean
3430 return GetUnitTypeId(GetFilterUnit()) == 'ngol'
3431endfunction
3432
3433//===========================================================================
3434function IssueHauntOrderAtLocBJ takes unit whichPeon, location loc returns boolean
3435 local group g = null
3436 local unit goldMine = null
3437
3438 // Search for a gold mine within a 1-cell radius of the specified location.
3439 set g = CreateGroup()
3440 call GroupEnumUnitsInRangeOfLoc(g, loc, 2*bj_CELLWIDTH, filterIssueHauntOrderAtLocBJ)
3441 set goldMine = FirstOfGroup(g)
3442 call DestroyGroup(g)
3443
3444 // If no mine was found, abort the request.
3445 if (goldMine == null) then
3446 return false
3447 endif
3448
3449 // Issue the Haunt Gold Mine order.
3450 return IssueTargetOrderById(whichPeon, 'ugol', goldMine)
3451endfunction
3452
3453//===========================================================================
3454function IssueBuildOrderByIdLocBJ takes unit whichPeon, integer unitId, location loc returns boolean
3455 if (unitId == 'ugol') then
3456 return IssueHauntOrderAtLocBJ(whichPeon, loc)
3457 else
3458 return IssueBuildOrderById(whichPeon, unitId, GetLocationX(loc), GetLocationY(loc))
3459 endif
3460endfunction
3461
3462//===========================================================================
3463function IssueTrainOrderByIdBJ takes unit whichUnit, integer unitId returns boolean
3464 return IssueImmediateOrderById(whichUnit, unitId)
3465endfunction
3466
3467//===========================================================================
3468function GroupTrainOrderByIdBJ takes group g, integer unitId returns boolean
3469 return GroupImmediateOrderById(g, unitId)
3470endfunction
3471
3472//===========================================================================
3473function IssueUpgradeOrderByIdBJ takes unit whichUnit, integer techId returns boolean
3474 return IssueImmediateOrderById(whichUnit, techId)
3475endfunction
3476
3477//===========================================================================
3478function GetAttackedUnitBJ takes nothing returns unit
3479 return GetTriggerUnit()
3480endfunction
3481
3482//===========================================================================
3483function SetUnitFlyHeightBJ takes unit whichUnit, real newHeight, real rate returns nothing
3484 call SetUnitFlyHeight(whichUnit, newHeight, rate)
3485endfunction
3486
3487//===========================================================================
3488function SetUnitTurnSpeedBJ takes unit whichUnit, real turnSpeed returns nothing
3489 call SetUnitTurnSpeed(whichUnit, turnSpeed)
3490endfunction
3491
3492//===========================================================================
3493function SetUnitPropWindowBJ takes unit whichUnit, real propWindow returns nothing
3494 local real angle = propWindow
3495 if (angle <= 0) then
3496 set angle = 1
3497 elseif (angle >= 360) then
3498 set angle = 359
3499 endif
3500 set angle = angle * bj_DEGTORAD
3501
3502 call SetUnitPropWindow(whichUnit, angle)
3503endfunction
3504
3505//===========================================================================
3506function GetUnitPropWindowBJ takes unit whichUnit returns real
3507 return GetUnitPropWindow(whichUnit) * bj_RADTODEG
3508endfunction
3509
3510//===========================================================================
3511function GetUnitDefaultPropWindowBJ takes unit whichUnit returns real
3512 return GetUnitDefaultPropWindow(whichUnit)
3513endfunction
3514
3515//===========================================================================
3516function SetUnitBlendTimeBJ takes unit whichUnit, real blendTime returns nothing
3517 call SetUnitBlendTime(whichUnit, blendTime)
3518endfunction
3519
3520//===========================================================================
3521function SetUnitAcquireRangeBJ takes unit whichUnit, real acquireRange returns nothing
3522 call SetUnitAcquireRange(whichUnit, acquireRange)
3523endfunction
3524
3525//===========================================================================
3526function UnitSetCanSleepBJ takes unit whichUnit, boolean canSleep returns nothing
3527 call UnitAddSleep(whichUnit, canSleep)
3528endfunction
3529
3530//===========================================================================
3531function UnitCanSleepBJ takes unit whichUnit returns boolean
3532 return UnitCanSleep(whichUnit)
3533endfunction
3534
3535//===========================================================================
3536function UnitWakeUpBJ takes unit whichUnit returns nothing
3537 call UnitWakeUp(whichUnit)
3538endfunction
3539
3540//===========================================================================
3541function UnitIsSleepingBJ takes unit whichUnit returns boolean
3542 return UnitIsSleeping(whichUnit)
3543endfunction
3544
3545//===========================================================================
3546function WakePlayerUnitsEnum takes nothing returns nothing
3547 call UnitWakeUp(GetEnumUnit())
3548endfunction
3549
3550//===========================================================================
3551function WakePlayerUnits takes player whichPlayer returns nothing
3552 local group g = CreateGroup()
3553 call GroupEnumUnitsOfPlayer(g, whichPlayer, null)
3554 call ForGroup(g, function WakePlayerUnitsEnum)
3555 call DestroyGroup(g)
3556endfunction
3557
3558//===========================================================================
3559function EnableCreepSleepBJ takes boolean enable returns nothing
3560 call SetPlayerState(Player(PLAYER_NEUTRAL_AGGRESSIVE), PLAYER_STATE_NO_CREEP_SLEEP, IntegerTertiaryOp(enable, 0, 1))
3561
3562 // If we're disabling, attempt to wake any already-sleeping creeps.
3563 if (not enable) then
3564 call WakePlayerUnits(Player(PLAYER_NEUTRAL_AGGRESSIVE))
3565 endif
3566endfunction
3567
3568//===========================================================================
3569function UnitGenerateAlarms takes unit whichUnit, boolean generate returns boolean
3570 return UnitIgnoreAlarm(whichUnit, not generate)
3571endfunction
3572
3573//===========================================================================
3574function DoesUnitGenerateAlarms takes unit whichUnit returns boolean
3575 return not UnitIgnoreAlarmToggled(whichUnit)
3576endfunction
3577
3578//===========================================================================
3579function PauseAllUnitsBJEnum takes nothing returns nothing
3580 call PauseUnit( GetEnumUnit(), bj_pauseAllUnitsFlag )
3581endfunction
3582
3583//===========================================================================
3584// Pause all units
3585function PauseAllUnitsBJ takes boolean pause returns nothing
3586 local integer index
3587 local player indexPlayer
3588 local group g
3589
3590 set bj_pauseAllUnitsFlag = pause
3591 set g = CreateGroup()
3592 set index = 0
3593 loop
3594 set indexPlayer = Player( index )
3595
3596 // If this is a computer slot, pause/resume the AI.
3597 if (GetPlayerController( indexPlayer ) == MAP_CONTROL_COMPUTER) then
3598 call PauseCompAI( indexPlayer, pause )
3599 endif
3600
3601 // Enumerate and unpause every unit owned by the player.
3602 call GroupEnumUnitsOfPlayer( g, indexPlayer, null )
3603 call ForGroup( g, function PauseAllUnitsBJEnum )
3604 call GroupClear( g )
3605
3606 set index = index + 1
3607 exitwhen index == bj_MAX_PLAYER_SLOTS
3608 endloop
3609 call DestroyGroup(g)
3610endfunction
3611
3612//===========================================================================
3613function PauseUnitBJ takes boolean pause, unit whichUnit returns nothing
3614 call PauseUnit(whichUnit, pause)
3615endfunction
3616
3617//===========================================================================
3618function IsUnitPausedBJ takes unit whichUnit returns boolean
3619 return IsUnitPaused(whichUnit)
3620endfunction
3621
3622//===========================================================================
3623function UnitPauseTimedLifeBJ takes boolean flag, unit whichUnit returns nothing
3624 call UnitPauseTimedLife(whichUnit, flag)
3625endfunction
3626
3627//===========================================================================
3628function UnitApplyTimedLifeBJ takes real duration, integer buffId, unit whichUnit returns nothing
3629 call UnitApplyTimedLife(whichUnit, buffId, duration)
3630endfunction
3631
3632//===========================================================================
3633function UnitShareVisionBJ takes boolean share, unit whichUnit, player whichPlayer returns nothing
3634 call UnitShareVision(whichUnit, whichPlayer, share)
3635endfunction
3636
3637//===========================================================================
3638function UnitRemoveBuffsBJ takes integer buffType, unit whichUnit returns nothing
3639 if (buffType == bj_REMOVEBUFFS_POSITIVE) then
3640 call UnitRemoveBuffs(whichUnit, true, false)
3641 elseif (buffType == bj_REMOVEBUFFS_NEGATIVE) then
3642 call UnitRemoveBuffs(whichUnit, false, true)
3643 elseif (buffType == bj_REMOVEBUFFS_ALL) then
3644 call UnitRemoveBuffs(whichUnit, true, true)
3645 elseif (buffType == bj_REMOVEBUFFS_NONTLIFE) then
3646 call UnitRemoveBuffsEx(whichUnit, true, true, false, false, false, true, false)
3647 else
3648 // Unrecognized dispel type - ignore the request.
3649 endif
3650endfunction
3651
3652//===========================================================================
3653function UnitRemoveBuffsExBJ takes integer polarity, integer resist, unit whichUnit, boolean bTLife, boolean bAura returns nothing
3654 local boolean bPos = (polarity == bj_BUFF_POLARITY_EITHER) or (polarity == bj_BUFF_POLARITY_POSITIVE)
3655 local boolean bNeg = (polarity == bj_BUFF_POLARITY_EITHER) or (polarity == bj_BUFF_POLARITY_NEGATIVE)
3656 local boolean bMagic = (resist == bj_BUFF_RESIST_BOTH) or (resist == bj_BUFF_RESIST_MAGIC)
3657 local boolean bPhys = (resist == bj_BUFF_RESIST_BOTH) or (resist == bj_BUFF_RESIST_PHYSICAL)
3658
3659 call UnitRemoveBuffsEx(whichUnit, bPos, bNeg, bMagic, bPhys, bTLife, bAura, false)
3660endfunction
3661
3662//===========================================================================
3663function UnitCountBuffsExBJ takes integer polarity, integer resist, unit whichUnit, boolean bTLife, boolean bAura returns integer
3664 local boolean bPos = (polarity == bj_BUFF_POLARITY_EITHER) or (polarity == bj_BUFF_POLARITY_POSITIVE)
3665 local boolean bNeg = (polarity == bj_BUFF_POLARITY_EITHER) or (polarity == bj_BUFF_POLARITY_NEGATIVE)
3666 local boolean bMagic = (resist == bj_BUFF_RESIST_BOTH) or (resist == bj_BUFF_RESIST_MAGIC)
3667 local boolean bPhys = (resist == bj_BUFF_RESIST_BOTH) or (resist == bj_BUFF_RESIST_PHYSICAL)
3668
3669 return UnitCountBuffsEx(whichUnit, bPos, bNeg, bMagic, bPhys, bTLife, bAura, false)
3670endfunction
3671
3672//===========================================================================
3673function UnitRemoveAbilityBJ takes integer abilityId, unit whichUnit returns boolean
3674 return UnitRemoveAbility(whichUnit, abilityId)
3675endfunction
3676
3677//===========================================================================
3678function UnitAddAbilityBJ takes integer abilityId, unit whichUnit returns boolean
3679 return UnitAddAbility(whichUnit, abilityId)
3680endfunction
3681
3682//===========================================================================
3683function UnitRemoveTypeBJ takes unittype whichType, unit whichUnit returns boolean
3684 return UnitRemoveType(whichUnit, whichType)
3685endfunction
3686
3687//===========================================================================
3688function UnitAddTypeBJ takes unittype whichType, unit whichUnit returns boolean
3689 return UnitAddType(whichUnit, whichType)
3690endfunction
3691
3692//===========================================================================
3693function UnitMakeAbilityPermanentBJ takes boolean permanent, integer abilityId, unit whichUnit returns boolean
3694 return UnitMakeAbilityPermanent(whichUnit, permanent, abilityId)
3695endfunction
3696
3697//===========================================================================
3698function SetUnitExplodedBJ takes unit whichUnit, boolean exploded returns nothing
3699 call SetUnitExploded(whichUnit, exploded)
3700endfunction
3701
3702//===========================================================================
3703function ExplodeUnitBJ takes unit whichUnit returns nothing
3704 call SetUnitExploded(whichUnit, true)
3705 call KillUnit(whichUnit)
3706endfunction
3707
3708//===========================================================================
3709function GetTransportUnitBJ takes nothing returns unit
3710 return GetTransportUnit()
3711endfunction
3712
3713//===========================================================================
3714function GetLoadedUnitBJ takes nothing returns unit
3715 return GetLoadedUnit()
3716endfunction
3717
3718//===========================================================================
3719function IsUnitInTransportBJ takes unit whichUnit, unit whichTransport returns boolean
3720 return IsUnitInTransport(whichUnit, whichTransport)
3721endfunction
3722
3723//===========================================================================
3724function IsUnitLoadedBJ takes unit whichUnit returns boolean
3725 return IsUnitLoaded(whichUnit)
3726endfunction
3727
3728//===========================================================================
3729function IsUnitIllusionBJ takes unit whichUnit returns boolean
3730 return IsUnitIllusion(whichUnit)
3731endfunction
3732
3733//===========================================================================
3734// This attempts to replace a unit with a new unit type by creating a new
3735// unit of the desired type using the old unit's location, facing, etc.
3736//
3737function ReplaceUnitBJ takes unit whichUnit, integer newUnitId, integer unitStateMethod returns unit
3738 local unit oldUnit = whichUnit
3739 local unit newUnit
3740 local boolean wasHidden
3741 local integer index
3742 local item indexItem
3743 local real oldRatio
3744
3745 // If we have bogus data, don't attempt the replace.
3746 if (oldUnit == null) then
3747 set bj_lastReplacedUnit = oldUnit
3748 return oldUnit
3749 endif
3750
3751 // Hide the original unit.
3752 set wasHidden = IsUnitHidden(oldUnit)
3753 call ShowUnit(oldUnit, false)
3754
3755 // Create the replacement unit.
3756 if (newUnitId == 'ugol') then
3757 set newUnit = CreateBlightedGoldmine(GetOwningPlayer(oldUnit), GetUnitX(oldUnit), GetUnitY(oldUnit), GetUnitFacing(oldUnit))
3758 else
3759 set newUnit = CreateUnit(GetOwningPlayer(oldUnit), newUnitId, GetUnitX(oldUnit), GetUnitY(oldUnit), GetUnitFacing(oldUnit))
3760 endif
3761
3762 // Set the unit's life and mana according to the requested method.
3763 if (unitStateMethod == bj_UNIT_STATE_METHOD_RELATIVE) then
3764 // Set the replacement's current/max life ratio to that of the old unit.
3765 // If both units have mana, do the same for mana.
3766 if (GetUnitState(oldUnit, UNIT_STATE_MAX_LIFE) > 0) then
3767 set oldRatio = GetUnitState(oldUnit, UNIT_STATE_LIFE) / GetUnitState(oldUnit, UNIT_STATE_MAX_LIFE)
3768 call SetUnitState(newUnit, UNIT_STATE_LIFE, oldRatio * GetUnitState(newUnit, UNIT_STATE_MAX_LIFE))
3769 endif
3770
3771 if (GetUnitState(oldUnit, UNIT_STATE_MAX_MANA) > 0) and (GetUnitState(newUnit, UNIT_STATE_MAX_MANA) > 0) then
3772 set oldRatio = GetUnitState(oldUnit, UNIT_STATE_MANA) / GetUnitState(oldUnit, UNIT_STATE_MAX_MANA)
3773 call SetUnitState(newUnit, UNIT_STATE_MANA, oldRatio * GetUnitState(newUnit, UNIT_STATE_MAX_MANA))
3774 endif
3775 elseif (unitStateMethod == bj_UNIT_STATE_METHOD_ABSOLUTE) then
3776 // Set the replacement's current life to that of the old unit.
3777 // If the new unit has mana, do the same for mana.
3778 call SetUnitState(newUnit, UNIT_STATE_LIFE, GetUnitState(oldUnit, UNIT_STATE_LIFE))
3779 if (GetUnitState(newUnit, UNIT_STATE_MAX_MANA) > 0) then
3780 call SetUnitState(newUnit, UNIT_STATE_MANA, GetUnitState(oldUnit, UNIT_STATE_MANA))
3781 endif
3782 elseif (unitStateMethod == bj_UNIT_STATE_METHOD_DEFAULTS) then
3783 // The newly created unit should already have default life and mana.
3784 elseif (unitStateMethod == bj_UNIT_STATE_METHOD_MAXIMUM) then
3785 // Use max life and mana.
3786 call SetUnitState(newUnit, UNIT_STATE_LIFE, GetUnitState(newUnit, UNIT_STATE_MAX_LIFE))
3787 call SetUnitState(newUnit, UNIT_STATE_MANA, GetUnitState(newUnit, UNIT_STATE_MAX_MANA))
3788 else
3789 // Unrecognized unit state method - ignore the request.
3790 endif
3791
3792 // Mirror properties of the old unit onto the new unit.
3793 //call PauseUnit(newUnit, IsUnitPaused(oldUnit))
3794 call SetResourceAmount(newUnit, GetResourceAmount(oldUnit))
3795
3796 // If both the old and new units are heroes, handle their hero info.
3797 if (IsUnitType(oldUnit, UNIT_TYPE_HERO) and IsUnitType(newUnit, UNIT_TYPE_HERO)) then
3798 call SetHeroXP(newUnit, GetHeroXP(oldUnit), false)
3799
3800 set index = 0
3801 loop
3802 set indexItem = UnitItemInSlot(oldUnit, index)
3803 if (indexItem != null) then
3804 call UnitRemoveItem(oldUnit, indexItem)
3805 call UnitAddItem(newUnit, indexItem)
3806 endif
3807
3808 set index = index + 1
3809 exitwhen index >= bj_MAX_INVENTORY
3810 endloop
3811 endif
3812
3813 // Remove or kill the original unit. It is sometimes unsafe to remove
3814 // hidden units, so kill the original unit if it was previously hidden.
3815 if wasHidden then
3816 call KillUnit(oldUnit)
3817 call RemoveUnit(oldUnit)
3818 else
3819 call RemoveUnit(oldUnit)
3820 endif
3821
3822 set bj_lastReplacedUnit = newUnit
3823 return newUnit
3824endfunction
3825
3826//===========================================================================
3827function GetLastReplacedUnitBJ takes nothing returns unit
3828 return bj_lastReplacedUnit
3829endfunction
3830
3831//===========================================================================
3832function SetUnitPositionLocFacingBJ takes unit whichUnit, location loc, real facing returns nothing
3833 call SetUnitPositionLoc(whichUnit, loc)
3834 call SetUnitFacing(whichUnit, facing)
3835endfunction
3836
3837//===========================================================================
3838function SetUnitPositionLocFacingLocBJ takes unit whichUnit, location loc, location lookAt returns nothing
3839 call SetUnitPositionLoc(whichUnit, loc)
3840 call SetUnitFacing(whichUnit, AngleBetweenPoints(loc, lookAt))
3841endfunction
3842
3843//===========================================================================
3844function AddItemToStockBJ takes integer itemId, unit whichUnit, integer currentStock, integer stockMax returns nothing
3845 call AddItemToStock(whichUnit, itemId, currentStock, stockMax)
3846endfunction
3847
3848//===========================================================================
3849function AddUnitToStockBJ takes integer unitId, unit whichUnit, integer currentStock, integer stockMax returns nothing
3850 call AddUnitToStock(whichUnit, unitId, currentStock, stockMax)
3851endfunction
3852
3853//===========================================================================
3854function RemoveItemFromStockBJ takes integer itemId, unit whichUnit returns nothing
3855 call RemoveItemFromStock(whichUnit, itemId)
3856endfunction
3857
3858//===========================================================================
3859function RemoveUnitFromStockBJ takes integer unitId, unit whichUnit returns nothing
3860 call RemoveUnitFromStock(whichUnit, unitId)
3861endfunction
3862
3863//===========================================================================
3864function SetUnitUseFoodBJ takes boolean enable, unit whichUnit returns nothing
3865 call SetUnitUseFood(whichUnit, enable)
3866endfunction
3867
3868//===========================================================================
3869function UnitDamagePointLoc takes unit whichUnit, real delay, real radius, location loc, real amount, attacktype whichAttack, damagetype whichDamage returns boolean
3870 return UnitDamagePoint(whichUnit, delay, radius, GetLocationX(loc), GetLocationY(loc), amount, true, false, whichAttack, whichDamage, WEAPON_TYPE_WHOKNOWS)
3871endfunction
3872
3873//===========================================================================
3874function UnitDamageTargetBJ takes unit whichUnit, unit target, real amount, attacktype whichAttack, damagetype whichDamage returns boolean
3875 return UnitDamageTarget(whichUnit, target, amount, true, false, whichAttack, whichDamage, WEAPON_TYPE_WHOKNOWS)
3876endfunction
3877
3878
3879
3880//***************************************************************************
3881//*
3882//* Destructable Utility Functions
3883//*
3884//***************************************************************************
3885
3886//===========================================================================
3887function CreateDestructableLoc takes integer objectid, location loc, real facing, real scale, integer variation returns destructable
3888 set bj_lastCreatedDestructable = CreateDestructable(objectid, GetLocationX(loc), GetLocationY(loc), facing, scale, variation)
3889 return bj_lastCreatedDestructable
3890endfunction
3891
3892//===========================================================================
3893function CreateDeadDestructableLocBJ takes integer objectid, location loc, real facing, real scale, integer variation returns destructable
3894 set bj_lastCreatedDestructable = CreateDeadDestructable(objectid, GetLocationX(loc), GetLocationY(loc), facing, scale, variation)
3895 return bj_lastCreatedDestructable
3896endfunction
3897
3898//===========================================================================
3899function GetLastCreatedDestructable takes nothing returns destructable
3900 return bj_lastCreatedDestructable
3901endfunction
3902
3903//===========================================================================
3904function ShowDestructableBJ takes boolean flag, destructable d returns nothing
3905 call ShowDestructable(d, flag)
3906endfunction
3907
3908//===========================================================================
3909function SetDestructableInvulnerableBJ takes destructable d, boolean flag returns nothing
3910 call SetDestructableInvulnerable(d, flag)
3911endfunction
3912
3913//===========================================================================
3914function IsDestructableInvulnerableBJ takes destructable d returns boolean
3915 return IsDestructableInvulnerable(d)
3916endfunction
3917
3918//===========================================================================
3919function GetDestructableLoc takes destructable whichDestructable returns location
3920 return Location(GetDestructableX(whichDestructable), GetDestructableY(whichDestructable))
3921endfunction
3922
3923//===========================================================================
3924function EnumDestructablesInRectAll takes rect r, code actionFunc returns nothing
3925 call EnumDestructablesInRect(r, null, actionFunc)
3926endfunction
3927
3928//===========================================================================
3929function EnumDestructablesInCircleBJFilter takes nothing returns boolean
3930 local location destLoc = GetDestructableLoc(GetFilterDestructable())
3931 local boolean result
3932
3933 set result = DistanceBetweenPoints(destLoc, bj_enumDestructableCenter) <= bj_enumDestructableRadius
3934 call RemoveLocation(destLoc)
3935 return result
3936endfunction
3937
3938//===========================================================================
3939function IsDestructableDeadBJ takes destructable d returns boolean
3940 return GetDestructableLife(d) <= 0
3941endfunction
3942
3943//===========================================================================
3944function IsDestructableAliveBJ takes destructable d returns boolean
3945 return not IsDestructableDeadBJ(d)
3946endfunction
3947
3948//===========================================================================
3949// See GroupPickRandomUnitEnum for the details of this algorithm.
3950//
3951function RandomDestructableInRectBJEnum takes nothing returns nothing
3952 set bj_destRandomConsidered = bj_destRandomConsidered + 1
3953 if (GetRandomInt(1,bj_destRandomConsidered) == 1) then
3954 set bj_destRandomCurrentPick = GetEnumDestructable()
3955 endif
3956endfunction
3957
3958//===========================================================================
3959// Picks a random destructable from within a rect, matching a condition
3960//
3961function RandomDestructableInRectBJ takes rect r, boolexpr filter returns destructable
3962 set bj_destRandomConsidered = 0
3963 set bj_destRandomCurrentPick = null
3964 call EnumDestructablesInRect(r, filter, function RandomDestructableInRectBJEnum)
3965 call DestroyBoolExpr(filter)
3966 return bj_destRandomCurrentPick
3967endfunction
3968
3969//===========================================================================
3970// Picks a random destructable from within a rect
3971//
3972function RandomDestructableInRectSimpleBJ takes rect r returns destructable
3973 return RandomDestructableInRectBJ(r, null)
3974endfunction
3975
3976//===========================================================================
3977// Enumerates within a rect, with a filter to narrow the enumeration down
3978// objects within a circular area.
3979//
3980function EnumDestructablesInCircleBJ takes real radius, location loc, code actionFunc returns nothing
3981 local rect r
3982
3983 if (radius >= 0) then
3984 set bj_enumDestructableCenter = loc
3985 set bj_enumDestructableRadius = radius
3986 set r = GetRectFromCircleBJ(loc, radius)
3987 call EnumDestructablesInRect(r, filterEnumDestructablesInCircleBJ, actionFunc)
3988 call RemoveRect(r)
3989 endif
3990endfunction
3991
3992//===========================================================================
3993function SetDestructableLifePercentBJ takes destructable d, real percent returns nothing
3994 call SetDestructableLife(d, GetDestructableMaxLife(d) * percent * 0.01)
3995endfunction
3996
3997//===========================================================================
3998function SetDestructableMaxLifeBJ takes destructable d, real max returns nothing
3999 call SetDestructableMaxLife(d, max)
4000endfunction
4001
4002//===========================================================================
4003function ModifyGateBJ takes integer gateOperation, destructable d returns nothing
4004 if (gateOperation == bj_GATEOPERATION_CLOSE) then
4005 if (GetDestructableLife(d) <= 0) then
4006 call DestructableRestoreLife(d, GetDestructableMaxLife(d), true)
4007 endif
4008 call SetDestructableAnimation(d, "stand")
4009 elseif (gateOperation == bj_GATEOPERATION_OPEN) then
4010 if (GetDestructableLife(d) > 0) then
4011 call KillDestructable(d)
4012 endif
4013 call SetDestructableAnimation(d, "death alternate")
4014 elseif (gateOperation == bj_GATEOPERATION_DESTROY) then
4015 if (GetDestructableLife(d) > 0) then
4016 call KillDestructable(d)
4017 endif
4018 call SetDestructableAnimation(d, "death")
4019 else
4020 // Unrecognized gate state - ignore the request.
4021 endif
4022endfunction
4023
4024//===========================================================================
4025// Determine the elevator's height from its occlusion height.
4026//
4027function GetElevatorHeight takes destructable d returns integer
4028 local integer height
4029
4030 set height = 1 + R2I(GetDestructableOccluderHeight(d) / bj_CLIFFHEIGHT)
4031 if (height < 1) or (height > 3) then
4032 set height = 1
4033 endif
4034 return height
4035endfunction
4036
4037//===========================================================================
4038// To properly animate an elevator, we must know not only what height we
4039// want to change to, but also what height we are currently at. This code
4040// determines the elevator's current height from its occlusion height.
4041// Arbitrarily changing an elevator's occlusion height is thus inadvisable.
4042//
4043function ChangeElevatorHeight takes destructable d, integer newHeight returns nothing
4044 local integer oldHeight
4045
4046 // Cap the new height within the supported range.
4047 set newHeight = IMaxBJ(1, newHeight)
4048 set newHeight = IMinBJ(3, newHeight)
4049
4050 // Find out what height the elevator is already at.
4051 set oldHeight = GetElevatorHeight(d)
4052
4053 // Set the elevator's occlusion height.
4054 call SetDestructableOccluderHeight(d, bj_CLIFFHEIGHT*(newHeight-1))
4055
4056 if (newHeight == 1) then
4057 if (oldHeight == 2) then
4058 call SetDestructableAnimation(d, "birth")
4059 call QueueDestructableAnimation(d, "stand")
4060 elseif (oldHeight == 3) then
4061 call SetDestructableAnimation(d, "birth third")
4062 call QueueDestructableAnimation(d, "stand")
4063 else
4064 // Unrecognized old height - snap to new height.
4065 call SetDestructableAnimation(d, "stand")
4066 endif
4067 elseif (newHeight == 2) then
4068 if (oldHeight == 1) then
4069 call SetDestructableAnimation(d, "death")
4070 call QueueDestructableAnimation(d, "stand second")
4071 elseif (oldHeight == 3) then
4072 call SetDestructableAnimation(d, "birth second")
4073 call QueueDestructableAnimation(d, "stand second")
4074 else
4075 // Unrecognized old height - snap to new height.
4076 call SetDestructableAnimation(d, "stand second")
4077 endif
4078 elseif (newHeight == 3) then
4079 if (oldHeight == 1) then
4080 call SetDestructableAnimation(d, "death third")
4081 call QueueDestructableAnimation(d, "stand third")
4082 elseif (oldHeight == 2) then
4083 call SetDestructableAnimation(d, "death second")
4084 call QueueDestructableAnimation(d, "stand third")
4085 else
4086 // Unrecognized old height - snap to new height.
4087 call SetDestructableAnimation(d, "stand third")
4088 endif
4089 else
4090 // Unrecognized new height - ignore the request.
4091 endif
4092endfunction
4093
4094//===========================================================================
4095// Grab the unit and throw his own coords in his face, forcing him to push
4096// and shove until he finds a spot where noone will bother him.
4097//
4098function NudgeUnitsInRectEnum takes nothing returns nothing
4099 local unit nudgee = GetEnumUnit()
4100
4101 call SetUnitPosition(nudgee, GetUnitX(nudgee), GetUnitY(nudgee))
4102endfunction
4103
4104//===========================================================================
4105function NudgeItemsInRectEnum takes nothing returns nothing
4106 local item nudgee = GetEnumItem()
4107
4108 call SetItemPosition(nudgee, GetItemX(nudgee), GetItemY(nudgee))
4109endfunction
4110
4111//===========================================================================
4112// Nudge the items and units within a given rect ever so gently, so as to
4113// encourage them to find locations where they can peacefully coexist with
4114// pathing restrictions and live happy, fruitful lives.
4115//
4116function NudgeObjectsInRect takes rect nudgeArea returns nothing
4117 local group g
4118
4119 set g = CreateGroup()
4120 call GroupEnumUnitsInRect(g, nudgeArea, null)
4121 call ForGroup(g, function NudgeUnitsInRectEnum)
4122 call DestroyGroup(g)
4123
4124 call EnumItemsInRect(nudgeArea, null, function NudgeItemsInRectEnum)
4125endfunction
4126
4127//===========================================================================
4128function NearbyElevatorExistsEnum takes nothing returns nothing
4129 local destructable d = GetEnumDestructable()
4130 local integer dType = GetDestructableTypeId(d)
4131
4132 if (dType == bj_ELEVATOR_CODE01) or (dType == bj_ELEVATOR_CODE02) then
4133 set bj_elevatorNeighbor = d
4134 endif
4135endfunction
4136
4137//===========================================================================
4138function NearbyElevatorExists takes real x, real y returns boolean
4139 local real findThreshold = 32
4140 local rect r
4141
4142 // If another elevator is overlapping this one, ignore the wall.
4143 set r = Rect(x - findThreshold, y - findThreshold, x + findThreshold, y + findThreshold)
4144 set bj_elevatorNeighbor = null
4145 call EnumDestructablesInRect(r, null, function NearbyElevatorExistsEnum)
4146 call RemoveRect(r)
4147
4148 return bj_elevatorNeighbor != null
4149endfunction
4150
4151//===========================================================================
4152function FindElevatorWallBlockerEnum takes nothing returns nothing
4153 set bj_elevatorWallBlocker = GetEnumDestructable()
4154endfunction
4155
4156//===========================================================================
4157// This toggles pathing on or off for one wall of an elevator by killing
4158// or reviving a pathing blocker at the appropriate location (and creating
4159// the pathing blocker in the first place, if it does not yet exist).
4160//
4161function ChangeElevatorWallBlocker takes real x, real y, real facing, boolean open returns nothing
4162 local destructable blocker = null
4163 local real findThreshold = 32
4164 local real nudgeLength = 4.25 * bj_CELLWIDTH
4165 local real nudgeWidth = 1.25 * bj_CELLWIDTH
4166 local rect r
4167
4168 // Search for the pathing blocker within the general area.
4169 set r = Rect(x - findThreshold, y - findThreshold, x + findThreshold, y + findThreshold)
4170 set bj_elevatorWallBlocker = null
4171 call EnumDestructablesInRect(r, null, function FindElevatorWallBlockerEnum)
4172 call RemoveRect(r)
4173 set blocker = bj_elevatorWallBlocker
4174
4175 // Ensure that the blocker exists.
4176 if (blocker == null) then
4177 set blocker = CreateDeadDestructable(bj_ELEVATOR_BLOCKER_CODE, x, y, facing, 1, 0)
4178 elseif (GetDestructableTypeId(blocker) != bj_ELEVATOR_BLOCKER_CODE) then
4179 // If a different destructible exists in the blocker's spot, ignore
4180 // the request. (Two destructibles cannot occupy the same location
4181 // on the map, so we cannot create an elevator blocker here.)
4182 return
4183 endif
4184
4185 if (open) then
4186 // Ensure that the blocker is dead.
4187 if (GetDestructableLife(blocker) > 0) then
4188 call KillDestructable(blocker)
4189 endif
4190 else
4191 // Ensure that the blocker is alive.
4192 if (GetDestructableLife(blocker) <= 0) then
4193 call DestructableRestoreLife(blocker, GetDestructableMaxLife(blocker), false)
4194 endif
4195
4196 // Nudge any objects standing in the blocker's way.
4197 if (facing == 0) then
4198 set r = Rect(x - nudgeWidth/2, y - nudgeLength/2, x + nudgeWidth/2, y + nudgeLength/2)
4199 call NudgeObjectsInRect(r)
4200 call RemoveRect(r)
4201 elseif (facing == 90) then
4202 set r = Rect(x - nudgeLength/2, y - nudgeWidth/2, x + nudgeLength/2, y + nudgeWidth/2)
4203 call NudgeObjectsInRect(r)
4204 call RemoveRect(r)
4205 else
4206 // Unrecognized blocker angle - don't nudge anything.
4207 endif
4208 endif
4209endfunction
4210
4211//===========================================================================
4212function ChangeElevatorWalls takes boolean open, integer walls, destructable d returns nothing
4213 local real x = GetDestructableX(d)
4214 local real y = GetDestructableY(d)
4215 local real distToBlocker = 192
4216 local real distToNeighbor = 256
4217
4218 if (walls == bj_ELEVATOR_WALL_TYPE_ALL) or (walls == bj_ELEVATOR_WALL_TYPE_EAST) then
4219 if (not NearbyElevatorExists(x + distToNeighbor, y)) then
4220 call ChangeElevatorWallBlocker(x + distToBlocker, y, 0, open)
4221 endif
4222 endif
4223
4224 if (walls == bj_ELEVATOR_WALL_TYPE_ALL) or (walls == bj_ELEVATOR_WALL_TYPE_NORTH) then
4225 if (not NearbyElevatorExists(x, y + distToNeighbor)) then
4226 call ChangeElevatorWallBlocker(x, y + distToBlocker, 90, open)
4227 endif
4228 endif
4229
4230 if (walls == bj_ELEVATOR_WALL_TYPE_ALL) or (walls == bj_ELEVATOR_WALL_TYPE_SOUTH) then
4231 if (not NearbyElevatorExists(x, y - distToNeighbor)) then
4232 call ChangeElevatorWallBlocker(x, y - distToBlocker, 90, open)
4233 endif
4234 endif
4235
4236 if (walls == bj_ELEVATOR_WALL_TYPE_ALL) or (walls == bj_ELEVATOR_WALL_TYPE_WEST) then
4237 if (not NearbyElevatorExists(x - distToNeighbor, y)) then
4238 call ChangeElevatorWallBlocker(x - distToBlocker, y, 0, open)
4239 endif
4240 endif
4241endfunction
4242
4243
4244
4245//***************************************************************************
4246//*
4247//* Neutral Building Utility Functions
4248//*
4249//***************************************************************************
4250
4251//===========================================================================
4252function WaygateActivateBJ takes boolean activate, unit waygate returns nothing
4253 call WaygateActivate(waygate, activate)
4254endfunction
4255
4256//===========================================================================
4257function WaygateIsActiveBJ takes unit waygate returns boolean
4258 return WaygateIsActive(waygate)
4259endfunction
4260
4261//===========================================================================
4262function WaygateSetDestinationLocBJ takes unit waygate, location loc returns nothing
4263 call WaygateSetDestination(waygate, GetLocationX(loc), GetLocationY(loc))
4264endfunction
4265
4266//===========================================================================
4267function WaygateGetDestinationLocBJ takes unit waygate returns location
4268 return Location(WaygateGetDestinationX(waygate), WaygateGetDestinationY(waygate))
4269endfunction
4270
4271//===========================================================================
4272function UnitSetUsesAltIconBJ takes boolean flag, unit whichUnit returns nothing
4273 call UnitSetUsesAltIcon(whichUnit, flag)
4274endfunction
4275
4276
4277
4278//***************************************************************************
4279//*
4280//* UI Utility Functions
4281//*
4282//***************************************************************************
4283
4284//===========================================================================
4285function ForceUIKeyBJ takes player whichPlayer, string key returns nothing
4286 if (GetLocalPlayer() == whichPlayer) then
4287 // Use only local code (no net traffic) within this block to avoid desyncs.
4288 call ForceUIKey(key)
4289 endif
4290endfunction
4291
4292//===========================================================================
4293function ForceUICancelBJ takes player whichPlayer returns nothing
4294 if (GetLocalPlayer() == whichPlayer) then
4295 // Use only local code (no net traffic) within this block to avoid desyncs.
4296 call ForceUICancel()
4297 endif
4298endfunction
4299
4300
4301
4302//***************************************************************************
4303//*
4304//* Group and Force Utility Functions
4305//*
4306//***************************************************************************
4307
4308//===========================================================================
4309function ForGroupBJ takes group whichGroup, code callback returns nothing
4310 // If the user wants the group destroyed, remember that fact and clear
4311 // the flag, in case it is used again in the callback.
4312 local boolean wantDestroy = bj_wantDestroyGroup
4313 set bj_wantDestroyGroup = false
4314
4315 call ForGroup(whichGroup, callback)
4316
4317 // If the user wants the group destroyed, do so now.
4318 if (wantDestroy) then
4319 call DestroyGroup(whichGroup)
4320 endif
4321endfunction
4322
4323//===========================================================================
4324function GroupAddUnitSimple takes unit whichUnit, group whichGroup returns nothing
4325 call GroupAddUnit(whichGroup, whichUnit)
4326endfunction
4327
4328//===========================================================================
4329function GroupRemoveUnitSimple takes unit whichUnit, group whichGroup returns nothing
4330 call GroupRemoveUnit(whichGroup, whichUnit)
4331endfunction
4332
4333//===========================================================================
4334function GroupAddGroupEnum takes nothing returns nothing
4335 call GroupAddUnit(bj_groupAddGroupDest, GetEnumUnit())
4336endfunction
4337
4338//===========================================================================
4339function GroupAddGroup takes group sourceGroup, group destGroup returns nothing
4340 // If the user wants the group destroyed, remember that fact and clear
4341 // the flag, in case it is used again in the callback.
4342 local boolean wantDestroy = bj_wantDestroyGroup
4343 set bj_wantDestroyGroup = false
4344
4345 set bj_groupAddGroupDest = destGroup
4346 call ForGroup(sourceGroup, function GroupAddGroupEnum)
4347
4348 // If the user wants the group destroyed, do so now.
4349 if (wantDestroy) then
4350 call DestroyGroup(sourceGroup)
4351 endif
4352endfunction
4353
4354//===========================================================================
4355function GroupRemoveGroupEnum takes nothing returns nothing
4356 call GroupRemoveUnit(bj_groupRemoveGroupDest, GetEnumUnit())
4357endfunction
4358
4359//===========================================================================
4360function GroupRemoveGroup takes group sourceGroup, group destGroup returns nothing
4361 // If the user wants the group destroyed, remember that fact and clear
4362 // the flag, in case it is used again in the callback.
4363 local boolean wantDestroy = bj_wantDestroyGroup
4364 set bj_wantDestroyGroup = false
4365
4366 set bj_groupRemoveGroupDest = destGroup
4367 call ForGroup(sourceGroup, function GroupRemoveGroupEnum)
4368
4369 // If the user wants the group destroyed, do so now.
4370 if (wantDestroy) then
4371 call DestroyGroup(sourceGroup)
4372 endif
4373endfunction
4374
4375//===========================================================================
4376function ForceAddPlayerSimple takes player whichPlayer, force whichForce returns nothing
4377 call ForceAddPlayer(whichForce, whichPlayer)
4378endfunction
4379
4380//===========================================================================
4381function ForceRemovePlayerSimple takes player whichPlayer, force whichForce returns nothing
4382 call ForceRemovePlayer(whichForce, whichPlayer)
4383endfunction
4384
4385//===========================================================================
4386// Consider each unit, one at a time, keeping a "current pick". Once all units
4387// are considered, this "current pick" will be the resulting random unit.
4388//
4389// The chance of picking a given unit over the "current pick" is 1/N, where N is
4390// the number of units considered thusfar (including the current consideration).
4391//
4392function GroupPickRandomUnitEnum takes nothing returns nothing
4393 set bj_groupRandomConsidered = bj_groupRandomConsidered + 1
4394 if (GetRandomInt(1,bj_groupRandomConsidered) == 1) then
4395 set bj_groupRandomCurrentPick = GetEnumUnit()
4396 endif
4397endfunction
4398
4399//===========================================================================
4400// Picks a random unit from a group.
4401//
4402function GroupPickRandomUnit takes group whichGroup returns unit
4403 // If the user wants the group destroyed, remember that fact and clear
4404 // the flag, in case it is used again in the callback.
4405 local boolean wantDestroy = bj_wantDestroyGroup
4406 set bj_wantDestroyGroup = false
4407
4408 set bj_groupRandomConsidered = 0
4409 set bj_groupRandomCurrentPick = null
4410 call ForGroup(whichGroup, function GroupPickRandomUnitEnum)
4411
4412 // If the user wants the group destroyed, do so now.
4413 if (wantDestroy) then
4414 call DestroyGroup(whichGroup)
4415 endif
4416 return bj_groupRandomCurrentPick
4417endfunction
4418
4419//===========================================================================
4420// See GroupPickRandomUnitEnum for the details of this algorithm.
4421//
4422function ForcePickRandomPlayerEnum takes nothing returns nothing
4423 set bj_forceRandomConsidered = bj_forceRandomConsidered + 1
4424 if (GetRandomInt(1,bj_forceRandomConsidered) == 1) then
4425 set bj_forceRandomCurrentPick = GetEnumPlayer()
4426 endif
4427endfunction
4428
4429//===========================================================================
4430// Picks a random player from a force.
4431//
4432function ForcePickRandomPlayer takes force whichForce returns player
4433 set bj_forceRandomConsidered = 0
4434 set bj_forceRandomCurrentPick = null
4435 call ForForce(whichForce, function ForcePickRandomPlayerEnum)
4436 return bj_forceRandomCurrentPick
4437endfunction
4438
4439//===========================================================================
4440function EnumUnitsSelected takes player whichPlayer, boolexpr enumFilter, code enumAction returns nothing
4441 local group g = CreateGroup()
4442 call SyncSelections()
4443 call GroupEnumUnitsSelected(g, whichPlayer, enumFilter)
4444 call DestroyBoolExpr(enumFilter)
4445 call ForGroup(g, enumAction)
4446 call DestroyGroup(g)
4447endfunction
4448
4449//===========================================================================
4450function GetUnitsInRectMatching takes rect r, boolexpr filter returns group
4451 local group g = CreateGroup()
4452 call GroupEnumUnitsInRect(g, r, filter)
4453 call DestroyBoolExpr(filter)
4454 return g
4455endfunction
4456
4457//===========================================================================
4458function GetUnitsInRectAll takes rect r returns group
4459 return GetUnitsInRectMatching(r, null)
4460endfunction
4461
4462//===========================================================================
4463function GetUnitsInRectOfPlayerFilter takes nothing returns boolean
4464 return GetOwningPlayer(GetFilterUnit()) == bj_groupEnumOwningPlayer
4465endfunction
4466
4467//===========================================================================
4468function GetUnitsInRectOfPlayer takes rect r, player whichPlayer returns group
4469 local group g = CreateGroup()
4470 set bj_groupEnumOwningPlayer = whichPlayer
4471 call GroupEnumUnitsInRect(g, r, filterGetUnitsInRectOfPlayer)
4472 return g
4473endfunction
4474
4475//===========================================================================
4476function GetUnitsInRangeOfLocMatching takes real radius, location whichLocation, boolexpr filter returns group
4477 local group g = CreateGroup()
4478 call GroupEnumUnitsInRangeOfLoc(g, whichLocation, radius, filter)
4479 call DestroyBoolExpr(filter)
4480 return g
4481endfunction
4482
4483//===========================================================================
4484function GetUnitsInRangeOfLocAll takes real radius, location whichLocation returns group
4485 return GetUnitsInRangeOfLocMatching(radius, whichLocation, null)
4486endfunction
4487
4488//===========================================================================
4489function GetUnitsOfTypeIdAllFilter takes nothing returns boolean
4490 return GetUnitTypeId(GetFilterUnit()) == bj_groupEnumTypeId
4491endfunction
4492
4493//===========================================================================
4494function GetUnitsOfTypeIdAll takes integer unitid returns group
4495 local group result = CreateGroup()
4496 local group g = CreateGroup()
4497 local integer index
4498
4499 set index = 0
4500 loop
4501 set bj_groupEnumTypeId = unitid
4502 call GroupClear(g)
4503 call GroupEnumUnitsOfPlayer(g, Player(index), filterGetUnitsOfTypeIdAll)
4504 call GroupAddGroup(g, result)
4505
4506 set index = index + 1
4507 exitwhen index == bj_MAX_PLAYER_SLOTS
4508 endloop
4509 call DestroyGroup(g)
4510
4511 return result
4512endfunction
4513
4514//===========================================================================
4515function GetUnitsOfPlayerMatching takes player whichPlayer, boolexpr filter returns group
4516 local group g = CreateGroup()
4517 call GroupEnumUnitsOfPlayer(g, whichPlayer, filter)
4518 call DestroyBoolExpr(filter)
4519 return g
4520endfunction
4521
4522//===========================================================================
4523function GetUnitsOfPlayerAll takes player whichPlayer returns group
4524 return GetUnitsOfPlayerMatching(whichPlayer, null)
4525endfunction
4526
4527//===========================================================================
4528function GetUnitsOfPlayerAndTypeIdFilter takes nothing returns boolean
4529 return GetUnitTypeId(GetFilterUnit()) == bj_groupEnumTypeId
4530endfunction
4531
4532//===========================================================================
4533function GetUnitsOfPlayerAndTypeId takes player whichPlayer, integer unitid returns group
4534 local group g = CreateGroup()
4535 set bj_groupEnumTypeId = unitid
4536 call GroupEnumUnitsOfPlayer(g, whichPlayer, filterGetUnitsOfPlayerAndTypeId)
4537 return g
4538endfunction
4539
4540//===========================================================================
4541function GetUnitsSelectedAll takes player whichPlayer returns group
4542 local group g = CreateGroup()
4543 call SyncSelections()
4544 call GroupEnumUnitsSelected(g, whichPlayer, null)
4545 return g
4546endfunction
4547
4548//===========================================================================
4549function GetForceOfPlayer takes player whichPlayer returns force
4550 local force f = CreateForce()
4551 call ForceAddPlayer(f, whichPlayer)
4552 return f
4553endfunction
4554
4555//===========================================================================
4556function GetPlayersAll takes nothing returns force
4557 return bj_FORCE_ALL_PLAYERS
4558endfunction
4559
4560//===========================================================================
4561function GetPlayersByMapControl takes mapcontrol whichControl returns force
4562 local force f = CreateForce()
4563 local integer playerIndex
4564 local player indexPlayer
4565
4566 set playerIndex = 0
4567 loop
4568 set indexPlayer = Player(playerIndex)
4569 if GetPlayerController(indexPlayer) == whichControl then
4570 call ForceAddPlayer(f, indexPlayer)
4571 endif
4572
4573 set playerIndex = playerIndex + 1
4574 exitwhen playerIndex == bj_MAX_PLAYER_SLOTS
4575 endloop
4576
4577 return f
4578endfunction
4579
4580//===========================================================================
4581function GetPlayersAllies takes player whichPlayer returns force
4582 local force f = CreateForce()
4583 call ForceEnumAllies(f, whichPlayer, null)
4584 return f
4585endfunction
4586
4587//===========================================================================
4588function GetPlayersEnemies takes player whichPlayer returns force
4589 local force f = CreateForce()
4590 call ForceEnumEnemies(f, whichPlayer, null)
4591 return f
4592endfunction
4593
4594//===========================================================================
4595function GetPlayersMatching takes boolexpr filter returns force
4596 local force f = CreateForce()
4597 call ForceEnumPlayers(f, filter)
4598 call DestroyBoolExpr(filter)
4599 return f
4600endfunction
4601
4602//===========================================================================
4603function CountUnitsInGroupEnum takes nothing returns nothing
4604 set bj_groupCountUnits = bj_groupCountUnits + 1
4605endfunction
4606
4607//===========================================================================
4608function CountUnitsInGroup takes group g returns integer
4609 // If the user wants the group destroyed, remember that fact and clear
4610 // the flag, in case it is used again in the callback.
4611 local boolean wantDestroy = bj_wantDestroyGroup
4612 set bj_wantDestroyGroup = false
4613
4614 set bj_groupCountUnits = 0
4615 call ForGroup(g, function CountUnitsInGroupEnum)
4616
4617 // If the user wants the group destroyed, do so now.
4618 if (wantDestroy) then
4619 call DestroyGroup(g)
4620 endif
4621 return bj_groupCountUnits
4622endfunction
4623
4624//===========================================================================
4625function CountPlayersInForceEnum takes nothing returns nothing
4626 set bj_forceCountPlayers = bj_forceCountPlayers + 1
4627endfunction
4628
4629//===========================================================================
4630function CountPlayersInForceBJ takes force f returns integer
4631 set bj_forceCountPlayers = 0
4632 call ForForce(f, function CountPlayersInForceEnum)
4633 return bj_forceCountPlayers
4634endfunction
4635
4636//===========================================================================
4637function GetRandomSubGroupEnum takes nothing returns nothing
4638 if (bj_randomSubGroupWant > 0) then
4639 if (bj_randomSubGroupWant >= bj_randomSubGroupTotal) or (GetRandomReal(0,1) < bj_randomSubGroupChance) then
4640 // We either need every remaining unit, or the unit passed its chance check.
4641 call GroupAddUnit(bj_randomSubGroupGroup, GetEnumUnit())
4642 set bj_randomSubGroupWant = bj_randomSubGroupWant - 1
4643 endif
4644 endif
4645 set bj_randomSubGroupTotal = bj_randomSubGroupTotal - 1
4646endfunction
4647
4648//===========================================================================
4649function GetRandomSubGroup takes integer count, group sourceGroup returns group
4650 local group g = CreateGroup()
4651
4652 set bj_randomSubGroupGroup = g
4653 set bj_randomSubGroupWant = count
4654 set bj_randomSubGroupTotal = CountUnitsInGroup(sourceGroup)
4655
4656 if (bj_randomSubGroupWant <= 0 or bj_randomSubGroupTotal <= 0) then
4657 return g
4658 endif
4659
4660 set bj_randomSubGroupChance = I2R(bj_randomSubGroupWant) / I2R(bj_randomSubGroupTotal)
4661 call ForGroup(sourceGroup, function GetRandomSubGroupEnum)
4662 return g
4663endfunction
4664
4665//===========================================================================
4666function LivingPlayerUnitsOfTypeIdFilter takes nothing returns boolean
4667 local unit filterUnit = GetFilterUnit()
4668 return IsUnitAliveBJ(filterUnit) and GetUnitTypeId(filterUnit) == bj_livingPlayerUnitsTypeId
4669endfunction
4670
4671//===========================================================================
4672function CountLivingPlayerUnitsOfTypeId takes integer unitId, player whichPlayer returns integer
4673 local group g
4674 local integer matchedCount
4675
4676 set g = CreateGroup()
4677 set bj_livingPlayerUnitsTypeId = unitId
4678 call GroupEnumUnitsOfPlayer(g, whichPlayer, filterLivingPlayerUnitsOfTypeId)
4679 set matchedCount = CountUnitsInGroup(g)
4680 call DestroyGroup(g)
4681
4682 return matchedCount
4683endfunction
4684
4685
4686
4687//***************************************************************************
4688//*
4689//* Animation Utility Functions
4690//*
4691//***************************************************************************
4692
4693//===========================================================================
4694function ResetUnitAnimation takes unit whichUnit returns nothing
4695 call SetUnitAnimation(whichUnit, "stand")
4696endfunction
4697
4698//===========================================================================
4699function SetUnitTimeScalePercent takes unit whichUnit, real percentScale returns nothing
4700 call SetUnitTimeScale(whichUnit, percentScale * 0.01)
4701endfunction
4702
4703//===========================================================================
4704function SetUnitScalePercent takes unit whichUnit, real percentScaleX, real percentScaleY, real percentScaleZ returns nothing
4705 call SetUnitScale(whichUnit, percentScaleX * 0.01, percentScaleY * 0.01, percentScaleZ * 0.01)
4706endfunction
4707
4708//===========================================================================
4709// This version differs from the common.j interface in that the alpha value
4710// is reversed so as to be displayed as transparency, and all four parameters
4711// are treated as percentages rather than bytes.
4712//
4713function SetUnitVertexColorBJ takes unit whichUnit, real red, real green, real blue, real transparency returns nothing
4714 call SetUnitVertexColor(whichUnit, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
4715endfunction
4716
4717//===========================================================================
4718function UnitAddIndicatorBJ takes unit whichUnit, real red, real green, real blue, real transparency returns nothing
4719 call AddIndicator(whichUnit, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
4720endfunction
4721
4722//===========================================================================
4723function DestructableAddIndicatorBJ takes destructable whichDestructable, real red, real green, real blue, real transparency returns nothing
4724 call AddIndicator(whichDestructable, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
4725endfunction
4726
4727//===========================================================================
4728function ItemAddIndicatorBJ takes item whichItem, real red, real green, real blue, real transparency returns nothing
4729 call AddIndicator(whichItem, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
4730endfunction
4731
4732//===========================================================================
4733// Sets a unit's facing to point directly at a location.
4734//
4735function SetUnitFacingToFaceLocTimed takes unit whichUnit, location target, real duration returns nothing
4736 local location unitLoc = GetUnitLoc(whichUnit)
4737
4738 call SetUnitFacingTimed(whichUnit, AngleBetweenPoints(unitLoc, target), duration)
4739 call RemoveLocation(unitLoc)
4740endfunction
4741
4742//===========================================================================
4743// Sets a unit's facing to point directly at another unit.
4744//
4745function SetUnitFacingToFaceUnitTimed takes unit whichUnit, unit target, real duration returns nothing
4746 local location unitLoc = GetUnitLoc(target)
4747
4748 call SetUnitFacingToFaceLocTimed(whichUnit, unitLoc, duration)
4749 call RemoveLocation(unitLoc)
4750endfunction
4751
4752//===========================================================================
4753function QueueUnitAnimationBJ takes unit whichUnit, string whichAnimation returns nothing
4754 call QueueUnitAnimation(whichUnit, whichAnimation)
4755endfunction
4756
4757//===========================================================================
4758function SetDestructableAnimationBJ takes destructable d, string whichAnimation returns nothing
4759 call SetDestructableAnimation(d, whichAnimation)
4760endfunction
4761
4762//===========================================================================
4763function QueueDestructableAnimationBJ takes destructable d, string whichAnimation returns nothing
4764 call QueueDestructableAnimation(d, whichAnimation)
4765endfunction
4766
4767//===========================================================================
4768function SetDestAnimationSpeedPercent takes destructable d, real percentScale returns nothing
4769 call SetDestructableAnimationSpeed(d, percentScale * 0.01)
4770endfunction
4771
4772
4773
4774//***************************************************************************
4775//*
4776//* Dialog Utility Functions
4777//*
4778//***************************************************************************
4779
4780//===========================================================================
4781function DialogDisplayBJ takes boolean flag, dialog whichDialog, player whichPlayer returns nothing
4782 call DialogDisplay(whichPlayer, whichDialog, flag)
4783endfunction
4784
4785//===========================================================================
4786function DialogSetMessageBJ takes dialog whichDialog, string message returns nothing
4787 call DialogSetMessage(whichDialog, message)
4788endfunction
4789
4790//===========================================================================
4791function DialogAddButtonBJ takes dialog whichDialog, string buttonText returns button
4792 set bj_lastCreatedButton = DialogAddButton(whichDialog, buttonText,0)
4793 return bj_lastCreatedButton
4794endfunction
4795
4796//===========================================================================
4797function DialogAddButtonWithHotkeyBJ takes dialog whichDialog, string buttonText, integer hotkey returns button
4798 set bj_lastCreatedButton = DialogAddButton(whichDialog, buttonText,hotkey)
4799 return bj_lastCreatedButton
4800endfunction
4801
4802//===========================================================================
4803function DialogClearBJ takes dialog whichDialog returns nothing
4804 call DialogClear(whichDialog)
4805endfunction
4806
4807//===========================================================================
4808function GetLastCreatedButtonBJ takes nothing returns button
4809 return bj_lastCreatedButton
4810endfunction
4811
4812//===========================================================================
4813function GetClickedButtonBJ takes nothing returns button
4814 return GetClickedButton()
4815endfunction
4816
4817//===========================================================================
4818function GetClickedDialogBJ takes nothing returns dialog
4819 return GetClickedDialog()
4820endfunction
4821
4822
4823
4824//***************************************************************************
4825//*
4826//* Alliance Utility Functions
4827//*
4828//***************************************************************************
4829
4830//===========================================================================
4831function SetPlayerAllianceBJ takes player sourcePlayer, alliancetype whichAllianceSetting, boolean value, player otherPlayer returns nothing
4832 // Prevent players from attempting to ally with themselves.
4833 if (sourcePlayer == otherPlayer) then
4834 return
4835 endif
4836
4837 call SetPlayerAlliance(sourcePlayer, otherPlayer, whichAllianceSetting, value)
4838endfunction
4839
4840//===========================================================================
4841// Set all flags used by the in-game "Ally" checkbox.
4842//
4843function SetPlayerAllianceStateAllyBJ takes player sourcePlayer, player otherPlayer, boolean flag returns nothing
4844 call SetPlayerAlliance(sourcePlayer, otherPlayer, ALLIANCE_PASSIVE, flag)
4845 call SetPlayerAlliance(sourcePlayer, otherPlayer, ALLIANCE_HELP_REQUEST, flag)
4846 call SetPlayerAlliance(sourcePlayer, otherPlayer, ALLIANCE_HELP_RESPONSE, flag)
4847 call SetPlayerAlliance(sourcePlayer, otherPlayer, ALLIANCE_SHARED_XP, flag)
4848 call SetPlayerAlliance(sourcePlayer, otherPlayer, ALLIANCE_SHARED_SPELLS, flag)
4849endfunction
4850
4851//===========================================================================
4852// Set all flags used by the in-game "Shared Vision" checkbox.
4853//
4854function SetPlayerAllianceStateVisionBJ takes player sourcePlayer, player otherPlayer, boolean flag returns nothing
4855 call SetPlayerAlliance(sourcePlayer, otherPlayer, ALLIANCE_SHARED_VISION, flag)
4856endfunction
4857
4858//===========================================================================
4859// Set all flags used by the in-game "Shared Units" checkbox.
4860//
4861function SetPlayerAllianceStateControlBJ takes player sourcePlayer, player otherPlayer, boolean flag returns nothing
4862 call SetPlayerAlliance(sourcePlayer, otherPlayer, ALLIANCE_SHARED_CONTROL, flag)
4863endfunction
4864
4865//===========================================================================
4866// Set all flags used by the in-game "Shared Units" checkbox with the Full
4867// Shared Unit Control feature enabled.
4868//
4869function SetPlayerAllianceStateFullControlBJ takes player sourcePlayer, player otherPlayer, boolean flag returns nothing
4870 call SetPlayerAlliance(sourcePlayer, otherPlayer, ALLIANCE_SHARED_ADVANCED_CONTROL, flag)
4871endfunction
4872
4873//===========================================================================
4874function SetPlayerAllianceStateBJ takes player sourcePlayer, player otherPlayer, integer allianceState returns nothing
4875 // Prevent players from attempting to ally with themselves.
4876 if (sourcePlayer == otherPlayer) then
4877 return
4878 endif
4879
4880 if allianceState == bj_ALLIANCE_UNALLIED then
4881 call SetPlayerAllianceStateAllyBJ( sourcePlayer, otherPlayer, false )
4882 call SetPlayerAllianceStateVisionBJ( sourcePlayer, otherPlayer, false )
4883 call SetPlayerAllianceStateControlBJ( sourcePlayer, otherPlayer, false )
4884 call SetPlayerAllianceStateFullControlBJ( sourcePlayer, otherPlayer, false )
4885 elseif allianceState == bj_ALLIANCE_UNALLIED_VISION then
4886 call SetPlayerAllianceStateAllyBJ( sourcePlayer, otherPlayer, false )
4887 call SetPlayerAllianceStateVisionBJ( sourcePlayer, otherPlayer, true )
4888 call SetPlayerAllianceStateControlBJ( sourcePlayer, otherPlayer, false )
4889 call SetPlayerAllianceStateFullControlBJ( sourcePlayer, otherPlayer, false )
4890 elseif allianceState == bj_ALLIANCE_ALLIED then
4891 call SetPlayerAllianceStateAllyBJ( sourcePlayer, otherPlayer, true )
4892 call SetPlayerAllianceStateVisionBJ( sourcePlayer, otherPlayer, false )
4893 call SetPlayerAllianceStateControlBJ( sourcePlayer, otherPlayer, false )
4894 call SetPlayerAllianceStateFullControlBJ( sourcePlayer, otherPlayer, false )
4895 elseif allianceState == bj_ALLIANCE_ALLIED_VISION then
4896 call SetPlayerAllianceStateAllyBJ( sourcePlayer, otherPlayer, true )
4897 call SetPlayerAllianceStateVisionBJ( sourcePlayer, otherPlayer, true )
4898 call SetPlayerAllianceStateControlBJ( sourcePlayer, otherPlayer, false )
4899 call SetPlayerAllianceStateFullControlBJ( sourcePlayer, otherPlayer, false )
4900 elseif allianceState == bj_ALLIANCE_ALLIED_UNITS then
4901 call SetPlayerAllianceStateAllyBJ( sourcePlayer, otherPlayer, true )
4902 call SetPlayerAllianceStateVisionBJ( sourcePlayer, otherPlayer, true )
4903 call SetPlayerAllianceStateControlBJ( sourcePlayer, otherPlayer, true )
4904 call SetPlayerAllianceStateFullControlBJ( sourcePlayer, otherPlayer, false )
4905 elseif allianceState == bj_ALLIANCE_ALLIED_ADVUNITS then
4906 call SetPlayerAllianceStateAllyBJ( sourcePlayer, otherPlayer, true )
4907 call SetPlayerAllianceStateVisionBJ( sourcePlayer, otherPlayer, true )
4908 call SetPlayerAllianceStateControlBJ( sourcePlayer, otherPlayer, true )
4909 call SetPlayerAllianceStateFullControlBJ( sourcePlayer, otherPlayer, true )
4910 elseif allianceState == bj_ALLIANCE_NEUTRAL then
4911 call SetPlayerAllianceStateAllyBJ( sourcePlayer, otherPlayer, false )
4912 call SetPlayerAllianceStateVisionBJ( sourcePlayer, otherPlayer, false )
4913 call SetPlayerAllianceStateControlBJ( sourcePlayer, otherPlayer, false )
4914 call SetPlayerAllianceStateFullControlBJ( sourcePlayer, otherPlayer, false )
4915 call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_PASSIVE, true )
4916 elseif allianceState == bj_ALLIANCE_NEUTRAL_VISION then
4917 call SetPlayerAllianceStateAllyBJ( sourcePlayer, otherPlayer, false )
4918 call SetPlayerAllianceStateVisionBJ( sourcePlayer, otherPlayer, true )
4919 call SetPlayerAllianceStateControlBJ( sourcePlayer, otherPlayer, false )
4920 call SetPlayerAllianceStateFullControlBJ( sourcePlayer, otherPlayer, false )
4921 call SetPlayerAlliance( sourcePlayer, otherPlayer, ALLIANCE_PASSIVE, true )
4922 else
4923 // Unrecognized alliance state - ignore the request.
4924 endif
4925endfunction
4926
4927//===========================================================================
4928// Set the alliance states for an entire force towards another force.
4929//
4930function SetForceAllianceStateBJ takes force sourceForce, force targetForce, integer allianceState returns nothing
4931 local integer sourceIndex
4932 local integer targetIndex
4933
4934 set sourceIndex = 0
4935 loop
4936
4937 if (sourceForce==bj_FORCE_ALL_PLAYERS or IsPlayerInForce(Player(sourceIndex), sourceForce)) then
4938 set targetIndex = 0
4939 loop
4940 if (targetForce==bj_FORCE_ALL_PLAYERS or IsPlayerInForce(Player(targetIndex), targetForce)) then
4941 call SetPlayerAllianceStateBJ(Player(sourceIndex), Player(targetIndex), allianceState)
4942 endif
4943
4944 set targetIndex = targetIndex + 1
4945 exitwhen targetIndex == bj_MAX_PLAYER_SLOTS
4946 endloop
4947 endif
4948
4949 set sourceIndex = sourceIndex + 1
4950 exitwhen sourceIndex == bj_MAX_PLAYER_SLOTS
4951 endloop
4952endfunction
4953
4954//===========================================================================
4955// Test to see if two players are co-allied (allied with each other).
4956//
4957function PlayersAreCoAllied takes player playerA, player playerB returns boolean
4958 // Players are considered to be allied with themselves.
4959 if (playerA == playerB) then
4960 return true
4961 endif
4962
4963 // Co-allies are both allied with each other.
4964 if GetPlayerAlliance(playerA, playerB, ALLIANCE_PASSIVE) then
4965 if GetPlayerAlliance(playerB, playerA, ALLIANCE_PASSIVE) then
4966 return true
4967 endif
4968 endif
4969 return false
4970endfunction
4971
4972//===========================================================================
4973// Force (whichPlayer) AI player to share vision and advanced unit control
4974// with all AI players of its allies.
4975//
4976function ShareEverythingWithTeamAI takes player whichPlayer returns nothing
4977 local integer playerIndex
4978 local player indexPlayer
4979
4980 set playerIndex = 0
4981 loop
4982 set indexPlayer = Player(playerIndex)
4983 if (PlayersAreCoAllied(whichPlayer, indexPlayer) and whichPlayer != indexPlayer) then
4984 if (GetPlayerController(indexPlayer) == MAP_CONTROL_COMPUTER) then
4985 call SetPlayerAlliance(whichPlayer, indexPlayer, ALLIANCE_SHARED_VISION, true)
4986 call SetPlayerAlliance(whichPlayer, indexPlayer, ALLIANCE_SHARED_CONTROL, true)
4987 call SetPlayerAlliance(whichPlayer, indexPlayer, ALLIANCE_SHARED_ADVANCED_CONTROL, true)
4988 endif
4989 endif
4990
4991 set playerIndex = playerIndex + 1
4992 exitwhen playerIndex == bj_MAX_PLAYERS
4993 endloop
4994endfunction
4995
4996//===========================================================================
4997// Force (whichPlayer) to share vision and advanced unit control with all of his/her allies.
4998//
4999function ShareEverythingWithTeam takes player whichPlayer returns nothing
5000 local integer playerIndex
5001 local player indexPlayer
5002
5003 set playerIndex = 0
5004 loop
5005 set indexPlayer = Player(playerIndex)
5006 if (PlayersAreCoAllied(whichPlayer, indexPlayer) and whichPlayer != indexPlayer) then
5007 call SetPlayerAlliance(whichPlayer, indexPlayer, ALLIANCE_SHARED_VISION, true)
5008 call SetPlayerAlliance(whichPlayer, indexPlayer, ALLIANCE_SHARED_CONTROL, true)
5009 call SetPlayerAlliance(indexPlayer, whichPlayer, ALLIANCE_SHARED_CONTROL, true)
5010 call SetPlayerAlliance(whichPlayer, indexPlayer, ALLIANCE_SHARED_ADVANCED_CONTROL, true)
5011 endif
5012
5013 set playerIndex = playerIndex + 1
5014 exitwhen playerIndex == bj_MAX_PLAYERS
5015 endloop
5016endfunction
5017
5018//===========================================================================
5019// Creates a 'Neutral Victim' player slot. This slot is passive towards all
5020// other players, but all other players are aggressive towards him/her.
5021//
5022function ConfigureNeutralVictim takes nothing returns nothing
5023 local integer index
5024 local player indexPlayer
5025 local player neutralVictim = Player(bj_PLAYER_NEUTRAL_VICTIM)
5026
5027 set index = 0
5028 loop
5029 set indexPlayer = Player(index)
5030
5031 call SetPlayerAlliance(neutralVictim, indexPlayer, ALLIANCE_PASSIVE, true)
5032 call SetPlayerAlliance(indexPlayer, neutralVictim, ALLIANCE_PASSIVE, false)
5033
5034 set index = index + 1
5035 exitwhen index == bj_MAX_PLAYERS
5036 endloop
5037
5038 // Neutral Victim and Neutral Aggressive should not fight each other.
5039 set indexPlayer = Player(PLAYER_NEUTRAL_AGGRESSIVE)
5040 call SetPlayerAlliance(neutralVictim, indexPlayer, ALLIANCE_PASSIVE, true)
5041 call SetPlayerAlliance(indexPlayer, neutralVictim, ALLIANCE_PASSIVE, true)
5042
5043 // Neutral Victim does not give bounties.
5044 call SetPlayerState(neutralVictim, PLAYER_STATE_GIVES_BOUNTY, 0)
5045endfunction
5046
5047//===========================================================================
5048function MakeUnitsPassiveForPlayerEnum takes nothing returns nothing
5049 call SetUnitOwner(GetEnumUnit(), Player(bj_PLAYER_NEUTRAL_VICTIM), false)
5050endfunction
5051
5052//===========================================================================
5053// Change ownership for every unit of (whichPlayer)'s team to neutral passive.
5054//
5055function MakeUnitsPassiveForPlayer takes player whichPlayer returns nothing
5056 local group playerUnits = CreateGroup()
5057 call CachePlayerHeroData(whichPlayer)
5058 call GroupEnumUnitsOfPlayer(playerUnits, whichPlayer, null)
5059 call ForGroup(playerUnits, function MakeUnitsPassiveForPlayerEnum)
5060 call DestroyGroup(playerUnits)
5061endfunction
5062
5063//===========================================================================
5064// Change ownership for every unit of (whichPlayer)'s team to neutral passive.
5065//
5066function MakeUnitsPassiveForTeam takes player whichPlayer returns nothing
5067 local integer playerIndex
5068 local player indexPlayer
5069
5070 set playerIndex = 0
5071 loop
5072 set indexPlayer = Player(playerIndex)
5073 if PlayersAreCoAllied(whichPlayer, indexPlayer) then
5074 call MakeUnitsPassiveForPlayer(indexPlayer)
5075 endif
5076
5077 set playerIndex = playerIndex + 1
5078 exitwhen playerIndex == bj_MAX_PLAYERS
5079 endloop
5080endfunction
5081
5082//===========================================================================
5083// Determine whether or not victory/defeat is disabled via cheat codes.
5084//
5085function AllowVictoryDefeat takes playergameresult gameResult returns boolean
5086 if (gameResult == PLAYER_GAME_RESULT_VICTORY) then
5087 return not IsNoVictoryCheat()
5088 endif
5089 if (gameResult == PLAYER_GAME_RESULT_DEFEAT) then
5090 return not IsNoDefeatCheat()
5091 endif
5092 if (gameResult == PLAYER_GAME_RESULT_NEUTRAL) then
5093 return (not IsNoVictoryCheat()) and (not IsNoDefeatCheat())
5094 endif
5095 return true
5096endfunction
5097
5098//===========================================================================
5099function EndGameBJ takes nothing returns nothing
5100 call EndGame( true )
5101endfunction
5102
5103//===========================================================================
5104function MeleeVictoryDialogBJ takes player whichPlayer, boolean leftGame returns nothing
5105 local trigger t = CreateTrigger()
5106 local dialog d = DialogCreate()
5107 local string formatString
5108
5109 // Display "player was victorious" or "player has left the game" message
5110 if (leftGame) then
5111 set formatString = GetLocalizedString( "PLAYER_LEFT_GAME" )
5112 else
5113 set formatString = GetLocalizedString( "PLAYER_VICTORIOUS" )
5114 endif
5115
5116 call DisplayTimedTextFromPlayer(whichPlayer, 0, 0, 60, formatString)
5117
5118 call DialogSetMessage( d, GetLocalizedString( "GAMEOVER_VICTORY_MSG" ) )
5119 call DialogAddButton( d, GetLocalizedString( "GAMEOVER_CONTINUE_GAME" ), GetLocalizedHotkey("GAMEOVER_CONTINUE_GAME") )
5120
5121 set t = CreateTrigger()
5122 call TriggerRegisterDialogButtonEvent( t, DialogAddQuitButton( d, true, GetLocalizedString( "GAMEOVER_QUIT_GAME" ), GetLocalizedHotkey("GAMEOVER_QUIT_GAME") ) )
5123
5124 call DialogDisplay( whichPlayer, d, true )
5125 call StartSoundForPlayerBJ( whichPlayer, bj_victoryDialogSound )
5126endfunction
5127
5128//===========================================================================
5129function MeleeDefeatDialogBJ takes player whichPlayer, boolean leftGame returns nothing
5130 local trigger t = CreateTrigger()
5131 local dialog d = DialogCreate()
5132 local string formatString
5133
5134 // Display "player was defeated" or "player has left the game" message
5135 if (leftGame) then
5136 set formatString = GetLocalizedString( "PLAYER_LEFT_GAME" )
5137 else
5138 set formatString = GetLocalizedString( "PLAYER_DEFEATED" )
5139 endif
5140
5141 call DisplayTimedTextFromPlayer(whichPlayer, 0, 0, 60, formatString)
5142
5143 call DialogSetMessage( d, GetLocalizedString( "GAMEOVER_DEFEAT_MSG" ) )
5144
5145 // Only show the continue button if the game is not over and observers on death are allowed
5146 if (not bj_meleeGameOver and IsMapFlagSet(MAP_OBSERVERS_ON_DEATH)) then
5147 call DialogAddButton( d, GetLocalizedString( "GAMEOVER_CONTINUE_OBSERVING" ), GetLocalizedHotkey("GAMEOVER_CONTINUE_OBSERVING") )
5148 endif
5149
5150 set t = CreateTrigger()
5151 call TriggerRegisterDialogButtonEvent( t, DialogAddQuitButton( d, true, GetLocalizedString( "GAMEOVER_QUIT_GAME" ), GetLocalizedHotkey("GAMEOVER_QUIT_GAME") ) )
5152
5153 call DialogDisplay( whichPlayer, d, true )
5154 call StartSoundForPlayerBJ( whichPlayer, bj_defeatDialogSound )
5155endfunction
5156
5157//===========================================================================
5158function GameOverDialogBJ takes player whichPlayer, boolean leftGame returns nothing
5159 local trigger t = CreateTrigger()
5160 local dialog d = DialogCreate()
5161 local string s
5162
5163 // Display "player left the game" message
5164 call DisplayTimedTextFromPlayer(whichPlayer, 0, 0, 60, GetLocalizedString( "PLAYER_LEFT_GAME" ))
5165
5166 if (GetIntegerGameState(GAME_STATE_DISCONNECTED) != 0) then
5167 set s = GetLocalizedString( "GAMEOVER_DISCONNECTED" )
5168 else
5169 set s = GetLocalizedString( "GAMEOVER_GAME_OVER" )
5170 endif
5171
5172 call DialogSetMessage( d, s )
5173
5174 set t = CreateTrigger()
5175 call TriggerRegisterDialogButtonEvent( t, DialogAddQuitButton( d, true, GetLocalizedString( "GAMEOVER_OK" ), GetLocalizedHotkey("GAMEOVER_OK") ) )
5176
5177 call DialogDisplay( whichPlayer, d, true )
5178 call StartSoundForPlayerBJ( whichPlayer, bj_defeatDialogSound )
5179endfunction
5180
5181//===========================================================================
5182function RemovePlayerPreserveUnitsBJ takes player whichPlayer, playergameresult gameResult, boolean leftGame returns nothing
5183 if AllowVictoryDefeat(gameResult) then
5184
5185 call RemovePlayer(whichPlayer, gameResult)
5186
5187 if( gameResult == PLAYER_GAME_RESULT_VICTORY ) then
5188 call MeleeVictoryDialogBJ( whichPlayer, leftGame )
5189 return
5190 elseif( gameResult == PLAYER_GAME_RESULT_DEFEAT ) then
5191 call MeleeDefeatDialogBJ( whichPlayer, leftGame )
5192 else
5193 call GameOverDialogBJ( whichPlayer, leftGame )
5194 endif
5195
5196 endif
5197endfunction
5198
5199//===========================================================================
5200function CustomVictoryOkBJ takes nothing returns nothing
5201 if bj_isSinglePlayer then
5202 call PauseGame( false )
5203 // Bump the difficulty back up to the default.
5204 call SetGameDifficulty(GetDefaultDifficulty())
5205 endif
5206
5207 if (bj_changeLevelMapName == null) then
5208 call EndGame( bj_changeLevelShowScores )
5209 else
5210 call ChangeLevel( bj_changeLevelMapName, bj_changeLevelShowScores )
5211 endif
5212endfunction
5213
5214//===========================================================================
5215function CustomVictoryQuitBJ takes nothing returns nothing
5216 if bj_isSinglePlayer then
5217 call PauseGame( false )
5218 // Bump the difficulty back up to the default.
5219 call SetGameDifficulty(GetDefaultDifficulty())
5220 endif
5221
5222 call EndGame( bj_changeLevelShowScores )
5223endfunction
5224
5225//===========================================================================
5226function CustomVictoryDialogBJ takes player whichPlayer returns nothing
5227 local trigger t = CreateTrigger()
5228 local dialog d = DialogCreate()
5229
5230 call DialogSetMessage( d, GetLocalizedString( "GAMEOVER_VICTORY_MSG" ) )
5231
5232 set t = CreateTrigger()
5233 call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, GetLocalizedString( "GAMEOVER_CONTINUE" ), GetLocalizedHotkey("GAMEOVER_CONTINUE") ) )
5234 call TriggerAddAction( t, function CustomVictoryOkBJ )
5235
5236 set t = CreateTrigger()
5237 call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, GetLocalizedString( "GAMEOVER_QUIT_MISSION" ), GetLocalizedHotkey("GAMEOVER_QUIT_MISSION") ) )
5238 call TriggerAddAction( t, function CustomVictoryQuitBJ )
5239
5240 if (GetLocalPlayer() == whichPlayer) then
5241 call EnableUserControl( true )
5242 if bj_isSinglePlayer then
5243 call PauseGame( true )
5244 endif
5245 call EnableUserUI(false)
5246 endif
5247
5248 call DialogDisplay( whichPlayer, d, true )
5249 call VolumeGroupSetVolumeForPlayerBJ( whichPlayer, SOUND_VOLUMEGROUP_UI, 1.0 )
5250 call StartSoundForPlayerBJ( whichPlayer, bj_victoryDialogSound )
5251endfunction
5252
5253//===========================================================================
5254function CustomVictorySkipBJ takes player whichPlayer returns nothing
5255 if (GetLocalPlayer() == whichPlayer) then
5256 if bj_isSinglePlayer then
5257 // Bump the difficulty back up to the default.
5258 call SetGameDifficulty(GetDefaultDifficulty())
5259 endif
5260
5261 if (bj_changeLevelMapName == null) then
5262 call EndGame( bj_changeLevelShowScores )
5263 else
5264 call ChangeLevel( bj_changeLevelMapName, bj_changeLevelShowScores )
5265 endif
5266 endif
5267endfunction
5268
5269//===========================================================================
5270function CustomVictoryBJ takes player whichPlayer, boolean showDialog, boolean showScores returns nothing
5271 if AllowVictoryDefeat( PLAYER_GAME_RESULT_VICTORY ) then
5272 call RemovePlayer( whichPlayer, PLAYER_GAME_RESULT_VICTORY )
5273
5274 if not bj_isSinglePlayer then
5275 call DisplayTimedTextFromPlayer(whichPlayer, 0, 0, 60, GetLocalizedString( "PLAYER_VICTORIOUS" ) )
5276 endif
5277
5278 // UI only needs to be displayed to users.
5279 if (GetPlayerController(whichPlayer) == MAP_CONTROL_USER) then
5280 set bj_changeLevelShowScores = showScores
5281 if showDialog then
5282 call CustomVictoryDialogBJ( whichPlayer )
5283 else
5284 call CustomVictorySkipBJ( whichPlayer )
5285 endif
5286 endif
5287 endif
5288endfunction
5289
5290//===========================================================================
5291function CustomDefeatRestartBJ takes nothing returns nothing
5292 call PauseGame( false )
5293 call RestartGame( true )
5294endfunction
5295
5296//===========================================================================
5297function CustomDefeatReduceDifficultyBJ takes nothing returns nothing
5298 local gamedifficulty diff = GetGameDifficulty()
5299
5300 call PauseGame( false )
5301
5302 // Knock the difficulty down, if possible.
5303 if (diff == MAP_DIFFICULTY_EASY) then
5304 // Sorry, but it doesn't get any easier than this.
5305 elseif (diff == MAP_DIFFICULTY_NORMAL) then
5306 call SetGameDifficulty(MAP_DIFFICULTY_EASY)
5307 elseif (diff == MAP_DIFFICULTY_HARD) then
5308 call SetGameDifficulty(MAP_DIFFICULTY_NORMAL)
5309 else
5310 // Unrecognized difficulty
5311 endif
5312
5313 call RestartGame( true )
5314endfunction
5315
5316//===========================================================================
5317function CustomDefeatLoadBJ takes nothing returns nothing
5318 call PauseGame( false )
5319 call DisplayLoadDialog()
5320endfunction
5321
5322//===========================================================================
5323function CustomDefeatQuitBJ takes nothing returns nothing
5324 if bj_isSinglePlayer then
5325 call PauseGame( false )
5326 endif
5327
5328 // Bump the difficulty back up to the default.
5329 call SetGameDifficulty(GetDefaultDifficulty())
5330 call EndGame( true )
5331endfunction
5332
5333//===========================================================================
5334function CustomDefeatDialogBJ takes player whichPlayer, string message returns nothing
5335 local trigger t = CreateTrigger()
5336 local dialog d = DialogCreate()
5337
5338 call DialogSetMessage( d, message )
5339
5340 if bj_isSinglePlayer then
5341 set t = CreateTrigger()
5342 call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, GetLocalizedString( "GAMEOVER_RESTART" ), GetLocalizedHotkey("GAMEOVER_RESTART") ) )
5343 call TriggerAddAction( t, function CustomDefeatRestartBJ )
5344
5345 if (GetGameDifficulty() != MAP_DIFFICULTY_EASY) then
5346 set t = CreateTrigger()
5347 call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, GetLocalizedString( "GAMEOVER_REDUCE_DIFFICULTY" ), GetLocalizedHotkey("GAMEOVER_REDUCE_DIFFICULTY") ) )
5348 call TriggerAddAction( t, function CustomDefeatReduceDifficultyBJ )
5349 endif
5350
5351 set t = CreateTrigger()
5352 call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, GetLocalizedString( "GAMEOVER_LOAD" ), GetLocalizedHotkey("GAMEOVER_LOAD") ) )
5353 call TriggerAddAction( t, function CustomDefeatLoadBJ )
5354 endif
5355
5356 set t = CreateTrigger()
5357 call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, GetLocalizedString( "GAMEOVER_QUIT_MISSION" ), GetLocalizedHotkey("GAMEOVER_QUIT_MISSION") ) )
5358 call TriggerAddAction( t, function CustomDefeatQuitBJ )
5359
5360 if (GetLocalPlayer() == whichPlayer) then
5361 call EnableUserControl( true )
5362 if bj_isSinglePlayer then
5363 call PauseGame( true )
5364 endif
5365 call EnableUserUI(false)
5366 endif
5367
5368 call DialogDisplay( whichPlayer, d, true )
5369 call VolumeGroupSetVolumeForPlayerBJ( whichPlayer, SOUND_VOLUMEGROUP_UI, 1.0 )
5370 call StartSoundForPlayerBJ( whichPlayer, bj_defeatDialogSound )
5371endfunction
5372
5373//===========================================================================
5374function CustomDefeatBJ takes player whichPlayer, string message returns nothing
5375 if AllowVictoryDefeat( PLAYER_GAME_RESULT_DEFEAT ) then
5376 call RemovePlayer( whichPlayer, PLAYER_GAME_RESULT_DEFEAT )
5377
5378 if not bj_isSinglePlayer then
5379 call DisplayTimedTextFromPlayer(whichPlayer, 0, 0, 60, GetLocalizedString( "PLAYER_DEFEATED" ) )
5380 endif
5381
5382 // UI only needs to be displayed to users.
5383 if (GetPlayerController(whichPlayer) == MAP_CONTROL_USER) then
5384 call CustomDefeatDialogBJ( whichPlayer, message )
5385 endif
5386 endif
5387endfunction
5388
5389//===========================================================================
5390function SetNextLevelBJ takes string nextLevel returns nothing
5391 if (nextLevel == "") then
5392 set bj_changeLevelMapName = null
5393 else
5394 set bj_changeLevelMapName = nextLevel
5395 endif
5396endfunction
5397
5398//===========================================================================
5399function SetPlayerOnScoreScreenBJ takes boolean flag, player whichPlayer returns nothing
5400 call SetPlayerOnScoreScreen(whichPlayer, flag)
5401endfunction
5402
5403
5404
5405//***************************************************************************
5406//*
5407//* Quest Utility Functions
5408//*
5409//***************************************************************************
5410
5411//===========================================================================
5412function CreateQuestBJ takes integer questType, string title, string description, string iconPath returns quest
5413 local boolean required = (questType == bj_QUESTTYPE_REQ_DISCOVERED) or (questType == bj_QUESTTYPE_REQ_UNDISCOVERED)
5414 local boolean discovered = (questType == bj_QUESTTYPE_REQ_DISCOVERED) or (questType == bj_QUESTTYPE_OPT_DISCOVERED)
5415
5416 set bj_lastCreatedQuest = CreateQuest()
5417 call QuestSetTitle(bj_lastCreatedQuest, title)
5418 call QuestSetDescription(bj_lastCreatedQuest, description)
5419 call QuestSetIconPath(bj_lastCreatedQuest, iconPath)
5420 call QuestSetRequired(bj_lastCreatedQuest, required)
5421 call QuestSetDiscovered(bj_lastCreatedQuest, discovered)
5422 call QuestSetCompleted(bj_lastCreatedQuest, false)
5423 return bj_lastCreatedQuest
5424endfunction
5425
5426//===========================================================================
5427function DestroyQuestBJ takes quest whichQuest returns nothing
5428 call DestroyQuest(whichQuest)
5429endfunction
5430
5431//===========================================================================
5432function QuestSetEnabledBJ takes boolean enabled, quest whichQuest returns nothing
5433 call QuestSetEnabled(whichQuest, enabled)
5434endfunction
5435
5436//===========================================================================
5437function QuestSetTitleBJ takes quest whichQuest, string title returns nothing
5438 call QuestSetTitle(whichQuest, title)
5439endfunction
5440
5441//===========================================================================
5442function QuestSetDescriptionBJ takes quest whichQuest, string description returns nothing
5443 call QuestSetDescription(whichQuest, description)
5444endfunction
5445
5446//===========================================================================
5447function QuestSetCompletedBJ takes quest whichQuest, boolean completed returns nothing
5448 call QuestSetCompleted(whichQuest, completed)
5449endfunction
5450
5451//===========================================================================
5452function QuestSetFailedBJ takes quest whichQuest, boolean failed returns nothing
5453 call QuestSetFailed(whichQuest, failed)
5454endfunction
5455
5456//===========================================================================
5457function QuestSetDiscoveredBJ takes quest whichQuest, boolean discovered returns nothing
5458 call QuestSetDiscovered(whichQuest, discovered)
5459endfunction
5460
5461//===========================================================================
5462function GetLastCreatedQuestBJ takes nothing returns quest
5463 return bj_lastCreatedQuest
5464endfunction
5465
5466//===========================================================================
5467function CreateQuestItemBJ takes quest whichQuest, string description returns questitem
5468 set bj_lastCreatedQuestItem = QuestCreateItem(whichQuest)
5469 call QuestItemSetDescription(bj_lastCreatedQuestItem, description)
5470 call QuestItemSetCompleted(bj_lastCreatedQuestItem, false)
5471 return bj_lastCreatedQuestItem
5472endfunction
5473
5474//===========================================================================
5475function QuestItemSetDescriptionBJ takes questitem whichQuestItem, string description returns nothing
5476 call QuestItemSetDescription(whichQuestItem, description)
5477endfunction
5478
5479//===========================================================================
5480function QuestItemSetCompletedBJ takes questitem whichQuestItem, boolean completed returns nothing
5481 call QuestItemSetCompleted(whichQuestItem, completed)
5482endfunction
5483
5484//===========================================================================
5485function GetLastCreatedQuestItemBJ takes nothing returns questitem
5486 return bj_lastCreatedQuestItem
5487endfunction
5488
5489//===========================================================================
5490function CreateDefeatConditionBJ takes string description returns defeatcondition
5491 set bj_lastCreatedDefeatCondition = CreateDefeatCondition()
5492 call DefeatConditionSetDescription(bj_lastCreatedDefeatCondition, description)
5493 return bj_lastCreatedDefeatCondition
5494endfunction
5495
5496//===========================================================================
5497function DestroyDefeatConditionBJ takes defeatcondition whichCondition returns nothing
5498 call DestroyDefeatCondition(whichCondition)
5499endfunction
5500
5501//===========================================================================
5502function DefeatConditionSetDescriptionBJ takes defeatcondition whichCondition, string description returns nothing
5503 call DefeatConditionSetDescription(whichCondition, description)
5504endfunction
5505
5506//===========================================================================
5507function GetLastCreatedDefeatConditionBJ takes nothing returns defeatcondition
5508 return bj_lastCreatedDefeatCondition
5509endfunction
5510
5511//===========================================================================
5512function FlashQuestDialogButtonBJ takes nothing returns nothing
5513 call FlashQuestDialogButton()
5514endfunction
5515
5516//===========================================================================
5517function QuestMessageBJ takes force f, integer messageType, string message returns nothing
5518 if (IsPlayerInForce(GetLocalPlayer(), f)) then
5519 // Use only local code (no net traffic) within this block to avoid desyncs.
5520
5521 if (messageType == bj_QUESTMESSAGE_DISCOVERED) then
5522 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUEST, " ")
5523 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUEST, message)
5524 call StartSound(bj_questDiscoveredSound)
5525 call FlashQuestDialogButton()
5526
5527 elseif (messageType == bj_QUESTMESSAGE_UPDATED) then
5528 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUESTUPDATE, " ")
5529 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUESTUPDATE, message)
5530 call StartSound(bj_questUpdatedSound)
5531 call FlashQuestDialogButton()
5532
5533 elseif (messageType == bj_QUESTMESSAGE_COMPLETED) then
5534 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUESTDONE, " ")
5535 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUESTDONE, message)
5536 call StartSound(bj_questCompletedSound)
5537 call FlashQuestDialogButton()
5538
5539 elseif (messageType == bj_QUESTMESSAGE_FAILED) then
5540 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUESTFAILED, " ")
5541 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUESTFAILED, message)
5542 call StartSound(bj_questFailedSound)
5543 call FlashQuestDialogButton()
5544
5545 elseif (messageType == bj_QUESTMESSAGE_REQUIREMENT) then
5546 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_QUESTREQUIREMENT, message)
5547
5548 elseif (messageType == bj_QUESTMESSAGE_MISSIONFAILED) then
5549 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_MISSIONFAILED, " ")
5550 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_MISSIONFAILED, message)
5551 call StartSound(bj_questFailedSound)
5552
5553 elseif (messageType == bj_QUESTMESSAGE_HINT) then
5554 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_HINT, " ")
5555 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_HINT, message)
5556 call StartSound(bj_questHintSound)
5557
5558 elseif (messageType == bj_QUESTMESSAGE_ALWAYSHINT) then
5559 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_ALWAYSHINT, " ")
5560 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_ALWAYSHINT, message)
5561 call StartSound(bj_questHintSound)
5562
5563 elseif (messageType == bj_QUESTMESSAGE_SECRET) then
5564 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_SECRET, " ")
5565 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_SECRET, message)
5566 call StartSound(bj_questSecretSound)
5567
5568 elseif (messageType == bj_QUESTMESSAGE_UNITACQUIRED) then
5569 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_UNITACQUIRED, " ")
5570 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_UNITACQUIRED, message)
5571 call StartSound(bj_questHintSound)
5572
5573 elseif (messageType == bj_QUESTMESSAGE_UNITAVAILABLE) then
5574 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_UNITAVAILABLE, " ")
5575 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_UNITAVAILABLE, message)
5576 call StartSound(bj_questHintSound)
5577
5578 elseif (messageType == bj_QUESTMESSAGE_ITEMACQUIRED) then
5579 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_ITEMACQUIRED, " ")
5580 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_ITEMACQUIRED, message)
5581 call StartSound(bj_questItemAcquiredSound)
5582
5583 elseif (messageType == bj_QUESTMESSAGE_WARNING) then
5584 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_WARNING, " ")
5585 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_TEXT_DELAY_WARNING, message)
5586 call StartSound(bj_questWarningSound)
5587
5588 else
5589 // Unrecognized message type - ignore the request.
5590 endif
5591 endif
5592endfunction
5593
5594
5595
5596//***************************************************************************
5597//*
5598//* Timer Utility Functions
5599//*
5600//***************************************************************************
5601
5602//===========================================================================
5603function StartTimerBJ takes timer t, boolean periodic, real timeout returns timer
5604 set bj_lastStartedTimer = t
5605 call TimerStart(t, timeout, periodic, null)
5606 return bj_lastStartedTimer
5607endfunction
5608
5609//===========================================================================
5610function CreateTimerBJ takes boolean periodic, real timeout returns timer
5611 set bj_lastStartedTimer = CreateTimer()
5612 call TimerStart(bj_lastStartedTimer, timeout, periodic, null)
5613 return bj_lastStartedTimer
5614endfunction
5615
5616//===========================================================================
5617function DestroyTimerBJ takes timer whichTimer returns nothing
5618 call DestroyTimer(whichTimer)
5619endfunction
5620
5621//===========================================================================
5622function PauseTimerBJ takes boolean pause, timer whichTimer returns nothing
5623 if pause then
5624 call PauseTimer(whichTimer)
5625 else
5626 call ResumeTimer(whichTimer)
5627 endif
5628endfunction
5629
5630//===========================================================================
5631function GetLastCreatedTimerBJ takes nothing returns timer
5632 return bj_lastStartedTimer
5633endfunction
5634
5635//===========================================================================
5636function CreateTimerDialogBJ takes timer t, string title returns timerdialog
5637 set bj_lastCreatedTimerDialog = CreateTimerDialog(t)
5638 call TimerDialogSetTitle(bj_lastCreatedTimerDialog, title)
5639 call TimerDialogDisplay(bj_lastCreatedTimerDialog, true)
5640 return bj_lastCreatedTimerDialog
5641endfunction
5642
5643//===========================================================================
5644function DestroyTimerDialogBJ takes timerdialog td returns nothing
5645 call DestroyTimerDialog(td)
5646endfunction
5647
5648//===========================================================================
5649function TimerDialogSetTitleBJ takes timerdialog td, string title returns nothing
5650 call TimerDialogSetTitle(td, title)
5651endfunction
5652
5653//===========================================================================
5654function TimerDialogSetTitleColorBJ takes timerdialog td, real red, real green, real blue, real transparency returns nothing
5655 call TimerDialogSetTitleColor(td, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
5656endfunction
5657
5658//===========================================================================
5659function TimerDialogSetTimeColorBJ takes timerdialog td, real red, real green, real blue, real transparency returns nothing
5660 call TimerDialogSetTimeColor(td, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
5661endfunction
5662
5663//===========================================================================
5664function TimerDialogSetSpeedBJ takes timerdialog td, real speedMultFactor returns nothing
5665 call TimerDialogSetSpeed(td, speedMultFactor)
5666endfunction
5667
5668//===========================================================================
5669function TimerDialogDisplayForPlayerBJ takes boolean show, timerdialog td, player whichPlayer returns nothing
5670 if (GetLocalPlayer() == whichPlayer) then
5671 // Use only local code (no net traffic) within this block to avoid desyncs.
5672 call TimerDialogDisplay(td, show)
5673 endif
5674endfunction
5675
5676//===========================================================================
5677function TimerDialogDisplayBJ takes boolean show, timerdialog td returns nothing
5678 call TimerDialogDisplay(td, show)
5679endfunction
5680
5681//===========================================================================
5682function GetLastCreatedTimerDialogBJ takes nothing returns timerdialog
5683 return bj_lastCreatedTimerDialog
5684endfunction
5685
5686
5687
5688//***************************************************************************
5689//*
5690//* Leaderboard Utility Functions
5691//*
5692//***************************************************************************
5693
5694//===========================================================================
5695function LeaderboardResizeBJ takes leaderboard lb returns nothing
5696 local integer size = LeaderboardGetItemCount(lb)
5697
5698 if (LeaderboardGetLabelText(lb) == "") then
5699 set size = size - 1
5700 endif
5701 call LeaderboardSetSizeByItemCount(lb, size)
5702endfunction
5703
5704//===========================================================================
5705function LeaderboardSetPlayerItemValueBJ takes player whichPlayer, leaderboard lb, integer val returns nothing
5706 call LeaderboardSetItemValue(lb, LeaderboardGetPlayerIndex(lb, whichPlayer), val)
5707endfunction
5708
5709//===========================================================================
5710function LeaderboardSetPlayerItemLabelBJ takes player whichPlayer, leaderboard lb, string val returns nothing
5711 call LeaderboardSetItemLabel(lb, LeaderboardGetPlayerIndex(lb, whichPlayer), val)
5712endfunction
5713
5714//===========================================================================
5715function LeaderboardSetPlayerItemStyleBJ takes player whichPlayer, leaderboard lb, boolean showLabel, boolean showValue, boolean showIcon returns nothing
5716 call LeaderboardSetItemStyle(lb, LeaderboardGetPlayerIndex(lb, whichPlayer), showLabel, showValue, showIcon)
5717endfunction
5718
5719//===========================================================================
5720function LeaderboardSetPlayerItemLabelColorBJ takes player whichPlayer, leaderboard lb, real red, real green, real blue, real transparency returns nothing
5721 call LeaderboardSetItemLabelColor(lb, LeaderboardGetPlayerIndex(lb, whichPlayer), PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
5722endfunction
5723
5724//===========================================================================
5725function LeaderboardSetPlayerItemValueColorBJ takes player whichPlayer, leaderboard lb, real red, real green, real blue, real transparency returns nothing
5726 call LeaderboardSetItemValueColor(lb, LeaderboardGetPlayerIndex(lb, whichPlayer), PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
5727endfunction
5728
5729//===========================================================================
5730function LeaderboardSetLabelColorBJ takes leaderboard lb, real red, real green, real blue, real transparency returns nothing
5731 call LeaderboardSetLabelColor(lb, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
5732endfunction
5733
5734//===========================================================================
5735function LeaderboardSetValueColorBJ takes leaderboard lb, real red, real green, real blue, real transparency returns nothing
5736 call LeaderboardSetValueColor(lb, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
5737endfunction
5738
5739//===========================================================================
5740function LeaderboardSetLabelBJ takes leaderboard lb, string label returns nothing
5741 call LeaderboardSetLabel(lb, label)
5742 call LeaderboardResizeBJ(lb)
5743endfunction
5744
5745//===========================================================================
5746function LeaderboardSetStyleBJ takes leaderboard lb, boolean showLabel, boolean showNames, boolean showValues, boolean showIcons returns nothing
5747 call LeaderboardSetStyle(lb, showLabel, showNames, showValues, showIcons)
5748endfunction
5749
5750//===========================================================================
5751function LeaderboardGetItemCountBJ takes leaderboard lb returns integer
5752 return LeaderboardGetItemCount(lb)
5753endfunction
5754
5755//===========================================================================
5756function LeaderboardHasPlayerItemBJ takes leaderboard lb, player whichPlayer returns boolean
5757 return LeaderboardHasPlayerItem(lb, whichPlayer)
5758endfunction
5759
5760//===========================================================================
5761function ForceSetLeaderboardBJ takes leaderboard lb, force toForce returns nothing
5762 local integer index
5763 local player indexPlayer
5764
5765 set index = 0
5766 loop
5767 set indexPlayer = Player(index)
5768 if IsPlayerInForce(indexPlayer, toForce) then
5769 call PlayerSetLeaderboard(indexPlayer, lb)
5770 endif
5771 set index = index + 1
5772 exitwhen index == bj_MAX_PLAYERS
5773 endloop
5774endfunction
5775
5776//===========================================================================
5777function CreateLeaderboardBJ takes force toForce, string label returns leaderboard
5778 set bj_lastCreatedLeaderboard = CreateLeaderboard()
5779 call LeaderboardSetLabel(bj_lastCreatedLeaderboard, label)
5780 call ForceSetLeaderboardBJ(bj_lastCreatedLeaderboard, toForce)
5781 call LeaderboardDisplay(bj_lastCreatedLeaderboard, true)
5782 return bj_lastCreatedLeaderboard
5783endfunction
5784
5785//===========================================================================
5786function DestroyLeaderboardBJ takes leaderboard lb returns nothing
5787 call DestroyLeaderboard(lb)
5788endfunction
5789
5790//===========================================================================
5791function LeaderboardDisplayBJ takes boolean show, leaderboard lb returns nothing
5792 call LeaderboardDisplay(lb, show)
5793endfunction
5794
5795//===========================================================================
5796function LeaderboardAddItemBJ takes player whichPlayer, leaderboard lb, string label, integer value returns nothing
5797 if (LeaderboardHasPlayerItem(lb, whichPlayer)) then
5798 call LeaderboardRemovePlayerItem(lb, whichPlayer)
5799 endif
5800 call LeaderboardAddItem(lb, label, value, whichPlayer)
5801 call LeaderboardResizeBJ(lb)
5802 //call LeaderboardSetSizeByItemCount(lb, LeaderboardGetItemCount(lb))
5803endfunction
5804
5805//===========================================================================
5806function LeaderboardRemovePlayerItemBJ takes player whichPlayer, leaderboard lb returns nothing
5807 call LeaderboardRemovePlayerItem(lb, whichPlayer)
5808 call LeaderboardResizeBJ(lb)
5809endfunction
5810
5811//===========================================================================
5812function LeaderboardSortItemsBJ takes leaderboard lb, integer sortType, boolean ascending returns nothing
5813 if (sortType == bj_SORTTYPE_SORTBYVALUE) then
5814 call LeaderboardSortItemsByValue(lb, ascending)
5815 elseif (sortType == bj_SORTTYPE_SORTBYPLAYER) then
5816 call LeaderboardSortItemsByPlayer(lb, ascending)
5817 elseif (sortType == bj_SORTTYPE_SORTBYLABEL) then
5818 call LeaderboardSortItemsByLabel(lb, ascending)
5819 else
5820 // Unrecognized sort type - ignore the request.
5821 endif
5822endfunction
5823
5824//===========================================================================
5825function LeaderboardSortItemsByPlayerBJ takes leaderboard lb, boolean ascending returns nothing
5826 call LeaderboardSortItemsByPlayer(lb, ascending)
5827endfunction
5828
5829//===========================================================================
5830function LeaderboardSortItemsByLabelBJ takes leaderboard lb, boolean ascending returns nothing
5831 call LeaderboardSortItemsByLabel(lb, ascending)
5832endfunction
5833
5834//===========================================================================
5835function LeaderboardGetPlayerIndexBJ takes player whichPlayer, leaderboard lb returns integer
5836 return LeaderboardGetPlayerIndex(lb, whichPlayer) + 1
5837endfunction
5838
5839//===========================================================================
5840// Returns the player who is occupying a specified position in a leaderboard.
5841// The position parameter is expected in the range of 1..16.
5842//
5843function LeaderboardGetIndexedPlayerBJ takes integer position, leaderboard lb returns player
5844 local integer index
5845 local player indexPlayer
5846
5847 set index = 0
5848 loop
5849 set indexPlayer = Player(index)
5850 if (LeaderboardGetPlayerIndex(lb, indexPlayer) == position - 1) then
5851 return indexPlayer
5852 endif
5853
5854 set index = index + 1
5855 exitwhen index == bj_MAX_PLAYERS
5856 endloop
5857
5858 return Player(PLAYER_NEUTRAL_PASSIVE)
5859endfunction
5860
5861//===========================================================================
5862function PlayerGetLeaderboardBJ takes player whichPlayer returns leaderboard
5863 return PlayerGetLeaderboard(whichPlayer)
5864endfunction
5865
5866//===========================================================================
5867function GetLastCreatedLeaderboard takes nothing returns leaderboard
5868 return bj_lastCreatedLeaderboard
5869endfunction
5870
5871//***************************************************************************
5872//*
5873//* Multiboard Utility Functions
5874//*
5875//***************************************************************************
5876
5877//===========================================================================
5878function CreateMultiboardBJ takes integer cols, integer rows, string title returns multiboard
5879 set bj_lastCreatedMultiboard = CreateMultiboard()
5880 call MultiboardSetRowCount(bj_lastCreatedMultiboard, rows)
5881 call MultiboardSetColumnCount(bj_lastCreatedMultiboard, cols)
5882 call MultiboardSetTitleText(bj_lastCreatedMultiboard, title)
5883 call MultiboardDisplay(bj_lastCreatedMultiboard, true)
5884 return bj_lastCreatedMultiboard
5885endfunction
5886
5887//===========================================================================
5888function DestroyMultiboardBJ takes multiboard mb returns nothing
5889 call DestroyMultiboard(mb)
5890endfunction
5891
5892//===========================================================================
5893function GetLastCreatedMultiboard takes nothing returns multiboard
5894 return bj_lastCreatedMultiboard
5895endfunction
5896
5897//===========================================================================
5898function MultiboardDisplayBJ takes boolean show, multiboard mb returns nothing
5899 call MultiboardDisplay(mb, show)
5900endfunction
5901
5902//===========================================================================
5903function MultiboardMinimizeBJ takes boolean minimize, multiboard mb returns nothing
5904 call MultiboardMinimize(mb, minimize)
5905endfunction
5906
5907//===========================================================================
5908function MultiboardSetTitleTextColorBJ takes multiboard mb, real red, real green, real blue, real transparency returns nothing
5909 call MultiboardSetTitleTextColor(mb, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
5910endfunction
5911
5912//===========================================================================
5913function MultiboardAllowDisplayBJ takes boolean flag returns nothing
5914 call MultiboardSuppressDisplay(not flag)
5915endfunction
5916
5917//===========================================================================
5918function MultiboardSetItemStyleBJ takes multiboard mb, integer col, integer row, boolean showValue, boolean showIcon returns nothing
5919 local integer curRow = 0
5920 local integer curCol = 0
5921 local integer numRows = MultiboardGetRowCount(mb)
5922 local integer numCols = MultiboardGetColumnCount(mb)
5923 local multiboarditem mbitem = null
5924
5925 // Loop over rows, using 1-based index
5926 loop
5927 set curRow = curRow + 1
5928 exitwhen curRow > numRows
5929
5930 // Apply setting to the requested row, or all rows (if row is 0)
5931 if (row == 0 or row == curRow) then
5932 // Loop over columns, using 1-based index
5933 set curCol = 0
5934 loop
5935 set curCol = curCol + 1
5936 exitwhen curCol > numCols
5937
5938 // Apply setting to the requested column, or all columns (if col is 0)
5939 if (col == 0 or col == curCol) then
5940 set mbitem = MultiboardGetItem(mb, curRow - 1, curCol - 1)
5941 call MultiboardSetItemStyle(mbitem, showValue, showIcon)
5942 call MultiboardReleaseItem(mbitem)
5943 endif
5944 endloop
5945 endif
5946 endloop
5947endfunction
5948
5949//===========================================================================
5950function MultiboardSetItemValueBJ takes multiboard mb, integer col, integer row, string val returns nothing
5951 local integer curRow = 0
5952 local integer curCol = 0
5953 local integer numRows = MultiboardGetRowCount(mb)
5954 local integer numCols = MultiboardGetColumnCount(mb)
5955 local multiboarditem mbitem = null
5956
5957 // Loop over rows, using 1-based index
5958 loop
5959 set curRow = curRow + 1
5960 exitwhen curRow > numRows
5961
5962 // Apply setting to the requested row, or all rows (if row is 0)
5963 if (row == 0 or row == curRow) then
5964 // Loop over columns, using 1-based index
5965 set curCol = 0
5966 loop
5967 set curCol = curCol + 1
5968 exitwhen curCol > numCols
5969
5970 // Apply setting to the requested column, or all columns (if col is 0)
5971 if (col == 0 or col == curCol) then
5972 set mbitem = MultiboardGetItem(mb, curRow - 1, curCol - 1)
5973 call MultiboardSetItemValue(mbitem, val)
5974 call MultiboardReleaseItem(mbitem)
5975 endif
5976 endloop
5977 endif
5978 endloop
5979endfunction
5980
5981//===========================================================================
5982function MultiboardSetItemColorBJ takes multiboard mb, integer col, integer row, real red, real green, real blue, real transparency returns nothing
5983 local integer curRow = 0
5984 local integer curCol = 0
5985 local integer numRows = MultiboardGetRowCount(mb)
5986 local integer numCols = MultiboardGetColumnCount(mb)
5987 local multiboarditem mbitem = null
5988
5989 // Loop over rows, using 1-based index
5990 loop
5991 set curRow = curRow + 1
5992 exitwhen curRow > numRows
5993
5994 // Apply setting to the requested row, or all rows (if row is 0)
5995 if (row == 0 or row == curRow) then
5996 // Loop over columns, using 1-based index
5997 set curCol = 0
5998 loop
5999 set curCol = curCol + 1
6000 exitwhen curCol > numCols
6001
6002 // Apply setting to the requested column, or all columns (if col is 0)
6003 if (col == 0 or col == curCol) then
6004 set mbitem = MultiboardGetItem(mb, curRow - 1, curCol - 1)
6005 call MultiboardSetItemValueColor(mbitem, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
6006 call MultiboardReleaseItem(mbitem)
6007 endif
6008 endloop
6009 endif
6010 endloop
6011endfunction
6012
6013//===========================================================================
6014function MultiboardSetItemWidthBJ takes multiboard mb, integer col, integer row, real width returns nothing
6015 local integer curRow = 0
6016 local integer curCol = 0
6017 local integer numRows = MultiboardGetRowCount(mb)
6018 local integer numCols = MultiboardGetColumnCount(mb)
6019 local multiboarditem mbitem = null
6020
6021 // Loop over rows, using 1-based index
6022 loop
6023 set curRow = curRow + 1
6024 exitwhen curRow > numRows
6025
6026 // Apply setting to the requested row, or all rows (if row is 0)
6027 if (row == 0 or row == curRow) then
6028 // Loop over columns, using 1-based index
6029 set curCol = 0
6030 loop
6031 set curCol = curCol + 1
6032 exitwhen curCol > numCols
6033
6034 // Apply setting to the requested column, or all columns (if col is 0)
6035 if (col == 0 or col == curCol) then
6036 set mbitem = MultiboardGetItem(mb, curRow - 1, curCol - 1)
6037 call MultiboardSetItemWidth(mbitem, width/100.0)
6038 call MultiboardReleaseItem(mbitem)
6039 endif
6040 endloop
6041 endif
6042 endloop
6043endfunction
6044
6045//===========================================================================
6046function MultiboardSetItemIconBJ takes multiboard mb, integer col, integer row, string iconFileName returns nothing
6047 local integer curRow = 0
6048 local integer curCol = 0
6049 local integer numRows = MultiboardGetRowCount(mb)
6050 local integer numCols = MultiboardGetColumnCount(mb)
6051 local multiboarditem mbitem = null
6052
6053 // Loop over rows, using 1-based index
6054 loop
6055 set curRow = curRow + 1
6056 exitwhen curRow > numRows
6057
6058 // Apply setting to the requested row, or all rows (if row is 0)
6059 if (row == 0 or row == curRow) then
6060 // Loop over columns, using 1-based index
6061 set curCol = 0
6062 loop
6063 set curCol = curCol + 1
6064 exitwhen curCol > numCols
6065
6066 // Apply setting to the requested column, or all columns (if col is 0)
6067 if (col == 0 or col == curCol) then
6068 set mbitem = MultiboardGetItem(mb, curRow - 1, curCol - 1)
6069 call MultiboardSetItemIcon(mbitem, iconFileName)
6070 call MultiboardReleaseItem(mbitem)
6071 endif
6072 endloop
6073 endif
6074 endloop
6075endfunction
6076
6077
6078
6079//***************************************************************************
6080//*
6081//* Text Tag Utility Functions
6082//*
6083//***************************************************************************
6084
6085//===========================================================================
6086// Scale the font size linearly such that size 10 equates to height 0.023.
6087// Screen-relative font heights are harder to grasp and than font sizes.
6088//
6089function TextTagSize2Height takes real size returns real
6090 return size * 0.023 / 10
6091endfunction
6092
6093//===========================================================================
6094// Scale the speed linearly such that speed 128 equates to 0.071.
6095// Screen-relative speeds are hard to grasp.
6096//
6097function TextTagSpeed2Velocity takes real speed returns real
6098 return speed * 0.071 / 128
6099endfunction
6100
6101//===========================================================================
6102function SetTextTagColorBJ takes texttag tt, real red, real green, real blue, real transparency returns nothing
6103 call SetTextTagColor(tt, PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100.0-transparency))
6104endfunction
6105
6106//===========================================================================
6107function SetTextTagVelocityBJ takes texttag tt, real speed, real angle returns nothing
6108 local real vel = TextTagSpeed2Velocity(speed)
6109 local real xvel = vel * Cos(angle * bj_DEGTORAD)
6110 local real yvel = vel * Sin(angle * bj_DEGTORAD)
6111
6112 call SetTextTagVelocity(tt, xvel, yvel)
6113endfunction
6114
6115//===========================================================================
6116function SetTextTagTextBJ takes texttag tt, string s, real size returns nothing
6117 local real textHeight = TextTagSize2Height(size)
6118
6119 call SetTextTagText(tt, s, textHeight)
6120endfunction
6121
6122//===========================================================================
6123function SetTextTagPosBJ takes texttag tt, location loc, real zOffset returns nothing
6124 call SetTextTagPos(tt, GetLocationX(loc), GetLocationY(loc), zOffset)
6125endfunction
6126
6127//===========================================================================
6128function SetTextTagPosUnitBJ takes texttag tt, unit whichUnit, real zOffset returns nothing
6129 call SetTextTagPosUnit(tt, whichUnit, zOffset)
6130endfunction
6131
6132//===========================================================================
6133function SetTextTagSuspendedBJ takes texttag tt, boolean flag returns nothing
6134 call SetTextTagSuspended(tt, flag)
6135endfunction
6136
6137//===========================================================================
6138function SetTextTagPermanentBJ takes texttag tt, boolean flag returns nothing
6139 call SetTextTagPermanent(tt, flag)
6140endfunction
6141
6142//===========================================================================
6143function SetTextTagAgeBJ takes texttag tt, real age returns nothing
6144 call SetTextTagAge(tt, age)
6145endfunction
6146
6147//===========================================================================
6148function SetTextTagLifespanBJ takes texttag tt, real lifespan returns nothing
6149 call SetTextTagLifespan(tt, lifespan)
6150endfunction
6151
6152//===========================================================================
6153function SetTextTagFadepointBJ takes texttag tt, real fadepoint returns nothing
6154 call SetTextTagFadepoint(tt, fadepoint)
6155endfunction
6156
6157//===========================================================================
6158function CreateTextTagLocBJ takes string s, location loc, real zOffset, real size, real red, real green, real blue, real transparency returns texttag
6159 set bj_lastCreatedTextTag = CreateTextTag()
6160 call SetTextTagTextBJ(bj_lastCreatedTextTag, s, size)
6161 call SetTextTagPosBJ(bj_lastCreatedTextTag, loc, zOffset)
6162 call SetTextTagColorBJ(bj_lastCreatedTextTag, red, green, blue, transparency)
6163
6164 return bj_lastCreatedTextTag
6165endfunction
6166
6167//===========================================================================
6168function CreateTextTagUnitBJ takes string s, unit whichUnit, real zOffset, real size, real red, real green, real blue, real transparency returns texttag
6169 set bj_lastCreatedTextTag = CreateTextTag()
6170 call SetTextTagTextBJ(bj_lastCreatedTextTag, s, size)
6171 call SetTextTagPosUnitBJ(bj_lastCreatedTextTag, whichUnit, zOffset)
6172 call SetTextTagColorBJ(bj_lastCreatedTextTag, red, green, blue, transparency)
6173
6174 return bj_lastCreatedTextTag
6175endfunction
6176
6177//===========================================================================
6178function DestroyTextTagBJ takes texttag tt returns nothing
6179 call DestroyTextTag(tt)
6180endfunction
6181
6182//===========================================================================
6183function ShowTextTagForceBJ takes boolean show, texttag tt, force whichForce returns nothing
6184 if (IsPlayerInForce(GetLocalPlayer(), whichForce)) then
6185 // Use only local code (no net traffic) within this block to avoid desyncs.
6186 call SetTextTagVisibility(tt, show)
6187 endif
6188endfunction
6189
6190//===========================================================================
6191function GetLastCreatedTextTag takes nothing returns texttag
6192 return bj_lastCreatedTextTag
6193endfunction
6194
6195
6196
6197//***************************************************************************
6198//*
6199//* Cinematic Utility Functions
6200//*
6201//***************************************************************************
6202
6203//===========================================================================
6204function PauseGameOn takes nothing returns nothing
6205 call PauseGame(true)
6206endfunction
6207
6208//===========================================================================
6209function PauseGameOff takes nothing returns nothing
6210 call PauseGame(false)
6211endfunction
6212
6213//===========================================================================
6214function SetUserControlForceOn takes force whichForce returns nothing
6215 if (IsPlayerInForce(GetLocalPlayer(), whichForce)) then
6216 // Use only local code (no net traffic) within this block to avoid desyncs.
6217 call EnableUserControl(true)
6218 endif
6219endfunction
6220
6221//===========================================================================
6222function SetUserControlForceOff takes force whichForce returns nothing
6223 if (IsPlayerInForce(GetLocalPlayer(), whichForce)) then
6224 // Use only local code (no net traffic) within this block to avoid desyncs.
6225 call EnableUserControl(false)
6226 endif
6227endfunction
6228
6229//===========================================================================
6230function ShowInterfaceForceOn takes force whichForce, real fadeDuration returns nothing
6231 if (IsPlayerInForce(GetLocalPlayer(), whichForce)) then
6232 // Use only local code (no net traffic) within this block to avoid desyncs.
6233 call ShowInterface(true, fadeDuration)
6234 endif
6235endfunction
6236
6237//===========================================================================
6238function ShowInterfaceForceOff takes force whichForce, real fadeDuration returns nothing
6239 if (IsPlayerInForce(GetLocalPlayer(), whichForce)) then
6240 // Use only local code (no net traffic) within this block to avoid desyncs.
6241 call ShowInterface(false, fadeDuration)
6242 endif
6243endfunction
6244
6245//===========================================================================
6246function PingMinimapForForce takes force whichForce, real x, real y, real duration returns nothing
6247 if (IsPlayerInForce(GetLocalPlayer(), whichForce)) then
6248 // Use only local code (no net traffic) within this block to avoid desyncs.
6249 call PingMinimap(x, y, duration)
6250 //call StartSound(bj_pingMinimapSound)
6251 endif
6252endfunction
6253
6254//===========================================================================
6255function PingMinimapLocForForce takes force whichForce, location loc, real duration returns nothing
6256 call PingMinimapForForce(whichForce, GetLocationX(loc), GetLocationY(loc), duration)
6257endfunction
6258
6259//===========================================================================
6260function PingMinimapForPlayer takes player whichPlayer, real x, real y, real duration returns nothing
6261 if (GetLocalPlayer() == whichPlayer) then
6262 // Use only local code (no net traffic) within this block to avoid desyncs.
6263 call PingMinimap(x, y, duration)
6264 //call StartSound(bj_pingMinimapSound)
6265 endif
6266endfunction
6267
6268//===========================================================================
6269function PingMinimapLocForPlayer takes player whichPlayer, location loc, real duration returns nothing
6270 call PingMinimapForPlayer(whichPlayer, GetLocationX(loc), GetLocationY(loc), duration)
6271endfunction
6272
6273//===========================================================================
6274function PingMinimapForForceEx takes force whichForce, real x, real y, real duration, integer style, real red, real green, real blue returns nothing
6275 local integer red255 = PercentTo255(red)
6276 local integer green255 = PercentTo255(green)
6277 local integer blue255 = PercentTo255(blue)
6278
6279 if (IsPlayerInForce(GetLocalPlayer(), whichForce)) then
6280 // Use only local code (no net traffic) within this block to avoid desyncs.
6281
6282 // Prevent 100% red simple and flashy pings, as they become "attack" pings.
6283 if (red255 == 255) and (green255 == 0) and (blue255 == 0) then
6284 set red255 = 254
6285 endif
6286
6287 if (style == bj_MINIMAPPINGSTYLE_SIMPLE) then
6288 call PingMinimapEx(x, y, duration, red255, green255, blue255, false)
6289 elseif (style == bj_MINIMAPPINGSTYLE_FLASHY) then
6290 call PingMinimapEx(x, y, duration, red255, green255, blue255, true)
6291 elseif (style == bj_MINIMAPPINGSTYLE_ATTACK) then
6292 call PingMinimapEx(x, y, duration, 255, 0, 0, false)
6293 else
6294 // Unrecognized ping style - ignore the request.
6295 endif
6296
6297 //call StartSound(bj_pingMinimapSound)
6298 endif
6299endfunction
6300
6301//===========================================================================
6302function PingMinimapLocForForceEx takes force whichForce, location loc, real duration, integer style, real red, real green, real blue returns nothing
6303 call PingMinimapForForceEx(whichForce, GetLocationX(loc), GetLocationY(loc), duration, style, red, green, blue)
6304endfunction
6305
6306//===========================================================================
6307function EnableWorldFogBoundaryBJ takes boolean enable, force f returns nothing
6308 if (IsPlayerInForce(GetLocalPlayer(), f)) then
6309 // Use only local code (no net traffic) within this block to avoid desyncs.
6310 call EnableWorldFogBoundary(enable)
6311 endif
6312endfunction
6313
6314//===========================================================================
6315function EnableOcclusionBJ takes boolean enable, force f returns nothing
6316 if (IsPlayerInForce(GetLocalPlayer(), f)) then
6317 // Use only local code (no net traffic) within this block to avoid desyncs.
6318 call EnableOcclusion(enable)
6319 endif
6320endfunction
6321
6322
6323
6324//***************************************************************************
6325//*
6326//* Cinematic Transmission Utility Functions
6327//*
6328//***************************************************************************
6329
6330//===========================================================================
6331// If cancelled, stop the sound and end the cinematic scene.
6332//
6333function CancelCineSceneBJ takes nothing returns nothing
6334 call StopSoundBJ(bj_cineSceneLastSound, true)
6335 call EndCinematicScene()
6336endfunction
6337
6338//===========================================================================
6339// Init a trigger to listen for END_CINEMATIC events and respond to them if
6340// a cinematic scene is in progress. For performance reasons, this should
6341// only be called once a cinematic scene has been started, so that maps
6342// lacking such scenes do not bother to register for these events.
6343//
6344function TryInitCinematicBehaviorBJ takes nothing returns nothing
6345 local integer index
6346
6347 if (bj_cineSceneBeingSkipped == null) then
6348 set bj_cineSceneBeingSkipped = CreateTrigger()
6349 set index = 0
6350 loop
6351 call TriggerRegisterPlayerEvent(bj_cineSceneBeingSkipped, Player(index), EVENT_PLAYER_END_CINEMATIC)
6352 set index = index + 1
6353 exitwhen index == bj_MAX_PLAYERS
6354 endloop
6355 call TriggerAddAction(bj_cineSceneBeingSkipped, function CancelCineSceneBJ)
6356 endif
6357endfunction
6358
6359//===========================================================================
6360function SetCinematicSceneBJ takes sound soundHandle, integer portraitUnitId, playercolor color, string speakerTitle, string text, real sceneDuration, real voiceoverDuration returns nothing
6361 set bj_cineSceneLastSound = soundHandle
6362 call PlaySoundBJ(soundHandle)
6363 call SetCinematicScene(portraitUnitId, color, speakerTitle, text, sceneDuration, voiceoverDuration)
6364endfunction
6365
6366//===========================================================================
6367function GetTransmissionDuration takes sound soundHandle, integer timeType, real timeVal returns real
6368 local real duration
6369
6370 if (timeType == bj_TIMETYPE_ADD) then
6371 set duration = GetSoundDurationBJ(soundHandle) + timeVal
6372 elseif (timeType == bj_TIMETYPE_SET) then
6373 set duration = timeVal
6374 elseif (timeType == bj_TIMETYPE_SUB) then
6375 set duration = GetSoundDurationBJ(soundHandle) - timeVal
6376 else
6377 // Unrecognized timeType - ignore timeVal.
6378 set duration = GetSoundDurationBJ(soundHandle)
6379 endif
6380
6381 // Make sure we have a non-negative duration.
6382 if (duration < 0) then
6383 set duration = 0
6384 endif
6385 return duration
6386endfunction
6387
6388//===========================================================================
6389function WaitTransmissionDuration takes sound soundHandle, integer timeType, real timeVal returns nothing
6390 if (timeType == bj_TIMETYPE_SET) then
6391 // If we have a static duration wait, just perform the wait.
6392 call TriggerSleepAction(timeVal)
6393
6394 elseif (soundHandle == null) then
6395 // If the sound does not exist, perform a default length wait.
6396 call TriggerSleepAction(bj_NOTHING_SOUND_DURATION)
6397
6398 elseif (timeType == bj_TIMETYPE_SUB) then
6399 // If the transmission is cutting off the sound, wait for the sound
6400 // to be mostly finished.
6401 call WaitForSoundBJ(soundHandle, timeVal)
6402
6403 elseif (timeType == bj_TIMETYPE_ADD) then
6404 // If the transmission is extending beyond the sound's length, wait
6405 // for it to finish, and then wait the additional time.
6406 call WaitForSoundBJ(soundHandle, 0)
6407 call TriggerSleepAction(timeVal)
6408
6409 else
6410 // Unrecognized timeType - ignore.
6411 endif
6412endfunction
6413
6414//===========================================================================
6415function DoTransmissionBasicsXYBJ takes integer unitId, playercolor color, real x, real y, sound soundHandle, string unitName, string message, real duration returns nothing
6416 call SetCinematicSceneBJ(soundHandle, unitId, color, unitName, message, duration + bj_TRANSMISSION_PORT_HANGTIME, duration)
6417
6418 if (unitId != 0) then
6419 call PingMinimap(x, y, bj_TRANSMISSION_PING_TIME)
6420 //call SetCameraQuickPosition(x, y)
6421 endif
6422endfunction
6423
6424//===========================================================================
6425// Display a text message to a Player Group with an accompanying sound,
6426// portrait, speech indicator, and all that good stuff.
6427// - Query duration of sound
6428// - Play sound
6429// - Display text message for duration
6430// - Display animating portrait for duration
6431// - Display a speech indicator for the unit
6432// - Ping the minimap
6433//
6434function TransmissionFromUnitWithNameBJ takes force toForce, unit whichUnit, string unitName, sound soundHandle, string message, integer timeType, real timeVal, boolean wait returns nothing
6435 call TryInitCinematicBehaviorBJ()
6436
6437 // Ensure that the time value is non-negative.
6438 set timeVal = RMaxBJ(timeVal, 0)
6439
6440 set bj_lastTransmissionDuration = GetTransmissionDuration(soundHandle, timeType, timeVal)
6441 set bj_lastPlayedSound = soundHandle
6442
6443 if (IsPlayerInForce(GetLocalPlayer(), toForce)) then
6444 // Use only local code (no net traffic) within this block to avoid desyncs.
6445
6446 if (whichUnit == null) then
6447 // If the unit reference is invalid, send the transmission from the center of the map with no portrait.
6448 call DoTransmissionBasicsXYBJ(0, PLAYER_COLOR_RED, 0, 0, soundHandle, unitName, message, bj_lastTransmissionDuration)
6449 else
6450 call DoTransmissionBasicsXYBJ(GetUnitTypeId(whichUnit), GetPlayerColor(GetOwningPlayer(whichUnit)), GetUnitX(whichUnit), GetUnitY(whichUnit), soundHandle, unitName, message, bj_lastTransmissionDuration)
6451 if (not IsUnitHidden(whichUnit)) then
6452 call UnitAddIndicator(whichUnit, bj_TRANSMISSION_IND_RED, bj_TRANSMISSION_IND_BLUE, bj_TRANSMISSION_IND_GREEN, bj_TRANSMISSION_IND_ALPHA)
6453 endif
6454 endif
6455 endif
6456
6457 if wait and (bj_lastTransmissionDuration > 0) then
6458 // call TriggerSleepAction(bj_lastTransmissionDuration)
6459 call WaitTransmissionDuration(soundHandle, timeType, timeVal)
6460 endif
6461
6462endfunction
6463
6464//===========================================================================
6465// This operates like TransmissionFromUnitWithNameBJ, but for a unit type
6466// rather than a unit instance. As such, no speech indicator is employed.
6467//
6468function TransmissionFromUnitTypeWithNameBJ takes force toForce, player fromPlayer, integer unitId, string unitName, location loc, sound soundHandle, string message, integer timeType, real timeVal, boolean wait returns nothing
6469 call TryInitCinematicBehaviorBJ()
6470
6471 // Ensure that the time value is non-negative.
6472 set timeVal = RMaxBJ(timeVal, 0)
6473
6474 set bj_lastTransmissionDuration = GetTransmissionDuration(soundHandle, timeType, timeVal)
6475 set bj_lastPlayedSound = soundHandle
6476
6477 if (IsPlayerInForce(GetLocalPlayer(), toForce)) then
6478 // Use only local code (no net traffic) within this block to avoid desyncs.
6479
6480 call DoTransmissionBasicsXYBJ(unitId, GetPlayerColor(fromPlayer), GetLocationX(loc), GetLocationY(loc), soundHandle, unitName, message, bj_lastTransmissionDuration)
6481 endif
6482
6483 if wait and (bj_lastTransmissionDuration > 0) then
6484 // call TriggerSleepAction(bj_lastTransmissionDuration)
6485 call WaitTransmissionDuration(soundHandle, timeType, timeVal)
6486 endif
6487
6488endfunction
6489
6490//===========================================================================
6491function GetLastTransmissionDurationBJ takes nothing returns real
6492 return bj_lastTransmissionDuration
6493endfunction
6494
6495//===========================================================================
6496function ForceCinematicSubtitlesBJ takes boolean flag returns nothing
6497 call ForceCinematicSubtitles(flag)
6498endfunction
6499
6500
6501//***************************************************************************
6502//*
6503//* Cinematic Mode Utility Functions
6504//*
6505//***************************************************************************
6506
6507//===========================================================================
6508// Makes many common UI settings changes at once, for use when beginning and
6509// ending cinematic sequences. Note that some affects apply to all players,
6510// such as game speed. This is unavoidable.
6511// - Clear the screen of text messages
6512// - Hide interface UI (letterbox mode)
6513// - Hide game messages (ally under attack, etc.)
6514// - Disable user control
6515// - Disable occlusion
6516// - Set game speed (for all players)
6517// - Lock game speed (for all players)
6518// - Disable black mask (for all players)
6519// - Disable fog of war (for all players)
6520// - Disable world boundary fog (for all players)
6521// - Dim non-speech sound channels
6522// - End any outstanding music themes
6523// - Fix the random seed to a set value
6524// - Reset the camera smoothing factor
6525//
6526function CinematicModeExBJ takes boolean cineMode, force forForce, real interfaceFadeTime returns nothing
6527 // If the game hasn't started yet, perform interface fades immediately
6528 if (not bj_gameStarted) then
6529 set interfaceFadeTime = 0
6530 endif
6531
6532 if (cineMode) then
6533 // Save the UI state so that we can restore it later.
6534 if (not bj_cineModeAlreadyIn) then
6535 set bj_cineModeAlreadyIn = true
6536 set bj_cineModePriorSpeed = GetGameSpeed()
6537 set bj_cineModePriorFogSetting = IsFogEnabled()
6538 set bj_cineModePriorMaskSetting = IsFogMaskEnabled()
6539 set bj_cineModePriorDawnDusk = IsDawnDuskEnabled()
6540 set bj_cineModeSavedSeed = GetRandomInt(0, 1000000)
6541 endif
6542
6543 // Perform local changes
6544 if (IsPlayerInForce(GetLocalPlayer(), forForce)) then
6545 // Use only local code (no net traffic) within this block to avoid desyncs.
6546 call ClearTextMessages()
6547 call ShowInterface(false, interfaceFadeTime)
6548 call EnableUserControl(false)
6549 call EnableOcclusion(false)
6550 call SetCineModeVolumeGroupsBJ()
6551 endif
6552
6553 // Perform global changes
6554 call SetGameSpeed(bj_CINEMODE_GAMESPEED)
6555 call SetMapFlag(MAP_LOCK_SPEED, true)
6556 call FogMaskEnable(false)
6557 call FogEnable(false)
6558 call EnableWorldFogBoundary(false)
6559 call EnableDawnDusk(false)
6560
6561 // Use a fixed random seed, so that cinematics play consistently.
6562 call SetRandomSeed(0)
6563 else
6564 set bj_cineModeAlreadyIn = false
6565
6566 // Perform local changes
6567 if (IsPlayerInForce(GetLocalPlayer(), forForce)) then
6568 // Use only local code (no net traffic) within this block to avoid desyncs.
6569 call ShowInterface(true, interfaceFadeTime)
6570 call EnableUserControl(true)
6571 call EnableOcclusion(true)
6572 call VolumeGroupReset()
6573 call EndThematicMusic()
6574 call CameraResetSmoothingFactorBJ()
6575 endif
6576
6577 // Perform global changes
6578 call SetMapFlag(MAP_LOCK_SPEED, false)
6579 call SetGameSpeed(bj_cineModePriorSpeed)
6580 call FogMaskEnable(bj_cineModePriorMaskSetting)
6581 call FogEnable(bj_cineModePriorFogSetting)
6582 call EnableWorldFogBoundary(true)
6583 call EnableDawnDusk(bj_cineModePriorDawnDusk)
6584 call SetRandomSeed(bj_cineModeSavedSeed)
6585 endif
6586endfunction
6587
6588//===========================================================================
6589function CinematicModeBJ takes boolean cineMode, force forForce returns nothing
6590 call CinematicModeExBJ(cineMode, forForce, bj_CINEMODE_INTERFACEFADE)
6591endfunction
6592
6593
6594
6595//***************************************************************************
6596//*
6597//* Cinematic Filter Utility Functions
6598//*
6599//***************************************************************************
6600
6601//===========================================================================
6602function DisplayCineFilterBJ takes boolean flag returns nothing
6603 call DisplayCineFilter(flag)
6604endfunction
6605
6606//===========================================================================
6607function CinematicFadeCommonBJ takes real red, real green, real blue, real duration, string tex, real startTrans, real endTrans returns nothing
6608 if (duration == 0) then
6609 // If the fade is instant, use the same starting and ending values,
6610 // so that we effectively do a set rather than a fade.
6611 set startTrans = endTrans
6612 endif
6613 call EnableUserUI(false)
6614 call SetCineFilterTexture(tex)
6615 call SetCineFilterBlendMode(BLEND_MODE_BLEND)
6616 call SetCineFilterTexMapFlags(TEXMAP_FLAG_NONE)
6617 call SetCineFilterStartUV(0, 0, 1, 1)
6618 call SetCineFilterEndUV(0, 0, 1, 1)
6619 call SetCineFilterStartColor(PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100-startTrans))
6620 call SetCineFilterEndColor(PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100-endTrans))
6621 call SetCineFilterDuration(duration)
6622 call DisplayCineFilter(true)
6623endfunction
6624
6625//===========================================================================
6626function FinishCinematicFadeBJ takes nothing returns nothing
6627 call DestroyTimer(bj_cineFadeFinishTimer)
6628 set bj_cineFadeFinishTimer = null
6629 call DisplayCineFilter(false)
6630 call EnableUserUI(true)
6631endfunction
6632
6633//===========================================================================
6634function FinishCinematicFadeAfterBJ takes real duration returns nothing
6635 // Create a timer to end the cinematic fade.
6636 set bj_cineFadeFinishTimer = CreateTimer()
6637 call TimerStart(bj_cineFadeFinishTimer, duration, false, function FinishCinematicFadeBJ)
6638endfunction
6639
6640//===========================================================================
6641function ContinueCinematicFadeBJ takes nothing returns nothing
6642 call DestroyTimer(bj_cineFadeContinueTimer)
6643 set bj_cineFadeContinueTimer = null
6644 call CinematicFadeCommonBJ(bj_cineFadeContinueRed, bj_cineFadeContinueGreen, bj_cineFadeContinueBlue, bj_cineFadeContinueDuration, bj_cineFadeContinueTex, bj_cineFadeContinueTrans, 100)
6645endfunction
6646
6647//===========================================================================
6648function ContinueCinematicFadeAfterBJ takes real duration, real red, real green, real blue, real trans, string tex returns nothing
6649 set bj_cineFadeContinueRed = red
6650 set bj_cineFadeContinueGreen = green
6651 set bj_cineFadeContinueBlue = blue
6652 set bj_cineFadeContinueTrans = trans
6653 set bj_cineFadeContinueDuration = duration
6654 set bj_cineFadeContinueTex = tex
6655
6656 // Create a timer to continue the cinematic fade.
6657 set bj_cineFadeContinueTimer = CreateTimer()
6658 call TimerStart(bj_cineFadeContinueTimer, duration, false, function ContinueCinematicFadeBJ)
6659endfunction
6660
6661//===========================================================================
6662function AbortCinematicFadeBJ takes nothing returns nothing
6663 if (bj_cineFadeContinueTimer != null) then
6664 call DestroyTimer(bj_cineFadeContinueTimer)
6665 endif
6666
6667 if (bj_cineFadeFinishTimer != null) then
6668 call DestroyTimer(bj_cineFadeFinishTimer)
6669 endif
6670endfunction
6671
6672//===========================================================================
6673function CinematicFadeBJ takes integer fadetype, real duration, string tex, real red, real green, real blue, real trans returns nothing
6674 if (fadetype == bj_CINEFADETYPE_FADEOUT) then
6675 // Fade out to the requested color.
6676 call AbortCinematicFadeBJ()
6677 call CinematicFadeCommonBJ(red, green, blue, duration, tex, 100, trans)
6678 elseif (fadetype == bj_CINEFADETYPE_FADEIN) then
6679 // Fade in from the requested color.
6680 call AbortCinematicFadeBJ()
6681 call CinematicFadeCommonBJ(red, green, blue, duration, tex, trans, 100)
6682 call FinishCinematicFadeAfterBJ(duration)
6683 elseif (fadetype == bj_CINEFADETYPE_FADEOUTIN) then
6684 // Fade out to the requested color, and then fade back in from it.
6685 if (duration > 0) then
6686 call AbortCinematicFadeBJ()
6687 call CinematicFadeCommonBJ(red, green, blue, duration * 0.5, tex, 100, trans)
6688 call ContinueCinematicFadeAfterBJ(duration * 0.5, red, green, blue, trans, tex)
6689 call FinishCinematicFadeAfterBJ(duration)
6690 endif
6691 else
6692 // Unrecognized fadetype - ignore the request.
6693 endif
6694endfunction
6695
6696//===========================================================================
6697function CinematicFilterGenericBJ takes real duration, blendmode bmode, string tex, real red0, real green0, real blue0, real trans0, real red1, real green1, real blue1, real trans1 returns nothing
6698 call AbortCinematicFadeBJ()
6699 call SetCineFilterTexture(tex)
6700 call SetCineFilterBlendMode(bmode)
6701 call SetCineFilterTexMapFlags(TEXMAP_FLAG_NONE)
6702 call SetCineFilterStartUV(0, 0, 1, 1)
6703 call SetCineFilterEndUV(0, 0, 1, 1)
6704 call SetCineFilterStartColor(PercentTo255(red0), PercentTo255(green0), PercentTo255(blue0), PercentTo255(100-trans0))
6705 call SetCineFilterEndColor(PercentTo255(red1), PercentTo255(green1), PercentTo255(blue1), PercentTo255(100-trans1))
6706 call SetCineFilterDuration(duration)
6707 call DisplayCineFilter(true)
6708endfunction
6709
6710
6711
6712//***************************************************************************
6713//*
6714//* Rescuable Unit Utility Functions
6715//*
6716//***************************************************************************
6717
6718//===========================================================================
6719// Rescues a unit for a player. This performs the default rescue behavior,
6720// including a rescue sound, flashing selection circle, ownership change,
6721// and optionally a unit color change.
6722//
6723function RescueUnitBJ takes unit whichUnit, player rescuer, boolean changeColor returns nothing
6724 if IsUnitDeadBJ(whichUnit) or (GetOwningPlayer(whichUnit) == rescuer) then
6725 return
6726 endif
6727
6728 call StartSound(bj_rescueSound)
6729 call SetUnitOwner(whichUnit, rescuer, changeColor)
6730 call UnitAddIndicator(whichUnit, 0, 255, 0, 255)
6731 call PingMinimapForPlayer(rescuer, GetUnitX(whichUnit), GetUnitY(whichUnit), bj_RESCUE_PING_TIME)
6732endfunction
6733
6734//===========================================================================
6735function TriggerActionUnitRescuedBJ takes nothing returns nothing
6736 local unit theUnit = GetTriggerUnit()
6737
6738 if IsUnitType(theUnit, UNIT_TYPE_STRUCTURE) then
6739 call RescueUnitBJ(theUnit, GetOwningPlayer(GetRescuer()), bj_rescueChangeColorBldg)
6740 else
6741 call RescueUnitBJ(theUnit, GetOwningPlayer(GetRescuer()), bj_rescueChangeColorUnit)
6742 endif
6743endfunction
6744
6745//===========================================================================
6746// Attempt to init triggers for default rescue behavior. For performance
6747// reasons, this should only be attempted if a player is set to Rescuable,
6748// or if a specific unit is thus flagged.
6749//
6750function TryInitRescuableTriggersBJ takes nothing returns nothing
6751 local integer index
6752
6753 if (bj_rescueUnitBehavior == null) then
6754 set bj_rescueUnitBehavior = CreateTrigger()
6755 set index = 0
6756 loop
6757 call TriggerRegisterPlayerUnitEvent(bj_rescueUnitBehavior, Player(index), EVENT_PLAYER_UNIT_RESCUED, null)
6758 set index = index + 1
6759 exitwhen index == bj_MAX_PLAYER_SLOTS
6760 endloop
6761 call TriggerAddAction(bj_rescueUnitBehavior, function TriggerActionUnitRescuedBJ)
6762 endif
6763endfunction
6764
6765//===========================================================================
6766// Determines whether or not rescued units automatically change color upon
6767// being rescued.
6768//
6769function SetRescueUnitColorChangeBJ takes boolean changeColor returns nothing
6770 set bj_rescueChangeColorUnit = changeColor
6771endfunction
6772
6773//===========================================================================
6774// Determines whether or not rescued buildings automatically change color
6775// upon being rescued.
6776//
6777function SetRescueBuildingColorChangeBJ takes boolean changeColor returns nothing
6778 set bj_rescueChangeColorBldg = changeColor
6779endfunction
6780
6781//===========================================================================
6782function MakeUnitRescuableToForceBJEnum takes nothing returns nothing
6783 call TryInitRescuableTriggersBJ()
6784 call SetUnitRescuable(bj_makeUnitRescuableUnit, GetEnumPlayer(), bj_makeUnitRescuableFlag)
6785endfunction
6786
6787//===========================================================================
6788function MakeUnitRescuableToForceBJ takes unit whichUnit, boolean isRescuable, force whichForce returns nothing
6789 // Flag the unit as rescuable/unrescuable for the appropriate players.
6790 set bj_makeUnitRescuableUnit = whichUnit
6791 set bj_makeUnitRescuableFlag = isRescuable
6792 call ForForce(whichForce, function MakeUnitRescuableToForceBJEnum)
6793endfunction
6794
6795//===========================================================================
6796function InitRescuableBehaviorBJ takes nothing returns nothing
6797 local integer index
6798
6799 set index = 0
6800 loop
6801 // If at least one player slot is "Rescuable"-controlled, init the
6802 // rescue behavior triggers.
6803 if (GetPlayerController(Player(index)) == MAP_CONTROL_RESCUABLE) then
6804 call TryInitRescuableTriggersBJ()
6805 return
6806 endif
6807 set index = index + 1
6808 exitwhen index == bj_MAX_PLAYERS
6809 endloop
6810endfunction
6811
6812
6813
6814//***************************************************************************
6815//*
6816//* Research and Upgrade Utility Functions
6817//*
6818//***************************************************************************
6819
6820//===========================================================================
6821function SetPlayerTechResearchedSwap takes integer techid, integer levels, player whichPlayer returns nothing
6822 call SetPlayerTechResearched(whichPlayer, techid, levels)
6823endfunction
6824
6825//===========================================================================
6826function SetPlayerTechMaxAllowedSwap takes integer techid, integer maximum, player whichPlayer returns nothing
6827 call SetPlayerTechMaxAllowed(whichPlayer, techid, maximum)
6828endfunction
6829
6830//===========================================================================
6831function SetPlayerMaxHeroesAllowed takes integer maximum, player whichPlayer returns nothing
6832 call SetPlayerTechMaxAllowed(whichPlayer, 'HERO', maximum)
6833endfunction
6834
6835//===========================================================================
6836function GetPlayerTechCountSimple takes integer techid, player whichPlayer returns integer
6837 return GetPlayerTechCount(whichPlayer, techid, true)
6838endfunction
6839
6840//===========================================================================
6841function GetPlayerTechMaxAllowedSwap takes integer techid, player whichPlayer returns integer
6842 return GetPlayerTechMaxAllowed(whichPlayer, techid)
6843endfunction
6844
6845//===========================================================================
6846function SetPlayerAbilityAvailableBJ takes boolean avail, integer abilid, player whichPlayer returns nothing
6847 call SetPlayerAbilityAvailable(whichPlayer, abilid, avail)
6848endfunction
6849
6850
6851
6852//***************************************************************************
6853//*
6854//* Campaign Utility Functions
6855//*
6856//***************************************************************************
6857
6858function SetCampaignMenuRaceBJ takes integer campaignNumber returns nothing
6859 if (campaignNumber == bj_CAMPAIGN_INDEX_T) then
6860 call SetCampaignMenuRace(RACE_OTHER)
6861 elseif (campaignNumber == bj_CAMPAIGN_INDEX_H) then
6862 call SetCampaignMenuRace(RACE_HUMAN)
6863 elseif (campaignNumber == bj_CAMPAIGN_INDEX_U) then
6864 call SetCampaignMenuRace(RACE_UNDEAD)
6865 elseif (campaignNumber == bj_CAMPAIGN_INDEX_O) then
6866 call SetCampaignMenuRace(RACE_ORC)
6867 elseif (campaignNumber == bj_CAMPAIGN_INDEX_N) then
6868 call SetCampaignMenuRace(RACE_NIGHTELF)
6869 elseif (campaignNumber == bj_CAMPAIGN_INDEX_XN) then
6870 call SetCampaignMenuRaceEx(bj_CAMPAIGN_OFFSET_XN)
6871 elseif (campaignNumber == bj_CAMPAIGN_INDEX_XH) then
6872 call SetCampaignMenuRaceEx(bj_CAMPAIGN_OFFSET_XH)
6873 elseif (campaignNumber == bj_CAMPAIGN_INDEX_XU) then
6874 call SetCampaignMenuRaceEx(bj_CAMPAIGN_OFFSET_XU)
6875 elseif (campaignNumber == bj_CAMPAIGN_INDEX_XO) then
6876 call SetCampaignMenuRaceEx(bj_CAMPAIGN_OFFSET_XO)
6877 else
6878 // Unrecognized campaign - ignore the request
6879 endif
6880endfunction
6881
6882//===========================================================================
6883// Converts a single campaign mission designation into campaign and mission
6884// numbers. The 1000's digit is considered the campaign index, and the 1's
6885// digit is considered the mission index within that campaign. This is done
6886// so that the trigger for this can use a single drop-down to list all of
6887// the campaign missions.
6888//
6889function SetMissionAvailableBJ takes boolean available, integer missionIndex returns nothing
6890 local integer campaignNumber = missionIndex / 1000
6891 local integer missionNumber = missionIndex - campaignNumber * 1000
6892
6893 call SetMissionAvailable(campaignNumber, missionNumber, available)
6894endfunction
6895
6896//===========================================================================
6897function SetCampaignAvailableBJ takes boolean available, integer campaignNumber returns nothing
6898 local integer campaignOffset
6899
6900 if (campaignNumber == bj_CAMPAIGN_INDEX_H) then
6901 call SetTutorialCleared(true)
6902 endif
6903
6904 if (campaignNumber == bj_CAMPAIGN_INDEX_XN) then
6905 set campaignOffset = bj_CAMPAIGN_OFFSET_XN
6906 elseif (campaignNumber == bj_CAMPAIGN_INDEX_XH) then
6907 set campaignOffset = bj_CAMPAIGN_OFFSET_XH
6908 elseif (campaignNumber == bj_CAMPAIGN_INDEX_XU) then
6909 set campaignOffset = bj_CAMPAIGN_OFFSET_XU
6910 elseif (campaignNumber == bj_CAMPAIGN_INDEX_XO) then
6911 set campaignOffset = bj_CAMPAIGN_OFFSET_XO
6912 else
6913 set campaignOffset = campaignNumber
6914 endif
6915
6916 call SetCampaignAvailable(campaignOffset, available)
6917 call SetCampaignMenuRaceBJ(campaignNumber)
6918 call ForceCampaignSelectScreen()
6919endfunction
6920
6921//===========================================================================
6922function SetCinematicAvailableBJ takes boolean available, integer cinematicIndex returns nothing
6923 if ( cinematicIndex == bj_CINEMATICINDEX_TOP ) then
6924 call SetOpCinematicAvailable( bj_CAMPAIGN_INDEX_T, available )
6925 call PlayCinematic( "TutorialOp" )
6926 elseif (cinematicIndex == bj_CINEMATICINDEX_HOP) then
6927 call SetOpCinematicAvailable( bj_CAMPAIGN_INDEX_H, available )
6928 call PlayCinematic( "HumanOp" )
6929 elseif (cinematicIndex == bj_CINEMATICINDEX_HED) then
6930 call SetEdCinematicAvailable( bj_CAMPAIGN_INDEX_H, available )
6931 call PlayCinematic( "HumanEd" )
6932 elseif (cinematicIndex == bj_CINEMATICINDEX_OOP) then
6933 call SetOpCinematicAvailable( bj_CAMPAIGN_INDEX_O, available )
6934 call PlayCinematic( "OrcOp" )
6935 elseif (cinematicIndex == bj_CINEMATICINDEX_OED) then
6936 call SetEdCinematicAvailable( bj_CAMPAIGN_INDEX_O, available )
6937 call PlayCinematic( "OrcEd" )
6938 elseif (cinematicIndex == bj_CINEMATICINDEX_UOP) then
6939 call SetEdCinematicAvailable( bj_CAMPAIGN_INDEX_U, available )
6940 call PlayCinematic( "UndeadOp" )
6941 elseif (cinematicIndex == bj_CINEMATICINDEX_UED) then
6942 call SetEdCinematicAvailable( bj_CAMPAIGN_INDEX_U, available )
6943 call PlayCinematic( "UndeadEd" )
6944 elseif (cinematicIndex == bj_CINEMATICINDEX_NOP) then
6945 call SetEdCinematicAvailable( bj_CAMPAIGN_INDEX_N, available )
6946 call PlayCinematic( "NightElfOp" )
6947 elseif (cinematicIndex == bj_CINEMATICINDEX_NED) then
6948 call SetEdCinematicAvailable( bj_CAMPAIGN_INDEX_N, available )
6949 call PlayCinematic( "NightElfEd" )
6950 elseif (cinematicIndex == bj_CINEMATICINDEX_XOP) then
6951 call SetOpCinematicAvailable( bj_CAMPAIGN_OFFSET_XN, available )
6952 call PlayCinematic( "IntroX" )
6953 elseif (cinematicIndex == bj_CINEMATICINDEX_XED) then
6954 call SetEdCinematicAvailable( bj_CAMPAIGN_OFFSET_XU, available )
6955 call PlayCinematic( "OutroX" )
6956 else
6957 // Unrecognized cinematic - ignore the request.
6958 endif
6959endfunction
6960
6961//===========================================================================
6962function InitGameCacheBJ takes string campaignFile returns gamecache
6963 set bj_lastCreatedGameCache = InitGameCache(campaignFile)
6964 return bj_lastCreatedGameCache
6965endfunction
6966
6967//===========================================================================
6968function SaveGameCacheBJ takes gamecache cache returns boolean
6969 return SaveGameCache(cache)
6970endfunction
6971
6972//===========================================================================
6973function GetLastCreatedGameCacheBJ takes nothing returns gamecache
6974 return bj_lastCreatedGameCache
6975endfunction
6976
6977//===========================================================================
6978function InitHashtableBJ takes nothing returns hashtable
6979 set bj_lastCreatedHashtable = InitHashtable()
6980 return bj_lastCreatedHashtable
6981endfunction
6982
6983//===========================================================================
6984function GetLastCreatedHashtableBJ takes nothing returns hashtable
6985 return bj_lastCreatedHashtable
6986endfunction
6987
6988//===========================================================================
6989function StoreRealBJ takes real value, string key, string missionKey, gamecache cache returns nothing
6990 call StoreReal(cache, missionKey, key, value)
6991endfunction
6992
6993//===========================================================================
6994function StoreIntegerBJ takes integer value, string key, string missionKey, gamecache cache returns nothing
6995 call StoreInteger(cache, missionKey, key, value)
6996endfunction
6997
6998//===========================================================================
6999function StoreBooleanBJ takes boolean value, string key, string missionKey, gamecache cache returns nothing
7000 call StoreBoolean(cache, missionKey, key, value)
7001endfunction
7002
7003//===========================================================================
7004function StoreStringBJ takes string value, string key, string missionKey, gamecache cache returns boolean
7005 return StoreString(cache, missionKey, key, value)
7006endfunction
7007
7008//===========================================================================
7009function StoreUnitBJ takes unit whichUnit, string key, string missionKey, gamecache cache returns boolean
7010 return StoreUnit(cache, missionKey, key, whichUnit)
7011endfunction
7012
7013//===========================================================================
7014function SaveRealBJ takes real value, integer key, integer missionKey, hashtable table returns nothing
7015 call SaveReal(table, missionKey, key, value)
7016endfunction
7017
7018//===========================================================================
7019function SaveIntegerBJ takes integer value, integer key, integer missionKey, hashtable table returns nothing
7020 call SaveInteger(table, missionKey, key, value)
7021endfunction
7022
7023//===========================================================================
7024function SaveBooleanBJ takes boolean value, integer key, integer missionKey, hashtable table returns nothing
7025 call SaveBoolean(table, missionKey, key, value)
7026endfunction
7027
7028//===========================================================================
7029function SaveStringBJ takes string value, integer key, integer missionKey, hashtable table returns boolean
7030 return SaveStr(table, missionKey, key, value)
7031endfunction
7032
7033//===========================================================================
7034function SavePlayerHandleBJ takes player whichPlayer, integer key, integer missionKey, hashtable table returns boolean
7035 return SavePlayerHandle(table, missionKey, key, whichPlayer)
7036endfunction
7037
7038//===========================================================================
7039function SaveWidgetHandleBJ takes widget whichWidget, integer key, integer missionKey, hashtable table returns boolean
7040 return SaveWidgetHandle(table, missionKey, key, whichWidget)
7041endfunction
7042
7043//===========================================================================
7044function SaveDestructableHandleBJ takes destructable whichDestructable, integer key, integer missionKey, hashtable table returns boolean
7045 return SaveDestructableHandle(table, missionKey, key, whichDestructable)
7046endfunction
7047
7048//===========================================================================
7049function SaveItemHandleBJ takes item whichItem, integer key, integer missionKey, hashtable table returns boolean
7050 return SaveItemHandle(table, missionKey, key, whichItem)
7051endfunction
7052
7053//===========================================================================
7054function SaveUnitHandleBJ takes unit whichUnit, integer key, integer missionKey, hashtable table returns boolean
7055 return SaveUnitHandle(table, missionKey, key, whichUnit)
7056endfunction
7057
7058//===========================================================================
7059function SaveAbilityHandleBJ takes ability whichAbility, integer key, integer missionKey, hashtable table returns boolean
7060 return SaveAbilityHandle(table, missionKey, key, whichAbility)
7061endfunction
7062
7063//===========================================================================
7064function SaveTimerHandleBJ takes timer whichTimer, integer key, integer missionKey, hashtable table returns boolean
7065 return SaveTimerHandle(table, missionKey, key, whichTimer)
7066endfunction
7067
7068//===========================================================================
7069function SaveTriggerHandleBJ takes trigger whichTrigger, integer key, integer missionKey, hashtable table returns boolean
7070 return SaveTriggerHandle(table, missionKey, key, whichTrigger)
7071endfunction
7072
7073//===========================================================================
7074function SaveTriggerConditionHandleBJ takes triggercondition whichTriggercondition, integer key, integer missionKey, hashtable table returns boolean
7075 return SaveTriggerConditionHandle(table, missionKey, key, whichTriggercondition)
7076endfunction
7077
7078//===========================================================================
7079function SaveTriggerActionHandleBJ takes triggeraction whichTriggeraction, integer key, integer missionKey, hashtable table returns boolean
7080 return SaveTriggerActionHandle(table, missionKey, key, whichTriggeraction)
7081endfunction
7082
7083//===========================================================================
7084function SaveTriggerEventHandleBJ takes event whichEvent, integer key, integer missionKey, hashtable table returns boolean
7085 return SaveTriggerEventHandle(table, missionKey, key, whichEvent)
7086endfunction
7087
7088//===========================================================================
7089function SaveForceHandleBJ takes force whichForce, integer key, integer missionKey, hashtable table returns boolean
7090 return SaveForceHandle(table, missionKey, key, whichForce)
7091endfunction
7092
7093//===========================================================================
7094function SaveGroupHandleBJ takes group whichGroup, integer key, integer missionKey, hashtable table returns boolean
7095 return SaveGroupHandle(table, missionKey, key, whichGroup)
7096endfunction
7097
7098//===========================================================================
7099function SaveLocationHandleBJ takes location whichLocation, integer key, integer missionKey, hashtable table returns boolean
7100 return SaveLocationHandle(table, missionKey, key, whichLocation)
7101endfunction
7102
7103//===========================================================================
7104function SaveRectHandleBJ takes rect whichRect, integer key, integer missionKey, hashtable table returns boolean
7105 return SaveRectHandle(table, missionKey, key, whichRect)
7106endfunction
7107
7108//===========================================================================
7109function SaveBooleanExprHandleBJ takes boolexpr whichBoolexpr, integer key, integer missionKey, hashtable table returns boolean
7110 return SaveBooleanExprHandle(table, missionKey, key, whichBoolexpr)
7111endfunction
7112
7113//===========================================================================
7114function SaveSoundHandleBJ takes sound whichSound, integer key, integer missionKey, hashtable table returns boolean
7115 return SaveSoundHandle(table, missionKey, key, whichSound)
7116endfunction
7117
7118//===========================================================================
7119function SaveEffectHandleBJ takes effect whichEffect, integer key, integer missionKey, hashtable table returns boolean
7120 return SaveEffectHandle(table, missionKey, key, whichEffect)
7121endfunction
7122
7123//===========================================================================
7124function SaveUnitPoolHandleBJ takes unitpool whichUnitpool, integer key, integer missionKey, hashtable table returns boolean
7125 return SaveUnitPoolHandle(table, missionKey, key, whichUnitpool)
7126endfunction
7127
7128//===========================================================================
7129function SaveItemPoolHandleBJ takes itempool whichItempool, integer key, integer missionKey, hashtable table returns boolean
7130 return SaveItemPoolHandle(table, missionKey, key, whichItempool)
7131endfunction
7132
7133//===========================================================================
7134function SaveQuestHandleBJ takes quest whichQuest, integer key, integer missionKey, hashtable table returns boolean
7135 return SaveQuestHandle(table, missionKey, key, whichQuest)
7136endfunction
7137
7138//===========================================================================
7139function SaveQuestItemHandleBJ takes questitem whichQuestitem, integer key, integer missionKey, hashtable table returns boolean
7140 return SaveQuestItemHandle(table, missionKey, key, whichQuestitem)
7141endfunction
7142
7143//===========================================================================
7144function SaveDefeatConditionHandleBJ takes defeatcondition whichDefeatcondition, integer key, integer missionKey, hashtable table returns boolean
7145 return SaveDefeatConditionHandle(table, missionKey, key, whichDefeatcondition)
7146endfunction
7147
7148//===========================================================================
7149function SaveTimerDialogHandleBJ takes timerdialog whichTimerdialog, integer key, integer missionKey, hashtable table returns boolean
7150 return SaveTimerDialogHandle(table, missionKey, key, whichTimerdialog)
7151endfunction
7152
7153//===========================================================================
7154function SaveLeaderboardHandleBJ takes leaderboard whichLeaderboard, integer key, integer missionKey, hashtable table returns boolean
7155 return SaveLeaderboardHandle(table, missionKey, key, whichLeaderboard)
7156endfunction
7157
7158//===========================================================================
7159function SaveMultiboardHandleBJ takes multiboard whichMultiboard, integer key, integer missionKey, hashtable table returns boolean
7160 return SaveMultiboardHandle(table, missionKey, key, whichMultiboard)
7161endfunction
7162
7163//===========================================================================
7164function SaveMultiboardItemHandleBJ takes multiboarditem whichMultiboarditem, integer key, integer missionKey, hashtable table returns boolean
7165 return SaveMultiboardItemHandle(table, missionKey, key, whichMultiboarditem)
7166endfunction
7167
7168//===========================================================================
7169function SaveTrackableHandleBJ takes trackable whichTrackable, integer key, integer missionKey, hashtable table returns boolean
7170 return SaveTrackableHandle(table, missionKey, key, whichTrackable)
7171endfunction
7172
7173//===========================================================================
7174function SaveDialogHandleBJ takes dialog whichDialog, integer key, integer missionKey, hashtable table returns boolean
7175 return SaveDialogHandle(table, missionKey, key, whichDialog)
7176endfunction
7177
7178//===========================================================================
7179function SaveButtonHandleBJ takes button whichButton, integer key, integer missionKey, hashtable table returns boolean
7180 return SaveButtonHandle(table, missionKey, key, whichButton)
7181endfunction
7182
7183//===========================================================================
7184function SaveTextTagHandleBJ takes texttag whichTexttag, integer key, integer missionKey, hashtable table returns boolean
7185 return SaveTextTagHandle(table, missionKey, key, whichTexttag)
7186endfunction
7187
7188//===========================================================================
7189function SaveLightningHandleBJ takes lightning whichLightning, integer key, integer missionKey, hashtable table returns boolean
7190 return SaveLightningHandle(table, missionKey, key, whichLightning)
7191endfunction
7192
7193//===========================================================================
7194function SaveImageHandleBJ takes image whichImage, integer key, integer missionKey, hashtable table returns boolean
7195 return SaveImageHandle(table, missionKey, key, whichImage)
7196endfunction
7197
7198//===========================================================================
7199function SaveUbersplatHandleBJ takes ubersplat whichUbersplat, integer key, integer missionKey, hashtable table returns boolean
7200 return SaveUbersplatHandle(table, missionKey, key, whichUbersplat)
7201endfunction
7202
7203//===========================================================================
7204function SaveRegionHandleBJ takes region whichRegion, integer key, integer missionKey, hashtable table returns boolean
7205 return SaveRegionHandle(table, missionKey, key, whichRegion)
7206endfunction
7207
7208//===========================================================================
7209function SaveFogStateHandleBJ takes fogstate whichFogState, integer key, integer missionKey, hashtable table returns boolean
7210 return SaveFogStateHandle(table, missionKey, key, whichFogState)
7211endfunction
7212
7213//===========================================================================
7214function SaveFogModifierHandleBJ takes fogmodifier whichFogModifier, integer key, integer missionKey, hashtable table returns boolean
7215 return SaveFogModifierHandle(table, missionKey, key, whichFogModifier)
7216endfunction
7217
7218//===========================================================================
7219function SaveAgentHandleBJ takes agent whichAgent, integer key, integer missionKey, hashtable table returns boolean
7220 return SaveAgentHandle(table, missionKey, key, whichAgent)
7221endfunction
7222
7223//===========================================================================
7224function SaveHashtableHandleBJ takes hashtable whichHashtable, integer key, integer missionKey, hashtable table returns boolean
7225 return SaveHashtableHandle(table, missionKey, key, whichHashtable)
7226endfunction
7227
7228//===========================================================================
7229function GetStoredRealBJ takes string key, string missionKey, gamecache cache returns real
7230 //call SyncStoredReal(cache, missionKey, key)
7231 return GetStoredReal(cache, missionKey, key)
7232endfunction
7233
7234//===========================================================================
7235function GetStoredIntegerBJ takes string key, string missionKey, gamecache cache returns integer
7236 //call SyncStoredInteger(cache, missionKey, key)
7237 return GetStoredInteger(cache, missionKey, key)
7238endfunction
7239
7240//===========================================================================
7241function GetStoredBooleanBJ takes string key, string missionKey, gamecache cache returns boolean
7242 //call SyncStoredBoolean(cache, missionKey, key)
7243 return GetStoredBoolean(cache, missionKey, key)
7244endfunction
7245
7246//===========================================================================
7247function GetStoredStringBJ takes string key, string missionKey, gamecache cache returns string
7248 local string s
7249
7250 //call SyncStoredString(cache, missionKey, key)
7251 set s = GetStoredString(cache, missionKey, key)
7252 if (s == null) then
7253 return ""
7254 else
7255 return s
7256 endif
7257endfunction
7258
7259//===========================================================================
7260function LoadRealBJ takes integer key, integer missionKey, hashtable table returns real
7261 //call SyncStoredReal(table, missionKey, key)
7262 return LoadReal(table, missionKey, key)
7263endfunction
7264
7265//===========================================================================
7266function LoadIntegerBJ takes integer key, integer missionKey, hashtable table returns integer
7267 //call SyncStoredInteger(table, missionKey, key)
7268 return LoadInteger(table, missionKey, key)
7269endfunction
7270
7271//===========================================================================
7272function LoadBooleanBJ takes integer key, integer missionKey, hashtable table returns boolean
7273 //call SyncStoredBoolean(table, missionKey, key)
7274 return LoadBoolean(table, missionKey, key)
7275endfunction
7276
7277//===========================================================================
7278function LoadStringBJ takes integer key, integer missionKey, hashtable table returns string
7279 local string s
7280
7281 //call SyncStoredString(table, missionKey, key)
7282 set s = LoadStr(table, missionKey, key)
7283 if (s == null) then
7284 return ""
7285 else
7286 return s
7287 endif
7288endfunction
7289
7290//===========================================================================
7291function LoadPlayerHandleBJ takes integer key, integer missionKey, hashtable table returns player
7292 return LoadPlayerHandle(table, missionKey, key)
7293endfunction
7294
7295//===========================================================================
7296function LoadWidgetHandleBJ takes integer key, integer missionKey, hashtable table returns widget
7297 return LoadWidgetHandle(table, missionKey, key)
7298endfunction
7299
7300//===========================================================================
7301function LoadDestructableHandleBJ takes integer key, integer missionKey, hashtable table returns destructable
7302 return LoadDestructableHandle(table, missionKey, key)
7303endfunction
7304
7305//===========================================================================
7306function LoadItemHandleBJ takes integer key, integer missionKey, hashtable table returns item
7307 return LoadItemHandle(table, missionKey, key)
7308endfunction
7309
7310//===========================================================================
7311function LoadUnitHandleBJ takes integer key, integer missionKey, hashtable table returns unit
7312 return LoadUnitHandle(table, missionKey, key)
7313endfunction
7314
7315//===========================================================================
7316function LoadAbilityHandleBJ takes integer key, integer missionKey, hashtable table returns ability
7317 return LoadAbilityHandle(table, missionKey, key)
7318endfunction
7319
7320//===========================================================================
7321function LoadTimerHandleBJ takes integer key, integer missionKey, hashtable table returns timer
7322 return LoadTimerHandle(table, missionKey, key)
7323endfunction
7324
7325//===========================================================================
7326function LoadTriggerHandleBJ takes integer key, integer missionKey, hashtable table returns trigger
7327 return LoadTriggerHandle(table, missionKey, key)
7328endfunction
7329
7330//===========================================================================
7331function LoadTriggerConditionHandleBJ takes integer key, integer missionKey, hashtable table returns triggercondition
7332 return LoadTriggerConditionHandle(table, missionKey, key)
7333endfunction
7334
7335//===========================================================================
7336function LoadTriggerActionHandleBJ takes integer key, integer missionKey, hashtable table returns triggeraction
7337 return LoadTriggerActionHandle(table, missionKey, key)
7338endfunction
7339
7340//===========================================================================
7341function LoadTriggerEventHandleBJ takes integer key, integer missionKey, hashtable table returns event
7342 return LoadTriggerEventHandle(table, missionKey, key)
7343endfunction
7344
7345//===========================================================================
7346function LoadForceHandleBJ takes integer key, integer missionKey, hashtable table returns force
7347 return LoadForceHandle(table, missionKey, key)
7348endfunction
7349
7350//===========================================================================
7351function LoadGroupHandleBJ takes integer key, integer missionKey, hashtable table returns group
7352 return LoadGroupHandle(table, missionKey, key)
7353endfunction
7354
7355//===========================================================================
7356function LoadLocationHandleBJ takes integer key, integer missionKey, hashtable table returns location
7357 return LoadLocationHandle(table, missionKey, key)
7358endfunction
7359
7360//===========================================================================
7361function LoadRectHandleBJ takes integer key, integer missionKey, hashtable table returns rect
7362 return LoadRectHandle(table, missionKey, key)
7363endfunction
7364
7365//===========================================================================
7366function LoadBooleanExprHandleBJ takes integer key, integer missionKey, hashtable table returns boolexpr
7367 return LoadBooleanExprHandle(table, missionKey, key)
7368endfunction
7369
7370//===========================================================================
7371function LoadSoundHandleBJ takes integer key, integer missionKey, hashtable table returns sound
7372 return LoadSoundHandle(table, missionKey, key)
7373endfunction
7374
7375//===========================================================================
7376function LoadEffectHandleBJ takes integer key, integer missionKey, hashtable table returns effect
7377 return LoadEffectHandle(table, missionKey, key)
7378endfunction
7379
7380//===========================================================================
7381function LoadUnitPoolHandleBJ takes integer key, integer missionKey, hashtable table returns unitpool
7382 return LoadUnitPoolHandle(table, missionKey, key)
7383endfunction
7384
7385//===========================================================================
7386function LoadItemPoolHandleBJ takes integer key, integer missionKey, hashtable table returns itempool
7387 return LoadItemPoolHandle(table, missionKey, key)
7388endfunction
7389
7390//===========================================================================
7391function LoadQuestHandleBJ takes integer key, integer missionKey, hashtable table returns quest
7392 return LoadQuestHandle(table, missionKey, key)
7393endfunction
7394
7395//===========================================================================
7396function LoadQuestItemHandleBJ takes integer key, integer missionKey, hashtable table returns questitem
7397 return LoadQuestItemHandle(table, missionKey, key)
7398endfunction
7399
7400//===========================================================================
7401function LoadDefeatConditionHandleBJ takes integer key, integer missionKey, hashtable table returns defeatcondition
7402 return LoadDefeatConditionHandle(table, missionKey, key)
7403endfunction
7404
7405//===========================================================================
7406function LoadTimerDialogHandleBJ takes integer key, integer missionKey, hashtable table returns timerdialog
7407 return LoadTimerDialogHandle(table, missionKey, key)
7408endfunction
7409
7410//===========================================================================
7411function LoadLeaderboardHandleBJ takes integer key, integer missionKey, hashtable table returns leaderboard
7412 return LoadLeaderboardHandle(table, missionKey, key)
7413endfunction
7414
7415//===========================================================================
7416function LoadMultiboardHandleBJ takes integer key, integer missionKey, hashtable table returns multiboard
7417 return LoadMultiboardHandle(table, missionKey, key)
7418endfunction
7419
7420//===========================================================================
7421function LoadMultiboardItemHandleBJ takes integer key, integer missionKey, hashtable table returns multiboarditem
7422 return LoadMultiboardItemHandle(table, missionKey, key)
7423endfunction
7424
7425//===========================================================================
7426function LoadTrackableHandleBJ takes integer key, integer missionKey, hashtable table returns trackable
7427 return LoadTrackableHandle(table, missionKey, key)
7428endfunction
7429
7430//===========================================================================
7431function LoadDialogHandleBJ takes integer key, integer missionKey, hashtable table returns dialog
7432 return LoadDialogHandle(table, missionKey, key)
7433endfunction
7434
7435//===========================================================================
7436function LoadButtonHandleBJ takes integer key, integer missionKey, hashtable table returns button
7437 return LoadButtonHandle(table, missionKey, key)
7438endfunction
7439
7440//===========================================================================
7441function LoadTextTagHandleBJ takes integer key, integer missionKey, hashtable table returns texttag
7442 return LoadTextTagHandle(table, missionKey, key)
7443endfunction
7444
7445//===========================================================================
7446function LoadLightningHandleBJ takes integer key, integer missionKey, hashtable table returns lightning
7447 return LoadLightningHandle(table, missionKey, key)
7448endfunction
7449
7450//===========================================================================
7451function LoadImageHandleBJ takes integer key, integer missionKey, hashtable table returns image
7452 return LoadImageHandle(table, missionKey, key)
7453endfunction
7454
7455//===========================================================================
7456function LoadUbersplatHandleBJ takes integer key, integer missionKey, hashtable table returns ubersplat
7457 return LoadUbersplatHandle(table, missionKey, key)
7458endfunction
7459
7460//===========================================================================
7461function LoadRegionHandleBJ takes integer key, integer missionKey, hashtable table returns region
7462 return LoadRegionHandle(table, missionKey, key)
7463endfunction
7464
7465//===========================================================================
7466function LoadFogStateHandleBJ takes integer key, integer missionKey, hashtable table returns fogstate
7467 return LoadFogStateHandle(table, missionKey, key)
7468endfunction
7469
7470//===========================================================================
7471function LoadFogModifierHandleBJ takes integer key, integer missionKey, hashtable table returns fogmodifier
7472 return LoadFogModifierHandle(table, missionKey, key)
7473endfunction
7474
7475//===========================================================================
7476function LoadHashtableHandleBJ takes integer key, integer missionKey, hashtable table returns hashtable
7477 return LoadHashtableHandle(table, missionKey, key)
7478endfunction
7479
7480//===========================================================================
7481function RestoreUnitLocFacingAngleBJ takes string key, string missionKey, gamecache cache, player forWhichPlayer, location loc, real facing returns unit
7482 //call SyncStoredUnit(cache, missionKey, key)
7483 set bj_lastLoadedUnit = RestoreUnit(cache, missionKey, key, forWhichPlayer, GetLocationX(loc), GetLocationY(loc), facing)
7484 return bj_lastLoadedUnit
7485endfunction
7486
7487//===========================================================================
7488function RestoreUnitLocFacingPointBJ takes string key, string missionKey, gamecache cache, player forWhichPlayer, location loc, location lookAt returns unit
7489 //call SyncStoredUnit(cache, missionKey, key)
7490 return RestoreUnitLocFacingAngleBJ(key, missionKey, cache, forWhichPlayer, loc, AngleBetweenPoints(loc, lookAt))
7491endfunction
7492
7493//===========================================================================
7494function GetLastRestoredUnitBJ takes nothing returns unit
7495 return bj_lastLoadedUnit
7496endfunction
7497
7498//===========================================================================
7499function FlushGameCacheBJ takes gamecache cache returns nothing
7500 call FlushGameCache(cache)
7501endfunction
7502
7503//===========================================================================
7504function FlushStoredMissionBJ takes string missionKey, gamecache cache returns nothing
7505 call FlushStoredMission(cache, missionKey)
7506endfunction
7507
7508//===========================================================================
7509function FlushParentHashtableBJ takes hashtable table returns nothing
7510 call FlushParentHashtable(table)
7511endfunction
7512
7513//===========================================================================
7514function FlushChildHashtableBJ takes integer missionKey, hashtable table returns nothing
7515 call FlushChildHashtable(table, missionKey)
7516endfunction
7517
7518//===========================================================================
7519function HaveStoredValue takes string key, integer valueType, string missionKey, gamecache cache returns boolean
7520 if (valueType == bj_GAMECACHE_BOOLEAN) then
7521 return HaveStoredBoolean(cache, missionKey, key)
7522 elseif (valueType == bj_GAMECACHE_INTEGER) then
7523 return HaveStoredInteger(cache, missionKey, key)
7524 elseif (valueType == bj_GAMECACHE_REAL) then
7525 return HaveStoredReal(cache, missionKey, key)
7526 elseif (valueType == bj_GAMECACHE_UNIT) then
7527 return HaveStoredUnit(cache, missionKey, key)
7528 elseif (valueType == bj_GAMECACHE_STRING) then
7529 return HaveStoredString(cache, missionKey, key)
7530 else
7531 // Unrecognized value type - ignore the request.
7532 return false
7533 endif
7534endfunction
7535
7536//===========================================================================
7537function HaveSavedValue takes integer key, integer valueType, integer missionKey, hashtable table returns boolean
7538 if (valueType == bj_HASHTABLE_BOOLEAN) then
7539 return HaveSavedBoolean(table, missionKey, key)
7540 elseif (valueType == bj_HASHTABLE_INTEGER) then
7541 return HaveSavedInteger(table, missionKey, key)
7542 elseif (valueType == bj_HASHTABLE_REAL) then
7543 return HaveSavedReal(table, missionKey, key)
7544 elseif (valueType == bj_HASHTABLE_STRING) then
7545 return HaveSavedString(table, missionKey, key)
7546 elseif (valueType == bj_HASHTABLE_HANDLE) then
7547 return HaveSavedHandle(table, missionKey, key)
7548 else
7549 // Unrecognized value type - ignore the request.
7550 return false
7551 endif
7552endfunction
7553
7554//===========================================================================
7555function ShowCustomCampaignButton takes boolean show, integer whichButton returns nothing
7556 call SetCustomCampaignButtonVisible(whichButton - 1, show)
7557endfunction
7558
7559//===========================================================================
7560function IsCustomCampaignButtonVisibile takes integer whichButton returns boolean
7561 return GetCustomCampaignButtonVisible(whichButton - 1)
7562endfunction
7563
7564//===========================================================================
7565function LoadGameBJ takes string loadFileName, boolean doScoreScreen returns nothing
7566 call LoadGame(loadFileName, doScoreScreen)
7567endfunction
7568
7569//===========================================================================
7570function SaveAndChangeLevelBJ takes string saveFileName, string newLevel, boolean doScoreScreen returns nothing
7571 call SaveGame(saveFileName)
7572 call ChangeLevel(newLevel, doScoreScreen)
7573endfunction
7574
7575//===========================================================================
7576function SaveAndLoadGameBJ takes string saveFileName, string loadFileName, boolean doScoreScreen returns nothing
7577 call SaveGame(saveFileName)
7578 call LoadGame(loadFileName, doScoreScreen)
7579endfunction
7580
7581//===========================================================================
7582function RenameSaveDirectoryBJ takes string sourceDirName, string destDirName returns boolean
7583 return RenameSaveDirectory(sourceDirName, destDirName)
7584endfunction
7585
7586//===========================================================================
7587function RemoveSaveDirectoryBJ takes string sourceDirName returns boolean
7588 return RemoveSaveDirectory(sourceDirName)
7589endfunction
7590
7591//===========================================================================
7592function CopySaveGameBJ takes string sourceSaveName, string destSaveName returns boolean
7593 return CopySaveGame(sourceSaveName, destSaveName)
7594endfunction
7595
7596
7597
7598//***************************************************************************
7599//*
7600//* Miscellaneous Utility Functions
7601//*
7602//***************************************************************************
7603
7604//===========================================================================
7605function GetPlayerStartLocationX takes player whichPlayer returns real
7606 return GetStartLocationX(GetPlayerStartLocation(whichPlayer))
7607endfunction
7608
7609//===========================================================================
7610function GetPlayerStartLocationY takes player whichPlayer returns real
7611 return GetStartLocationY(GetPlayerStartLocation(whichPlayer))
7612endfunction
7613
7614//===========================================================================
7615function GetPlayerStartLocationLoc takes player whichPlayer returns location
7616 return GetStartLocationLoc(GetPlayerStartLocation(whichPlayer))
7617endfunction
7618
7619//===========================================================================
7620function GetRectCenter takes rect whichRect returns location
7621 return Location(GetRectCenterX(whichRect), GetRectCenterY(whichRect))
7622endfunction
7623
7624//===========================================================================
7625function IsPlayerSlotState takes player whichPlayer, playerslotstate whichState returns boolean
7626 return GetPlayerSlotState(whichPlayer) == whichState
7627endfunction
7628
7629//===========================================================================
7630function GetFadeFromSeconds takes real seconds returns integer
7631 if (seconds != 0) then
7632 return 128 / R2I(seconds)
7633 endif
7634 return 10000
7635endfunction
7636
7637//===========================================================================
7638function GetFadeFromSecondsAsReal takes real seconds returns real
7639 if (seconds != 0) then
7640 return 128.00 / seconds
7641 endif
7642 return 10000.00
7643endfunction
7644
7645//===========================================================================
7646function AdjustPlayerStateSimpleBJ takes player whichPlayer, playerstate whichPlayerState, integer delta returns nothing
7647 call SetPlayerState(whichPlayer, whichPlayerState, GetPlayerState(whichPlayer, whichPlayerState) + delta)
7648endfunction
7649
7650//===========================================================================
7651function AdjustPlayerStateBJ takes integer delta, player whichPlayer, playerstate whichPlayerState returns nothing
7652 // If the change was positive, apply the difference to the player's
7653 // gathered resources property as well.
7654 if (delta > 0) then
7655 if (whichPlayerState == PLAYER_STATE_RESOURCE_GOLD) then
7656 call AdjustPlayerStateSimpleBJ(whichPlayer, PLAYER_STATE_GOLD_GATHERED, delta)
7657 elseif (whichPlayerState == PLAYER_STATE_RESOURCE_LUMBER) then
7658 call AdjustPlayerStateSimpleBJ(whichPlayer, PLAYER_STATE_LUMBER_GATHERED, delta)
7659 endif
7660 endif
7661
7662 call AdjustPlayerStateSimpleBJ(whichPlayer, whichPlayerState, delta)
7663endfunction
7664
7665//===========================================================================
7666function SetPlayerStateBJ takes player whichPlayer, playerstate whichPlayerState, integer value returns nothing
7667 local integer oldValue = GetPlayerState(whichPlayer, whichPlayerState)
7668 call AdjustPlayerStateBJ(value - oldValue, whichPlayer, whichPlayerState)
7669endfunction
7670
7671//===========================================================================
7672function SetPlayerFlagBJ takes playerstate whichPlayerFlag, boolean flag, player whichPlayer returns nothing
7673 call SetPlayerState(whichPlayer, whichPlayerFlag, IntegerTertiaryOp(flag, 1, 0))
7674endfunction
7675
7676//===========================================================================
7677function SetPlayerTaxRateBJ takes integer rate, playerstate whichResource, player sourcePlayer, player otherPlayer returns nothing
7678 call SetPlayerTaxRate(sourcePlayer, otherPlayer, whichResource, rate)
7679endfunction
7680
7681//===========================================================================
7682function GetPlayerTaxRateBJ takes playerstate whichResource, player sourcePlayer, player otherPlayer returns integer
7683 return GetPlayerTaxRate(sourcePlayer, otherPlayer, whichResource)
7684endfunction
7685
7686//===========================================================================
7687function IsPlayerFlagSetBJ takes playerstate whichPlayerFlag, player whichPlayer returns boolean
7688 return GetPlayerState(whichPlayer, whichPlayerFlag) == 1
7689endfunction
7690
7691//===========================================================================
7692function AddResourceAmountBJ takes integer delta, unit whichUnit returns nothing
7693 call AddResourceAmount(whichUnit, delta)
7694endfunction
7695
7696//===========================================================================
7697function GetConvertedPlayerId takes player whichPlayer returns integer
7698 return GetPlayerId(whichPlayer) + 1
7699endfunction
7700
7701//===========================================================================
7702function ConvertedPlayer takes integer convertedPlayerId returns player
7703 return Player(convertedPlayerId - 1)
7704endfunction
7705
7706//===========================================================================
7707function GetRectWidthBJ takes rect r returns real
7708 return GetRectMaxX(r) - GetRectMinX(r)
7709endfunction
7710
7711//===========================================================================
7712function GetRectHeightBJ takes rect r returns real
7713 return GetRectMaxY(r) - GetRectMinY(r)
7714endfunction
7715
7716//===========================================================================
7717// Replaces a gold mine with a blighted gold mine for the given player.
7718//
7719function BlightGoldMineForPlayerBJ takes unit goldMine, player whichPlayer returns unit
7720 local real mineX
7721 local real mineY
7722 local integer mineGold
7723 local unit newMine
7724
7725 // Make sure we're replacing a Gold Mine and not some other type of unit.
7726 if GetUnitTypeId(goldMine) != 'ngol' then
7727 return null
7728 endif
7729
7730 // Save the Gold Mine's properties and remove it.
7731 set mineX = GetUnitX(goldMine)
7732 set mineY = GetUnitY(goldMine)
7733 set mineGold = GetResourceAmount(goldMine)
7734 call RemoveUnit(goldMine)
7735
7736 // Create a Haunted Gold Mine to replace the Gold Mine.
7737 set newMine = CreateBlightedGoldmine(whichPlayer, mineX, mineY, bj_UNIT_FACING)
7738 call SetResourceAmount(newMine, mineGold)
7739 return newMine
7740endfunction
7741
7742//===========================================================================
7743function BlightGoldMineForPlayer takes unit goldMine, player whichPlayer returns unit
7744 set bj_lastHauntedGoldMine = BlightGoldMineForPlayerBJ(goldMine, whichPlayer)
7745 return bj_lastHauntedGoldMine
7746endfunction
7747
7748//===========================================================================
7749function GetLastHauntedGoldMine takes nothing returns unit
7750 return bj_lastHauntedGoldMine
7751endfunction
7752
7753//===========================================================================
7754function IsPointBlightedBJ takes location where returns boolean
7755 return IsPointBlighted(GetLocationX(where), GetLocationY(where))
7756endfunction
7757
7758//===========================================================================
7759function SetPlayerColorBJEnum takes nothing returns nothing
7760 call SetUnitColor(GetEnumUnit(), bj_setPlayerTargetColor)
7761endfunction
7762
7763//===========================================================================
7764function SetPlayerColorBJ takes player whichPlayer, playercolor color, boolean changeExisting returns nothing
7765 local group g
7766
7767 call SetPlayerColor(whichPlayer, color)
7768 if changeExisting then
7769 set bj_setPlayerTargetColor = color
7770 set g = CreateGroup()
7771 call GroupEnumUnitsOfPlayer(g, whichPlayer, null)
7772 call ForGroup(g, function SetPlayerColorBJEnum)
7773 call DestroyGroup(g)
7774 endif
7775endfunction
7776
7777//===========================================================================
7778function SetPlayerUnitAvailableBJ takes integer unitId, boolean allowed, player whichPlayer returns nothing
7779 if allowed then
7780 call SetPlayerTechMaxAllowed(whichPlayer, unitId, -1)
7781 else
7782 call SetPlayerTechMaxAllowed(whichPlayer, unitId, 0)
7783 endif
7784endfunction
7785
7786//===========================================================================
7787function LockGameSpeedBJ takes nothing returns nothing
7788 call SetMapFlag(MAP_LOCK_SPEED, true)
7789endfunction
7790
7791//===========================================================================
7792function UnlockGameSpeedBJ takes nothing returns nothing
7793 call SetMapFlag(MAP_LOCK_SPEED, false)
7794endfunction
7795
7796//===========================================================================
7797function IssueTargetOrderBJ takes unit whichUnit, string order, widget targetWidget returns boolean
7798 return IssueTargetOrder( whichUnit, order, targetWidget )
7799endfunction
7800
7801//===========================================================================
7802function IssuePointOrderLocBJ takes unit whichUnit, string order, location whichLocation returns boolean
7803 return IssuePointOrderLoc( whichUnit, order, whichLocation )
7804endfunction
7805
7806//===========================================================================
7807// Two distinct trigger actions can't share the same function name, so this
7808// dummy function simply mimics the behavior of an existing call.
7809//
7810function IssueTargetDestructableOrder takes unit whichUnit, string order, widget targetWidget returns boolean
7811 return IssueTargetOrder( whichUnit, order, targetWidget )
7812endfunction
7813
7814function IssueTargetItemOrder takes unit whichUnit, string order, widget targetWidget returns boolean
7815 return IssueTargetOrder( whichUnit, order, targetWidget )
7816endfunction
7817
7818//===========================================================================
7819function IssueImmediateOrderBJ takes unit whichUnit, string order returns boolean
7820 return IssueImmediateOrder( whichUnit, order )
7821endfunction
7822
7823//===========================================================================
7824function GroupTargetOrderBJ takes group whichGroup, string order, widget targetWidget returns boolean
7825 return GroupTargetOrder( whichGroup, order, targetWidget )
7826endfunction
7827
7828//===========================================================================
7829function GroupPointOrderLocBJ takes group whichGroup, string order, location whichLocation returns boolean
7830 return GroupPointOrderLoc( whichGroup, order, whichLocation )
7831endfunction
7832
7833//===========================================================================
7834function GroupImmediateOrderBJ takes group whichGroup, string order returns boolean
7835 return GroupImmediateOrder( whichGroup, order )
7836endfunction
7837
7838//===========================================================================
7839// Two distinct trigger actions can't share the same function name, so this
7840// dummy function simply mimics the behavior of an existing call.
7841//
7842function GroupTargetDestructableOrder takes group whichGroup, string order, widget targetWidget returns boolean
7843 return GroupTargetOrder( whichGroup, order, targetWidget )
7844endfunction
7845
7846function GroupTargetItemOrder takes group whichGroup, string order, widget targetWidget returns boolean
7847 return GroupTargetOrder( whichGroup, order, targetWidget )
7848endfunction
7849
7850//===========================================================================
7851function GetDyingDestructable takes nothing returns destructable
7852 return GetTriggerDestructable()
7853endfunction
7854
7855//===========================================================================
7856// Rally point setting
7857//
7858function SetUnitRallyPoint takes unit whichUnit, location targPos returns nothing
7859 call IssuePointOrderLocBJ(whichUnit, "setrally", targPos)
7860endfunction
7861
7862//===========================================================================
7863function SetUnitRallyUnit takes unit whichUnit, unit targUnit returns nothing
7864 call IssueTargetOrder(whichUnit, "setrally", targUnit)
7865endfunction
7866
7867//===========================================================================
7868function SetUnitRallyDestructable takes unit whichUnit, destructable targDest returns nothing
7869 call IssueTargetOrder(whichUnit, "setrally", targDest)
7870endfunction
7871
7872//===========================================================================
7873// Utility function for use by editor-generated item drop table triggers.
7874// This function is added as an action to all destructable drop triggers,
7875// so that a widget drop may be differentiated from a unit drop.
7876//
7877function SaveDyingWidget takes nothing returns nothing
7878 set bj_lastDyingWidget = GetTriggerWidget()
7879endfunction
7880
7881//===========================================================================
7882function SetBlightRectBJ takes boolean addBlight, player whichPlayer, rect r returns nothing
7883 call SetBlightRect(whichPlayer, r, addBlight)
7884endfunction
7885
7886//===========================================================================
7887function SetBlightRadiusLocBJ takes boolean addBlight, player whichPlayer, location loc, real radius returns nothing
7888 call SetBlightLoc(whichPlayer, loc, radius, addBlight)
7889endfunction
7890
7891//===========================================================================
7892function GetAbilityName takes integer abilcode returns string
7893 return GetObjectName(abilcode)
7894endfunction
7895
7896
7897//***************************************************************************
7898//*
7899//* Melee Template Visibility Settings
7900//*
7901//***************************************************************************
7902
7903//===========================================================================
7904function MeleeStartingVisibility takes nothing returns nothing
7905 // Start by setting the ToD.
7906 call SetFloatGameState(GAME_STATE_TIME_OF_DAY, bj_MELEE_STARTING_TOD)
7907
7908 // call FogMaskEnable(true)
7909 // call FogEnable(true)
7910endfunction
7911
7912
7913
7914//***************************************************************************
7915//*
7916//* Melee Template Starting Resources
7917//*
7918//***************************************************************************
7919
7920//===========================================================================
7921function MeleeStartingResources takes nothing returns nothing
7922 local integer index
7923 local player indexPlayer
7924 local version v
7925 local integer startingGold
7926 local integer startingLumber
7927
7928 set v = VersionGet()
7929 if (v == VERSION_REIGN_OF_CHAOS) then
7930 set startingGold = bj_MELEE_STARTING_GOLD_V0
7931 set startingLumber = bj_MELEE_STARTING_LUMBER_V0
7932 else
7933 set startingGold = bj_MELEE_STARTING_GOLD_V1
7934 set startingLumber = bj_MELEE_STARTING_LUMBER_V1
7935 endif
7936
7937 // Set each player's starting resources.
7938 set index = 0
7939 loop
7940 set indexPlayer = Player(index)
7941 if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
7942 call SetPlayerState(indexPlayer, PLAYER_STATE_RESOURCE_GOLD, startingGold)
7943 call SetPlayerState(indexPlayer, PLAYER_STATE_RESOURCE_LUMBER, startingLumber)
7944 endif
7945
7946 set index = index + 1
7947 exitwhen index == bj_MAX_PLAYERS
7948 endloop
7949endfunction
7950
7951
7952
7953//***************************************************************************
7954//*
7955//* Melee Template Hero Limit
7956//*
7957//***************************************************************************
7958
7959//===========================================================================
7960function ReducePlayerTechMaxAllowed takes player whichPlayer, integer techId, integer limit returns nothing
7961 local integer oldMax = GetPlayerTechMaxAllowed(whichPlayer, techId)
7962
7963 // A value of -1 is used to indicate no limit, so check for that as well.
7964 if (oldMax < 0 or oldMax > limit) then
7965 call SetPlayerTechMaxAllowed(whichPlayer, techId, limit)
7966 endif
7967endfunction
7968
7969//===========================================================================
7970function MeleeStartingHeroLimit takes nothing returns nothing
7971 local integer index
7972
7973 set index = 0
7974 loop
7975 // max heroes per player
7976 call SetPlayerMaxHeroesAllowed(bj_MELEE_HERO_LIMIT, Player(index))
7977
7978 // each player is restricted to a limit per hero type as well
7979 call ReducePlayerTechMaxAllowed(Player(index), 'Hamg', bj_MELEE_HERO_TYPE_LIMIT)
7980 call ReducePlayerTechMaxAllowed(Player(index), 'Hmkg', bj_MELEE_HERO_TYPE_LIMIT)
7981 call ReducePlayerTechMaxAllowed(Player(index), 'Hpal', bj_MELEE_HERO_TYPE_LIMIT)
7982 call ReducePlayerTechMaxAllowed(Player(index), 'Hblm', bj_MELEE_HERO_TYPE_LIMIT)
7983
7984 call ReducePlayerTechMaxAllowed(Player(index), 'Obla', bj_MELEE_HERO_TYPE_LIMIT)
7985 call ReducePlayerTechMaxAllowed(Player(index), 'Ofar', bj_MELEE_HERO_TYPE_LIMIT)
7986 call ReducePlayerTechMaxAllowed(Player(index), 'Otch', bj_MELEE_HERO_TYPE_LIMIT)
7987 call ReducePlayerTechMaxAllowed(Player(index), 'Oshd', bj_MELEE_HERO_TYPE_LIMIT)
7988
7989 call ReducePlayerTechMaxAllowed(Player(index), 'Edem', bj_MELEE_HERO_TYPE_LIMIT)
7990 call ReducePlayerTechMaxAllowed(Player(index), 'Ekee', bj_MELEE_HERO_TYPE_LIMIT)
7991 call ReducePlayerTechMaxAllowed(Player(index), 'Emoo', bj_MELEE_HERO_TYPE_LIMIT)
7992 call ReducePlayerTechMaxAllowed(Player(index), 'Ewar', bj_MELEE_HERO_TYPE_LIMIT)
7993
7994 call ReducePlayerTechMaxAllowed(Player(index), 'Udea', bj_MELEE_HERO_TYPE_LIMIT)
7995 call ReducePlayerTechMaxAllowed(Player(index), 'Udre', bj_MELEE_HERO_TYPE_LIMIT)
7996 call ReducePlayerTechMaxAllowed(Player(index), 'Ulic', bj_MELEE_HERO_TYPE_LIMIT)
7997 call ReducePlayerTechMaxAllowed(Player(index), 'Ucrl', bj_MELEE_HERO_TYPE_LIMIT)
7998
7999 call ReducePlayerTechMaxAllowed(Player(index), 'Npbm', bj_MELEE_HERO_TYPE_LIMIT)
8000 call ReducePlayerTechMaxAllowed(Player(index), 'Nbrn', bj_MELEE_HERO_TYPE_LIMIT)
8001 call ReducePlayerTechMaxAllowed(Player(index), 'Nngs', bj_MELEE_HERO_TYPE_LIMIT)
8002 call ReducePlayerTechMaxAllowed(Player(index), 'Nplh', bj_MELEE_HERO_TYPE_LIMIT)
8003 call ReducePlayerTechMaxAllowed(Player(index), 'Nbst', bj_MELEE_HERO_TYPE_LIMIT)
8004 call ReducePlayerTechMaxAllowed(Player(index), 'Nalc', bj_MELEE_HERO_TYPE_LIMIT)
8005 call ReducePlayerTechMaxAllowed(Player(index), 'Ntin', bj_MELEE_HERO_TYPE_LIMIT)
8006 call ReducePlayerTechMaxAllowed(Player(index), 'Nfir', bj_MELEE_HERO_TYPE_LIMIT)
8007
8008 set index = index + 1
8009 exitwhen index == bj_MAX_PLAYERS
8010 endloop
8011endfunction
8012
8013
8014
8015//***************************************************************************
8016//*
8017//* Melee Template Granted Hero Items
8018//*
8019//***************************************************************************
8020
8021//===========================================================================
8022function MeleeTrainedUnitIsHeroBJFilter takes nothing returns boolean
8023 return IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO)
8024endfunction
8025
8026//===========================================================================
8027// The first N heroes trained or hired for each player start off with a
8028// standard set of items. This is currently:
8029// - 1x Scroll of Town Portal
8030//
8031function MeleeGrantItemsToHero takes unit whichUnit returns nothing
8032 local integer owner = GetPlayerId(GetOwningPlayer(whichUnit))
8033
8034 // If we haven't twinked N heroes for this player yet, twink away.
8035 if (bj_meleeTwinkedHeroes[owner] < bj_MELEE_MAX_TWINKED_HEROES) then
8036 call UnitAddItemById(whichUnit, 'stwp')
8037 set bj_meleeTwinkedHeroes[owner] = bj_meleeTwinkedHeroes[owner] + 1
8038 endif
8039endfunction
8040
8041//===========================================================================
8042function MeleeGrantItemsToTrainedHero takes nothing returns nothing
8043 call MeleeGrantItemsToHero(GetTrainedUnit())
8044endfunction
8045
8046//===========================================================================
8047function MeleeGrantItemsToHiredHero takes nothing returns nothing
8048 call MeleeGrantItemsToHero(GetSoldUnit())
8049endfunction
8050
8051//===========================================================================
8052function MeleeGrantHeroItems takes nothing returns nothing
8053 local integer index
8054 local trigger trig
8055
8056 // Initialize the twinked hero counts.
8057 set index = 0
8058 loop
8059 set bj_meleeTwinkedHeroes[index] = 0
8060
8061 set index = index + 1
8062 exitwhen index == bj_MAX_PLAYER_SLOTS
8063 endloop
8064
8065 // Register for an event whenever a hero is trained, so that we can give
8066 // him/her their starting items.
8067 set index = 0
8068 loop
8069 set trig = CreateTrigger()
8070 call TriggerRegisterPlayerUnitEvent(trig, Player(index), EVENT_PLAYER_UNIT_TRAIN_FINISH, filterMeleeTrainedUnitIsHeroBJ)
8071 call TriggerAddAction(trig, function MeleeGrantItemsToTrainedHero)
8072
8073 set index = index + 1
8074 exitwhen index == bj_MAX_PLAYERS
8075 endloop
8076
8077 // Register for an event whenever a neutral hero is hired, so that we
8078 // can give him/her their starting items.
8079 set trig = CreateTrigger()
8080 call TriggerRegisterPlayerUnitEvent(trig, Player(PLAYER_NEUTRAL_PASSIVE), EVENT_PLAYER_UNIT_SELL, filterMeleeTrainedUnitIsHeroBJ)
8081 call TriggerAddAction(trig, function MeleeGrantItemsToHiredHero)
8082
8083 // Flag that we are giving starting items to heroes, so that the melee
8084 // starting units code can create them as necessary.
8085 set bj_meleeGrantHeroItems = true
8086endfunction
8087
8088
8089
8090//***************************************************************************
8091//*
8092//* Melee Template Clear Start Locations
8093//*
8094//***************************************************************************
8095
8096//===========================================================================
8097function MeleeClearExcessUnit takes nothing returns nothing
8098 local unit theUnit = GetEnumUnit()
8099 local integer owner = GetPlayerId(GetOwningPlayer(theUnit))
8100
8101 if (owner == PLAYER_NEUTRAL_AGGRESSIVE) then
8102 // Remove any Neutral Hostile units from the area.
8103 call RemoveUnit(GetEnumUnit())
8104 elseif (owner == PLAYER_NEUTRAL_PASSIVE) then
8105 // Remove non-structure Neutral Passive units from the area.
8106 if not IsUnitType(theUnit, UNIT_TYPE_STRUCTURE) then
8107 call RemoveUnit(GetEnumUnit())
8108 endif
8109 endif
8110endfunction
8111
8112//===========================================================================
8113function MeleeClearNearbyUnits takes real x, real y, real range returns nothing
8114 local group nearbyUnits
8115
8116 set nearbyUnits = CreateGroup()
8117 call GroupEnumUnitsInRange(nearbyUnits, x, y, range, null)
8118 call ForGroup(nearbyUnits, function MeleeClearExcessUnit)
8119 call DestroyGroup(nearbyUnits)
8120endfunction
8121
8122//===========================================================================
8123function MeleeClearExcessUnits takes nothing returns nothing
8124 local integer index
8125 local real locX
8126 local real locY
8127 local player indexPlayer
8128
8129 set index = 0
8130 loop
8131 set indexPlayer = Player(index)
8132
8133 // If the player slot is being used, clear any nearby creeps.
8134 if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
8135 set locX = GetStartLocationX(GetPlayerStartLocation(indexPlayer))
8136 set locY = GetStartLocationY(GetPlayerStartLocation(indexPlayer))
8137
8138 call MeleeClearNearbyUnits(locX, locY, bj_MELEE_CLEAR_UNITS_RADIUS)
8139 endif
8140
8141 set index = index + 1
8142 exitwhen index == bj_MAX_PLAYERS
8143 endloop
8144endfunction
8145
8146
8147
8148//***************************************************************************
8149//*
8150//* Melee Template Starting Units
8151//*
8152//***************************************************************************
8153
8154//===========================================================================
8155function MeleeEnumFindNearestMine takes nothing returns nothing
8156 local unit enumUnit = GetEnumUnit()
8157 local real dist
8158 local location unitLoc
8159
8160 if (GetUnitTypeId(enumUnit) == 'ngol') then
8161 set unitLoc = GetUnitLoc(enumUnit)
8162 set dist = DistanceBetweenPoints(unitLoc, bj_meleeNearestMineToLoc)
8163 call RemoveLocation(unitLoc)
8164
8165 // If this is our first mine, or the closest thusfar, use it instead.
8166 if (bj_meleeNearestMineDist < 0) or (dist < bj_meleeNearestMineDist) then
8167 set bj_meleeNearestMine = enumUnit
8168 set bj_meleeNearestMineDist = dist
8169 endif
8170 endif
8171endfunction
8172
8173//===========================================================================
8174function MeleeFindNearestMine takes location src, real range returns unit
8175 local group nearbyMines
8176
8177 set bj_meleeNearestMine = null
8178 set bj_meleeNearestMineDist = -1
8179 set bj_meleeNearestMineToLoc = src
8180
8181 set nearbyMines = CreateGroup()
8182 call GroupEnumUnitsInRangeOfLoc(nearbyMines, src, range, null)
8183 call ForGroup(nearbyMines, function MeleeEnumFindNearestMine)
8184 call DestroyGroup(nearbyMines)
8185
8186 return bj_meleeNearestMine
8187endfunction
8188
8189//===========================================================================
8190function MeleeRandomHeroLoc takes player p, integer id1, integer id2, integer id3, integer id4, location loc returns unit
8191 local unit hero = null
8192 local integer roll
8193 local integer pick
8194 local version v
8195
8196 // The selection of heroes is dependant on the game version.
8197 set v = VersionGet()
8198 if (v == VERSION_REIGN_OF_CHAOS) then
8199 set roll = GetRandomInt(1,3)
8200 else
8201 set roll = GetRandomInt(1,4)
8202 endif
8203
8204 // Translate the roll into a unitid.
8205 if roll == 1 then
8206 set pick = id1
8207 elseif roll == 2 then
8208 set pick = id2
8209 elseif roll == 3 then
8210 set pick = id3
8211 elseif roll == 4 then
8212 set pick = id4
8213 else
8214 // Unrecognized id index - pick the first hero in the list.
8215 set pick = id1
8216 endif
8217
8218 // Create the hero.
8219 set hero = CreateUnitAtLoc(p, pick, loc, bj_UNIT_FACING)
8220 if bj_meleeGrantHeroItems then
8221 call MeleeGrantItemsToHero(hero)
8222 endif
8223 return hero
8224endfunction
8225
8226//===========================================================================
8227// Returns a location which is (distance) away from (src) in the direction of (targ).
8228//
8229function MeleeGetProjectedLoc takes location src, location targ, real distance, real deltaAngle returns location
8230 local real srcX = GetLocationX(src)
8231 local real srcY = GetLocationY(src)
8232 local real direction = Atan2(GetLocationY(targ) - srcY, GetLocationX(targ) - srcX) + deltaAngle
8233 return Location(srcX + distance * Cos(direction), srcY + distance * Sin(direction))
8234endfunction
8235
8236//===========================================================================
8237function MeleeGetNearestValueWithin takes real val, real minVal, real maxVal returns real
8238 if (val < minVal) then
8239 return minVal
8240 elseif (val > maxVal) then
8241 return maxVal
8242 else
8243 return val
8244 endif
8245endfunction
8246
8247//===========================================================================
8248function MeleeGetLocWithinRect takes location src, rect r returns location
8249 local real withinX = MeleeGetNearestValueWithin(GetLocationX(src), GetRectMinX(r), GetRectMaxX(r))
8250 local real withinY = MeleeGetNearestValueWithin(GetLocationY(src), GetRectMinY(r), GetRectMaxY(r))
8251 return Location(withinX, withinY)
8252endfunction
8253
8254//===========================================================================
8255// Starting Units for Human Players
8256// - 1 Town Hall, placed at start location
8257// - 5 Peasants, placed between start location and nearest gold mine
8258//
8259function MeleeStartingUnitsHuman takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
8260 local boolean useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
8261 local real unitSpacing = 64.00
8262 local unit nearestMine
8263 local location nearMineLoc
8264 local location heroLoc
8265 local real peonX
8266 local real peonY
8267 local unit townHall = null
8268
8269 if (doPreload) then
8270 call Preloader( "scripts\\HumanMelee.pld" )
8271 endif
8272
8273 set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
8274 if (nearestMine != null) then
8275 // Spawn Town Hall at the start location.
8276 set townHall = CreateUnitAtLoc(whichPlayer, 'htow', startLoc, bj_UNIT_FACING)
8277
8278 // Spawn Peasants near the mine.
8279 set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
8280 set peonX = GetLocationX(nearMineLoc)
8281 set peonY = GetLocationY(nearMineLoc)
8282 call CreateUnit(whichPlayer, 'hpea', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
8283 call CreateUnit(whichPlayer, 'hpea', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
8284 call CreateUnit(whichPlayer, 'hpea', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
8285 call CreateUnit(whichPlayer, 'hpea', peonX + 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
8286 call CreateUnit(whichPlayer, 'hpea', peonX - 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
8287
8288 // Set random hero spawn point to be off to the side of the start location.
8289 set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
8290 else
8291 // Spawn Town Hall at the start location.
8292 set townHall = CreateUnitAtLoc(whichPlayer, 'htow', startLoc, bj_UNIT_FACING)
8293
8294 // Spawn Peasants directly south of the town hall.
8295 set peonX = GetLocationX(startLoc)
8296 set peonY = GetLocationY(startLoc) - 224.00
8297 call CreateUnit(whichPlayer, 'hpea', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8298 call CreateUnit(whichPlayer, 'hpea', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8299 call CreateUnit(whichPlayer, 'hpea', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8300 call CreateUnit(whichPlayer, 'hpea', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8301 call CreateUnit(whichPlayer, 'hpea', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8302
8303 // Set random hero spawn point to be just south of the start location.
8304 set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
8305 endif
8306
8307 if (townHall != null) then
8308 call UnitAddAbilityBJ('Amic', townHall)
8309 call UnitMakeAbilityPermanentBJ(true, 'Amic', townHall)
8310 endif
8311
8312 if (doHeroes) then
8313 // If the "Random Hero" option is set, start the player with a random hero.
8314 // Otherwise, give them a "free hero" token.
8315 if useRandomHero then
8316 call MeleeRandomHeroLoc(whichPlayer, 'Hamg', 'Hmkg', 'Hpal', 'Hblm', heroLoc)
8317 else
8318 call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
8319 endif
8320 endif
8321
8322 if (doCamera) then
8323 // Center the camera on the initial Peasants.
8324 call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
8325 call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
8326 endif
8327endfunction
8328
8329//===========================================================================
8330// Starting Units for Orc Players
8331// - 1 Great Hall, placed at start location
8332// - 5 Peons, placed between start location and nearest gold mine
8333//
8334function MeleeStartingUnitsOrc takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
8335 local boolean useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
8336 local real unitSpacing = 64.00
8337 local unit nearestMine
8338 local location nearMineLoc
8339 local location heroLoc
8340 local real peonX
8341 local real peonY
8342
8343 if (doPreload) then
8344 call Preloader( "scripts\\OrcMelee.pld" )
8345 endif
8346
8347 set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
8348 if (nearestMine != null) then
8349 // Spawn Great Hall at the start location.
8350 call CreateUnitAtLoc(whichPlayer, 'ogre', startLoc, bj_UNIT_FACING)
8351
8352 // Spawn Peons near the mine.
8353 set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
8354 set peonX = GetLocationX(nearMineLoc)
8355 set peonY = GetLocationY(nearMineLoc)
8356 call CreateUnit(whichPlayer, 'opeo', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
8357 call CreateUnit(whichPlayer, 'opeo', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
8358 call CreateUnit(whichPlayer, 'opeo', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
8359 call CreateUnit(whichPlayer, 'opeo', peonX + 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
8360 call CreateUnit(whichPlayer, 'opeo', peonX - 0.60 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
8361
8362 // Set random hero spawn point to be off to the side of the start location.
8363 set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
8364 else
8365 // Spawn Great Hall at the start location.
8366 call CreateUnitAtLoc(whichPlayer, 'ogre', startLoc, bj_UNIT_FACING)
8367
8368 // Spawn Peons directly south of the town hall.
8369 set peonX = GetLocationX(startLoc)
8370 set peonY = GetLocationY(startLoc) - 224.00
8371 call CreateUnit(whichPlayer, 'opeo', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8372 call CreateUnit(whichPlayer, 'opeo', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8373 call CreateUnit(whichPlayer, 'opeo', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8374 call CreateUnit(whichPlayer, 'opeo', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8375 call CreateUnit(whichPlayer, 'opeo', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8376
8377 // Set random hero spawn point to be just south of the start location.
8378 set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
8379 endif
8380
8381 if (doHeroes) then
8382 // If the "Random Hero" option is set, start the player with a random hero.
8383 // Otherwise, give them a "free hero" token.
8384 if useRandomHero then
8385 call MeleeRandomHeroLoc(whichPlayer, 'Obla', 'Ofar', 'Otch', 'Oshd', heroLoc)
8386 else
8387 call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
8388 endif
8389 endif
8390
8391 if (doCamera) then
8392 // Center the camera on the initial Peons.
8393 call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
8394 call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
8395 endif
8396endfunction
8397
8398//===========================================================================
8399// Starting Units for Undead Players
8400// - 1 Necropolis, placed at start location
8401// - 1 Haunted Gold Mine, placed on nearest gold mine
8402// - 3 Acolytes, placed between start location and nearest gold mine
8403// - 1 Ghoul, placed between start location and nearest gold mine
8404// - Blight, centered on nearest gold mine, spread across a "large area"
8405//
8406function MeleeStartingUnitsUndead takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
8407 local boolean useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
8408 local real unitSpacing = 64.00
8409 local unit nearestMine
8410 local location nearMineLoc
8411 local location nearTownLoc
8412 local location heroLoc
8413 local real peonX
8414 local real peonY
8415 local real ghoulX
8416 local real ghoulY
8417
8418 if (doPreload) then
8419 call Preloader( "scripts\\UndeadMelee.pld" )
8420 endif
8421
8422 set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
8423 if (nearestMine != null) then
8424 // Spawn Necropolis at the start location.
8425 call CreateUnitAtLoc(whichPlayer, 'unpl', startLoc, bj_UNIT_FACING)
8426
8427 // Replace the nearest gold mine with a blighted version.
8428 set nearestMine = BlightGoldMineForPlayerBJ(nearestMine, whichPlayer)
8429
8430 // Spawn Ghoul near the Necropolis.
8431 set nearTownLoc = MeleeGetProjectedLoc(startLoc, GetUnitLoc(nearestMine), 288, 0)
8432 set ghoulX = GetLocationX(nearTownLoc)
8433 set ghoulY = GetLocationY(nearTownLoc)
8434 set bj_ghoul[GetPlayerId(whichPlayer)] = CreateUnit(whichPlayer, 'ugho', ghoulX + 0.00 * unitSpacing, ghoulY + 0.00 * unitSpacing, bj_UNIT_FACING)
8435
8436 // Spawn Acolytes near the mine.
8437 set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
8438 set peonX = GetLocationX(nearMineLoc)
8439 set peonY = GetLocationY(nearMineLoc)
8440 call CreateUnit(whichPlayer, 'uaco', peonX + 0.00 * unitSpacing, peonY + 0.50 * unitSpacing, bj_UNIT_FACING)
8441 call CreateUnit(whichPlayer, 'uaco', peonX + 0.65 * unitSpacing, peonY - 0.50 * unitSpacing, bj_UNIT_FACING)
8442 call CreateUnit(whichPlayer, 'uaco', peonX - 0.65 * unitSpacing, peonY - 0.50 * unitSpacing, bj_UNIT_FACING)
8443
8444 // Create a patch of blight around the gold mine.
8445 call SetBlightLoc(whichPlayer,nearMineLoc, 768, true)
8446
8447 // Set random hero spawn point to be off to the side of the start location.
8448 set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
8449 else
8450 // Spawn Necropolis at the start location.
8451 call CreateUnitAtLoc(whichPlayer, 'unpl', startLoc, bj_UNIT_FACING)
8452
8453 // Spawn Acolytes and Ghoul directly south of the Necropolis.
8454 set peonX = GetLocationX(startLoc)
8455 set peonY = GetLocationY(startLoc) - 224.00
8456 call CreateUnit(whichPlayer, 'uaco', peonX - 1.50 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8457 call CreateUnit(whichPlayer, 'uaco', peonX - 0.50 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8458 call CreateUnit(whichPlayer, 'uaco', peonX + 0.50 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8459 call CreateUnit(whichPlayer, 'ugho', peonX + 1.50 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8460
8461 // Create a patch of blight around the start location.
8462 call SetBlightLoc(whichPlayer,startLoc, 768, true)
8463
8464 // Set random hero spawn point to be just south of the start location.
8465 set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
8466 endif
8467
8468 if (doHeroes) then
8469 // If the "Random Hero" option is set, start the player with a random hero.
8470 // Otherwise, give them a "free hero" token.
8471 if useRandomHero then
8472 call MeleeRandomHeroLoc(whichPlayer, 'Udea', 'Udre', 'Ulic', 'Ucrl', heroLoc)
8473 else
8474 call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
8475 endif
8476 endif
8477
8478 if (doCamera) then
8479 // Center the camera on the initial Acolytes.
8480 call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
8481 call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
8482 endif
8483endfunction
8484
8485//===========================================================================
8486// Starting Units for Night Elf Players
8487// - 1 Tree of Life, placed by nearest gold mine, already entangled
8488// - 5 Wisps, placed between Tree of Life and nearest gold mine
8489//
8490function MeleeStartingUnitsNightElf takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
8491 local boolean useRandomHero = IsMapFlagSet(MAP_RANDOM_HERO)
8492 local real unitSpacing = 64.00
8493 local real minTreeDist = 3.50 * bj_CELLWIDTH
8494 local real minWispDist = 1.75 * bj_CELLWIDTH
8495 local unit nearestMine
8496 local location nearMineLoc
8497 local location wispLoc
8498 local location heroLoc
8499 local real peonX
8500 local real peonY
8501 local unit tree
8502
8503 if (doPreload) then
8504 call Preloader( "scripts\\NightElfMelee.pld" )
8505 endif
8506
8507 set nearestMine = MeleeFindNearestMine(startLoc, bj_MELEE_MINE_SEARCH_RADIUS)
8508 if (nearestMine != null) then
8509 // Spawn Tree of Life near the mine and have it entangle the mine.
8510 // Project the Tree's coordinates from the gold mine, and then snap
8511 // the X and Y values to within minTreeDist of the Gold Mine.
8512 set nearMineLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 650, 0)
8513 set nearMineLoc = MeleeGetLocWithinRect(nearMineLoc, GetRectFromCircleBJ(GetUnitLoc(nearestMine), minTreeDist))
8514 set tree = CreateUnitAtLoc(whichPlayer, 'etol', nearMineLoc, bj_UNIT_FACING)
8515 call IssueTargetOrder(tree, "entangleinstant", nearestMine)
8516
8517 // Spawn Wisps at the start location.
8518 set wispLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 320, 0)
8519 set wispLoc = MeleeGetLocWithinRect(wispLoc, GetRectFromCircleBJ(GetUnitLoc(nearestMine), minWispDist))
8520 set peonX = GetLocationX(wispLoc)
8521 set peonY = GetLocationY(wispLoc)
8522 call CreateUnit(whichPlayer, 'ewsp', peonX + 0.00 * unitSpacing, peonY + 1.00 * unitSpacing, bj_UNIT_FACING)
8523 call CreateUnit(whichPlayer, 'ewsp', peonX + 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
8524 call CreateUnit(whichPlayer, 'ewsp', peonX - 1.00 * unitSpacing, peonY + 0.15 * unitSpacing, bj_UNIT_FACING)
8525 call CreateUnit(whichPlayer, 'ewsp', peonX + 0.58 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
8526 call CreateUnit(whichPlayer, 'ewsp', peonX - 0.58 * unitSpacing, peonY - 1.00 * unitSpacing, bj_UNIT_FACING)
8527
8528 // Set random hero spawn point to be off to the side of the start location.
8529 set heroLoc = MeleeGetProjectedLoc(GetUnitLoc(nearestMine), startLoc, 384, 45)
8530 else
8531 // Spawn Tree of Life at the start location.
8532 call CreateUnitAtLoc(whichPlayer, 'etol', startLoc, bj_UNIT_FACING)
8533
8534 // Spawn Wisps directly south of the town hall.
8535 set peonX = GetLocationX(startLoc)
8536 set peonY = GetLocationY(startLoc) - 224.00
8537 call CreateUnit(whichPlayer, 'ewsp', peonX - 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8538 call CreateUnit(whichPlayer, 'ewsp', peonX - 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8539 call CreateUnit(whichPlayer, 'ewsp', peonX + 0.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8540 call CreateUnit(whichPlayer, 'ewsp', peonX + 1.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8541 call CreateUnit(whichPlayer, 'ewsp', peonX + 2.00 * unitSpacing, peonY + 0.00 * unitSpacing, bj_UNIT_FACING)
8542
8543 // Set random hero spawn point to be just south of the start location.
8544 set heroLoc = Location(peonX, peonY - 2.00 * unitSpacing)
8545 endif
8546
8547 if (doHeroes) then
8548 // If the "Random Hero" option is set, start the player with a random hero.
8549 // Otherwise, give them a "free hero" token.
8550 if useRandomHero then
8551 call MeleeRandomHeroLoc(whichPlayer, 'Edem', 'Ekee', 'Emoo', 'Ewar', heroLoc)
8552 else
8553 call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
8554 endif
8555 endif
8556
8557 if (doCamera) then
8558 // Center the camera on the initial Wisps.
8559 call SetCameraPositionForPlayer(whichPlayer, peonX, peonY)
8560 call SetCameraQuickPositionForPlayer(whichPlayer, peonX, peonY)
8561 endif
8562endfunction
8563
8564//===========================================================================
8565// Starting Units for Players Whose Race is Unknown
8566// - 12 Sheep, placed randomly around the start location
8567//
8568function MeleeStartingUnitsUnknownRace takes player whichPlayer, location startLoc, boolean doHeroes, boolean doCamera, boolean doPreload returns nothing
8569 local integer index
8570
8571 if (doPreload) then
8572 endif
8573
8574 set index = 0
8575 loop
8576 call CreateUnit(whichPlayer, 'nshe', GetLocationX(startLoc) + GetRandomReal(-256, 256), GetLocationY(startLoc) + GetRandomReal(-256, 256), GetRandomReal(0, 360))
8577 set index = index + 1
8578 exitwhen index == 12
8579 endloop
8580
8581 if (doHeroes) then
8582 // Give them a "free hero" token, out of pity.
8583 call SetPlayerState(whichPlayer, PLAYER_STATE_RESOURCE_HERO_TOKENS, bj_MELEE_STARTING_HERO_TOKENS)
8584 endif
8585
8586 if (doCamera) then
8587 // Center the camera on the initial sheep.
8588 call SetCameraPositionLocForPlayer(whichPlayer, startLoc)
8589 call SetCameraQuickPositionLocForPlayer(whichPlayer, startLoc)
8590 endif
8591endfunction
8592
8593//===========================================================================
8594function MeleeStartingUnits takes nothing returns nothing
8595 local integer index
8596 local player indexPlayer
8597 local location indexStartLoc
8598 local race indexRace
8599
8600 call Preloader( "scripts\\SharedMelee.pld" )
8601
8602 set index = 0
8603 loop
8604 set indexPlayer = Player(index)
8605 if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
8606 set indexStartLoc = GetStartLocationLoc(GetPlayerStartLocation(indexPlayer))
8607 set indexRace = GetPlayerRace(indexPlayer)
8608
8609 // Create initial race-specific starting units
8610 if (indexRace == RACE_HUMAN) then
8611 call MeleeStartingUnitsHuman(indexPlayer, indexStartLoc, true, true, true)
8612 elseif (indexRace == RACE_ORC) then
8613 call MeleeStartingUnitsOrc(indexPlayer, indexStartLoc, true, true, true)
8614 elseif (indexRace == RACE_UNDEAD) then
8615 call MeleeStartingUnitsUndead(indexPlayer, indexStartLoc, true, true, true)
8616 elseif (indexRace == RACE_NIGHTELF) then
8617 call MeleeStartingUnitsNightElf(indexPlayer, indexStartLoc, true, true, true)
8618 else
8619 call MeleeStartingUnitsUnknownRace(indexPlayer, indexStartLoc, true, true, true)
8620 endif
8621 endif
8622
8623 set index = index + 1
8624 exitwhen index == bj_MAX_PLAYERS
8625 endloop
8626
8627endfunction
8628
8629//===========================================================================
8630function MeleeStartingUnitsForPlayer takes race whichRace, player whichPlayer, location loc, boolean doHeroes returns nothing
8631 // Create initial race-specific starting units
8632 if (whichRace == RACE_HUMAN) then
8633 call MeleeStartingUnitsHuman(whichPlayer, loc, doHeroes, false, false)
8634 elseif (whichRace == RACE_ORC) then
8635 call MeleeStartingUnitsOrc(whichPlayer, loc, doHeroes, false, false)
8636 elseif (whichRace == RACE_UNDEAD) then
8637 call MeleeStartingUnitsUndead(whichPlayer, loc, doHeroes, false, false)
8638 elseif (whichRace == RACE_NIGHTELF) then
8639 call MeleeStartingUnitsNightElf(whichPlayer, loc, doHeroes, false, false)
8640 else
8641 // Unrecognized race - ignore the request.
8642 endif
8643endfunction
8644
8645
8646
8647//***************************************************************************
8648//*
8649//* Melee Template Starting AI Scripts
8650//*
8651//***************************************************************************
8652
8653//===========================================================================
8654function PickMeleeAI takes player num, string s1, string s2, string s3 returns nothing
8655 local integer pick
8656
8657 // easy difficulty never uses any custom AI scripts
8658 // that are designed to be a bit more challenging
8659 //
8660 if GetAIDifficulty(num) == AI_DIFFICULTY_NEWBIE then
8661 call StartMeleeAI(num,s1)
8662 return
8663 endif
8664
8665 if s2 == null then
8666 set pick = 1
8667 elseif s3 == null then
8668 set pick = GetRandomInt(1,2)
8669 else
8670 set pick = GetRandomInt(1,3)
8671 endif
8672
8673 if pick == 1 then
8674 call StartMeleeAI(num,s1)
8675 elseif pick == 2 then
8676 call StartMeleeAI(num,s2)
8677 else
8678 call StartMeleeAI(num,s3)
8679 endif
8680endfunction
8681
8682//===========================================================================
8683function MeleeStartingAI takes nothing returns nothing
8684 local integer index
8685 local player indexPlayer
8686 local race indexRace
8687
8688 set index = 0
8689 loop
8690 set indexPlayer = Player(index)
8691 if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
8692 set indexRace = GetPlayerRace(indexPlayer)
8693 if (GetPlayerController(indexPlayer) == MAP_CONTROL_COMPUTER) then
8694 // Run a race-specific melee AI script.
8695 if (indexRace == RACE_HUMAN) then
8696 call PickMeleeAI(indexPlayer, "human.ai", null, null)
8697 elseif (indexRace == RACE_ORC) then
8698 call PickMeleeAI(indexPlayer, "orc.ai", null, null)
8699 elseif (indexRace == RACE_UNDEAD) then
8700 call PickMeleeAI(indexPlayer, "undead.ai", null, null)
8701 call RecycleGuardPosition(bj_ghoul[index])
8702 elseif (indexRace == RACE_NIGHTELF) then
8703 call PickMeleeAI(indexPlayer, "elf.ai", null, null)
8704 else
8705 // Unrecognized race.
8706 endif
8707 call ShareEverythingWithTeamAI(indexPlayer)
8708 endif
8709 endif
8710
8711 set index = index + 1
8712 exitwhen index == bj_MAX_PLAYERS
8713 endloop
8714endfunction
8715
8716function LockGuardPosition takes unit targ returns nothing
8717 call SetUnitCreepGuard(targ,true)
8718endfunction
8719
8720
8721//***************************************************************************
8722//*
8723//* Melee Template Victory / Defeat Conditions
8724//*
8725//***************************************************************************
8726
8727//===========================================================================
8728function MeleePlayerIsOpponent takes integer playerIndex, integer opponentIndex returns boolean
8729 local player thePlayer = Player(playerIndex)
8730 local player theOpponent = Player(opponentIndex)
8731
8732 // The player himself is not an opponent.
8733 if (playerIndex == opponentIndex) then
8734 return false
8735 endif
8736
8737 // Unused player slots are not opponents.
8738 if (GetPlayerSlotState(theOpponent) != PLAYER_SLOT_STATE_PLAYING) then
8739 return false
8740 endif
8741
8742 // Players who are already defeated are not opponents.
8743 if (bj_meleeDefeated[opponentIndex]) then
8744 return false
8745 endif
8746
8747 // Allied players with allied victory set are not opponents.
8748 if GetPlayerAlliance(thePlayer, theOpponent, ALLIANCE_PASSIVE) then
8749 if GetPlayerAlliance(theOpponent, thePlayer, ALLIANCE_PASSIVE) then
8750 if (GetPlayerState(thePlayer, PLAYER_STATE_ALLIED_VICTORY) == 1) then
8751 if (GetPlayerState(theOpponent, PLAYER_STATE_ALLIED_VICTORY) == 1) then
8752 return false
8753 endif
8754 endif
8755 endif
8756 endif
8757
8758 return true
8759endfunction
8760
8761//===========================================================================
8762// Count buildings currently owned by all allies, including the player themself.
8763//
8764function MeleeGetAllyStructureCount takes player whichPlayer returns integer
8765 local integer playerIndex
8766 local integer buildingCount
8767 local player indexPlayer
8768
8769 // Count the number of buildings controlled by all not-yet-defeated co-allies.
8770 set buildingCount = 0
8771 set playerIndex = 0
8772 loop
8773 set indexPlayer = Player(playerIndex)
8774
8775 // uncomment to cause defeat even if you have control of ally structures, but yours have been nixed
8776 //if (PlayersAreCoAllied(whichPlayer, indexPlayer) and not bj_meleeDefeated[playerIndex]) then
8777 if (PlayersAreCoAllied(whichPlayer, indexPlayer)) then
8778 set buildingCount = buildingCount + GetPlayerStructureCount(indexPlayer, true)
8779 endif
8780
8781 set playerIndex = playerIndex + 1
8782 exitwhen playerIndex == bj_MAX_PLAYERS
8783 endloop
8784
8785 return buildingCount
8786endfunction
8787
8788//===========================================================================
8789// Count allies, excluding dead players and the player themself.
8790//
8791function MeleeGetAllyCount takes player whichPlayer returns integer
8792 local integer playerIndex
8793 local integer playerCount
8794 local player indexPlayer
8795
8796 // Count the number of not-yet-defeated co-allies.
8797 set playerCount = 0
8798 set playerIndex = 0
8799 loop
8800 set indexPlayer = Player(playerIndex)
8801 if PlayersAreCoAllied(whichPlayer, indexPlayer) and not bj_meleeDefeated[playerIndex] and (whichPlayer != indexPlayer) then
8802 set playerCount = playerCount + 1
8803 endif
8804
8805 set playerIndex = playerIndex + 1
8806 exitwhen playerIndex == bj_MAX_PLAYERS
8807 endloop
8808
8809 return playerCount
8810endfunction
8811
8812//===========================================================================
8813// Counts key structures owned by a player and his or her allies, including
8814// structures currently upgrading or under construction.
8815//
8816// Key structures: Town Hall, Great Hall, Tree of Life, Necropolis
8817//
8818function MeleeGetAllyKeyStructureCount takes player whichPlayer returns integer
8819 local integer playerIndex
8820 local player indexPlayer
8821 local integer keyStructs
8822
8823 // Count the number of buildings controlled by all not-yet-defeated co-allies.
8824 set keyStructs = 0
8825 set playerIndex = 0
8826 loop
8827 set indexPlayer = Player(playerIndex)
8828 if (PlayersAreCoAllied(whichPlayer, indexPlayer)) then
8829 set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "townhall", true, true)
8830 set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "greathall", true, true)
8831 set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "treeoflife", true, true)
8832 set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "necropolis", true, true)
8833 endif
8834
8835 set playerIndex = playerIndex + 1
8836 exitwhen playerIndex == bj_MAX_PLAYERS
8837 endloop
8838
8839 return keyStructs
8840endfunction
8841
8842//===========================================================================
8843// Enum: Draw out a specific player.
8844//
8845function MeleeDoDrawEnum takes nothing returns nothing
8846 local player thePlayer = GetEnumPlayer()
8847
8848 call CachePlayerHeroData(thePlayer)
8849 call RemovePlayerPreserveUnitsBJ(thePlayer, PLAYER_GAME_RESULT_TIE, false)
8850endfunction
8851
8852//===========================================================================
8853// Enum: Victory out a specific player.
8854//
8855function MeleeDoVictoryEnum takes nothing returns nothing
8856 local player thePlayer = GetEnumPlayer()
8857 local integer playerIndex = GetPlayerId(thePlayer)
8858
8859 if (not bj_meleeVictoried[playerIndex]) then
8860 set bj_meleeVictoried[playerIndex] = true
8861 call CachePlayerHeroData(thePlayer)
8862 call RemovePlayerPreserveUnitsBJ(thePlayer, PLAYER_GAME_RESULT_VICTORY, false)
8863 endif
8864endfunction
8865
8866//===========================================================================
8867// Defeat out a specific player.
8868//
8869function MeleeDoDefeat takes player whichPlayer returns nothing
8870 set bj_meleeDefeated[GetPlayerId(whichPlayer)] = true
8871 call RemovePlayerPreserveUnitsBJ(whichPlayer, PLAYER_GAME_RESULT_DEFEAT, false)
8872endfunction
8873
8874//===========================================================================
8875// Enum: Defeat out a specific player.
8876//
8877function MeleeDoDefeatEnum takes nothing returns nothing
8878 local player thePlayer = GetEnumPlayer()
8879
8880 // needs to happen before ownership change
8881 call CachePlayerHeroData(thePlayer)
8882 call MakeUnitsPassiveForTeam(thePlayer)
8883 call MeleeDoDefeat(thePlayer)
8884endfunction
8885
8886//===========================================================================
8887// A specific player left the game.
8888//
8889function MeleeDoLeave takes player whichPlayer returns nothing
8890 if (GetIntegerGameState(GAME_STATE_DISCONNECTED) != 0) then
8891 call GameOverDialogBJ( whichPlayer, true )
8892 else
8893 set bj_meleeDefeated[GetPlayerId(whichPlayer)] = true
8894 call RemovePlayerPreserveUnitsBJ(whichPlayer, PLAYER_GAME_RESULT_DEFEAT, true)
8895 endif
8896endfunction
8897
8898//===========================================================================
8899// Remove all observers
8900//
8901function MeleeRemoveObservers takes nothing returns nothing
8902 local integer playerIndex
8903 local player indexPlayer
8904
8905 // Give all observers the game over dialog
8906 set playerIndex = 0
8907 loop
8908 set indexPlayer = Player(playerIndex)
8909
8910 if (IsPlayerObserver(indexPlayer)) then
8911 call RemovePlayerPreserveUnitsBJ(indexPlayer, PLAYER_GAME_RESULT_NEUTRAL, false)
8912 endif
8913
8914 set playerIndex = playerIndex + 1
8915 exitwhen playerIndex == bj_MAX_PLAYERS
8916 endloop
8917endfunction
8918
8919//===========================================================================
8920// Test all players to determine if a team has won. For a team to win, all
8921// remaining (read: undefeated) players need to be co-allied with all other
8922// remaining players. If even one player is not allied towards another,
8923// everyone must be denied victory.
8924//
8925function MeleeCheckForVictors takes nothing returns force
8926 local integer playerIndex
8927 local integer opponentIndex
8928 local force opponentlessPlayers = CreateForce()
8929 local boolean gameOver = false
8930
8931 // Check to see if any players have opponents remaining.
8932 set playerIndex = 0
8933 loop
8934 if (not bj_meleeDefeated[playerIndex]) then
8935 // Determine whether or not this player has any remaining opponents.
8936 set opponentIndex = 0
8937 loop
8938 // If anyone has an opponent, noone can be victorious yet.
8939 if MeleePlayerIsOpponent(playerIndex, opponentIndex) then
8940 return CreateForce()
8941 endif
8942
8943 set opponentIndex = opponentIndex + 1
8944 exitwhen opponentIndex == bj_MAX_PLAYERS
8945 endloop
8946
8947 // Keep track of each opponentless player so that we can give
8948 // them a victory later.
8949 call ForceAddPlayer(opponentlessPlayers, Player(playerIndex))
8950 set gameOver = true
8951 endif
8952
8953 set playerIndex = playerIndex + 1
8954 exitwhen playerIndex == bj_MAX_PLAYERS
8955 endloop
8956
8957 // Set the game over global flag
8958 set bj_meleeGameOver = gameOver
8959
8960 return opponentlessPlayers
8961endfunction
8962
8963//===========================================================================
8964// Test each player to determine if anyone has been defeated.
8965//
8966function MeleeCheckForLosersAndVictors takes nothing returns nothing
8967 local integer playerIndex
8968 local player indexPlayer
8969 local force defeatedPlayers = CreateForce()
8970 local force victoriousPlayers
8971 local boolean gameOver = false
8972
8973 // If the game is already over, do nothing
8974 if (bj_meleeGameOver) then
8975 return
8976 endif
8977
8978 // If the game was disconnected then it is over, in this case we
8979 // don't want to report results for anyone as they will most likely
8980 // conflict with the actual game results
8981 if (GetIntegerGameState(GAME_STATE_DISCONNECTED) != 0) then
8982 set bj_meleeGameOver = true
8983 return
8984 endif
8985
8986 // Check each player to see if he or she has been defeated yet.
8987 set playerIndex = 0
8988 loop
8989 set indexPlayer = Player(playerIndex)
8990
8991 if (not bj_meleeDefeated[playerIndex] and not bj_meleeVictoried[playerIndex]) then
8992 //call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "Player"+I2S(playerIndex)+" has "+I2S(MeleeGetAllyStructureCount(indexPlayer))+" ally buildings.")
8993 if (MeleeGetAllyStructureCount(indexPlayer) <= 0) then
8994
8995 // Keep track of each defeated player so that we can give
8996 // them a defeat later.
8997 call ForceAddPlayer(defeatedPlayers, Player(playerIndex))
8998
8999 // Set their defeated flag now so MeleeCheckForVictors
9000 // can detect victors.
9001 set bj_meleeDefeated[playerIndex] = true
9002 endif
9003 endif
9004
9005 set playerIndex = playerIndex + 1
9006 exitwhen playerIndex == bj_MAX_PLAYERS
9007 endloop
9008
9009 // Now that the defeated flags are set, check if there are any victors
9010 set victoriousPlayers = MeleeCheckForVictors()
9011
9012 // Defeat all defeated players
9013 call ForForce(defeatedPlayers, function MeleeDoDefeatEnum)
9014
9015 // Give victory to all victorious players
9016 call ForForce(victoriousPlayers, function MeleeDoVictoryEnum)
9017
9018 // If the game is over we should remove all observers
9019 if (bj_meleeGameOver) then
9020 call MeleeRemoveObservers()
9021 endif
9022endfunction
9023
9024//===========================================================================
9025// Returns a race-specific "build X or be revealed" message.
9026//
9027function MeleeGetCrippledWarningMessage takes player whichPlayer returns string
9028 local race r = GetPlayerRace(whichPlayer)
9029
9030 if (r == RACE_HUMAN) then
9031 return GetLocalizedString("CRIPPLE_WARNING_HUMAN")
9032 elseif (r == RACE_ORC) then
9033 return GetLocalizedString("CRIPPLE_WARNING_ORC")
9034 elseif (r == RACE_NIGHTELF) then
9035 return GetLocalizedString("CRIPPLE_WARNING_NIGHTELF")
9036 elseif (r == RACE_UNDEAD) then
9037 return GetLocalizedString("CRIPPLE_WARNING_UNDEAD")
9038 else
9039 // Unrecognized Race
9040 return ""
9041 endif
9042endfunction
9043
9044//===========================================================================
9045// Returns a race-specific "build X" label for cripple timers.
9046//
9047function MeleeGetCrippledTimerMessage takes player whichPlayer returns string
9048 local race r = GetPlayerRace(whichPlayer)
9049
9050 if (r == RACE_HUMAN) then
9051 return GetLocalizedString("CRIPPLE_TIMER_HUMAN")
9052 elseif (r == RACE_ORC) then
9053 return GetLocalizedString("CRIPPLE_TIMER_ORC")
9054 elseif (r == RACE_NIGHTELF) then
9055 return GetLocalizedString("CRIPPLE_TIMER_NIGHTELF")
9056 elseif (r == RACE_UNDEAD) then
9057 return GetLocalizedString("CRIPPLE_TIMER_UNDEAD")
9058 else
9059 // Unrecognized Race
9060 return ""
9061 endif
9062endfunction
9063
9064//===========================================================================
9065// Returns a race-specific "build X" label for cripple timers.
9066//
9067function MeleeGetCrippledRevealedMessage takes player whichPlayer returns string
9068 return GetLocalizedString("CRIPPLE_REVEALING_PREFIX") + GetPlayerName(whichPlayer) + GetLocalizedString("CRIPPLE_REVEALING_POSTFIX")
9069endfunction
9070
9071//===========================================================================
9072function MeleeExposePlayer takes player whichPlayer, boolean expose returns nothing
9073 local integer playerIndex
9074 local player indexPlayer
9075 local force toExposeTo = CreateForce()
9076
9077 call CripplePlayer( whichPlayer, toExposeTo, false )
9078
9079 set bj_playerIsExposed[GetPlayerId(whichPlayer)] = expose
9080 set playerIndex = 0
9081 loop
9082 set indexPlayer = Player(playerIndex)
9083 if (not PlayersAreCoAllied(whichPlayer, indexPlayer)) then
9084 call ForceAddPlayer( toExposeTo, indexPlayer )
9085 endif
9086
9087 set playerIndex = playerIndex + 1
9088 exitwhen playerIndex == bj_MAX_PLAYERS
9089 endloop
9090
9091 call CripplePlayer( whichPlayer, toExposeTo, expose )
9092 call DestroyForce(toExposeTo)
9093endfunction
9094
9095//===========================================================================
9096function MeleeExposeAllPlayers takes nothing returns nothing
9097 local integer playerIndex
9098 local player indexPlayer
9099 local integer playerIndex2
9100 local player indexPlayer2
9101 local force toExposeTo = CreateForce()
9102
9103 set playerIndex = 0
9104 loop
9105 set indexPlayer = Player(playerIndex)
9106
9107 call ForceClear( toExposeTo )
9108 call CripplePlayer( indexPlayer, toExposeTo, false )
9109
9110 set playerIndex2 = 0
9111 loop
9112 set indexPlayer2 = Player(playerIndex2)
9113
9114 if playerIndex != playerIndex2 then
9115 if (not PlayersAreCoAllied(indexPlayer, indexPlayer2)) then
9116 call ForceAddPlayer( toExposeTo, indexPlayer2 )
9117 endif
9118 endif
9119
9120 set playerIndex2 = playerIndex2 + 1
9121 exitwhen playerIndex2 == bj_MAX_PLAYERS
9122 endloop
9123
9124 call CripplePlayer( indexPlayer, toExposeTo, true )
9125
9126 set playerIndex = playerIndex + 1
9127 exitwhen playerIndex == bj_MAX_PLAYERS
9128 endloop
9129
9130 call DestroyForce( toExposeTo )
9131endfunction
9132
9133//===========================================================================
9134function MeleeCrippledPlayerTimeout takes nothing returns nothing
9135 local timer expiredTimer = GetExpiredTimer()
9136 local integer playerIndex
9137 local player exposedPlayer
9138
9139 // Determine which player's timer expired.
9140 set playerIndex = 0
9141 loop
9142 if (bj_crippledTimer[playerIndex] == expiredTimer) then
9143 exitwhen true
9144 endif
9145
9146 set playerIndex = playerIndex + 1
9147 exitwhen playerIndex == bj_MAX_PLAYERS
9148 endloop
9149 if (playerIndex == bj_MAX_PLAYERS) then
9150 return
9151 endif
9152 set exposedPlayer = Player(playerIndex)
9153
9154 if (GetLocalPlayer() == exposedPlayer) then
9155 // Use only local code (no net traffic) within this block to avoid desyncs.
9156
9157 // Hide the timer window for this player.
9158 call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], false)
9159 endif
9160
9161 // Display a text message to all players, explaining the exposure.
9162 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, MeleeGetCrippledRevealedMessage(exposedPlayer))
9163
9164 // Expose the player.
9165 call MeleeExposePlayer(exposedPlayer, true)
9166endfunction
9167
9168//===========================================================================
9169function MeleePlayerIsCrippled takes player whichPlayer returns boolean
9170 local integer allyStructures = MeleeGetAllyStructureCount(whichPlayer)
9171 local integer allyKeyStructures = MeleeGetAllyKeyStructureCount(whichPlayer)
9172
9173 // Dead teams are not considered to be crippled.
9174 return (allyStructures > 0) and (allyKeyStructures <= 0)
9175endfunction
9176
9177//===========================================================================
9178// Test each player to determine if anyone has become crippled.
9179//
9180function MeleeCheckForCrippledPlayers takes nothing returns nothing
9181 local integer playerIndex
9182 local player indexPlayer
9183 local force crippledPlayers = CreateForce()
9184 local boolean isNowCrippled
9185 local race indexRace
9186
9187 // The "finish soon" exposure of all players overrides any "crippled" exposure
9188 if bj_finishSoonAllExposed then
9189 return
9190 endif
9191
9192 // Check each player to see if he or she has been crippled or uncrippled.
9193 set playerIndex = 0
9194 loop
9195 set indexPlayer = Player(playerIndex)
9196 set isNowCrippled = MeleePlayerIsCrippled(indexPlayer)
9197
9198 if (not bj_playerIsCrippled[playerIndex] and isNowCrippled) then
9199
9200 // Player became crippled; start their cripple timer.
9201 set bj_playerIsCrippled[playerIndex] = true
9202 call TimerStart(bj_crippledTimer[playerIndex], bj_MELEE_CRIPPLE_TIMEOUT, false, function MeleeCrippledPlayerTimeout)
9203
9204 if (GetLocalPlayer() == indexPlayer) then
9205 // Use only local code (no net traffic) within this block to avoid desyncs.
9206
9207 // Show the timer window.
9208 call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], true)
9209
9210 // Display a warning message.
9211 call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, MeleeGetCrippledWarningMessage(indexPlayer))
9212 endif
9213
9214 elseif (bj_playerIsCrippled[playerIndex] and not isNowCrippled) then
9215
9216 // Player became uncrippled; stop their cripple timer.
9217 set bj_playerIsCrippled[playerIndex] = false
9218 call PauseTimer(bj_crippledTimer[playerIndex])
9219
9220 if (GetLocalPlayer() == indexPlayer) then
9221 // Use only local code (no net traffic) within this block to avoid desyncs.
9222
9223 // Hide the timer window for this player.
9224 call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], false)
9225
9226 // Display a confirmation message if the player's team is still alive.
9227 if (MeleeGetAllyStructureCount(indexPlayer) > 0) then
9228 if (bj_playerIsExposed[playerIndex]) then
9229 call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, GetLocalizedString("CRIPPLE_UNREVEALED"))
9230 else
9231 call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, GetLocalizedString("CRIPPLE_UNCRIPPLED"))
9232 endif
9233 endif
9234 endif
9235
9236 // If the player granted shared vision, deny that vision now.
9237 call MeleeExposePlayer(indexPlayer, false)
9238
9239 endif
9240
9241 set playerIndex = playerIndex + 1
9242 exitwhen playerIndex == bj_MAX_PLAYERS
9243 endloop
9244endfunction
9245
9246//===========================================================================
9247// Determine if the lost unit should result in any defeats or victories.
9248//
9249function MeleeCheckLostUnit takes unit lostUnit returns nothing
9250 local player lostUnitOwner = GetOwningPlayer(lostUnit)
9251
9252 // We only need to check for mortality if this was the last building.
9253 if (GetPlayerStructureCount(lostUnitOwner, true) <= 0) then
9254 call MeleeCheckForLosersAndVictors()
9255 endif
9256
9257 // Check if the lost unit has crippled or uncrippled the player.
9258 // (A team with 0 units is dead, and thus considered uncrippled.)
9259 call MeleeCheckForCrippledPlayers()
9260endfunction
9261
9262//===========================================================================
9263// Determine if the gained unit should result in any defeats, victories,
9264// or cripple-status changes.
9265//
9266function MeleeCheckAddedUnit takes unit addedUnit returns nothing
9267 local player addedUnitOwner = GetOwningPlayer(addedUnit)
9268
9269 // If the player was crippled, this unit may have uncrippled him/her.
9270 if (bj_playerIsCrippled[GetPlayerId(addedUnitOwner)]) then
9271 call MeleeCheckForCrippledPlayers()
9272 endif
9273endfunction
9274
9275//===========================================================================
9276function MeleeTriggerActionConstructCancel takes nothing returns nothing
9277 call MeleeCheckLostUnit(GetCancelledStructure())
9278endfunction
9279
9280//===========================================================================
9281function MeleeTriggerActionUnitDeath takes nothing returns nothing
9282 if (IsUnitType(GetDyingUnit(), UNIT_TYPE_STRUCTURE)) then
9283 call MeleeCheckLostUnit(GetDyingUnit())
9284 endif
9285endfunction
9286
9287//===========================================================================
9288function MeleeTriggerActionUnitConstructionStart takes nothing returns nothing
9289 call MeleeCheckAddedUnit(GetConstructingStructure())
9290endfunction
9291
9292//===========================================================================
9293function MeleeTriggerActionPlayerDefeated takes nothing returns nothing
9294 local player thePlayer = GetTriggerPlayer()
9295 call CachePlayerHeroData(thePlayer)
9296
9297 if (MeleeGetAllyCount(thePlayer) > 0) then
9298 // If at least one ally is still alive and kicking, share units with
9299 // them and proceed with death.
9300 call ShareEverythingWithTeam(thePlayer)
9301 if (not bj_meleeDefeated[GetPlayerId(thePlayer)]) then
9302 call MeleeDoDefeat(thePlayer)
9303 endif
9304 else
9305 // If no living allies remain, swap all units and buildings over to
9306 // neutral_passive and proceed with death.
9307 call MakeUnitsPassiveForTeam(thePlayer)
9308 if (not bj_meleeDefeated[GetPlayerId(thePlayer)]) then
9309 call MeleeDoDefeat(thePlayer)
9310 endif
9311 endif
9312 call MeleeCheckForLosersAndVictors()
9313endfunction
9314
9315//===========================================================================
9316function MeleeTriggerActionPlayerLeft takes nothing returns nothing
9317 local player thePlayer = GetTriggerPlayer()
9318
9319 // Just show game over for observers when they leave
9320 if (IsPlayerObserver(thePlayer)) then
9321 call RemovePlayerPreserveUnitsBJ(thePlayer, PLAYER_GAME_RESULT_NEUTRAL, false)
9322 return
9323 endif
9324
9325 call CachePlayerHeroData(thePlayer)
9326
9327 // This is the same as defeat except the player generates the message
9328 // "player left the game" as opposed to "player was defeated".
9329
9330 if (MeleeGetAllyCount(thePlayer) > 0) then
9331 // If at least one ally is still alive and kicking, share units with
9332 // them and proceed with death.
9333 call ShareEverythingWithTeam(thePlayer)
9334 call MeleeDoLeave(thePlayer)
9335 else
9336 // If no living allies remain, swap all units and buildings over to
9337 // neutral_passive and proceed with death.
9338 call MakeUnitsPassiveForTeam(thePlayer)
9339 call MeleeDoLeave(thePlayer)
9340 endif
9341 call MeleeCheckForLosersAndVictors()
9342endfunction
9343
9344//===========================================================================
9345function MeleeTriggerActionAllianceChange takes nothing returns nothing
9346 call MeleeCheckForLosersAndVictors()
9347 call MeleeCheckForCrippledPlayers()
9348endfunction
9349
9350//===========================================================================
9351function MeleeTriggerTournamentFinishSoon takes nothing returns nothing
9352 // Note: We may get this trigger multiple times
9353 local integer playerIndex
9354 local player indexPlayer
9355 local real timeRemaining = GetTournamentFinishSoonTimeRemaining()
9356
9357 if not bj_finishSoonAllExposed then
9358 set bj_finishSoonAllExposed = true
9359
9360 // Reset all crippled players and their timers, and hide the local crippled timer dialog
9361 set playerIndex = 0
9362 loop
9363 set indexPlayer = Player(playerIndex)
9364 if bj_playerIsCrippled[playerIndex] then
9365 // Uncripple the player
9366 set bj_playerIsCrippled[playerIndex] = false
9367 call PauseTimer(bj_crippledTimer[playerIndex])
9368
9369 if (GetLocalPlayer() == indexPlayer) then
9370 // Use only local code (no net traffic) within this block to avoid desyncs.
9371
9372 // Hide the timer window.
9373 call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], false)
9374 endif
9375
9376 endif
9377 set playerIndex = playerIndex + 1
9378 exitwhen playerIndex == bj_MAX_PLAYERS
9379 endloop
9380
9381 // Expose all players
9382 call MeleeExposeAllPlayers()
9383 endif
9384
9385 // Show the "finish soon" timer dialog and set the real time remaining
9386 call TimerDialogDisplay(bj_finishSoonTimerDialog, true)
9387 call TimerDialogSetRealTimeRemaining(bj_finishSoonTimerDialog, timeRemaining)
9388endfunction
9389
9390
9391//===========================================================================
9392function MeleeWasUserPlayer takes player whichPlayer returns boolean
9393 local playerslotstate slotState
9394
9395 if (GetPlayerController(whichPlayer) != MAP_CONTROL_USER) then
9396 return false
9397 endif
9398
9399 set slotState = GetPlayerSlotState(whichPlayer)
9400
9401 return (slotState == PLAYER_SLOT_STATE_PLAYING or slotState == PLAYER_SLOT_STATE_LEFT)
9402endfunction
9403
9404//===========================================================================
9405function MeleeTournamentFinishNowRuleA takes integer multiplier returns nothing
9406 local integer array playerScore
9407 local integer array teamScore
9408 local force array teamForce
9409 local integer teamCount
9410 local integer index
9411 local player indexPlayer
9412 local integer index2
9413 local player indexPlayer2
9414 local integer bestTeam
9415 local integer bestScore
9416 local boolean draw
9417
9418 // Compute individual player scores
9419 set index = 0
9420 loop
9421 set indexPlayer = Player(index)
9422 if MeleeWasUserPlayer(indexPlayer) then
9423 set playerScore[index] = GetTournamentScore(indexPlayer)
9424 if playerScore[index] <= 0 then
9425 set playerScore[index] = 1
9426 endif
9427 else
9428 set playerScore[index] = 0
9429 endif
9430 set index = index + 1
9431 exitwhen index == bj_MAX_PLAYERS
9432 endloop
9433
9434 // Compute team scores and team forces
9435 set teamCount = 0
9436 set index = 0
9437 loop
9438 if playerScore[index] != 0 then
9439 set indexPlayer = Player(index)
9440
9441 set teamScore[teamCount] = 0
9442 set teamForce[teamCount] = CreateForce()
9443
9444 set index2 = index
9445 loop
9446 if playerScore[index2] != 0 then
9447 set indexPlayer2 = Player(index2)
9448
9449 if PlayersAreCoAllied(indexPlayer, indexPlayer2) then
9450 set teamScore[teamCount] = teamScore[teamCount] + playerScore[index2]
9451 call ForceAddPlayer(teamForce[teamCount], indexPlayer2)
9452 set playerScore[index2] = 0
9453 endif
9454 endif
9455
9456 set index2 = index2 + 1
9457 exitwhen index2 == bj_MAX_PLAYERS
9458 endloop
9459
9460 set teamCount = teamCount + 1
9461 endif
9462
9463 set index = index + 1
9464 exitwhen index == bj_MAX_PLAYERS
9465 endloop
9466
9467 // The game is now over
9468 set bj_meleeGameOver = true
9469
9470 // There should always be at least one team, but continue to work if not
9471 if teamCount != 0 then
9472
9473 // Find best team score
9474 set bestTeam = -1
9475 set bestScore = -1
9476 set index = 0
9477 loop
9478 if teamScore[index] > bestScore then
9479 set bestTeam = index
9480 set bestScore = teamScore[index]
9481 endif
9482
9483 set index = index + 1
9484 exitwhen index == teamCount
9485 endloop
9486
9487 // Check whether the best team's score is 'multiplier' times better than
9488 // every other team. In the case of multiplier == 1 and exactly equal team
9489 // scores, the first team (which was randomly chosen by the server) will win.
9490 set draw = false
9491 set index = 0
9492 loop
9493 if index != bestTeam then
9494 if bestScore < (multiplier * teamScore[index]) then
9495 set draw = true
9496 endif
9497 endif
9498
9499 set index = index + 1
9500 exitwhen index == teamCount
9501 endloop
9502
9503 if draw then
9504 // Give draw to all players on all teams
9505 set index = 0
9506 loop
9507 call ForForce(teamForce[index], function MeleeDoDrawEnum)
9508
9509 set index = index + 1
9510 exitwhen index == teamCount
9511 endloop
9512 else
9513 // Give defeat to all players on teams other than the best team
9514 set index = 0
9515 loop
9516 if index != bestTeam then
9517 call ForForce(teamForce[index], function MeleeDoDefeatEnum)
9518 endif
9519
9520 set index = index + 1
9521 exitwhen index == teamCount
9522 endloop
9523
9524 // Give victory to all players on the best team
9525 call ForForce(teamForce[bestTeam], function MeleeDoVictoryEnum)
9526 endif
9527 endif
9528
9529endfunction
9530
9531//===========================================================================
9532function MeleeTriggerTournamentFinishNow takes nothing returns nothing
9533 local integer rule = GetTournamentFinishNowRule()
9534
9535 // If the game is already over, do nothing
9536 if bj_meleeGameOver then
9537 return
9538 endif
9539
9540 if (rule == 1) then
9541 // Finals games
9542 call MeleeTournamentFinishNowRuleA(1)
9543 else
9544 // Preliminary games
9545 call MeleeTournamentFinishNowRuleA(3)
9546 endif
9547
9548 // Since the game is over we should remove all observers
9549 call MeleeRemoveObservers()
9550
9551endfunction
9552
9553//===========================================================================
9554function MeleeInitVictoryDefeat takes nothing returns nothing
9555 local trigger trig
9556 local integer index
9557 local player indexPlayer
9558
9559 // Create a timer window for the "finish soon" timeout period, it has no timer
9560 // because it is driven by real time (outside of the game state to avoid desyncs)
9561 set bj_finishSoonTimerDialog = CreateTimerDialog(null)
9562
9563 // Set a trigger to fire when we receive a "finish soon" game event
9564 set trig = CreateTrigger()
9565 call TriggerRegisterGameEvent(trig, EVENT_GAME_TOURNAMENT_FINISH_SOON)
9566 call TriggerAddAction(trig, function MeleeTriggerTournamentFinishSoon)
9567
9568 // Set a trigger to fire when we receive a "finish now" game event
9569 set trig = CreateTrigger()
9570 call TriggerRegisterGameEvent(trig, EVENT_GAME_TOURNAMENT_FINISH_NOW)
9571 call TriggerAddAction(trig, function MeleeTriggerTournamentFinishNow)
9572
9573 // Set up each player's mortality code.
9574 set index = 0
9575 loop
9576 set indexPlayer = Player(index)
9577
9578 // Make sure this player slot is playing.
9579 if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
9580 set bj_meleeDefeated[index] = false
9581 set bj_meleeVictoried[index] = false
9582
9583 // Create a timer and timer window in case the player is crippled.
9584 set bj_playerIsCrippled[index] = false
9585 set bj_playerIsExposed[index] = false
9586 set bj_crippledTimer[index] = CreateTimer()
9587 set bj_crippledTimerWindows[index] = CreateTimerDialog(bj_crippledTimer[index])
9588 call TimerDialogSetTitle(bj_crippledTimerWindows[index], MeleeGetCrippledTimerMessage(indexPlayer))
9589
9590 // Set a trigger to fire whenever a building is cancelled for this player.
9591 set trig = CreateTrigger()
9592 call TriggerRegisterPlayerUnitEvent(trig, indexPlayer, EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL, null)
9593 call TriggerAddAction(trig, function MeleeTriggerActionConstructCancel)
9594
9595 // Set a trigger to fire whenever a unit dies for this player.
9596 set trig = CreateTrigger()
9597 call TriggerRegisterPlayerUnitEvent(trig, indexPlayer, EVENT_PLAYER_UNIT_DEATH, null)
9598 call TriggerAddAction(trig, function MeleeTriggerActionUnitDeath)
9599
9600 // Set a trigger to fire whenever a unit begins construction for this player
9601 set trig = CreateTrigger()
9602 call TriggerRegisterPlayerUnitEvent(trig, indexPlayer, EVENT_PLAYER_UNIT_CONSTRUCT_START, null)
9603 call TriggerAddAction(trig, function MeleeTriggerActionUnitConstructionStart)
9604
9605 // Set a trigger to fire whenever this player defeats-out
9606 set trig = CreateTrigger()
9607 call TriggerRegisterPlayerEvent(trig, indexPlayer, EVENT_PLAYER_DEFEAT)
9608 call TriggerAddAction(trig, function MeleeTriggerActionPlayerDefeated)
9609
9610 // Set a trigger to fire whenever this player leaves
9611 set trig = CreateTrigger()
9612 call TriggerRegisterPlayerEvent(trig, indexPlayer, EVENT_PLAYER_LEAVE)
9613 call TriggerAddAction(trig, function MeleeTriggerActionPlayerLeft)
9614
9615 // Set a trigger to fire whenever this player changes his/her alliances.
9616 set trig = CreateTrigger()
9617 call TriggerRegisterPlayerAllianceChange(trig, indexPlayer, ALLIANCE_PASSIVE)
9618 call TriggerRegisterPlayerStateEvent(trig, indexPlayer, PLAYER_STATE_ALLIED_VICTORY, EQUAL, 1)
9619 call TriggerAddAction(trig, function MeleeTriggerActionAllianceChange)
9620 else
9621 set bj_meleeDefeated[index] = true
9622 set bj_meleeVictoried[index] = false
9623
9624 // Handle leave events for observers
9625 if (IsPlayerObserver(indexPlayer)) then
9626 // Set a trigger to fire whenever this player leaves
9627 set trig = CreateTrigger()
9628 call TriggerRegisterPlayerEvent(trig, indexPlayer, EVENT_PLAYER_LEAVE)
9629 call TriggerAddAction(trig, function MeleeTriggerActionPlayerLeft)
9630 endif
9631 endif
9632
9633 set index = index + 1
9634 exitwhen index == bj_MAX_PLAYERS
9635 endloop
9636
9637 // Test for victory / defeat at startup, in case the user has already won / lost.
9638 // Allow for a short time to pass first, so that the map can finish loading.
9639 call TimerStart(CreateTimer(), 2.0, false, function MeleeTriggerActionAllianceChange)
9640endfunction
9641
9642
9643
9644//***************************************************************************
9645//*
9646//* Player Slot Availability
9647//*
9648//***************************************************************************
9649
9650//===========================================================================
9651function CheckInitPlayerSlotAvailability takes nothing returns nothing
9652 local integer index
9653
9654 if (not bj_slotControlReady) then
9655 set index = 0
9656 loop
9657 set bj_slotControlUsed[index] = false
9658 set bj_slotControl[index] = MAP_CONTROL_USER
9659 set index = index + 1
9660 exitwhen index == bj_MAX_PLAYERS
9661 endloop
9662 set bj_slotControlReady = true
9663 endif
9664endfunction
9665
9666//===========================================================================
9667function SetPlayerSlotAvailable takes player whichPlayer, mapcontrol control returns nothing
9668 local integer playerIndex = GetPlayerId(whichPlayer)
9669
9670 call CheckInitPlayerSlotAvailability()
9671 set bj_slotControlUsed[playerIndex] = true
9672 set bj_slotControl[playerIndex] = control
9673endfunction
9674
9675
9676
9677//***************************************************************************
9678//*
9679//* Generic Template Player-slot Initialization
9680//*
9681//***************************************************************************
9682
9683//===========================================================================
9684function TeamInitPlayerSlots takes integer teamCount returns nothing
9685 local integer index
9686 local player indexPlayer
9687 local integer team
9688
9689 call SetTeams(teamCount)
9690
9691 call CheckInitPlayerSlotAvailability()
9692 set index = 0
9693 set team = 0
9694 loop
9695 if (bj_slotControlUsed[index]) then
9696 set indexPlayer = Player(index)
9697 call SetPlayerTeam( indexPlayer, team )
9698 set team = team + 1
9699 if (team >= teamCount) then
9700 set team = 0
9701 endif
9702 endif
9703
9704 set index = index + 1
9705 exitwhen index == bj_MAX_PLAYERS
9706 endloop
9707endfunction
9708
9709//===========================================================================
9710function MeleeInitPlayerSlots takes nothing returns nothing
9711 call TeamInitPlayerSlots(bj_MAX_PLAYERS)
9712endfunction
9713
9714//===========================================================================
9715function FFAInitPlayerSlots takes nothing returns nothing
9716 call TeamInitPlayerSlots(bj_MAX_PLAYERS)
9717endfunction
9718
9719//===========================================================================
9720function OneOnOneInitPlayerSlots takes nothing returns nothing
9721 // Limit the game to 2 players.
9722 call SetTeams(2)
9723 call SetPlayers(2)
9724 call TeamInitPlayerSlots(2)
9725endfunction
9726
9727//===========================================================================
9728function InitGenericPlayerSlots takes nothing returns nothing
9729 local gametype gType = GetGameTypeSelected()
9730
9731 if (gType == GAME_TYPE_MELEE) then
9732 call MeleeInitPlayerSlots()
9733 elseif (gType == GAME_TYPE_FFA) then
9734 call FFAInitPlayerSlots()
9735 elseif (gType == GAME_TYPE_USE_MAP_SETTINGS) then
9736 // Do nothing; the map-specific script handles this.
9737 elseif (gType == GAME_TYPE_ONE_ON_ONE) then
9738 call OneOnOneInitPlayerSlots()
9739 elseif (gType == GAME_TYPE_TWO_TEAM_PLAY) then
9740 call TeamInitPlayerSlots(2)
9741 elseif (gType == GAME_TYPE_THREE_TEAM_PLAY) then
9742 call TeamInitPlayerSlots(3)
9743 elseif (gType == GAME_TYPE_FOUR_TEAM_PLAY) then
9744 call TeamInitPlayerSlots(4)
9745 else
9746 // Unrecognized Game Type
9747 endif
9748endfunction
9749
9750
9751
9752//***************************************************************************
9753//*
9754//* Blizzard.j Initialization
9755//*
9756//***************************************************************************
9757
9758//===========================================================================
9759function SetDNCSoundsDawn takes nothing returns nothing
9760 if bj_useDawnDuskSounds then
9761 call StartSound(bj_dawnSound)
9762 endif
9763endfunction
9764
9765//===========================================================================
9766function SetDNCSoundsDusk takes nothing returns nothing
9767 if bj_useDawnDuskSounds then
9768 call StartSound(bj_duskSound)
9769 endif
9770endfunction
9771
9772//===========================================================================
9773function SetDNCSoundsDay takes nothing returns nothing
9774 local real ToD = GetTimeOfDay()
9775
9776 if (ToD >= bj_TOD_DAWN and ToD < bj_TOD_DUSK) and not bj_dncIsDaytime then
9777 set bj_dncIsDaytime = true
9778
9779 // change ambient sounds
9780 call StopSound(bj_nightAmbientSound, false, true)
9781 call StartSound(bj_dayAmbientSound)
9782 endif
9783endfunction
9784
9785//===========================================================================
9786function SetDNCSoundsNight takes nothing returns nothing
9787 local real ToD = GetTimeOfDay()
9788
9789 if (ToD < bj_TOD_DAWN or ToD >= bj_TOD_DUSK) and bj_dncIsDaytime then
9790 set bj_dncIsDaytime = false
9791
9792 // change ambient sounds
9793 call StopSound(bj_dayAmbientSound, false, true)
9794 call StartSound(bj_nightAmbientSound)
9795 endif
9796endfunction
9797
9798//===========================================================================
9799function InitDNCSounds takes nothing returns nothing
9800 // Create sounds to be played at dawn and dusk.
9801 set bj_dawnSound = CreateSoundFromLabel("RoosterSound", false, false, false, 10000, 10000)
9802 set bj_duskSound = CreateSoundFromLabel("WolfSound", false, false, false, 10000, 10000)
9803
9804 // Set up triggers to respond to dawn and dusk.
9805 set bj_dncSoundsDawn = CreateTrigger()
9806 call TriggerRegisterGameStateEvent(bj_dncSoundsDawn, GAME_STATE_TIME_OF_DAY, EQUAL, bj_TOD_DAWN)
9807 call TriggerAddAction(bj_dncSoundsDawn, function SetDNCSoundsDawn)
9808
9809 set bj_dncSoundsDusk = CreateTrigger()
9810 call TriggerRegisterGameStateEvent(bj_dncSoundsDusk, GAME_STATE_TIME_OF_DAY, EQUAL, bj_TOD_DUSK)
9811 call TriggerAddAction(bj_dncSoundsDusk, function SetDNCSoundsDusk)
9812
9813 // Set up triggers to respond to changes from day to night or vice-versa.
9814 set bj_dncSoundsDay = CreateTrigger()
9815 call TriggerRegisterGameStateEvent(bj_dncSoundsDay, GAME_STATE_TIME_OF_DAY, GREATER_THAN_OR_EQUAL, bj_TOD_DAWN)
9816 call TriggerRegisterGameStateEvent(bj_dncSoundsDay, GAME_STATE_TIME_OF_DAY, LESS_THAN, bj_TOD_DUSK)
9817 call TriggerAddAction(bj_dncSoundsDay, function SetDNCSoundsDay)
9818
9819 set bj_dncSoundsNight = CreateTrigger()
9820 call TriggerRegisterGameStateEvent(bj_dncSoundsNight, GAME_STATE_TIME_OF_DAY, LESS_THAN, bj_TOD_DAWN)
9821 call TriggerRegisterGameStateEvent(bj_dncSoundsNight, GAME_STATE_TIME_OF_DAY, GREATER_THAN_OR_EQUAL, bj_TOD_DUSK)
9822 call TriggerAddAction(bj_dncSoundsNight, function SetDNCSoundsNight)
9823endfunction
9824
9825//===========================================================================
9826function InitBlizzardGlobals takes nothing returns nothing
9827 local integer index
9828 local integer userControlledPlayers
9829 local version v
9830
9831 // Init filter function vars
9832 set filterIssueHauntOrderAtLocBJ = Filter(function IssueHauntOrderAtLocBJFilter)
9833 set filterEnumDestructablesInCircleBJ = Filter(function EnumDestructablesInCircleBJFilter)
9834 set filterGetUnitsInRectOfPlayer = Filter(function GetUnitsInRectOfPlayerFilter)
9835 set filterGetUnitsOfTypeIdAll = Filter(function GetUnitsOfTypeIdAllFilter)
9836 set filterGetUnitsOfPlayerAndTypeId = Filter(function GetUnitsOfPlayerAndTypeIdFilter)
9837 set filterMeleeTrainedUnitIsHeroBJ = Filter(function MeleeTrainedUnitIsHeroBJFilter)
9838 set filterLivingPlayerUnitsOfTypeId = Filter(function LivingPlayerUnitsOfTypeIdFilter)
9839
9840 // Init force presets
9841 set index = 0
9842 loop
9843 exitwhen index == bj_MAX_PLAYER_SLOTS
9844 set bj_FORCE_PLAYER[index] = CreateForce()
9845 call ForceAddPlayer(bj_FORCE_PLAYER[index], Player(index))
9846 set index = index + 1
9847 endloop
9848
9849 set bj_FORCE_ALL_PLAYERS = CreateForce()
9850 call ForceEnumPlayers(bj_FORCE_ALL_PLAYERS, null)
9851
9852 // Init Cinematic Mode history
9853 set bj_cineModePriorSpeed = GetGameSpeed()
9854 set bj_cineModePriorFogSetting = IsFogEnabled()
9855 set bj_cineModePriorMaskSetting = IsFogMaskEnabled()
9856
9857 // Init Trigger Queue
9858 set index = 0
9859 loop
9860 exitwhen index >= bj_MAX_QUEUED_TRIGGERS
9861 set bj_queuedExecTriggers[index] = null
9862 set bj_queuedExecUseConds[index] = false
9863 set index = index + 1
9864 endloop
9865
9866 // Init singleplayer check
9867 set bj_isSinglePlayer = false
9868 set userControlledPlayers = 0
9869 set index = 0
9870 loop
9871 exitwhen index >= bj_MAX_PLAYERS
9872 if (GetPlayerController(Player(index)) == MAP_CONTROL_USER and GetPlayerSlotState(Player(index)) == PLAYER_SLOT_STATE_PLAYING) then
9873 set userControlledPlayers = userControlledPlayers + 1
9874 endif
9875 set index = index + 1
9876 endloop
9877 set bj_isSinglePlayer = (userControlledPlayers == 1)
9878
9879 // Init sounds
9880 //set bj_pingMinimapSound = CreateSoundFromLabel("AutoCastButtonClick", false, false, false, 10000, 10000)
9881 set bj_rescueSound = CreateSoundFromLabel("Rescue", false, false, false, 10000, 10000)
9882 set bj_questDiscoveredSound = CreateSoundFromLabel("QuestNew", false, false, false, 10000, 10000)
9883 set bj_questUpdatedSound = CreateSoundFromLabel("QuestUpdate", false, false, false, 10000, 10000)
9884 set bj_questCompletedSound = CreateSoundFromLabel("QuestCompleted", false, false, false, 10000, 10000)
9885 set bj_questFailedSound = CreateSoundFromLabel("QuestFailed", false, false, false, 10000, 10000)
9886 set bj_questHintSound = CreateSoundFromLabel("Hint", false, false, false, 10000, 10000)
9887 set bj_questSecretSound = CreateSoundFromLabel("SecretFound", false, false, false, 10000, 10000)
9888 set bj_questItemAcquiredSound = CreateSoundFromLabel("ItemReward", false, false, false, 10000, 10000)
9889 set bj_questWarningSound = CreateSoundFromLabel("Warning", false, false, false, 10000, 10000)
9890 set bj_victoryDialogSound = CreateSoundFromLabel("QuestCompleted", false, false, false, 10000, 10000)
9891 set bj_defeatDialogSound = CreateSoundFromLabel("QuestFailed", false, false, false, 10000, 10000)
9892
9893 // Init corpse creation triggers.
9894 call DelayedSuspendDecayCreate()
9895
9896 // Init version-specific data
9897 set v = VersionGet()
9898 if (v == VERSION_REIGN_OF_CHAOS) then
9899 set bj_MELEE_MAX_TWINKED_HEROES = bj_MELEE_MAX_TWINKED_HEROES_V0
9900 else
9901 set bj_MELEE_MAX_TWINKED_HEROES = bj_MELEE_MAX_TWINKED_HEROES_V1
9902 endif
9903endfunction
9904
9905//===========================================================================
9906function InitQueuedTriggers takes nothing returns nothing
9907 set bj_queuedExecTimeout = CreateTrigger()
9908 call TriggerRegisterTimerExpireEvent(bj_queuedExecTimeout, bj_queuedExecTimeoutTimer)
9909 call TriggerAddAction(bj_queuedExecTimeout, function QueuedTriggerDoneBJ)
9910endfunction
9911
9912//===========================================================================
9913function InitMapRects takes nothing returns nothing
9914 set bj_mapInitialPlayableArea = Rect(GetCameraBoundMinX()-GetCameraMargin(CAMERA_MARGIN_LEFT), GetCameraBoundMinY()-GetCameraMargin(CAMERA_MARGIN_BOTTOM), GetCameraBoundMaxX()+GetCameraMargin(CAMERA_MARGIN_RIGHT), GetCameraBoundMaxY()+GetCameraMargin(CAMERA_MARGIN_TOP))
9915 set bj_mapInitialCameraBounds = GetCurrentCameraBoundsMapRectBJ()
9916endfunction
9917
9918//===========================================================================
9919function InitSummonableCaps takes nothing returns nothing
9920 local integer index
9921
9922 set index = 0
9923 loop
9924 // upgraded units
9925 // Note: Only do this if the corresponding upgrade is not yet researched
9926 // Barrage - Siege Engines
9927 if (not GetPlayerTechResearched(Player(index), 'Rhrt', true)) then
9928 call SetPlayerTechMaxAllowed(Player(index), 'hrtt', 0)
9929 endif
9930
9931 // Berserker Upgrade - Troll Berserkers
9932 if (not GetPlayerTechResearched(Player(index), 'Robk', true)) then
9933 call SetPlayerTechMaxAllowed(Player(index), 'otbk', 0)
9934 endif
9935
9936 // max skeletons per player
9937 call SetPlayerTechMaxAllowed(Player(index), 'uske', bj_MAX_SKELETONS)
9938
9939 set index = index + 1
9940 exitwhen index == bj_MAX_PLAYERS
9941 endloop
9942endfunction
9943
9944//===========================================================================
9945// Update the per-class stock limits.
9946//
9947function UpdateStockAvailability takes item whichItem returns nothing
9948 local itemtype iType = GetItemType(whichItem)
9949 local integer iLevel = GetItemLevel(whichItem)
9950
9951 // Update allowed type/level combinations.
9952 if (iType == ITEM_TYPE_PERMANENT) then
9953 set bj_stockAllowedPermanent[iLevel] = true
9954 elseif (iType == ITEM_TYPE_CHARGED) then
9955 set bj_stockAllowedCharged[iLevel] = true
9956 elseif (iType == ITEM_TYPE_ARTIFACT) then
9957 set bj_stockAllowedArtifact[iLevel] = true
9958 else
9959 // Not interested in this item type - ignore the item.
9960 endif
9961endfunction
9962
9963//===========================================================================
9964// Find a sellable item of the given type and level, and then add it.
9965//
9966function UpdateEachStockBuildingEnum takes nothing returns nothing
9967 local integer iteration = 0
9968 local integer pickedItemId
9969
9970 loop
9971 set pickedItemId = ChooseRandomItemEx(bj_stockPickedItemType, bj_stockPickedItemLevel)
9972 exitwhen IsItemIdSellable(pickedItemId)
9973
9974 // If we get hung up on an entire class/level combo of unsellable
9975 // items, or a very unlucky series of random numbers, give up.
9976 set iteration = iteration + 1
9977 if (iteration > bj_STOCK_MAX_ITERATIONS) then
9978 return
9979 endif
9980 endloop
9981 call AddItemToStock(GetEnumUnit(), pickedItemId, 1, 1)
9982endfunction
9983
9984//===========================================================================
9985function UpdateEachStockBuilding takes itemtype iType, integer iLevel returns nothing
9986 local group g
9987
9988 set bj_stockPickedItemType = iType
9989 set bj_stockPickedItemLevel = iLevel
9990
9991 set g = CreateGroup()
9992 call GroupEnumUnitsOfType(g, "marketplace", null)
9993 call ForGroup(g, function UpdateEachStockBuildingEnum)
9994 call DestroyGroup(g)
9995endfunction
9996
9997//===========================================================================
9998// Update stock inventory.
9999//
10000function PerformStockUpdates takes nothing returns nothing
10001 local integer pickedItemId
10002 local itemtype pickedItemType
10003 local integer pickedItemLevel = 0
10004 local integer allowedCombinations = 0
10005 local integer iLevel
10006
10007 // Give each type/level combination a chance of being picked.
10008 set iLevel = 1
10009 loop
10010 if (bj_stockAllowedPermanent[iLevel]) then
10011 set allowedCombinations = allowedCombinations + 1
10012 if (GetRandomInt(1, allowedCombinations) == 1) then
10013 set pickedItemType = ITEM_TYPE_PERMANENT
10014 set pickedItemLevel = iLevel
10015 endif
10016 endif
10017 if (bj_stockAllowedCharged[iLevel]) then
10018 set allowedCombinations = allowedCombinations + 1
10019 if (GetRandomInt(1, allowedCombinations) == 1) then
10020 set pickedItemType = ITEM_TYPE_CHARGED
10021 set pickedItemLevel = iLevel
10022 endif
10023 endif
10024 if (bj_stockAllowedArtifact[iLevel]) then
10025 set allowedCombinations = allowedCombinations + 1
10026 if (GetRandomInt(1, allowedCombinations) == 1) then
10027 set pickedItemType = ITEM_TYPE_ARTIFACT
10028 set pickedItemLevel = iLevel
10029 endif
10030 endif
10031
10032 set iLevel = iLevel + 1
10033 exitwhen iLevel > bj_MAX_ITEM_LEVEL
10034 endloop
10035
10036 // Make sure we found a valid item type to add.
10037 if (allowedCombinations == 0) then
10038 return
10039 endif
10040
10041 call UpdateEachStockBuilding(pickedItemType, pickedItemLevel)
10042endfunction
10043
10044//===========================================================================
10045// Perform the first update, and then arrange future updates.
10046//
10047function StartStockUpdates takes nothing returns nothing
10048 call PerformStockUpdates()
10049 call TimerStart(bj_stockUpdateTimer, bj_STOCK_RESTOCK_INTERVAL, true, function PerformStockUpdates)
10050endfunction
10051
10052//===========================================================================
10053function RemovePurchasedItem takes nothing returns nothing
10054 call RemoveItemFromStock(GetSellingUnit(), GetItemTypeId(GetSoldItem()))
10055endfunction
10056
10057//===========================================================================
10058function InitNeutralBuildings takes nothing returns nothing
10059 local integer iLevel
10060
10061 // Chart of allowed stock items.
10062 set iLevel = 0
10063 loop
10064 set bj_stockAllowedPermanent[iLevel] = false
10065 set bj_stockAllowedCharged[iLevel] = false
10066 set bj_stockAllowedArtifact[iLevel] = false
10067 set iLevel = iLevel + 1
10068 exitwhen iLevel > bj_MAX_ITEM_LEVEL
10069 endloop
10070
10071 // Limit stock inventory slots.
10072 call SetAllItemTypeSlots(bj_MAX_STOCK_ITEM_SLOTS)
10073 call SetAllUnitTypeSlots(bj_MAX_STOCK_UNIT_SLOTS)
10074
10075 // Arrange the first update.
10076 set bj_stockUpdateTimer = CreateTimer()
10077 call TimerStart(bj_stockUpdateTimer, bj_STOCK_RESTOCK_INITIAL_DELAY, false, function StartStockUpdates)
10078
10079 // Set up a trigger to fire whenever an item is sold.
10080 set bj_stockItemPurchased = CreateTrigger()
10081 call TriggerRegisterPlayerUnitEvent(bj_stockItemPurchased, Player(PLAYER_NEUTRAL_PASSIVE), EVENT_PLAYER_UNIT_SELL_ITEM, null)
10082 call TriggerAddAction(bj_stockItemPurchased, function RemovePurchasedItem)
10083endfunction
10084
10085//===========================================================================
10086function MarkGameStarted takes nothing returns nothing
10087 set bj_gameStarted = true
10088 call DestroyTimer(bj_gameStartedTimer)
10089endfunction
10090
10091//===========================================================================
10092function DetectGameStarted takes nothing returns nothing
10093 set bj_gameStartedTimer = CreateTimer()
10094 call TimerStart(bj_gameStartedTimer, bj_GAME_STARTED_THRESHOLD, false, function MarkGameStarted)
10095endfunction
10096
10097//===========================================================================
10098function InitBlizzard takes nothing returns nothing
10099 // Set up the Neutral Victim player slot, to torture the abandoned units
10100 // of defeated players. Since some triggers expect this player slot to
10101 // exist, this is performed for all maps.
10102 call ConfigureNeutralVictim()
10103
10104 call InitBlizzardGlobals()
10105 call InitQueuedTriggers()
10106 call InitRescuableBehaviorBJ()
10107 call InitDNCSounds()
10108 call InitMapRects()
10109 call InitSummonableCaps()
10110 call InitNeutralBuildings()
10111 call DetectGameStarted()
10112endfunction
10113
10114
10115
10116//***************************************************************************
10117//*
10118//* Random distribution
10119//*
10120//* Used to select a random object from a given distribution of chances
10121//*
10122//* - RandomDistReset clears the distribution list
10123//*
10124//* - RandomDistAddItem adds a new object to the distribution list
10125//* with a given identifier and an integer chance to be chosen
10126//*
10127//* - RandomDistChoose will use the current distribution list to choose
10128//* one of the objects randomly based on the chance distribution
10129//*
10130//* Note that the chances are effectively normalized by their sum,
10131//* so only the relative values of each chance are important
10132//*
10133//***************************************************************************
10134
10135//===========================================================================
10136function RandomDistReset takes nothing returns nothing
10137 set bj_randDistCount = 0
10138endfunction
10139
10140//===========================================================================
10141function RandomDistAddItem takes integer inID, integer inChance returns nothing
10142 set bj_randDistID[bj_randDistCount] = inID
10143 set bj_randDistChance[bj_randDistCount] = inChance
10144 set bj_randDistCount = bj_randDistCount + 1
10145endfunction
10146
10147//===========================================================================
10148function RandomDistChoose takes nothing returns integer
10149 local integer sum = 0
10150 local integer chance = 0
10151 local integer index
10152 local integer foundID = -1
10153 local boolean done
10154
10155 // No items?
10156 if (bj_randDistCount == 0) then
10157 return -1
10158 endif
10159
10160 // Find sum of all chances
10161 set index = 0
10162 loop
10163 set sum = sum + bj_randDistChance[index]
10164
10165 set index = index + 1
10166 exitwhen index == bj_randDistCount
10167 endloop
10168
10169 // Choose random number within the total range
10170 set chance = GetRandomInt(1, sum)
10171
10172 // Find ID which corresponds to this chance
10173 set index = 0
10174 set sum = 0
10175 set done = false
10176 loop
10177 set sum = sum + bj_randDistChance[index]
10178
10179 if (chance <= sum) then
10180 set foundID = bj_randDistID[index]
10181 set done = true
10182 endif
10183
10184 set index = index + 1
10185 if (index == bj_randDistCount) then
10186 set done = true
10187 endif
10188
10189 exitwhen done == true
10190 endloop
10191
10192 return foundID
10193endfunction
10194
10195
10196
10197//***************************************************************************
10198//*
10199//* Drop item
10200//*
10201//* Makes the given unit drop the given item
10202//*
10203//* Note: This could potentially cause problems if the unit is standing
10204//* right on the edge of an unpathable area and happens to drop the
10205//* item into the unpathable area where nobody can get it...
10206//*
10207//***************************************************************************
10208
10209function UnitDropItem takes unit inUnit, integer inItemID returns item
10210 local real x
10211 local real y
10212 local real radius = 32
10213 local real unitX
10214 local real unitY
10215 local item droppedItem
10216
10217 if (inItemID == -1) then
10218 return null
10219 endif
10220
10221 set unitX = GetUnitX(inUnit)
10222 set unitY = GetUnitY(inUnit)
10223
10224 set x = GetRandomReal(unitX - radius, unitX + radius)
10225 set y = GetRandomReal(unitY - radius, unitY + radius)
10226
10227 set droppedItem = CreateItem(inItemID, x, y)
10228
10229 call SetItemDropID(droppedItem, GetUnitTypeId(inUnit))
10230 call UpdateStockAvailability(droppedItem)
10231
10232 return droppedItem
10233endfunction
10234
10235//===========================================================================
10236function WidgetDropItem takes widget inWidget, integer inItemID returns item
10237 local real x
10238 local real y
10239 local real radius = 32
10240 local real widgetX
10241 local real widgetY
10242
10243 if (inItemID == -1) then
10244 return null
10245 endif
10246
10247 set widgetX = GetWidgetX(inWidget)
10248 set widgetY = GetWidgetY(inWidget)
10249
10250 set x = GetRandomReal(widgetX - radius, widgetX + radius)
10251 set y = GetRandomReal(widgetY - radius, widgetY + radius)
10252
10253 return CreateItem(inItemID, x, y)
10254endfunction