소스 검색

- Coded @reset.
- Reenabled @changesex
- Added function pet_create_egg which handles creating pet eggs correctly (when passed item id is indeed a valid petegg). Applied this on @createitem and getitem.
- Cleaned up code of @item
- Added define UNKNOWN_ITEM_ID (512 = apple)
- Added IT_* enumation item_Types to identify said data from items.
- Cleaned up the itemdb_isequip functions. itemdb_isequip will now return if the item is equipable by players, itemdb_isstackable returns if the item can be stacked, and itemdb_isidentified returns if the item should drop identified.
- Added defines CARD0_PET/CARD0_FORGE/CARD0_CREATED to identify if a given item has "invalid" cards, added define function itemdb_isspecial to simplify this check.
- Removed itemdb.c considering item ids above 20000 as invalid.
- Cleaned up script commands getitem and card-counting related ones.
- Cleaned up a bit more pc_isequip


git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@7613 54d463be-8e91-2dee-dedb-b68131a5f0ec

skotlex 19 년 전
부모
커밋
a6c3f3a1fc
18개의 변경된 파일430개의 추가작업 그리고 346개의 파일을 삭제
  1. 17 0
      Changelog-Trunk.txt
  2. 31 33
      src/map/atcommand.c
  3. 3 3
      src/map/charcommand.c
  4. 25 23
      src/map/clif.c
  5. 1 1
      src/map/intif.c
  6. 78 47
      src/map/itemdb.c
  7. 29 1
      src/map/itemdb.h
  8. 1 1
      src/map/map.c
  9. 14 14
      src/map/mob.c
  10. 1 1
      src/map/npc.c
  11. 33 41
      src/map/pc.c
  12. 18 4
      src/map/pet.c
  13. 1 0
      src/map/pet.h
  14. 167 165
      src/map/script.c
  15. 5 4
      src/map/skill.c
  16. 2 4
      src/map/status.c
  17. 2 2
      src/map/storage.c
  18. 2 2
      src/map/trade.c

+ 17 - 0
Changelog-Trunk.txt

@@ -5,6 +5,23 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 
 2006/07/11
+	* Coded @reset. [Skotlex]
+	* Reenabled @changesex [Skotlex]
+	* Added function pet_create_egg which handles creating pet eggs correctly
+	  (when passed item id is indeed a valid petegg). Applied this on @createitem
+	  and getitem. [Skotlex]
+	* Cleaned up code of @item [Skotlex]
+	* Cleaned up the itemdb_isequip functions. itemdb_isequip will now return
+	  if the item is equipable by players, itemdb_isstackable returns if the item
+	  can be stacked, and itemdb_isidentified returns if the item should drop
+	  identified. [Skotlex]
+	* Added defines CARD0_PET/CARD0_FORGE/CARD0_CREATED to identify if a given
+	  item has "invalid" cards, added define function itemdb_isspecial to
+	  simplify this check. [Skotlex]
+	* Removed itemdb.c considering item ids above 20000 as invalid. [Skotlex]
+	* Cleaned up script commands getitem and card-counting related ones.
+	  [Skotlex]
+	* Cleaned up a bit more pc_isequip [Skotlex]
 	* Added script function warpportal(x,y,targetmap$,targetx,targety).
 	  This creates warp portals as in the skill unit as a volatile alternative
 	  to static warp portals. [blackhole89]

+ 31 - 33
src/map/atcommand.c

@@ -215,6 +215,7 @@ ACMD_FUNC(cleanmap);
 ACMD_FUNC(npctalk);
 ACMD_FUNC(pettalk);
 ACMD_FUNC(users);
+ACMD_FUNC(reset);
 ACMD_FUNC(autoloot);  // Improved version imported from Freya.
 
 #ifndef TXT_ONLY
@@ -510,7 +511,7 @@ static AtCommandInfo atcommand_info[] = {
 	{ AtCommand_UnMute,			"@unmute",			60, atcommand_unmute }, // [Valaris]
 	{ AtCommand_Clearweather,		"@clearweather",		99, atcommand_clearweather }, // Dexity
 	{ AtCommand_UpTime,			"@uptime",			 1, atcommand_uptime }, // by MC Cameri
-//	{ AtCommand_ChangeSex,			"@changesex",		 1, atcommand_changesex }, // by MC Cameri <- do we still need this? [Foruken]
+	{ AtCommand_ChangeSex,			"@changesex",		 60, atcommand_changesex }, // by MC Cameri <- do we still need this? [Foruken] <- why not? [Skotlex]
 	{ AtCommand_Mute,				"@mute",			99, atcommand_mute }, // [celest]
 	{ AtCommand_Mute,				"@red",			99, atcommand_mute }, // [celest]
 	{ AtCommand_WhoZeny,			"@whozeny",			20, atcommand_whozeny }, // [Valaris]
@@ -525,7 +526,7 @@ static AtCommandInfo atcommand_info[] = {
 	{ AtCommand_NpcTalk,			"@npctalk",			20, atcommand_npctalk },
 	{ AtCommand_PetTalk,			"@pettalk",			10, atcommand_pettalk },
 	{ AtCommand_Users,			"@users",			40, atcommand_users },
-	{ AtCommand_ResetState,			"/reset",			40, NULL },
+	{ AtCommand_ResetState,			"@reset",			40, atcommand_reset },
 
 #ifndef TXT_ONLY // sql-only commands
 	{ AtCommand_CheckMail,			"@checkmail",		 1, atcommand_listmail }, // [Valaris]
@@ -2543,7 +2544,7 @@ int atcommand_item(
 	int number = 0, item_id, flag;
 	struct item item_tmp;
 	struct item_data *item_data;
-	int get_count, i, pet_id;
+	int get_count, i;
 	nullpo_retr(-1, sd);
 
 	memset(item_name, '\0', sizeof(item_name));
@@ -2565,24 +2566,14 @@ int atcommand_item(
 
 	item_id = item_data->nameid;
 	get_count = number;
-	// check pet egg
-	pet_id = search_petDB_index(item_id, PET_EGG);
+	//Check if it's stackable.
 	if (item_data->type == 4 || item_data->type == 5 ||
 		item_data->type == 7 || item_data->type == 8) {
 		get_count = 1;
 	}
 	for (i = 0; i < number; i += get_count) {
-		// if pet egg
-		if (pet_id >= 0) {
-			sd->catch_target_class = pet_db[pet_id].class_;
-			intif_create_pet(sd->status.account_id, sd->status.char_id,
-				(short)pet_db[pet_id].class_,
-				(short)mob_db(pet_db[pet_id].class_)->lv,
-				(short)pet_db[pet_id].EggID, 0,
-			  	(short)pet_db[pet_id].intimate,
-				100, 0, 1, pet_db[pet_id].jname);
 		// if not pet egg
-		} else {
+		if (!pet_create_egg(sd, item_id)) {
 			memset(&item_tmp, 0, sizeof(item_tmp));
 			item_tmp.nameid = item_id;
 			item_tmp.identify = 1;
@@ -3831,15 +3822,15 @@ int atcommand_produce(
 	}
 
 	item_id = 0;
-	if ((item_data = itemdb_searchname(item_name)) != NULL ||
-	    (item_data = itemdb_exists(atoi(item_name))) != NULL)
-		item_id = item_data->nameid;
-
-	if (itemdb_exists(item_id) &&
-	    (item_id <= 500 || item_id > 1099) &&
-	    (item_id < 4001 || item_id > 4148) &&
-	    (item_id < 7001 || item_id > 10019) &&
-	    itemdb_isequip(item_id)) {
+	if ((item_data = itemdb_searchname(item_name)) == NULL &&
+	    (item_data = itemdb_exists(atoi(item_name))) == NULL)
+	{
+		sprintf(atcmd_output, msg_table[170]); // This item is not an equipment.
+		clif_displaymessage(fd, atcmd_output);
+		return -1;
+	}
+	item_id = item_data->nameid;
+	if (itemdb_isequip2(item_data) && item_data->type == IT_WEAPON) {
 		if (attribute < MIN_ATTRIBUTE || attribute > MAX_ATTRIBUTE)
 			attribute = ATTRIBUTE_NORMAL;
 		if (star < MIN_STAR || star > MAX_STAR)
@@ -3848,12 +3839,12 @@ int atcommand_produce(
 		tmp_item.nameid = item_id;
 		tmp_item.amount = 1;
 		tmp_item.identify = 1;
-		tmp_item.card[0] = 0x00ff;
+		tmp_item.card[0] = CARD0_FORGE;
 		tmp_item.card[1] = ((star * 5) << 8) + attribute;
 		tmp_item.card[2] = GetWord(sd->char_id, 0);
 		tmp_item.card[3] = GetWord(sd->char_id, 1);
-		clif_produceeffect(sd, 0, item_id); // 製造エフェクトパケット
-		clif_misceffect(&sd->bl, 3); // 他人にも成功を通知
+		clif_produceeffect(sd, 0, item_id);
+		clif_misceffect(&sd->bl, 3);
 
 		//Logs (A)dmins items [Lupus]
 		if(log_config.pick > 0 ) {
@@ -3864,12 +3855,7 @@ int atcommand_produce(
 		if ((flag = pc_additem(sd, &tmp_item, 1)))
 			clif_additem(sd, 0, 0, flag);
 	} else {
-		if (battle_config.error_log)
-			ShowError("@produce NOT WEAPON [%d]\n", item_id);
-		if (item_id != 0 && itemdb_exists(item_id))
-			sprintf(atcmd_output, msg_table[169], item_id, item_data->name); // This item (%d: '%s') is not an equipment.
-		else
-			sprintf(atcmd_output, msg_table[170]); // This item is not an equipment.
+		sprintf(atcmd_output, msg_table[169], item_id, item_data->name); // This item (%d: '%s') is not an equipment.
 		clif_displaymessage(fd, atcmd_output);
 		return -1;
 	}
@@ -8187,6 +8173,18 @@ atcommand_users(
 	return 0;
 }
 
+int
+atcommand_reset(
+	const int fd, struct map_session_data* sd,
+	const char* command, const char* message)
+{
+	pc_resetstate(sd);
+	pc_resetskill(sd,1);
+	sprintf(atcmd_output, msg_table[208], sd->status.name); // '%s' skill and stats points reseted!
+	clif_displaymessage(fd, atcmd_output);
+	return 0;
+}
+
 /*==========================================
  *
  *------------------------------------------

+ 3 - 3
src/map/charcommand.c

@@ -817,17 +817,17 @@ charcommand_itemlist(
 					memset(output, '\0', sizeof(output));
 					counter2 = 0;
 
-					if(i_item->card[0]==(short)0xff00) { //pet eggs
+					if(i_item->card[0]==CARD0_PET) { //pet eggs
 						if (i_item->card[3])
 							sprintf(outputtmp, " -> (pet egg, pet id: %u, named)", (unsigned int)MakeDWord(i_item->card[1], i_item->card[2]));
 						else
 							sprintf(outputtmp, " -> (pet egg, pet id: %u, unnamed)", (unsigned int)MakeDWord(i_item->card[1], i_item->card[2]));
 						strcat(output, outputtmp);
 					} else
-					if(i_item->card[0]==0x00ff) { //forged items.
+					if(i_item->card[0]==CARD0_FORGE) { //forged items.
 						sprintf(outputtmp, " -> (crafted item, creator id: %u, star crumbs %d, element %d)", (unsigned int)MakeDWord(i_item->card[2], i_item->card[3]), i_item->card[1]>>8, i_item->card[1]&0x0f);
 					} else
-					if(i_item->card[0]==0x00fe) { //created items.
+					if(i_item->card[0]==CARD0_CREATE) { //created items.
 						sprintf(outputtmp, " -> (produced item, creator id: %u)", (unsigned int)MakeDWord(i_item->card[2], i_item->card[3]));
 						strcat(output, outputtmp);
 					} else //Normal slots

+ 25 - 23
src/map/clif.c

@@ -2097,14 +2097,14 @@ static void clif_addcards(unsigned char* buf, struct item* item)
 		WBUFW(buf,6)=0;
 		return;
 	}
-	if(item->card[0]==(short)0xff00) { //pet eggs
+	if(item->card[0]==CARD0_PET) { //pet eggs
 		WBUFW(buf,0)=0;
 		WBUFW(buf,2)=0;
 		WBUFW(buf,4)=0;
 		WBUFW(buf,6)=item->card[3]; //Pet renamed flag.
 		return;
 	}
-	if(item->card[0]==0x00ff || item->card[0]==0x00fe) { //Forged/created items
+	if(item->card[0]==CARD0_FORGE || item->card[0]==CARD0_CREATE) { //Forged/created items
 		WBUFW(buf,0)=item->card[0];
 		WBUFW(buf,2)=item->card[1];
 		WBUFW(buf,4)=item->card[2];
@@ -2257,8 +2257,8 @@ void clif_inventorylist(struct map_session_data *sd)
 		if (sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL)
 			continue;  
 	
-		if(itemdb_isequip2(sd->inventory_data[i])) 
-		{	//Equippable
+		if(!itemdb_isstackable2(sd->inventory_data[i])) 
+		{	//Non-stackable (Equippable)
 			WBUFW(bufe,ne*20+4)=i+2;
 			clif_item_sub(bufe, ne*20+6, &sd->status.inventory[i], sd->inventory_data[i], pc_equippoint(sd,i));
 			clif_addcards(WBUFP(bufe, ne*20+16), &sd->status.inventory[i]);
@@ -2307,7 +2307,7 @@ void clif_equiplist(struct map_session_data *sd)
 		if (sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL)
 			continue;  
 	
-		if(!itemdb_isequip2(sd->inventory_data[i])) 
+		if(itemdb_isstackable2(sd->inventory_data[i])) 
 			continue;
 		//Equippable
 		WBUFW(buf,n*20+4)=i+2;
@@ -2341,7 +2341,7 @@ void clif_storagelist(struct map_session_data *sd,struct storage *stor)
 		if(stor->storage_[i].nameid<=0)
 			continue;
 		id = itemdb_search(stor->storage_[i].nameid);
-		if(itemdb_isequip2(id))
+		if(!itemdb_isstackable2(id))
 		{ //Equippable
 			WBUFW(bufe,ne*20+4)=i+1;
 			clif_item_sub(bufe, ne*20+6, &stor->storage_[i], id, id->equip);
@@ -2391,7 +2391,7 @@ void clif_guildstoragelist(struct map_session_data *sd,struct guild_storage *sto
 		if(stor->storage_[i].nameid<=0)
 			continue;
 		id = itemdb_search(stor->storage_[i].nameid);
-		if(itemdb_isequip2(id))
+		if(!itemdb_isstackable2(id))
 		{ //Equippable
 			WBUFW(bufe,ne*20+4)=i+1;
 			clif_item_sub(bufe, ne*20+6, &stor->storage_[i], id, id->equip);
@@ -2440,7 +2440,7 @@ void clif_cartlist(struct map_session_data *sd)
 		if(sd->status.cart[i].nameid<=0)
 			continue;
 		id = itemdb_search(sd->status.cart[i].nameid);
-		if(itemdb_isequip2(id))
+		if(!itemdb_isstackable2(id))
 		{ //Equippable
 			WBUFW(bufe,ne*20+4)=i+2;
 			clif_item_sub(bufe, ne*20+6, &sd->status.cart[i], id, id->equip);
@@ -5233,7 +5233,7 @@ int clif_use_card(struct map_session_data *sd,int idx)
 	if (idx < 0 || idx >= MAX_INVENTORY) //Crash-fix from bad packets.
 		return 0;
 
-	if (!sd->inventory_data[idx] || sd->inventory_data[idx]->type != 6)
+	if (!sd->inventory_data[idx] || sd->inventory_data[idx]->type != IT_CARD)
 		return 0; //Avoid parsing invalid item indexes (no card/no item)
 			
 	ep=sd->inventory_data[idx]->equip;
@@ -5245,22 +5245,25 @@ int clif_use_card(struct map_session_data *sd,int idx)
 
 		if(sd->inventory_data[i] == NULL)
 			continue;
-		if(sd->inventory_data[i]->type!=4 && sd->inventory_data[i]->type!=5)	// 武器防具じゃない
+		if(sd->inventory_data[i]->type!=IT_WEAPON && sd->inventory_data[i]->type!=IT_ARMOR)
 			continue;
-		if(sd->status.inventory[i].card[0]==0x00ff || sd->status.inventory[i].card[0]==(short)0xff00 || sd->status.inventory[i].card[0]==0x00fe)
+		if(itemdb_isspecial(sd->status.inventory[i].card[0])) //Can't slot it
 			continue;
-		if(sd->status.inventory[i].identify==0 )	// 未鑑定
+
+		if(sd->status.inventory[i].identify==0 )	//Not identified
 			continue;
 
-		if((sd->inventory_data[i]->equip&ep)==0)	// 装備個所が違う
+		if((sd->inventory_data[i]->equip&ep)==0)	//Not equippable on this part.
 			continue;
-		if(sd->inventory_data[i]->type==4 && ep==32)	// 盾カードと両手武器
+
+		if(sd->inventory_data[i]->type==IT_WEAPON && ep==EQP_HAND_L) //Shield card won't go on left weapon.
 			continue;
+
 		for(j=0;j<sd->inventory_data[i]->slot;j++){
 			if( sd->status.inventory[i].card[j]==0 )
 				break;
 		}
-		if(j==sd->inventory_data[i]->slot)	// すでにカードが一杯
+		if(j==sd->inventory_data[i]->slot)	// No room
 			continue;
 
 		WFIFOW(fd,4+c*2)=i+2;
@@ -9177,14 +9180,13 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd)
 	}
 	//ペット用装備であるかないか
 	if(sd->inventory_data[index]) {
-		if(sd->inventory_data[index]->type != 8){
-			if(sd->inventory_data[index]->type == 10)
-				RFIFOW(fd,4)=0x8000;	// 矢を無理やり装備できるように(--;
-			pc_equipitem(sd,index,RFIFOW(fd,4));
-		} else{
-			if(sd->pd)
-				pet_equipitem(sd,index);
-		}
+		if(sd->inventory_data[index]->type != IT_PETARMOR){
+			if(sd->inventory_data[index]->type == IT_AMMO)
+				pc_equipitem(sd,index,EQP_AMMO); //Client doesn't sends the position.
+			else
+				pc_equipitem(sd,index,RFIFOW(fd,4));
+		} else
+			pet_equipitem(sd,index);
 	}
 }
 

+ 1 - 1
src/map/intif.c

@@ -108,7 +108,7 @@ int intif_delete_petdata(int pet_id)
 	WFIFOL(inter_fd,2) = pet_id;
 	WFIFOSET(inter_fd,6);
 
-	return 0;
+	return 1;
 }
 int intif_rename_pet(struct map_session_data *sd,char *name)
 {

+ 78 - 47
src/map/itemdb.c

@@ -102,14 +102,14 @@ int itemdb_searchrandomid(int group)
 	if(group<1 || group>=MAX_ITEMGROUP) {
 		if (battle_config.error_log)
 			ShowError("itemdb_searchrandomid: Invalid group id %d\n", group);
-		return 512; //Return apple?
+		return UNKNOWN_ITEM_ID;
 	}
 	if (itemgroup_db[group].qty)
 		return itemgroup_db[group].nameid[rand()%itemgroup_db[group].qty];
 	
 	if (battle_config.error_log)
 		ShowError("itemdb_searchrandomid: No item entries for group id %d\n", group);
-	return 512;
+	return UNKNOWN_ITEM_ID;
 }
 
 /*==========================================
@@ -210,7 +210,7 @@ static void create_dummy_data(void) {
 	dummy_item.type=3; //Etc item
 	strncpy(dummy_item.name,"UNKNOWN_ITEM",ITEM_NAME_LENGTH-1);
 	strncpy(dummy_item.jname,"UNKNOWN_ITEM",ITEM_NAME_LENGTH-1);
-	dummy_item.view_id = 512; //Use apple sprite.
+	dummy_item.view_id = UNKNOWN_ITEM_ID;
 }
 
 static void* create_item_data(DBKey key, va_list args) {
@@ -218,7 +218,7 @@ static void* create_item_data(DBKey key, va_list args) {
 	id=(struct item_data *)aCalloc(1,sizeof(struct item_data));
 	id->nameid = key.i;
 	id->weight=1;
-	id->type=3; //Etc item
+	id->type=IT_ETC;
 	return id;
 }
 
@@ -256,46 +256,76 @@ struct item_data* itemdb_search(int nameid)
 }
 
 /*==========================================
- *
+ * Returns if given item is a player-equippable piece.
  *------------------------------------------
  */
 int itemdb_isequip(int nameid)
 {
 	int type=itemdb_type(nameid);
-	if(type==0 || type==2 || type==3 || type==6 || type==10)
-		return 0;
-	return 1;
+	switch (type) {
+		case IT_WEAPON:
+		case IT_ARMOR:
+		case IT_AMMO:
+			return 1;
+		default:
+			return 0;
+	}
 }
+
 /*==========================================
- *
+ * Alternate version of itemdb_isequip
  *------------------------------------------
  */
 int itemdb_isequip2(struct item_data *data)
 { 
 	nullpo_retr(0, data);
 	switch(data->type) {
-		case 0:
-		case 2:
-		case 3:
-		case 6:
-		case 10:
-			return 0;
-		default:
-			return 1;
-	}
-}
-//Checks if the item is pet-equipment (7/8)
-static int itemdb_ispetequip(struct item_data *data)
-{ 
-	switch(data->type) {
-		case 7:
-		case 8:
+		case IT_WEAPON:
+		case IT_ARMOR:
+		case IT_AMMO:
 			return 1;
 		default:
 			return 0;
 	}
 }
 
+/*==========================================
+* Returns if given item's type is stackable.
+*------------------------------------------
+*/
+int itemdb_isstackable(int nameid)
+{
+  int type=itemdb_type(nameid);
+  switch(type) {
+	  case IT_WEAPON:
+	  case IT_ARMOR:
+	  case IT_PETEGG:
+	  case IT_PETARMOR:
+		  return 0;
+	  default:
+		  return 1;
+  }
+}
+
+/*==========================================
+* Alternate version of itemdb_isstackable
+*------------------------------------------
+*/
+int itemdb_isstackable2(struct item_data *data)
+{
+  nullpo_retr(0, data);
+  switch(data->type) {
+	  case IT_WEAPON:
+	  case IT_ARMOR:
+	  case IT_PETEGG:
+	  case IT_PETARMOR:
+		  return 0;
+	  default:
+		  return 1;
+  }
+}
+
+
 /*==========================================
  * Trade Restriction functions [Skotlex]
  *------------------------------------------
@@ -343,10 +373,7 @@ int itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(stru
 	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)
+	if(item_data->slot == 0 || itemdb_isspecial(item->card[0]))
 		return 1;
 	
 	for(i = 0; i < item_data->slot; i++) {
@@ -358,15 +385,20 @@ int itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(stru
 }
 
 /*==========================================
- *
+ *	Specifies if item-type should drop unidentified.
  *------------------------------------------
  */
-int itemdb_isequip3(int nameid)
+int itemdb_isidentified(int nameid)
 {
 	int type=itemdb_type(nameid);
-	if(type==4 || type==5 || type == 8)
-		return 1;
-	return 0;
+	switch (type) {
+		case IT_WEAPON:
+		case IT_ARMOR:
+		case IT_PETARMOR:
+			return 0;
+		default:
+			return 1;
+	}
 }
 
 /*==========================================
@@ -704,7 +736,7 @@ static int itemdb_read_noequip(void)
 			continue;
 
 		nameid=atoi(str[0]);
-		if(nameid<=0 || nameid>=20000 || !(id=itemdb_exists(nameid)))
+		if(nameid<=0 || !(id=itemdb_exists(nameid)))
 			continue;
 
 		id->flag.no_equip=atoi(str[1]);
@@ -747,7 +779,7 @@ static int itemdb_read_itemtrade(void)
 		}
 
 		if (j < 3 || str[0] == NULL ||
-			(nameid = atoi(str[0])) < 0 || nameid >= 20000 || !(id = itemdb_exists(nameid)))
+			(nameid = atoi(str[0])) < 0 || !(id = itemdb_exists(nameid)))
 			continue;
 
 		flag = atoi(str[1]);
@@ -775,9 +807,9 @@ static int itemdb_gendercheck(struct item_data *id)
 		return 1;
 	if (id->nameid == WEDDING_RING_F) //Bride Ring
 		return 0;
-	if (id->look == 13 && id->type == 4) //Musical instruments are always male-only
+	if (id->look == W_MUSICAL && id->type == IT_WEAPON) //Musical instruments are always male-only
 		return 1;
-	if (id->look == 14 && id->type == 4) //Whips are always female-only
+	if (id->look == W_WHIP && id->type == IT_WEAPON) //Whips are always female-only
 		return 0;
 
 	return (battle_config.ignore_items_gender?2:id->sex);
@@ -837,7 +869,7 @@ static int itemdb_read_sqldb(void)
 					nameid = atoi(sql_row[0]);
 
 					// If the identifier is not within the valid range, process the next row
-					if (nameid == 0 || nameid >= 20000)
+					if (nameid == 0)
 						continue;
 
 					ln++;
@@ -849,10 +881,10 @@ static int itemdb_read_sqldb(void)
 					strncpy(id->jname, sql_row[2], ITEM_NAME_LENGTH-1);
 
 					id->type = atoi(sql_row[3]);
-					if (id->type == 11)
+					if (id->type == IT_DELAYCONSUME)
 					{	//Items that are consumed upon target confirmation
 						//(yggdrasil leaf, spells & pet lures) [Skotlex]
-						id->type = 2;
+						id->type = IT_USABLE;
 						id->flag.delay_consume=1;
 					}
 
@@ -891,7 +923,7 @@ static int itemdb_read_sqldb(void)
 					id->class_upper= (sql_row[12] != NULL) ? atoi(sql_row[12]) : 0;
 					id->sex		= (sql_row[13] != NULL) ? atoi(sql_row[13]) : 0;
 					id->equip	= (sql_row[14] != NULL) ? atoi(sql_row[14]) : 0;
-					if (!id->equip && itemdb_isequip2(id) && !itemdb_ispetequip(id))
+					if (!id->equip && itemdb_isequip2(id))
 					{
 						ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname);
 						id->type = 3;
@@ -1018,10 +1050,10 @@ static int itemdb_readdb(void)
 			strncpy(id->name, str[1], ITEM_NAME_LENGTH-1);
 			strncpy(id->jname, str[2], ITEM_NAME_LENGTH-1);
 			id->type=atoi(str[3]);
-			if (id->type == 11)
+			if (id->type == IT_DELAYCONSUME)
 			{	//Items that are consumed upon target confirmation
 				//(yggdrasil leaf, spells & pet lures) [Skotlex]
-				id->type = 2;
+				id->type = IT_USABLE;
 				id->flag.delay_consume=1;
 			}
 
@@ -1063,7 +1095,7 @@ static int itemdb_readdb(void)
 			if(id->equip != atoi(str[14])){
 				id->equip=atoi(str[14]);
 			}
-			if (!id->equip && itemdb_isequip2(id) && !itemdb_ispetequip(id))
+			if (!id->equip && itemdb_isequip2(id))
 			{
 				ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname);
 				id->type = 3;
@@ -1201,8 +1233,7 @@ static int itemdb_final_sub (DBKey key,void *data,va_list ap)
 
 void itemdb_reload(void)
 {
-	// free up all item scripts first
-	item_db->foreach(item_db, itemdb_final_sub, 0);
+	//Just read, the function takes care of freeing scripts.
 	itemdb_read();
 }
 

+ 29 - 1
src/map/itemdb.h

@@ -7,6 +7,32 @@
 #include "map.h"
 #define MAX_RANDITEM	10000
 
+enum {
+	IT_HEALING = 0,
+	IT_UNKNOWN, //1
+	IT_USABLE,  //2
+	IT_ETC,     //3
+	IT_WEAPON,  //4
+	IT_ARMOR,   //5
+	IT_CARD,    //6
+	IT_PETEGG,  //7
+	IT_PETARMOR,//8
+	IT_UNKNOWN2,//9
+	IT_AMMO,    //10
+	IT_DELAYCONSUME,//11
+	IT_MAX 
+} item_types;
+
+#define CARD0_FORGE 0x00FF
+#define CARD0_CREATE 0x00FE
+#define CARD0_PET ((short)0xFF00)
+
+//Marks if the card0 given is "special" (non-item id used to mark pets/created items. [Skotlex]
+#define itemdb_isspecial(i) (i == CARD0_FORGE || i == CARD0_CREATE || i == CARD0_PET)
+
+//Use apple for unknown items.
+#define UNKNOWN_ITEM_ID 512
+
 struct item_data {
 	int nameid;
 	char name[ITEM_NAME_LENGTH],jname[ITEM_NAME_LENGTH];
@@ -106,7 +132,9 @@ int itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(stru
 
 int itemdb_isequip(int);
 int itemdb_isequip2(struct item_data *);
-int itemdb_isequip3(int);
+int itemdb_isidentified(int);
+int itemdb_isstackable(int);
+int itemdb_isstackable2(struct item_data *);
 
 // itemdb_equipマクロとitemdb_equippointとの違いは
 // 前者が鯖側dbで定義された値そのものを返すのに対し

+ 1 - 1
src/map/map.c

@@ -1391,7 +1391,7 @@ int map_clearflooritem_timer(int tid,unsigned int tick,int id,int data) {
 	}
 	if(data)
 		delete_timer(fitem->cleartimer,map_clearflooritem_timer);
-	else if(fitem->item_data.card[0] == (short)0xff00)
+	else if(fitem->item_data.card[0] == CARD0_PET)
 		intif_delete_petdata( MakeDWord(fitem->item_data.card[1],fitem->item_data.card[2]) );
 	clif_clearflooritem(fitem,0);
 	map_delobject(fitem->bl.id);

+ 14 - 14
src/map/mob.c

@@ -1415,7 +1415,7 @@ static struct item_drop* mob_setdropitem(int nameid, int qty)
 	memset(&drop->item_data, 0, sizeof(struct item));
 	drop->item_data.nameid = nameid;
 	drop->item_data.amount = qty;
-	drop->item_data.identify = !itemdb_isequip3(nameid);
+	drop->item_data.identify = itemdb_isidentified(nameid);
 	drop->next = NULL;
 	return drop;
 };
@@ -2043,7 +2043,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 
 			memset(&item,0,sizeof(item));
 			item.nameid=md->db->mvpitem[i].nameid;
-			item.identify=!itemdb_isequip3(item.nameid);
+			item.identify= itemdb_isidentified(item.nameid);
 			clif_mvp_item(mvp_sd,item.nameid);
 			log_mvp[0] = item.nameid;
 			
@@ -3278,7 +3278,7 @@ static int mob_readdb(void)
 				}
 				else switch (type)	// Added suport to restrict normal drops of MVP's [Reddozen]
 				{
-				case 0:
+				case IT_HEALING:
 					if (status->mode&MD_BOSS)
 						rate_adjust = battle_config.item_rate_heal_boss;
 					else
@@ -3286,7 +3286,7 @@ static int mob_readdb(void)
 					ratemin = battle_config.item_drop_heal_min;
 					ratemax = battle_config.item_drop_heal_max;
 					break;
-				case 2:
+				case IT_USABLE:
 					if (status->mode&MD_BOSS)
 						rate_adjust = battle_config.item_rate_use_boss;
 					else
@@ -3294,9 +3294,9 @@ static int mob_readdb(void)
 					ratemin = battle_config.item_drop_use_min;
 					ratemax = battle_config.item_drop_use_max;
 					break;
-				case 4:
-				case 5:
-				case 8:		// Changed to include Pet Equip
+				case IT_WEAPON:
+				case IT_ARMOR:
+				case IT_PETARMOR:		// Changed to include Pet Equip
 					if (status->mode&MD_BOSS)
 						rate_adjust = battle_config.item_rate_equip_boss;
 					else
@@ -3304,7 +3304,7 @@ static int mob_readdb(void)
 					ratemin = battle_config.item_drop_equip_min;
 					ratemax = battle_config.item_drop_equip_max;
 					break;
-				case 6:
+				case IT_CARD:
 					if (status->mode&MD_BOSS)
 						rate_adjust = battle_config.item_rate_card_boss;
 					else
@@ -3958,7 +3958,7 @@ static int mob_read_sqldb(void)
 					}
 					else switch (type)	// Added suport to restrict normal drops of MVP's [Reddozen]
 					{
-					case 0:	// Val added heal restrictions
+					case IT_HEALING:	// Val added heal restrictions
 						if (status->mode&MD_BOSS)
 							rate_adjust = battle_config.item_rate_heal_boss;
 						else
@@ -3966,7 +3966,7 @@ static int mob_read_sqldb(void)
 						ratemin = battle_config.item_drop_heal_min;
 						ratemax = battle_config.item_drop_heal_max;
 						break;
-					case 2:
+					case IT_USABLE:
 						if (status->mode&MD_BOSS)
 							rate_adjust = battle_config.item_rate_use_boss;
 						else
@@ -3974,9 +3974,9 @@ static int mob_read_sqldb(void)
 						ratemin = battle_config.item_drop_use_min;
 						ratemax = battle_config.item_drop_use_max;
 						break;
-					case 4:
-					case 5:
-					case 8:		// Changed to include Pet Equip
+					case IT_WEAPON:
+					case IT_ARMOR:
+					case IT_PETEQUIP:		// Changed to include Pet Equip
 						if (status->mode&MD_BOSS)
 							rate_adjust = battle_config.item_rate_equip_boss;
 						else
@@ -3984,7 +3984,7 @@ static int mob_read_sqldb(void)
 						ratemin = battle_config.item_drop_equip_min;
 						ratemax = battle_config.item_drop_equip_max;
 						break;
-					case 6:
+					case IT_CARD:
 						if (status->mode&MD_BOSS)
 							rate_adjust = battle_config.item_rate_card_boss;
 						else

+ 1 - 1
src/map/npc.c

@@ -1198,7 +1198,7 @@ int npc_buylist(struct map_session_data *sd,int n,unsigned short *item_list)
 		if (nd->u.shop_item[j].nameid==0)
 			return 3;
 		
-		if (itemdb_isequip3(nd->u.shop_item[j].nameid) && item_list[i*2] > 1)
+		if (itemdb_isstackable(nd->u.shop_item[j].nameid) && item_list[i*2] > 1)
 		{	//Exploit? You can't buy more than 1 of equipment types o.O
 			ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n",
 				sd->status.name, sd->status.account_id, sd->status.char_id, item_list[i*2], nd->u.shop_item[j].nameid);

+ 33 - 41
src/map/pc.c

@@ -386,14 +386,18 @@ int pc_equippoint(struct map_session_data *sd,int n)
 
 	nullpo_retr(0, sd);
 
-	if(sd->inventory_data[n]) {
-		ep = sd->inventory_data[n]->equip;
-		if(sd->inventory_data[n]->look == W_DAGGER	||
-			sd->inventory_data[n]->look == W_1HSWORD ||
-			sd->inventory_data[n]->look == W_1HAXE) {
-			if(ep == EQP_HAND_R && (pc_checkskill(sd,AS_LEFT) > 0 || (sd->class_&MAPID_UPPERMASK) == MAPID_ASSASSIN))
-				return EQP_WEAPON;
-		}
+	if(!sd->inventory_data[n])
+		return 0;
+
+	if (!itemdb_isequip2(sd->inventory_data[n]))
+		return 0; //Not equippable by players.
+	
+	ep = sd->inventory_data[n]->equip;
+	if(sd->inventory_data[n]->look == W_DAGGER	||
+		sd->inventory_data[n]->look == W_1HSWORD ||
+		sd->inventory_data[n]->look == W_1HAXE) {
+		if(ep == EQP_HAND_R && (pc_checkskill(sd,AS_LEFT) > 0 || (sd->class_&MAPID_UPPERMASK) == MAPID_ASSASSIN))
+			return EQP_WEAPON;
 	}
 	return ep;
 }
@@ -487,11 +491,8 @@ static int pc_isAllowedCardOn(struct map_session_data *sd,int s,int eqindex,int
 	int i;
 	struct item *item = &sd->status.inventory[eqindex];
 	struct item_data *data;
-	if (	//Crafted/made/hatched items.
-		item->card[0]==0x00ff ||
-		item->card[0]==0x00fe ||
-		item->card[0]==(short)0xff00
-	)
+	//Crafted/made/hatched items.
+	if (itemdb_isspecial(item->card[0]))
 		return 1;
 	
 	for (i=0;i<s;i++)	{
@@ -2380,26 +2381,23 @@ int pc_insert_card(struct map_session_data *sd,int idx_card,int idx_equip)
 	cardid=sd->status.inventory[idx_card].nameid;
 	ep=sd->inventory_data[idx_card]->equip;
 
+	//Check validity
 	if( nameid <= 0 || cardid <= 0 ||
-		(sd->inventory_data[idx_equip]->type!=4 && sd->inventory_data[idx_equip]->type!=5)||	// ? 備じゃない
-		sd->inventory_data[idx_card]->type!=6 || // Prevent Hack [Ancyker]
-		sd->status.inventory[idx_equip].identify==0 ||		// 未鑑定
-		sd->status.inventory[idx_equip].card[0]==0x00ff ||		// 製造武器
-		sd->status.inventory[idx_equip].card[0]==0x00fe ||
-		sd->status.inventory[idx_equip].card[0]==(short)0xff00 ||
-		!(sd->inventory_data[idx_equip]->equip&ep) ||					// ? 備個所違い
-		(sd->inventory_data[idx_equip]->type==4 && ep==EQP_SHIELD) ||			// ? 手武器と盾カ?ド
+		(sd->inventory_data[idx_equip]->type!=IT_WEAPON && sd->inventory_data[idx_equip]->type!=IT_WEAPON)||
+		sd->inventory_data[idx_card]->type!=IT_CARD || // Prevent Hack [Ancyker]
+		sd->status.inventory[idx_equip].identify==0 ||
+		itemdb_isspecial(sd->status.inventory[idx_equip].card[0]) ||
+		!(sd->inventory_data[idx_equip]->equip&ep) ||
+		(sd->inventory_data[idx_equip]->type==IT_WEAPON && ep==EQP_SHIELD) || //Card shield attempted to place on left-hand weapon.
 		sd->status.inventory[idx_equip].equip){
 
 		clif_insert_card(sd,idx_equip,idx_card,1);
 		return 0;
 	}
 	for(i=0;i<sd->inventory_data[idx_equip]->slot;i++){
-		if( sd->status.inventory[idx_equip].card[i] == 0){
-		// 空きスロットが� ったので差し?む
+		if( sd->status.inventory[idx_equip].card[i] == 0)
+		{	//Free slot found.
 			sd->status.inventory[idx_equip].card[i]=cardid;
-
-		// カ?ドは減らす
 			clif_insert_card(sd,idx_equip,idx_card,0);
 			pc_delitem(sd,idx_card,1,1);
 			return 0;
@@ -2461,7 +2459,7 @@ int pc_checkadditem(struct map_session_data *sd,int nameid,int amount)
 
 	nullpo_retr(0, sd);
 
-	if(itemdb_isequip(nameid))
+	if(!itemdb_isstackable(nameid))
 		return ADDITEM_NEW;
 
 	for(i=0;i<MAX_INVENTORY;i++){
@@ -2584,7 +2582,7 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount)
 
 	i = MAX_INVENTORY;
 
-	if (!itemdb_isequip2(data))
+	if (itemdb_isstackable2(data))
 	{ //Stackable
 		for (i = 0; i < MAX_INVENTORY; i++)
 		{
@@ -2883,7 +2881,7 @@ int pc_useitem(struct map_session_data *sd,int n)
 		//Logs
 		pc_delitem(sd,n,1,1);
 	}
-	if(sd->status.inventory[n].card[0]==0x00fe &&
+	if(sd->status.inventory[n].card[0]==CARD0_CREATE &&
 		pc_famerank(MakeDWord(sd->status.inventory[n].card[2],sd->status.inventory[n].card[3]), MAPID_ALCHEMIST))
 	{
 	    potion_flag = 2; // Famous player's potions have 50% more efficiency
@@ -2924,8 +2922,7 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun
 		return 1;
 
 	i=MAX_CART;
-	if(!itemdb_isequip2(data)){
-		// 装 備品ではないので、既所有品なら個数のみ変化させる
+	if(itemdb_isstackable2(data)){
 		for(i=0;i<MAX_CART;i++){
 			if(sd->status.cart[i].nameid==item_data->nameid &&
 				sd->status.cart[i].card[0] == item_data->card[0] && sd->status.cart[i].card[1] == item_data->card[1] &&
@@ -2939,7 +2936,6 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun
 		}
 	}
 	if(i >= MAX_CART){
-		// 装 備品か未所有品だったので空き欄へ追加
 		for(i=0;i<MAX_CART;i++){
 			if(sd->status.cart[i].nameid==0){
 				memcpy(&sd->status.cart[i],item_data,sizeof(sd->status.cart[0]));
@@ -3134,7 +3130,7 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl)
 	memset(&tmp_item,0,sizeof(tmp_item));
 	tmp_item.nameid = itemid;
 	tmp_item.amount = 1;
-	tmp_item.identify = !itemdb_isequip3(itemid);
+	tmp_item.identify = itemdb_isidentified(itemid);
 	flag = pc_additem(sd,&tmp_item,1);
 
 	if(battle_config.show_steal_in_same_party)
@@ -4486,7 +4482,7 @@ int pc_resetlvl(struct map_session_data* sd,int type)
 	clif_updatestatus(sd,SP_UDEX);
 	clif_updatestatus(sd,SP_ULUK);	// End Addition
 
-	for(i=0;i<11;i++) { // unequip items that can't be equipped by base 1 [Valaris]
+	for(i=0;i<EQI_MAX;i++) { // unequip items that can't be equipped by base 1 [Valaris]
 		if(sd->equip_index[i] >= 0)
 			if(!pc_isequip(sd,sd->equip_index[i]))
 				pc_unequipitem(sd,sd->equip_index[i],2);
@@ -4820,7 +4816,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 		memset(&item_tmp,0,sizeof(item_tmp));
 		item_tmp.nameid=7420; //PVP Skull item ID
 		item_tmp.identify=1;
-		item_tmp.card[0]=0x00fe;
+		item_tmp.card[0]=CARD0_CREATE;
 		item_tmp.card[1]=0;
 		item_tmp.card[2]=GetWord(sd->char_id,0); // CharId
 		item_tmp.card[3]=GetWord(sd->char_id,1);
@@ -5388,7 +5384,7 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
 	clif_updatestatus(sd,SP_JOBEXP);
 	clif_updatestatus(sd,SP_NEXTJOBEXP);
 
-	for(i=0;i<11;i++) {
+	for(i=0;i<EQI_MAX;i++) {
 		if(sd->equip_index[i] >= 0)
 			if(!pc_isequip(sd,sd->equip_index[i]))
 				pc_unequipitem(sd,sd->equip_index[i],2);	// ?備外し
@@ -6248,9 +6244,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
 		struct item_data *data;
 		if (sd->inventory_data[n]->equip_script)
 			run_script(sd->inventory_data[n]->equip_script,0,sd->bl.id,fake_nd->bl.id);
-		if(sd->status.inventory[n].card[0]==0x00ff ||
-			sd->status.inventory[n].card[0]==0x00fe ||
-			sd->status.inventory[n].card[0]==(short)0xff00)
+		if(itemdb_isspecial(sd->status.inventory[n].card[0]))
 			; //No cards
 		else
 		for(i=0;i<sd->inventory_data[n]->slot; i++)
@@ -6346,9 +6340,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
 		struct item_data *data;
 		if (sd->inventory_data[n]->unequip_script)
 			run_script(sd->inventory_data[n]->unequip_script,0,sd->bl.id,fake_nd->bl.id);
-		if(sd->status.inventory[n].card[0]==0x00ff ||
-			sd->status.inventory[n].card[0]==0x00fe ||
-			sd->status.inventory[n].card[0]==(short)0xff00)
+		if(itemdb_isspecial(sd->status.inventory[n].card[0]))
 			; //No cards
 		else
 		for(i=0;i<sd->inventory_data[n]->slot; i++)

+ 18 - 4
src/map/pet.c

@@ -108,6 +108,20 @@ static int pet_calc_pos(struct pet_data *pd,int tx,int ty,int dir)
 	return 0;
 }
 
+int pet_create_egg(struct map_session_data *sd, int item_id)
+{
+	int pet_id = search_petDB_index(item_id, PET_EGG);
+	if (pet_id < 0) return 0; //No pet egg here.
+	sd->catch_target_class = pet_db[pet_id].class_;
+	intif_create_pet(sd->status.account_id, sd->status.char_id,
+		(short)pet_db[pet_id].class_,
+		(short)mob_db(pet_db[pet_id].class_)->lv,
+		(short)pet_db[pet_id].EggID, 0,
+		(short)pet_db[pet_id].intimate,
+		100, 0, 1, pet_db[pet_id].jname);
+	return 1;
+}
+
 int pet_unlocktarget(struct pet_data *pd)
 {
 	nullpo_retr(0, pd);
@@ -335,7 +349,7 @@ static int pet_return_egg(struct map_session_data *sd, struct pet_data *pd)
 	memset(&tmp_item,0,sizeof(tmp_item));
 	tmp_item.nameid = pd->petDB->EggID;
 	tmp_item.identify = 1;
-	tmp_item.card[0] = (short)0xff00;
+	tmp_item.card[0] = CARD0_PET;
 	tmp_item.card[1] = GetWord(sd->pet.pet_id,0);
 	tmp_item.card[2] = GetWord(sd->pet.pet_id,1);
 	tmp_item.card[3] = sd->pet.rename_flag;
@@ -481,7 +495,7 @@ int pet_recv_petdata(int account_id,struct s_pet *p,int flag)
 		int i;
 		//Delete egg from inventory. [Skotlex]
 		for (i = 0; i < MAX_INVENTORY; i++) {
-			if(sd->status.inventory[i].card[0] == (short)0xff00 &&
+			if(sd->status.inventory[i].card[0] == CARD0_PET &&
 				p->pet_id == MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2]))
 				break;
 		}
@@ -517,7 +531,7 @@ int pet_select_egg(struct map_session_data *sd,short egg_index)
 	if(egg_index < 0 || egg_index >= MAX_INVENTORY)
 		return 0; //Forged packet!
 
-	if(sd->status.inventory[egg_index].card[0] == (short)0xff00)
+	if(sd->status.inventory[egg_index].card[0] == CARD0_PET)
 		intif_request_petdata(sd->status.account_id, sd->status.char_id, MakeDWord(sd->status.inventory[egg_index].card[1], sd->status.inventory[egg_index].card[2]) );
 	else {
 		if(battle_config.error_log)
@@ -637,7 +651,7 @@ int pet_get_egg(int account_id,int pet_id,int flag)
 	memset(&tmp_item,0,sizeof(tmp_item));
 	tmp_item.nameid = pet_db[i].EggID;
 	tmp_item.identify = 1;
-	tmp_item.card[0] = (short)0xff00;
+	tmp_item.card[0] = CARD0_PET;
 	tmp_item.card[1] = GetWord(pet_id,0);
 	tmp_item.card[2] = GetWord(pet_id,1);
 	tmp_item.card[3] = 0; //New pets are not named.

+ 1 - 0
src/map/pet.h

@@ -33,6 +33,7 @@ extern struct pet_db pet_db[MAX_PET_DB];
 
 enum { PET_CLASS,PET_CATCH,PET_EGG,PET_EQUIP,PET_FOOD };
 
+int pet_create_egg(struct map_session_data *sd, int item_id);
 int pet_hungry_val(struct map_session_data *sd);
 int pet_target_check(struct map_session_data *sd,struct block_list *bl,int type);
 int pet_unlocktarget(struct pet_data *pd);

+ 167 - 165
src/map/script.c

@@ -47,7 +47,7 @@
 #include "log.h"
 #include "unit.h"
 #include "irc.h"
-
+#include "pet.h"
 #define SCRIPT_BLOCK_SIZE 256
 
 #define FETCH(n, t) \
@@ -3924,7 +3924,7 @@ int buildin_checkweight(struct script_state *st)
  */
 int buildin_getitem(struct script_state *st)
 {
-	int nameid,nameidsrc,amount,flag = 0;
+	int nameid,amount,flag = 0;
 	struct item item_tmp;
 	struct map_session_data *sd;
 	struct script_data *data;
@@ -3936,46 +3936,52 @@ int buildin_getitem(struct script_state *st)
 	if( data->type==C_STR || data->type==C_CONSTSTR ){
 		const char *name=conv_str(st,data);
 		struct item_data *item_data = itemdb_searchname(name);
-		nameid=512; //Apple item ID
-		if( item_data != NULL)
-			nameid=item_data->nameid;
+		if( item_data == NULL) {
+			ShowWarning("buildin_getitem: Nonexistant item %s requested.\n", name);
+			return 1; //No item created.
+		}
+		nameid=item_data->nameid;
 	}else
 		nameid=conv_num(st,data);
 
-	if ( ( amount=conv_num(st,& (st->stack->stack_data[st->start+3])) ) <= 0) {
+	if ( ( amount=conv_num(st,& (st->stack->stack_data[st->start+3])) ) <= 0)
 		return 0; //return if amount <=0, skip the useles iteration
-	}
+
 	//Violet Box, Blue Box, etc - random item pick
-	if((nameidsrc = nameid)<0) { // Save real ID of the source Box [Lupus]
+	if(nameid <0) {
 		nameid=itemdb_searchrandomid(-nameid);
-
 		flag = 1;
 	}
 
-	if(nameid > 0) {
-		memset(&item_tmp,0,sizeof(item_tmp));
-		item_tmp.nameid=nameid;
-		if(!flag)
-			item_tmp.identify=1;
-		else
-			item_tmp.identify=!itemdb_isequip3(nameid);
-		if( st->end>st->start+5 ) //アイテムを指定したIDに渡す
-			sd=map_id2sd(conv_num(st,& (st->stack->stack_data[st->start+5])));
-		if(sd == NULL) //アイテムを渡す相手がいなかったらお帰り
-			return 0;
-		if((flag = pc_additem(sd,&item_tmp,amount))) {
-			clif_additem(sd,0,0,flag);
-			if (pc_candrop(sd, &item_tmp))
-				map_addflooritem(&item_tmp,amount,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0);
-		}
-
-		//Logs items, got from (N)PC scripts [Lupus]
-		if(log_config.pick > 0 ) {
-			log_pick(sd, "N", 0, nameid, amount, NULL);
-		}
-		//Logs
+	if(nameid <= 0 || !itemdb_exists(nameid)) {
+		ShowWarning("buildin_getitem: Nonexistant item %d requested.\n", nameid);
+		return 1; //No item created.
+	}
+		
+	memset(&item_tmp,0,sizeof(item_tmp));
+	item_tmp.nameid=nameid;
+	if(!flag)
+		item_tmp.identify=1;
+	else
+		item_tmp.identify=itemdb_isidentified(nameid);
+	if( st->end>st->start+5 ) //アイテムを指定したIDに渡す
+		sd=map_id2sd(conv_num(st,& (st->stack->stack_data[st->start+5])));
+	if(sd == NULL) //アイテムを渡す相手がいなかったらお帰り
+		return 0;
+	if(pet_create_egg(sd, nameid))
+		amount = 1; //This is a pet!
+	else
+	if((flag = pc_additem(sd,&item_tmp,amount))) {
+		clif_additem(sd,0,0,flag);
+		if (pc_candrop(sd, &item_tmp))
+			map_addflooritem(&item_tmp,amount,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0);
+	}
 
+	//Logs items, got from (N)PC scripts [Lupus]
+	if(log_config.pick > 0 ) {
+		log_pick(sd, "N", 0, nameid, amount, NULL);
 	}
+	//Logs
 
 	return 0;
 }
@@ -4000,7 +4006,7 @@ int buildin_getitem2(struct script_state *st)
 	if( data->type==C_STR || data->type==C_CONSTSTR ){
 		const char *name=conv_str(st,data);
 		struct item_data *item_data = itemdb_searchname(name);
-		nameid=512; //Apple item ID
+		nameid=UNKNOWN_ITEM_ID;
 		if( item_data )
 			nameid=item_data->nameid;
 	}else
@@ -4102,7 +4108,7 @@ int buildin_getnameditem(struct script_state *st)
 	}else
 		nameid = conv_num(st,data);
 
-	if(!itemdb_exists(nameid) || !itemdb_isequip3(nameid))
+	if(!itemdb_exists(nameid) || itemdb_isstackable(nameid))
 	{	//We don't allow non-equipable/stackable items to be named
 		//to avoid any qty exploits that could happen because of it.
 		push_val(st->stack,C_INT,0);
@@ -4175,7 +4181,7 @@ int buildin_makeitem(struct script_state *st)
 	if( data->type==C_STR || data->type==C_CONSTSTR ){
 		const char *name=conv_str(st,data);
 		struct item_data *item_data = itemdb_searchname(name);
-		nameid=512; //Apple Item ID
+		nameid=UNKNOWN_ITEM_ID;
 		if( item_data )
 			nameid=item_data->nameid;
 	}else
@@ -4206,7 +4212,7 @@ int buildin_makeitem(struct script_state *st)
 		if(!flag)
 			item_tmp.identify=1;
 		else
-			item_tmp.identify=!itemdb_isequip3(nameid);
+			item_tmp.identify=itemdb_isidentified(nameid);
 
 		map_addflooritem(&item_tmp,amount,m,x,y,NULL,NULL,NULL,0);
 	}
@@ -4230,7 +4236,7 @@ int buildin_delitem(struct script_state *st)
 	if( data->type==C_STR || data->type==C_CONSTSTR ){
 		const char *name=conv_str(st,data);
 		struct item_data *item_data = itemdb_searchname(name);
-		//nameid=512;
+		//nameid=UNKNOWN_ITEM_ID;
 		if( item_data )
 			nameid=item_data->nameid;
 	}else
@@ -4247,20 +4253,24 @@ int buildin_delitem(struct script_state *st)
 	for(i=0;i<MAX_INVENTORY;i++){
 		//we don't delete wrong item or equipped item
 		if(sd->status.inventory[i].nameid<=0 || sd->inventory_data[i] == NULL ||
-		   sd->status.inventory[i].amount<=0 ||	sd->status.inventory[i].nameid!=nameid )
+		   sd->status.inventory[i].amount<=0 || sd->status.inventory[i].nameid!=nameid)
 			continue;
 		//1 egg uses 1 cell in the inventory. so it's ok to delete 1 pet / per cycle
-		if(sd->inventory_data[i]->type==7 && sd->status.inventory[i].card[0] == (short)0xff00 && search_petDB_index(nameid, PET_EGG) >= 0 ){
-			intif_delete_petdata( MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2]) );
-			//clear egg flag. so it won't be put in IMPORTANT items (eggs look like item with 2 cards ^_^)
-			sd->status.inventory[i].card[1] = sd->status.inventory[i].card[0] = 0;
-			//now this egg'll be deleted as a common unimportant item
+		if(sd->inventory_data[i]->type==IT_PETEGG &&
+			sd->status.inventory[i].card[0] == CARD0_PET)
+		{
+			if (intif_delete_petdata(MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2])))
+				continue; //pet couldn't be sent for deletion.
 		}
 		//is this item important? does it have cards? or Player's name? or Refined/Upgraded
-		if( sd->status.inventory[i].card[0] || sd->status.inventory[i].card[1] ||
-			sd->status.inventory[i].card[2] || sd->status.inventory[i].card[3] || sd->status.inventory[i].refine) {
-			//this is important item, count it
-			important_item++;
+		if(itemdb_isspecial(sd->status.inventory[i].card[0]) ||
+			sd->status.inventory[i].card[1] ||
+			sd->status.inventory[i].card[2] ||
+		  	sd->status.inventory[i].card[3] ||
+		  	sd->status.inventory[i].refine) {
+			//this is important item, count it (except for pet eggs)
+			if(sd->status.inventory[i].card[0] != CARD0_PET)
+				important_item++;
 			continue;
 		}
 
@@ -4339,7 +4349,7 @@ int buildin_delitem2(struct script_state *st)
 	if( data->type==C_STR || data->type==C_CONSTSTR ){
 		const char *name=conv_str(st,data);
 		struct item_data *item_data = itemdb_searchname(name);
-		//nameid=512;
+		//nameid=UNKNOWN_ITEM_ID;
 		if( item_data )
 			nameid=item_data->nameid;
 	}else
@@ -4354,9 +4364,9 @@ int buildin_delitem2(struct script_state *st)
 	c3=conv_num(st,& (st->stack->stack_data[st->start+9]));
 	c4=conv_num(st,& (st->stack->stack_data[st->start+10]));
 
-	if (nameid<500 || amount<=0 ) {//by Lupus. Don't run FOR if u got wrong item ID or amount<=0
-	 //eprintf("wrong item ID or amount<=0 : delitem %i,\n",nameid,amount);
-	 return 0;
+	if (!itemdb_exists(nameid) || amount<=0 ) {//by Lupus. Don't run FOR if u got wrong item ID or amount<=0
+		 //eprintf("wrong item ID or amount<=0 : delitem %i,\n",nameid,amount);
+		 return 0;
 	}
 
 	for(i=0;i<MAX_INVENTORY;i++){
@@ -4369,11 +4379,10 @@ int buildin_delitem2(struct script_state *st)
 			sd->status.inventory[i].card[3]!=c4)
 			continue;
 	//1 egg uses 1 cell in the inventory. so it's ok to delete 1 pet / per cycle
-		if(sd->inventory_data[i]->type==7 && sd->status.inventory[i].card[0] == (short)0xff00 && search_petDB_index(nameid, PET_EGG) >= 0 ){
-			intif_delete_petdata( MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2]) );
-			//clear egg flag. so it won't be put in IMPORTANT items (eggs look like item with 2 cards ^_^)
-			sd->status.inventory[i].card[1] = sd->status.inventory[i].card[0] = 0;
-			//now this egg'll be deleted as a common unimportant item
+		if(sd->inventory_data[i]->type==IT_PETEGG && sd->status.inventory[i].card[0] == CARD0_PET)
+		{
+			if (!intif_delete_petdata( MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2])))
+				continue; //Failed to send delete the pet.
 		}
 
 		if(sd->status.inventory[i].amount>=amount){
@@ -4946,7 +4955,10 @@ int buildin_successrefitem(struct script_state *st)
 		clif_additem(sd,i,1,0);
 		pc_equipitem(sd,i,ep);
 		clif_misceffect(&sd->bl,3);
-		if(sd->status.inventory[i].refine == 10 && sd->status.inventory[i].card[0] == 0x00ff && sd->char_id == MakeDWord(sd->status.inventory[i].card[2],sd->status.inventory[i].card[3])){ // Fame point system [DracoRPG]
+		if(sd->status.inventory[i].refine == MAX_REFINE &&
+			sd->status.inventory[i].card[0] == CARD0_FORGE &&
+		  	sd->char_id == MakeDWord(sd->status.inventory[i].card[2],sd->status.inventory[i].card[3])
+		){ // Fame point system [DracoRPG]
 	 		switch (sd->inventory_data[i]->wlv){
 				case 1:
 					pc_addfame(sd,1); // Success to refine to +10 a lv1 weapon you forged = +1 fame point
@@ -6267,7 +6279,7 @@ int buildin_getareadropitem(struct script_state *st)
 	if( data->type==C_STR || data->type==C_CONSTSTR ){
 		const char *name=conv_str(st,data);
 		struct item_data *item_data = itemdb_searchname(name);
-		item=512;
+		item=UNKNOWN_ITEM_ID;
 		if( item_data )
 			item=item_data->nameid;
 	}else
@@ -7569,14 +7581,14 @@ int buildin_getequipcardcnt(struct script_state *st)
 	num=conv_num(st,& (st->stack->stack_data[st->start+2]));
 	sd=script_rid2sd(st);
 	i=pc_checkequip(sd,equip[num-1]);
-	if(sd->status.inventory[i].card[0] == 0x00ff){ // 製造武器はカードなし
+	if(itemdb_isspecial(sd->status.inventory[i].card[0]))
+	{
 		push_val(st->stack,C_INT,0);
 		return 0;
 	}
 	do{
-		if( (sd->status.inventory[i].card[c-1] > 4000 &&
-			sd->status.inventory[i].card[c-1] < 5000) ||
-			itemdb_type(sd->status.inventory[i].card[c-1]) == 6){	// [Celest]
+		if(sd->status.inventory[i].card[c-1] &&
+			itemdb_type(sd->status.inventory[i].card[c-1]) == IT_CARD){	// [Celest]
 			push_val(st->stack,C_INT,(c));
 			return 0;
 		}
@@ -7599,13 +7611,12 @@ int buildin_successremovecards(struct script_state *st)
 	num=conv_num(st,& (st->stack->stack_data[st->start+2]));
 	sd=script_rid2sd(st);
 	i=pc_checkequip(sd,equip[num-1]);
-	if(sd->status.inventory[i].card[0]==0x00ff){ // 製造武器は処理しない
+	if(itemdb_isspecial(sd->status.inventory[i].card[0])) 
 		return 0;
-	}
+
 	do{
-		if( (sd->status.inventory[i].card[c-1] > 4000 &&
-			sd->status.inventory[i].card[c-1] < 5000) ||
-			itemdb_type(sd->status.inventory[i].card[c-1]) == 6){	// [Celest]
+		if(sd->status.inventory[i].card[c-1] &&
+			itemdb_type(sd->status.inventory[i].card[c-1]) == IT_CARD){	// [Celest]
 
 			cardflag = 1;
 			item_tmp.id=0,item_tmp.nameid=sd->status.inventory[i].card[c-1];
@@ -7675,13 +7686,12 @@ int buildin_failedremovecards(struct script_state *st)
 	typefail=conv_num(st,& (st->stack->stack_data[st->start+3]));
 	sd=script_rid2sd(st);
 	i=pc_checkequip(sd,equip[num-1]);
-	if(sd->status.inventory[i].card[0]==0x00ff){ // 製造武器は処理しない
+	if(itemdb_isspecial(sd->status.inventory[i].card[0]))
 		return 0;
-	}
+
 	do{
-		if( (sd->status.inventory[i].card[c-1] > 4000 &&
-			sd->status.inventory[i].card[c-1] < 5000) ||
-			itemdb_type(sd->status.inventory[i].card[c-1]) == 6){	// [Celest]
+		if(sd->status.inventory[i].card[c-1] &&
+			itemdb_type(sd->status.inventory[i].card[c-1]) == IT_CARD){	// [Celest]
 
 			cardflag = 1;
 
@@ -9452,32 +9462,34 @@ int buildin_isequipped(struct script_state *st)
 		if (id <= 0)
 			continue;
 		
-		for (j=0; j<10; j++) {
-			int index, type;
+		for (j=0; j<EQI_MAX; j++) {
+			int index;
 			index = sd->equip_index[j];
 			if(index < 0) continue;
-			if(j == 9 && sd->equip_index[8] == index) continue;
-			if(j == 5 && sd->equip_index[4] == index) continue;
-			if(j == 6 && (sd->equip_index[5] == index || sd->equip_index[4] == index)) continue;
-			type = itemdb_type(id);
+			if(j == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index) continue;
+			if(j == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index) continue;
+			if(j == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index)) continue;
 			
-			if(sd->inventory_data[index]) {
-				if (type == 4 || type == 5) {
-					if (sd->inventory_data[index]->nameid == id)
+			if(!sd->inventory_data[index])
+				continue;
+
+			if(itemdb_type(id) != IT_CARD) { //Non card
+				if (sd->inventory_data[index]->nameid == id) {
+					flag = 1;
+					break;
+				}
+			} else { //Card
+				if (itemdb_isspecial(sd->status.inventory[index].card[0]))
+					continue;
+				for(k=0; k<sd->inventory_data[index]->slot; k++) {
+					if (sd->status.inventory[index].card[k] == id)
+					{
 						flag = 1;
-				} else if (type == 6) {
-					for(k=0; k<sd->inventory_data[index]->slot; k++) {
-						if (sd->status.inventory[index].card[0]!=0x00ff &&
-							sd->status.inventory[index].card[0]!=0x00fe &&
-							sd->status.inventory[index].card[0]!=(short)0xff00 &&
-							sd->status.inventory[index].card[k] == id) {
-							flag = 1;
-							break;
-						}
+						break;
 					}
 				}
-				if (flag) break;
 			}
+			if (flag) break;
 		}
 		if (ret == -1)
 			ret = flag;
@@ -9503,34 +9515,36 @@ int buildin_isequippedcnt(struct script_state *st)
 	int ret = 0;
 
 	sd = script_rid2sd(st);
+	if (!sd) { //If the player is not attached it is a script error anyway... but better prevent the map server from crashing...
+		push_val(st->stack,C_INT,0);
+		return 0;
+	}
 	
 	for (i=0; id!=0; i++) {
 		FETCH (i+2, id) else id = 0;
 		if (id <= 0)
 			continue;
 		
-		for (j=0; j<10; j++) {
-			int index, type;
+		for (j=0; j<EQI_MAX; j++) {
+			int index;
 			index = sd->equip_index[j];
 			if(index < 0) continue;
-			if(j == 9 && sd->equip_index[8] == index) continue;
-			if(j == 5 && sd->equip_index[4] == index) continue;
-			if(j == 6 && (sd->equip_index[5] == index || sd->equip_index[4] == index)) continue;
-			type = itemdb_type(id);
+			if(j == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index) continue;
+			if(j == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index) continue;
+			if(j == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index)) continue;
 			
-			if(sd->inventory_data[index]) {
-				if (type == 4 || type == 5) {
-					if (sd->inventory_data[index]->nameid == id)
+			if(!sd->inventory_data[index])
+				continue;
+
+			if (itemdb_type(id) != IT_CARD) { //No card. Count amount in inventory.
+				if (sd->inventory_data[index]->nameid == id)
+					ret+= sd->status.inventory[index].amount;
+			} else { //Count cards.
+				if (itemdb_isspecial(sd->status.inventory[index].card[0]))
+					continue; //No cards
+				for(k=0; k<sd->inventory_data[index]->slot; k++) {
+					if (sd->status.inventory[index].card[k] == id) 
 						ret++; //[Lupus]
-				} else if (type == 6) {
-					for(k=0; k<sd->inventory_data[index]->slot; k++) {
-						if (sd->status.inventory[index].card[0]!=0x00ff &&
-							sd->status.inventory[index].card[0]!=0x00fe &&
-							sd->status.inventory[index].card[0]!=(short)0xff00 &&
-							sd->status.inventory[index].card[k] == id) {
-							ret++; //[Lupus]
-						}
-					}
 				}				
 			}
 		}
@@ -9551,7 +9565,7 @@ int buildin_isequipped(struct script_state *st)
 {
 	struct map_session_data *sd;
 	int i, j, k, id = 1;
-	int index, type, flag;
+	int index, flag;
 	int ret = -1;
 
 	sd = script_rid2sd(st);
@@ -9567,58 +9581,49 @@ int buildin_isequipped(struct script_state *st)
 		if (id <= 0)
 			continue;
 		
-		type = itemdb_type(id);
 		flag = 0;
-		for (j=0; j<10; j++)
+		for (j=0; j<EQI_MAX; j++)
 		{
 			index = sd->equip_index[j];
 			if(index < 0) continue;
-			if(j == 9 && sd->equip_index[8] == index) continue;
-			if(j == 5 && sd->equip_index[4] == index) continue;
-			if(j == 6 && (sd->equip_index[5] == index || sd->equip_index[4] == index)) continue;
-			
+			if(j == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index) continue;
+			if(j == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index) continue;
+			if(j == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index)) continue;
+	
 			if(!sd->inventory_data[index])
 				continue;
 			
-			switch (type)
-			{
-				case 4:
-				case 5:
-					if (sd->inventory_data[index]->nameid == id)
-						flag = 1;
-					break;
-				case 6:
-					if (
-						sd->inventory_data[index]->slot == 0 ||
-						sd->status.inventory[index].card[0] == 0x00ff ||
-						sd->status.inventory[index].card[0] == 0x00fe ||
-						sd->status.inventory[index].card[0] == (short)0xff00)
-						continue;
+			if (itemdb_type(id) != IT_CARD) {
+				if (sd->inventory_data[index]->nameid == id)
+					flag = 1;
+				break;
+			} else { //Cards
+				if (sd->inventory_data[index]->slot == 0 ||
+					itemdb_isspecial(sd->status.inventory[index].card[0]))
+					continue;
 
-					for (k = 0; k < sd->inventory_data[index]->slot; k++)
-					{	//New hash system which should support up to 4 slots on any equipment. [Skotlex]
-						unsigned int hash = 0;
-						if (sd->status.inventory[index].card[k] != id)
-							continue;
+				for (k = 0; k < sd->inventory_data[index]->slot; k++)
+				{	//New hash system which should support up to 4 slots on any equipment. [Skotlex]
+					unsigned int hash = 0;
+					if (sd->status.inventory[index].card[k] != id)
+						continue;
 
-						hash = 1<<((j<5?j:j-5)*4 + k);
-						// check if card is already used by another set
-						if ((j<5?sd->setitem_hash:sd->setitem_hash2) & hash)	
-							continue;
+					hash = 1<<((j<5?j:j-5)*4 + k);
+					// check if card is already used by another set
+					if ((j<5?sd->setitem_hash:sd->setitem_hash2) & hash)	
+						continue;
 
-						// We have found a match
-						flag = 1;
-						// Set hash so this card cannot be used by another
-						if (j<5)
-							sd->setitem_hash |= hash;
-						else
-							sd->setitem_hash2 |= hash;
-						break;
-					}
-				//Case 6 end
-				break;
+					// We have found a match
+					flag = 1;
+					// Set hash so this card cannot be used by another
+					if (j<5)
+						sd->setitem_hash |= hash;
+					else
+						sd->setitem_hash2 |= hash;
+					break;
+				}
 			}
-			if (flag) break;
+			if (flag) break; //Card found
 		}
 		if (ret == -1)
 			ret = flag;
@@ -9641,7 +9646,7 @@ int buildin_cardscnt(struct script_state *st)
 	struct map_session_data *sd;
 	int i, k, id = 1;
 	int ret = 0;
-	int index, type;
+	int index;
 
 	sd = script_rid2sd(st);
 	
@@ -9652,22 +9657,19 @@ int buildin_cardscnt(struct script_state *st)
 		
 		index = current_equip_item_index; //we get CURRENT WEAPON inventory index from status.c [Lupus]
 		if(index < 0) continue;
-
-		type = itemdb_type(id);
 			
-		if(sd->inventory_data[index]) {
-			if (type == 4 || type == 5) {
-				if (sd->inventory_data[index]->nameid == id)
+		if(!sd->inventory_data[index])
+			continue;
+
+		if(itemdb_type(id) != IT_CARD) {
+			if (sd->inventory_data[index]->nameid == id)
+				ret+= sd->status.inventory[index].amount;
+		} else {
+			if (itemdb_isspecial(sd->status.inventory[index].card[0]))
+				continue;
+			for(k=0; k<sd->inventory_data[index]->slot; k++) {
+				if (sd->status.inventory[index].card[k] == id)
 					ret++;
-			} else if (type == 6) {
-				for(k=0; k<sd->inventory_data[index]->slot; k++) {
-					if (sd->status.inventory[index].card[0]!=0x00ff &&
-						sd->status.inventory[index].card[0]!=0x00fe &&
-						sd->status.inventory[index].card[0]!=(short)0xff00 &&
-						sd->status.inventory[index].card[k] == id) {
-						ret++;
-					}
-				}
 			}				
 		}
 	}

+ 5 - 4
src/map/skill.c

@@ -8595,7 +8595,8 @@ void skill_weaponrefine (struct map_session_data *sd, int idx)
 				if (ep)
 					pc_equipitem(sd,idx,ep);
 				clif_misceffect(&sd->bl,3);
-				if(item->refine == MAX_REFINE && item->card[0] == 0x00ff && MakeDWord(item->card[2],item->card[3]) == sd->char_id){ // Fame point system [DracoRPG]
+				if(item->refine == MAX_REFINE && item->card[0] == CARD0_FORGE &&
+					MakeDWord(item->card[2],item->card[3]) == sd->char_id){ // Fame point system [DracoRPG]
 					switch(ditem->wlv){
 						case 1:
 							pc_addfame(sd,1); // Success to refine to +10 a lv1 weapon you forged = +1 fame point
@@ -10118,7 +10119,7 @@ int skill_produce_mix (struct map_session_data *sd, int skill_id, int nameid, in
 		tmp_item.amount=1;
 		tmp_item.identify=1;
 		if(equip){
-			tmp_item.card[0]=0x00ff;
+			tmp_item.card[0]=CARD0_FORGE;
 			tmp_item.card[1]=((sc*5)<<8)+ele;
 			tmp_item.card[2]=GetWord(sd->char_id,0); // CharId
 			tmp_item.card[3]=GetWord(sd->char_id,1);
@@ -10142,7 +10143,7 @@ int skill_produce_mix (struct map_session_data *sd, int skill_id, int nameid, in
 					break;
 			}
 			if (flag) {
-				tmp_item.card[0]=0x00fe;
+				tmp_item.card[0]=CARD0_CREATE;
 				tmp_item.card[1]=0;
 				tmp_item.card[2]=GetWord(sd->char_id,0); // CharId
 				tmp_item.card[3]=GetWord(sd->char_id,1);
@@ -10286,7 +10287,7 @@ int skill_arrow_create (struct map_session_data *sd, int nameid)
 		tmp_item.nameid = skill_arrow_db[index].cre_id[i];
 		tmp_item.amount = skill_arrow_db[index].cre_amount[i];
 		if(battle_config.making_arrow_name_input) {
-			tmp_item.card[0]=0x00fe;
+			tmp_item.card[0]=CARD0_CREATE;
 			tmp_item.card[1]=0;
 			tmp_item.card[2]=GetWord(sd->char_id,0); // CharId
 			tmp_item.card[3]=GetWord(sd->char_id,1);

+ 2 - 4
src/map/status.c

@@ -1721,7 +1721,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
 					return 1;
 			}
 
-			if(sd->status.inventory[index].card[0]==0x00ff)
+			if(sd->status.inventory[index].card[0]==CARD0_FORGE)
 			{	// Forged weapon
 				wd->star += (sd->status.inventory[index].card[1]>>8);
 				if(wd->star >= 15) wd->star = 40; // 3 Star Crumbs now give +40 dmg
@@ -1777,9 +1777,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
 			struct item_data *data;
 	
 			//Card script execution.
-			if(sd->status.inventory[index].card[0]==0x00ff ||
-				sd->status.inventory[index].card[0]==0x00fe ||
-				sd->status.inventory[index].card[0]==(short)0xff00)
+			if(itemdb_isspecial(sd->status.inventory[index].card[0]))
 				continue;
 			for(j=0;j<sd->inventory_data[index]->slot;j++){	
 				current_equip_card_id= c= sd->status.inventory[index].card[j];

+ 2 - 2
src/map/storage.c

@@ -174,7 +174,7 @@ static int storage_additem(struct map_session_data *sd,struct storage *stor,stru
 		return 1;
 	}
 	
-	if(!itemdb_isequip2(data)){ //Stackable
+	if(itemdb_isstackable2(data)){ //Stackable
 		for(i=0;i<MAX_STORAGE;i++){
 			if( compare_item (&stor->storage_[i], item_data)) {
 				if(amount > MAX_AMOUNT - stor->storage_[i].amount)
@@ -523,7 +523,7 @@ int guild_storage_additem(struct map_session_data *sd,struct guild_storage *stor
 		return 1;
 	}
 
-	if(!itemdb_isequip2(data)){ //Stackable
+	if(itemdb_isstackable2(data)){ //Stackable
 		for(i=0;i<MAX_GUILD_STORAGE;i++){
 			if(compare_item(&stor->storage_[i], item_data)) {
 				if(stor->storage_[i].amount+amount > MAX_AMOUNT)

+ 2 - 2
src/map/trade.c

@@ -223,7 +223,7 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd) {
 			
 			data = itemdb_search(inventory[n].nameid);
 			i = MAX_INVENTORY;
-			if (!itemdb_isequip2(data)) { //Stackable item.
+			if (itemdb_isstackable2(data)) { //Stackable item.
 				for(i = 0; i < MAX_INVENTORY; i++)
 					if (inventory2[i].nameid == inventory[n].nameid &&
 						inventory2[i].card[0] == inventory[n].card[0] && inventory2[i].card[1] == inventory[n].card[1] &&
@@ -259,7 +259,7 @@ int trade_check(struct map_session_data *sd, struct map_session_data *tsd) {
 		// search if it's possible to add item (for full inventory)
 		data = itemdb_search(inventory2[n].nameid);
 		i = MAX_INVENTORY;
-		if (!itemdb_isequip2(data)) {
+		if (itemdb_isstackable2(data)) {
 			for(i = 0; i < MAX_INVENTORY; i++)
 				if (inventory[i].nameid == inventory2[n].nameid &&
 					inventory[i].card[0] == inventory2[n].card[0] && inventory[i].card[1] == inventory2[n].card[1] &&