summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpanikon <panikon@zoho.com>2014-04-10 01:23:13 -0300
committerpanikon <panikon@zoho.com>2014-04-10 01:23:13 -0300
commitb5c2a71ef2575b66e7b1b25aed0ad3c60b4fef2b (patch)
tree5bea5273e47b379bc8c89cc44789c6f66a3898eb
parent4147d9f7966e7ebd94811248527cc45af1e54941 (diff)
downloadhercules-b5c2a71ef2575b66e7b1b25aed0ad3c60b4fef2b.tar.gz
hercules-b5c2a71ef2575b66e7b1b25aed0ad3c60b4fef2b.tar.bz2
hercules-b5c2a71ef2575b66e7b1b25aed0ad3c60b4fef2b.tar.xz
hercules-b5c2a71ef2575b66e7b1b25aed0ad3c60b4fef2b.zip
Fixed issue: 7936
http://hercules.ws/board/tracker/issue-7936-guildparty-item-bounded/
-rw-r--r--src/char/char.h2
-rw-r--r--src/char/int_storage.c68
-rw-r--r--src/common/mmo.h26
-rw-r--r--src/map/pc.h26
4 files changed, 88 insertions, 34 deletions
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)