From b5c2a71ef2575b66e7b1b25aed0ad3c60b4fef2b Mon Sep 17 00:00:00 2001 From: panikon Date: Thu, 10 Apr 2014 01:23:13 -0300 Subject: Fixed issue: 7936 http://hercules.ws/board/tracker/issue-7936-guildparty-item-bounded/ --- src/char/char.h | 2 ++ src/char/int_storage.c | 68 ++++++++++++++++++++++++++++++++++++++++++++------ src/common/mmo.h | 26 +++++++++++++++++++ src/map/pc.h | 26 ------------------- 4 files changed, 88 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/char/char.h b/src/char/char.h index 372af91f7..2928929de 100644 --- a/src/char/char.h +++ b/src/char/char.h @@ -65,6 +65,8 @@ int mapif_sendallwos(int fd,unsigned char *buf,unsigned int len); int mapif_send(int fd,unsigned char *buf,unsigned int len); void mapif_on_parse_accinfo(int account_id,int u_fd, int aid, int castergroup, int map_fd); +void disconnect_player(int account_id); + int char_married(int pl1,int pl2); int char_child(int parent_id, int child_id); int char_family(int pl1,int pl2,int pl3); diff --git a/src/char/int_storage.c b/src/char/int_storage.c index 0313f2a41..c01e3619e 100644 --- a/src/char/int_storage.c +++ b/src/char/int_storage.c @@ -258,8 +258,9 @@ int mapif_parse_ItemBoundRetrieve_sub(int fd) StringBuf buf; SqlStmt* stmt; struct item item; - int j, i=0, s; + int j, i=0, s=0, bound_qt=0; struct item items[MAX_INVENTORY]; + unsigned int bound_item[MAX_INVENTORY] = {0}; int char_id = RFIFOL(fd,2); int aid = RFIFOL(fd,6); int guild_id = RFIFOW(fd,10); @@ -313,6 +314,11 @@ int mapif_parse_ItemBoundRetrieve_sub(int fd) StrBuf->AppendStr(&buf, " OR"); StrBuf->Printf(&buf, " `id`=%d",items[j].id); + + if( items[j].bound && items[j].equip ) { + bound_item[bound_qt] = items[j].equip; + bound_qt++; + } } if( SQL_ERROR == SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf)) @@ -324,19 +330,62 @@ int mapif_parse_ItemBoundRetrieve_sub(int fd) return 1; } + // Removes any view id that was set by an item that was removed + if( bound_qt ) { + // Verifies equip bitmasks (see item.equip) and handles the sql statement +#define CHECK_REMOVE(var,mask,token) do {\ + if((var&mask)) {\ + if((var) != mask && s) StrBuf->AppendStr((&buf), ",");\ + StrBuf->AppendStr((&buf),"`"#token"`='0'");\ + var &= ~mask;\ + s++;\ + }\ + } while(0) + StrBuf->Clear(&buf); + StrBuf->Printf(&buf, "UPDATE `%s` SET ", char_db); + for( j = 0; j < bound_qt; j++ ) { + // Equips can be at more than one slot at the same time + CHECK_REMOVE(bound_item[j],EQP_HAND_R,weapon); + CHECK_REMOVE(bound_item[j],EQP_HAND_L,shield); + CHECK_REMOVE(bound_item[j],EQP_HEAD_TOP,head_top); + CHECK_REMOVE(bound_item[j],EQP_HEAD_MID,head_mid); + CHECK_REMOVE(bound_item[j],EQP_HEAD_LOW,head_bottom); + CHECK_REMOVE(bound_item[j],EQP_GARMENT,robe); + } + StrBuf->Printf(&buf, " WHERE `char_id`='%d'", char_id); + + if( SQL_ERROR == SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf)) + || SQL_ERROR == SQL->StmtExecute(stmt) ) + { + Sql_ShowDebug(sql_handle); + SQL->StmtFree(stmt); + StrBuf->Destroy(&buf); + return 1; + } +#undef CHECK_REMOVE + } + //Now let's update the guild storage with those deleted items + /// TODO/FIXME: + /// This approach is basically the same as the one from memitemdata_to_sql, but + /// the latter compares current database values and this is not needed in this case + /// maybe sometime separate memitemdata_to_sql into different methods in order to use + /// call that function here as well [Panikon] StrBuf->Clear(&buf); - StrBuf->Printf(&buf, "INSERT INTO `%s` (`guild_id`, `nameid`, `amount`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`", guild_storage_db); - for( j = 0; j < MAX_SLOTS; ++j ) - StrBuf->Printf(&buf, ", `card%d`", j); - StrBuf->AppendStr(&buf, ") VALUES "); - + StrBuf->Printf(&buf,"INSERT INTO `%s` (`guild_id`,`nameid`,`amount`,`equip`,`identify`,`refine`," + "`attribute`,`expire_time`,`bound`,`unique_id`", + guild_storage_db); + for( s = 0; s < MAX_SLOTS; ++s ) + StrBuf->Printf(&buf, ", `card%d`", s); + StrBuf->AppendStr(&buf," ) VALUES "); + for( j = 0; j < i; ++j ) { if( j ) StrBuf->AppendStr(&buf, ","); - StrBuf->Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d'", - guild_id, items[j].nameid, items[j].amount, items[j].identify, items[j].refine, items[j].attribute, items[j].expire_time, items[j].bound, items[j].unique_id); + StrBuf->Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d'", + guild_id, items[j].nameid, items[j].amount, items[j].equip, items[j].identify, items[j].refine, + items[j].attribute, items[j].expire_time, items[j].bound, items[j].unique_id); for( s = 0; s < MAX_SLOTS; ++s ) StrBuf->Printf(&buf, ", '%d'", items[j].card[s]); StrBuf->AppendStr(&buf, ")"); @@ -356,6 +405,9 @@ int mapif_parse_ItemBoundRetrieve_sub(int fd) //Finally reload storage and tell map we're done mapif_load_guild_storage(fd,aid,guild_id,0); + + // If character is logged in char, disconnect + disconnect_player(aid); #endif return 0; } diff --git a/src/common/mmo.h b/src/common/mmo.h index 019472acb..476d12d3f 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -230,6 +230,32 @@ struct item { uint64 unique_id; }; +//Equip position constants +enum equip_pos { + EQP_HEAD_LOW = 0x000001, + EQP_HEAD_MID = 0x000200, //512 + EQP_HEAD_TOP = 0x000100, //256 + EQP_HAND_R = 0x000002, //2 + EQP_HAND_L = 0x000020, //32 + EQP_ARMOR = 0x000010, //16 + EQP_SHOES = 0x000040, //64 + EQP_GARMENT = 0x000004, //4 + EQP_ACC_L = 0x000008, //8 + EQP_ACC_R = 0x000080, //128 + EQP_COSTUME_HEAD_TOP = 0x000400, //1024 + EQP_COSTUME_HEAD_MID = 0x000800, //2048 + EQP_COSTUME_HEAD_LOW = 0x001000, //4096 + EQP_COSTUME_GARMENT = 0x002000, //8192 + //UNUSED_COSTUME_FLOOR = 0x004000, //16384 + EQP_AMMO = 0x008000, //32768 + EQP_SHADOW_ARMOR = 0x010000, //65536 + EQP_SHADOW_WEAPON = 0x020000, //131072 + EQP_SHADOW_SHIELD = 0x040000, //262144 + EQP_SHADOW_SHOES = 0x080000, //524288 + EQP_SHADOW_ACC_R = 0x100000, //1048576 + EQP_SHADOW_ACC_L = 0x200000, //2097152 +}; + struct point { unsigned short map; short x,y; diff --git a/src/map/pc.h b/src/map/pc.h index 90448fa1d..3a1d15746 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -545,32 +545,6 @@ struct map_session_data { }; -//Equip position constants -enum equip_pos { - EQP_HEAD_LOW = 0x000001, - EQP_HEAD_MID = 0x000200, //512 - EQP_HEAD_TOP = 0x000100, //256 - EQP_HAND_R = 0x000002, //2 - EQP_HAND_L = 0x000020, //32 - EQP_ARMOR = 0x000010, //16 - EQP_SHOES = 0x000040, //64 - EQP_GARMENT = 0x000004, //4 - EQP_ACC_L = 0x000008, //8 - EQP_ACC_R = 0x000080, //128 - EQP_COSTUME_HEAD_TOP = 0x000400, //1024 - EQP_COSTUME_HEAD_MID = 0x000800, //2048 - EQP_COSTUME_HEAD_LOW = 0x001000, //4096 - EQP_COSTUME_GARMENT = 0x002000, //8192 - //UNUSED_COSTUME_FLOOR = 0x004000, //16384 - EQP_AMMO = 0x008000, //32768 - EQP_SHADOW_ARMOR = 0x010000, //65536 - EQP_SHADOW_WEAPON = 0x020000, //131072 - EQP_SHADOW_SHIELD = 0x040000, //262144 - EQP_SHADOW_SHOES = 0x080000, //524288 - EQP_SHADOW_ACC_R = 0x100000, //1048576 - EQP_SHADOW_ACC_L = 0x200000, //2097152 -}; - #define EQP_WEAPON EQP_HAND_R #define EQP_SHIELD EQP_HAND_L #define EQP_ARMS (EQP_HAND_R|EQP_HAND_L) -- cgit v1.2.3-60-g2f50