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
Link to comment
Share on other sites

  • Premium

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

Link to comment
Share on other sites

  • Bronze
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
Link to comment
Share on other sites

  • 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

Link to comment
Share on other sites

  • 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

Link to comment
Share on other sites

  • Premium
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

Link to comment
Share on other sites

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
Link to comment
Share on other sites

Announcements



×
×
  • 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.