diff --git a/sql-files/main.sql b/sql-files/main.sql index 4d00bd9b76..49f50940fa 100644 --- a/sql-files/main.sql +++ b/sql-files/main.sql @@ -282,6 +282,7 @@ CREATE TABLE IF NOT EXISTS `char` ( `title_id` INT(11) unsigned NOT NULL default '0', `show_equip` tinyint(3) unsigned NOT NULL default '0', `inventory_slots` smallint(6) NOT NULL default '100', + `body_direction` tinyint(1) unsigned NOT NULL default '0', PRIMARY KEY (`char_id`), UNIQUE KEY `name_key` (`name`), KEY `account_id` (`account_id`), diff --git a/sql-files/upgrades/upgrade_20220830.sql b/sql-files/upgrades/upgrade_20220830.sql new file mode 100644 index 0000000000..809a78e865 --- /dev/null +++ b/sql-files/upgrades/upgrade_20220830.sql @@ -0,0 +1,3 @@ +ALTER TABLE `char` + ADD COLUMN `body_direction` tinyint unsigned NOT NULL default '0' +; diff --git a/src/char/char.cpp b/src/char/char.cpp index 0f0a29c71a..406e9ef7d3 100644 --- a/src/char/char.cpp +++ b/src/char/char.cpp @@ -346,18 +346,21 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){ (p->partner_id != cp->partner_id) || (p->father != cp->father) || (p->mother != cp->mother) || (p->child != cp->child) || (p->karma != cp->karma) || (p->manner != cp->manner) || - (p->fame != cp->fame) || (p->inventory_slots != cp->inventory_slots) + (p->fame != cp->fame) || (p->inventory_slots != cp->inventory_slots) || + (p->body_direction != cp->body_direction) ) { if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `class`='%d'," "`hair`='%d', `hair_color`='%d', `clothes_color`='%d', `body`='%d'," "`partner_id`='%u', `father`='%u', `mother`='%u', `child`='%u'," - "`karma`='%d',`manner`='%d', `fame`='%d', `inventory_slots`='%hu'" + "`karma`='%d',`manner`='%d', `fame`='%d', `inventory_slots`='%hu'," + "`body_direction`='%d'" " WHERE `account_id`='%d' AND `char_id` = '%d'", schema_config.char_db, p->class_, p->hair, p->hair_color, p->clothes_color, p->body, p->partner_id, p->father, p->mother, p->child, p->karma, p->manner, p->fame, p->inventory_slots, + p->body_direction, p->account_id, p->char_id) ) { Sql_ShowDebug(sql_handle); @@ -936,7 +939,7 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf, uint8* coun "`robe`,`moves`,`unban_time`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`,`title_id`,`show_equip`," "`hotkey_rowshift2`," "`max_ap`,`ap`,`trait_point`,`pow`,`sta`,`wis`,`spl`,`con`,`crt`," - "`inventory_slots`" + "`inventory_slots`,`body_direction`" " FROM `%s` WHERE `account_id`='%d' AND `char_num` < '%d'", schema_config.char_db, sd->account_id, MAX_CHARS) || SQL_ERROR == SqlStmt_Execute(stmt) || SQL_ERROR == SqlStmt_BindColumn(stmt, 0, SQLDT_INT, &p.char_id, 0, NULL, NULL) @@ -995,6 +998,7 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf, uint8* coun || SQL_ERROR == SqlStmt_BindColumn(stmt, 53, SQLDT_SHORT, &p.con, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 54, SQLDT_SHORT, &p.crt, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 55, SQLDT_UINT16, &p.inventory_slots, 0, NULL, NULL) + || SQL_ERROR == SqlStmt_BindColumn(stmt, 56, SQLDT_UINT8, &p.body_direction, 0, NULL, NULL) ) { SqlStmt_ShowDebug(stmt); @@ -1064,7 +1068,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev "`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`,`robe`, `moves`," "`unban_time`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`,`clan_id`,`title_id`,`show_equip`,`hotkey_rowshift2`," "`max_ap`,`ap`,`trait_point`,`pow`,`sta`,`wis`,`spl`,`con`,`crt`," - "`inventory_slots`" + "`inventory_slots`,`body_direction`" " FROM `%s` WHERE `char_id`=? LIMIT 1", schema_config.char_db) || SQL_ERROR == SqlStmt_BindParam(stmt, 0, SQLDT_INT, &char_id, 0) || SQL_ERROR == SqlStmt_Execute(stmt) @@ -1141,6 +1145,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev || SQL_ERROR == SqlStmt_BindColumn(stmt, 70, SQLDT_SHORT, &p->con, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 71, SQLDT_SHORT, &p->crt, 0, NULL, NULL) || SQL_ERROR == SqlStmt_BindColumn(stmt, 72, SQLDT_UINT16, &p->inventory_slots, 0, NULL, NULL) + || SQL_ERROR == SqlStmt_BindColumn(stmt, 73, SQLDT_UINT8, &p->body_direction, 0, NULL, NULL) ) { SqlStmt_ShowDebug(stmt); @@ -2334,7 +2339,7 @@ bool char_checkdb(void){ "`moves`,`unban_time`,`font`,`sex`,`hotkey_rowshift`,`clan_id`,`last_login`,`title_id`,`show_equip`," "`hotkey_rowshift2`," "`max_ap`,`ap`,`trait_point`,`pow`,`sta`,`wis`,`spl`,`con`,`crt`," - "`inventory_slots`" + "`inventory_slots`,`body_direction`" " FROM `%s` LIMIT 1;", schema_config.char_db) ){ Sql_ShowDebug(sql_handle); return false; diff --git a/src/common/mmo.hpp b/src/common/mmo.hpp index e86112fd02..f4d770bed7 100644 --- a/src/common/mmo.hpp +++ b/src/common/mmo.hpp @@ -572,6 +572,7 @@ struct mmo_charstatus { short shield; // view-id short head_top,head_mid,head_bottom; short robe; + uint8 body_direction; char name[NAME_LENGTH]; unsigned int base_level,job_level; diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 8ca7787d45..6bcc986e1b 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -11045,6 +11045,10 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) //Login Event npc_script_event(sd, NPCE_LOGIN); } + + // Set facing direction before check below to update client + if (battle_config.spawn_direction) + unit_setdir(&sd->bl, sd->status.body_direction, false); } else { //For some reason the client "loses" these on warp/map-change. clif_updatestatus(sd,SP_STR); diff --git a/src/map/unit.cpp b/src/map/unit.cpp index 6c5b1ca732..bf17a02914 100644 --- a/src/map/unit.cpp +++ b/src/map/unit.cpp @@ -121,8 +121,10 @@ int unit_walktoxy_sub(struct block_list *bl) ud->state.change_walk_target=0; if (bl->type == BL_PC) { - ((TBL_PC *)bl)->head_dir = 0; - clif_walkok((TBL_PC*)bl); + map_session_data *sd = BL_CAST(BL_PC, bl); + + sd->head_dir = DIR_NORTH; + clif_walkok(sd); } #if PACKETVER >= 20170726 // If this is a walking NPC and it will use a player sprite @@ -400,7 +402,7 @@ static TIMER_FUNC(unit_walktoxy_timer) return 0; } - ud->dir = dir; + unit_setdir(bl, dir, false); int dx = dirx[dir]; int dy = diry[dir]; @@ -1023,7 +1025,6 @@ int unit_escape(struct block_list *bl, struct block_list *target, short dist, ui bool unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool checkpath) { short dx,dy; - uint8 dir; struct unit_data *ud = NULL; struct map_session_data *sd = NULL; @@ -1044,8 +1045,7 @@ bool unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, boo ud->to_x = dst_x; ud->to_y = dst_y; - dir = map_calc_dir(bl, dst_x, dst_y); - ud->dir = dir; + unit_setdir(bl, map_calc_dir(bl, dst_x, dst_y), false); dx = dst_x - bl->x; dy = dst_y - bl->y; @@ -1094,27 +1094,31 @@ bool unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, boo * Sets direction of a unit * @param bl: Object to set direction * @param dir: Direction (0-7) - * @return 0 + * @param send_update: Update the client area of direction (default: true) + * @return True on success or False on failure */ -int unit_setdir(struct block_list *bl, unsigned char dir) +bool unit_setdir(block_list *bl, uint8 dir, bool send_update) { - struct unit_data *ud; - nullpo_ret(bl); - ud = unit_bl2ud(bl); + unit_data *ud = unit_bl2ud(bl); - if (!ud) - return 0; + if (ud == nullptr) + return false; ud->dir = dir; - if (bl->type == BL_PC) - ((TBL_PC *)bl)->head_dir = 0; + if (bl->type == BL_PC) { + map_session_data *sd = BL_CAST(BL_PC, bl); - clif_changed_dir(bl, AREA); + sd->head_dir = DIR_NORTH; + sd->status.body_direction = ud->dir; + } - return 0; + if (send_update) + clif_changed_dir(bl, AREA); + + return true; } /** @@ -2762,7 +2766,7 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, t_tick tick) if( DIFF_TICK(ud->attackabletime,tick) <= 0 ) { if (battle_config.attack_direction_change && (src->type&battle_config.attack_direction_change)) - ud->dir = map_calc_dir(src, target->x, target->y); + unit_setdir(src, map_calc_dir(src, target->x, target->y), false); if(ud->walktimer != INVALID_TIMER) unit_stop_walking(src,1); diff --git a/src/map/unit.hpp b/src/map/unit.hpp index a24faa24eb..478c980c23 100644 --- a/src/map/unit.hpp +++ b/src/map/unit.hpp @@ -125,7 +125,7 @@ int unit_escape(struct block_list *bl, struct block_list *target, short dist, ui // Instant unit changes bool unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool checkpath); int unit_warp(struct block_list *bl, short map, short x, short y, clr_type type); -int unit_setdir(struct block_list *bl, unsigned char dir); +bool unit_setdir(block_list *bl, uint8 dir, bool send_update = true); uint8 unit_getdir(struct block_list *bl); int unit_blown(struct block_list* bl, int dx, int dy, int count, enum e_skill_blown flag); enum e_unit_blown unit_blown_immune(struct block_list* bl, uint8 flag);