Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Development

Development::Development Forum for development topics and for those interested in EQEMu development. (Not a support forum)

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #1  
Old 06-19-2006, 08:41 AM
unicorn97211
Sarnak
 
Join Date: May 2006
Posts: 37
Default Feign Death Reliability Fix - Pet Fix - Feign Memory Overhaul

Feign Reliability Fix

Feign was failing outside our control.

client_process.cpp

In Client::Process

Change

Code:
#ifdef REVERSE_AGGRO
	//At this point, we are still connected, everything important has taken
	//place, now check to see if anybody wants to aggro us.
	if(ret && scanarea_timer.Check()) {
		entity_list.CheckClientAggro(this);
	}
#endif
to

Code:
#ifdef REVERSE_AGGRO
	//At this point, we are still connected, everything important has taken
	//place, now check to see if anybody wants to aggro us.
	if(ret && scanarea_timer.Check()) {
		// Everhood 6/15/06 - only check prox agro if we are not feigned
		if(!feigned){
			entity_list.CheckClientAggro(this);
		}
	}
#endif
client.h

Change

Code:
inline bool    GetFeigned()	{ return(GetAppearance() != eaDead ? false : feigned); }
To

Code:
	// EverHood 6/16/06
	// this cures timing issues cuz dead animation isn't done but server side feigning is?
	inline bool    GetFeigned()	{return feigned; }
Feigned Owner Pet Aggro Fix

Now that pets don't die when we feign, this stops us from inheriting any hate the pet does while we are fiegned.

i.e. If someone trains my pet with 20 mobs and I feign, when my pet dies the mobs should return home. Pre-Fix when my pet died the mobs would begin attacking me even though I am feigned.

attack.cpp

In Mob::AddToHateList

Change

Code:
	if (owner) { // Other has a pet, add him and it
		hate_list.Add(other, hate, 0, bFrenzy, !iBuffTic);
		hate_list.Add(owner, 1, damage, false, !iBuffTic);
	}
To

Code:
	if (owner) { // Other is a pet, add him and it
		hate_list.Add(other, hate, 0, bFrenzy, !iBuffTic);
		// EverHood 6/12/06
		// Can't add a feigned owner to hate list
		if(!owner->CastToClient()->GetFeigned()){
			hate_list.Add(owner, 1, damage, false, !iBuffTic);
		}
	}
Improved Feign Memory

The current feign memory only allows an NPC to remember a single attacker and the attacker was being remembered 100% of the time. When the NPCs feign memory was being processed, the dice were thrown and the attacker got a chance to be forgotten and if he lost the roll enough times the attacker was eventually removed from feign memory. This was a problem since Necro A could aggro then feign then Necro B could aggro and feign overwriting Necro A in the feign memory allowing Necro A to get up when he shouldn't be able to yet. This did not follow live feign memory functionality in any way.

I've replaced the single slot feign memory with a feign memory list to hold multiple attackers. I've changed the code so that when you feign, if the NPC is level 35+, the dice are thrown and there is a 3 in 5 chance you will be added to the NPCs feign memory list. When the NPC processes its feign memory, any attacker on it that has stood up will be added back to that NPCs hate list. If the NPC reaches it's guard point (spawn point) it will clear all attackers from it's feign memory. If the NPC is on a grid and reaches waypoint 1 it will clear all attackers from it's feign memory.

npc.h

Change
Code:
	void	SetFeignMemory(const char* num) {feign_memory = num;}

	inline const char*    GetFeignMemory()	{ return feign_memory; }
To
Code:
	// EverHood 6/14/06
	// Mobs need to be able to remember more than one feigned attacker
	void	AddFeignMemory(Client* attacker);
	void	RemoveFromFeignMemory(Client* attacker);
	void	ClearFeignMemory();
Change
Code:
	const char*	feign_memory;
To
Code:
	// EverHood 6/14/06
	LinkedList<const char*> feign_memory_list;
npc.cpp

In NPC::Process

Change
Code:
	//Feign Death Memory
	if (forget_timer.Check() && strstr(GetFeignMemory(),"0") == NULL) {
		Client* remember_client = entity_list.GetClientByName(GetFeignMemory());
		if (remember_client != 0)
		{
			if (!remember_client->CastToClient()->GetFeigned())
			{
				AddToHateList(remember_client,1);
				SetFeignMemory("0");
				forgetchance = 0;
			}
			else if (rand()%100 <= forgetchance)
			{
				SetFeignMemory("0");
				forgetchance = 0;
			}
			else
			{
				forgetchance += 1;
			}
		}
		else
		{
			SetFeignMemory("0");
		}
	}
To
Code:
	// EverHood - 6/14/06
	// Improved Feign Death Memory
	if (forget_timer.Check()) {
		LinkedListIterator<const char*> iterator(feign_memory_list);
		iterator.Reset();
		while(iterator.MoreElements())
		{
			Client* remember_client = entity_list.GetClientByName(iterator.GetData());
			if (!remember_client->CastToClient()->GetFeigned())
			{
				AddToHateList(remember_client,1);
				iterator.RemoveCurrent();
				// Personal humor
				Emote("realizes %s wasn't really dead",remember_client->GetName());
			}
			iterator.Advance();
		}		
	}
Add
Code:
	// EverHood 6/14/06 - Feign Death memory 
	void   NPC::AddFeignMemory(Client* attacker) {
		feign_memory_list.Insert(attacker->CastToMob()->GetName());
		// Leaving this debug in is kinda interesting...
		Emote("is suspicious of %ss unexpected death.",attacker->GetName());
	}
	void   NPC::RemoveFromFeignMemory(Client* attacker){
		LinkedListIterator<const char*> iterator(feign_memory_list);
		iterator.Reset();
		while(iterator.MoreElements())
		{
			if(iterator.GetData() == attacker->GetName()){
				// Leaving this debug in is kinda interesting...
				this->CastToMob()->Emote("loses interest in %s.",attacker->GetName());
				iterator.RemoveCurrent();
			}
			iterator.Advance();
		}
	}
	void   NPC::ClearFeignMemory(){
		if(feign_memory_list.Count()>0){
			feign_memory_list.Clear();
			// Leaving this debug in is kinda interesting...
			this->CastToMob()->Emote("is no longer suspicious of the dead.");
		}
	}
entity.cpp

Change
Code:
void EntityList::ClearFeignAggro(Mob* targ)
{
	LinkedListIterator<NPC*> iterator(npc_list);
	iterator.Reset();
	while(iterator.MoreElements())
	{
		if (iterator.GetData()->CastToNPC()->CheckAggro(targ))
		{
			iterator.GetData()->CastToNPC()->RemoveFromHateList(targ);
			if (iterator.GetData()->CastToMob()->GetLevel() >= 35)
				iterator.GetData()->CastToNPC()->SetFeignMemory(targ->CastToMob()->GetName());
		}
		iterator.Advance();
	}
}
To
Code:
void EntityList::ClearFeignAggro(Mob* targ)
{
	LinkedListIterator<NPC*> iterator(npc_list);
	iterator.Reset();
	while(iterator.MoreElements())
	{
		if (iterator.GetData()->CastToNPC()->CheckAggro(targ))
		{
			iterator.GetData()->CastToNPC()->RemoveFromHateList(targ);
			if (iterator.GetData()->CastToMob()->GetLevel() >= 35)
				// EverHood 6/14/06
				// the mob that hated us is 35+ so 3 outta 5 chance 
				// he adds us to its feign memory. 
				if(((float)rand()/RAND_MAX)*100 < 40){
					iterator.GetData()->CastToNPC()->AddFeignMemory(targ->CastToClient());
				}
		}
		iterator.Advance();
	}
}
MobAI.cpp

In NPC::AI_DoMovement

Change
Code:
				{	// are we there yet? then stop
					mlog(AI__WAYPOINTS, "We have reached waypoint %d (%.3f,%.3f,%.3f) on grid %d", cur_wp, GetX(), GetY(), GetZ(), GetGrid());
					SetWaypointPause();
					SetAppearance(eaStanding, false);
					SetMoving(false);
					SendPosition();
				}
To
Code:
				{	// are we there yet? then stop
					mlog(AI__WAYPOINTS, "We have reached waypoint %d (%.3f,%.3f,%.3f) on grid %d", cur_wp, GetX(), GetY(), GetZ(), GetGrid());
					SetWaypointPause();
					SetAppearance(eaStanding, false);
					SetMoving(false);
					SendPosition();
					// EverHood - wipe feign memory since we reached our first waypoint
					if(cur_wp==1){
						ClearFeignMemory();
					}
				}
Change
Code:
			mlog(AI__WAYPOINTS, "Reached guard point (%.3f,%.3f,%.3f)", guard_x, guard_y, guard_z);
			moved=false;
To
Code:
			mlog(AI__WAYPOINTS, "Reached guard point (%.3f,%.3f,%.3f)", guard_x, guard_y, guard_z);
			// EverHood 6/18/06- we are home so clear our feign memory
			ClearFeignMemory();
			moved=false;
Feign Memory 2 Minute Wipe

I saw no code to handle this. When a client is feigned for 2 minutes, clear client off all feign memory lists in zone and let client know it is clear to stand up.


Client.h

Change
Code:
	Timer	fishing_timer;
#ifdef REVERSE_AGGRO
	Timer	scanarea_timer;
#endif
To
Code:
	Timer	fishing_timer;
	// EverHood 6/16/06
	// our 2 min everybody forgets you timer
	Timer	forget_timer;
#ifdef REVERSE_AGGRO
	Timer	scanarea_timer;
#endif
client.cpp

In Client::Client

Change
Code:
	fishing_timer(8000),
#ifdef REVERSE_AGGRO
	scanarea_timer(AIClientScanarea_delay),
#endif
To
Code:
	fishing_timer(8000),
	// EverHood 6/16/06
	forget_timer(120000),
#ifdef REVERSE_AGGRO
	scanarea_timer(AIClientScanarea_delay),
#endif
client_process.cpp

In Client::Process

Change
Code:
		OnDisconnect(true);
	}
	
	
	return ret;
}
To
Code:
		OnDisconnect(true);
	}
	// EverHood Feign Death 2 minutes and zone forgets you
	if (forget_timer.Check()) {
		forget_timer.Disable();
		entity_list.ClearZoneFeignAggro(this);
		Message(0,"Your enemies have forgotten your aggressions.");
	}
	
	return ret;
}
entity.h

Change
Code:
	void	ClearFeignAggro(Mob* targ);
	bool	Fighting(Mob* targ);
to
Code:
	void	ClearFeignAggro(Mob* targ);
	// Everhood 6/17/06
	void	ClearZoneFeignAggro(Client* targ);
	bool	Fighting(Mob* targ);
entity.cpp

Add
Code:
// EverHood 6/17/06
void EntityList::ClearZoneFeignAggro(Client* targ)
{
	LinkedListIterator<NPC*> iterator(npc_list);
	iterator.Reset();
	while(iterator.MoreElements())
	{
		iterator.GetData()->RemoveFromFeignMemory(targ);
		iterator.Advance();
	}
}
Reply With Quote
 


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 07:10 PM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3