Skip to content

Commit 60f3f74

Browse files
Merge pull request #3323 from skyleo/add-getunitparam-scriptcmd
Add *getunitparam to obtain values set via unit_parameters_db.conf in scripts
2 parents 58b217e + 1adb7c6 commit 60f3f74

File tree

3 files changed

+161
-0
lines changed

3 files changed

+161
-0
lines changed

doc/script_commands.txt

+31
Original file line numberDiff line numberDiff line change
@@ -3101,6 +3101,37 @@ Examples:
31013101

31023102
---------------------------------------
31033103

3104+
*getunitparam(<param type>{, <class>{, <maxlv array>, <value array>}})
3105+
3106+
Thi will return the requested parameter's value or fill the required arrays in
3107+
the case of UNIT_PARAM_MAX_HP.
3108+
3109+
<param type>:
3110+
- UNIT_PARAM_NAME ^= name of unit_parameters_db.conf entry used by class.
3111+
- UNIT_PARAM_NATHEAL_WEIGHT_RATE ^= NaturalHealWeightRate value
3112+
- UNIT_PARAM_MAX_ASPD ^= MaxASPD
3113+
- UNIT_PARAM_MAX_HP ^= MaxHP
3114+
- UNIT_PARAM_MAX_STATS ^= MaxStats
3115+
3116+
<class> can be -1 if attached players class is desired, such as in the case of UNIT_PARAM_MAX_HP,
3117+
where <class> is mandatory.
3118+
3119+
Examples:
3120+
3121+
// Outputs the possible maximum ASPD of attached player.
3122+
mesf("MAX_ASPD: %d", getunitparam(UNIT_PARAM_MAX_ASPD));
3123+
3124+
// Outputs the possible maximum stats of Job_Baby.
3125+
mesf("MAX_STATS: %d", getunitparam(UNIT_PARAM_MAX_STATS, Job_Baby));
3126+
3127+
// Saves the entries for MAXHP per level ranges of JOB_SUPER_NOVICE into the given arrays and prints them.
3128+
.@count = getunitparam(UNIT_PARAM_MAX_ASPD, JOB_SUPER_NOVICE, .@max_lv, .@max_hp);
3129+
for (.@i = 0; .@i < .@count; ++.@i) {
3130+
mesf("max_lv: %d, max_hp: %d", .@max_lv[.@i], .@max_hp[.@i]);
3131+
}
3132+
3133+
---------------------------------------
3134+
31043135
*sit({"<character name>"})
31053136
*stand({"<character name>"})
31063137

src/map/script.c

+122
Original file line numberDiff line numberDiff line change
@@ -28628,6 +28628,120 @@ static BUILDIN(mestipbox)
2862828628
return true;
2862928629
}
2863028630

28631+
28632+
/**
28633+
* Returns a units <parameter>'s values
28634+
*
28635+
* NOTE: UNIT_PARAM_MAX_HP needs two arrays.
28636+
*
28637+
* getunitparam(<param>{, <class id>{, <maxlv array>, <value array>}})
28638+
*/
28639+
static BUILDIN(getunitparam)
28640+
{
28641+
int class = -1;
28642+
if (script_hasdata(st, 3)) {
28643+
class = script_getnum(st, 3);
28644+
if (class != -1) {
28645+
if (!pc->db_checkid(class)) {
28646+
ShowError("buildin_getunitparam: invalid class (%d)\n", class);
28647+
st->state = END;
28648+
return false;
28649+
}
28650+
class = pc->class2idx(class);
28651+
}
28652+
}
28653+
28654+
struct map_session_data *sd = NULL;
28655+
if (class == -1) {
28656+
sd = script_rid2sd(st);
28657+
if (sd == NULL) {
28658+
ShowError("buildin_getunitparam: No player attached, but class == -1.\n");
28659+
return false;
28660+
}
28661+
class = pc->class2idx(sd->status.class);
28662+
}
28663+
28664+
struct s_unit_params *entry = status->dbs->unit_params[class];
28665+
int param = script_getnum(st, 2);
28666+
switch (param) {
28667+
case UNIT_PARAM_NAME:
28668+
script_pushconststr(st, entry->name);
28669+
break;
28670+
case UNIT_PARAM_NATHEAL_WEIGHT_RATE:
28671+
script_pushint(st, entry->natural_heal_weight_rate);
28672+
break;
28673+
case UNIT_PARAM_MAX_ASPD:
28674+
script_pushint(st, (2000 - entry->max_aspd) / 10); // max_aspd is actually min_amotion :)
28675+
break;
28676+
case UNIT_PARAM_MAX_HP: {
28677+
if (!script_hasdata(st, 4) || !script_hasdata(st, 5)) {
28678+
ShowError("buildin_getunitparam: UNIT_PARAM_MAXP_HP requires 4 parameters: <param>, <class id>, <maxlv array>, <value array>\n");
28679+
st->state = END;
28680+
return false;
28681+
}
28682+
28683+
struct script_data *maxhp_maxlvls = script_getdata(st, 4);
28684+
struct script_data *maxhp_values = script_getdata(st, 5);
28685+
if (!data_isreference(maxhp_maxlvls) || reference_toconstant(maxhp_maxlvls)) {
28686+
ShowError("buildin_getunitparam: <maxlv array> argument must be reference and not a reference to constant\n");
28687+
script->reportdata(maxhp_maxlvls);
28688+
st->state = END;
28689+
return false;
28690+
}
28691+
if (!data_isreference(maxhp_values) || reference_toconstant(maxhp_values)) {
28692+
ShowError("buildin_getunitparam: <value array> argument must be reference and not a reference to constant\n");
28693+
script->reportdata(maxhp_values);
28694+
st->state = END;
28695+
return false;
28696+
}
28697+
28698+
const char *maxhp_maxlvls_varname = reference_getname(maxhp_maxlvls);
28699+
const char *maxhp_values_varname = reference_getname(maxhp_values);
28700+
if (!is_int_variable(maxhp_maxlvls_varname)) {
28701+
ShowError("buildin_getunitparam: <maxlv array> argument must be of integer type\n");
28702+
script->reportdata(maxhp_maxlvls);
28703+
st->state = END;
28704+
return false;
28705+
}
28706+
if (!is_int_variable(maxhp_values_varname)) {
28707+
ShowError("buildin_getunitparam: <value array> argument must be of integer type\n");
28708+
script->reportdata(maxhp_values);
28709+
st->state = END;
28710+
return false;
28711+
}
28712+
28713+
if (not_server_variable(*maxhp_maxlvls_varname) || not_server_variable(*maxhp_values_varname)) {
28714+
if (sd == NULL) {
28715+
sd = script->rid2sd(st);
28716+
if (sd == NULL)
28717+
return false; // player variable but no player attached
28718+
}
28719+
}
28720+
28721+
int varid1 = reference_getid(maxhp_maxlvls);
28722+
int varid2 = reference_getid(maxhp_values);
28723+
int count = entry->maxhp_size;
28724+
for (int i = 0; i < count; i++) {
28725+
script->set_reg(st, sd, reference_uid(varid1, i), maxhp_maxlvls_varname, (const void *)h64BPTRSIZE(entry->maxhp[i].max_level),
28726+
reference_getref(maxhp_maxlvls));
28727+
script->set_reg(st, sd, reference_uid(varid2, i), maxhp_values_varname, (const void *)h64BPTRSIZE(entry->maxhp[i].value),
28728+
reference_getref(maxhp_values));
28729+
}
28730+
script_pushint(st, count);
28731+
break;
28732+
}
28733+
case UNIT_PARAM_MAX_STATS:
28734+
script_pushint(st, entry->max_stats);
28735+
break;
28736+
default:
28737+
ShowError("buildin_getunitparam: Received invalid param: %d\n", param);
28738+
st->state = END;
28739+
return false;
28740+
}
28741+
28742+
return true;
28743+
}
28744+
2863128745
/**
2863228746
* Adds a built-in script function.
2863328747
*
@@ -29507,6 +29621,7 @@ static void script_parse_builtin(void)
2950729621

2950829622
BUILDIN_DEF(mesurl, "ss??"),
2950929623
BUILDIN_DEF(mestipbox, "si"),
29624+
BUILDIN_DEF(getunitparam, "i???"),
2951029625
};
2951129626
int i, len = ARRAYLENGTH(BUILDIN);
2951229627
RECREATE(script->buildin, char *, script->buildin_count + len); // Pre-alloc to speed up
@@ -30490,6 +30605,13 @@ static void script_hardcoded_constants(void)
3049030605
script->set_constant("HOMINFO_RENAME", HOMINFO_RENAME, false, false);
3049130606
script->set_constant("HOMINFO_LEVEL", HOMINFO_LEVEL, false, false);
3049230607

30608+
script->constdb_comment("getunitparam param-types");
30609+
script->set_constant("UNIT_PARAM_NAME", UNIT_PARAM_NAME, false, false);
30610+
script->set_constant("UNIT_PARAM_NATHEAL_WEIGHT_RATE", UNIT_PARAM_NATHEAL_WEIGHT_RATE, false, false);
30611+
script->set_constant("UNIT_PARAM_MAX_ASPD", UNIT_PARAM_MAX_ASPD, false, false);
30612+
script->set_constant("UNIT_PARAM_MAX_HP", UNIT_PARAM_MAX_HP, false, false);
30613+
script->set_constant("UNIT_PARAM_MAX_STATS", UNIT_PARAM_MAX_STATS, false, false);
30614+
3049330615
script->constdb_comment("Renewal");
3049430616
#ifdef RENEWAL
3049530617
script->set_constant("RENEWAL", 1, false, false);

src/map/status.h

+8
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,14 @@ struct s_maxhp_entry {
13231323
int value; ///< The actual max hp value
13241324
};
13251325

1326+
enum e_unit_params {
1327+
UNIT_PARAM_NAME,
1328+
UNIT_PARAM_NATHEAL_WEIGHT_RATE,
1329+
UNIT_PARAM_MAX_ASPD,
1330+
UNIT_PARAM_MAX_HP,
1331+
UNIT_PARAM_MAX_STATS,
1332+
};
1333+
13261334
struct s_unit_params {
13271335
char name[SCRIPT_VARNAME_LENGTH]; ///< group name as defined in conf
13281336

0 commit comments

Comments
 (0)