Permalink
Cannot retrieve contributors at this time
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
231 lines (218 sloc)
10.1 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //===== rAthena Script ======================================= | |
| //= Instance Loot System | |
| //===== By =================================================== | |
| //= llchrisll | |
| //===== Version ============================================== | |
| //= 1.0 - Initial Version | |
| //===== Tested With ========================================== | |
| //= rAthena 10/10/2018 Revision | |
| //= GIT Hash: 55acdb9863382d8935d9df25e1462d5d1ebd7d54 | |
| //===== Description ========================================== | |
| //= Handles an Loot Distribution after an Instance run | |
| //= Every Monster Drop will be automatically "looted" | |
| // and saved in the database | |
| //= Members can select the loot they want | |
| //= Loot will be shared evenly | |
| //= Odd Amount of Loot will be random given to the members, | |
| // which wanted the specific item | |
| //===== Comments ============================================== | |
| //= Installation: | |
| // 1. Add the instance maps at the end of the file via duplicate | |
| // 2. Add the function "F_InstancedLoot" in every NPC Event regarding Mob Deaths | |
| // > callfunc "F_InstancedLoot",killedrid,getcharid(1); | |
| //===== SQL Tables =========================================== | |
| /* phpMyAdmin: | |
| CREATE TABLE IF NOT EXISTS `ilootsys` ( | |
| `pty_id` int(5) UNSIGNED NOT NULL, | |
| `item_id` int(8) UNSIGNED DEFAULT NULL, | |
| `item_am` int(5) UNSIGNED DEFAULT NULL, | |
| KEY `pty_id` (`pty_id`), | |
| KEY `item_id` (`item_id`) | |
| ) ENGINE=InnoDB DEFAULT CHARSET=latin1; | |
| */ | |
| //===== ToDO ================================================= | |
| //= Thinking about a good way to checkweight and maybe | |
| // automatically store items when weight is at capacity | |
| //============================================================ | |
| prontera,147,172,5 script Instance Loot 100,{ | |
| mes .n$; | |
| mes "Welcome!"; | |
| if(!getcharid(1)) { | |
| mes "It looks like you are not in a party, therefore I can't help you!"; | |
| close; | |
| } | |
| mes "How can I help you?"; | |
| next; | |
| switch(select("- Select Loot:- Information:- Nevermind")) { | |
| case 1: | |
| query_sql "SELECT `item_id` , `item_am` FROM `ilootsys` WHERE `pty_id` = '"+getcharid(1)+"'",.@item_id,.@item_am; | |
| if(getarraysize(.@item_id) < 1) { | |
| mes .n$; | |
| mes "I'm sorry, but there is no loot you could select from."; | |
| close; | |
| } | |
| set .@pty_id,getcharid(1); | |
| for ( set .@p,0; .@p < getarraysize(.pty_id); set .@p,.@p + 1) | |
| if(.@pty_id == .pty_id[.@p]) break; | |
| if(.@p >= getarraysize(.pty_id)) | |
| setarray .pty_id[.@p],.@pty_id; | |
| if(getarraysize(getd(".pty_aid_"+.@pty_id)) == 0) { | |
| getpartymember(.@pty_id),1; | |
| getpartymember(.@pty_id),2; | |
| for ( set .@a,0; .@a < $@partymembercount; set .@a,.@a + 1) | |
| if(isloggedin($@partymemberaid[.@a],$@partymembercid[.@a]) == 1) | |
| setarray getd(".pty_aid_"+.@pty_id+"["+getarraysize(getd(".pty_aid_"+.@pty_id))+"]"),$@partymemberaid[.@a]; | |
| } | |
| if(getarraysize(getd(".items_"+getcharid(3))) != 0) { | |
| mes .n$; | |
| mes "You have selected your loot already."; | |
| mes "Please wait until everybody else selected their items."; | |
| close; | |
| } | |
| while(1) { | |
| set .@loot$,""; | |
| for ( set .@i,0; .@i < getarraysize(.@item_id); set .@i,.@i + 1) | |
| set .@loot$,.@loot$ + "> "+.@item_am[.@i]+"x "+getitemname(.@item_id[.@i])+ ( (.@item_id[.@i+1] != 0)?":":""); | |
| if(.@loot$ != "") // Optical Check, existing value? | |
| set .@loot$,.@loot$ + ":> Done"; | |
| else // No item inserted, nothing else to select | |
| set .@loot$,"> Done"; | |
| mes .n$; | |
| mes "Please select the loot you want:"; | |
| mes "Note: The amount is what you're party has looted in total, not what is left!"; | |
| next; | |
| if(select(.@loot$) >= getarraysize(.@item_id)) { // Selected "Done" | |
| setarray .pty_ct[.@p],.pty_ct[.@p] + 1; | |
| if(getarraysize(getd(".items_"+getcharid(3))) == 0) // Loot selected? No? | |
| setarray getd(".items_"+getcharid(3)+"[0]"),1; // Better than using an extra variable | |
| break; | |
| } | |
| set .@c,@menu - 1; | |
| mes .n$; | |
| mes "Chosen Item:"; | |
| mes getitemname(.@item_id[.@c]); | |
| mes " "; | |
| mes "Is this correct?"; | |
| next; | |
| if(select("- Yes:- No") - 1) continue; | |
| setarray getd(".items_"+getcharid(3)+"["+getarraysize(getd(".items_"+getcharid(3)))+"]"),.@item_id[.@c]; | |
| deletearray .@item_id[.@c],1; | |
| deletearray .@item_am[.@c],1; | |
| } | |
| mes .n$; | |
| mes "Now I'll have to wait at least 1 minute until everybody else from your party has selected their loot."; | |
| if(getpartyleader(.@pty_id,1) == getcharid(3)) { // If the attached player is the party leader | |
| attachnpctimer; // attach the Timer to him/her | |
| initnpctimer; | |
| } | |
| break; | |
| case 2: | |
| mes .n$; | |
| mes "I will manage your loot from instances by distributing it evenly and according to your party members selection evenly."; | |
| mes "Every party member will be able to select the loot he/she wants from a list, which you have recieved during your instance run."; | |
| mes " "; | |
| mes "As soon every member has completed this task, I will calculate from the looted items how many of the selected item recieves the players which want it."; | |
| mes "In case there is a odd number of loot, the last item will distributed randomly among them."; | |
| mes "Example:"; | |
| mes "You have looted 10 Yellopy, got 5 Members which want this item, so each of them gets 2 of it."; | |
| break; | |
| case 3: break; | |
| } | |
| close; | |
| OnTimer60000: // Every Minute | |
| stopnpctimer; | |
| for ( set .@p,0; .@p < getarraysize(.pty_id); set .@p,.@p + 1) | |
| if(getcharid(1) == .pty_id[.@p]) break; | |
| // Just a check to prevent a possible bug | |
| if(.@p >= getarraysize(.pty_id)) { | |
| debugmes "Instanced Loot: Attached party ID "+getcharid(1)+" not found in .pty_id Array"; | |
| end; | |
| } | |
| if(.pty_ct[.@p] != getarraysize(getd(".pty_aid_"+getcharid(1)))) { | |
| initnpctimer; | |
| end; | |
| } | |
| query_sql "SELECT `item_id` , `item_am` FROM `ilootsys` WHERE `pty_id` = '"+getcharid(1)+"'",.@item_id,.@item_am; | |
| // Count how many players want the same item: | |
| for ( set .@c,0; .@c < getarraysize(getd(".pty_aid_"+getcharid(1))); set .@c,.@c + 1) | |
| for ( set .@i,0; .@i < getarraysize(.@item_id); set .@i,.@i + 1) { | |
| for ( set .@l,0; .@l < getarraysize(getd(".items_"+getd(".pty_aid_"+getcharid(1)))); set .@l,.@l + 1) | |
| if(getd(".items_"+getd(".pty_aid_"+getcharid(1)+"["+.@c+"]")+"["+.@l+"]") == .@item_id[.@i]) | |
| setarray .@item_pl[.@i],.@item_pl[.@i] + 1; | |
| // Calculate the shared amount of the loot and delete the Loot Counter | |
| if(.@item_pl[.@i]) { // The selected item is wanted | |
| setarray .@item_share[.@i],.@item_am[.@i]/.@item_pl[.@i]; | |
| if(.@item_am[.@i]%.@item_pl[.@i] > 0) | |
| setarray .@item_left[.@i],1; | |
| } | |
| deletearray .@item_pl[.@i],1; | |
| } | |
| // Loot Distribution: | |
| for ( set .@c,0; .@c < getarraysize(getd(".pty_aid_"+getcharid(1))); set .@c,.@c + 1) | |
| for ( set .@i,0; .@i < getarraysize(.@item_id); set .@i,.@i + 1) { | |
| for ( set .@l,0; .@l < getarraysize(getd(".items_"+getd(".pty_aid_"+getcharid(1)))); set .@l,.@l + 1) | |
| // Check if the current Player has chosen the current Item | |
| if(getd(".items_"+getd(".pty_aid_"+getcharid(1)+"["+.@c+"]")+"["+.@l+"]") == .@item_id[.@i]) { | |
| if(.@item_am[.@i] >= .@item_share[.@i]) // Check if there is still loot available, in case the Loot is not enough for Player who selected it | |
| getitem .@item_id[.@i],.@item_share[.@i],getd(".pty_aid_"+getcharid(1)+"["+.@c+"]"); | |
| setarray .@item_am[.@i],( (.@item_am[.@i] > .@item_share[.@i])?.@item_am[.@i]-.@item_share[.@i]:0); // Reduce the item amount available | |
| if(.@item_left[.@i]) // Save Account ID in an extra array in case there is an odd number of loot | |
| setarray getd(".@items_shared_"+.@item_id[.@i]+"["+getarraysize(getd(".@items_shared_"+.@item_id[.@i]))+"]"),getd(".pty_aid_"+getcharid(1)+"["+.@c+"]"); | |
| deletearray getd(".items_"+getd(".pty_aid_"+getcharid(1)+"["+.@c+"]")+"["+.@l+"]"),1; // Remove Item from Loot list of the player | |
| } | |
| if(.@item_left[.@i] > 0) | |
| getitem .@item_id[.@i],1,rand(getarraysize(getd(".@items_shared_"+.@item_id[.@i]))+"]"); | |
| } | |
| deletearray getd(".pty_aid_"+getcharid(1)+"[0]"),getarraysize(getd(".pty_aid_"+getcharid(1))); | |
| deletearray .pty_id[.@p],1; | |
| deletearray .pty_ct[.@p],1; | |
| query_sql "DELETE FROM `ilootsys` WHERE `pty_id` = '"+getcharid(1)+"'"; | |
| npctalk .n$+": The Loot Distribution is complete!",strnpcinfo(0),bc_self; | |
| end; | |
| OnInit: | |
| set .n$,"["+strnpcinfo(0)+"]"; | |
| //query_sql "DROP TABLE IF EXISTS `ilootsys`"; | |
| if(query_sql("SHOW TABLES LIKE 'ilootsys'",.@iloot$) == 0) { | |
| query_sql "CREATE TABLE IF NOT EXISTS `ilootsys` ( `pty_id` int(5) UNSIGNED NOT NULL, `item_id` int(8) UNSIGNED DEFAULT NULL, `item_am` int(5) UNSIGNED DEFAULT NULL, KEY `pty_id` (`pty_id`), KEY `item_id` (`item_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;"; | |
| //query_sql "ALTER TABLE `ilootsys` ADD KEY `pty_id` (`pty_id`), ADD KEY `item_id` (`item_id`)"; | |
| } | |
| set $@ilootsys,1; | |
| end; | |
| } | |
| function script F_InstancedLoot { | |
| // getarg(0) == Party ID | |
| // getarg(1) == Mob ID | |
| if(!$@ilootsys) return; | |
| if(getarraysize(getd("'items_"+getarg(1))) == 0) { | |
| getmobdrops(getarg(1)); | |
| copyarray getd("'items_"+getarg(1)+"[0]"),$@MobDrop_item[0],$@MobDrop_count; | |
| copyarray getd("'rate_"+getarg(1)+"[0]"),$@MobDrop_rate[0],$@MobDrop_count; | |
| } | |
| for ( set .@d,0; .@d < getarraysize(getd("'items_"+getarg(1))); set .@d,.@d + 1) | |
| if(rand(1,10000) <= getd("'rate_"+getarg(1)+"["+.@d+"]")) { | |
| if(query_sql("SELECT `item_am` FROM `ilootsys` WHERE `pty_id` = '"+getarg(0)+"' AND `item_id` = '"+getd("'items_"+getarg(1)+"["+.@d+"]")+"'",.@i_am) == 0) | |
| query_sql "INSERT INTO `ilootsys` ( `pty_id` , `item_id` , `item_am` ) VALUES ( '"+getarg(0)+"' , '"+getd("'items_"+getarg(1)+"["+.@d+"]")+"' , '1')"; | |
| else | |
| query_sql "UPDATE `ilootsys` SET `item_am` = `item_am` + '1' WHERE `pty_id` = '"+getarg(0)+"' AND `item_id` = '"+getd("'items_"+getarg(1)+"["+.@d+"]")+"'"; | |
| } | |
| return; | |
| } | |
| - script I_Loot -1,{ | |
| end; | |
| OnInstanceInit: | |
| if(!$@ilootsys) end; | |
| setmapflag instance_mapname(strnpcinfo(4)),mf_noloot; | |
| if(getmapflag(instance_mapname(strnpcinfo(4)),mf_noloot) == 1) | |
| instance_announce 0,"[Instance Loot]: This Instance uses the Instance Loot System, which means that your loot will not appear on the floor, but can be collected afterwards at the NPC in the Main Town.",0; | |
| end; | |
| OnInstanceDestroy: | |
| if(!$@ilootsys) end; | |
| removemapflag instance_mapname(strnpcinfo(4)),mf_noloot; | |
| end; | |
| } | |
| // Duplicates of I_Loot Template above, for OnInstanceInit required | |
| // To add an instance, add the maps used in it | |
| //map_of_instance,0,0,0 duplicate(I_Loot) I_Loot#1 -1 | |
| //map_of_instance,0,0,0 duplicate(I_Loot) I_Loot#2 -1 | |
| //map_of_instance,0,0,0 duplicate(I_Loot) I_Loot#3 -1 | |
| //map_of_instance,0,0,0 duplicate(I_Loot) I_Loot#4 -1 |