浏览代码

Improved item_check to remove unavailable items from inventory, cart, and storage on character login. (tid:81548)

aleos89 11 年之前
父节点
当前提交
cdccf88376
共有 8 个文件被更改,包括 81 次插入38 次删除
  1. 6 3
      conf/battle/items.conf
  2. 4 1
      conf/msg_conf/map_msg.conf
  3. 1 1
      src/map/battle.c
  4. 2 1
      src/map/clif.c
  5. 1 0
      src/map/itemdb.c
  6. 3 2
      src/map/mail.c
  7. 63 30
      src/map/pc.c
  8. 1 0
      src/map/pc.h

+ 6 - 3
conf/battle/items.conf

@@ -51,12 +51,15 @@ random_monster_checklv: no
 // NOTE: Wedding Rings and Whips/Musical Instruments will check gender regardless of setting.
 ignore_items_gender: yes
 
-// Item check? (Note 1)
+// Item check?
 // On map change it will check for items not tagged as "available" and 
-// auto-delete them from inventory/cart.
+// auto-delete them from inventory/cart/storage.
 // NOTE: An item is not available if it was not loaded from the item_db or you 
 // specify it as unavailable in db/item_avail.txt
-item_check: no
+// 1: Inventory
+// 2: Cart
+// 4: Storage
+item_check: 0
 
 // How much time must pass between item uses?
 // Only affects the delay between using items, prevents healing item abuse. Recommended ~500 ms

+ 4 - 1
conf/msg_conf/map_msg.conf

@@ -668,7 +668,10 @@
 678: You are no longer the Guild Master.
 679: You have become the Guild Master!
 680: You have been recovered!
-//681-899 free
+681: Item %d has been removed from your inventory.
+682: Item %d has been removed from your cart.
+683: Item %d has been removed from your storage.
+//684-899 free
 
 681: Rune Knight T
 682: Warlock T

+ 1 - 1
src/map/battle.c

@@ -6867,7 +6867,7 @@ static const struct _battle_data {
 	{ "max_heal_lv",                        &battle_config.max_heal_lv,                     11,     1,      INT_MAX,        },
 	{ "max_heal",                           &battle_config.max_heal,                        9999,   0,      INT_MAX,        },
 	{ "combo_delay_rate",                   &battle_config.combo_delay_rate,                100,    0,      INT_MAX,        },
-	{ "item_check",                         &battle_config.item_check,                      0,      0,      1,              },
+	{ "item_check",                         &battle_config.item_check,                      0,      0,      7,              },
 	{ "item_use_interval",                  &battle_config.item_use_interval,               100,    0,      INT_MAX,        },
 	{ "cashfood_use_interval",              &battle_config.cashfood_use_interval,           60000,  0,      INT_MAX,        },
 	{ "wedding_modifydisplay",              &battle_config.wedding_modifydisplay,           0,      0,      1,              },

+ 2 - 1
src/map/clif.c

@@ -14264,7 +14264,8 @@ void clif_parse_Auction_setitem(int fd, struct map_session_data *sd){
 
 	if( !pc_can_give_items(sd) || sd->status.inventory[idx].expire_time ||
 			!sd->status.inventory[idx].identify ||
-				!itemdb_canauction(&sd->status.inventory[idx],pc_get_group_level(sd)) ) { // Quest Item or something else
+			!itemdb_available(sd->status.inventory[idx].nameid) ||
+			!itemdb_canauction(&sd->status.inventory[idx],pc_get_group_level(sd)) ) { // Quest Item or something else
 		clif_Auction_setitem(sd->fd, idx, true);
 		return;
 	}

+ 1 - 0
src/map/itemdb.c

@@ -1471,6 +1471,7 @@ void itemdb_reload(void)
 	for( sd = (struct map_session_data*)mapit_first(iter); mapit_exists(iter); sd = (struct map_session_data*)mapit_next(iter) ) {
 		memset(sd->item_delay, 0, sizeof(sd->item_delay));  // reset item delays
 		pc_setinventorydata(sd);
+		pc_check_available_item(sd); // Check for invalid(ated) items.
 		/* clear combo bonuses */
 		if( sd->combos.count ) {
 			aFree(sd->combos.bonus);

+ 3 - 2
src/map/mail.c

@@ -78,8 +78,9 @@ unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount) {
 			return 1;
 		if( amount < 0 || amount > sd->status.inventory[idx].amount )
 			return 1;
-		if( !pc_can_give_items(sd) || sd->status.inventory[idx].expire_time 
-			|| !itemdb_canmail(&sd->status.inventory[idx],pc_get_group_level(sd)) 
+		if( !pc_can_give_items(sd) || sd->status.inventory[idx].expire_time
+			|| !itemdb_available(sd->status.inventory[idx].nameid)
+			|| !itemdb_canmail(&sd->status.inventory[idx],pc_get_group_level(sd))
 			|| (sd->status.inventory[idx].bound && !pc_can_give_bounded_items(sd)) )
 			return 1;
 

+ 63 - 30
src/map/pc.c

@@ -39,6 +39,7 @@
 #include "script.h" // script_config
 #include "skill.h"
 #include "status.h" // struct status_data
+#include "storage.h"
 #include "pc.h"
 #include "pc_groups.h"
 #include "quest.h"
@@ -1287,6 +1288,7 @@ int pc_reg_received(struct map_session_data *sd)
 	if (!chrif_auth_finished(sd))
 		ShowError("pc_reg_received: Failed to properly remove player %d:%d from logging db!\n", sd->status.account_id, sd->status.char_id);
 
+	pc_check_available_item(sd); // Check for invalid(ated) items.
 	pc_load_combo(sd);
 
 	status_calc_pc(sd,1);
@@ -9018,46 +9020,26 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
 }
 
 /*==========================================
- * Checking if player (sd) have unauthorize, invalide item
- * on inventory, cart, equiped for the map (item_noequip)
+ * Checking if player (sd) has an invalid item
+ * and is unequiped on map load (item_noequip)
  *------------------------------------------*/
-int pc_checkitem(struct map_session_data *sd)
-{
-	int i,id,calc_flag = 0;
+int pc_checkitem(struct map_session_data *sd) {
+	int i, calc_flag = 0;
+	struct item it;
 
 	nullpo_ret(sd);
 
 	if( sd->state.vending ) //Avoid reorganizing items when we are vending, as that leads to exploits (pointed out by End of Exam)
 		return 0;
 
-	if( battle_config.item_check ) {// check for invalid(ated) items
-		for( i = 0; i < MAX_INVENTORY; i++ ) {
-			id = sd->status.inventory[i].nameid;
-
-			if( id && !itemdb_available(id) ) {
-				ShowWarning("Removed invalid/disabled item id %d from inventory (amount=%d, char_id=%d).\n", id, sd->status.inventory[i].amount, sd->status.char_id);
-				pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER);
-			}
-		}
+	for( i = 0; i < MAX_INVENTORY; i++ ) {
+		it = sd->status.inventory[i];
 
-		for( i = 0; i < MAX_CART; i++ ) {
-			id = sd->status.cart[i].nameid;
-
-			if( id && !itemdb_available(id) ) {
-				ShowWarning("Removed invalid/disabled item id %d from cart (amount=%d, char_id=%d).\n", id, sd->status.cart[i].amount, sd->status.char_id);
-				pc_cart_delitem(sd, i, sd->status.cart[i].amount, 0, LOG_TYPE_OTHER);
-			}
-		}
-	}
-
-	for( i = 0; i < MAX_INVENTORY; i++) {
-		if( !(&sd->status.inventory[i]) || sd->status.inventory[i].nameid == 0 )
+		if( it.nameid == 0 )
 			continue;
-
-		if( !sd->status.inventory[i].equip )
+		if( !it.equip )
 			continue;
-
-		if( sd->status.inventory[i].equip&~pc_equippoint(sd,i) ) {
+		if( it.equip&~pc_equippoint(sd,i) ) {
 			pc_unequipitem(sd, i, 2);
 			calc_flag = 1;
 			continue;
@@ -9078,6 +9060,57 @@ int pc_checkitem(struct map_session_data *sd)
 	return 0;
 }
 
+/*==========================================
+ * Checks for unavailable items and removes them.
+ *------------------------------------------*/
+int pc_check_available_item(struct map_session_data *sd) {
+	int i, it;
+	char output[256];
+
+	nullpo_ret(sd);
+
+	if( battle_config.item_check&1 ) { // Check for invalid(ated) items in inventory.
+		for( i = 0; i < MAX_INVENTORY; i++ ) {
+			it = sd->status.inventory[i].nameid;
+
+			if( it && !itemdb_available(it) ) {
+				sprintf(output, msg_txt(sd, 681), it); // Item %d has been removed from your inventory.
+				clif_displaymessage(sd->fd, output);
+				ShowWarning("Removed invalid/disabled item id %d from inventory (amount=%d, char_id=%d).\n", it, sd->status.inventory[i].amount, sd->status.char_id);
+				pc_delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER);
+			}
+		}
+	}
+
+	if( battle_config.item_check&2 ) { // Check for invalid(ated) items in cart.
+		for( i = 0; i < MAX_CART; i++ ) {
+			it = sd->status.cart[i].nameid;
+
+			if( it && !itemdb_available(it) ) {
+				sprintf(output, msg_txt(sd, 682), it); // Item %d has been removed from your cart.
+				clif_displaymessage(sd->fd, output);
+				ShowWarning("Removed invalid/disabled item id %d from cart (amount=%d, char_id=%d).\n", it, sd->status.cart[i].amount, sd->status.char_id);
+				pc_cart_delitem(sd, i, sd->status.cart[i].amount, 0, LOG_TYPE_OTHER);
+			}
+		}
+	}
+
+	if( battle_config.item_check&4 ) { // Check for invalid(ated) items in storage.
+		for( i = 0; i < MAX_STORAGE; i++ ) {
+			it = sd->status.storage.items[i].nameid;
+
+			if( it && !itemdb_available(it) ) {
+				sprintf(output, msg_txt(sd, 683), it); // Item %d has been removed from your storage.
+				clif_displaymessage(sd->fd, output);
+				ShowWarning("Removed invalid/disabled item id %d from storage (amount=%d, char_id=%d).\n", it, sd->status.storage.items[i].amount, sd->status.char_id);
+				storage_delitem(sd, i, sd->status.storage.items[i].amount);
+			}
+ 		}
+	}
+
+	return 0;
+}
+
 /*==========================================
  * Update PVP rank for sd1 in cmp to sd2
  *------------------------------------------*/

+ 1 - 0
src/map/pc.h

@@ -860,6 +860,7 @@ int pc_resethate(struct map_session_data*);
 int pc_equipitem(struct map_session_data*,int,int);
 int pc_unequipitem(struct map_session_data*,int,int);
 int pc_checkitem(struct map_session_data*);
+int pc_check_available_item(struct map_session_data *sd);
 int pc_useitem(struct map_session_data*,int);
 
 int pc_skillatk_bonus(struct map_session_data *sd, uint16 skill_id);