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 | } |