Prechádzať zdrojové kódy

- 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 rokov pred
rodič
commit
a4d0df735d
10 zmenil súbory, kde vykonal 64 pridanie a 36 odobranie
  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.
 
 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
 	  the minimum skill delay for all skills. Defaults to mobs, since they
 	  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;
 	for(i=0;i<MAX_INVENTORY;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;
 
 			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]
  *------------------------------------------
  */
-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));
 }
 
-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));
 }
 
-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));
 }
 
-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));
 }
 
-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));
 }
 
-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));
 }
 
-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));
 }
 
+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_canrefine(n) itemdb_search(n)->flag.no_refine
 //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_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.
 	}
 	
-	if (!pc_candrop(sd,sd->status.inventory[n].nameid)) {
+	if (!pc_candrop(sd,&sd->status.inventory[n])) {
 		clif_displaymessage (sd->fd, msg_txt(263));
 		return 0;
 	}
@@ -2914,7 +2914,7 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun
 		return 1;
 	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]
 		clif_displaymessage (sd->fd, msg_txt(264));
 		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);
 	if ( pc_can_give_items(level) ) //check if this GM level can drop items
 		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);
 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_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;
 		if((flag = pc_additem(sd,&item_tmp,amount))) {
 			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);
 		}
 

+ 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);
 
-	if (!itemdb_canstore(item_data->nameid, pc_isGM(sd)))
+	if (!itemdb_canstore(item_data, pc_isGM(sd)))
 	{	//Check if item is storable. [Skotlex]
 		clif_displaymessage (sd->fd, msg_txt(264));
 		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)
 		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]
 		clif_displaymessage (sd->fd, msg_txt(264));
 		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) {
 	struct map_session_data *target_sd;
-	int trade_i, trade_weight, nameid;
+	struct item *item;
+	int trade_i, trade_weight;
 
 	nullpo_retv(sd);
 	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)
 		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));
 		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++) {
 			sd->vending[i].index = *(short*)(p+8*j)-2;
 			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.
 				continue;