Browse Source

Loot Protection Time Fixes
- Fixed Loot Protection time being calculated incorrectly when there was no second or third attacker
* Bystanders can now always only loot after 7000ms on normal monsters and 22000ms on boss monsters
- Any loot from bosses and MVPs now uses the extended protection time
* This was previously only applied to MVP reward items that drop to the ground when inventory was full
- Corrected the protection times
* Normal Monster -> second after 3000ms, third after 5000ms, anyone else after 7000ms
* Boss Monster -> second after 10000ms, third after 20000ms, anyone else after 22000ms
- Fixes #9240

Playtester 1 month ago
parent
commit
46e1605423
4 changed files with 34 additions and 16 deletions
  1. 8 5
      conf/battle/drops.conf
  2. 2 2
      src/map/battle.cpp
  3. 12 3
      src/map/map.cpp
  4. 12 6
      src/map/pc.cpp

+ 8 - 5
conf/battle/drops.conf

@@ -18,20 +18,23 @@ item_first_get_time: 3000
 
 
 // Grace time during which only the first and second person who did the most damage to a monster can get the item? (in milliseconds)
 // Grace time during which only the first and second person who did the most damage to a monster can get the item? (in milliseconds)
 // (Takes effect after item_first_get_time elapses)
 // (Takes effect after item_first_get_time elapses)
-item_second_get_time: 1000
+item_second_get_time: 2000
 
 
 // Grace time during which only the first, second and third person who did the most damage to a monster can get the item? (in milliseconds)
 // Grace time during which only the first, second and third person who did the most damage to a monster can get the item? (in milliseconds)
 // (Takes effect after the item_second_get_time elapses)
 // (Takes effect after the item_second_get_time elapses)
-item_third_get_time: 1000
+item_third_get_time: 2000
 
 
-// Grace time to apply to MvP reward items when the Most Valuable Player can't get the prize item and it drops on the ground? (in milliseconds)
+// Grace time during which only the person who did the most damage to a boss can get the item? (in milliseconds)
+// Also applies to MvP reward items when the Most Valuable Player can't get the prize item and it drops on the ground
 mvp_item_first_get_time: 10000
 mvp_item_first_get_time: 10000
 
 
-// Grace time for the first and second MvP so they can get the item? (in milliseconds)
+// Grace time during which only the first and second person who did the most damage to a boss can get the item? (in milliseconds)
+// Also applies to MvP reward items when first and second MVP can't get the prize item and it drops on the ground
 // (Takes effect after mvp_item_first_get_time elapses)
 // (Takes effect after mvp_item_first_get_time elapses)
 mvp_item_second_get_time: 10000
 mvp_item_second_get_time: 10000
 
 
-// Grace time for the first, second and third MvP so they can get the item? (in milliseconds)
+// Grace time during which only the first, second and third person who did the most damage to a boss can get the item? (in milliseconds)
+// Also applies to MvP reward items when first, second and third MvP can't get the prize item and it drops on the ground
 // (Takes effect after mvp_item_second_get_time elapses)
 // (Takes effect after mvp_item_second_get_time elapses)
 mvp_item_third_get_time: 2000
 mvp_item_third_get_time: 2000
 
 

+ 2 - 2
src/map/battle.cpp

@@ -11521,8 +11521,8 @@ static const struct _battle_data {
 	{ "flooritem_lifetime",                 &battle_config.flooritem_lifetime,              60000,  1000,   INT_MAX,        },
 	{ "flooritem_lifetime",                 &battle_config.flooritem_lifetime,              60000,  1000,   INT_MAX,        },
 	{ "item_auto_get",                      &battle_config.item_auto_get,                   0,      0,      1,              },
 	{ "item_auto_get",                      &battle_config.item_auto_get,                   0,      0,      1,              },
 	{ "item_first_get_time",                &battle_config.item_first_get_time,             3000,   0,      INT_MAX,        },
 	{ "item_first_get_time",                &battle_config.item_first_get_time,             3000,   0,      INT_MAX,        },
-	{ "item_second_get_time",               &battle_config.item_second_get_time,            1000,   0,      INT_MAX,        },
-	{ "item_third_get_time",                &battle_config.item_third_get_time,             1000,   0,      INT_MAX,        },
+	{ "item_second_get_time",               &battle_config.item_second_get_time,            2000,   0,      INT_MAX,        },
+	{ "item_third_get_time",                &battle_config.item_third_get_time,             2000,   0,      INT_MAX,        },
 	{ "mvp_item_first_get_time",            &battle_config.mvp_item_first_get_time,         10000,  0,      INT_MAX,        },
 	{ "mvp_item_first_get_time",            &battle_config.mvp_item_first_get_time,         10000,  0,      INT_MAX,        },
 	{ "mvp_item_second_get_time",           &battle_config.mvp_item_second_get_time,        10000,  0,      INT_MAX,        },
 	{ "mvp_item_second_get_time",           &battle_config.mvp_item_second_get_time,        10000,  0,      INT_MAX,        },
 	{ "mvp_item_third_get_time",            &battle_config.mvp_item_third_get_time,         2000,   0,      INT_MAX,        },
 	{ "mvp_item_third_get_time",            &battle_config.mvp_item_third_get_time,         2000,   0,      INT_MAX,        },

+ 12 - 3
src/map/map.cpp

@@ -2028,12 +2028,21 @@ int32 map_addflooritem(struct item *item, int32 amount, int16 m, int16 x, int16
 		return 0;
 		return 0;
 	}
 	}
 
 
+	// If item is flagged as MVP item or dropped by bosses, it is protected for longer
+	bool extend_protection = (flags&1);
+	if (mob_id > 0) {
+		std::shared_ptr<s_mob_db> mob = mob_db.find(mob_id);
+		// Boss and MVP drops both have prelonged loot protection
+		if (mob != nullptr && mob->get_bosstype() != BOSSTYPE_NONE)
+			extend_protection = true;
+	}
+
 	fitem->first_get_charid = first_charid;
 	fitem->first_get_charid = first_charid;
-	fitem->first_get_tick = gettick() + (flags&1 ? battle_config.mvp_item_first_get_time : battle_config.item_first_get_time);
+	fitem->first_get_tick = gettick() + (extend_protection ? battle_config.mvp_item_first_get_time : battle_config.item_first_get_time);
 	fitem->second_get_charid = second_charid;
 	fitem->second_get_charid = second_charid;
-	fitem->second_get_tick = fitem->first_get_tick + (flags&1 ? battle_config.mvp_item_second_get_time : battle_config.item_second_get_time);
+	fitem->second_get_tick = fitem->first_get_tick + (extend_protection ? battle_config.mvp_item_second_get_time : battle_config.item_second_get_time);
 	fitem->third_get_charid = third_charid;
 	fitem->third_get_charid = third_charid;
-	fitem->third_get_tick = fitem->second_get_tick + (flags&1 ? battle_config.mvp_item_third_get_time : battle_config.item_third_get_time);
+	fitem->third_get_tick = fitem->second_get_tick + (extend_protection ? battle_config.mvp_item_third_get_time : battle_config.item_third_get_time);
 	fitem->mob_id = mob_id;
 	fitem->mob_id = mob_id;
 
 
 	memcpy(&fitem->item,item,sizeof(*item));
 	memcpy(&fitem->item,item,sizeof(*item));

+ 12 - 6
src/map/pc.cpp

@@ -6103,16 +6103,20 @@ bool pc_takeitem(map_session_data *sd,struct flooritem_data *fitem)
 	if (sd->status.party_id)
 	if (sd->status.party_id)
 		p = party_search(sd->status.party_id);
 		p = party_search(sd->status.party_id);
 
 
-	if (fitem->first_get_charid > 0 && fitem->first_get_charid != sd->status.char_id) {
-		map_session_data *first_sd = map_charid2sd(fitem->first_get_charid);
+	if (fitem->first_get_charid == 0 || fitem->first_get_charid != sd->status.char_id) {
+		map_session_data* first_sd = nullptr;
+		if (fitem->first_get_charid > 0)
+			first_sd = map_charid2sd(fitem->first_get_charid);
 		if (DIFF_TICK(tick,fitem->first_get_tick) < 0) {
 		if (DIFF_TICK(tick,fitem->first_get_tick) < 0) {
 			if (!(p && p->party.item&1 &&
 			if (!(p && p->party.item&1 &&
 				first_sd && first_sd->status.party_id == sd->status.party_id
 				first_sd && first_sd->status.party_id == sd->status.party_id
 				))
 				))
 				return false;
 				return false;
 		}
 		}
-		else if (fitem->second_get_charid > 0 && fitem->second_get_charid != sd->status.char_id) {
-			map_session_data *second_sd = map_charid2sd(fitem->second_get_charid);
+		else if (fitem->second_get_charid == 0 || fitem->second_get_charid != sd->status.char_id) {
+			map_session_data* second_sd = nullptr;
+			if (fitem->second_get_charid > 0)
+				second_sd = map_charid2sd(fitem->second_get_charid);
 			if (DIFF_TICK(tick, fitem->second_get_tick) < 0) {
 			if (DIFF_TICK(tick, fitem->second_get_tick) < 0) {
 				if (!(p && p->party.item&1 &&
 				if (!(p && p->party.item&1 &&
 					((first_sd && first_sd->status.party_id == sd->status.party_id) ||
 					((first_sd && first_sd->status.party_id == sd->status.party_id) ||
@@ -6120,8 +6124,10 @@ bool pc_takeitem(map_session_data *sd,struct flooritem_data *fitem)
 					))
 					))
 					return false;
 					return false;
 			}
 			}
-			else if (fitem->third_get_charid > 0 && fitem->third_get_charid != sd->status.char_id){
-				map_session_data *third_sd = map_charid2sd(fitem->third_get_charid);
+			else if (fitem->third_get_charid == 0 || fitem->third_get_charid != sd->status.char_id) {
+				map_session_data* third_sd = nullptr;
+				if (fitem->third_get_charid > 0)
+					third_sd = map_charid2sd(fitem->third_get_charid);
 				if (DIFF_TICK(tick,fitem->third_get_tick) < 0) {
 				if (DIFF_TICK(tick,fitem->third_get_tick) < 0) {
 					if(!(p && p->party.item&1 &&
 					if(!(p && p->party.item&1 &&
 						((first_sd && first_sd->status.party_id == sd->status.party_id) ||
 						((first_sd && first_sd->status.party_id == sd->status.party_id) ||