keitenai 1 Posted April 12, 2016 (edited) I saw lots of players asking to have @autoloot id with more than one item to autoloot. There are many src code for this but none was available for 3ceam compatible. So here's @autloot item with 20slots made compatible for 3ceam V1 : 3CEAM_@ALOOTID_20SLOTS.patch Index: conf/atcommand_athena.conf =================================================================== --- conf/atcommand_athena.conf (revision 6) +++ conf/atcommand_athena.conf (working copy) @@ -157,10 +157,8 @@ // Enables/disables autolooting from killed mobs. autoloot: 10,10 +aloot: 10,10 -// Enables/disables autolooting an item. -alootid: 10,10 - // Allows you continue vending offline. autotrade: 10,10 at: 10,10 Index: src/map/atcommand.c =================================================================== --- src/map/atcommand.c (revision 6) +++ src/map/atcommand.c (working copy) @@ -6517,70 +6517,134 @@ } /*========================================== - * @autoloot by Upa-Kun - * Turns on/off AutoLoot for a specific player + * @autoloot by Zephyrus *------------------------------------------*/ ACMD_FUNC(autoloot) { - int rate; - double drate; - nullpo_retr(-1, sd); - // autoloot command without value - if(!message || !*message) + int p = 0; + char subcmd[100], data[100]; + memset(subcmd, '\0', sizeof(subcmd)); + memset(data, '\0', sizeof(data)); + + if( !message || !*message ) + { // Normal Autoloot usage + if( sd->aloot.rate ) + { + sd->aloot.rate = 0; + clif_displaymessage(fd, "Autoloot per percentage of drop turned off."); + } + else + { + sd->aloot.rate = 10000; + clif_displaymessage(fd, "Autoloot activated to receive all drops."); + } + + clif_displaymessage(fd, "To learn how to use the autoloot command use @autoloot help"); + return 0; + } + + if( (p = sscanf(message, "%99s %99[^\n]", subcmd, data)) < 1 ) { - if (sd->state.autoloot) - rate = 0; + clif_displaymessage(fd, "To learn how to use the autoloot command use @aloot help"); + return -1; + } + + if( !strcmp(subcmd, "rate") ) + { // Set autoloot rate value + int rate; + if( p < 2 ) + { + clif_displaymessage(fd, "It's required to enter a percentage value of drop. Ex. @aloot rate 0.03"); + return -1; + } + + rate = (int)(atof(data) * 100); + sd->aloot.rate = cap_value(rate, 0, 10000); + + if( sd->aloot.rate ) + { + snprintf(atcmd_output, sizeof(atcmd_output), "Autoloot activated for items of drop %0.02f%% or lower.",((double)sd->aloot.rate)/100.); + clif_displaymessage(fd, atcmd_output); + } else - rate = 10000; - } else { - drate = atof(message); - rate = (int)(drate*100); + clif_displaymessage(fd, "This item is already on your autoloot list."); } - if (rate < 0) rate = 0; - if (rate > 10000) rate = 10000; + else if( !strcmp(subcmd, "clear") ) + { + memset(&sd->aloot, 0, sizeof(sd->aloot)); + clif_displaymessage(fd, "Percentage and items autoloot Information deleted."); + } + else if( !strcmp(subcmd, "info") ) + { + int i, c = 0; + struct item_data *it = NULL; - sd->state.autoloot = rate; - if (sd->state.autoloot) { - snprintf(atcmd_output, sizeof atcmd_output, "Autolooting items with drop rates of %0.02f%% and below.",((double)sd->state.autoloot)/100.); + snprintf(atcmd_output, sizeof(atcmd_output), "Autoloot activated for items of drop %0.02f%% or lower.",((double)sd->aloot.rate)/100.); clif_displaymessage(fd, atcmd_output); - }else - clif_displaymessage(fd, "Autoloot is now off."); + for( i = 0; i < MAX_AUTOLOOTID; i++ ) + { + if( sd->aloot.nameid[i] == 0 || (it = itemdb_exists(sd->aloot.nameid[i])) == NULL ) + continue; - return 0; -} + snprintf(atcmd_output, sizeof(atcmd_output), "+ Autolooting of item : %s (%d).", it->jname, it->nameid); + clif_displaymessage(fd, atcmd_output); + c++; + } -/*========================================== - * @alootid - *------------------------------------------*/ -ACMD_FUNC(autolootitem) -{ - struct item_data *item_data = NULL; + snprintf(atcmd_output, sizeof(atcmd_output), "You're using %d of %d spots for autoloot per item.", c, MAX_AUTOLOOTID); + clif_displaymessage(fd, atcmd_output); + } + else if( !strcmp(subcmd, "item") ) + { + int i, j; + struct item_data *it = NULL; - if (!message || !*message) { - if (sd->state.autolootid) { - sd->state.autolootid = 0; - clif_displaymessage(fd, "Autolootitem has been turned OFF."); - } else - clif_displaymessage(fd, "Please, enter item name or it's ID (usage: @alootid <item_name_or_ID>)."); + if( p < 2 ) + { + clif_displaymessage(fd, "Please enter the name or id of the item for autoloot. Ex. @aloot item Elunium"); + return -1; + } - return -1; - } + ARR_FIND(0, MAX_AUTOLOOTID, i, sd->aloot.nameid[i] == 0); + if( i == MAX_AUTOLOOTID ) + { + clif_displaymessage(fd, msg_txt(886)); + return -1; + } - if ((item_data = itemdb_exists(atoi(message))) == NULL) - item_data = itemdb_searchname(message); + if( (it = itemdb_exists(atoi(data))) == NULL ) + it = itemdb_searchname(data); - if (!item_data) { - // No items founds in the DB with Id or Name - clif_displaymessage(fd, "Item not found."); + if( !it ) + { + clif_displaymessage(fd, "Please enter the name or id of the item for autoloot. Ex. @aloot item Elunium"); + return -1; + } + + ARR_FIND(0, MAX_AUTOLOOTID, j, sd->aloot.nameid[i] == it->nameid); + if( j < MAX_AUTOLOOTID ) + { + clif_displaymessage(fd, "This item is already on your autoloot list."); + return -1; + } + + sd->aloot.nameid[i] = it->nameid; + snprintf(atcmd_output, sizeof(atcmd_output), "+ Autolooting of item : %s (%d).", it->jname, it->nameid); + clif_displaymessage(fd, atcmd_output); + } + else if( !strcmp(subcmd, "help") ) + { + clif_displaymessage(fd, "@aloot rate <amount> : For autolooting items with percentage of drop <amount> and lower."); + clif_displaymessage(fd, "@aloot item <id/name> : For autolooting the item. You can change it up to 20 times."); + clif_displaymessage(fd, "@aloot info : To see autoloot's configuration list."); + clif_displaymessage(fd, "@aloot clear : To erase autoloot's configuration & deactivate it."); + } + else + { + clif_displaymessage(fd, "To learn how to use the autoloot command use @aloot help"); return -1; } - sd->state.autolootid = item_data->nameid; // Autoloot Activated - - sprintf(atcmd_output, "Autolooting item: '%s'/'%s' (%d)", - item_data->name, item_data->jname, item_data->nameid); - clif_displaymessage(fd, atcmd_output); - return 0; } @@ -9406,7 +9470,7 @@ { "disguiseall", 99,99, atcommand_disguiseall }, { "changelook", 60,60, atcommand_changelook }, { "autoloot", 10,10, atcommand_autoloot }, - { "alootid", 10,10, atcommand_autolootitem }, + { "aloot", 10,10, atcommand_autoloot }, { "mobinfo", 1,1, atcommand_mobinfo }, { "monsterinfo", 1,1, atcommand_mobinfo }, { "mi", 1,1, atcommand_mobinfo }, Index: src/map/mob.c =================================================================== --- src/map/mob.c (revision 7) +++ src/map/mob.c (working copy) @@ -1730,9 +1730,10 @@ * rate is the drop-rate of the item, required for autoloot. * flag : Killed only by homunculus? *------------------------------------------*/ -static void mob_item_drop(struct mob_data *md, struct item_drop_list *dlist, struct item_drop *ditem, int loot, int drop_rate, unsigned short flag) +static void mob_item_drop(struct mob_data *md, struct item_drop_list *dlist, struct item_drop *ditem, int loot, int drop_rate, bool flag) { TBL_PC* sd; + int i = MAX_AUTOLOOTID; if(log_config.enable_logs&0x10) { //Logs items, dropped by mobs [Lupus] @@ -1745,19 +1746,30 @@ sd = map_charid2sd(dlist->first_charid); if( sd == NULL ) sd = map_charid2sd(dlist->second_charid); if( sd == NULL ) sd = map_charid2sd(dlist->third_charid); + + // Display Drop + if( sd && sd->state.displaydrop && drop_rate <= sd->state.displaydrop ) + { + char message[128]; + sprintf(message, "Monster dropped %d %s (drop rate: %0.02f%%)", ditem->item_data.amount, itemdb_exists(ditem->item_data.nameid)->jname, (float)drop_rate / 100.); + clif_disp_onlyself(sd, message, strlen(message)); + } + if( sd ) + ARR_FIND(0, MAX_AUTOLOOTID, i, sd->aloot.nameid[i] == ditem->item_data.nameid); + if( sd - && (drop_rate <= sd->state.autoloot || ditem->item_data.nameid == sd->state.autolootid) - && (battle_config.idle_no_autoloot == 0 || DIFF_TICK(last_tick, sd->idletime) < battle_config.idle_no_autoloot) - && (battle_config.homunculus_autoloot?1:!flag) + && ( drop_rate <= sd->aloot.rate || i < MAX_AUTOLOOTID ) + && ( battle_config.idle_no_autoloot == 0 || DIFF_TICK(last_tick, sd->idletime) < battle_config.idle_no_autoloot ) + && ( battle_config.homunculus_autoloot?1:!flag ) #ifdef AUTOLOOT_DISTANCE && sd->bl.m == md->bl.m && check_distance_blxy(&sd->bl, dlist->x, dlist->y, AUTOLOOT_DISTANCE) #endif - ) { //Autoloot. - if (party_share_loot(party_search(sd->status.party_id), - sd, &ditem->item_data, sd->status.char_id) == 0 - ) { + ) + { // Autoloot. + if( party_share_loot(party_search(sd->status.party_id), sd, &ditem->item_data, sd->status.char_id) == 0 ) + { ers_free(item_drop_ers, ditem); return; } Index: src/map/pc.c =================================================================== --- src/map/pc.c (revision 6) +++ src/map/pc.c (working copy) @@ -1240,7 +1240,7 @@ sd->autobonus3[i].active = INVALID_TIMER; if (battle_config.item_auto_get) - sd->state.autoloot = 10000; + sd->aloot.rate = 10000; if (battle_config.disp_experience) sd->state.showexp = 1; Index: src/map/pc.h =================================================================== --- src/map/pc.h (revision 6) +++ src/map/pc.h (working copy) @@ -22,9 +22,11 @@ #define MAX_PC_SKILL_REQUIRE 5 #define MAX_PC_FEELHATE 3 +#define MAX_AUTOLOOTID 20 + #define MAX_RUNE 20 -#define MAX_RAGE 15 -#define MAX_SPELLBOOK 7 +#define MAX_RAGE 15 +#define MAX_SPELLBOOK 7 struct weapon_data { int atkmods[3]; @@ -141,8 +143,7 @@ unsigned buyingstore : 1; unsigned lesseffect : 1; unsigned vending : 1; - unsigned short autoloot; - unsigned short autolootid; // [Zephyrus] + unsigned short displaydrop; unsigned noks : 3; // [Zeph Kill Steal Protection] bool changemap; short pmap; // Previous map on Map Change @@ -167,6 +168,12 @@ unsigned no_knockback : 1; unsigned bonus_coma : 1; } special_state; + + struct { + unsigned short rate; + int nameid[MAX_AUTOLOOTID]; + } aloot; + int login_id1, login_id2; unsigned short class_; //This is the internal job ID used by the map server to simplify comparisons/queries/etc. [Skotlex] int gmlevel; Edited April 13, 2016 by keitenai Quote Share this post Link to post Share on other sites
PunkBuster 5 Posted January 2, 2021 This should have been part of the official version. Thanks, it helped a lot. Quote Share this post Link to post Share on other sites