[Performance] Reworked how client to NPC aggro checks are made

- Before when reverse aggro checks were done (client to NPC), checks would happen every 750 millseconds where a client would
		check an entire entity list with distance calcs and other checks for aggro, with many clients in a zone and many NPC's this would
		add a lot of unecessary overhead. A temporary adjustment on 3/25 was made and upped the check to 6 seconds.
	- Now, there is a new methodology to scanning. The client will build a cache list of NPC's within close range as defined in new rule:
		RULE_INT(Range, ClientNPCScan, 300) and will also get any NPC that has an aggro range beyond that defined range to use in
		the frequent checks for aggro, the result is far less overhead
	- Client scanning changes when moving versus not moving, the client will scan aggro every 500 milliseconds while moving, and
		3000 millseconds aggro check when not moving, with a 6000ms re-fetch for close NPC's
	- A demo of these changes can be found here:
		https://youtu.be/aGroiwLSTVU
This commit is contained in:
Akkadius
2017-03-28 01:30:42 -05:00
parent 940f3b03e8
commit 4b6ce1c19e
9 changed files with 191 additions and 105 deletions
+5 -2
View File
@@ -135,7 +135,7 @@ Client::Client(EQStreamInterface* ieqs)
forget_timer(0),
autosave_timer(RuleI(Character, AutosaveIntervalS) * 1000),
#ifdef REVERSE_AGGRO
scanarea_timer(RuleI(Aggro, ClientAggroCheckInterval) * 1000),
client_scan_npc_aggro_timer(RuleI(Aggro, ClientAggroCheckInterval) * 1000),
#endif
tribute_timer(Tribute_duration),
proximity_timer(ClientProximity_interval),
@@ -160,7 +160,8 @@ Client::Client(EQStreamInterface* ieqs)
m_AutoAttackPosition(0.0f, 0.0f, 0.0f, 0.0f),
m_AutoAttackTargetLocation(0.0f, 0.0f, 0.0f),
last_region_type(RegionTypeUnsupported),
m_dirtyautohaters(false)
m_dirtyautohaters(false),
npc_close_scan_timer(6000)
{
for(int cf=0; cf < _FilterCount; cf++)
ClientFilters[cf] = FilterShow;
@@ -358,6 +359,8 @@ Client::~Client() {
m_tradeskill_object = nullptr;
}
close_npcs.clear();
if(IsDueling() && GetDuelTarget() != 0) {
Entity* entity = entity_list.GetID(GetDuelTarget());
if(entity != nullptr && entity->IsClient()) {