summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql-files/main.sql2
-rw-r--r--sql-files/upgrades/2015-08-27--20-42.sql3
-rw-r--r--src/char/char.c9
-rw-r--r--src/common/mmo.h2
-rw-r--r--src/map/clif.c33
-rw-r--r--src/map/clif.h1
-rw-r--r--src/map/packets.h1
-rw-r--r--src/map/packets_struct.h19
8 files changed, 50 insertions, 20 deletions
diff --git a/sql-files/main.sql b/sql-files/main.sql
index a980cfd80..64bdfb5c7 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -176,6 +176,7 @@ CREATE TABLE IF NOT EXISTS `char` (
`unban_time` INT(11) UNSIGNED NOT NULL DEFAULT '0',
`uniqueitem_counter` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
`sex` ENUM('M','F','U') NOT NULL DEFAULT 'U',
+ `hotkey_rowshift` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`char_id`),
UNIQUE KEY `name_key` (`name`),
KEY `account_id` (`account_id`),
@@ -800,6 +801,7 @@ INSERT INTO `sql_updates` (`timestamp`) VALUES (1409590380); -- 2014-09-01--16-5
INSERT INTO `sql_updates` (`timestamp`) VALUES (1414975503); -- 2014-11-03--00-45.sql
INSERT INTO `sql_updates` (`timestamp`) VALUES (1435860840); -- 2015-07-02--18-14.sql
INSERT INTO `sql_updates` (`timestamp`) VALUES (1436360978); -- 2015-07-08--13-08.sql
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1440688342); -- 2015-08-27--20-42.sql
--
-- Table structure for table `storage`
diff --git a/sql-files/upgrades/2015-08-27--20-42.sql b/sql-files/upgrades/2015-08-27--20-42.sql
new file mode 100644
index 000000000..e95e1836b
--- /dev/null
+++ b/sql-files/upgrades/2015-08-27--20-42.sql
@@ -0,0 +1,3 @@
+#1440688342
+ALTER TABLE `char` ADD COLUMN `hotkey_rowshift` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0';
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1440688342);
diff --git a/src/char/char.c b/src/char/char.c
index 576eb9630..819cd2ef8 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -443,7 +443,7 @@ int char_mmo_char_tosql(int char_id, struct mmo_charstatus* p)
(p->head_mid != cp->head_mid) || (p->head_bottom != cp->head_bottom) || (p->delete_date != cp->delete_date) ||
(p->rename != cp->rename) || (p->slotchange != cp->slotchange) || (p->robe != cp->robe) ||
(p->show_equip != cp->show_equip) || (p->allow_party != cp->allow_party) || (p->font != cp->font) ||
- (p->uniqueitem_counter != cp->uniqueitem_counter)
+ (p->uniqueitem_counter != cp->uniqueitem_counter) || (p->hotkey_rowshift != cp->hotkey_rowshift)
) {
//Save status
unsigned int opt = 0;
@@ -460,7 +460,8 @@ int char_mmo_char_tosql(int char_id, struct mmo_charstatus* p)
"`option`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',`homun_id`='%d',`elemental_id`='%d',"
"`weapon`='%d',`shield`='%d',`head_top`='%d',`head_mid`='%d',`head_bottom`='%d',"
"`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d', `rename`='%d',"
- "`delete_date`='%lu',`robe`='%d',`slotchange`='%d', `char_opt`='%u', `font`='%u', `uniqueitem_counter` ='%u'"
+ "`delete_date`='%lu',`robe`='%d',`slotchange`='%d', `char_opt`='%u', `font`='%u', `uniqueitem_counter` ='%u',"
+ "`hotkey_rowshift`='%d'"
" WHERE `account_id`='%d' AND `char_id` = '%d'",
char_db, p->base_level, p->job_level,
p->base_exp, p->job_exp, p->zeny,
@@ -472,6 +473,7 @@ int char_mmo_char_tosql(int char_id, struct mmo_charstatus* p)
mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->rename,
(unsigned long)p->delete_date, // FIXME: platform-dependent size
p->robe,p->slotchange,opt,p->font,p->uniqueitem_counter,
+ p->hotkey_rowshift,
p->account_id, p->char_id) )
{
Sql_ShowDebug(inter->sql_handle);
@@ -1160,7 +1162,7 @@ int char_mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_every
"`status_point`,`skill_point`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`elemental_id`,`hair`,"
"`hair_color`,`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`last_x`,`last_y`,"
"`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`,`robe`,`slotchange`,"
- "`char_opt`,`font`,`uniqueitem_counter`,`sex`"
+ "`char_opt`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`"
" FROM `%s` WHERE `char_id`=? LIMIT 1", char_db)
|| SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &char_id, 0)
|| SQL_ERROR == SQL->StmtExecute(stmt)
@@ -1221,6 +1223,7 @@ int char_mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_every
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 54, SQLDT_UCHAR, &p->font, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 55, SQLDT_UINT, &p->uniqueitem_counter, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 56, SQLDT_ENUM, &sex, sizeof(sex), NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt, 57, SQLDT_UCHAR, &p->hotkey_rowshift, 0, NULL, NULL)
) {
SqlStmt_ShowDebug(stmt);
SQL->StmtFree(stmt);
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 3e497c667..1567f20be 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -533,6 +533,8 @@ struct mmo_charstatus {
unsigned char font;
uint32 uniqueitem_counter;
+
+ unsigned char hotkey_rowshift;
};
typedef enum mail_status {
diff --git a/src/map/clif.c b/src/map/clif.c
index 26cf4faac..12565de3c 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -9430,31 +9430,29 @@ void clif_parse_TickSend(int fd, struct map_session_data *sd)
/// 02b9 { <is skill>.B <id>.L <count>.W }*27 (ZC_SHORTCUT_KEY_LIST)
/// 07d9 { <is skill>.B <id>.L <count>.W }*36 (ZC_SHORTCUT_KEY_LIST_V2, PACKETVER >= 20090603)
/// 07d9 { <is skill>.B <id>.L <count>.W }*38 (ZC_SHORTCUT_KEY_LIST_V2, PACKETVER >= 20090617)
+/// 0a00 <rotate>.B { <is skill>.B <id>.L <count>.W }*38 (ZC_SHORTCUT_KEY_LIST_V3, PACKETVER >= 20141022)
void clif_hotkeys_send(struct map_session_data *sd) {
#ifdef HOTKEY_SAVING
- const int fd = sd->fd;
+ struct packet_hotkey p;
int i;
- int offset = 2;
-#if PACKETVER < 20090603
- const int cmd = 0x2b9;
-#elif PACKETVER < 20141022
- const int cmd = 0x7d9;
-#else
- const int cmd = 0xa00;
- offset = 3;
+ p.PacketType = hotkeyType;
+#if PACKETVER >= 20141022
+ p.Rotate = sd->status.hotkey_rowshift;
#endif
- if (!fd) return;
- WFIFOHEAD(fd, offset+MAX_HOTKEYS*7);
- WFIFOW(fd, 0) = cmd;
- for(i = 0; i < MAX_HOTKEYS; i++) {
- WFIFOB(fd, offset + 0 + i * 7) = sd->status.hotkeys[i].type; // type: 0: item, 1: skill
- WFIFOL(fd, offset + 1 + i * 7) = sd->status.hotkeys[i].id; // item or skill ID
- WFIFOW(fd, offset + 5 + i * 7) = sd->status.hotkeys[i].lv; // item qty or skill level
+ for(i = 0; i < ARRAYLENGTH(p.hotkey); i++) {
+ p.hotkey[i].isSkill = sd->status.hotkeys[i].type;
+ p.hotkey[i].ID = sd->status.hotkeys[i].id;
+ p.hotkey[i].count = sd->status.hotkeys[i].lv;
}
- WFIFOSET(fd, packet_len(cmd));
+ clif->send(&p, sizeof(p), &sd->bl, SELF);
#endif
}
+void clif_parse_HotkeyRowShift(int fd, struct map_session_data *sd)
+{
+ int cmd = RFIFOW(fd, 0);
+ sd->status.hotkey_rowshift = RFIFOB(fd, packet_db[cmd].pos[0]);
+}
/// Request to update a position on the hotkey bar (CZ_SHORTCUT_KEY_CHANGE).
/// 02ba <index>.W <is skill>.B <id>.L <count>.W
@@ -19333,4 +19331,5 @@ void clif_defaults(void) {
clif->pNPCMarketPurchase = clif_parse_NPCMarketPurchase;
/* */
clif->add_random_options = clif_add_random_options;
+ clif->pHotkeyRowShift = clif_parse_HotkeyRowShift;
}
diff --git a/src/map/clif.h b/src/map/clif.h
index 3f0d043f7..fdcc929e3 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -1317,6 +1317,7 @@ struct clif_interface {
void (*pNPCMarketPurchase) (int fd, struct map_session_data *sd);
/* */
void (*add_random_options) (unsigned char* buf, struct item* item);
+ void (*pHotkeyRowShift) (int fd, struct map_session_data *sd);
};
#ifdef HERCULES_CORE
diff --git a/src/map/packets.h b/src/map/packets.h
index e84607aaf..1f465b833 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -2850,6 +2850,7 @@ packet(0x96e,-1,clif->ackmergeitems);
packet(0x091A,26,clif->pFriendsListAdd,2);
packet(0x0899,5,clif->pHomMenu,2,4);
packet(0x0438,36,clif->pStoragePassword,0);
+ packet(0x0A01,3,clif->pHotkeyRowShift,2);
#endif
#if PACKETVER >= 20150226
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index daf77c134..8f9747747 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -18,6 +18,13 @@ enum packet_headers {
banking_checkType = 0x9a6,
cart_additem_ackType = 0x12c,
sc_notickType = 0x196,
+#if PACKETVER >= 20141022
+ hotkeyType = 0xa00,
+#elif PACKETVER >= 20090603
+ hotkeyType = 0x7d9,
+#else
+ hotkeyType = 0x2b9,
+#endif
#if PACKETVER >= 20150226
cartaddType = 0xa0b,
#elif PACKETVER >= 5
@@ -1082,6 +1089,18 @@ struct packet_party_leader_changed {
unsigned int new_leader_aid;
} __attribute__((packed));
+struct packet_hotkey {
+ short PacketType;
+#if PACKETVER >= 20141022
+ char Rotate;
+#endif
+ struct {
+ char isSkill; // 0: Item, 1:Skill
+ unsigned int ID; // Item/Skill ID
+ short count; // Item Quantity/Skill Level
+ } hotkey[MAX_HOTKEYS];
+} __attribute__((packed));
+
#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
#pragma pack(pop)
#endif // not NetBSD < 6 / Solaris