NPC_EMOTION and NPC_EMOTION_ON

* Moved the emotion in NPC_EMOTION and NPC_EMOTION_ON skills in a separated field
** "...always,0,9,0x308D,,,,," : the emotion "9" is now saved in emotion2, this emotion coming from another table != the "global" emotion
* the corrections on NPC_EMOTION and NPC_EMOTION_ON are reverted, the corrections will be made in next PR after merge of mob skill DB
This commit is contained in:
Atemo 2022-08-07 17:19:41 +02:00
parent cd962a2fda
commit 394e3fd6a5
6 changed files with 806 additions and 853 deletions

File diff suppressed because it is too large Load Diff

View File

@ -6164,6 +6164,24 @@ uint64 MobSkillDatabase::parseBodyNode(const ryml::NodeRef& node) {
skill->emotion = ET_NONE;
}
if (this->nodeExists(it, "Emotion2")) {
std::string emotion_name;
if (!this->asString(it, "Emotion2", emotion_name))
return 0;
int64 constant;
if (!script_get_constant(emotion_name.c_str(), &constant) || constant <= ET_NONE || constant >= ET_MAX) {
this->invalidWarning(it["Emotion2"], "Invalid Emotion %s.\n", emotion_name.c_str());
return 0;
}
skill->emotion2 = static_cast<int16>(constant);
} else {
if (!skill_exists)
skill->emotion2 = ET_NONE;
}
if (this->nodeExists(it, "Chat")) {
uint16 msg_id;

View File

@ -246,7 +246,7 @@ struct s_mob_skill {
int32 cond2, cond3;
int mob_mode;
std::unordered_map<uint16, int> summons; // index, mob ID
short emotion;
short emotion, emotion2;
unsigned short msg_id;
};

View File

@ -9547,6 +9547,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
// NPC_EMOTION_ON adds the mode to the current mode
if(md && md->skill_idx >= 0 && tsc)
{
if (md->db->skill[md->skill_idx]->emotion2 > ET_NONE)
clif_emotion(bl, md->db->skill[md->skill_idx]->emotion2);
int mode_passive = (md->db->skill[md->skill_idx]->mob_mode & MD_AGGRESSIVE) ? 0 : MD_AGGRESSIVE; // Remove aggressive mode when the new mob type is passive.
if (md->db->skill[md->skill_idx]->mob_mode > -1)
@ -9563,8 +9566,34 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case NPC_EMOTION:
break;
// Change a mob's mode 'permanently'
if (md && md->skill_idx >= 0 && tsc) {
std::shared_ptr<s_mob_skill> skilltmp = md->db->skill[md->skill_idx];
if (skilltmp->emotion2 > ET_NONE)
clif_emotion(bl, skilltmp->emotion2);
if (skilltmp->mob_mode > -1 && tsc->data[SC_MODECHANGE]) // asks to delete the previous mode change regardless of the current monster mode since we 'sets' the mode
status_change_end(src, SC_MODECHANGE, INVALID_TIMER);
//If mode gets set by NPC_EMOTION then the target should be reset [Playtester]
if (!battle_config.npc_emotion_behavior && skilltmp->mob_mode > -1 && skilltmp->mob_mode != md->db->status.mode)
mob_unlocktarget(md,tick);
if (skilltmp->mob_mode > -1 && skilltmp->mob_mode != md->db->status.mode) {
sc_start4(src,src, SC_MODECHANGE, 100, skill_lv,
skilltmp->mob_mode, // 'sets' the mode
0, // adds to the current mode
0, // removes from the current mode
skill_get_time(skill_id, skill_lv));
}
//Reset aggressive state depending on resulting mode
if (!battle_config.npc_emotion_behavior)
md->state.aggressive = status_has_mode(&md->status,MD_ANGRY)?1:0;
}
break;
case NPC_POWERUP:
sc_start(src,bl,SC_INCATKRATE,100,200,skill_get_time(skill_id, skill_lv));
clif_skill_nodamage(src,bl,skill_id,skill_lv,
@ -12439,34 +12468,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
}
// Change a mob's mode 'permanently'
if (md && md->skill_idx >= 0 && skill_id != NPC_EMOTION_ON) {
status_change *sc = status_get_sc(src);
if (sc) {
std::shared_ptr<s_mob_skill> skilltmp = md->db->skill[md->skill_idx];
if (skilltmp->mob_mode > -1 && sc->data[SC_MODECHANGE]) // asks to delete the previous mode change regardless of the current monster mode since we 'sets' the mode
status_change_end(src, SC_MODECHANGE, INVALID_TIMER);
//If mode gets set by NPC_EMOTION then the target should be reset [Playtester]
if (!battle_config.npc_emotion_behavior && skilltmp->mob_mode > -1 && skilltmp->mob_mode != md->db->status.mode)
mob_unlocktarget(md,tick);
if (skilltmp->mob_mode > -1 && skilltmp->mob_mode != md->db->status.mode) {
sc_start4(src,src, SC_MODECHANGE, 100, skill_lv,
skilltmp->mob_mode, // 'sets' the mode
0, // adds to the current mode
0, // removes from the current mode
skill_get_time(skill_id, skill_lv));
}
//Reset aggressive state depending on resulting mode
if (!battle_config.npc_emotion_behavior)
md->state.aggressive = status_has_mode(&md->status,MD_ANGRY)?1:0;
}
}
if (skill_id != SR_CURSEDCIRCLE && skill_id != NPC_SR_CURSEDCIRCLE) {
struct status_change *sc = status_get_sc(src);
@ -14059,32 +14060,6 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
return 1;
}
mob_data *md = BL_CAST(BL_MOB, src);
// Change a mob's mode 'permanently'
if (md && md->skill_idx >= 0 && sc) {
std::shared_ptr<s_mob_skill> skilltmp = md->db->skill[md->skill_idx];
//if (skilltmp->mob_mode > -1 && skilltmp->mob_mode == md->db->status.mode) // asks to delete the previous mode change
if (skilltmp->mob_mode > -1 && sc->data[SC_MODECHANGE]) // asks to delete the previous mode change regardless of the current monster mode since we 'sets' the mode
status_change_end(src, SC_MODECHANGE, INVALID_TIMER);
if (!battle_config.npc_emotion_behavior && skilltmp->mob_mode > -1 && skilltmp->mob_mode != md->db->status.mode)
mob_unlocktarget(md,tick);
if (skilltmp->mob_mode > -1 && skilltmp->mob_mode != md->db->status.mode) {
sc_start4(src,src, SC_MODECHANGE, 100, skill_lv,
skilltmp->mob_mode, // 'sets' the mode
0, // adds to the current mode
0, // removes from the current mode
skill_get_time(skill_id, skill_lv));
}
//Reset aggressive state depending on resulting mode
if (!battle_config.npc_emotion_behavior)
md->state.aggressive = status_has_mode(&md->status,MD_ANGRY)?1:0;
}
if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] ) //Should only remove after the skill has been casted.
status_change_end(src,SC_CURSEDCIRCLE_ATKER,INVALID_TIMER);

View File

@ -5090,14 +5090,14 @@ static bool mob_parse_row_mobskilldb(char** str, int columns, int current) {
}
case NPC_EMOTION:
case NPC_EMOTION_ON:
if (i == 0) { // Emoticon is now stored in entry.emotion instead of val 1
if (i == 0) { // Emoticon is now stored in entry.emotion2 instead of val 1
char *constant = const_cast<char *>(constant_lookup(val, "ET_"));
if (constant != nullptr)
entry.emotion = constant;
entry.emotion2 = constant;
else {
std::string emotion(str[val]);
entry.emotion = emotion;
entry.emotion2 = emotion;
}
continue;
}
@ -5184,6 +5184,8 @@ static bool mob_parse_row_mobskilldb_yaml(void) {
if (!mob_skill.emotion.empty())
body << YAML::Key << "Emotion" << YAML::Value << mob_skill.emotion;
if (!mob_skill.emotion2.empty())
body << YAML::Key << "Emotion2" << YAML::Value << mob_skill.emotion2;
if (mob_skill.msg_id > 0)
body << YAML::Key << "Chat" << YAML::Value << mob_skill.msg_id;
body << YAML::EndMap;

View File

@ -149,7 +149,7 @@ struct s_mercenary_skill_csv {
std::unordered_map<uint16, std::vector<s_mercenary_skill_csv>> mercenary_skill_tree;
struct s_mob_skill_csv {
std::string skill_name, state_name, cond1_name, cond2_name, target_name, emotion;
std::string skill_name, state_name, cond1_name, cond2_name, target_name, emotion, emotion2; // emotion2: another field for emotion used by NPC_EMOTION
uint16 skill_lv, permillage, msg_id;
int32 casttime, delay;
std::string mob_ai;