Add 4 new special attacks to Perl/Lua.

- IMMUNE_DAMAGE_CLIENT (47)
Immune to all damage except NPC damage.

- IMMUNE_DAMAGE_NPC (48)
Immune to all damage except Client damage.

- IMMUNE_AGGRO_CLIENT (49)
Immune to aggro by a Client.

- IMMUNE_AGGRO_NPC (50)
Immune to aggro by an NPC, clients must attack directly to gain aggro, allows pet only boss mechanics and stuff.
This commit is contained in:
Kinglykrab 2021-01-23 20:36:30 -05:00
parent c481d52064
commit d30593c35e
7 changed files with 76 additions and 15 deletions

View File

@ -468,6 +468,12 @@ bool Mob::IsAttackAllowed(Mob *target, bool isSpellAttack)
return false; return false;
} }
if (target->GetSpecialAbility(IMMUNE_DAMAGE_CLIENT) && IsClient())
return false;
if (target->GetSpecialAbility(IMMUNE_DAMAGE_NPC) && IsNPC())
return false;
// can't damage own pet (applies to everthing) // can't damage own pet (applies to everthing)
Mob *target_owner = target->GetOwner(); Mob *target_owner = target->GetOwner();
Mob *our_owner = GetOwner(); Mob *our_owner = GetOwner();

View File

@ -2667,6 +2667,12 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
if (IsFamiliar() || GetSpecialAbility(IMMUNE_AGGRO)) if (IsFamiliar() || GetSpecialAbility(IMMUNE_AGGRO))
return; return;
if (GetSpecialAbility(IMMUNE_AGGRO_NPC) && other->IsNPC())
return;
if (GetSpecialAbility(IMMUNE_AGGRO_CLIENT) && other->IsClient())
return;
if (spell_id != SPELL_UNKNOWN && NoDetrimentalSpellAggro(spell_id)) if (spell_id != SPELL_UNKNOWN && NoDetrimentalSpellAggro(spell_id))
return; return;
@ -2758,8 +2764,11 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
else { else {
// cb:2007-08-17 // cb:2007-08-17
// owner must get on list, but he's not actually gained any hate yet // owner must get on list, but he's not actually gained any hate yet
if (!owner->GetSpecialAbility(IMMUNE_AGGRO)) if (
{ !owner->GetSpecialAbility(IMMUNE_AGGRO) &&
!(this->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) && owner->IsClient()) &&
!(this->GetSpecialAbility(IMMUNE_AGGRO_NPC) && owner->IsNPC())
) {
if (owner->IsClient() && !CheckAggro(owner)) if (owner->IsClient() && !CheckAggro(owner))
owner->CastToClient()->AddAutoXTarget(this); owner->CastToClient()->AddAutoXTarget(this);
hate_list.AddEntToHateList(owner, 0, 0, false, !iBuffTic); hate_list.AddEntToHateList(owner, 0, 0, false, !iBuffTic);
@ -2768,13 +2777,25 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
} }
if (mypet && !mypet->IsHeld() && !mypet->IsPetStop()) { // I have a pet, add other to it if (mypet && !mypet->IsHeld() && !mypet->IsPetStop()) { // I have a pet, add other to it
if (!mypet->IsFamiliar() && !mypet->GetSpecialAbility(IMMUNE_AGGRO)) if (
!mypet->IsFamiliar() &&
!mypet->GetSpecialAbility(IMMUNE_AGGRO) &&
!(mypet->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) && this->IsClient()) &&
!(mypet->GetSpecialAbility(IMMUNE_AGGRO_NPC) && this->IsNPC())
) {
mypet->hate_list.AddEntToHateList(other, 0, 0, bFrenzy); mypet->hate_list.AddEntToHateList(other, 0, 0, bFrenzy);
} }
}
else if (myowner) { // I am a pet, add other to owner if it's NPC/LD else if (myowner) { // I am a pet, add other to owner if it's NPC/LD
if (myowner->IsAIControlled() && !myowner->GetSpecialAbility(IMMUNE_AGGRO)) if (
myowner->IsAIControlled() &&
!myowner->GetSpecialAbility(IMMUNE_AGGRO) &&
!(this->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) && myowner->IsClient()) &&
!(this->GetSpecialAbility(IMMUNE_AGGRO_NPC) && myowner->IsNPC())
) {
myowner->hate_list.AddEntToHateList(other, 0, 0, bFrenzy); myowner->hate_list.AddEntToHateList(other, 0, 0, bFrenzy);
} }
}
if (other->GetTempPetCount()) if (other->GetTempPetCount())
entity_list.AddTempPetsToHateList(other, this, bFrenzy); entity_list.AddTempPetsToHateList(other, this, bFrenzy);
@ -3467,8 +3488,19 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
// pets that have GHold will never automatically add NPCs // pets that have GHold will never automatically add NPCs
// pets that have Hold and no Focus will add NPCs if they're engaged // pets that have Hold and no Focus will add NPCs if they're engaged
// pets that have Hold and Focus will not add NPCs // pets that have Hold and Focus will not add NPCs
if (pet && !pet->IsFamiliar() && !pet->GetSpecialAbility(IMMUNE_AGGRO) && !pet->IsEngaged() && attacker && attacker != this && !attacker->IsCorpse() && !pet->IsGHeld() && !attacker->IsTrap()) if (
{ pet &&
!pet->IsFamiliar() &&
!pet->GetSpecialAbility(IMMUNE_AGGRO) &&
!pet->IsEngaged() &&
attacker &&
!(pet->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) && attacker->IsClient()) &&
!(pet->GetSpecialAbility(IMMUNE_AGGRO_NPC) && attacker->IsNPC()) &&
attacker != this &&
!attacker->IsCorpse() &&
!pet->IsGHeld() &&
!attacker->IsTrap()
) {
if (!pet->IsHeld()) { if (!pet->IsHeld()) {
LogAggro("Sending pet [{}] into battle due to attack", pet->GetName()); LogAggro("Sending pet [{}] into battle due to attack", pet->GetName());
if (IsClient()) { if (IsClient()) {

View File

@ -2433,13 +2433,17 @@ bool Client::CheckIncreaseSkill(EQ::skills::SkillType skillid, Mob *against_who,
char buffer[24] = { 0 }; char buffer[24] = { 0 };
snprintf(buffer, 23, "%d %d", skillid, skillval); snprintf(buffer, 23, "%d %d", skillid, skillval);
parse->EventPlayer(EVENT_USE_SKILL, this, buffer, 0); parse->EventPlayer(EVENT_USE_SKILL, this, buffer, 0);
if(against_who) if (against_who) {
{ if (
if(against_who->GetSpecialAbility(IMMUNE_AGGRO) || against_who->IsClient() || against_who->GetSpecialAbility(IMMUNE_AGGRO) ||
GetLevelCon(against_who->GetLevel()) == CON_GRAY) against_who->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) ||
{ against_who->IsClient() ||
GetLevelCon(against_who->GetLevel()) == CON_GRAY
) {
//false by default //false by default
if( !mod_can_increase_skill(skillid, against_who) ) { return(false); } if (!mod_can_increase_skill(skillid, against_who)) {
return false;
}
} }
} }

View File

@ -195,7 +195,11 @@ enum {
COUNTER_AVOID_DAMAGE = 44, COUNTER_AVOID_DAMAGE = 44,
PROX_AGGRO = 45, PROX_AGGRO = 45,
IMMUNE_RANGED_ATTACKS = 46, IMMUNE_RANGED_ATTACKS = 46,
MAX_SPECIAL_ATTACK = 47 IMMUNE_DAMAGE_CLIENT = 47,
IMMUNE_DAMAGE_NPC = 48,
IMMUNE_AGGRO_CLIENT = 49,
IMMUNE_AGGRO_NPC = 50,
MAX_SPECIAL_ATTACK = 51
}; };
typedef enum { //fear states typedef enum { //fear states

View File

@ -4135,10 +4135,15 @@ void EntityList::AddTempPetsToHateList(Mob *owner, Mob* other, bool bFrenzy)
NPC* n = it->second; NPC* n = it->second;
if (n->GetSwarmInfo()) { if (n->GetSwarmInfo()) {
if (n->GetSwarmInfo()->owner_id == owner->GetID()) { if (n->GetSwarmInfo()->owner_id == owner->GetID()) {
if (!n->GetSpecialAbility(IMMUNE_AGGRO)) if (
!n->GetSpecialAbility(IMMUNE_AGGRO) &&
!(n->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) && other->IsClient()) &&
!(n->GetSpecialAbility(IMMUNE_AGGRO_NPC) && other->IsNPC())
) {
n->hate_list.AddEntToHateList(other, 0, 0, bFrenzy); n->hate_list.AddEntToHateList(other, 0, 0, bFrenzy);
} }
} }
}
++it; ++it;
} }
} }

View File

@ -2708,7 +2708,11 @@ luabind::scope lua_register_special_abilities() {
luabind::value("ignore_root_aggro_rules", static_cast<int>(IGNORE_ROOT_AGGRO_RULES)), luabind::value("ignore_root_aggro_rules", static_cast<int>(IGNORE_ROOT_AGGRO_RULES)),
luabind::value("casting_resist_diff", static_cast<int>(CASTING_RESIST_DIFF)), luabind::value("casting_resist_diff", static_cast<int>(CASTING_RESIST_DIFF)),
luabind::value("counter_avoid_damage", static_cast<int>(COUNTER_AVOID_DAMAGE)), luabind::value("counter_avoid_damage", static_cast<int>(COUNTER_AVOID_DAMAGE)),
luabind::value("immune_ranged_attacks", static_cast<int>(IMMUNE_RANGED_ATTACKS)) luabind::value("immune_ranged_attacks", static_cast<int>(IMMUNE_RANGED_ATTACKS)),
luabind::value("immune_damage_client", static_cast<int>(IMMUNE_DAMAGE_CLIENT)),
luabind::value("immune_damage_npc", static_cast<int>(IMMUNE_DAMAGE_NPC)),
luabind::value("immune_aggro_client", static_cast<int>(IMMUNE_AGGRO_CLIENT)),
luabind::value("immune_aggro_npc", static_cast<int>(IMMUNE_AGGRO_NPC))
]; ];
} }

View File

@ -3132,6 +3132,12 @@ void Mob::ExecWeaponProc(const EQ::ItemInstance *inst, uint16 spell_id, Mob *on,
return; return;
} }
if (on->GetSpecialAbility(IMMUNE_DAMAGE_CLIENT) && IsClient())
return;
if (on->GetSpecialAbility(IMMUNE_DAMAGE_NPC) && IsNPC())
return;
if (IsNoCast()) if (IsNoCast())
return; return;