Skip to content

Commit

Permalink
Add *getunitparam to obtain values set via unit_parameters_db.conf in…
Browse files Browse the repository at this point in the history
… scripts
  • Loading branch information
skyleo committed Sep 21, 2024
1 parent 71fc107 commit 7b6437f
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 0 deletions.
31 changes: 31 additions & 0 deletions doc/script_commands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3101,6 +3101,37 @@ Examples:

---------------------------------------

*getunitparam(<param type>{, <class>{, <maxlv array>, <value array>}})

Thi will return the requested parameter's value or fill the required arrays in
the case of UNIT_PARAM_MAX_HP.

<param type>:
- 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

<class> can be -1 if attached players class is desired, such as in the case of UNIT_PARAM_MAX_HP,
where <class> 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({"<character name>"})
*stand({"<character name>"})

Expand Down
109 changes: 109 additions & 0 deletions src/map/script.c
Original file line number Diff line number Diff line change
Expand Up @@ -28628,6 +28628,107 @@ static BUILDIN(mestipbox)
return true;
}


/**
* Returns a units <parameter>'s values
*
* NOTE: UNIT_PARAM_MAX_HP needs two arrays.
*
* getunitparam(<param>{, <class id>{, <maxlv array>, <value array>}})
*/
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: <param>, <class id>, <maxlv array>, <value array>\n");
st->state = END;
return false;
}
struct script_data *maxhp_maxlvls = script_getdata(st, 4);
struct script_data *maxhp_values = script_getdata(st, 5);
const char *maxhp_maxlvls_varname = reference_getname(maxhp_maxlvls);
const char *maxhp_values_varname = reference_getname(maxhp_values);

if (!data_isreference(maxhp_maxlvls) || reference_toconstant(maxhp_maxlvls) || !is_int_variable(maxhp_maxlvls_varname)) {
ShowError("buildin_getunitparam: <maxlv array> argument must be of integer type\n");
script->reportdata(maxhp_maxlvls);
st->state = END;
return false;
}
if (!data_isreference(maxhp_values) || reference_toconstant(maxhp_values) || !is_int_variable(maxhp_values_varname)) {
ShowError("buildin_getunitparam: <value array> 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.
*
Expand Down Expand Up @@ -29507,6 +29608,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
Expand Down Expand Up @@ -30490,6 +30592,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);
Expand Down
8 changes: 8 additions & 0 deletions src/map/status.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit 7b6437f

Please sign in to comment.