View Single Post
  #14  
Old 04-14-2017, 12:17 AM
Coenxai's Avatar
Coenxai
Hill Giant
 
Join Date: Dec 2013
Posts: 151
Default

Quote:
Originally Posted by ChaosSlayerZ View Post
actually it would be better if Undead don't always aggro automatically - because you may want undead that don't aggro. (not all undead on live were always aggro - there was a number of undead in various places/levels that obeyed level difference green status)
So its better to have all mobs without default rules, and then apply the "always aggro" flag where actually needed.
You can have a mob of type BT_Undead that doesn't aggro. This purely relates to FACTION_THREATENLY && FACTION_SCOWLS.

I'm going to post slightly more readable aggro code.

I didn't test this properly but it should work.
Code:
aggro.cpp

bool Mob::CheckWillAggro(Mob *mob) {

	if(!mob)
		return false;

	if (mob->IsClient()) {
		if (!mob->CastToClient()->ClientFinishedLoading() || mob->CastToClient()->IsHoveringForRespawn() || mob->CastToClient()->zoning || !mob->CastToClient()->Connected() 
			|| mob->CastToClient()->GetGM() || mob->CastToClient()->IsLD() || mob->CastToClient()->IsBecomeNPC() || mob->IsInvisible(this))
			return false;
	}

	Mob *ownr = mob->GetOwner();
	if (ownr && ownr->IsClient() && !ownr->CastToClient()->ClientFinishedLoading() || mob == ownr)
		return false;

	// Don't aggro new clients if we are already engaged unless PROX_AGGRO is set. WHY ARE WE CHECKING COMBAT AND AGGRO RANGE? THIS SHOULD BE COMBINED.
	if (IsEngaged() && !GetSpecialAbility(PROX_AGGRO) || GetSpecialAbility(PROX_AGGRO) && !CombatRange(mob)) {
		Log(Logs::Moderate, Logs::Aggro, "%s is in combat, and does not have prox_aggro, or does and is out of combat range with %s", GetName(), mob->GetName());
		return false;
	}

	float AggroRange, t1, t2, t3;

	AggroRange = GetAggroRange();
	t1 = mob->GetX() - GetX();
	t2 = mob->GetY() - GetY();
	t3 = mob->GetZ() - GetZ();

	if (t1 < 0)
		t1 = 0 - t1;
	if (t2 < 0)
		t2 = 0 - t2;
	if (t3 < 0)
		t3 = 0 - t3;

	if ((t1 > AggroRange) || (t2 > AggroRange) || (t3 > AggroRange))
		return false;

	float dist2 = DistanceSquared(mob->GetPosition(), m_Position);
	float AggroRange2 = AggroRange*AggroRange;

	if (dist2 > AggroRange2)
		return false;

	FACTION_VALUE fv = mob->GetReverseFactionCon(this);
	uint8 MyLevel = GetLevel();

	int heroicCHA_mod = mob->itembonuses.HeroicCHA/25; // 800 Heroic CHA cap
	if(heroicCHA_mod > THREATENLY_ARRGO_CHANCE)
		heroicCHA_mod = THREATENLY_ARRGO_CHANCE;

	if (MyLevel >= RuleI(Aggro, LevelAggro) || (GetBodyType() == BT_Undead && MyLevel >= RuleI(Aggro, UndeadLevelAggro)) || GetINT() <= RuleI(Aggro, IntAggroThreshold)
		|| mob->IsClient() && mob->CastToClient()->IsSitting() || GetSpecialAbility(ALWAYS_AGGRO) || mob->GetLevelCon(GetLevel()) != CON_GREEN) {
		if (fv == FACTION_SCOWLS || fv == FACTION_THREATENLY && zone->random.Roll(THREATENLY_ARRGO_CHANCE - heroicCHA_mod) 
			|| (mob->GetPrimaryFaction() != GetPrimaryFaction() && mob->GetPrimaryFaction() == -4 && GetOwner() == nullptr)) {
			if (CheckLosFN(mob)) {
				Log(Logs::Detail, Logs::Aggro, "Check aggro for %s target %s.", GetName(), mob->GetName());
				return(mod_will_aggro(mob, this));
			}
		}
	}

	Log(Logs::Detail, Logs::Aggro, "InZone: %d | Dist^2: %f | Range^2: %f | Faction: %d | Con: %d | Int: %d | MyLevel: %d", mob->InZone(), dist2, AggroRange2, fv, GetINT(), GetLevelCon(mob->GetLevel()), MyLevel);

	return false;
}
Code:
ruletypes.h

RULE_CATEGORY(Aggro)
RULE_BOOL(Aggro, SmartAggroList, true)
RULE_INT(Aggro, SittingAggroMod, 35) //35%
RULE_INT(Aggro, MeleeRangeAggroMod, 10) //10%
RULE_INT(Aggro, CurrentTargetAggroMod, 0) //0% -- will prefer our current target to any other; makes it harder for our npcs to switch targets.
RULE_INT(Aggro, CriticallyWoundedAggroMod, 100) //100%
RULE_INT(Aggro, SpellAggroMod, 100)
RULE_INT(Aggro, SongAggroMod, 33)
RULE_INT(Aggro, PetSpellAggroMod, 10)
RULE_REAL(Aggro, TunnelVisionAggroMod, 0.75) //people not currently the top hate generate this much hate on a Tunnel Vision mob
RULE_INT(Aggro, MaxScalingProcAggro, 400) // Set to -1 for no limit. Maxmimum amount of aggro that HP scaling SPA effect in a proc will add.
RULE_INT(Aggro, IntAggroThreshold, 75) // Int <= this will aggro regardless of level difference.
RULE_BOOL(Aggro, AllowTickPulling, false) // tick pulling is an exploit in an NPC's call for help fixed sometime in 2006 on live
RULE_BOOL(Aggro, UseLevelAggro, true)
RULE_INT(Aggro, LevelAggro, 18)
RULE_INT(Aggro, UndeadLevelAggro, 6)
RULE_INT(Aggro, ClientAggroCheckInterval, 6) // Interval in which clients actually check for aggro - in seconds
RULE_CATEGORY_END()
Code:
common.h

   ...

	COUNTER_AVOID_DAMAGE = 44,
	PROX_AGGRO = 45,
	ALWAYS_AGGRO = 46, <---
	MAX_SPECIAL_ATTACK = 47
__________________
"The true sign of intelligence is not knowledge but imagination."
Reply With Quote