diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index 1c4bb8aa3ab..939ea863f4f 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -3101,6 +3101,37 @@ Examples:
---------------------------------------
+*getunitparam({, {, , }})
+
+Thi will return the requested parameter's value or fill the required arrays in
+the case of UNIT_PARAM_MAX_HP.
+
+:
+- UNIT_PARAM_NAME ^= name of unit_parameters_db.conf entry used by class.
+- UNIT_PARAM_NATHEAL_WEIGHT_RATE ^= NaturalHealWeightRate value
+- UNIT_PARAM_MAX_ASPD ^= MaxASPD
+- UNIT_PARAM_MAX_HP ^= MaxHP
+- UNIT_PARAM_MAX_STATS ^= MaxStats
+
+ can be -1 if attached players class is desired, such as in the case of UNIT_PARAM_MAX_HP,
+where is mandatory.
+
+Examples:
+
+// Outputs the possible maximum ASPD of attached player.
+ mesf("MAX_ASPD: %d", getunitparam(UNIT_PARAM_MAX_ASPD));
+
+// Outputs the possible maximum stats of Job_Baby.
+ mesf("MAX_STATS: %d", getunitparam(UNIT_PARAM_MAX_STATS, Job_Baby));
+
+// Saves the entries for MAXHP per level ranges of JOB_SUPER_NOVICE into the given arrays and prints them.
+ .@count = getunitparam(UNIT_PARAM_MAX_ASPD, JOB_SUPER_NOVICE, .@max_lv, .@max_hp);
+ for (.@i = 0; .@i < .@count; ++.@i) {
+ mesf("max_lv: %d, max_hp: %d", .@max_lv[.@i], .@max_hp[.@i]);
+ }
+
+---------------------------------------
+
*sit({""})
*stand({""})
diff --git a/src/map/script.c b/src/map/script.c
index 8ecddd7fc43..6f9541f0986 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -28628,6 +28628,120 @@ static BUILDIN(mestipbox)
return true;
}
+
+/**
+ * Returns a units 's values
+ *
+ * NOTE: UNIT_PARAM_MAX_HP needs two arrays.
+ *
+ * getunitparam({, {, , }})
+ */
+static BUILDIN(getunitparam)
+{
+ int class = -1;
+ if (script_hasdata(st, 3)) {
+ class = script_getnum(st, 3);
+ if (class != -1) {
+ if (!pc->db_checkid(class)) {
+ ShowError("buildin_getunitparam: invalid class (%d)\n", class);
+ st->state = END;
+ return false;
+ }
+ class = pc->class2idx(class);
+ }
+ }
+
+ struct map_session_data *sd = NULL;
+ if (class == -1) {
+ sd = script_rid2sd(st);
+ if (sd == NULL) {
+ ShowError("buildin_getunitparam: No player attached, but class == -1.\n");
+ return false;
+ }
+ class = pc->class2idx(sd->status.class);
+ }
+
+ struct s_unit_params *entry = status->dbs->unit_params[class];
+ int param = script_getnum(st, 2);
+ switch (param) {
+ case UNIT_PARAM_NAME:
+ script_pushconststr(st, entry->name);
+ break;
+ case UNIT_PARAM_NATHEAL_WEIGHT_RATE:
+ script_pushint(st, entry->natural_heal_weight_rate);
+ break;
+ case UNIT_PARAM_MAX_ASPD:
+ script_pushint(st, (2000 - entry->max_aspd) / 10); // max_aspd is actually min_amotion :)
+ break;
+ case UNIT_PARAM_MAX_HP: {
+ if (!script_hasdata(st, 4) || !script_hasdata(st, 5)) {
+ ShowError("buildin_getunitparam: UNIT_PARAM_MAXP_HP requires 4 parameters: , , , \n");
+ st->state = END;
+ return false;
+ }
+
+ struct script_data *maxhp_maxlvls = script_getdata(st, 4);
+ struct script_data *maxhp_values = script_getdata(st, 5);
+ if (!data_isreference(maxhp_maxlvls) || reference_toconstant(maxhp_maxlvls)) {
+ ShowError("buildin_getunitparam: argument must be reference and not a reference to constant\n");
+ script->reportdata(maxhp_maxlvls);
+ st->state = END;
+ return false;
+ }
+ if (!data_isreference(maxhp_values) || reference_toconstant(maxhp_values)) {
+ ShowError("buildin_getunitparam: argument must be reference and not a reference to constant\n");
+ script->reportdata(maxhp_values);
+ st->state = END;
+ return false;
+ }
+
+ const char *maxhp_maxlvls_varname = reference_getname(maxhp_maxlvls);
+ const char *maxhp_values_varname = reference_getname(maxhp_values);
+ if (!is_int_variable(maxhp_maxlvls_varname)) {
+ ShowError("buildin_getunitparam: argument must be of integer type\n");
+ script->reportdata(maxhp_maxlvls);
+ st->state = END;
+ return false;
+ }
+ if (!is_int_variable(maxhp_values_varname)) {
+ ShowError("buildin_getunitparam: argument must be of integer type\n");
+ script->reportdata(maxhp_values);
+ st->state = END;
+ return false;
+ }
+
+ if (not_server_variable(*maxhp_maxlvls_varname) || not_server_variable(*maxhp_values_varname)) {
+ if (sd == NULL) {
+ sd = script->rid2sd(st);
+ if (sd == NULL)
+ return false; // player variable but no player attached
+ }
+ }
+
+ int varid1 = reference_getid(maxhp_maxlvls);
+ int varid2 = reference_getid(maxhp_values);
+ int count = entry->maxhp_size;
+ for (int i = 0; i < count; i++) {
+ script->set_reg(st, sd, reference_uid(varid1, i), maxhp_maxlvls_varname, (const void *)h64BPTRSIZE(entry->maxhp[i].max_level),
+ reference_getref(maxhp_maxlvls));
+ script->set_reg(st, sd, reference_uid(varid2, i), maxhp_values_varname, (const void *)h64BPTRSIZE(entry->maxhp[i].value),
+ reference_getref(maxhp_values));
+ }
+ script_pushint(st, count);
+ break;
+ }
+ case UNIT_PARAM_MAX_STATS:
+ script_pushint(st, entry->max_stats);
+ break;
+ default:
+ ShowError("buildin_getunitparam: Received invalid param: %d\n", param);
+ st->state = END;
+ return false;
+ }
+
+ return true;
+}
+
/**
* Adds a built-in script function.
*
@@ -29507,6 +29621,7 @@ static void script_parse_builtin(void)
BUILDIN_DEF(mesurl, "ss??"),
BUILDIN_DEF(mestipbox, "si"),
+ BUILDIN_DEF(getunitparam, "i???"),
};
int i, len = ARRAYLENGTH(BUILDIN);
RECREATE(script->buildin, char *, script->buildin_count + len); // Pre-alloc to speed up
@@ -30490,6 +30605,13 @@ static void script_hardcoded_constants(void)
script->set_constant("HOMINFO_RENAME", HOMINFO_RENAME, false, false);
script->set_constant("HOMINFO_LEVEL", HOMINFO_LEVEL, false, false);
+ script->constdb_comment("getunitparam param-types");
+ script->set_constant("UNIT_PARAM_NAME", UNIT_PARAM_NAME, false, false);
+ script->set_constant("UNIT_PARAM_NATHEAL_WEIGHT_RATE", UNIT_PARAM_NATHEAL_WEIGHT_RATE, false, false);
+ script->set_constant("UNIT_PARAM_MAX_ASPD", UNIT_PARAM_MAX_ASPD, false, false);
+ script->set_constant("UNIT_PARAM_MAX_HP", UNIT_PARAM_MAX_HP, false, false);
+ script->set_constant("UNIT_PARAM_MAX_STATS", UNIT_PARAM_MAX_STATS, false, false);
+
script->constdb_comment("Renewal");
#ifdef RENEWAL
script->set_constant("RENEWAL", 1, false, false);
diff --git a/src/map/status.h b/src/map/status.h
index a426a71d765..6f6712f060a 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -1323,6 +1323,14 @@ struct s_maxhp_entry {
int value; ///< The actual max hp value
};
+enum e_unit_params {
+ UNIT_PARAM_NAME,
+ UNIT_PARAM_NATHEAL_WEIGHT_RATE,
+ UNIT_PARAM_MAX_ASPD,
+ UNIT_PARAM_MAX_HP,
+ UNIT_PARAM_MAX_STATS,
+};
+
struct s_unit_params {
char name[SCRIPT_VARNAME_LENGTH]; ///< group name as defined in conf