summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorshennetsind <ind@henn.et>2013-11-15 03:32:45 -0200
committershennetsind <ind@henn.et>2013-11-15 03:32:45 -0200
commit1f5161a2bd3c7934373146d8cac3c131536758ba (patch)
treee788177258e61e81b5d20dc7eb43c2d7c6cd8ff5 /src/map
parentcdf6dc90768b1b524c78e3a172c7a844dd88a943 (diff)
downloadhercules-1f5161a2bd3c7934373146d8cac3c131536758ba.tar.gz
hercules-1f5161a2bd3c7934373146d8cac3c131536758ba.tar.bz2
hercules-1f5161a2bd3c7934373146d8cac3c131536758ba.tar.xz
hercules-1f5161a2bd3c7934373146d8cac3c131536758ba.zip
Official Item BindOnEquip Support
Implements the 'BindOnEquip' item db field which determines whether the piece of equipment should bind to the character upon being equipped. When a character tries to equip such a item for the first time a dialog shows up asking the character to confirm whether to equip the item or not, and notifying the character that by equipping the item it will become bound to the character, and therefore unable to be used by another character. Special Thanks to Beret for all the information, Haruna for testing. Signed-off-by: shennetsind <ind@henn.et>
Diffstat (limited to 'src/map')
-rw-r--r--src/map/clif.c16
-rw-r--r--src/map/clif.h2
-rw-r--r--src/map/itemdb.c12
-rw-r--r--src/map/itemdb.h1
-rw-r--r--src/map/packets_struct.h8
-rw-r--r--src/map/pc.c6
6 files changed, 38 insertions, 7 deletions
diff --git a/src/map/clif.c b/src/map/clif.c
index f0a85d478..f1a2ecf81 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -2235,7 +2235,7 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail) {
/* why restrict the flag to non-stackable? because this is the only packet allows stackable to,
* show the color, and therefore it'd be inconsistent with the rest (aka it'd show yellow, you relog/refresh and boom its gone)
*/
- p.bindOnEquipType = sd->status.inventory[n].bound && !itemdb->isstackable2(sd->inventory_data[n]) ? 2 : 0;
+ p.bindOnEquipType = sd->status.inventory[n].bound && !itemdb->isstackable2(sd->inventory_data[n]) ? 2 : sd->inventory_data[n]->flag.bindonequip ? 1 : 0;
#endif
}
p.result = (unsigned char)fail;
@@ -2347,7 +2347,7 @@ void clif_item_equip(short idx, struct EQUIPITEM_INFO *p, struct item *i, struct
#endif
#if PACKETVER >= 20080102
- p->bindOnEquipType = i->bound ? 2 : 0;
+ p->bindOnEquipType = i->bound ? 2 : id->flag.bindonequip ? 1 : 0;
#endif
#if PACKETVER >= 20100629
@@ -17663,7 +17663,7 @@ void clif_bgqueue_pcleft(struct map_session_data *sd) {
void clif_bgqueue_battlebegins(struct map_session_data *sd, unsigned char arena_id, enum send_target target) {
struct packet_bgqueue_battlebegins p;
- p.PacketType = bgqueue_battlebegins;
+ p.PacketType = bgqueue_battlebeginsType;
safestrncpy(p.bg_name, bg->arena[arena_id]->name, sizeof(p.bg_name));
safestrncpy(p.game_name, bg->arena[arena_id]->name, sizeof(p.game_name));
@@ -17825,6 +17825,14 @@ void clif_show_modifiers (struct map_session_data *sd) {
}
+void clif_notify_bounditem(struct map_session_data *sd, unsigned short index) {
+ struct packet_notify_bounditem p;
+
+ p.PacketType = notify_bounditemType;
+ p.index = index+2;
+
+ clif->send(&p,sizeof(p), &sd->bl, SELF);
+}
/* */
unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) {
if( sd ) {
@@ -18628,6 +18636,8 @@ void clif_defaults(void) {
clif->bank_withdraw = clif_bank_withdraw;
/* */
clif->show_modifiers = clif_show_modifiers;
+ /* */
+ clif->notify_bounditem = clif_notify_bounditem;
/*------------------------
*- Parse Incoming Packet
*------------------------*/
diff --git a/src/map/clif.h b/src/map/clif.h
index cc222d8aa..e50af7432 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -1016,6 +1016,8 @@ struct clif_interface {
void (*bank_withdraw) (struct map_session_data *sd,enum e_BANKING_WITHDRAW_ACK reason);
/* */
void (*show_modifiers) (struct map_session_data *sd);
+ /* */
+ void (*notify_bounditem) (struct map_session_data *sd, unsigned short index);
/*------------------------
*- Parse Incoming Packet
*------------------------*/
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 929a90562..8eb9c0f14 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -1652,6 +1652,7 @@ int itemdb_readdb_sql_sub(Sql *handle, int n, const char *source) {
* `equip_level_max` smallint(5) unsigned DEFAULT NULL
* `refineable` tinyint(1) unsigned DEFAULT NULL
* `view` smallint(3) unsigned DEFAULT NULL
+ * `bindonequip` tinyint(1) unsigned DEFAULT NULL
* `script` text
* `equip_script` text
* `unequip_script` text
@@ -1677,9 +1678,10 @@ int itemdb_readdb_sql_sub(Sql *handle, int n, const char *source) {
SQL->GetData(handle, 18, &data, NULL); id.elvmax = data ? atoi(data) : 0;
SQL->GetData(handle, 19, &data, NULL); id.flag.no_refine = data && atoi(data) ? 0 : 1;
SQL->GetData(handle, 20, &data, NULL); id.look = data ? atoi(data) : 0;
- SQL->GetData(handle, 21, &data, NULL); id.script = *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL;
- SQL->GetData(handle, 22, &data, NULL); id.equip_script = *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL;
- SQL->GetData(handle, 23, &data, NULL); id.unequip_script = *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL;
+ SQL->GetData(handle, 21, &data, NULL); id.flag.bindonequip = data && atoi(data) ? 1 : 0;
+ SQL->GetData(handle, 22, &data, NULL); id.script = *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL;
+ SQL->GetData(handle, 23, &data, NULL); id.equip_script = *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL;
+ SQL->GetData(handle, 24, &data, NULL); id.unequip_script = *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL;
return itemdb->validate_entry(&id, n, source);
}
@@ -1714,6 +1716,7 @@ int itemdb_readdb_libconfig_sub(config_setting_t *it, int n, const char *source)
* EquipLv: Equip required level
* Refine: Refineable
* View: View ID
+ * BindOnEquip: (true or false)
* Script: <"
* Script
* (it can be multi-line)
@@ -1827,6 +1830,9 @@ int itemdb_readdb_libconfig_sub(config_setting_t *it, int n, const char *source)
if( config_setting_lookup_int(it, "View", &i32) && i32 >= 0 )
id.look = i32;
+ if( (t = config_setting_get_member(it, "BindOnEquip")) )
+ id.flag.bindonequip = config_setting_get_bool(t) ? 1 : 0;
+
if( config_setting_lookup_string(it, "Script", &str) )
id.script = *str ? script->parse(str, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL;
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index 533a808bc..092db52d7 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -158,6 +158,7 @@ struct item_data {
unsigned trade_restriction : 9; //Item restrictions mask [Skotlex]
unsigned autoequip: 1;
unsigned buyingstore : 1;
+ unsigned bindonequip : 1;
} flag;
struct {// item stacking limitation
unsigned short amount;
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index 813aebee0..fa947a163 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -99,7 +99,8 @@ enum packet_headers {
bgqueue_revokereqType = 0x8da,
bgqueue_battlebeginackType = 0x8e0,
bgqueue_notify_entryType = 0x8d9,
- bgqueue_battlebegins = 0x8df,
+ bgqueue_battlebeginsType = 0x8df,
+ notify_bounditemType = 0x2d3,
#if PACKETVER > 20130000 /* not sure date */
dropflooritemType = 0x84b,
#else
@@ -181,6 +182,7 @@ enum packet_headers {
#else
viewequipackType = 0x2d7,
#endif
+ notifybindonequip = 0x2d3,
monsterhpType = 0x977,
maptypeproperty2Type = 0x99b,
};
@@ -804,6 +806,10 @@ struct packet_viewequip_ack {
struct EQUIPITEM_INFO list[MAX_INVENTORY];
} __attribute__((packed));
+struct packet_notify_bounditem {
+ short PacketType;
+ unsigned short index;
+} __attribute__((packed));
#pragma pack(pop)
diff --git a/src/map/pc.c b/src/map/pc.c
index d597ccf9f..317e4e476 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -8707,6 +8707,12 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
return 0;
}
+ /* won't fail from this point onwards */
+ if( id->flag.bindonequip && !sd->status.inventory[n].bound ) {
+ sd->status.inventory[n].bound = (unsigned char)IBT_CHARACTER;
+ clif->notify_bounditem(sd,n);
+ }
+
if(pos == EQP_ACC) { //Accesories should only go in one of the two,
pos = req_pos&EQP_ACC;
if (pos == EQP_ACC) //User specified both slots..