diff --git a/conf/battle/items.conf b/conf/battle/items.conf index da58cf3986..3f6a5f77c3 100644 --- a/conf/battle/items.conf +++ b/conf/battle/items.conf @@ -98,3 +98,11 @@ item_enabled_npc: yes // If yes, undroppable items will be destroyed instead of appearing on the map when a player's inventory is full. // Default: yes item_flooritem_check: yes + +// Set default bound type for item_flag &8 (see db/[pre-]re/item_flag.txt +// 0 - None +// 1 - Account +// 2 - Guild +// 3 - Party +// 4 - Character +default_bind_on_equip: 4 diff --git a/db/import-tmpl/item_flag.txt b/db/import-tmpl/item_flag.txt index 3ae5039bad..a4419df723 100644 --- a/db/import-tmpl/item_flag.txt +++ b/db/import-tmpl/item_flag.txt @@ -5,4 +5,5 @@ // 1 - As Dead Branch item (will be logged at `branchlog` table and cannot be used at 'nobranch' mapflag) // 2 - As item group container, check player's inventory and weight before consumed // 4 - GUID item, cannot be stacked even same or stackable item +// 8 - Item will be bound item when equipped // NOTE: For removing flag by import file, use "-" to remove the flag. Example, 604,-1 will removes flag 1 from Branch_Of_Dead_Tree diff --git a/db/packet_db.txt b/db/packet_db.txt index f5c927cc80..f5d298f2ed 100644 --- a/db/packet_db.txt +++ b/db/packet_db.txt @@ -1057,7 +1057,7 @@ packet_ver: 22 0x02d0,-1 0x02d1,-1 0x02d2,-1 -0x02d3,4 +0x02d3,4,ZC_NOTIFY_BIND_ON_EQUIP,2 0x02d4,29 0x02d5,2 0x02d6,6,viewplayerequip,2 diff --git a/db/pre-re/item_flag.txt b/db/pre-re/item_flag.txt index 2126e5d970..0fe7309abf 100644 --- a/db/pre-re/item_flag.txt +++ b/db/pre-re/item_flag.txt @@ -5,6 +5,7 @@ // 1 - As Dead Branch item (will be logged at `branchlog` table and cannot be used at 'nobranch' mapflag) // 2 - As item group container, check player's inventory and weight before consumed // 4 - GUID item, cannot be stacked even same or stackable item +// 8 - Item will be bound item when equipped // NOTE: For removing flag by import file, use "-" to remove the flag. Example, 604,-1 will removes flag 1 from Branch_Of_Dead_Tree // Logged as Dead Branch item diff --git a/db/re/item_flag.txt b/db/re/item_flag.txt index 92e28ef7b5..96a78c2156 100644 --- a/db/re/item_flag.txt +++ b/db/re/item_flag.txt @@ -5,6 +5,7 @@ // 1 - As Dead Branch item (will be logged at `branchlog` table and cannot be used at 'nobranch' mapflag) // 2 - As item group container, check player's inventory and weight before consumed // 4 - GUID item, cannot be stacked even same or stackable item +// 8 - Item will be bound item when equipped // NOTE: For removing flag by import file, use "-" to remove the flag. Example, 604,-1 will removes flag 1 from Branch_Of_Dead_Tree // Logged as Dead Branch item diff --git a/src/common/mmo.h b/src/common/mmo.h index badfe34ff2..4c14819327 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -798,7 +798,7 @@ enum bound_type { BOUND_CHAR, /// 4 - Character Bound BOUND_MAX, - //BOUND_ONEQUIP = 1, //! TODO + BOUND_ONEQUIP = 1, ///< Show notification when item will be bound on equip BOUND_DISPYELLOW = 2, /// Shows the item name in yellow color }; diff --git a/src/map/battle.c b/src/map/battle.c index 12afb3e605..e9d0db79de 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -7939,6 +7939,7 @@ static const struct _battle_data { { "snap_dodge", &battle_config.snap_dodge, 0, 0, 1, }, { "stormgust_knockback", &battle_config.stormgust_knockback, 1, 0, 1, }, { "default_fixed_castrate", &battle_config.default_fixed_castrate, 20, 0, 100, }, + { "default_bind_on_equip", &battle_config.default_bind_on_equip, BOUND_CHAR, BOUND_NONE, BOUND_MAX-1, }, }; #ifndef STATS_OPT_OUT diff --git a/src/map/battle.h b/src/map/battle.h index eae76a892b..880d533507 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -580,6 +580,7 @@ extern struct Battle_Config int snap_dodge; // Enable or disable dodging damage snapping away [csnv] int stormgust_knockback; int default_fixed_castrate; + int default_bind_on_equip; } battle_config; void do_init_battle(void); diff --git a/src/map/clif.c b/src/map/clif.c index 9c39efde6d..9ba570d1eb 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -2253,7 +2253,7 @@ void clif_additem(struct map_session_data *sd, int n, int amount, unsigned char #endif #if PACKETVER >= 20071002 /* Yellow color only for non-stackable item */ - WFIFOW(fd,offs+27)=(sd->status.inventory[n].bound && !itemdb_isstackable(sd->status.inventory[n].nameid)) ? BOUND_DISPYELLOW : 0; + WFIFOW(fd,offs+27)=(sd->status.inventory[n].bound && !itemdb_isstackable(sd->status.inventory[n].nameid)) ? BOUND_DISPYELLOW : sd->inventory_data[n]->flag.bindOnEquip ? BOUND_ONEQUIP : 0; #endif } @@ -2322,7 +2322,7 @@ void clif_item_sub_v5(unsigned char *buf, int n, int idx, struct item *it, struc WBUFB(buf,n+13) = it->refine; //refine lvl clif_addcards(WBUFP(buf, n+14), it); //EQUIPSLOTINFO 8B WBUFL(buf,n+22) = it->expire_time; - WBUFW(buf,n+26) = it->bound ? BOUND_DISPYELLOW : 0; //bindOnEquipType + WBUFW(buf,n+26) = it->bound ? BOUND_DISPYELLOW : id->flag.bindOnEquip ? BOUND_ONEQUIP : 0; //bindOnEquipType WBUFW(buf,n+28) = (id->equip&EQP_VISIBLE) ? id->look : 0; //V5_ITEM_flag WBUFB(buf,n+30) = it->identify; //0x1 IsIdentified @@ -2359,7 +2359,7 @@ void clif_item_sub(unsigned char *buf, int n, int idx, struct item *it, struct i clif_addcards(WBUFP(buf, n+12), it); //8B #if PACKETVER >= 20071002 WBUFL(buf,n+20) = it->expire_time; - WBUFW(buf,n+24) = it->bound ? BOUND_DISPYELLOW : 0; + WBUFW(buf,n+24) = it->bound ? BOUND_DISPYELLOW : id->flag.bindOnEquip ? BOUND_ONEQUIP : 0; #endif #if PACKETVER >= 20100629 WBUFW(buf,n+26) = (id->equip&EQP_VISIBLE) ? id->look : 0; @@ -17408,6 +17408,26 @@ void clif_crimson_marker(struct map_session_data *sd, struct block_list *bl, boo clif_send(buf, len, &sd->bl, SELF); } +/** + * 02d3 .W (ZC_NOTIFY_BIND_ON_EQUIP) + **/ +void clif_notify_bindOnEquip(struct map_session_data *sd, int n) { + struct s_packet_db *info = NULL; + int cmd = 0; + + nullpo_retv(sd); + + cmd = packet_db_ack[sd->packet_ver][ZC_NOTIFY_BIND_ON_EQUIP]; + info = &packet_db[sd->packet_ver][cmd]; + if (!cmd || !info->len) + return; + + WFIFOHEAD(sd->fd, info->len); + WFIFOW(sd->fd, 0) = cmd; + WFIFOW(sd->fd, info->pos[0]) = n+2; + WFIFOSET(sd->fd, info->len); +} + /// [Ind/Hercules] void clif_showscript(struct block_list* bl, const char* message) { char buf[256]; @@ -18105,6 +18125,7 @@ void packetdb_readdb(void) { "ZC_PERSONAL_INFOMATION_CHN", ZC_PERSONAL_INFOMATION_CHN}, { "ZC_CLEAR_DIALOG", ZC_CLEAR_DIALOG}, { "ZC_C_MARKERINFO", ZC_C_MARKERINFO}, + { "ZC_NOTIFY_BIND_ON_EQUIP", ZC_NOTIFY_BIND_ON_EQUIP }, }; const char *filename[] = { "packet_db.txt", DBIMPORT"/packet_db.txt"}; int f; diff --git a/src/map/clif.h b/src/map/clif.h index 3ab83ebd01..7b71305a78 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -47,6 +47,7 @@ enum e_packet_ack { ZC_PERSONAL_INFOMATION_CHN, ZC_CLEAR_DIALOG, ZC_C_MARKERINFO, + ZC_NOTIFY_BIND_ON_EQUIP, //add other here MAX_ACK_FUNC //auto upd len }; @@ -888,6 +889,7 @@ void clif_showscript(struct block_list* bl, const char* message); void clif_party_leaderchanged(struct map_session_data *sd, int prev_leader_aid, int new_leader_aid); void clif_account_name(int fd, uint32 account_id, const char* accname); +void clif_notify_bindOnEquip(struct map_session_data *sd, int n); //void clif_broadcast_obtain_special_item(); ///TODO! diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 1c10975fb6..8d7452dbac 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -919,6 +919,7 @@ static bool itemdb_read_flag(char* fields[], int columns, int current) { #ifdef ENABLE_ITEM_GUID if (flag&4 && itemdb_isstackable2(id)) id->flag.guid = set ? 1 : 0; #endif + if (flag&8) id->flag.bindOnEquip = true; return true; } diff --git a/src/map/itemdb.h b/src/map/itemdb.h index 795c5660e6..0ebb3218d5 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -416,6 +416,7 @@ struct item_data unsigned dead_branch : 1; // As dead branch item. Logged at `branchlog` table and cannot be used at 'nobranch' mapflag [Cydh] unsigned group : 1; // As item group container [Cydh] unsigned guid : 1; // This item always be attached with GUID and make it as bound item! [Cydh] + bool bindOnEquip; ///< Set item as bound when equipped } flag; struct {// item stacking limitation unsigned short amount; diff --git a/src/map/pc.c b/src/map/pc.c index 9e81d88abf..b4a1ff451d 100755 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -9166,6 +9166,12 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos) clif_equipitemack(sd,n,0,0); //Fail return false; } + + if (id->flag.bindOnEquip && !sd->status.inventory[n].bound) { + sd->status.inventory[n].bound = (char)battle_config.default_bind_on_equip; + clif_notify_bindOnEquip(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..