[PVP] Pvp guard assist code. (Guards will assist in PvP based on faction) (#1367)

* Added Guard Assist Code

* Added PvP Rule and Detrimental Spell Check

* Added IsGuard() Method

* Change from uint to bool

* Added a faction check to IsGuard()

* Simplified Guard Checks, reduced costs

* Added IsNPC check to guard check

* simplified pet check

* Removed Magic numbers

* Formatting Fix

* Code fixes

* Fixed constants

Co-authored-by: ProducerZekServer <go@away.com>
This commit is contained in:
RoTPvP 2021-05-30 18:22:52 -07:00 committed by GitHub
parent 542ec38660
commit 71e9dd5a3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 97 additions and 1 deletions

View File

@ -438,6 +438,13 @@ static const uint8 SkillDamageTypes[EQ::skills::HIGHEST_SKILL + 1] = // change t
static const uint32 MAX_SPELL_DB_ID_VAL = 65535;
static const uint32 DB_SPELL_CAZIC_TOUCH = 982;
static const uint32 DB_SPELL_TOUCH_OF_VINITRAS = 2859;
static const uint32 DB_FACTION_GEM_CHOPPERS = 255;
static const uint32 DB_FACTION_HERETICS = 265;
static const uint32 DB_FACTION_KING_AKANON = 333;
enum ChatChannelNames : uint16
{
ChatChannel_Guild = 0,

View File

@ -860,7 +860,6 @@ uint16 GetRaceIDFromPlayerRaceBit(uint32 player_race_bit);
float GetRaceGenderDefaultHeight(int race, int gender);
// player race-/gender-based model feature validators
namespace PlayerAppearance
{

View File

@ -163,6 +163,7 @@ RULE_BOOL(Character, SoftDeletes, true, "When characters are deleted in characte
RULE_INT(Character, DefaultGuild, 0, "If not 0, new characters placed into the guild # indicated")
RULE_BOOL(Character, ProcessFearedProximity, false, "Processes proximity checks when feared")
RULE_BOOL(Character, EnableCharacterEXPMods, false, "Enables character zone-based experience modifiers.")
RULE_BOOL(Character, PVPEnableGuardFactionAssist, true, "Enables faction based assisting against the aggresor in pvp.")
RULE_CATEGORY_END()
RULE_CATEGORY(Mercs)

View File

@ -1522,6 +1522,25 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
other->AddToHateList(this, hate);
//Guard Assist Code
if (RuleB(Character, PVPEnableGuardFactionAssist)) {
if (IsClient() || (HasOwner() && GetOwner()->IsClient())) {
auto& mob_list = entity_list.GetCloseMobList(other);
for (auto& e : mob_list) {
auto mob = e.second;
if (mob->IsNPC() && mob->CastToNPC()->IsGuard()) {
float distance = Distance(other->CastToClient()->m_Position, mob->GetPosition());
if ((mob->CheckLosFN(other) || mob->CheckLosFN(this)) && distance <= 70) {
auto petorowner = GetOwnerOrSelf();
if (other->GetReverseFactionCon(mob) <= petorowner->GetReverseFactionCon(mob)) {
mob->AddToHateList(this);
}
}
}
}
}
}
///////////////////////////////////////////////////////////
////// Send Attack Damage
///////////////////////////////////////////////////////////
@ -2002,6 +2021,24 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
}
}
//Guard Assist Code
if (RuleB(Character, PVPEnableGuardFactionAssist)) {
if (IsClient() || (HasOwner() && GetOwner()->IsClient())) {
auto& mob_list = entity_list.GetCloseMobList(other);
for (auto& e : mob_list) {
auto mob = e.second;
if (mob->IsNPC() && mob->CastToNPC()->IsGuard()) {
float distance = Distance(other->GetPosition(), mob->GetPosition());
if ((mob->CheckLosFN(other) || mob->CheckLosFN(this)) && distance <= 70) {
if (other->GetReverseFactionCon(mob) <= GetOwner()->GetReverseFactionCon(mob)) {
mob->AddToHateList(this);
}
}
}
}
}
}
int weapon_damage = GetWeaponDamage(other, weapon);
//do attack animation regardless of whether or not we can hit below

View File

@ -3368,3 +3368,35 @@ void NPC::ScaleNPC(uint8 npc_level) {
npc_scale_manager->ResetNPCScaling(this);
npc_scale_manager->ScaleNPC(this);
}
bool NPC::IsGuard()
{
switch (GetRace()) {
case RT_GUARD:
if (GetTexture() == 1 || GetTexture() == 2)
return true;
break;
case RT_IKSAR_2:
if (GetTexture() == 1)
return true;
break;
case RT_GUARD_2:
case RT_GUARD_3:
case RT_GUARD_4:
case RT_HUMAN_3:
case RT_HALFLING_2:
case RT_ERUDITE_2:
case RT_BARBARIAN_2:
case RT_DARK_ELF_2:
case RT_TROLL_2:
case OGGOK_CITIZEN:
case RT_DWARF_2:
return true;
default:
break;
}
if (GetPrimaryFaction() == DB_FACTION_GEM_CHOPPERS || GetPrimaryFaction() == DB_FACTION_HERETICS || GetPrimaryFaction() == DB_FACTION_KING_AKANON) { //these 3 factions of guards use player races instead of their own races so we must define them by faction.
return true;
}
return false;
}

View File

@ -175,6 +175,7 @@ public:
bool DatabaseCastAccepted(int spell_id);
bool IsFactionListAlly(uint32 other_faction);
bool IsGuard();
FACTION_VALUE CheckNPCFactionAlly(int32 other_faction);
virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther);

View File

@ -2044,6 +2044,25 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui
if(!IsValidSpell(spell_id))
return false;
//Guard Assist Code
if (RuleB(Character, PVPEnableGuardFactionAssist) && IsDetrimentalSpell(spell_id) && spell_target != this) {
if (IsClient() || (HasOwner() && GetOwner()->IsClient())) {
auto& mob_list = entity_list.GetCloseMobList(spell_target);
for (auto& e : mob_list) {
auto mob = e.second;
if (mob->IsNPC() && mob->CastToNPC()->IsGuard()) {
float distance = Distance(spell_target->GetPosition(), mob->GetPosition());
if ((mob->CheckLosFN(spell_target) || mob->CheckLosFN(this)) && distance <= 70) {
auto petorowner = GetOwnerOrSelf();
if (spell_target->GetReverseFactionCon(mob) <= petorowner->GetReverseFactionCon(mob)) {
mob->AddToHateList(this);
}
}
}
}
}
}
if( spells[spell_id].zonetype == 1 && !zone->CanCastOutdoor()){
if(IsClient()){
if(!CastToClient()->GetGM()){