summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/HPMDataCheck.h130
-rw-r--r--src/map/clif.c9
-rw-r--r--src/map/pc.c93
-rw-r--r--src/map/pc.h3
-rw-r--r--src/map/script.c5
-rw-r--r--src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc4
-rw-r--r--src/plugins/HPMHooking/HPMHooking.HookingPoints.inc1
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Hooks.inc38
8 files changed, 240 insertions, 43 deletions
diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h
new file mode 100644
index 000000000..19b079418
--- /dev/null
+++ b/src/common/HPMDataCheck.h
@@ -0,0 +1,130 @@
+// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// See the LICENSE file
+//
+// NOTE: This file was auto-generated and should never be manually edited,
+// as it will get overwritten.
+#ifndef _HPM_DATA_CHECK_H_
+#define _HPM_DATA_CHECK_H_
+
+
+const struct s_HPMDataCheck HPMDataCheck[] = {
+ #ifdef _COMMON_CONF_H_
+ { "libconfig_interface", sizeof(struct libconfig_interface) },
+ #else
+ #define _COMMON_CONF_H_
+ #endif // _COMMON_CONF_H_
+ #ifdef _COMMON_DB_H_
+ { "DBData", sizeof(struct DBData) },
+ { "DBIterator", sizeof(struct DBIterator) },
+ { "DBMap", sizeof(struct DBMap) },
+ #else
+ #define _COMMON_DB_H_
+ #endif // _COMMON_DB_H_
+ #ifdef _COMMON_DES_H_
+ { "BIT64", sizeof(struct BIT64) },
+ #else
+ #define _COMMON_DES_H_
+ #endif // _COMMON_DES_H_
+ #ifdef _COMMON_ERS_H_
+ { "eri", sizeof(struct eri) },
+ #else
+ #define _COMMON_ERS_H_
+ #endif // _COMMON_ERS_H_
+ #ifdef _COMMON_MAPINDEX_H_
+ { "mapindex_interface", sizeof(struct mapindex_interface) },
+ #else
+ #define _COMMON_MAPINDEX_H_
+ #endif // _COMMON_MAPINDEX_H_
+ #ifdef _COMMON_MMO_H_
+ { "quest", sizeof(struct quest) },
+ #else
+ #define _COMMON_MMO_H_
+ #endif // _COMMON_MMO_H_
+ #ifdef _COMMON_SOCKET_H_
+ { "socket_interface", sizeof(struct socket_interface) },
+ #else
+ #define _COMMON_SOCKET_H_
+ #endif // _COMMON_SOCKET_H_
+ #ifdef _COMMON_STRLIB_H_
+ { "StringBuf", sizeof(struct StringBuf) },
+ { "s_svstate", sizeof(struct s_svstate) },
+ #else
+ #define _COMMON_STRLIB_H_
+ #endif // _COMMON_STRLIB_H_
+ #ifdef _MAP_ATCOMMAND_H_
+ { "AliasInfo", sizeof(struct AliasInfo) },
+ { "atcommand_interface", sizeof(struct atcommand_interface) },
+ #else
+ #define _MAP_ATCOMMAND_H_
+ #endif // _MAP_ATCOMMAND_H_
+ #ifdef _MAP_BATTLE_H_
+ { "Damage", sizeof(struct Damage) },
+ { "battle_interface", sizeof(struct battle_interface) },
+ #else
+ #define _MAP_BATTLE_H_
+ #endif // _MAP_BATTLE_H_
+ #ifdef _MAP_BUYINGSTORE_H_
+ { "buyingstore_interface", sizeof(struct buyingstore_interface) },
+ { "s_buyingstore_item", sizeof(struct s_buyingstore_item) },
+ #else
+ #define _MAP_BUYINGSTORE_H_
+ #endif // _MAP_BUYINGSTORE_H_
+ #ifdef _MAP_CHRIF_H_
+ { "auth_node", sizeof(struct auth_node) },
+ #else
+ #define _MAP_CHRIF_H_
+ #endif // _MAP_CHRIF_H_
+ #ifdef _MAP_CLIF_H_
+ { "clif_interface", sizeof(struct clif_interface) },
+ #else
+ #define _MAP_CLIF_H_
+ #endif // _MAP_CLIF_H_
+ #ifdef _MAP_ELEMENTAL_H_
+ { "elemental_skill", sizeof(struct elemental_skill) },
+ #else
+ #define _MAP_ELEMENTAL_H_
+ #endif // _MAP_ELEMENTAL_H_
+ #ifdef _MAP_GUILD_H_
+ { "eventlist", sizeof(struct eventlist) },
+ #else
+ #define _MAP_GUILD_H_
+ #endif // _MAP_GUILD_H_
+ #ifdef _MAP_MAP_H_
+ { "map_data_other_server", sizeof(struct map_data_other_server) },
+ #else
+ #define _MAP_MAP_H_
+ #endif // _MAP_MAP_H_
+ #ifdef _MAP_PACKETS_STRUCT_H_
+ { "EQUIPSLOTINFO", sizeof(struct EQUIPSLOTINFO) },
+ #else
+ #define _MAP_PACKETS_STRUCT_H_
+ #endif // _MAP_PACKETS_STRUCT_H_
+ #ifdef _MAP_PC_H_
+ { "autotrade_vending", sizeof(struct autotrade_vending) },
+ { "item_cd", sizeof(struct item_cd) },
+ #else
+ #define _MAP_PC_H_
+ #endif // _MAP_PC_H_
+ #ifdef _MAP_SCRIPT_H_
+ { "Script_Config", sizeof(struct Script_Config) },
+ { "script_interface", sizeof(struct script_interface) },
+ #else
+ #define _MAP_SCRIPT_H_
+ #endif // _MAP_SCRIPT_H_
+ #ifdef _MAP_SEARCHSTORE_H_
+ { "searchstore_interface", sizeof(struct searchstore_interface) },
+ #else
+ #define _MAP_SEARCHSTORE_H_
+ #endif // _MAP_SEARCHSTORE_H_
+ #ifdef _MAP_SKILL_H_
+ { "skill_cd", sizeof(struct skill_cd) },
+ { "skill_condition", sizeof(struct skill_condition) },
+ { "skill_interface", sizeof(struct skill_interface) },
+ { "skill_unit_save", sizeof(struct skill_unit_save) },
+ #else
+ #define _MAP_SKILL_H_
+ #endif // _MAP_SKILL_H_
+};
+unsigned int HPMDataCheckLen = ARRAYLENGTH(HPMDataCheck);
+
+#endif /* _HPM_DATA_CHECK_H_ */
diff --git a/src/map/clif.c b/src/map/clif.c
index 9ae88200c..1e1a98e09 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -11175,11 +11175,10 @@ void clif_parse_ChangeCart(int fd,struct map_session_data *sd)
/// status id:
/// SP_STR ~ SP_LUK
/// amount:
-/// client sends always 1 for this, even when using /str+ and
-/// the like
-void clif_parse_StatusUp(int fd,struct map_session_data *sd)
-{
- pc->statusup(sd,RFIFOW(fd,2));
+/// Old clients send always 1 for this, even when using /str+ and the like.
+/// Newer clients (2013-12-23 and newer) send the correct amount.
+void clif_parse_StatusUp(int fd,struct map_session_data *sd) {
+ pc->statusup(sd,RFIFOW(fd,2), RFIFOB(fd, 4));
}
diff --git a/src/map/pc.c b/src/map/pc.c
index 12a49faa8..7ca582b86 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -6174,52 +6174,88 @@ int pc_need_status_point(struct map_session_data* sd, int type, int val)
return sp;
}
-/// Raises a stat by 1.
-/// Obeys max_parameter limits.
-/// Subtracts stat points.
-///
-/// @param type The stat to change (see enum _sp)
-int pc_statusup(struct map_session_data* sd, int type)
-{
- int max, need, val;
+/**
+ * Returns the value the specified stat can be increased by with the current
+ * amount of available status points for the current character's class.
+ *
+ * @param sd The target character.
+ * @param type Stat to verify.
+ * @return Maximum value the stat could grow by.
+ */
+int pc_maxparameterincrease(struct map_session_data* sd, int type) {
+ int base, final, status_points = sd->status.status_point;
+
+ base = final = pc->getstat(sd, type);
+
+ while (final <= pc_maxparameter(sd) && status_points >= 0) {
+#ifdef RENEWAL // renewal status point cost formula
+ status_points -= (final < 100) ? (2 + (final - 1) / 10) : (16 + 4 * ((final - 100) / 5));
+#else
+ status_points -= ( 1 + (final + 9) / 10 );
+#endif
+ final++;
+ }
+ final--;
+
+ return final > base ? final-base : 0;
+}
+
+/**
+ * Raises a stat by the specified amount.
+ * Obeys max_parameter limits.
+ * Subtracts stat points.
+ *
+ * @param sd The target character.
+ * @param type The stat to change (see enum _sp)
+ * @param increase The stat increase amount.
+ * @return true if the stat was increased by any amount, false if there were no
+ * changes.
+ */
+bool pc_statusup(struct map_session_data* sd, int type, int increase) {
+ int max_increase = 0, current = 0, needed_points = 0, final_value = 0;
nullpo_ret(sd);
// check conditions
- need = pc->need_status_point(sd,type,1);
- if( type < SP_STR || type > SP_LUK || need < 0 || need > sd->status.status_point )
- {
- clif->statusupack(sd,type,0,0);
- return 1;
+ if (type < SP_STR || type > SP_LUK || increase <= 0) {
+ clif->statusupack(sd, type, 0, 0);
+ return false;
}
// check limits
- max = pc_maxparameter(sd);
- if( pc->getstat(sd,type) >= max )
- {
- clif->statusupack(sd,type,0,0);
- return 1;
+ current = pc->getstat(sd, type);
+ max_increase = pc->maxparameterincrease(sd, type);
+ increase = cap_value(increase, 0, max_increase); // cap to the maximum status points available
+ if (increase <= 0 || current + increase > pc_maxparameter(sd)) {
+ clif->statusupack(sd, type, 0, 0);
+ return false;
+ }
+
+ // check status points
+ needed_points = pc->need_status_point(sd, type, increase);
+ if (needed_points < 0 || needed_points > sd->status.status_point) { // Sanity check
+ clif->statusupack(sd, type, 0, 0);
+ return false;
}
// set new values
- val = pc->setstat(sd, type, pc->getstat(sd,type) + 1);
- sd->status.status_point -= need;
+ final_value = pc->setstat(sd, type, current + increase);
+ sd->status.status_point -= needed_points;
- status_calc_pc(sd,SCO_NONE);
+ status_calc_pc(sd, SCO_NONE);
// update increase cost indicator
- if( need != pc->need_status_point(sd,type,1) )
- clif->updatestatus(sd, SP_USTR + type-SP_STR);
+ clif->updatestatus(sd, SP_USTR + type-SP_STR);
// update statpoint count
- clif->updatestatus(sd,SP_STATUSPOINT);
+ clif->updatestatus(sd, SP_STATUSPOINT);
// update stat value
- clif->statusupack(sd,type,1,val); // required
- if( val > 255 )
- clif->updatestatus(sd,type); // send after the 'ack' to override the truncated value
+ clif->statusupack(sd, type, 1, final_value); // required
+ if (final_value > 255)
+ clif->updatestatus(sd, type); // send after the 'ack' to override the truncated value
- return 0;
+ return true;
}
/// Raises a stat by the specified amount.
@@ -10670,6 +10706,7 @@ void pc_defaults(void) {
pc->thisjobexp = pc_thisjobexp;
pc->gets_status_point = pc_gets_status_point;
pc->need_status_point = pc_need_status_point;
+ pc->maxparameterincrease = pc_maxparameterincrease;
pc->statusup = pc_statusup;
pc->statusup2 = pc_statusup2;
pc->skillup = pc_skillup;
diff --git a/src/map/pc.h b/src/map/pc.h
index f106631e7..30a24c00e 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -888,7 +888,8 @@ struct pc_interface {
unsigned int (*thisjobexp) (struct map_session_data *sd);
int (*gets_status_point) (int level);
int (*need_status_point) (struct map_session_data *sd,int type,int val);
- int (*statusup) (struct map_session_data *sd,int type);
+ int (*maxparameterincrease) (struct map_session_data* sd, int type);
+ bool (*statusup) (struct map_session_data *sd, int type, int increase);
int (*statusup2) (struct map_session_data *sd,int type,int val);
int (*skillup) (struct map_session_data *sd,uint16 skill_id);
int (*allskillup) (struct map_session_data *sd);
diff --git a/src/map/script.c b/src/map/script.c
index adea269c7..21d55ca77 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -7803,8 +7803,7 @@ BUILDIN(delequip)
/*==========================================
*
*------------------------------------------*/
-BUILDIN(statusup)
-{
+BUILDIN(statusup) {
int type;
TBL_PC *sd;
@@ -7813,7 +7812,7 @@ BUILDIN(statusup)
if( sd == NULL )
return true;
- pc->statusup(sd,type);
+ pc->statusup(sd, type, 1);
return true;
}
diff --git a/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc
index 3dfa69d4c..1767f103a 100644
--- a/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc
@@ -3649,6 +3649,8 @@ struct {
struct HPMHookPoint *HP_pc_gets_status_point_post;
struct HPMHookPoint *HP_pc_need_status_point_pre;
struct HPMHookPoint *HP_pc_need_status_point_post;
+ struct HPMHookPoint *HP_pc_maxparameterincrease_pre;
+ struct HPMHookPoint *HP_pc_maxparameterincrease_post;
struct HPMHookPoint *HP_pc_statusup_pre;
struct HPMHookPoint *HP_pc_statusup_post;
struct HPMHookPoint *HP_pc_statusup2_pre;
@@ -8668,6 +8670,8 @@ struct {
int HP_pc_gets_status_point_post;
int HP_pc_need_status_point_pre;
int HP_pc_need_status_point_post;
+ int HP_pc_maxparameterincrease_pre;
+ int HP_pc_maxparameterincrease_post;
int HP_pc_statusup_pre;
int HP_pc_statusup_post;
int HP_pc_statusup2_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc
index 0b7201cdc..f47a9cc5d 100644
--- a/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc
@@ -1855,6 +1855,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(pc->thisjobexp, HP_pc_thisjobexp) },
{ HP_POP(pc->gets_status_point, HP_pc_gets_status_point) },
{ HP_POP(pc->need_status_point, HP_pc_need_status_point) },
+ { HP_POP(pc->maxparameterincrease, HP_pc_maxparameterincrease) },
{ HP_POP(pc->statusup, HP_pc_statusup) },
{ HP_POP(pc->statusup2, HP_pc_statusup2) },
{ HP_POP(pc->skillup, HP_pc_skillup) },
diff --git a/src/plugins/HPMHooking/HPMHooking.Hooks.inc b/src/plugins/HPMHooking/HPMHooking.Hooks.inc
index 4db53868d..9584f4960 100644
--- a/src/plugins/HPMHooking/HPMHooking.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Hooks.inc
@@ -46994,14 +46994,40 @@ int HP_pc_need_status_point(struct map_session_data *sd, int type, int val) {
}
return retVal___;
}
-int HP_pc_statusup(struct map_session_data *sd, int type) {
+int HP_pc_maxparameterincrease(struct map_session_data *sd, int type) {
int hIndex = 0;
int retVal___ = 0;
- if( HPMHooks.count.HP_pc_statusup_pre ) {
+ if( HPMHooks.count.HP_pc_maxparameterincrease_pre ) {
int (*preHookFunc) (struct map_session_data *sd, int *type);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_maxparameterincrease_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_pc_maxparameterincrease_pre[hIndex].func;
+ retVal___ = preHookFunc(sd, &type);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.pc.maxparameterincrease(sd, type);
+ }
+ if( HPMHooks.count.HP_pc_maxparameterincrease_post ) {
+ int (*postHookFunc) (int retVal___, struct map_session_data *sd, int *type);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_maxparameterincrease_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_pc_maxparameterincrease_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, sd, &type);
+ }
+ }
+ return retVal___;
+}
+bool HP_pc_statusup(struct map_session_data *sd, int type, int increase) {
+ int hIndex = 0;
+ bool retVal___ = false;
+ if( HPMHooks.count.HP_pc_statusup_pre ) {
+ bool (*preHookFunc) (struct map_session_data *sd, int *type, int *increase);
for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_statusup_pre; hIndex++ ) {
preHookFunc = HPMHooks.list.HP_pc_statusup_pre[hIndex].func;
- retVal___ = preHookFunc(sd, &type);
+ retVal___ = preHookFunc(sd, &type, &increase);
}
if( *HPMforce_return ) {
*HPMforce_return = false;
@@ -47009,13 +47035,13 @@ int HP_pc_statusup(struct map_session_data *sd, int type) {
}
}
{
- retVal___ = HPMHooks.source.pc.statusup(sd, type);
+ retVal___ = HPMHooks.source.pc.statusup(sd, type, increase);
}
if( HPMHooks.count.HP_pc_statusup_post ) {
- int (*postHookFunc) (int retVal___, struct map_session_data *sd, int *type);
+ bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, int *type, int *increase);
for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_statusup_post; hIndex++ ) {
postHookFunc = HPMHooks.list.HP_pc_statusup_post[hIndex].func;
- retVal___ = postHookFunc(retVal___, sd, &type);
+ retVal___ = postHookFunc(retVal___, sd, &type, &increase);
}
}
return retVal___;