Add skill_plagiarism script commands (#6304)
* Allow players to copy skills with script command skill_plagiarism. * Plagiarized skills can be cleared with script command skill_plagiarism_reset.
This commit is contained in:
108
src/map/pc.cpp
108
src/map/pc.cpp
@@ -51,6 +51,7 @@
|
||||
#include "pc_groups.hpp"
|
||||
#include "pet.hpp" // pet_unlocktarget()
|
||||
#include "quest.hpp"
|
||||
#include "skill.hpp" // skill_isCopyable()
|
||||
#include "script.hpp" // struct script_reg, struct script_regstr
|
||||
#include "searchstore.hpp" // struct s_search_store_info
|
||||
#include "status.hpp" // OPTION_*, struct weapon_atk
|
||||
@@ -5087,6 +5088,93 @@ bool pc_skill(struct map_session_data* sd, uint16 skill_id, int level, enum e_ad
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set's a player's plagiarized skill.
|
||||
* @param sd: Player
|
||||
* @param skill_id: Skill to be plagiarized
|
||||
* @param skill_lv: Skill level to be plagiarized
|
||||
* @return True on success or false otherwise
|
||||
*/
|
||||
bool pc_skill_plagiarism(map_session_data &sd, uint16 skill_id, uint16 skill_lv)
|
||||
{
|
||||
skill_id = skill_dummy2skill_id(skill_id);
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
|
||||
// Use skill index, avoiding out-of-bound array [Cydh]
|
||||
if (idx == 0) {
|
||||
ShowWarning("pc_skill_plagiarism: invalid skill idx 0 for skill %d.\n", skill_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
skill_lv = cap_value(skill_lv, 1, skill_get_max(skill_id));
|
||||
|
||||
int type = skill_isCopyable(&sd, skill_id);
|
||||
if (type == 1) {
|
||||
pc_skill_plagiarism_reset(sd, type);
|
||||
|
||||
sd.cloneskill_idx = idx;
|
||||
pc_setglobalreg(&sd, add_str(SKILL_VAR_PLAGIARISM), skill_id);
|
||||
pc_setglobalreg(&sd, add_str(SKILL_VAR_PLAGIARISM_LV), skill_lv);
|
||||
} else if (type == 2) {
|
||||
pc_skill_plagiarism_reset(sd, type);
|
||||
|
||||
sd.reproduceskill_idx = idx;
|
||||
pc_setglobalreg(&sd, add_str(SKILL_VAR_REPRODUCE), skill_id);
|
||||
pc_setglobalreg(&sd, add_str(SKILL_VAR_REPRODUCE_LV), skill_lv);
|
||||
} else {
|
||||
ShowWarning("pc_skill_plagiarism: skill %d is not copyable.\n", skill_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
sd.status.skill[idx].id = skill_id;
|
||||
sd.status.skill[idx].lv = skill_lv;
|
||||
sd.status.skill[idx].flag = SKILL_FLAG_PLAGIARIZED;
|
||||
clif_addskill(&sd, skill_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear plagiarized skills from a player.
|
||||
* @param sd: Player
|
||||
* @param type: 1 for Plagiarism or 2 for Reproduce
|
||||
* @return True on success or false otherwise
|
||||
*/
|
||||
bool pc_skill_plagiarism_reset(map_session_data &sd, uint8 type)
|
||||
{
|
||||
uint16 idx;
|
||||
if (type == 1)
|
||||
idx = sd.cloneskill_idx;
|
||||
else if (type == 2)
|
||||
idx = sd.reproduceskill_idx;
|
||||
else {
|
||||
ShowError("pc_skill_plagiarism_reset: Unknown type %d.\n", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sd.status.skill[idx].flag == SKILL_FLAG_PLAGIARIZED) {
|
||||
uint16 skill_id = sd.status.skill[idx].id;
|
||||
sd.status.skill[idx].id = 0;
|
||||
sd.status.skill[idx].lv = 0;
|
||||
sd.status.skill[idx].flag = SKILL_FLAG_PERMANENT;
|
||||
clif_deleteskill(&sd, skill_id);
|
||||
|
||||
if (type == 1) {
|
||||
sd.cloneskill_idx = 0;
|
||||
pc_setglobalreg(&sd, add_str(SKILL_VAR_PLAGIARISM), 0);
|
||||
pc_setglobalreg(&sd, add_str(SKILL_VAR_PLAGIARISM_LV), 0);
|
||||
}
|
||||
else if (type == 2) {
|
||||
sd.reproduceskill_idx = 0;
|
||||
pc_setglobalreg(&sd, add_str(SKILL_VAR_REPRODUCE), 0);
|
||||
pc_setglobalreg(&sd, add_str(SKILL_VAR_REPRODUCE_LV), 0);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Append a card to an item ?
|
||||
*------------------------------------------*/
|
||||
@@ -10302,27 +10390,11 @@ bool pc_jobchange(struct map_session_data *sd,int job, char upper)
|
||||
}
|
||||
|
||||
if(sd->cloneskill_idx > 0) {
|
||||
if( sd->status.skill[sd->cloneskill_idx].flag == SKILL_FLAG_PLAGIARIZED ) {
|
||||
sd->status.skill[sd->cloneskill_idx].id = 0;
|
||||
sd->status.skill[sd->cloneskill_idx].lv = 0;
|
||||
sd->status.skill[sd->cloneskill_idx].flag = SKILL_FLAG_PERMANENT;
|
||||
clif_deleteskill(sd, static_cast<int>(pc_readglobalreg(sd, add_str(SKILL_VAR_PLAGIARISM))));
|
||||
}
|
||||
sd->cloneskill_idx = 0;
|
||||
pc_setglobalreg(sd, add_str(SKILL_VAR_PLAGIARISM), 0);
|
||||
pc_setglobalreg(sd, add_str(SKILL_VAR_PLAGIARISM_LV), 0);
|
||||
pc_skill_plagiarism_reset(*sd, 1);
|
||||
}
|
||||
|
||||
if(sd->reproduceskill_idx > 0) {
|
||||
if( sd->status.skill[sd->reproduceskill_idx].flag == SKILL_FLAG_PLAGIARIZED ) {
|
||||
sd->status.skill[sd->reproduceskill_idx].id = 0;
|
||||
sd->status.skill[sd->reproduceskill_idx].lv = 0;
|
||||
sd->status.skill[sd->reproduceskill_idx].flag = SKILL_FLAG_PERMANENT;
|
||||
clif_deleteskill(sd, static_cast<int>(pc_readglobalreg(sd, add_str(SKILL_VAR_REPRODUCE))));
|
||||
}
|
||||
sd->reproduceskill_idx = 0;
|
||||
pc_setglobalreg(sd, add_str(SKILL_VAR_REPRODUCE), 0);
|
||||
pc_setglobalreg(sd, add_str(SKILL_VAR_REPRODUCE_LV), 0);
|
||||
pc_skill_plagiarism_reset(*sd, 2);
|
||||
}
|
||||
|
||||
if ( (b_class&MAPID_UPPERMASK) != (sd->class_&MAPID_UPPERMASK) ) { //Things to remove when changing class tree.
|
||||
|
||||
Reference in New Issue
Block a user