From 6749d6567aa972b5cc46e1ed85986be21e2ec799 Mon Sep 17 00:00:00 2001 From: skotlex Date: Tue, 11 Jul 2006 16:32:37 +0000 Subject: - 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://rathena.svn.sourceforge.net/svnroot/rathena/trunk@7613 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/atcommand.c | 64 +++++----- src/map/charcommand.c | 6 +- src/map/clif.c | 48 ++++---- src/map/intif.c | 2 +- src/map/itemdb.c | 125 ++++++++++++------- src/map/itemdb.h | 30 ++++- src/map/map.c | 2 +- src/map/mob.c | 28 ++--- src/map/npc.c | 2 +- src/map/pc.c | 74 +++++------ src/map/pet.c | 22 +++- src/map/pet.h | 1 + src/map/script.c | 332 +++++++++++++++++++++++++------------------------- src/map/skill.c | 9 +- src/map/status.c | 6 +- src/map/storage.c | 4 +- src/map/trade.c | 4 +- 17 files changed, 413 insertions(+), 346 deletions(-) (limited to 'src') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 3d8f260b9..e31d62845 100644 --- a/src/map/atcommand.c +++ b/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; +} + /*========================================== * *------------------------------------------ diff --git a/src/map/charcommand.c b/src/map/charcommand.c index 7abbda002..034fb017b 100644 --- a/src/map/charcommand.c +++ b/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 diff --git a/src/map/clif.c b/src/map/clif.c index 59b6df8e1..68f9254d8 100644 --- a/src/map/clif.c +++ b/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;jinventory_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); } } diff --git a/src/map/intif.c b/src/map/intif.c index ef616e638..1acdf9360 100644 --- a/src/map/intif.c +++ b/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) { diff --git a/src/map/itemdb.c b/src/map/itemdb.c index ddae6b38a..1849fdbb6 100644 --- a/src/map/itemdb.c +++ b/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(); } diff --git a/src/map/itemdb.h b/src/map/itemdb.h index a9b74b0ca..d8255ef5a 100644 --- a/src/map/itemdb.h +++ b/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で定義された値そのものを返すのに対し diff --git a/src/map/map.c b/src/map/map.c index fb1ee84ec..d1859327e 100644 --- a/src/map/map.c +++ b/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); diff --git a/src/map/mob.c b/src/map/mob.c index 63b71b941..ead808d70 100644 --- a/src/map/mob.c +++ b/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 diff --git a/src/map/npc.c b/src/map/npc.c index 372851ca6..c5fd46d02 100644 --- a/src/map/npc.c +++ b/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); diff --git a/src/map/pc.c b/src/map/pc.c index 5ce2a8394..fa7d614ff 100644 --- a/src/map/pc.c +++ b/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;istatus.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;iinventory_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;istatus.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;istatus.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;istatus.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;iequip_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;iequip_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;iinventory_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;iinventory_data[n]->slot; i++) diff --git a/src/map/pet.c b/src/map/pet.c index 3bec8da30..2f5e210ad 100644 --- a/src/map/pet.c +++ b/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. diff --git a/src/map/pet.h b/src/map/pet.h index 619db93d1..2d461594d 100644 --- a/src/map/pet.h +++ b/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); diff --git a/src/map/script.c b/src/map/script.c index fdcc98c6e..c8b83f794 100644 --- a/src/map/script.c +++ b/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;istatus.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;istatus.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; jequip_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; kinventory_data[index]->slot; k++) { + if (sd->status.inventory[index].card[k] == id) + { flag = 1; - } else if (type == 6) { - for(k=0; kinventory_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; jequip_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; kinventory_data[index]->slot; k++) { + if (sd->status.inventory[index].card[k] == id) ret++; //[Lupus] - } else if (type == 6) { - for(k=0; kinventory_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; jequip_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; kinventory_data[index]->slot; k++) { + if (sd->status.inventory[index].card[k] == id) ret++; - } else if (type == 6) { - for(k=0; kinventory_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++; - } - } } } } diff --git a/src/map/skill.c b/src/map/skill.c index 164a6c7c2..af9fb74dc 100644 --- a/src/map/skill.c +++ b/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); diff --git a/src/map/status.c b/src/map/status.c index bb928def5..b3a77dadf 100644 --- a/src/map/status.c +++ b/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;jinventory_data[index]->slot;j++){ current_equip_card_id= c= sd->status.inventory[index].card[j]; diff --git a/src/map/storage.c b/src/map/storage.c index 0a54f0dde..3cdeb5b42 100644 --- a/src/map/storage.c +++ b/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;istorage_[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;istorage_[i], item_data)) { if(stor->storage_[i].amount+amount > MAX_AMOUNT) diff --git a/src/map/trade.c b/src/map/trade.c index 04d4c83e5..6cf7fe293 100644 --- a/src/map/trade.c +++ b/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] && -- cgit v1.2.3-70-g09d2