diff --git a/common/ruletypes.h b/common/ruletypes.h index 1d266a269..052571d82 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -437,6 +437,7 @@ RULE_BOOL ( NPC, SmartLastFightingDelayMoving, true) RULE_BOOL ( NPC, ReturnNonQuestNoDropItems, false) // Returns NO DROP items on NPCs that don't have an EVENT_TRADE sub in their script RULE_INT ( NPC, StartEnrageValue, 9) // % HP that an NPC will begin to enrage RULE_BOOL ( NPC, LiveLikeEnrage, false) // If set to true then only player controlled pets will enrage +RULE_BOOL ( NPC, EnableMeritBasedFaction, false) // If set to true, faction will given in the same way as experience (solo/group/raid) RULE_CATEGORY_END() RULE_CATEGORY ( Aggro ) diff --git a/zone/attack.cpp b/zone/attack.cpp index da812e724..51b8bb26a 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -2131,7 +2131,7 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack give_exp_client = give_exp->CastToClient(); bool IsLdonTreasure = (this->GetClass() == LDON_TREASURE); - if (give_exp_client && !IsCorpse() && MerchantType == 0) + if (give_exp_client && !IsCorpse()) { Group *kg = entity_list.GetGroupByClient(give_exp_client); Raid *kr = entity_list.GetRaidByClient(give_exp_client); @@ -2141,15 +2141,19 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack if(kr) { - if(!IsLdonTreasure) { + if(!IsLdonTreasure && MerchantType == 0) { kr->SplitExp((finalxp), this); if(killerMob && (kr->IsRaidMember(killerMob->GetName()) || kr->IsRaidMember(killerMob->GetUltimateOwner()->GetName()))) killerMob->TrySpellOnKill(killed_level,spell); } /* Send the EVENT_KILLED_MERIT event for all raid members */ for (int i = 0; i < MAX_RAID_MEMBERS; i++) { - if (kr->members[i].member != nullptr) { // If Group Member is Client - parse->EventNPC(EVENT_KILLED_MERIT, this, kr->members[i].member, "killed", 0); + if (kr->members[i].member != nullptr && kr->members[i].member->IsClient()) { // If Group Member is Client + Client *c = kr->members[i].member; + parse->EventNPC(EVENT_KILLED_MERIT, this, c, "killed", 0); + + if(RuleB(NPC, EnableMeritBasedFaction)) + c->SetFactionLevel(c->CharacterID(), GetNPCFactionID(), c->GetBaseClass(), c->GetBaseRace(), c->GetDeity()); mod_npc_killed_merit(kr->members[i].member); @@ -2168,7 +2172,7 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack QS->s1.ZoneID = this->GetZoneID(); QS->s1.Type = 2; // Raid Fight for (int i = 0; i < MAX_RAID_MEMBERS; i++) { - if (kr->members[i].member != nullptr) { // If Group Member is Client + if (kr->members[i].member != nullptr && kr->members[i].member->IsClient()) { // If Group Member is Client Client *c = kr->members[i].member; QS->Chars[PlayerCount].char_id = c->CharacterID(); PlayerCount++; @@ -2182,7 +2186,7 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack } else if (give_exp_client->IsGrouped() && kg != nullptr) { - if(!IsLdonTreasure) { + if(!IsLdonTreasure && MerchantType == 0) { kg->SplitExp((finalxp), this); if(killerMob && (kg->IsGroupMember(killerMob->GetName()) || kg->IsGroupMember(killerMob->GetUltimateOwner()->GetName()))) killerMob->TrySpellOnKill(killed_level,spell); @@ -2194,6 +2198,9 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack Client *c = kg->members[i]->CastToClient(); parse->EventNPC(EVENT_KILLED_MERIT, this, c, "killed", 0); + if(RuleB(NPC, EnableMeritBasedFaction)) + c->SetFactionLevel(c->CharacterID(), GetNPCFactionID(), c->GetBaseClass(), c->GetBaseRace(), c->GetDeity()); + mod_npc_killed_merit(c); if(RuleB(TaskSystem, EnableTaskSystem)) @@ -2225,14 +2232,13 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack } else { - if(!IsLdonTreasure) { + if(!IsLdonTreasure && MerchantType == 0) { int conlevel = give_exp->GetLevelCon(GetLevel()); if (conlevel != CON_GREEN) { - if(GetOwner() && GetOwner()->IsClient()){ - } - else { - give_exp_client->AddEXP((finalxp), conlevel); // Pyro: Comment this if NPC death crashes zone + if(!GetOwner() || (GetOwner() && !GetOwner()->IsClient())) + { + give_exp_client->AddEXP((finalxp), conlevel); if(killerMob && (killerMob->GetID() == give_exp_client->GetID() || killerMob->GetUltimateOwner()->GetID() == give_exp_client->GetID())) killerMob->TrySpellOnKill(killed_level,spell); } @@ -2241,6 +2247,10 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack /* Send the EVENT_KILLED_MERIT event */ parse->EventNPC(EVENT_KILLED_MERIT, this, give_exp_client, "killed", 0); + if(RuleB(NPC, EnableMeritBasedFaction)) + give_exp_client->SetFactionLevel(give_exp_client->CharacterID(), GetNPCFactionID(), give_exp_client->GetBaseClass(), + give_exp_client->GetBaseRace(), give_exp_client->GetDeity()); + mod_npc_killed_merit(give_exp_client); if(RuleB(TaskSystem, EnableTaskSystem)) @@ -2264,7 +2274,7 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack } //do faction hits even if we are a merchant, so long as a player killed us - if(give_exp_client) + if(give_exp_client && !RuleB(NPC, EnableMeritBasedFaction)) hate_list.DoFactionHits(GetNPCFactionID()); if (!HasOwner() && !IsMerc() && class_ != MERCHANT && class_ != ADVENTUREMERCHANT && !GetSwarmInfo()