浏览代码

- Rewrote all the item restriction functions so that they will take into account slotted card restrictions as well.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@7552 54d463be-8e91-2dee-dedb-b68131a5f0ec
skotlex 19 年之前
父节点
当前提交
a4d0df735d
共有 10 个文件被更改,包括 64 次插入36 次删除
  1. 2 0
      Changelog-Trunk.txt
  2. 1 1
      src/map/clif.c
  3. 29 14
      src/map/itemdb.c
  4. 15 7
      src/map/itemdb.h
  5. 4 4
      src/map/pc.c
  6. 1 1
      src/map/pc.h
  7. 1 1
      src/map/script.c
  8. 2 2
      src/map/storage.c
  9. 8 5
      src/map/trade.c
  10. 1 1
      src/map/vending.c

+ 2 - 0
Changelog-Trunk.txt

@@ -4,6 +4,8 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 
 2006/07/06
 2006/07/06
+	* Rewrote all the item restriction functions so that they will take into
+	  account slotted card restrictions as well. [Skotlex]
 	* Added no_skill_delay setting, when set, affected object types will have
 	* Added no_skill_delay setting, when set, affected object types will have
 	  the minimum skill delay for all skills. Defaults to mobs, since they
 	  the minimum skill delay for all skills. Defaults to mobs, since they
 	  don't have skill delays. [Skotlex]
 	  don't have skill delays. [Skotlex]

+ 1 - 1
src/map/clif.c

@@ -1873,7 +1873,7 @@ int clif_selllist(struct map_session_data *sd) {
 	WFIFOW(fd,0)=0xc7;
 	WFIFOW(fd,0)=0xc7;
 	for(i=0;i<MAX_INVENTORY;i++) {
 	for(i=0;i<MAX_INVENTORY;i++) {
 		if(sd->status.inventory[i].nameid > 0 && sd->inventory_data[i]) {
 		if(sd->status.inventory[i].nameid > 0 && sd->inventory_data[i]) {
-			if (!itemdb_cansell(sd->status.inventory[i].nameid, pc_isGM(sd)))
+			if (!itemdb_cansell(&sd->status.inventory[i], pc_isGM(sd)))
 				continue;
 				continue;
 
 
 			val=sd->inventory_data[i]->value_sell;
 			val=sd->inventory_data[i]->value_sell;

+ 29 - 14
src/map/itemdb.c

@@ -289,48 +289,63 @@ static int itemdb_ispetequip(struct item_data *data)
  * Trade Restriction functions [Skotlex]
  * Trade Restriction functions [Skotlex]
  *------------------------------------------
  *------------------------------------------
  */
  */
-int itemdb_isdropable(int nameid, int gmlv)
+int itemdb_isdropable_sub(struct item_data *item, int gmlv, int unused)
 {
 {
-	struct item_data* item = itemdb_exists(nameid);
 	return (item && (!(item->flag.trade_restriction&1) || gmlv >= item->gm_lv_trade_override));
 	return (item && (!(item->flag.trade_restriction&1) || gmlv >= item->gm_lv_trade_override));
 }
 }
 
 
-int itemdb_cantrade(int nameid, int gmlv, int gmlv2)
+int itemdb_cantrade_sub(struct item_data* item, int gmlv, int gmlv2)
 {
 {
-	struct item_data* item = itemdb_exists(nameid);
 	return (item && (!(item->flag.trade_restriction&2) || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override));
 	return (item && (!(item->flag.trade_restriction&2) || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override));
 }
 }
 
 
-int itemdb_canpartnertrade(int nameid, int gmlv, int gmlv2)
+int itemdb_canpartnertrade_sub(struct item_data* item, int gmlv, int gmlv2)
 {
 {
-	struct item_data* item = itemdb_exists(nameid);
 	return (item && (item->flag.trade_restriction&4 || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override));
 	return (item && (item->flag.trade_restriction&4 || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override));
 }
 }
 
 
-int itemdb_cansell(int nameid, int gmlv)
+int itemdb_cansell_sub(struct item_data* item, int gmlv, int unused)
 {
 {
-	struct item_data* item = itemdb_exists(nameid);
 	return (item && (!(item->flag.trade_restriction&8) || gmlv >= item->gm_lv_trade_override));
 	return (item && (!(item->flag.trade_restriction&8) || gmlv >= item->gm_lv_trade_override));
 }
 }
 
 
-int itemdb_cancartstore(int nameid, int gmlv)
+int itemdb_cancartstore_sub(struct item_data* item, int gmlv, int unused)
 {	
 {	
-	struct item_data* item = itemdb_exists(nameid);
 	return (item && (!(item->flag.trade_restriction&16) || gmlv >= item->gm_lv_trade_override));
 	return (item && (!(item->flag.trade_restriction&16) || gmlv >= item->gm_lv_trade_override));
 }
 }
 
 
-int itemdb_canstore(int nameid, int gmlv)
+int itemdb_canstore_sub(struct item_data* item, int gmlv, int unused)
 {	
 {	
-	struct item_data* item = itemdb_exists(nameid);
 	return (item && (!(item->flag.trade_restriction&32) || gmlv >= item->gm_lv_trade_override));
 	return (item && (!(item->flag.trade_restriction&32) || gmlv >= item->gm_lv_trade_override));
 }
 }
 
 
-int itemdb_canguildstore(int nameid, int gmlv)
+int itemdb_canguildstore_sub(struct item_data* item, int gmlv, int unused)
 {	
 {	
-	struct item_data* item = itemdb_exists(nameid);
 	return (item && (!(item->flag.trade_restriction&64) || gmlv >= item->gm_lv_trade_override));
 	return (item && (!(item->flag.trade_restriction&64) || gmlv >= item->gm_lv_trade_override));
 }
 }
 
 
+int itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(struct item_data*, int, int))
+{
+	struct item_data* item_data = itemdb_search(item->nameid);
+	int i;
+
+	if (!func(item_data, gmlv, gmlv2))
+		return 0;
+	
+	if(item_data->slot == 0 ||
+		item->card[0] ==(short)0xff00 ||
+		item->card[0]==0x00ff ||
+	  	item->card[0]==0x00fe)
+		return 1;
+	
+	for(i = 0; i < item_data->slot; i++) {
+		if (!item->card[i]) continue;
+		if (!func(itemdb_search(item->card[i]), gmlv, gmlv2))
+			return 0;
+	}
+	return 1;
+}
+
 /*==========================================
 /*==========================================
  *
  *
  *------------------------------------------
  *------------------------------------------

+ 15 - 7
src/map/itemdb.h

@@ -88,13 +88,21 @@ int itemdb_searchrandomid(int flags);
 #define itemdb_value_notoc(n) itemdb_search(n)->flag.value_notoc
 #define itemdb_value_notoc(n) itemdb_search(n)->flag.value_notoc
 #define itemdb_canrefine(n) itemdb_search(n)->flag.no_refine
 #define itemdb_canrefine(n) itemdb_search(n)->flag.no_refine
 //Item trade restrictions [Skotlex]
 //Item trade restrictions [Skotlex]
-int itemdb_isdropable(int nameid, int gmlv);
-int itemdb_cantrade(int nameid, int gmlv, int gmlv2);
-int itemdb_cansell(int nameid, int gmlv);
-int itemdb_canstore(int nameid, int gmlv);
-int itemdb_canguildstore(int nameid, int gmlv);
-int itemdb_cancartstore(int nameid, int gmlv);
-int itemdb_canpartnertrade(int nameid, int gmlv, int gmlv2);
+int itemdb_isdropable_sub(struct item_data *, int, int);
+int itemdb_cantrade_sub(struct item_data*, int, int);
+int itemdb_canpartnertrade_sub(struct item_data*, int, int);
+int itemdb_cansell_sub(struct item_data*,int, int);
+int itemdb_cancartstore_sub(struct item_data*, int, int);
+int itemdb_canstore_sub(struct item_data*, int, int);
+int itemdb_canguildstore_sub(struct item_data*, int, int);
+int itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(struct item_data*, int, int));
+#define itemdb_isdropable(item, gmlv) itemdb_isrestricted(item, gmlv, 0, itemdb_isdropable_sub)
+#define itemdb_cantrade(item, gmlv, gmlv2) itemdb_isrestricted(item, gmlv, gmlv2, itemdb_cantrade_sub)
+#define itemdb_canpartnertrade(item, gmlv, gmlv2) itemdb_isrestricted(item, gmlv, gmlv2, itemdb_canpartnertrade_sub)
+#define itemdb_cansell(item, gmlv) itemdb_isrestricted(item, gmlv, 0, itemdb_cansell_sub)
+#define itemdb_cancartstore(item, gmlv)  itemdb_isrestricted(item, gmlv, 0, itemdb_cancartstore_sub)
+#define itemdb_canstore(item, gmlv) itemdb_isrestricted(item, gmlv, 0, itemdb_canstore_sub) 
+#define itemdb_canguildstore(item, gmlv) itemdb_isrestricted(item , gmlv, 0, itemdb_canguildstore_sub) 
 
 
 int itemdb_isequip(int);
 int itemdb_isequip(int);
 int itemdb_isequip2(struct item_data *);
 int itemdb_isequip2(struct item_data *);

+ 4 - 4
src/map/pc.c

@@ -2672,7 +2672,7 @@ int pc_dropitem(struct map_session_data *sd,int n,int amount)
 		return 0; //Can't drop items in nodrop mapflag maps.
 		return 0; //Can't drop items in nodrop mapflag maps.
 	}
 	}
 	
 	
-	if (!pc_candrop(sd,sd->status.inventory[n].nameid)) {
+	if (!pc_candrop(sd,&sd->status.inventory[n])) {
 		clif_displaymessage (sd->fd, msg_txt(263));
 		clif_displaymessage (sd->fd, msg_txt(263));
 		return 0;
 		return 0;
 	}
 	}
@@ -2914,7 +2914,7 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun
 		return 1;
 		return 1;
 	data = itemdb_search(item_data->nameid);
 	data = itemdb_search(item_data->nameid);
 
 
-	if(!itemdb_cancartstore(item_data->nameid, pc_isGM(sd)))
+	if(!itemdb_cancartstore(item_data, pc_isGM(sd)))
 	{	//Check item trade restrictions	[Skotlex]
 	{	//Check item trade restrictions	[Skotlex]
 		clif_displaymessage (sd->fd, msg_txt(264));
 		clif_displaymessage (sd->fd, msg_txt(264));
 		return 1;
 		return 1;
@@ -5645,12 +5645,12 @@ int pc_setriding(struct map_session_data *sd)
  * アイテムドロップ可不可判定
  * アイテムドロップ可不可判定
  *------------------------------------------
  *------------------------------------------
  */
  */
-int pc_candrop(struct map_session_data *sd,int item_id)
+int pc_candrop(struct map_session_data *sd,struct item *item)
 {
 {
 	int level = pc_isGM(sd);
 	int level = pc_isGM(sd);
 	if ( pc_can_give_items(level) ) //check if this GM level can drop items
 	if ( pc_can_give_items(level) ) //check if this GM level can drop items
 		return 0;
 		return 0;
-	return (itemdb_isdropable(item_id, level));
+	return (itemdb_isdropable(item, level));
 }
 }
 
 
 /*==========================================
 /*==========================================

+ 1 - 1
src/map/pc.h

@@ -246,7 +246,7 @@ struct map_session_data *pc_get_child(struct map_session_data *sd);
 
 
 int pc_set_gm_level(int account_id, int level);
 int pc_set_gm_level(int account_id, int level);
 void pc_setstand(struct map_session_data *sd);
 void pc_setstand(struct map_session_data *sd);
-int pc_candrop(struct map_session_data *sd,int item_id);
+int pc_candrop(struct map_session_data *sd,struct item *item);
 
 
 int pc_jobid2mapid(unsigned short b_class);	// Skotlex
 int pc_jobid2mapid(unsigned short b_class);	// Skotlex
 int pc_mapid2jobid(unsigned short class_, int sex);	// Skotlex
 int pc_mapid2jobid(unsigned short class_, int sex);	// Skotlex

+ 1 - 1
src/map/script.c

@@ -3959,7 +3959,7 @@ int buildin_getitem(struct script_state *st)
 			return 0;
 			return 0;
 		if((flag = pc_additem(sd,&item_tmp,amount))) {
 		if((flag = pc_additem(sd,&item_tmp,amount))) {
 			clif_additem(sd,0,0,flag);
 			clif_additem(sd,0,0,flag);
-			if(pc_candrop(sd,nameid))
+			if (pc_candrop(sd, &item_tmp))
 				map_addflooritem(&item_tmp,amount,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0);
 				map_addflooritem(&item_tmp,amount,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0);
 		}
 		}
 
 

+ 2 - 2
src/map/storage.c

@@ -168,7 +168,7 @@ static int storage_additem(struct map_session_data *sd,struct storage *stor,stru
 	
 	
 	data = itemdb_search(item_data->nameid);
 	data = itemdb_search(item_data->nameid);
 
 
-	if (!itemdb_canstore(item_data->nameid, pc_isGM(sd)))
+	if (!itemdb_canstore(item_data, pc_isGM(sd)))
 	{	//Check if item is storable. [Skotlex]
 	{	//Check if item is storable. [Skotlex]
 		clif_displaymessage (sd->fd, msg_txt(264));
 		clif_displaymessage (sd->fd, msg_txt(264));
 		return 1;
 		return 1;
@@ -517,7 +517,7 @@ int guild_storage_additem(struct map_session_data *sd,struct guild_storage *stor
 	if(item_data->nameid <= 0 || amount <= 0)
 	if(item_data->nameid <= 0 || amount <= 0)
 		return 1;
 		return 1;
 
 
-	if (!itemdb_canguildstore(item_data->nameid, pc_isGM(sd)))
+	if (!itemdb_canguildstore(item_data, pc_isGM(sd)))
 	{	//Check if item is storable. [Skotlex]
 	{	//Check if item is storable. [Skotlex]
 		clif_displaymessage (sd->fd, msg_txt(264));
 		clif_displaymessage (sd->fd, msg_txt(264));
 		return 1;
 		return 1;

+ 8 - 5
src/map/trade.c

@@ -294,7 +294,8 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd) {
  */
  */
 void trade_tradeadditem(struct map_session_data *sd, int index, int amount) {
 void trade_tradeadditem(struct map_session_data *sd, int index, int amount) {
 	struct map_session_data *target_sd;
 	struct map_session_data *target_sd;
-	int trade_i, trade_weight, nameid;
+	struct item *item;
+	int trade_i, trade_weight;
 
 
 	nullpo_retv(sd);
 	nullpo_retv(sd);
 	if (!sd->state.trading || sd->state.deal_locked > 0)
 	if (!sd->state.trading || sd->state.deal_locked > 0)
@@ -324,10 +325,12 @@ void trade_tradeadditem(struct map_session_data *sd, int index, int amount) {
 	if (amount < 0 || amount > sd->status.inventory[index].amount)
 	if (amount < 0 || amount > sd->status.inventory[index].amount)
 		return;
 		return;
 
 
-	nameid = sd->inventory_data[index]->nameid;
-
-	if (!itemdb_cantrade(nameid, pc_isGM(sd), pc_isGM(target_sd)) &&	//Can't trade
-		(pc_get_partner(sd) != target_sd || !itemdb_canpartnertrade(nameid, pc_isGM(sd), pc_isGM(target_sd))))	//Can't partner-trade
+	item = &sd->status.inventory[index];
+	trade_i = pc_isGM(sd); //Recycling the variables to check for trad restrict.
+	trade_weight = pc_isGM(target_sd);
+	if (!itemdb_cantrade(item, trade_i, trade_weight) &&	//Can't trade
+		(pc_get_partner(sd) != target_sd ||
+		!itemdb_canpartnertrade(item, trade_i, trade_weight))) //Can't partner-trade
 	{
 	{
 		clif_displaymessage (sd->fd, msg_txt(260));
 		clif_displaymessage (sd->fd, msg_txt(260));
 		return;
 		return;

+ 1 - 1
src/map/vending.c

@@ -231,7 +231,7 @@ void vending_openvending(struct map_session_data *sd,int len,char *message,int f
 		for(i = 0, j = 0; (85 + 8 * j < len) && (i < MAX_VENDING); i++, j++) {
 		for(i = 0, j = 0; (85 + 8 * j < len) && (i < MAX_VENDING); i++, j++) {
 			sd->vending[i].index = *(short*)(p+8*j)-2;
 			sd->vending[i].index = *(short*)(p+8*j)-2;
 			if (sd->vending[i].index < 0 || sd->vending[i].index >= MAX_CART ||
 			if (sd->vending[i].index < 0 || sd->vending[i].index >= MAX_CART ||
-				!itemdb_cantrade(sd->status.cart[sd->vending[i].index].nameid, pc_isGM(sd), pc_isGM(sd)))
+				!itemdb_cantrade(&sd->status.cart[sd->vending[i].index], pc_isGM(sd), pc_isGM(sd)))
 			{
 			{
 				i--; //Preserve the vending index, skip to the next item.
 				i--; //Preserve the vending index, skip to the next item.
 				continue;
 				continue;