Implements autoloot support for Mercenary (#5594)

* Fixed #5570.
* Adds the ability for mercenary to trigger autoloot.
* Adds idle sharing and idle option configs for granular settings.
Thanks to @saya9200's suggestion and @Lemongrass3110!
Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
This commit is contained in:
Aleos
2021-02-27 17:14:10 -05:00
committed by GitHub
parent 0e9308cba6
commit 2b94f0aeff
9 changed files with 97 additions and 9 deletions

View File

@@ -2239,9 +2239,9 @@ static TIMER_FUNC(mob_delay_item_drop){
* Sets the item_drop into the item_drop_list.
* Also performs logging and autoloot if enabled.
* rate is the drop-rate of the item, required for autoloot.
* flag : Killed only by homunculus?
* flag : Killed only by homunculus/mercenary?
*------------------------------------------*/
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;
bool test_autoloot;
@@ -2253,7 +2253,7 @@ static void mob_item_drop(struct mob_data *md, struct item_drop_list *dlist, str
if( sd == NULL ) sd = map_charid2sd(dlist->third_charid);
test_autoloot = sd
&& (drop_rate <= sd->state.autoloot || pc_isautolooting(sd, ditem->item_data.nameid))
&& (flag?(battle_config.homunculus_autoloot?(battle_config.hom_idle_no_share == 0 || !pc_isidle_hom(sd)):0):
&& (flag ? ((battle_config.homunculus_autoloot ? (battle_config.hom_idle_no_share == 0 || !pc_isidle_hom(sd)) : 0) || (battle_config.mercenary_autoloot ? (battle_config.mer_idle_no_share == 0 || !pc_isidle_mer(sd)) : 0)) :
(battle_config.idle_no_autoloot == 0 || DIFF_TICK(last_tick, sd->idletime) < battle_config.idle_no_autoloot));
#ifdef AUTOLOOT_DISTANCE
test_autoloot = test_autoloot && sd->bl.m == md->bl.m
@@ -2515,7 +2515,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
int dmgbltypes = 0; // bitfield of all bl types, that caused damage to the mob and are elligible for exp distribution
unsigned int mvp_damage;
t_tick tick = gettick();
bool rebirth, homkillonly;
bool rebirth, homkillonly, merckillonly;
status = &md->status;
@@ -2581,6 +2581,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
// determines, if the monster was killed by homunculus' damage only
homkillonly = (bool)( ( dmgbltypes&BL_HOM ) && !( dmgbltypes&~BL_HOM ) );
// determines if the monster was killed by mercenary damage only
merckillonly = (bool)((dmgbltypes & BL_MER) && !(dmgbltypes & ~BL_MER));
if(!battle_config.exp_calc_type && count > 1) { //Apply first-attacker 200% exp share bonus
//TODO: Determine if this should go before calculating the MVP player instead of after.
@@ -2848,7 +2850,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
}
// Announce first, or else ditem will be freed. [Lance]
// By popular demand, use base drop rate for autoloot code. [Skotlex]
mob_item_drop(md, dlist, ditem, 0, battle_config.autoloot_adjust ? drop_rate : md->db->dropitem[i].rate, homkillonly);
mob_item_drop(md, dlist, ditem, 0, battle_config.autoloot_adjust ? drop_rate : md->db->dropitem[i].rate, homkillonly || merckillonly);
}
// Ore Discovery [Celest]
@@ -2857,7 +2859,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
memset(&mobdrop, 0, sizeof(struct s_mob_drop));
mobdrop.nameid = itemdb_searchrandomid(IG_FINDINGORE,1);
ditem = mob_setdropitem(&mobdrop, 1, md->mob_id);
mob_item_drop(md, dlist, ditem, 0, battle_config.finding_ore_rate/10, homkillonly);
mob_item_drop(md, dlist, ditem, 0, battle_config.finding_ore_rate/10, homkillonly || merckillonly);
}
if(sd) {
@@ -2889,7 +2891,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
memset(&mobdrop, 0, sizeof(struct s_mob_drop));
mobdrop.nameid = dropid;
mob_item_drop(md, dlist, mob_setdropitem(&mobdrop,1,md->mob_id), 0, drop_rate, homkillonly);
mob_item_drop(md, dlist, mob_setdropitem(&mobdrop,1,md->mob_id), 0, drop_rate, homkillonly || merckillonly);
}
}
@@ -2904,7 +2906,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
// process items looted by the mob
if (md->lootitems) {
for (i = 0; i < md->lootitem_count; i++)
mob_item_drop(md, dlist, mob_setlootitem(&md->lootitems[i], md->mob_id), 1, 10000, homkillonly);
mob_item_drop(md, dlist, mob_setlootitem(&md->lootitems[i], md->mob_id), 1, 10000, homkillonly || merckillonly);
}
if (dlist->item) //There are drop items.
add_timer(tick + (!battle_config.delay_battle_damage?500:0), mob_delay_item_drop, 0, (intptr_t)dlist);
@@ -2920,7 +2922,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
dlist->third_charid = (third_sd ? third_sd->status.char_id : 0);
dlist->item = NULL;
for (i = 0; i < md->lootitem_count; i++)
mob_item_drop(md, dlist, mob_setlootitem(&md->lootitems[i], md->mob_id), 1, 10000, homkillonly);
mob_item_drop(md, dlist, mob_setlootitem(&md->lootitems[i], md->mob_id), 1, 10000, homkillonly || merckillonly);
add_timer(tick + (!battle_config.delay_battle_damage?500:0), mob_delay_item_drop, 0, (intptr_t)dlist);
}