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;
}
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)
Mob *target_owner = target->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))
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))
return;
@ -2758,8 +2764,11 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
else {
// cb:2007-08-17
// 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))
owner->CastToClient()->AddAutoXTarget(this);
hate_list.AddEntToHateList(owner, 0, 0, false, !iBuffTic);
@ -2768,12 +2777,24 @@ 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->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);
}
}
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);
}
}
if (other->GetTempPetCount())
@ -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 Hold and no Focus will add NPCs if they're engaged
// 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()) {
LogAggro("Sending pet [{}] into battle due to attack", pet->GetName());
if (IsClient()) {

View File

@ -2433,13 +2433,17 @@ bool Client::CheckIncreaseSkill(EQ::skills::SkillType skillid, Mob *against_who,
char buffer[24] = { 0 };
snprintf(buffer, 23, "%d %d", skillid, skillval);
parse->EventPlayer(EVENT_USE_SKILL, this, buffer, 0);
if(against_who)
{
if(against_who->GetSpecialAbility(IMMUNE_AGGRO) || against_who->IsClient() ||
GetLevelCon(against_who->GetLevel()) == CON_GRAY)
{
if (against_who) {
if (
against_who->GetSpecialAbility(IMMUNE_AGGRO) ||
against_who->GetSpecialAbility(IMMUNE_AGGRO_CLIENT) ||
against_who->IsClient() ||
GetLevelCon(against_who->GetLevel()) == CON_GRAY
) {
//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,
PROX_AGGRO = 45,
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

View File

@ -4135,8 +4135,13 @@ void EntityList::AddTempPetsToHateList(Mob *owner, Mob* other, bool bFrenzy)
NPC* n = it->second;
if (n->GetSwarmInfo()) {
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);
}
}
}
++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("casting_resist_diff", static_cast<int>(CASTING_RESIST_DIFF)),
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;
}
if (on->GetSpecialAbility(IMMUNE_DAMAGE_CLIENT) && IsClient())
return;
if (on->GetSpecialAbility(IMMUNE_DAMAGE_NPC) && IsNPC())
return;
if (IsNoCast())
return;