Jump to content

No Aggropulling when Monster Poisoned and you're Dead


Recommended Posts

No aggro-pulling when the monster is poisoned and you're dead and want to stand up again.
maybe someone need this.

in char_battle.cpp

void CHARACTER::UpdateAggrPointEx(LPCHARACTER pAttacker, EDamageType type, int dam, CHARACTER::TBattleInfo & info)

//this (last line):
ChangeVictimByAggro(info.iAggro, pAttacker);


//Change with this:
	if (type != DAMAGE_TYPE_POISON)
		ChangeVictimByAggro(info.iAggro, pAttacker);

 

  • Love 3
  • Honorable Member

Make it complete, then.

 

	switch (type)
	{
		case DAMAGE_TYPE_POISON:
		case DAMAGE_TYPE_BLEEDING:
		case DAMAGE_TYPE_FIRE:
			return;
	}

	ChangeVictimByAggro(info.iAggro, pAttacker);

 

  • Love 1

 

"Nothing's free in this life.

Ignorant people have an obligation to make up for their ignorance by paying those who help them.

Either you got the brains or cash, if you lack both you're useless."

Syreldar

2 hours ago, Syreldar said:

Make it complete, then.

 


	switch (type)
	{
		case DAMAGE_TYPE_POISON:
		case DAMAGE_TYPE_BLEEDING:
		case DAMAGE_TYPE_FIRE:
			return;
	}

	ChangeVictimByAggro(info.iAggro, pAttacker);

 

	switch (type)
	{
		case DAMAGE_TYPE_POISON:
#ifdef ENABLE_WOLFMAN_CHARACTER
		case DAMAGE_TYPE_BLEEDING:
#endif
		case DAMAGE_TYPE_FIRE:
			return;

		default:
			break;
	}

	ChangeVictimByAggro(info.iAggro, pAttacker);

 

  • Love 1
  • Forum Moderator

@Tatsumaru My question might look stupid, but are you in the room where all the mobs are agressive by default? Otherwise it would work.

 

About the original release, thank you. But are you the author of the code? Because it might be a ripoff from WoM² sources, in that case, credit the author.

 

Nice release anyway, getting chain killed by large groups of poisoned monsters because you can't run away is a pain.

Gurgarath
coming soon
My Services

  • Honorable Member
29 minut temu, Gurgarath napisał:

@Tatsumaru My question might look stupid, but are you in the room where all the mobs are agressive by default? Otherwise it would work.

 

About the original release, thank you. But are you the author of the code? Because it might be a ripoff from WoM² sources, in that case, credit the author.

 

Nice release anyway, getting chain killed by large groups of poisoned monsters because you can't run away is a pain.

These monsters are not aggressive. I tested also on others. Maybe I added the code wrong?

https://pastebin.com/hnxyPWXK

  • Metin2 Dev 2

GhwYizE.gif

  • Honorable Member
9 hours ago, Tatsumaru said:

These monsters are not aggressive. I tested also on others. Maybe I added the code wrong?

https://pastebin.com/hnxyPWXK

Inside dungeons monsters are set aggressive regardless of the regen/db settings.

 

"Nothing's free in this life.

Ignorant people have an obligation to make up for their ignorance by paying those who help them.

Either you got the brains or cash, if you lack both you're useless."

Syreldar

  • Honorable Member
4 godziny temu, Syreldar napisał:

Inside dungeons monsters are set aggressive regardless of the regen/db settings.

It is similar with other monsters.

giphy.gif

Edited by Metin2 Dev
Core X - External 2 Internal

GhwYizE.gif

The problem is the m_Victim, each LPCHARACTERS stores the target and, even if ChangeVictimByAggro(args) won't be executed since type = DAMAGE_TYPE_POISON, the monster will keep the target pointer to their last victim, you need to also remove the resurrected LPCHARACTER as victim of nearby monsters. To do so you can use some simple structs, I already posted this solution for Invisibility skill.

in char.cpp find void CHARACTER::ReviveInvisible(int iDur) and replace whole function

struct RemoveInvisibleVictim
{
	RemoveInvisibleVictim(LPCHARACTER pkOldVictim)
	{
		m_pkOldVictim = pkOldVictim;
	}
	void operator () (LPENTITY ent)
	{
		if (ent->IsType(ENTITY_CHARACTER))
		{
			LPCHARACTER pkChr = (LPCHARACTER) ent;
			if (pkChr && pkChr->IsMonster())
			{
				LPCHARACTER pkVictim = pkChr->GetVictim();
				if (pkVictim && pkVictim == m_pkOldVictim)
				{
					LPCHARACTER new_victim = pkChr->GetNewNearestVictim(pkChr, m_pkOldVictim);
					pkChr->SetVictim(new_victim);
				}
			}
		}
	}
	LPCHARACTER m_pkOldVictim;
};
void CHARACTER::ReviveInvisible(int iDur)
{
	if (GetSectree())
	{
		RemoveInvisibleVictim f(this);
		GetSectree()->ForEachAround(f);
	}
	AddAffect(AFFECT_REVIVE_INVISIBLE, POINT_NONE, 0, AFF_REVIVE_INVISIBLE, iDur, 0, true);
}
in char_battle.cpp add (and define it in char.h: LPCHARACTER GetNewNearestVictim(LPCHARACTER pkChr, LPCHARACTER pkVictimOld); )
LPCHARACTER CHARACTER::GetNewNearestVictim(LPCHARACTER pkChr, LPCHARACTER pkVictimOld)
{
	if (NULL == pkChr)
		pkChr = this;

	float fMinDist = 99999.0f;
	LPCHARACTER pkVictim = NULL;

	TDamageMap::iterator it = m_map_kDamage.begin();

	while (it != m_map_kDamage.end())
	{
		const VID & c_VID = it->first;
		++it;

		LPCHARACTER pAttacker = CHARACTER_MANAGER::instance().Find(c_VID);

		if (!pAttacker)
			continue;
		
		if (pAttacker->IsAffectFlag(AFF_EUNHYUNG) || 
				pAttacker->IsAffectFlag(AFF_INVISIBILITY) ||
				pAttacker->IsAffectFlag(AFF_REVIVE_INVISIBLE))
			continue;

		float fDist = DISTANCE_APPROX(pAttacker->GetX() - pkChr->GetX(), pAttacker->GetY() - pkChr->GetY());

		if (fDist < fMinDist && !pAttacker->IsDead() && pAttacker != pkVictimOld)
		{
			pkVictim = pAttacker;
			fMinDist = fDist;
		}
	}

	return pkVictim;
}

And then clean some miscoding:

In char_affect.cpp at CHARACTER::AddAffect(args...) if bool bOverride (one of the function arguments) is true it will first reset a said flag calling 

if (pkAff && bOverride)
	{
		ComputeAffect(pkAff, false); //

		if (GetDesc())
			SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
	}

WE change it as follows
  if (pkAff && bOverride)
	{
		ComputeAffect(pkAff, false, true); // ComputeAffect(Affect, !bOvveride, bOverride); 

		if (GetDesc())
			SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
	}

But we do not need to reset said flag early in the function if we are going to set it back few moments later so we can change CHARACTER::ComputeAffect(args..) as follows:

find
void CHARACTER::ComputeAffect(CAffect * pkAff, bool bAdd)
  	if (bAdd && pkAff->dwType >= GUILD_SKILL_START && pkAff->dwType <= GUILD_SKILL_END)	
	{
		if (!GetGuild())
			return;

		if (!GetGuild()->UnderAnyWar())
			return;
	}
	if (pkAff->dwFlag)
	{
		if (!bAdd)
			m_afAffectFlag.Reset(pkAff->dwFlag);
		else
			m_afAffectFlag.Set(pkAff->dwFlag);
	}
replace with
void CHARACTER::ComputeAffect(CAffect * pkAff, bool bAdd, bool bTemp)
{
	if (bAdd && pkAff->dwType >= GUILD_SKILL_START && pkAff->dwType <= GUILD_SKILL_END)	
	{
		if (!GetGuild())
			return;

		if (!GetGuild()->UnderAnyWar())
			return;
	}
	if (pkAff->dwFlag)
	{
		if (!bAdd && !bTemp)
			m_afAffectFlag.Reset(pkAff->dwFlag);
		else if (bAdd)
			m_afAffectFlag.Set(pkAff->dwFlag);
	}

//HEADER char.h find
		void			ComputeAffect(CAffect * pkAff, bool bAdd);
replace with
		void			ComputeAffect(CAffect * pkAff, bool bAdd, bool bTemp = false);

tested and working.

Edited by OtherChoice
TESTED AND WORKING
  • Love 3

Don't use any images from : imgur, turkmmop, freakgamers, inforge, hizliresim... Or your content will be deleted without notice...
Use : https://metin2.download/media/add/

Please use https://metin2.download/ when uploading files smaller than 100MB, otherwise the approval will take longer due to manual upload.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.