diff --git a/sql-files/main.sql b/sql-files/main.sql index 95cdbf23a6..386b3aca52 100644 --- a/sql-files/main.sql +++ b/sql-files/main.sql @@ -671,8 +671,8 @@ CREATE TABLE IF NOT EXISTS `homunculus` ( `luk` smallint(4) unsigned NOT NULL default '0', `hp` int(11) unsigned NOT NULL default '0', `max_hp` int(11) unsigned NOT NULL default '0', - `sp` int(11) NOT NULL default '0', - `max_sp` int(11) NOT NULL default '0', + `sp` int(11) unsigned NOT NULL default '0', + `max_sp` int(11) unsigned NOT NULL default '0', `skill_point` smallint(4) unsigned NOT NULL default '0', `alive` tinyint(2) NOT NULL default '1', `rename_flag` tinyint(2) NOT NULL default '0', diff --git a/sql-files/upgrades/upgrade_20240907.sql b/sql-files/upgrades/upgrade_20240907.sql new file mode 100644 index 0000000000..128dc2124d --- /dev/null +++ b/sql-files/upgrades/upgrade_20240907.sql @@ -0,0 +1,3 @@ +ALTER TABLE `homunculus` + CHANGE COLUMN `sp` `sp` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `max_hp`, + CHANGE COLUMN `max_sp` `max_sp` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `sp`; diff --git a/src/char/int_homun.cpp b/src/char/int_homun.cpp index 7f0b4021cd..1c4ae8379d 100644 --- a/src/char/int_homun.cpp +++ b/src/char/int_homun.cpp @@ -189,10 +189,10 @@ bool mapif_homunculus_load(int homun_id, struct s_homunculus* hd) Sql_GetData(sql_handle, 12, &data, nullptr); hd->int_ = atoi(data); Sql_GetData(sql_handle, 13, &data, nullptr); hd->dex = atoi(data); Sql_GetData(sql_handle, 14, &data, nullptr); hd->luk = atoi(data); - Sql_GetData(sql_handle, 15, &data, nullptr); hd->hp = atoi(data); - Sql_GetData(sql_handle, 16, &data, nullptr); hd->max_hp = atoi(data); - Sql_GetData(sql_handle, 17, &data, nullptr); hd->sp = atoi(data); - Sql_GetData(sql_handle, 18, &data, nullptr); hd->max_sp = atoi(data); + Sql_GetData(sql_handle, 15, &data, nullptr); hd->hp = static_cast(strtoul(data, nullptr, 10)); + Sql_GetData(sql_handle, 16, &data, nullptr); hd->max_hp = static_cast(strtoul(data, nullptr, 10)); + Sql_GetData(sql_handle, 17, &data, nullptr); hd->sp = static_cast(strtoul(data, nullptr, 10)); + Sql_GetData(sql_handle, 18, &data, nullptr); hd->max_sp = static_cast(strtoul(data, nullptr, 10)); Sql_GetData(sql_handle, 19, &data, nullptr); hd->skillpts = atoi(data); Sql_GetData(sql_handle, 20, &data, nullptr); hd->rename_flag = atoi(data); Sql_GetData(sql_handle, 21, &data, nullptr); hd->vaporize = atoi(data); diff --git a/src/common/mmo.hpp b/src/common/mmo.hpp index 671f40b09f..e5cdc23e57 100644 --- a/src/common/mmo.hpp +++ b/src/common/mmo.hpp @@ -497,7 +497,7 @@ struct s_homunculus { //[orn] uint32 char_id; short class_; short prev_class; - int hp,max_hp,sp,max_sp; + uint32 hp,max_hp,sp,max_sp; unsigned int intimacy; //[orn] short hunger; struct s_skill hskill[MAX_HOMUNSKILL]; //albator diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 5f56b722f2..0663ff0864 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -1768,13 +1768,30 @@ void clif_homunculus_updatestatus(map_session_data& sd, _sp type) { p.value = static_cast( std::minhomunculus.exp)>( sd.hd->homunculus.exp, std::numeric_limits::max() ) ); break; case SP_HP: - if (status->max_hp > (std::is_same::value ? INT16_MAX : INT32_MAX / 100)) + // Homunculus HP and SP bars will screw up if the percentage calculation exceeds signed values + // Any value above will screw up the bars +#if PACKETVER_MAIN_NUM >= 20200819 || PACKETVER_RE_NUM >= 20200723 || PACKETVER_ZERO_NUM >= 20190626 + // Tested maximum: 2147483647 (INT32_MAX) + if (status->max_hp > INT32_MAX) +#elif PACKETVER_MAIN_NUM >= 20131230 || PACKETVER_RE_NUM >= 20131230 || defined(PACKETVER_ZERO) + // Tested maximum: 21474836 (INT32_MAX / 100) + if (status->max_hp > INT32_MAX / 100) +#else + // Tested maximum: 32767 (INT16_MAX) + if (status->max_hp > INT16_MAX) +#endif p.value = status->hp / (status->max_hp / 100); else p.value = static_cast(status->hp); break; case SP_SP: - if (status->max_sp > (std::is_same::value ? INT16_MAX : INT32_MAX / 100)) +#if PACKETVER_MAIN_NUM >= 20200819 || PACKETVER_RE_NUM >= 20200723 || PACKETVER_ZERO_NUM >= 20190626 + // Tested maximum: 2147483647 (INT32_MAX) + if (status->max_sp > INT32_MAX) +#else + // Tested maximum: 32767 (INT16_MAX) + if (status->max_sp > INT16_MAX) +#endif p.value = status->sp / (status->max_sp / 100); else p.value = static_cast(status->sp); @@ -1827,15 +1844,32 @@ void clif_hominfo( map_session_data *sd, struct homun_data *hd, int flag ){ p.flee = status->flee; p.amotion = (flag) ? 0 : status->amotion; // Homunculus HP and SP bars will screw up if the percentage calculation exceeds signed values - // Tested maximum: 21474836(=INT32_MAX/100), any value above will screw up the bars - if( status->max_hp > ( std::is_same::value ? INT16_MAX : INT32_MAX / 100 ) ){ + // Any value above will screw up the bars +#if PACKETVER_MAIN_NUM >= 20200819 || PACKETVER_RE_NUM >= 20200723 || PACKETVER_ZERO_NUM >= 20190626 + // Tested maximum: 2147483647 (INT32_MAX) + if (status->max_hp > INT32_MAX) +#elif PACKETVER_MAIN_NUM >= 20131230 || PACKETVER_RE_NUM >= 20131230 || defined(PACKETVER_ZERO) + // Tested maximum: 21474836 (INT32_MAX / 100) + if (status->max_hp > INT32_MAX / 100) +#else + // Tested maximum: 32767 (INT16_MAX) + if (status->max_hp > INT16_MAX) +#endif + { p.hp = status->hp / ( status->max_hp / 100 ); p.maxHp = 100; }else{ p.hp = static_cast(status->hp); p.maxHp = static_cast(status->max_hp); } - if( status->max_sp > ( std::is_same::value ? INT16_MAX : INT32_MAX / 100 ) ){ +#if PACKETVER_MAIN_NUM >= 20200819 || PACKETVER_RE_NUM >= 20200723 || PACKETVER_ZERO_NUM >= 20190626 + // Tested maximum: 2147483647 (INT32_MAX) + if (status->max_sp > INT32_MAX) +#else + // Tested maximum: 32767 (INT16_MAX) + if (status->max_sp > INT16_MAX) +#endif + { p.sp = status->sp / ( status->max_sp / 100 ); p.maxSp = 100; }else{