View difference between Paste ID: Can4RJxF and x1SGnE3e
SHOW: | | - or go back to the newest paste.
1
//===== rAthena Script =======================================
2
//= World Boss Event
3
//===== By: ==================================================
4
//= Musika6988, Sehrentos
5
//===== Current Version: =====================================
6-
//= 2.9.4
6+
//= 2.9.3
7
//===== Compatible With: =====================================
8
//= rAthena Project
9
//===== Description: =========================================
10
//= Summon random World Boss and when defeated get treasure.
11
//= Leader will have option to distribute or dispose loots.
12
//= GM panel: info/start/stop/skip/lootMode/modify.
13
//= Boss HP will increase or decrease by 1.500.000 per each 
14
//= player nearby and is updated every 10 seconds.
15
//= When boss is defeated it will trigger increased exp and
16
//= drop rates to whole server for 1 hour(IF enabled).
17
//===== Additional Comments: =================================
18
//= 1.x Initial script by Musika6988.
19
//= 2.0 Sehrentos added reward arrays. Randomly select a reward.
20
//= 2.1 Sehrentos changed single random reward into random all rewards.
21
//= 2.2 Sehrentos minor optimizations.
22
//= 2.3 Sehrentos added more loot options.
23
//= 2.4 Sehrentos added GM panel, Default mob attributes(.MOB_),
24
//=  Same party check(reward stealing)
25
//= 2.5 Sehrentos added NPC WorldBossRadar to monitor players nearby,
26
//=  Removed Flee and Perfect Dodge from Treasure Chest,
27
//=  Added timeout to stop the event. Minor text changes.
28
//= 2.6 Sehrentos added loot mode 1 give one reward to one random party member.
29
//=  Added loot modes 4-5 give all/one rewards to all nearby players and their party members.
30
//=  Added loot modes 6-7 give all/one rewards to all nearby players.
31
//= 2.7 Sehrentos removed Treasure Chest monster.
32
//=  Added Treasure Chest NPCs.
33
//=  Added multiple events at once, but not in same map.
34
//=  Added loot modes 8-9 give all/one rewards to all players in same map.
35
//=  Added double server rates for 1 hour after boss is killed event.
36
//= 2.8 Sehrentos added jump_zero optimizations.
37
//=  Fixed WorldBossRates::OnInit first run on the server.
38
//=  Added $@WB_ACCESS_EXPIRE timer. Clean the access array when it expires.
39
//= 2.9 Sehrentos WorldBossRadar enable/disable option.
40
//=  Added loot modes 10 give all rewards to selected party member.
41
//=  Added loot modes 11 give one random reward to selected party member.
42
//= 2.9.1 Sehrentos Fixes and additions.
43
//=  Added option to turn off mapflags.
44
//=  Added more default .MOB_ status points.
45
//=  Fix random reward will be selected only once, to avoid abuse ($@WB_REWARD_INDEX).
46
//=  Renamed some values. easier to understand.
47
//= 2.9.2 Sehrentos Disabled FOG effect.
48
//=  Added more announcements when event fail to start.
49
//=  Added unit checks on OnMobDie event.
50
//=  Added inarray optimizations.
51
//= 2.9.3 Sehrentos changed the way event starts and announces.
52
//=  Fixed WorldBossRates when .use_floating_rates is enabled(report @Quesooo).
53-
//= 2.9.4 Sehrentos added loots amounts in array (suggest @Radian).
53+
54
//============================================================
55
-	script	WorldBoss	-1,{
56
OnInit:
57
	// Settings
58
	.npc_name$ = strnpcinfo(0); // Name of this NPC
59
	.event_sleep = 60000;       // Event sleep time in milliseconds(60000 = 1 minute)
60
	.event_timeout = 7200000;   // Event timeout time in milliseconds before Boss is disabled(60000 = 1 minute)
61
	.event_access_expire = 900000; // Event access expire time in milliseconds(60000 = 1 minute)
62
63
	// Reward distribution
64
	.loot_mode = 4;             // Event loot distribution mode. Look npc_loot_mode_desc for descriptions
65
	.loop_max = 200;            // Maximum number of loops (When selecting a random party member)
66
	.duplicate_npc_count = 9;   // Number of duplicate Treasure Chest NPC's (Important! 0 counts as well)
67
68
	// Experience increases during event(In current event map)
69
	.base_exp_multiplier = 3;   // Event base exp rating multiplier(In current event map)
70
	.job_exp_multiplier = 3;    // Event job exp rating multiplier(In current event map)
71
	.use_floating_rates = 0;    // Increase servers exp and drop rates for 1 hour after boss kill(0=Disable, 1=Enable)
72
73
	// Monsters default attributes
74
	.MOB_MAXHP = 100000000;     // How much HP can monster have at maximum
75
	.MOB_HP = 5000000;          // How much HP monster has on spawn
76
	.MOB_SPEED = 130;           // Speed
77
	.MOB_CRIT = 450;            // Crit rate (1000=100%)
78
	.MOB_HIT = 300;             // Hit rate
79
	.MOB_ATKMIN = 1000;         // Base Attack Minimum
80
	.MOB_ATKMAX = 4000;         // Base Attack Maximum
81
	.MOB_MATKMIN = 1000;        // Magic Attack Minimum
82
	.MOB_MATKMAX = 4000;        // Magic Attack Maximum
83
	.MOB_DEF = 35;              // Defence
84
	.MOB_MDEF = 35;             // Magic Defence
85
	.MOB_FLEE = 200;            // Flee rate
86
	.MOB_PDODGE = 60;           // Perfect Dodge
87
	.MOB_STR = 150;             // Stat strength
88
	.MOB_AGI = 150;             // Stat agility
89
	.MOB_VIT = 150;             // Stat vitality
90
	.MOB_INT = 150;             // Stat intellect
91
	.MOB_DEX = 150;             // Stat dexterity
92
	.MOB_LUK = 150;             // Stat luck
93
94
	// Floating monster HP
95
	// When player is detected near the mob, update it's HP.
96
	.use_radar = 1;             // 0=Disable, 1=Enable
97
98
	// Mapflags effects, monster status, party lock, etc.
99
	.use_mapflags = 1;          // 0=Disable, 1=Enable
100
101
	// Event monster ID's
102
	setarray .event_mobs[0],
103
		1093, // Eclipse
104
		1096, // Angeling
105
		1120, // Ghostring
106
		1388, // Archangeling
107
		1582, // Deviling
108
		1795; // Bloody Knight
109
110
	// Event reward ID's (One random array is selected)
111-
	// Event rewards <ID>,<Amount> (One random array is selected)
111+
	setarray .loots_0[0], 501, 502, 503, 504, 505, 506;
112-
	setarray .loots_0, 501,1, 502,1, 503,2, 504,2, 505,3, 506,3;
112+
	setarray .loots_1[0], 507, 508, 509, 510, 511, 512;
113-
	setarray .loots_1, 507,1, 508,1, 509,2, 510,2, 511,3, 512,3;
113+
	setarray .loots_2[0], 513, 514, 515, 516, 517, 518;
114-
	setarray .loots_2, 513,1, 514,1, 515,2, 516,2, 517,3, 518,3;
114+
	setarray .loots_3[0], 519, 520, 521, 522, 523, 525;
115-
	setarray .loots_3, 519,1, 520,1, 521,2, 522,2, 523,3, 525,3;
115+
116
	// Event reward ID's array size (Important!)
117
	// If you add new .loots_<Number> arrays. You must change this accordingly.
118
	.loots_count = 3;  // 0 count aswell
119
120
	// Event map names
121
	setarray .event_maps$[0],
122
		"prontera", "morocc", "geffen", "payon",
123
		"alberta", "aldebaran", "xmas", "comodo",
124
		"yuno", "amatsu", "gonryun", "umbala",
125
		"louyang", "ayothaya", "einbroch", "hugel",
126
		"rachel", "veins", "moscovia";
127
128
	// Event loot distribution mode description
129
	setarray .loot_mode_desc$[0],
130
		"Give all rewards to all party members",                          // .loot_mode = 0
131-
		"Give all rewards to all party members",                          // 0
131+
		"Give one reward to one random party member",                     // .loot_mode = 1
132-
		"Give one reward to one random party member",                     // 1
132+
		"Give all rewards to one random party member",                    // .loot_mode = 2
133-
		"Give all rewards to one random party member",                    // 2
133+
		"Give rewards randomly between all party members",                // .loot_mode = 3
134-
		"Give rewards randomly between all party members",                // 3
134+
		"Give all rewards to all nearby players and their party members", // .loot_mode = 4 (Skip UI)
135-
		"Give all rewards to all nearby players and their party members", // 4 (Skip UI)
135+
		"Give one reward to all nearby players and their party members",  // .loot_mode = 5 (Skip UI)
136-
		"Give one reward to all nearby players and their party members",  // 5 (Skip UI)
136+
		"Give all rewards to all nearby players",                         // .loot_mode = 6 (Skip UI)
137-
		"Give all rewards to all nearby players",                         // 6 (Skip UI)
137+
		"Give one reward to all nearby players",                          // .loot_mode = 7 (Skip UI)
138-
		"Give one reward to all nearby players",                          // 7 (Skip UI)
138+
		"Give all rewards to all players in the same map",                // .loot_mode = 8 (Skip UI)
139-
		"Give all rewards to all players in the same map",                // 8 (Skip UI)
139+
		"Give one reward to all players in the same map",                 // .loot_mode = 9 (Skip UI)
140-
		"Give one reward to all players in the same map",                 // 9 (Skip UI)
140+
		"Give all rewards to selected party member",                      // .loot_mode = 10
141-
		"Give all rewards to selected party member",                      // 10
141+
		"Give one random reward to selected party member";                // .loot_mode = 11
142-
		"Give one random reward to selected party member";                // 11
142+
143
	// TESTS
144
	// Log console information
145
	// This will report incorrect monster ID's on script load
146
	/*for( .@i = 0; .@i < getarraysize(.event_mobs); .@i++ ) {
147
		if( getmonsterinfo(.event_mobs[.@i], 0) == "null" ) {
148
			debugmes .npc_name$ + ":OnInit Monster ID:" + .event_mobs[.@i] + " DOES NOT EXIST!";
149
		}
150
	}*/
151
	// Start event on script load (For testing purposes)
152
	//donpcevent .npc_name$ + "::OnEnable";
153
	end;
154
155
OnEnable:
156
OnClock0402:
157
OnClock2359:
158
	// Check free event maps
159
	if ( getarraysize($@WB_MAP$) >= getarraysize(.event_maps$) ) {
160
		debugmes .npc_name$+"::OnEnable all event maps are active!";
161
		//announce "[World Boss] Event has been cancelled! All event maps are active!", BC_ALL, 0xFF0000;
162
		end;
163
	}
164
165
	// Select random monster
166
	.@rand_mob = rand( getarraysize( .event_mobs ) );
167
	.@monster_id = .event_mobs[ .@rand_mob ];
168
169
	// Select random map
170
	.@i = 0;
171
	.@rand_map = rand( getarraysize( .event_maps$ ) ); // Random map index number
172
	while(inarray($@WB_MAP$[0], .event_maps$[.@rand_map]) != -1) {
173
		if(.@i > .loop_max) {
174
			debugmes .npc_name$+"::OnEnable event map max loop count!";
175
			//announce "[World Boss] Event has been cancelled! Could not find free event map!", BC_ALL, 0xFF0000;
176
			end;
177
		}
178
		.@rand_map = rand( getarraysize( .event_maps$ ) );
179
		.@i++;
180
	}
181
	.@map_name$ = .event_maps$[ .@rand_map ];
182
183
	// Announce event will start soon
184
	announce "[World Boss] A rift on time and space is about to be opened! A World Boss will appear in "+(.event_sleep / 60000)+" minute! Prepare your Hunting Party!",BC_ALL,0xFF0000,FW_BOLD,18;
185
186
	// Sleep until X time have passed and then continue script
187
	sleep .event_sleep;
188
189
	// Get last event index
190
	.@index = getarraysize($@WB_MOB_GID);
191
192
	// Set mapflags if enabled
193
	if ( .use_mapflags ) {
194
		// Save event maps original mapflags
195
		setarray $@WB_MF_PARTYLOCK[.@index], getmapflag(.@map_name$, MF_PARTYLOCK);
196
		setarray $@WB_MF_NOMOBLOOT[.@index], getmapflag(.@map_name$, MF_NOMOBLOOT);
197
		setarray $@WB_MF_NOMVPLOOT[.@index], getmapflag(.@map_name$, MF_NOMVPLOOT);
198
		setarray $@WB_MF_NOPENALTY[.@index], getmapflag(.@map_name$, MF_NOPENALTY);
199
		setarray $@WB_MF_NOMOBTELE[.@index], getmapflag(.@map_name$, MF_MONSTER_NOTELEPORT);
200
		setarray $@WB_MF_BASEEXP[.@index], getmapflag(.@map_name$, MF_BEXP);
201
		setarray $@WB_MF_JOBEXP[.@index], getmapflag(.@map_name$, MF_JEXP);
202
		//setarray $@WB_MF_FOG[.@index], getmapflag(.@map_name$, MF_FOG);
203
204
		// Set new mapflags
205
		setmapflag .@map_name$, MF_PARTYLOCK; // Disable changing party(Inviting new players in event map)
206
		setmapflag .@map_name$, MF_NOMOBLOOT; // Disable Normal monster loot drops
207
		setmapflag .@map_name$, MF_NOMVPLOOT; // Disable Boss monster loot drops
208
		setmapflag .@map_name$, MF_NOPENALTY; // Disable Exp and Zeny penalty
209
		setmapflag .@map_name$, MF_MONSTER_NOTELEPORT; // Disable monster teleport
210
		setmapflag .@map_name$, MF_BEXP, ($@WB_MF_BASEEXP[.@index] * .base_exp_multiplier); // Set Base Exp rating
211
		setmapflag .@map_name$, MF_JEXP, ($@WB_MF_JOBEXP[.@index] * .job_exp_multiplier); // Set Job Exp rating
212
		//setmapflag .@map_name$, MF_FOG; // Enable FOG effect
213
	}
214
215
	// Summon event monster unit
216
	monster .@map_name$, 0, 0, "World Boss", .@monster_id, 1, .npc_name$+"::OnMobDie", Size_Large, AI_NONE;
217
	.@gid = $@mobid[0]; // Get monster's Game ID
218
219
	// Change unit data to defaults
220
	setunitdata .@gid, UMOB_MAXHP, .MOB_MAXHP;
221
	setunitdata .@gid, UMOB_HP, .MOB_HP;
222
	setunitdata .@gid, UMOB_SPEED, .MOB_SPEED;
223
	setunitdata .@gid, UMOB_CRIT, .MOB_CRIT;
224
	setunitdata .@gid, UMOB_HIT, .MOB_HIT;
225
	setunitdata .@gid, UMOB_ATKMIN, .MOB_ATKMIN;
226
	setunitdata .@gid, UMOB_ATKMAX, .MOB_ATKMAX;
227
	setunitdata .@gid, UMOB_MATKMIN, .MOB_MATKMIN;
228
	setunitdata .@gid, UMOB_MATKMAX, .MOB_MATKMAX;
229
	setunitdata .@gid, UMOB_DEF, .MOB_DEF;
230
	setunitdata .@gid, UMOB_MDEF, .MOB_MDEF;
231
	setunitdata .@gid, UMOB_FLEE, .MOB_FLEE;
232
	setunitdata .@gid, UMOB_PDODGE, .MOB_PDODGE;
233
	setunitdata .@gid, UMOB_STR, .MOB_STR;
234
	setunitdata .@gid, UMOB_AGI, .MOB_AGI;
235
	setunitdata .@gid, UMOB_VIT, .MOB_VIT;
236
	setunitdata .@gid, UMOB_INT, .MOB_INT;
237
	setunitdata .@gid, UMOB_DEX, .MOB_DEX;
238
	setunitdata .@gid, UMOB_LUK, .MOB_LUK;
239
240
	// Get units updated data
241
	getunitdata(.@gid, .@unit);
242
243
	// Save event arrays
244
	setarray $@WB_MOB_ID[.@index], .@monster_id;
245
	setarray $@WB_MOB_GID[.@index], .@gid;
246
	setarray $@WB_TIMEOUT[.@index], gettimetick(0);
247
	setarray $@WB_RADAR_NEAR[.@index], 0;
248
	setarray $@WB_MAP$[.@index], .@map_name$;
249
	setarray $@WB_X[.@index], .@unit[UMOB_X];
250
	setarray $@WB_Y[.@index], .@unit[UMOB_Y];
251
252
	// Unit talk
253
	unittalk .@gid, "Tremble before me mortals!", BC_AREA;
254
255
	// Announce event started
256
	announce "[World Boss] A "+ getunitname(.@gid) +" has appeared in "+ .@map_name$ +" to wreck havoc!! Form a Hunting Party and stop it!!",BC_ALL,0xFF0000,FW_BOLD,18;
257
258
	// Start unit radar
259
	if ( .use_radar && getarraysize($@WB_MOB_GID) ) {
260
		donpcevent "WorldBossRadar::OnEnable";
261
	}
262
263
	// Start timeout timer
264
	if ( !getnpctimer(1, "WorldBossTimeout") ) {
265
		donpcevent "WorldBossTimeout::OnEnable";
266
	}
267
	end;
268
269
// Disable event
270
OnDisable:
271
	//debugmes .npc_name$+"::OnDisable stop event!";
272
	// Stop timeout timer
273
	donpcevent "WorldBossTimeout::OnDisable";
274
275
	// Stop unit radar
276
	if ( .use_radar ) {
277
		donpcevent "WorldBossRadar::OnDisable";
278
	}
279
280
	// Reset server exp and drop rates
281
	if ( .use_floating_rates ) {
282
		donpcevent "WorldBossRates::OnDisable";
283
	}
284
285
	// Loop all events
286
	for ( .@i = 0; .@i < getarraysize($@WB_MOB_GID); .@i++ ) {
287
		// Kill all units
288
		if ( unitexists($@WB_MOB_GID[.@i]) ) {
289
			unitkill($@WB_MOB_GID[.@i]);
290
		}
291
292
		// Reset all mapflags to original values
293
		if ( .use_mapflags ) {
294
			callfunc("WB_ResetMapflags", $@WB_MAP$[.@i], .@i);
295
		}
296
	}
297
	// Kill all script or gm summoned monsters
298
	//killmonster .event_map$, "All";
299
300
	// Reset all event arrays
301
	callfunc("WB_ResetAllGlobals");
302
	end;
303
304
OnMobDie:
305
	// Event when monster has been killed
306
	// Stop unit radar and timeout if no unit is alive
307
	if ( !getarraysize($@WB_MOB_GID) ) {
308
		if ( .use_radar ) donpcevent "WorldBossRadar::OnDisable";
309
		donpcevent "WorldBossTimeout::OnDisable";
310
	}
311
312
	// Check attached unit
313
	.@unit_gid = getattachedrid();
314
	if ( !.@unit_gid ) {
315
		// No unit attached. Propably killed by unitkill or other script command
316
		//donpcevent .npc_name$+"::OnDisable";
317
		end;
318
	}
319
320
	// Get unit type
321
	.@unit_type = getunittype(.@unit_gid);
322
	if ( .@unit_type == -1 ) {
323
		debugmes .npc_name$+"::OnMobDie FATAL no unit type found!";
324
		donpcevent .npc_name$+"::OnDisable";
325
		end;
326
	}
327
328
	// Get map coordinates (Treasure Chest NPC will need these coordinates)
329
	getmapxy(.event_map$, .event_x, .event_y, .@unit_type);
330
331
	// Announce
332
	announce "[World Boss] The World Boss have been killed! Congratulations!", bc_all, 0xFF0000;
333
334
	// Increase server exp and drop rates for limited time
335
	if ( .use_floating_rates ) {
336
		donpcevent "WorldBossRates::OnEnable";
337
	}
338
339
	// Get index if map name are the same
340
	.@event_index = inarray($@WB_MAP$[0], .event_map$);
341
342
	// Check if index was found and stop if not
343
	if ( .@event_index == -1 ) {
344
		debugmes .npc_name$+"::OnMobDie event index was not found!";
345
		end;
346
	}
347
348
	// Reset mapflags to original values
349
	if ( .use_mapflags ) {
350
		callfunc("WB_ResetMapflags", $@WB_MAP$[.@event_index], .@event_index);
351
	}
352
353
	// If unit is not PC, try to attach unit master to the script
354
	if ( .@unit_type !=  UNITTYPE_PC ) {
355-
	if ( .@unit_type != BL_PC ) {
355+
356
		if (.@unit_type == UNITTYPE_NPC) {
357-
		if (.@unit_type == BL_NPC) {
357+
358
			debugmes .npc_name$+"::OnMobDie NPC no player attached!";
359
			end;
360
		}
361
		if (.@unit_type == UNITTYPE_PET) {
362-
		if (.@unit_type == BL_PET) {
362+
363
				debugmes .npc_name$+"::OnMobDie PET no player attached!";
364
				end;
365
			}
366
		}
367
		if (.@unit_type == UNITTYPE_MOB) {
368-
		if (.@unit_type == BL_MOB) {
368+
369
				debugmes .npc_name$+"::OnMobDie MOB no player attached!";
370
				end;
371
			}
372
		}
373
		if (.@unit_type == UNITTYPE_HOM) {
374-
		if (.@unit_type == BL_HOM) {
374+
375
			if (!attachrid(getcharid(3,.@name$))) {
376
				debugmes .npc_name$+"::OnMobDie HOM no player attached!";
377
				end;
378
			}
379
		}
380
		if (.@unit_type == UNITTYPE_MER) {
381-
		if (.@unit_type == BL_MER) {
381+
382
			if (!attachrid(getcharid(3,.@name$))) {
383
				debugmes .npc_name$+"::OnMobDie MER no player attached!";
384
				end;
385
			}
386
		}
387
		if (.@unit_type == UNITTYPE_ELEM) {
388-
		if (.@unit_type == BL_ELEM) {
388+
389
			if (!attachrid(getcharid(3,.@name$))) {
390
				debugmes .npc_name$+"::OnMobDie ELE no player attached!";
391
				end;
392
			}
393
		}
394
	}
395
396
	// Get party ID
397
	.@party_id = getcharid(1);
398
	// Save event arrays
399
	setarray $@WB_MAP$[.@event_index], .event_map$;
400
	setarray $@WB_X[.@event_index], .event_x;
401
	setarray $@WB_Y[.@event_index], .event_y;
402
	setarray $@WB_PARTY_ID[.@event_index], .@party_id;
403
	// Select random reward/loots array
404
	setarray $@WB_REWARD_INDEX[.@event_index], rand(0, .loots_count);
405
406
	// Enable first available Treasure Chest NPC
407
	// Set .event_map$, .event_x, .event_y before enabling ( Important! )
408
	for ( .@i = 0; .@i <= .duplicate_npc_count; .@i++ ) {
409
		.@npc$ = "Treasure Chest#wb_"+ .@i; // Name of the NPC
410
		if ( getnpcid(0, .@npc$) ) { // If NPC exists
411
			if ( !getnpctimer( 1, .@npc$ ) ) { // If has active timer=1
412
				setarray $@WB_NPC_NAME$[.@event_index], .@npc$;
413
				donpcevent .@npc$ +"::OnEnable";
414
				break;
415
			}
416
		} else {
417
			debugmes .npc_name$+"::OnMobDie no Treasure Chest#wb_"+.@i+" NPC found!";
418
		}
419
	}
420
421
	// Switch by loot mode and save character IDs for access
422
	switch( .loot_mode ) {
423
		case 0:
424
		case 1:
425
		case 2:
426
		case 3: // In same party or single player
427
		case 10: // All to selected party member
428
		case 11: // One random to selected party member
429
			// Attach all available party members
430
			if ( getcharid(1) ) {
431
				addrid(2, 0, getcharid(1));
432
			}
433
			break;
434
435
		case 4:
436
		case 5: // In range and party
437
			// Attach all available players in 20 cells from the killer RID
438
			addrid(4, 0, (.event_x - 20),(.event_y - 20), (.event_x + 20),(.event_y + 20));
439
440
			// Attach all available party members
441
			if ( getcharid(1) ) {
442
				addrid(2, 0, getcharid(1));
443
			}
444
			break;
445
446
		case 6:
447
		case 7: // In range
448
			// Attach all available players in 20 cells from the killer RID
449
			addrid(4, 0, (.event_x - 20),(.event_y - 20), (.event_x + 20),(.event_y + 20));
450
			break;
451
452
		case 8:
453
		case 9: // In the same map
454
			addrid(1, 0, getcharid(1));
455
			break;
456
	}
457
458
	// Find matching character IDs from the access array
459
	.@access_index = inarray($@WB_ACCESS[0], getcharid(0));
460
461
	// Exit if character already has access
462
	if ( .@access_index != -1 ) {
463
		end;
464
	}
465
466
	// Save character ID into access array
467
	setarray $@WB_ACCESS[getarraysize($@WB_ACCESS)], getcharid(0);
468
	setarray $@WB_ACCESS_EXPIRE[getarraysize($@WB_ACCESS_EXPIRE)], gettimetick(0);
469
	
470
	// Start access expire timer if not already running
471
	if ( !getnpctimer(1, "WorldBossAccessExpire") ) {
472
		donpcevent "WorldBossAccessExpire::OnEnable";
473
	}
474
	end;
475
476
// Event when player opens Treasure Chest NPC
477
OnTreasureOpen:
478
	// Get map coordinates of the player
479
	getmapxy(.@event_map$, .@x, .@y, UNITTYPE_PC);
480-
	getmapxy(.@event_map$, .@x, .@y, BL_PC);
480+
481
	// Search for character ID from the access array
482
	.@access_index = inarray($@WB_ACCESS[0], getcharid(0));
483
484
	// User has no access!
485
	if ( .@access_index == -1 ) {
486
		message strcharinfo(0), "Treasure Chest is empty.";
487
		end;
488
	}
489
490
	// Get event index from the map name array
491
	.@event_index = inarray($@WB_MAP$[0], .@event_map$);
492
493
	// Check if event index was found
494
	if ( .@event_index == -1 ) {
495
		debugmes .@name$+"::OnTreasureOpen event map name ( "+ .@event_map$ +" ) not found!";
496
		message strcharinfo(0), "Treasure Chest is empty.";
497
		end;
498
	}
499
500
	// Select reward array
501
	.@rand_reward = $@WB_REWARD_INDEX[.@event_index];
502
	.@reward_size = getarraysize( getd(".loots_" + .@rand_reward) );
503-
	.@loots_size = getarraysize( getd(".loots_" + .@rand_reward) );
503+
	copyarray .@rewards[0], getd(".loots_" + .@rand_reward + "[0]"), .@reward_size;
504-
	//copyarray .@rewards_id[0], getd(".loots_" + .@rand_reward + "[0]"), .@loots_size; // .loots_0
504+
505
	switch( .loot_mode ) {
506-
	// Rewards array
506+
507-
	// Get every second value from array.
507+
508
		case 3: // Randomly to all members
509-
	for( .@j = 0; .@j < .@loots_size; .@j += 2 ) {
509+
510-
		setarray .@rewards_id[.@i], getd(".loots_" + .@rand_reward + "[" + .@j + "]");
510+
511
			if ( getcharid(1) ) {
512
				goto OnPartyLeader;
513-
	.@reward_size = getarraysize( .@rewards_id );
513+
514-
	// Amounts array
514+
515-
	// Get every second value from array.
515+
516
					getitem .@rewards[.@i], 1;
517-
	for( .@j = 1; .@j < .@loots_size; .@j += 2 ) {
517+
518-
		setarray .@rewards_amount[.@i], getd(".loots_" + .@rand_reward + "[" + .@j + "]");
518+
519
			break;
520
521
		case 1: // One to random member
522
			if ( getcharid(1) ) {
523
				// Party Leader will distribute loots
524
				goto OnPartyLeader;
525
			} else {
526
				// Has no party
527
				getitem .@rewards[rand(.@reward_size)], 1;
528
			}
529
			break;
530
531
		case 4: // All in range and party
532
		case 6: // All in range
533-
					getitem .@rewards_id[.@i], .@rewards_amount[.@i];
533+
534
		default:
535
			// No UI
536
			for( .@i = 0; .@i < .@reward_size; .@i++ ) {
537
				getitem .@rewards[.@i], 1;
538
			}
539
			break;
540
541
		case 5: // One in range and party
542
		case 7: // One in range
543
		case 9: // One in same map
544-
				.@rand = rand(.@reward_size);
544+
545-
				getitem .@rewards_id[.@rand], .@rewards_amount[.@rand];
545+
			getitem .@rewards[rand(.@reward_size)], 1;
546
			break;
547
	}
548
549
	// Remove character ID from the access array (Access is now used)
550
	deletearray $@WB_ACCESS[.@access_index], 1;
551
	deletearray $@WB_ACCESS_EXPIRE[.@access_index], 1;
552
553
	// Announce player
554
	message strcharinfo(0), "Congratulations! You have been rewarded for killing the World Boss.";
555-
				getitem .@rewards_id[.@i], .@rewards_amount[.@i];
555+
556
	// Disable current NPC Treasure Chest
557
	if ( !getarraysize($@WB_ACCESS) ) {
558
		// Disable current NPC Treasure Chest
559
		callfunc("WB_ResetBox", .@event_index);
560
		// Stop access expire timer
561
		donpcevent "WorldBossAccessExpire::OnDisable";
562
	}
563-
			.@rand = rand(.@reward_size);
563+
564-
			getitem .@rewards_id[.@rand], .@rewards_amount[.@rand];
564+
565
OnPartyLeader:
566
	// Get party ID
567
	.@party_id = getcharid(1);
568
569
	// Check if player is party leader
570
	if ( getcharid(0) != getpartyleader( .@party_id, 2 ) ) {
571
		message strcharinfo(0), "You're not Party Leader.";
572
		end;
573
	}
574
575
	// Get event index from the party ID array
576
	.@event_index = inarray($@WB_PARTY_ID[0], .@party_id );
577
578
	// Check if party id has access!
579
	if ( .@event_index == -1 ) {
580
		message strcharinfo(0), "Treasure Chest is empty.";
581
		end;
582
	}
583
584
	// Select random reward array
585
	.@rand_reward = $@WB_REWARD_INDEX[.@event_index];
586
	.@reward_size = getarraysize(getd(".loots_" + .@rand_reward));
587
	copyarray .@rewards[0], getd(".loots_" + .@rand_reward + "[0]"), .@reward_size;
588
589
	// Show loot distribution window
590
	mes "[ Loot Distributor ]";
591
	mes "Please ensure you distribute the Rewards. If you cancelled this, your party might not able to receive any rewards.";
592
	mes "^777777Loot mode : ^000000" + .loot_mode_desc$[.loot_mode]; // Loot mode description
593
	next;
594
	mes "[ Loot Distributor ]";
595
	for( .@i = 0; .@i < .@reward_size; .@i++ ) {
596
		mes "^777777 ~ " + getitemname( .@rewards[.@i] ) + "^000000";
597
	}
598
	next;
599
	if( select( "Distribute Loots", "Dispose Loots" ) == 1 ) {
600
		// Get party data
601
		getpartymember .@party_id, 0; // Name
602
		getpartymember .@party_id, 1; // Character IDs
603
		getpartymember .@party_id, 2; // Account IDs
604
605-
	.@loots_size = getarraysize(getd(".loots_" + .@rand_reward));
605+
606-
	//copyarray .@rewards_id[0], getd(".loots_" + .@rand_reward + "[0]"), .@loots_size; // .loots_0_id
606+
607
		copyarray .@party_cid[0], $@partymembercid[0], .@party_size;
608-
	// Rewards array
608+
609-
	// Get every second value from array.
609+
610
611-
	for( .@j = 0; .@j < .@loots_size; .@j += 2 ) {
611+
612-
		setarray .@rewards_id[.@i], getd(".loots_" + .@rand_reward + "[" + .@j + "]");
612+
613
			mes "[ Loot Distributor ]";
614
			// Loop through each party member
615-
	.@reward_size = getarraysize( .@rewards_id );
615+
616-
	// Amounts array
616+
617-
	// Get every second value from array.
617+
618
					mes " ~ " + strcharinfo(0, .@party_cid[.@idx]) + " was rewarded!";
619-
	for( .@j = 1; .@j < .@loots_size; .@j += 2 ) {
619+
620-
		setarray .@rewards_amount[.@i], getd(".loots_" + .@rand_reward + "[" + .@j + "]");
620+
621
						getitem .@rewards[.@i], 1, .@party_aid[.@idx];
622
					}
623
				}
624
			}
625
		}
626
627
		// LOOT MODE 1: Give one reward to one random party member
628
		else if( .loot_mode == 1 ) {
629
			// Select random party member X times.
630
			SelectRandom1:
631-
		mes "^777777 ~ " + .@rewards_amount[.@i] + " x " + getitemname( .@rewards_id[.@i] ) + "^000000";
631+
632
			.@rand_party = rand(.@party_size);
633
			while( !isloggedin(.@party_aid[.@rand_party], .@party_cid[.@rand_party]) ) {
634
				if( .@attempts >= .loop_max ) break;
635
				.@rand_party = rand(.@party_size);
636
				.@attempts++;
637
			}
638
			// Max attempts reached					
639
			if( .@attempts >= .loop_max ) {
640
				mes "[ Player not found ]";
641
				mes "Tried to select random player " + .@attempts + " times!";
642
				mes "Do you want to try again?";
643
				next;
644
				if( select("Yes:No") == 1 ) {
645
					goto SelectRandom1;
646
				} else {
647
					goto OnClose;
648
				}
649
			}
650
			// Backup online check (next; will pause script and players can disconnect)
651
			if( !isloggedin(.@party_aid[.@rand_party], .@party_cid[.@rand_party]) ) {
652
				mes "[ Player not online ]";
653
				mes "Member is ^777777offline^000000";
654
				mes "Do you want to try again?";
655
				next;
656-
						getitem .@rewards_id[.@i], .@rewards_amount[.@i], .@party_aid[.@idx];
656+
657
					goto SelectRandom1;
658
				} else {
659
					goto OnClose;
660
				}
661
			}
662
			// Give random reward
663
			.@rand_item = rand(.@reward_size);
664
			.@name$ = strcharinfo(0, .@party_cid[.@rand_party]);
665
			mes "[ Loot Distributor ]";
666
			mes .@name$ + "^777777 ~ " + getitemname( .@rewards[.@rand_item] ) + "^000000";
667
			message .@name$, "Gained " + getitemname( .@rewards[.@rand_item] ) + " ( Distributed Randomly )";
668
			getitem .@rewards[.@rand_item], 1, .@party_aid[.@rand_party];
669
		}
670
671
		// LOOT MODE 2: Give all rewards to one random party member
672
		else if( .loot_mode == 2 ) {
673
			// Select random party member X times.
674
			SelectRandom2:
675
			.@attempts = 0; // Counter for random player select
676
			.@rand_party = rand(.@party_size);
677
			while( !isloggedin(.@party_aid[.@rand_party], .@party_cid[.@rand_party]) ) {
678
				if( .@attempts >= .loop_max ) break;
679
				.@rand_party = rand(.@party_size);
680
				.@attempts++;
681
			}
682
			// Max attempts reached					
683
			if( .@attempts >= .loop_max ) {
684
				mes "[ Player not found ]";
685
				mes "Tried to select random player " + .@attempts + " times!";
686
				mes "Do you want to try again?";
687
				next;
688
				if( select("Yes:No") == 1 ) {
689
					goto SelectRandom2;
690
				} else {
691
					goto OnClose;
692
				}
693
			}
694
			// Backup online check (next; will pause script and players can disconnect)
695
			if( !isloggedin(.@party_aid[.@rand_party], .@party_cid[.@rand_party]) ) {
696
				mes "[ Player not online ]";
697
				mes "Member is ^777777offline^000000";
698
				mes "Do you want to try again?";
699
				next;
700
				if( select("Yes:No") == 1 ) {
701-
			mes .@name$ + "^777777 ~ " + .@rewards_amount[.@rand_item] + " x " + getitemname( .@rewards_id[.@rand_item] ) + "^000000";
701+
702-
			message .@name$, "Gained " + .@rewards_amount[.@rand_item] + " x " + getitemname( .@rewards_id[.@rand_item] ) + " ( Distributed Randomly )";
702+
703-
			getitem .@rewards_id[.@rand_item], .@rewards_amount[.@rand_item], .@party_aid[.@rand_party];
703+
704
				}
705
			}
706
			// Give rewards
707
			.@name$ = strcharinfo(0, .@party_cid[.@rand_party]);
708
			mes "[ Loot Distributor ]";
709
			// Loop through each reward
710
			for( .@i = 0; .@i < .@reward_size; .@i++ ) {
711
				mes .@name$ + "^777777 ~ " + getitemname( .@rewards[.@i] ) + "^000000";
712
				message .@name$, "Gained " + getitemname( .@rewards[.@i] ) + " ( Distributed Randomly )";
713
				getitem .@rewards[.@i], 1, .@party_aid[.@rand_party];
714
			}
715
		}
716
717
		// LOOT MODE 3: Give rewards randomly between all party members
718
		else if( .loot_mode == 3 ) {
719
			mes "[ Loot Distributor ]";
720
			// Loop through each reward
721
			for( .@i = 0; .@i < .@reward_size; .@i++ ) {
722
				// Select random party member X times.
723
				SelectRandom3:
724
				.@attempts = 0; // Counter for random player select
725
				.@rand_party = rand(.@party_size);
726
				while( !isloggedin(.@party_aid[.@rand_party], .@party_cid[.@rand_party]) ) {
727
					if( .@attempts >= .loop_max ) break;
728
					.@rand_party = rand(.@party_size);
729
					.@attempts++;
730
				}
731
				// Max attempts reached					
732
				if( .@attempts >= .loop_max ) {
733
					mes "[ Player not found ]";
734
					mes "Tried to select random player " + .@attempts + " times!";
735
					mes "Do you want to try again?";
736
					next;
737
					if( select("Yes:No") == 1 ) {
738
						goto SelectRandom3;
739
					} else {
740
						goto OnClose;
741
					}
742
				}
743
				// Backup online check (next; will pause script and players can disconnect)
744
				if( !isloggedin(.@party_aid[.@rand_party], .@party_cid[.@rand_party]) ) {
745
					mes "[ Player not online ]";
746-
				mes .@name$ + "^777777 ~ " + .@rewards_amount[.@i] + " x " + getitemname( .@rewards_id[.@i] ) + "^000000";
746+
747-
				message .@name$, "Gained " + .@rewards_amount[.@i] + " x " + getitemname( .@rewards_id[.@i] ) + " ( Distributed Randomly )";
747+
748-
				getitem .@rewards_id[.@i], .@rewards_amount[.@i], .@party_aid[.@rand_party];
748+
749
					if( select("Yes:No") == 1 ) {
750
						goto SelectRandom3;
751
					} else {
752
						goto OnClose;
753
					}
754
				}
755
				// Give single reward
756
				.@name$ = strcharinfo(0, .@party_cid[.@rand_party]);
757
				mes .@name$ + "^777777 ~ " + getitemname( .@rewards[.@i] ) + "^000000";
758
				message .@name$, "Gained " + getitemname( .@rewards[.@i] ) + " ( Distributed Randomly )";
759
				getitem .@rewards[.@i], 1, .@party_aid[.@rand_party];
760
			}
761
		}
762
763
		// LOOT MODE 10: Give all rewards to selected party member
764
		// LOOT MODE 11: Give one reward to selected party member
765
		else if( .loot_mode >= 10 && .loot_mode <= 11 ) {
766
			SelectMember:
767
			// Open Party Select Menu
768
			.@select = callfunc("WB_PartySelect", 1, 1);
769
770
			// Refresh selected
771
			while ( .@select == -1 ) {
772
				message strcharinfo(0), "Refresh menu!";
773
				.@select = callfunc("WB_PartySelect", 1, 1);
774
			}
775
776
			// Not in a party (Leaved before select or removed)
777
			if ( .@select == -2 ) {
778
				message strcharinfo(0), "You don't have a party.";
779
				end;
780
			}
781
782
			// Is selected member online
783
			if ( !isloggedin(.@party_aid[.@select], .@party_cid[.@select]) ) {
784
				mes "[ Loot Distributor ]";
785
				mes "Selected party member is not online.";
786
				mes "Please select again.";
787
				next;
788
				goto SelectMember;
789
			}
790
791
			// Get more party data
792-
				mes .@name$ + "^777777 ~ " + .@rewards_amount[.@i] + " x " + getitemname( .@rewards_id[.@i] ) + "^000000";
792+
793-
				message .@name$, "Gained " + .@rewards_amount[.@i] + " x " + getitemname( .@rewards_id[.@i] ) + " ( Distributed Randomly )";
793+
794-
				getitem .@rewards_id[.@i], .@rewards_amount[.@i], .@party_aid[.@rand_party];
794+
795
			.@party_leader_name$ = "[Offline]";
796
			if ( .@party_leader_cid != -1 ) {
797
				// strcharinfo(0,.@party_leader_cid); will fail if leader is offline!
798
				for (.@i = 0; .@i < .@party_size; .@i++ ) {
799
					// Match leader cid with party member cid
800
					if ( .@party_leader_cid == .@party_member_cid[.@i] ) {
801
						.@party_leader_name$ = .@party_member_name$[.@i];
802
					}
803
				}
804
			}
805
806
			// Double check
807
			// Check for party changes, because players can leave anytime.
808
			.@party_id2 = getcharid(1);
809
			.@check_failed = false;
810
811
			// Not in a party anymore (Leaved after select or removed)
812
			if ( !.@party_id2 ) {
813
				message strcharinfo(0), "You don't have a party.";
814
				mes "[ Loot Distributor ]";
815
				mes "Your party has made changes during selection.";
816
				mes "Please select again.";
817
				close;
818
			}
819
			
820
			// Check if party ID has changed
821
			if (.@party_id != .@party_id2) {
822
				message strcharinfo(0), "Failed: Party ID has changed!";
823
				mes "[ Loot Distributor ]";
824
				mes "Your party has made changes during selection.";
825
				mes "Please select again.";
826
				close;
827
			}
828
829
			// Get new party data
830
			getpartymember .@party_id2, 0; // names
831
			.@new_party_size = $@partymembercount;
832
			copyarray .@partymembername$[0], $@partymembername$[0], .@new_party_size;
833
834
			// Check if party size has changed during select.
835
			if (.@new_party_size != .@party_size) {
836
				message strcharinfo(0), "Failed: Party size has changed!";
837
				mes "[ Loot Distributor ]";
838
				mes "Your party has made changes during selection.";
839
				mes "Please select again.";
840
				close;
841
			}
842
843
			// Check if party member names has changed during select.
844
			for (.@i = 0; .@i < .@party_size; .@i++ ) {
845
				// Match new and old name
846
				if ( .@partymembername$[.@i] != .@party_member_name$[.@i] ) {
847
					.@check_failed = true;
848
					message strcharinfo(0), "Failed: Party member name has changed!";
849
					break;
850
				}
851
			}
852
853
			// Has any checks failed
854
			if ( .@i >= .@party_size && .@check_failed ) {
855
				mes "[ Loot Distributor ]";
856
				mes "Your party has made changes during selection.";
857
				mes "Please select again.";
858
				close;
859
			}
860
861
			// Success; Give rewards
862
			if (.loot_mode == 10) {
863
				// All rewards to selected member
864
				.@name$ = strcharinfo(0, .@party_cid[.@select]);
865
				mes "[ Loot Distributor ]";
866
				// Loop through each reward
867
				for( .@i = 0; .@i < .@reward_size; .@i++ ) {
868
					mes .@name$ + "^777777 ~ " + getitemname( .@rewards[.@i] ) + "^000000";
869
					message .@name$, "Gained " + getitemname( .@rewards[.@i] ) + " ( Distributed Randomly )";
870
					getitem .@rewards[.@i], 1, .@party_aid[.@select];
871
				}
872
			}
873
			else if (.loot_mode == 11) {
874
				// Give one random reward to selected member
875
				.@rand_item = rand(.@reward_size);
876
				.@name$ = strcharinfo(0, .@party_cid[.@select]);
877
				mes "[ Loot Distributor ]";
878
				mes .@name$ + "^777777 ~ " + getitemname( .@rewards[.@rand_item] ) + "^000000";
879
				message .@name$, "Gained " + getitemname( .@rewards[.@rand_item] ) + " ( Distributed Randomly )";
880
				getitem .@rewards[.@rand_item], 1, .@party_aid[.@select];
881
			}
882
		}
883
	} else {
884
		// Disposed loots
885
		mes "[ Loot Distributor ]";
886
	}
887
	mes "Congratulations!";
888
	// Remove all party members access
889
	callfunc("WB_ResetPartyAccess", .@party_id);
890
	close2;
891
	// Disable current NPC Treasure Chest
892
	callfunc("WB_ResetBox", .@event_index);
893
	end;
894
895
OnClose:
896
	// Close reward window
897
	mes "[ Loot Distributor ]";
898
	mes "Good bye.";
899
	close;
900
}
901
902
// Function: Reset all party members access IDs
903-
					mes .@name$ + "^777777 ~ " + .@rewards_amount[.@i] + " x " + getitemname( .@rewards_id[.@i] ) + "^000000";
903+
904-
					message .@name$, "Gained " + .@rewards_amount[.@i] + " x " + getitemname( .@rewards_id[.@i] ) + " ( Distributed Randomly )";
904+
905-
					getitem .@rewards_id[.@i], .@rewards_amount[.@i], .@party_aid[.@select];
905+
906
	getpartymember .@party_id, 1; // Character IDs
907
	.@party_size = $@partymembercount;
908
	copyarray .@party_cid[0], $@partymembercid[0], .@party_size;
909
	for ( .@i = 0; .@i < .@party_size; .@i++ ) {
910
		for ( .@j = 0; .@j < getarraysize($@WB_ACCESS); .@j++ ) {
911
			if ( $@WB_ACCESS[.@j] == .@party_cid[.@i] ) {
912
				deletearray $@WB_ACCESS[.@j], 1;
913-
				mes .@name$ + "^777777 ~ " + .@rewards_amount[.@rand_item] + " x " + getitemname( .@rewards_id[.@rand_item] ) + "^000000";
913+
914-
				message .@name$, "Gained " + .@rewards_amount[.@rand_item] + " x " + getitemname( .@rewards_id[.@rand_item] ) + " ( Distributed Randomly )";
914+
915-
				getitem .@rewards_id[.@rand_item], .@rewards_amount[.@rand_item], .@party_aid[.@select];
915+
916
	}
917
	// Remove party id
918
	/*for ( .@i = 0; .@i < getarraysize($@WB_PARTY_ID); .@i++ ) {
919
		if ( $@WB_PARTY_ID[.@i] == .@party_id ) {
920
			deletearray $@WB_PARTY_ID[.@i], 1;
921
		}
922
	}*/
923
	return;
924
}
925
926
// Function: Reset specific WorldBoss event global arrays
927
// callfunc("WB_ResetEventGlobals", <index>)
928
function	script	WB_ResetEventGlobals	{
929
	.@index = getarg(0, 0); // Event index Default=0
930
	deletearray $@WB_MOB_ID[.@index], 1;   // Rename from $@WB_ID
931
	deletearray $@WB_MOB_GID[.@index], 1;  // Rename from $@WB_GID
932
	deletearray $@WB_TIMEOUT[.@index], 1;
933
	deletearray $@WB_RADAR_NEAR[.@index], 1; // Rename from $@WB_NEAR
934
	deletearray $@WB_MAP$[.@index], 1;
935
	deletearray $@WB_X[.@index], 1;
936
	deletearray $@WB_Y[.@index], 1;
937
	deletearray $@WB_REWARD_INDEX[.@index], 1; // Rename from $@WB_REWARD
938
	deletearray $@WB_PARTY_ID[.@index], 1; // Rename from $@WB_PARTY
939
	deletearray $@WB_NPC_NAME$[.@index], 1; // Rename from $@WB_BOX
940
	//deletearray $@WB_ACCESS[.@index], 1;
941
	//deletearray $@WB_ACCESS_EXPIRE[.@index], 1;
942
	deletearray $@WB_MF_PARTYLOCK[.@index], 1;
943
	deletearray $@WB_MF_NOMOBLOOT[.@index], 1;
944
	deletearray $@WB_MF_NOMVPLOOT[.@index], 1;
945
	deletearray $@WB_MF_NOPENALTY[.@index], 1;
946
	deletearray $@WB_MF_NOMOBTELE[.@index], 1;
947
	deletearray $@WB_MF_BASEEXP[.@index], 1;
948
	deletearray $@WB_MF_JOBEXP[.@index], 1;
949
	//deletearray $@WB_MF_FOG[.@index], 1;
950
	return;
951
}
952
953
// Function: Reset all WorldBoss event global arrays
954
// callfunc("WB_ResetAllGlobals")
955
function	script	WB_ResetAllGlobals	{
956
	deletearray $@WB_MOB_ID[0], getarraysize($@WB_MOB_ID);
957
	deletearray $@WB_MOB_GID[0], getarraysize($@WB_MOB_GID);
958
	deletearray $@WB_TIMEOUT[0], getarraysize($@WB_TIMEOUT);
959
	deletearray $@WB_RADAR_NEAR[0], getarraysize($@WB_RADAR_NEAR);
960
	deletearray $@WB_MAP$[0], getarraysize($@WB_MAP$);
961
	deletearray $@WB_X[0], getarraysize($@WB_X);
962
	deletearray $@WB_Y[0], getarraysize($@WB_Y);
963
	deletearray $@WB_REWARD_INDEX[0], getarraysize($@WB_REWARD_INDEX);
964
	deletearray $@WB_PARTY_ID[0], getarraysize($@WB_PARTY_ID);
965
	deletearray $@WB_NPC_NAME$[0], getarraysize($@WB_NPC_NAME$);
966
	deletearray $@WB_ACCESS[0], getarraysize($@WB_ACCESS);
967
	deletearray $@WB_ACCESS_EXPIRE[0], getarraysize($@WB_ACCESS_EXPIRE);
968
	deletearray $@WB_MF_PARTYLOCK[0], getarraysize($@WB_MF_PARTYLOCK);
969
	deletearray $@WB_MF_NOMOBLOOT[0], getarraysize($@WB_MF_NOMOBLOOT);
970
	deletearray $@WB_MF_NOMVPLOOT[0], getarraysize($@WB_MF_NOMVPLOOT);
971
	deletearray $@WB_MF_NOPENALTY[0], getarraysize($@WB_MF_NOPENALTY);
972
	deletearray $@WB_MF_NOMOBTELE[0], getarraysize($@WB_MF_NOMOBTELE);
973
	deletearray $@WB_MF_BASEEXP[0], getarraysize($@WB_MF_BASEEXP);
974
	deletearray $@WB_MF_JOBEXP[0], getarraysize($@WB_MF_JOBEXP);
975
	//deletearray $@WB_MF_FOG[0], getarraysize($@WB_MF_FOG);
976
	return;
977
}
978
979
// Function: Reset all mapflags to original values
980
// callfunc("WB_ResetMapflags", <map name>, <index>)
981
function	script	WB_ResetMapflags	{
982
	.@map$ = getarg(0, "null"); // Map name Default="null"
983
	.@index = getarg(1, 0); // Event index Default=0
984
	// Map name exists
985
	if (.@map$ == "" || .@map$ == "null") {
986
		debugmes "WB_ResetMapflags was given:"+ .@map$;
987
		return;
988
	}
989
	// Party Lock
990
	if ( $@WB_MF_PARTYLOCK[.@index] )
991
		setmapflag .@map$, MF_PARTYLOCK;
992
	else
993
		removemapflag .@map$, MF_PARTYLOCK;
994
	// No mob loot
995
	if ( $@WB_MF_NOMOBLOOT[.@index] )
996
		setmapflag .@map$, MF_NOMOBLOOT;
997
	else
998
		removemapflag .@map$, MF_NOMOBLOOT;
999
	// No MVP loot
1000
	if ( $@WB_MF_NOMVPLOOT[.@index] )
1001
		setmapflag .@map$, MF_NOMVPLOOT;
1002
	else
1003
		removemapflag .@map$, MF_NOMVPLOOT;
1004
	// No penalty
1005
	if ( $@WB_MF_NOPENALTY[.@index] )
1006
		setmapflag .@map$, MF_NOPENALTY;
1007
	else
1008
		removemapflag .@map$, MF_NOPENALTY;
1009
	// No mob teleport
1010
	if ( $@WB_MF_NOMOBTELE[.@index] )
1011
		setmapflag .@map$, MF_MONSTER_NOTELEPORT;
1012
	else
1013
		removemapflag .@map$, MF_MONSTER_NOTELEPORT;
1014
	// Base Exp
1015
	setmapflag .@map$, MF_BEXP, $@WB_MF_BASEEXP[.@index];
1016
	// Job Exp
1017
	setmapflag .@map$, MF_JEXP, $@WB_MF_JOBEXP[.@index];
1018
	// Effect FOG
1019
	//if ( $@WB_MF_FOG[.@index] )
1020
	//	setmapflag .@map$, MF_FOG;
1021
	//else
1022
	//	removemapflag .@map$, MF_FOG;
1023
	return;
1024
}
1025
1026
// Function: Reset specific Treasure Chest NPC
1027
// callfunc("WB_ResetBox", <index>)
1028
function	script	WB_ResetBox	{
1029
	.@index = getarg(0, 0); // Event index Default=0
1030
	if ( $@WB_NPC_NAME$[.@index] != "" ) {
1031
		if ( getnpcid(0, $@WB_NPC_NAME$[.@index]) ) {
1032
			// Do these checks or this will select all NPCs on the server when fail
1033
			donpcevent $@WB_NPC_NAME$[.@index]+"::OnDisable";
1034
		}
1035
	}
1036
}
1037
1038
// Function: Reset all Treasure Chest NPC's
1039
// callfunc("WB_ResetAllBoxes")
1040
function	script	WB_ResetAllBoxes	{
1041
	for ( .@i = 0; .@i < getarraysize($@WB_NPC_NAME$); .@i++ ) {
1042
		if ( $@WB_NPC_NAME$[.@i] != "" ) {
1043
			if ( getnpcid(0, $@WB_NPC_NAME$[.@i]) ) {
1044
				// Do these checks or this will select all NPCs on the server when fail
1045
				donpcevent $@WB_NPC_NAME$[.@i]+"::OnDisable";
1046
			}
1047
		}
1048
	}
1049
}
1050
1051
// Function Party Select
1052
// callfunc("WB_PartySelect", <INT_show_offline>, <INT_show_refresh>)
1053
// Return INT=Party index number, -1=Refresh selected, -2=Not in party
1054
function	script	WB_PartySelect	{
1055
	.@s_offline = getarg(0, 1); // Show offline players in menu? 1=Yes 0=No
1056
	.@s_refresh = getarg(1, 1); // Show refresh menu item? 1=Yes 0=No
1057
	.@party_id = getcharid(1);  // Party ID
1058
 
1059
	// Not in a party
1060
	if ( !.@party_id )
1061
		return -2;
1062
 
1063
	getpartymember .@party_id, 0; // Names
1064
	getpartymember .@party_id, 1; // Character IDs
1065
	getpartymember .@party_id, 2; // Account IDs
1066
 
1067
	// Copy the temporary party data
1068
	.@party_size = $@partymembercount;
1069
	copyarray .@party_member_name$[0], $@partymembername$[0], .@party_size;
1070
	copyarray .@party_member_cid[0], $@partymembercid[0], .@party_size;
1071
	copyarray .@party_member_aid[0], $@partymemberaid[0], .@party_size;
1072
 
1073
	// Create menu
1074
	if ( .@s_refresh )
1075
		.@menu_party$ = "^777777[Refresh]^000000";
1076
	.@menu_party$ = .@menu_party$ + ":";
1077
 
1078
	// Loop through each party member and add to menu
1079
	for ( .@i = 0; .@i < .@party_size; .@i++ ) {
1080
		if ( isloggedin(.@party_member_aid[.@i], .@party_member_cid[.@i]) ) {
1081
			if (.@s_offline)
1082
				.@menu_party$ = .@menu_party$ + .@party_member_name$[.@i] + " ^00cc36[ON]^000000";
1083
			else
1084
				.@menu_party$ = .@menu_party$ + .@party_member_name$[.@i];
1085
		} else if (.@s_offline)
1086
			.@menu_party$ = .@menu_party$ + .@party_member_name$[.@i] + " ^777777[OFF]^000000";
1087
		.@menu_party$ = .@menu_party$ + ":";
1088
	}
1089
 
1090
	// Open select menu (-2 select start from 1 and we have [Refresh] at first)
1091
	.@select = select(.@menu_party$) - 2;
1092
	return .@select;
1093
}
1094
1095
// Treasure chest NPC
1096
alberta,0,0,5	script	Treasure Chest#wb_0	1324,{
1097
	emotion ET_SURPRISE, getcharid(3); // Emotion on the player
1098
	// Disable current NPC Treasure Chest if empty
1099
	if ( !getarraysize($@WB_ACCESS) ) {
1100
		message strcharinfo(0), "Treasure Chest is empty.";
1101
		donpcevent strnpcinfo(0)+"::OnDisable";
1102
		// Stop access expire timer
1103
		donpcevent "WorldBossAccessExpire::OnDisable";
1104
		end;
1105
	}
1106
	doevent "WorldBoss::OnTreasureOpen";
1107
	end;
1108
1109
OnInit:
1110
	.@name$ = strnpcinfo(0); //rid2name( .@id );
1111
	.@timer = getnpctimer(1, .@name$);
1112
	getmapxy(.map$, .x, .y, UNITTYPE_NPC);
1113
	disablenpc .@name$;
1114
	//debugmes .@name$+"::OnInit target=" + .map$ + " NPC="+ .@name$ + " timer="+ .@timer;
1115
	end;
1116
1117
OnEnable:
1118
	// if enabled getnpctimer(1, strnpcinfo(0)) will return 1
1119
	.@id = getnpcid(0);
1120
	.@name$ = strnpcinfo(0); //rid2name( .@id );
1121
	.@timer = getnpctimer(1, .@name$);
1122
1123
	.@npc$ = "WorldBoss";
1124
	.@map$ = getvariableofnpc(.event_map$, .@npc$);
1125
	.@x = getvariableofnpc(.event_x, .@npc$);
1126
	.@y = getvariableofnpc(.event_y, .@npc$);
1127
1128
	enablenpc( .@name$ );
1129
	unitwarp( .@id, .@map$, .@x, .@y ); // Move to new position
1130
	initnpctimer( .@name$ ); // Start timeout timer
1131
1132
	//debugmes .@name$+"::OnEnable target="+ .@map$ +", "+ .@x +", "+ .@y +" NPC="+ .@name$ +" timer="+ .@timer;
1133
	end;
1134
1135
// Disable Treasure NPC and clean event array
1136
OnDisable:
1137
	.@id = getnpcid(0);
1138
	.@name$ = strnpcinfo(0); //rid2name( .@id );
1139
	.@timer = getnpctimer(1, .@name$);
1140
	getmapxy(.@event_map$, .@x, .@y, UNITTYPE_NPC);
1141
1142
	stopnpctimer( .@name$ ); // Stop timeout timer
1143
	unitwarp( .@id, .map$, .x, .y ); // Return to default position
1144
	disablenpc( .@name$ );
1145
1146
	// Clean event data
1147-
	getmapxy(.map$, .x, .y, BL_NPC);
1147+
1148
	.@index = inarray($@WB_MAP$[0], .@event_map$);
1149
1150
	// Check if index was found
1151
	if ( .@index == -1 ) {
1152
		debugmes .@name$+"::OnDisable event map name ( "+ .@event_map$ +" ) not found!";
1153
		end;
1154
	}
1155
1156
	// Remove current event from the arrays
1157
	callfunc("WB_ResetEventGlobals", .@index);
1158
1159
	//debugmes .@name$+"::OnDisable target="+ .@event_map$ +", "+ .@x +", "+ .@y +" NPC="+ .@name$ +" timer="+ .@timer;
1160
	end;
1161
1162
//OnTimer30000:  // 30 seconds
1163
//OnTimer120000:  // 2 minutes
1164
//OnTimer300000:  // 5 minutes
1165
OnTimer600000: // 10 minutes
1166
//OnTimer900000: // 15 minutes
1167
	.@name$ = strnpcinfo(0);
1168
	getmapxy(.@map$, .@x, .@y, UNITTYPE_NPC);
1169
	//debugmes .@name$+"::OnTimeout target="+ .@map$ +", "+ .@x +", "+ .@y +" NPC="+ .@name$;
1170
	donpcevent .@name$+"::OnDisable";
1171
	end;
1172
}
1173
1174
// Treasure Chest duplicates (Add more if you run out)
1175-
	getmapxy(.@event_map$, .@x, .@y, BL_NPC);
1175+
1176
alberta,0,0,5	duplicate(Treasure Chest#wb_0)	Treasure Chest#wb_1	1324
1177
alberta,0,0,5	duplicate(Treasure Chest#wb_0)	Treasure Chest#wb_2	1324
1178
alberta,0,0,5	duplicate(Treasure Chest#wb_0)	Treasure Chest#wb_3	1324
1179
alberta,0,0,5	duplicate(Treasure Chest#wb_0)	Treasure Chest#wb_4	1324
1180
alberta,0,0,5	duplicate(Treasure Chest#wb_0)	Treasure Chest#wb_5	1324
1181
alberta,0,0,5	duplicate(Treasure Chest#wb_0)	Treasure Chest#wb_6	1324
1182
alberta,0,0,5	duplicate(Treasure Chest#wb_0)	Treasure Chest#wb_7	1324
1183
alberta,0,0,5	duplicate(Treasure Chest#wb_0)	Treasure Chest#wb_8	1324
1184
alberta,0,0,5	duplicate(Treasure Chest#wb_0)	Treasure Chest#wb_9	1324
1185
1186
// World Boss timeout timer
1187
-	script	WorldBossTimeout	-1,{
1188
	end;
1189
OnEnable:
1190
	initnpctimer;
1191
	end;
1192
OnDisable:
1193
	stopnpctimer;
1194
	end;
1195
// Update every 1 minutes
1196
OnTimer60000:
1197
	.@time = gettimetick(0);
1198
	.@timeout = getvariableofnpc(.event_timeout, "WorldBoss");
1199
	.@mapflags = getvariableofnpc(.use_mapflags, "WorldBoss");
1200
	for ( .@i = 0; .@i < getarraysize($@WB_MOB_GID); .@i++ ) {
1201
		// Unit must be alive
1202
		if ( unitexists($@WB_MOB_GID[.@i]) && .@time > ($@WB_TIMEOUT[.@i] + .@timeout) ) {
1203-
	getmapxy(.@map$, .@x, .@y, BL_NPC);
1203+
1204
			unitkill( $@WB_MOB_GID[.@i] );
1205
1206
			// Reset event mapflags
1207
			if ( .@mapflags ) {
1208
				callfunc("WB_ResetMapflags", $@WB_MAP$[.@i], .@i);
1209
			}
1210
1211
			// Remove event global arrays
1212
			callfunc("WB_ResetEventGlobals", .@i);
1213
		}
1214
	}
1215
	initnpctimer;
1216
	end;
1217
}
1218
1219
// World Boss Unit's Radar
1220
// Count users around the world boss and increase it's HP by each Player nearby
1221
-	script	WorldBossRadar	-1,{
1222
	end;
1223
OnInit:
1224
	.npc_name$ = strnpcinfo(0);
1225
	.radius = 15; // Cell radius
1226
	.HPLevel = 1500000; // HP increase per player
1227
	.MinHP = .HPLevel * 2; // Minimum HP when to stop decreasing HP
1228
	end;
1229
OnEnable:
1230
	initnpctimer;
1231
	end;
1232
OnDisable:
1233
	stopnpctimer;
1234
	end;
1235
// Every 10 secods update all World Boss unit data
1236
OnTimer10000:
1237
	for ( .@i = 0; .@i < getarraysize($@WB_MOB_GID); .@i++ ) {
1238
		.@unit_gid = $@WB_MOB_GID[.@i];
1239
		if ( unitexists(.@unit_gid) ) {
1240
			getunitdata(.@unit_gid, .@udata);
1241
			.@hp = .@udata[UMOB_HP];
1242
			.@maxhp = .@udata[UMOB_MAXHP];
1243
			.@x = .@udata[UMOB_X];
1244
			.@y = .@udata[UMOB_Y];
1245
			.@users = getareausers(mapid2name(.@udata[UMOB_MAPID]), (.@x - .radius), (.@y - .radius), (.@x + .radius), (.@y + .radius));
1246
			if ( .@users > $@WB_RADAR_NEAR[.@i] ) {
1247
				// Increase HP per each player nearby
1248
				.@new_hp = .@hp + ( .HPLevel * .@users );
1249
				// Stop increasing HP after maximum has been reached
1250
				if ( .@new_hp < .@maxhp ) {
1251
					setunitdata .@unit_gid, UMOB_HP, .@new_hp;
1252
					unittalk .@unit_gid, rid2name(.@unit_gid) + " : Mortals has entered my sight!", bc_area;
1253
				}
1254
			} else if ( .@users < $@WB_RADAR_NEAR[.@i] ) {
1255
				// Decrease HP per each player nearby
1256
				.@new_hp = .@hp - .HPLevel;
1257
				// Stop decreasing HP after minimum has been reached
1258
				if ( .@new_hp > .MinHP ) {
1259
					setunitdata .@unit_gid, UMOB_HP, .@new_hp;
1260
					unittalk .@unit_gid, rid2name(.@unit_gid) + " : Mortals has left my sight!", bc_area;
1261
				}
1262
			}
1263
			// Update users count
1264
			setarray $@WB_RADAR_NEAR[.@i], .@users;
1265
		}
1266
	}
1267
	initnpctimer;
1268
	end;
1269
}
1270
1271
// World Boss access expire timer
1272
// This will clean event access array from getting too big in time.
1273
-	script	WorldBossAccessExpire	-1,{
1274
	end;
1275
OnEnable:
1276
	//debugmes strnpcinfo(0)+"::OnEnable";
1277
	initnpctimer;
1278
	end;
1279
OnDisable:
1280
	//debugmes strnpcinfo(0)+"::OnDisable";
1281
	stopnpctimer;
1282
	end;
1283
// Update every 5 minutes
1284
OnTimer300000:
1285
	//debugmes strnpcinfo(0)+"::OnTimer";
1286
	.@time = gettimetick(0);
1287
	.@expires = getvariableofnpc(.event_access_expire, "WorldBoss");
1288
	for ( .@i = 0; .@i < getarraysize($@WB_ACCESS); .@i++ ) {
1289
		// Check if access has expired
1290
		if ( .@time > ($@WB_ACCESS_EXPIRE[.@i] + .@expires) ) {
1291
			// Current access has expired! Remove access and expire time.
1292
			deletearray $@WB_ACCESS[.@i], 1;
1293
			deletearray $@WB_ACCESS_EXPIRE[.@i], 1;
1294
		}
1295
	}
1296
	// Continue timer if access is not empty
1297
	if ( getarraysize($@WB_ACCESS) ) {
1298
		initnpctimer;
1299
	}
1300
	end;
1301
}
1302
1303
// World Boss Floating Rates
1304
-	script	WorldBossRates	-1,{
1305
OnInit: // Will fire before OnInterIfInitOnce on server start
1306
	// Floating rates are enabled
1307
	if(!getvariableofnpc(.use_floating_rates, "WorldBoss")) end;
1308
1309
	// Reset rates on script load
1310
	if ( $wb_base_exp_rate && getBattleFlag("base_exp_rate") != $wb_base_exp_rate )
1311
		donpcevent strnpcinfo(0)+"::OnDisable";
1312
	end;
1313
1314
OnInterIfInitOnce: // Will fire after OnInit on server start
1315
	// Floating rates are enabled
1316
	if(!getvariableofnpc(.use_floating_rates, "WorldBoss")) end;
1317
	// Set once on server start
1318
	$wb_battle_flags = 0;
1319
	// Set servers default battle flags
1320
	$wb_base_exp_rate = getBattleFlag("base_exp_rate");
1321
	$wb_job_exp_rate = getBattleFlag("job_exp_rate");
1322
	$wb_item_rate_common = getBattleFlag("item_rate_common");
1323
	$wb_item_rate_common_boss = getBattleFlag("item_rate_common_boss");
1324
	$wb_item_rate_common_mvp = getBattleFlag("item_rate_common_mvp");
1325
	$wb_item_rate_heal = getBattleFlag("item_rate_heal");
1326
	$wb_item_rate_heal_boss = getBattleFlag("item_rate_heal_boss");
1327
	$wb_item_rate_heal_mvp = getBattleFlag("item_rate_heal_mvp");
1328
	$wb_item_rate_use = getBattleFlag("item_rate_use");
1329
	$wb_item_rate_use_boss = getBattleFlag("item_rate_use_boss");
1330
	$wb_item_rate_use_mvp = getBattleFlag("item_rate_use_mvp");
1331
	$wb_item_rate_equip = getBattleFlag("item_rate_equip");
1332
	$wb_item_rate_equip_boss = getBattleFlag("item_rate_equip_boss");
1333
	$wb_item_rate_equip_mvp = getBattleFlag("item_rate_equip_mvp");
1334
	$wb_item_rate_card = getBattleFlag("item_rate_card");
1335
	$wb_item_rate_card_boss = getBattleFlag("item_rate_card_boss");
1336
	$wb_item_rate_card_mvp = getBattleFlag("item_rate_card_mvp");
1337
	$wb_item_rate_mvp = getBattleFlag("item_rate_mvp");
1338
	$wb_item_rate_adddrop = getBattleFlag("item_rate_adddrop");
1339
	$wb_item_rate_treasure = getBattleFlag("item_rate_treasure");
1340
	end;
1341
1342
OnDisable:
1343
	// Reset normal rates
1344
	if ( $wb_battle_flags ) {
1345
		setBattleFlag("base_exp_rate", $wb_base_exp_rate);
1346
		setBattleFlag("job_exp_rate", $wb_job_exp_rate);
1347
		setBattleFlag("item_rate_common", $wb_item_rate_common);
1348
		setBattleFlag("item_rate_common_boss", $wb_item_rate_common_boss);
1349
		setBattleFlag("item_rate_common_mvp", $wb_item_rate_common_mvp);
1350
		setBattleFlag("item_rate_heal", $wb_item_rate_heal);
1351
		setBattleFlag("item_rate_heal_boss", $wb_item_rate_heal_boss);
1352
		setBattleFlag("item_rate_heal_mvp", $wb_item_rate_heal_mvp);
1353
		setBattleFlag("item_rate_use", $wb_item_rate_use);
1354
		setBattleFlag("item_rate_use_boss", $wb_item_rate_use_boss);
1355
		setBattleFlag("item_rate_use_mvp", $wb_item_rate_use_mvp);
1356
		setBattleFlag("item_rate_equip", $wb_item_rate_equip);
1357
		setBattleFlag("item_rate_equip_boss", $wb_item_rate_equip_boss);
1358
		setBattleFlag("item_rate_equip_mvp", $wb_item_rate_equip_mvp);
1359
		setBattleFlag("item_rate_card", $wb_item_rate_card);
1360
		setBattleFlag("item_rate_card_boss", $wb_item_rate_card_boss);
1361
		setBattleFlag("item_rate_card_mvp", $wb_item_rate_card_mvp);
1362
		setBattleFlag("item_rate_mvp", $wb_item_rate_mvp);
1363
		setBattleFlag("item_rate_adddrop", $wb_item_rate_adddrop);
1364
		setBattleFlag("item_rate_treasure", $wb_item_rate_treasure);
1365
	}
1366
	$wb_battle_flags = 0;
1367
	stopnpctimer;
1368
	end;
1369
1370
OnEnable:
1371
	// Check already enabled
1372
	if ( !$wb_battle_flags ) {
1373
		// Double server ratings
1374
		setBattleFlag("base_exp_rate", $wb_base_exp_rate * 2);
1375
		setBattleFlag("job_exp_rate", $wb_job_exp_rate * 2);
1376
		setBattleFlag("item_rate_common", $wb_item_rate_common * 2);
1377
		setBattleFlag("item_rate_common_boss", $wb_item_rate_common_boss * 2);
1378
		setBattleFlag("item_rate_common_mvp", $wb_item_rate_common_mvp * 2);
1379
		setBattleFlag("item_rate_heal", $wb_item_rate_heal * 2);
1380
		setBattleFlag("item_rate_heal_boss", $wb_item_rate_heal_boss * 2);
1381
		setBattleFlag("item_rate_heal_mvp", $wb_item_rate_heal_mvp * 2);
1382
		setBattleFlag("item_rate_use", $wb_item_rate_use * 2);
1383
		setBattleFlag("item_rate_use_boss", $wb_item_rate_use_boss * 2);
1384
		setBattleFlag("item_rate_use_mvp", $wb_item_rate_use_mvp * 2);
1385
		setBattleFlag("item_rate_equip", $wb_item_rate_equip * 2);
1386
		setBattleFlag("item_rate_equip_boss", $wb_item_rate_equip_boss * 2);
1387
		setBattleFlag("item_rate_equip_mvp", $wb_item_rate_equip_mvp * 2);
1388
		setBattleFlag("item_rate_card", $wb_item_rate_card * 2);
1389
		setBattleFlag("item_rate_card_boss", $wb_item_rate_card_boss * 2);
1390
		setBattleFlag("item_rate_card_mvp", $wb_item_rate_card_mvp * 2);
1391
		setBattleFlag("item_rate_mvp", $wb_item_rate_mvp * 2);
1392
		setBattleFlag("item_rate_adddrop", $wb_item_rate_adddrop * 2);
1393
		setBattleFlag("item_rate_treasure", $wb_item_rate_treasure * 2);
1394
	}
1395
	announce "[World Boss] Experience and Drop rates has been doubled for one hour! Enjoy!", bc_all, 0x00FF00;
1396
	$wb_battle_flags = 1;
1397
	initnpctimer;
1398
	end;
1399
1400
OnTimer3600000: // 1 hour
1401
	donpcevent strnpcinfo(0)+"::OnDisable";
1402
	end;
1403
}
1404
1405
// NPC World Boss Information
1406
prontera,147,174,4	script	World Boss#info	495,5,5,{
1407
	mes "[ " + strnpcinfo(1) + " ]";
1408
	mes "About the world bosses.";
1409
	if ( getarraysize($@WB_MOB_GID) ) {
1410
		.@time = gettimetick(0);
1411
		.@timeout = getvariableofnpc(.event_timeout, "WorldBoss");
1412
		mes "Status: ^00CC36Active^000000";
1413
		for ( .@i = 0; .@i < getarraysize($@WB_MOB_GID); .@i++ ) {
1414
			.@timeleft = ($@WB_TIMEOUT[.@i] + .@timeout) - .@time;
1415
			mes (.@i + 1) + ". Location : " + $@WB_MAP$[.@i];
1416
			mes " ^777777 Time Left :^000000 " + (.@timeleft / 60000) + " min.";
1417
		}
1418
		mes "Good luck!";
1419
	} else {
1420
		mes "Status: ^CC3300Inactive^000000";
1421
		mes "Event timetable:";
1422
		mes "^777777 ~ 04:02 ^000000";
1423
		mes "^777777 ~ 23:59 ^000000";
1424
		mes "Wait until the event starts.";
1425
	}
1426
	// GM level 60+ has access to menu
1427
	if( getgmlevel() >= 60 ) {
1428
		next;
1429
		switch( select("Information:Start Event:Skip Start Timer:Stop Event:Change Loot Mode:Change Unit Data:Map Flags:Leave") ) {
1430
			case 1: callsub S_Info; break;
1431
			case 2: callsub S_Start; break;
1432
			case 3: callsub S_Skip; break;
1433
			case 4: callsub S_Stop; break;
1434
			case 5: callsub S_Loot; break;
1435
			case 6: callsub S_Unit; break;
1436
			case 7: callsub S_Mapflags; break;
1437
			default: break;
1438
		}
1439
	}
1440
	close;
1441
1442
S_Info:
1443
	// Set variables
1444
	.@enabled = getarraysize($@WB_MOB_GID);
1445
	.@loot_mode = getvariableofnpc(.loot_mode, .event_npc$);
1446
	.@time = gettimetick(0);
1447
	.@timeout = getvariableofnpc(.event_timeout, "WorldBoss");
1448
	mes "[ " + strnpcinfo(1) + " ]";
1449
	mes "^777777Status: ^000000" + (.@enabled ? "^00CC36Active^000000" : "^CC3300Inactive^000000");
1450
	mes "^777777Loot mode: ^000000" + .event_loot_modes$[.@loot_mode];
1451
	.@menu$ = "Leave:";
1452
	for ( .@i = 0; .@i < getarraysize($@WB_MOB_GID); .@i++ ) {
1453
		if ( $@WB_MOB_GID[.@i] || $@WB_NPC_NAME$[.@i] != "" ) {
1454
			// Monster Unit
1455
			.@timeleft = ($@WB_TIMEOUT[.@i] + .@timeout) - .@time; // ms
1456
			// Get unit data
1457
			if ( unitexists($@WB_MOB_GID[.@i]) ) {
1458
				// Monster unit
1459
				getunitdata($@WB_MOB_GID[.@i], .@udata);
1460
				mes (.@i + 1) +". Monster: " + $@WB_MOB_ID[.@i] +" / "+ getmonsterinfo($@WB_MOB_ID[.@i], 0);
1461
				mes " ^777777 GID: ^000000" + $@WB_MOB_GID[.@i];
1462
				mes " ^777777 Name: ^000000" + rid2name($@WB_MOB_GID[.@i]);
1463
				mes " ^777777 HP: ^000000" + .@udata[UMOB_HP] + " / " + .@udata[UMOB_MAXHP];
1464
				mes " ^777777 Location: ^000000" + mapid2name(.@udata[UMOB_MAPID]) +
1465
					" ^777777 x ^000000" + .@udata[UMOB_X] +
1466
					" ^777777 y ^000000" + .@udata[UMOB_Y];
1467
				mes " ^777777 Time Left :^000000 " + (.@timeleft / 60000) + " min.";
1468
			} else if (unitexists(getnpcid(0, $@WB_NPC_NAME$[.@i]))) {
1469
				// NPC unit
1470
				getunitdata(getnpcid(0, $@WB_NPC_NAME$[.@i]), .@udata);
1471
				mes (.@i + 1) +". Treasure Chest";
1472
				mes " ^777777 GID: ^000000" + getnpcid(0, $@WB_NPC_NAME$[.@i]);
1473
				mes " ^777777 Name: ^000000" + $@WB_NPC_NAME$[.@i];
1474
				mes " ^777777 Location: ^000000" + mapid2name(.@udata[UNPC_MAPID]) +
1475
					" ^777777 x ^000000" + .@udata[UNPC_X] +
1476
					" ^777777 y ^000000" + .@udata[UNPC_Y];
1477
			}
1478
			mes "^777777-------^000000";
1479
			.@menu$ += "Go to "+$@WB_MAP$[.@i];
1480
		}
1481
		.@menu$ += ":";
1482
	}
1483
	.@selected = select(.@menu$) - 2;
1484
	if ( .@selected >= 0 ) {
1485
		if ( unitexists($@WB_MOB_GID[.@selected]) ) {
1486
			// Warp to the monster location
1487
			getunitdata($@WB_MOB_GID[.@selected], .@data);
1488
			warp mapid2name(.@data[UMOB_MAPID]), .@data[UMOB_X], .@data[UMOB_Y];
1489
		} else if ( $@WB_NPC_NAME$[.@selected] != "" ) {
1490
			// Warp to the NPC location
1491
			if (unitexists(getnpcid(0, $@WB_NPC_NAME$[.@selected]))) {
1492
				getunitdata(getnpcid(0, $@WB_NPC_NAME$[.@selected]), .@data);
1493
				warp mapid2name(.@data[UNPC_MAPID]), .@data[UNPC_X], .@data[UNPC_Y];
1494
			}
1495
		}
1496
		end;
1497
	}
1498
	return;
1499
1500
S_Mapflags:
1501
	mes "[ " + strnpcinfo(1) + " ] Mapflags";
1502
	.@size = getarraysize($@WB_MOB_GID);
1503
	.@mapflags = getvariableofnpc(.use_mapflags, "WorldBoss");
1504
	if ( .@mapflags && .@size ) {
1505
		for ( .@i = 0; .@i < .@size; .@i++ ) {
1506
			.@map$ = $@WB_MAP$[.@i];
1507
			mes .@map$ + " : Original Flags";
1508
			mes " ^777777 PartyLock : " + $@WB_MF_PARTYLOCK[.@i] + "^000000";
1509
			mes " ^777777 NoMobLoot : " + $@WB_MF_NOMOBLOOT[.@i] + "^000000";
1510
			mes " ^777777 NoMVPLoot : " + $@WB_MF_NOMVPLOOT[.@i] + "^000000";
1511
			mes " ^777777 NoPenalty : " + $@WB_MF_NOPENALTY[.@i] + "^000000";
1512
			mes " ^777777 NoMobTele : " + $@WB_MF_NOMOBTELE[.@i] + "^000000";
1513
			mes " ^777777 BaseExp : " + $@WB_MF_BASEEXP[.@i] + "^000000";
1514
			mes " ^777777 JobExp : " + $@WB_MF_JOBEXP[.@i] + "^000000";
1515
			//mes " ^777777 Fog : " + $@WB_MF_FOG[.@i] + "^000000";
1516
			mes .@map$ + " : New Flags";
1517
			mes " ^777777 PartyLock : " + getmapflag(.@map$, MF_PARTYLOCK) + "^000000";
1518
			mes " ^777777 NoMobLoot : " + getmapflag(.@map$, MF_NOMOBLOOT) + "^000000";
1519
			mes " ^777777 NoMVPLoot : " + getmapflag(.@map$, MF_NOMVPLOOT) + "^000000";
1520
			mes " ^777777 NoPenalty : " + getmapflag(.@map$, MF_NOPENALTY) + "^000000";
1521
			mes " ^777777 NoMobTele : " + getmapflag(.@map$, MF_MONSTER_NOTELEPORT) + "^000000";
1522
			mes " ^777777 BaseExp : " + getmapflag(.@map$, MF_BEXP) + "^000000";
1523
			mes " ^777777 JobExp : " + getmapflag(.@map$, MF_JEXP) + "^000000";
1524
			//mes " ^777777 Fog : " + getmapflag(.@map$, MF_FOG) + "^000000";
1525
			mes "^777777-------^000000";
1526
		}
1527
	} else {
1528
		mes "No mapflags has been set.";
1529
	}
1530
	return;
1531
1532
S_Start:
1533
	donpcevent .event_npc$ + "::OnEnable";
1534
	message strcharinfo(0), "Event has been started!";
1535
	return;
1536
1537
S_Skip:
1538
	awake .event_npc$; // Cancels any running sleep timers on the NPC
1539
	message strcharinfo(0), "Event timer has been skipped!";
1540
	return;
1541
1542
S_Stop:
1543
	awake .event_npc$; // Cancels any running sleep timers on the NPC
1544
	donpcevent .event_npc$ + "::OnDisable";
1545
	// Announce event stopped
1546
	announce "[World Boss] The event has been stopped!", bc_all, 0xFF0000;
1547
	message strcharinfo(0), "Event has been stopped!";
1548
	return;
1549
1550
S_Loot:
1551
	.@size = getarraysize(.event_loot_modes$);
1552
	for( .@i = 0; .@i < .@size; .@i++ ) {
1553
		message strcharinfo(0), "Loot mode "+ .@i +" : " + .event_loot_modes$[.@i];
1554
	}
1555
	// Change event loot mode option
1556
	input .@input, 0, .@size;
1557
	set getvariableofnpc(.loot_mode, .event_npc$), .@input;
1558
	message strcharinfo(0), "Event loot mode changed: " + .event_loot_modes$[.@input];
1559
	return;
1560
1561
S_Unit:
1562
	// Create menu
1563
	.@menu$ = "Leave:";
1564
	for ( .@i = 0; .@i < getarraysize($@WB_MOB_GID); .@i++ ) {
1565
		if ( unitexists($@WB_MOB_GID[.@i]) ) {
1566
			.@menu$ += $@WB_MAP$[.@i] +" - "+ getmonsterinfo($@WB_MOB_ID[.@i], 0);
1567
		}
1568
		.@menu$ += ":";
1569
	}
1570
	.@selected = select(.@menu$) - 2;
1571
1572
	// Change unit data (HP,Level,Atk,Etc.)
1573
	if ( .@selected >= 0 ) {
1574
		mes "[ " + strnpcinfo(1) + " ]";
1575
		getunitdata($@WB_MOB_GID[.@selected], .@udata);
1576
		for (.@i = 0; .@i < getarraysize(.@udata); .@i++ ) {
1577
			mes .UMOB$[.@i] + " = " + .@udata[.@i];
1578
		}
1579
		.@select = select(.UMOB_menu$) - 1;
1580
		message strcharinfo(0), "Write a new unit ( " + .UMOB$[.@select] + " ) value.";
1581
		input .@val, 0, 1000000000;
1582
		setunitdata($@WB_MOB_GID[.@selected], .@select, .@val);
1583
		// Confim data has changed
1584
		getunitdata($@WB_MOB_GID[.@selected], .@confirm_udata);
1585
		message strcharinfo(0), "New unit data is: " + .@confirm_udata[.@select];
1586
	}
1587
	return;
1588
1589
OnInit:
1590
	// Event NPC name
1591
	.event_npc$ = "WorldBoss";
1592
1593
	// Event loot mode descriptions
1594
	// Copy array from other NPC
1595
	copyarray .event_loot_modes$[0], getelementofarray(getvariableofnpc(.loot_mode_desc$, .event_npc$),0), getarraysize(getvariableofnpc(.loot_mode_desc$, .event_npc$));
1596
1597
	// Unit data attibute names
1598
	setarray .UMOB$[0],
1599
		"Size","Level","Hp","Max Hp",
1600
		"Master AID","Map ID","Map X","Map Y",
1601
		"Speed","Mode","Ai","Scoption",
1602
		"Sex","Class","Hair style","Hair color",
1603
		"Head bottom","Head middle","Head top","Cloth color",
1604
		"Shield","Weapon","Look dir","Can move tick",
1605
		"Str","Agi","Vit","Int",
1606
		"Dex","Luk","Slave cpymstrmd","Dmg immune",
1607
		"Atk range","Atk min","Atk max","Matk min",
1608
		"Matk max","Def","Mdef","Hit",
1609
		"Flee","Pdodge","Crit","Race",
1610
		"Ele type","Ele level","A-motion","A-delay",
1611
		"D-motion";
1612
1613
	// Unit data menu string
1614
	.UMOB_menu$ = implode(.UMOB$, ":");
1615
1616
	// Set NPC size if class_id supports
1617
	.@npc_class = rand(495, 498);
1618
	.@npc_size = rand(0, 2); // 0=normal, 1=small, 2=big
1619
	setnpcdisplay(strnpcinfo(0), strnpcinfo(1), .@npc_class, .@npc_size);
1620
	end;
1621
1622
OnTouch:
1623
	// Player attached
1624
	end;
1625
1626
OnTouchNPC:
1627
	// Monster attached
1628
	.@UNIT_GID = getattachedrid();
1629
	//.@UNIT_NAME$ = rid2name(.@UNIT_GID);
1630
	//debugmes "Target unit name:" + .@UNIT_NAME$;
1631
	// Get unit data as Array
1632
	getunitdata(.@UNIT_GID, .@data);
1633
	.@MASTER_AID = .@data[UMOB_MASTERAID]; // UMOB_MASTERAID=4
1634
	// Unit has a master
1635
	if ( .@MASTER_AID ) {
1636
		.@MASTER_NAME$ = rid2name(.@MASTER_AID);
1637
		.@online = isloggedin(.@MASTER_AID);
1638
		if ( .@online ) {
1639
			end; // Do not target players unit
1640
		}
1641
	}
1642
	// NPC emotion
1643
	emotion ET_KEK;
1644
	// Warp monsters away from the NPC
1645
	unitwarp 0, "this", -1, -1;
1646
	end;
1647
}