existence_dev92

rAthena - worldBoss

Jan 30th, 2019
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //===== rAthena Script =======================================
  2. //= World Boss Event
  3. //===== By: ==================================================
  4. //= Musika6988, Sehrentos
  5. //===== Current Version: =====================================
  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. //= !TODO: Loot mode 12 give each reward to selected party member one by one.
  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. setarray .loots_0[0], 501, 502, 503, 504, 505, 506;
  112. setarray .loots_1[0], 507, 508, 509, 510, 511, 512;
  113. setarray .loots_2[0], 513, 514, 515, 516, 517, 518;
  114. setarray .loots_3[0], 519, 520, 521, 522, 523, 525;
  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 one reward to one random party member", // .loot_mode = 1
  132. "Give all rewards to one random party member", // .loot_mode = 2
  133. "Give rewards randomly between all party members", // .loot_mode = 3
  134. "Give all rewards to all nearby players and their party members", // .loot_mode = 4 (Skip UI)
  135. "Give one reward to all nearby players and their party members", // .loot_mode = 5 (Skip UI)
  136. "Give all rewards to all nearby players", // .loot_mode = 6 (Skip UI)
  137. "Give one reward to all nearby players", // .loot_mode = 7 (Skip UI)
  138. "Give all rewards to all players in the same map", // .loot_mode = 8 (Skip UI)
  139. "Give one reward to all players in the same map", // .loot_mode = 9 (Skip UI)
  140. "Give all rewards to selected party member", // .loot_mode = 10
  141. "Give one random reward to selected party member"; // .loot_mode = 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. getunitdata(.@unit_gid, .@data);
  356. if (.@unit_type == UNITTYPE_NPC) {
  357. // NPC does not have master
  358. debugmes .npc_name$+"::OnMobDie NPC no player attached!";
  359. end;
  360. }
  361. if (.@unit_type == UNITTYPE_PET) {
  362. if (!attachrid(.@data[UPET_MASTERAID])) {
  363. debugmes .npc_name$+"::OnMobDie PET no player attached!";
  364. end;
  365. }
  366. }
  367. if (.@unit_type == UNITTYPE_MOB) {
  368. if (!attachrid(.@data[UMOB_MASTERAID])) {
  369. debugmes .npc_name$+"::OnMobDie MOB no player attached!";
  370. end;
  371. }
  372. }
  373. if (.@unit_type == UNITTYPE_HOM) {
  374. .@name$ = strcharinfo(0,.@data[UHOM_MASTERCID]);
  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. .@name$ = strcharinfo(0,.@data[UMER_MASTERCID]);
  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. .@name$ = strcharinfo(0,.@data[UELE_MASTERCID]);
  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.  
  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. copyarray .@rewards[0], getd(".loots_" + .@rand_reward + "[0]"), .@reward_size;
  504.  
  505. switch( .loot_mode ) {
  506. case 0: // All to all members
  507. case 2: // All to random member
  508. case 3: // Randomly to all members
  509. case 10: // All to selected party member
  510. case 11: // One random to selected party member
  511. if ( getcharid(1) ) {
  512. goto OnPartyLeader;
  513. } else {
  514. // Has no party
  515. for( .@i = 0; .@i < .@reward_size; .@i++ ) {
  516. getitem .@rewards[.@i], 1;
  517. }
  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. case 8: // All in same map
  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. // No UI
  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.  
  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. end;
  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. // Copy the temporary party data
  606. .@party_size = $@partymembercount;
  607. copyarray .@party_cid[0], $@partymembercid[0], .@party_size;
  608. copyarray .@party_aid[0], $@partymemberaid[0], .@party_size;
  609. copyarray .@party_name$[0], $@partymembername$[0], .@party_size;
  610.  
  611. // LOOT MODE 0: Give all rewards to all party members
  612. if( .loot_mode == 0 ) {
  613. mes "[ Loot Distributor ]";
  614. // Loop through each party member
  615. for( .@idx = 0; .@idx < .@party_size; .@idx++ ) {
  616. // Online check
  617. if( isloggedin(.@party_aid[.@idx], .@party_cid[.@idx]) ) {
  618. mes " ~ " + strcharinfo(0, .@party_cid[.@idx]) + " was rewarded!";
  619. // Loop through each reward
  620. for( .@i = 0; .@i < .@reward_size; .@i++ ) {
  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. .@attempts = 0; // Counter for random player select
  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. if( select("Yes:No") == 1 ) {
  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. goto SelectRandom2;
  702. } else {
  703. goto OnClose;
  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 "Member is ^777777offline^000000";
  747. mes "Do you want to try again?";
  748. next;
  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. .@party_name$ = getpartyname(.@party_id); // Party Name
  793. .@party_leader_cid = getpartyleader(.@party_id, 2); // Party Leader Character ID
  794. // Party Leader Name
  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. // callfunc("WB_ResetPartyAccess", <party id>)
  904. function script WB_ResetPartyAccess {
  905. .@party_id = getarg(0);
  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. deletearray $@WB_ACCESS_EXPIRE[.@j], 1;
  914. }
  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. // Get event index from the map name array
  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. // NPC Name = Treasure Chest#wb_<indexNumber> (Important!)
  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. announce "[World Boss] World Boss in "+ $@WB_MAP$[.@i] +" has expired!", bc_all, 0xFF0000;
  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. }
Add Comment
Please, Sign In to add comment