View Single Post
  #1  
Old 10-24-2002, 06:41 PM
Wiz
Dragon
 
Join Date: Feb 2002
Posts: 583
Default Feign Death Code - Revised

This is a complete code snippet for Feign Death, including aggro clearing, enemy memory, and such.

To initiate, open client_process.cpp, and insert this under the opcodes.

Code:
					case OP_FeignDeath:
					{
int16 feignskill = GetSkill(FEIGN_DEATH);
						int16 primfeign = feignskill;
						int16 secfeign = feignskill;
						if (primfeign > 100) 
						{
							primfeign = 100;
							secfeign = secfeign - 100;
							secfeign = secfeign / 2;
						}	
						else
							secfeign = 0;
						int16 totalfeign = primfeign + secfeign;
						if (rand()%160 > totalfeign)
						{
							SetFeigned(false);
							entity_list.MessageClose(this,false,200,0,"%s has fallen to the ground.",this->GetName());
						}
						else
						{
							SetFeigned(true);
							entity_list.ClearFeignAggro(this);
						}
						if (rand()%300 > feignskill && rand()%4 == 1 && feignskill < 200 && feignskill < GetLevel()*5+5) 
						{
						    SetSkill(25,++pp.skills[25]);
							UpdateWho();
						}
						break;
					}
Now, go further up in client_process.cpp, find OP_SpawnAppearance. Under standing, sitting, looting and ducking, insert

Code:
SetFeigned(false);
Insert this into client.h:

Code:
	void	SetFeigned(bool in_feigned);
	bool    GetFeigned()	{return feigned;}
        bool    feigned;
Insert this into Client::Client in client.cpp

Code:
feigned=false;
And this at the bottom of client.cpp

Code:
void Client::SetFeigned(bool in_feigned) {
	if (in_feigned)
		SetPet(0); //Crashes unless this is put here
	feigned=in_feigned;
 }
Insert into npc.h

Code:
void	SetFeignMemory(const char* num) {feign_memory = num;}
const char*	feign_memory;
int8    forgetchance;
Timer* forget_timer;
Insert into npc.cpp, in NPC::NPC

Code:
feign_memory = "0";
forget_timer = new Timer(500);
forgetchance = 0;
Insert into npc.cpp, at the bottom of Process();

Code:
	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 = forgetchance + 5;
			}
		}
		else
		{
			SetFeignMemory("0");
		}
	}
Insert into entity.h:

Code:
	void	ClearFeignAggro(Mob* targ);
Insert into entity.cpp:

Code:
void EntityList::ClearFeignAggro(Mob* targ)
{
	LinkedListIterator<Entity*> iterator(list);
	iterator.Reset();
	while(iterator.MoreElements())
	{
		if (iterator.GetData()->IsNPC() && 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();
	}
}
In NpcAI.cpp, find this line:

Code:
								sender->AddToHateList(currentmob,1);
A bit above it, in the if statement, add
Code:
&& !currentmob->CastToClient()->GetFeigned()
to prevent mobs from aggroing a feigned person.

Insert this into spells.cpp, under SpellEffect:

Code:
	if (spells[spell_id].goodEffect == 0 && this->IsClient() && this->CastToClient()->GetFeigned()) {
		this->CastToClient()->Message(MT_Shout,"You are no longer feigning death because a spell hit you!");
		this->CastToClient()->SetFeigned(false);
	}
Finally, insert into spells.cpp, under SE_FeignDeath:
Code:
				this->CastToClient()->SetFeigned(true);
				entity_list.ClearFeignAggro(this);
You're done! Yeah, it doesn't work exactly like VI's rather fucked up feign death code, but here's the advantages:

- Easier processing. Having a purely time based forget chance eliminates some of the more comical aspects to VI's FD, and can also be modified per NPC through a database, if some tweaking is done.

- You don't have to turn off autoattack for this feign to work (Never understood that anyways).

- No feign bug, at all. This feign always works when successfully processed.
Reply With Quote