Implements petautobonus script commands (#7053)

* Fixes #7038.
* Implements script commands: petautobonus, petautobonus2, and petautobonus3.
* This allows pets to utilize the same autobonus features that players can use without having to check for the equipped item position.
Thanks to @EditorFc's suggestion and @Lemongrass3110!
This commit is contained in:
Aleos
2022-09-16 12:46:53 -04:00
committed by GitHub
parent ee5ba2d889
commit f8cd4aa8c7
9 changed files with 386 additions and 48 deletions

View File

@@ -4613,6 +4613,27 @@ void script_add_autobonus(const char *autobonus)
}
}
void script_run_petautobonus(const std::string &autobonus, map_session_data &sd) {
std::shared_ptr<s_pet_autobonus_wrapper> script = util::umap_find(pet_autobonuses, autobonus);
if (script != nullptr) {
run_script(script->script, 0, sd.bl.id, 0);
}
}
void script_add_petautobonus(const std::string &autobonus) {
if (util::umap_find(pet_autobonuses, autobonus) == nullptr) {
script_code *script = parse_script(autobonus.c_str(), "petautobonus", 0, 0);
if (script != nullptr) {
std::shared_ptr<s_pet_autobonus_wrapper> bonus = std::make_shared<s_pet_autobonus_wrapper>();
bonus->script = script;
pet_autobonuses.emplace(autobonus, bonus);
}
}
}
/// resets a temporary character array variable to given value
void script_cleararray_pc( struct map_session_data* sd, const char* varname ){
@@ -10065,6 +10086,96 @@ BUILDIN_FUNC(autobonus3)
return SCRIPT_CMD_SUCCESS;
}
BUILDIN_FUNC(petautobonus) {
map_session_data *sd;
if (!script_rid2sd(sd))
return SCRIPT_CMD_FAILURE; // No player attached
const char *command = script_getfuncname(st);
if (sd->pd == nullptr) {
ShowError("buildin_%s: Requires an active pet.\n", command);
return SCRIPT_CMD_FAILURE; // No pet attached to player
}
std::string bonus_script = script_getstr(st, 2);
int16 rate = script_getnum(st, 3);
uint32 dur = script_getnum(st, 4);
if (!rate || !dur || bonus_script.empty())
return SCRIPT_CMD_FAILURE;
uint16 atk_type = 0;
std::string other_script = {};
bool bonus2 = false;
if (strcmpi(command, "petautobonus2") == 0)
bonus2 = true;
if (script_hasdata(st, 5))
atk_type = script_getnum(st, 5);
if (script_hasdata(st, 6))
other_script = script_getstr(st, 6);
if (pet_addautobonus(bonus2 ? sd->pd->autobonus2 : sd->pd->autobonus, bonus_script, rate, dur, atk_type, other_script, false)) {
script_add_petautobonus(bonus_script);
if (!other_script.empty())
script_add_petautobonus(other_script);
}
return SCRIPT_CMD_SUCCESS;
}
BUILDIN_FUNC(petautobonus3) {
map_session_data *sd;
if (!script_rid2sd(sd))
return SCRIPT_CMD_SUCCESS; // No player attached
if (sd->pd == nullptr) {
ShowError("buildin_petautobonus3: Requires an active pet.\n");
return SCRIPT_CMD_FAILURE; // No pet attached to player
}
std::string bonus_script = script_getstr(st, 2);
int16 rate = script_getnum(st, 3);
uint32 dur = script_getnum(st, 4);
if (!rate || !dur || bonus_script.empty())
return SCRIPT_CMD_SUCCESS;
uint16 skill_id = 0;
std::string other_script = {};
if (script_isstring(st, 5)) {
const char *name = script_getstr(st, 5);
if (!(skill_id = skill_name2id(name))) {
ShowError("buildin_petautobonus3: Invalid skill name %s passed to item bonus. Skipping.\n", name);
return SCRIPT_CMD_FAILURE;
}
} else {
skill_id = script_getnum(st, 5);
if (!skill_get_index(skill_id)) {
ShowError("buildin_petautobonus3: Invalid skill ID %d passed to item bonus. Skipping.\n", skill_id);
return SCRIPT_CMD_FAILURE;
}
}
if (script_hasdata(st, 6))
other_script = script_getstr(st, 6);
if (pet_addautobonus(sd->pd->autobonus3, bonus_script, rate, dur, skill_id, other_script, true)) {
script_add_petautobonus(bonus_script);
if (!other_script.empty())
script_add_petautobonus(other_script);
}
return SCRIPT_CMD_SUCCESS;
}
/// Changes the level of a player skill.
/// <flag> defaults to 1
/// <flag>=0 : set the level of the skill
@@ -26578,6 +26689,9 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(autobonus,"sii??"),
BUILDIN_DEF(autobonus2,"sii??"),
BUILDIN_DEF(autobonus3,"siiv?"),
BUILDIN_DEF(petautobonus,"sii??"),
BUILDIN_DEF2(petautobonus,"petautobonus2","sii??"),
BUILDIN_DEF(petautobonus3,"siiv?"),
BUILDIN_DEF(skill,"vi?"),
BUILDIN_DEF2(skill,"addtoskill","vi?"), // [Valaris]
BUILDIN_DEF(guildskill,"vi"),