Jump to content
  • 0

Make monsters and players die immediately


ReFresh

Question

  • Premium

Hey guys,

I'm still wondering about this function:

char_battle.cpp:

Spoiler
void CHARACTER::Stun()
{
	if (IsStun())
		return;

	if (IsDead())
		return;

	if (!IsPC() && m_pkParty)
	{
		m_pkParty->SendMessage(this, PM_ATTACKED_BY, 0, 0);
	}

	sys_log(1, "%s: Stun %p", GetName(), this);

	PointChange(POINT_HP_RECOVERY, -GetPoint(POINT_HP_RECOVERY));
	PointChange(POINT_SP_RECOVERY, -GetPoint(POINT_SP_RECOVERY));

	CloseMyShop();

	event_cancel(&m_pkRecoveryEvent);

	TPacketGCStun pack;
	pack.header	= HEADER_GC_STUN;
	pack.vid	= m_vid;
	PacketAround(&pack, sizeof(pack));

	SET_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_STUN);

	if (m_pkStunEvent)
		return;

	char_event_info* info = AllocEventInfo<char_event_info>();

	info->ch = this;

	m_pkStunEvent = event_create(StunEvent, info, PASSES_PER_SEC(3));
}

 

Why we need to call this s*it function mentioned above to make monster or player dead when HP is <=0 in statement below?

Spoiler
if (GetHP() <= 0)
	{
		Stun();

		if (pAttacker && !pAttacker->IsNPC())
			m_dwKillerPID = pAttacker->GetPlayerID();
		else
			m_dwKillerPID = 0;
	}

 

It couldn't be JustDieMonsterWithoutStunEffect(); or something shorter than the Stun(); function to make the target dead when the target(mob or player) reach 0 HP without any stun effect?

I would be really glad for some Stun(); function explanation or some simple solution to make it working without lines of "garbage code".

(I know there is guy who did some fix at this forum but it's not a good solution to remove some functions which were done by ymir).

I thought about this as fix, but I don't really want to fix that like below because I think it's not a good solution:

Spoiler
//SET_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_STUN); - just commented

m_pkStunEvent = event_create(StunEvent, info, PASSES_PER_SEC(0)); - edited number from 3 to 0

 

Thanks for your answers!

Sincerely,

ReFresh

Edited by ReFresh

I'll be always helpful! 👊 

Link to comment
Share on other sites

7 answers to this question

Recommended Posts

  • 0
  • Bronze

Yeah, I see what you talking about. The Dead method is called so fast now and it removes the stun flag so the check for the skill is not working anymore.

Try this: 

// char_skill.cpp
// Replace:
		if (!pkChrVictim->Damage(m_pkChr, iDam, dt) && !pkChrVictim->IsStun())
// With:
		if (!pkChrVictim->Damage(m_pkChr, iDam, dt) && !pkChrVictim->IsStun() && !pkChrVictim->IsDead())

 

  • Love 1
Link to comment
Share on other sites

  • 1
  • Bronze

They (ymir) used Stun because it does more stuff beside locking the character. Also they checked some stuff with the IsStun so I recommend you keep using it.

Try this and tell me if it's ok:

// char.h
// Replace:
		void				Stun();
// With:
		void				Stun(bool bJustDie = false);


// char_battle.cpp
// Replace:
void CHARACTER::Stun()
{
  ...
}
// With:
void CHARACTER::Stun(bool bJustDie)
{
	if (IsStun())
		return;

	if (IsDead())
		return;

	if (!IsPC() && m_pkParty)
	{
		m_pkParty->SendMessage(this, PM_ATTACKED_BY, 0, 0);
	}

	sys_log(1, "%s: Stun %p", GetName(), this);

	PointChange(POINT_HP_RECOVERY, -GetPoint(POINT_HP_RECOVERY));
	PointChange(POINT_SP_RECOVERY, -GetPoint(POINT_SP_RECOVERY));
	
	CloseMyShop();

	event_cancel(&m_pkRecoveryEvent); // 회복 이벤트를 죽인다.
	
	if(bJustDie)
	{
		SET_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_STUN);
		Dead();
	}
	else
	{
		TPacketGCStun pack;
		pack.header	= HEADER_GC_STUN;
		pack.vid	= m_vid;
		PacketAround(&pack, sizeof(pack));
	
		SET_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_STUN);
	
		if (m_pkStunEvent)
			return;
	
		char_event_info* info = AllocEventInfo<char_event_info>();
	
		info->ch = this;
	
		m_pkStunEvent = event_create(StunEvent, info, PASSES_PER_SEC(3));
	}
}

// Inside:
bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type)
// Replace:
	if (GetHP() <= 0)
	{
		Stun();

		if (pAttacker && !pAttacker->IsNPC())
			m_dwKillerPID = pAttacker->GetPlayerID();
		else
			m_dwKillerPID = 0;
	}
// With:
	if (GetHP() <= 0)
	{
		if (pAttacker && !pAttacker->IsNPC())
			m_dwKillerPID = pAttacker->GetPlayerID();
		else
			m_dwKillerPID = 0;

		Stun(true);
	}

 

  • Love 1
Link to comment
Share on other sites

  • 0
  • Premium

@xXIntelXx Thanks for your try, but like this, I will must add many lines to remove exact stun effect done by target skill. I'm thinking about something which will be able remove that stun effect by detecting the stun effect.

Stun(); function is able to remove this effect when player die but Dead(pAttacker) not.

And this piece of code written alone did nothing ingame:

Spoiler
if (NULL != FindAffect(AFFECT_STUN))
	RemoveAffect(AFFECT_STUN);

 

Something like this could do the thing, but it doesn't work too:

Spoiler
REMOVE_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_STUN);

 

And in the last case I was thinking about new event function especially for dead. Make it almost like Stun(); but just for Dead(); without stun effect.

Edited by ReFresh

I'll be always helpful! 👊 

Link to comment
Share on other sites

  • 0
  • Premium
39 minutes ago, ReFresh said:

@xXIntelXx Thanks for your try, but like this, I will must add many lines to remove exact stun effect done by target skill. I'm thinking about something which will be able remove that stun effect by detecting the stun effect.

Stun(); function is able to remove this effect when player die but Dead(pAttacker) not.

And this piece of code written alone did nothing ingame:

  Hide contents
if (NULL != FindAffect(AFFECT_STUN))
	RemoveAffect(AFFECT_STUN);

 

Something like this could do the thing, but it doesn't work too:

  Hide contents
REMOVE_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_STUN);

 

And in the last case I was thinking about new event function especially for dead. Make it almost like Stun(); but just for Dead(); without stun effect.

The RemoveAffect didn't work? Uh.. I don't know then, I have a total different skill system from the official files, I have no way to do better tests 😕

 

Maybe a similar Stun() function may work

No hold on a second, RemoveAffect(AFFECT_STUN); MUST  remove the stun (it's used in void CHARACTER::RemoveBadAffect()) so I don't understand the:
"I will must add many lines to remove exact stun effect done by target skill". Of course if the enemy is not stunned when it has to die, that peace of code does nothing.
 

Also the stun function doesn't remove any stun, actually the contrary:

	if (IsStun())
		return;

but, I do have:

REMOVE_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_STUN);

in the Dead function

 

UV04cru.png

Edited by Metin2 Dev
Core X - External 2 Internal
  • Confused 1
Link to comment
Share on other sites

  • 0
  • Premium

@Abel(Tiger) Thanks man, I always appreciate your help. You helped me a lot in the past too. 

I've just tested your code and there is still one thing which I need to solve somehow and that's:

When I gave "one-shot" to someone, not depends if it was mob or player and the skill with I "one-shoted" the target contained Stun probability, player or mob died but with the Stun (because they were stunned by the skill) and the stun is visible on dead target until the duration of it's stun is expired.

I need to have it like:

When player reach <= 0 HP the game must remove the stun affect, because it's only the last affect which isn't removed since the stun function is not defined in char_affect so I don't know how remove the stun affect. -->

--> In the past the Dead(); function wasn't removing any of affects like poison, fire, bleed too but it was fixed by adding this to EVENTFUNC in char_ressist.cpp to the exact function:

Spoiler
if (ch->IsDead())
{
	ch->RemoveFire();
}

 

Screen of player one-shoted by poisoned arrow, as you can see, player is dead and still have the stun:

So something is missing somewhere because the stun isn't removed when player dies. Default Stun(); function removing the stun.

It looks like the ClearAffect(true); or REMOVE_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_STUN); doesn't work in Dead(); function. I don't really know.

Edited by ReFresh

I'll be always helpful! 👊 

Link to comment
Share on other sites

  • 0
  • Premium

@Abel(Tiger) You are the real god of solving things in C++. Thanks so much, you always solve it so simply. I love it. ❤️ 

I removed these things too and it works without it to all affects correctly too:

Spoiler
if (ch->IsDead()) { ch->RemoveFire(); }

if (ch->IsDead()) { ch->RemovePoison(); }

if (ch->IsDead()) { ch->RemoveBleed(); }

 

That was whole problem of affects when the target died. Thank you again!

Edited by ReFresh

I'll be always helpful! 👊 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

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.