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; 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")) { if (this->nodeExists(it, "Chat")) {
uint16 msg_id; uint16 msg_id;

View File

@ -246,7 +246,7 @@ struct s_mob_skill {
int32 cond2, cond3; int32 cond2, cond3;
int mob_mode; int mob_mode;
std::unordered_map<uint16, int> summons; // index, mob ID std::unordered_map<uint16, int> summons; // index, mob ID
short emotion; short emotion, emotion2;
unsigned short msg_id; 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 // NPC_EMOTION_ON adds the mode to the current mode
if(md && md->skill_idx >= 0 && tsc) 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. 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) if (md->db->skill[md->skill_idx]->mob_mode > -1)
@ -9563,6 +9566,32 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break; break;
case NPC_EMOTION: case NPC_EMOTION:
// 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; break;
case NPC_POWERUP: case NPC_POWERUP:
@ -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) { if (skill_id != SR_CURSEDCIRCLE && skill_id != NPC_SR_CURSEDCIRCLE) {
struct status_change *sc = status_get_sc(src); 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; 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. 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); 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:
case NPC_EMOTION_ON: 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_")); char *constant = const_cast<char *>(constant_lookup(val, "ET_"));
if (constant != nullptr) if (constant != nullptr)
entry.emotion = constant; entry.emotion2 = constant;
else { else {
std::string emotion(str[val]); std::string emotion(str[val]);
entry.emotion = emotion; entry.emotion2 = emotion;
} }
continue; continue;
} }
@ -5184,6 +5184,8 @@ static bool mob_parse_row_mobskilldb_yaml(void) {
if (!mob_skill.emotion.empty()) if (!mob_skill.emotion.empty())
body << YAML::Key << "Emotion" << YAML::Value << mob_skill.emotion; 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) if (mob_skill.msg_id > 0)
body << YAML::Key << "Chat" << YAML::Value << mob_skill.msg_id; body << YAML::Key << "Chat" << YAML::Value << mob_skill.msg_id;
body << YAML::EndMap; 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; std::unordered_map<uint16, std::vector<s_mercenary_skill_csv>> mercenary_skill_tree;
struct s_mob_skill_csv { 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; uint16 skill_lv, permillage, msg_id;
int32 casttime, delay; int32 casttime, delay;
std::string mob_ai; std::string mob_ai;