Jump to content

HP REGEN BONUS AND ABOUT ITS FORMULA


Recommended Posts

hi everyone not a dev here but a player i had some questions about the formulas in the game such as critical hit chance and hp regen stuff and seems like no better place to ask to the devs right ? it would really help me a lot if you could post the formulas or just inform me about how it works

1: Critical Chance : Even tho if you get +%100 crti chance in game it doesnt translate it to the skills even tho it does work on regular hits does it scale differently from normal attacks or is it fixed chance  ?

2: HP REGEN : it seems even tho if you have hp regen it does not scale as the amount you have and does it just ignored if you have poison or bleed or just reduced 

 

thanks for your replies i would be so happy if you guys could inform me 

Link to comment
Share on other sites

  • Replies 2
  • Created
  • Last Reply

Top Posters In This Topic

  • Contributor

CRITICAL:

Spoiler
	if (type == DAMAGE_TYPE_MELEE || type == DAMAGE_TYPE_RANGE || type == DAMAGE_TYPE_MAGIC)
	{
		if (pAttacker)
		{
			// critical
			int iCriticalPct = pAttacker->GetPoint(POINT_CRITICAL_PCT);

			if (!IsPC())
				iCriticalPct += pAttacker->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_CRITICAL_BONUS);

			if (iCriticalPct)
			{
				if (iCriticalPct >= 10) // 5% + (increase by 1% for every 4) greater than 10, so 20% if number is 50
					iCriticalPct = 5 + (iCriticalPct - 10) / 4;
				else // If less than 10, simply cut in half, 10 = 5%
					iCriticalPct /= 2;

				//Critical resistance value applied.
				iCriticalPct -= GetPoint(POINT_RESIST_CRITICAL);

				if (number(1, 100) <= iCriticalPct)
				{
					IsCritical = true;
					dam *= 2;
					EffectPacket(SE_CRITICAL);

					if (IsAffectFlag(AFF_MANASHIELD))
					{
						RemoveAffect(AFF_MANASHIELD);
					}
				}
			}

			// penetrating attack
			int iPenetratePct = pAttacker->GetPoint(POINT_PENETRATE_PCT);

			if (!IsPC())
				iPenetratePct += pAttacker->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_PENETRATE_BONUS);


			if (iPenetratePct)
			{
				{
					CSkillProto* pkSk = CSkillManager::instance().Get(SKILL_RESIST_PENETRATE);

					if (NULL != pkSk)
					{
						pkSk->SetPointVar("k", 1.0f * GetSkillPower(SKILL_RESIST_PENETRATE) / 100.0f);

						iPenetratePct -= static_cast<int>(pkSk->kPointPoly.Eval());
					}
				}

				if (iPenetratePct >= 10)
				{
					// 5% + (increase by 1% for every 4) greater than 10, so 20% if number is 50
					iPenetratePct = 5 + (iPenetratePct - 10) / 4;
				}
				else
				{
					// If less than 10, simply cut in half, 10 = 5%
					iPenetratePct /= 2;
				}

				//Apply the penetrating strike resistance value.
				iPenetratePct -= GetPoint(POINT_RESIST_PENETRATE);

				if (number(1, 100) <= iPenetratePct)
				{
					IsPenetrate = true;

					if (test_server)
						ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Additional Stabbing Weapon Damage %d"), GetPoint(POINT_DEF_GRADE) * (100 + GetPoint(POINT_DEF_BONUS)) / 100);

					dam += GetPoint(POINT_DEF_GRADE) * (100 + GetPoint(POINT_DEF_BONUS)) / 100;

					if (IsAffectFlag(AFF_MANASHIELD))
					{
						RemoveAffect(AFF_MANASHIELD);
					}
				}
			}
		}
	}
		//
		// simplified
		//
		if (pAttacker)
		{
			// simplified

			// critical
			int iCriticalPct = pAttacker->GetPoint(POINT_CRITICAL_PCT);

			if (!IsPC())
				iCriticalPct += pAttacker->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_CRITICAL_BONUS);

			if (iCriticalPct)
			{
				//Apply the critical resistance value.
				iCriticalPct -= GetPoint(POINT_RESIST_CRITICAL);

				if (number(1, 100) <= iCriticalPct)
				{
					IsCritical = true;
					dam *= 2;
					EffectPacket(SE_CRITICAL);
				}
			}

			// penetration attack
			int iPenetratePct = pAttacker->GetPoint(POINT_PENETRATE_PCT);

			if (!IsPC())
				iPenetratePct += pAttacker->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_PENETRATE_BONUS);

			{
				CSkillProto* pkSk = CSkillManager::instance().Get(SKILL_RESIST_PENETRATE);

				if (NULL != pkSk)
				{
					pkSk->SetPointVar("k", 1.0f * GetSkillPower(SKILL_RESIST_PENETRATE) / 100.0f);

					iPenetratePct -= static_cast<int>(pkSk->kPointPoly.Eval());
				}
			}


			if (iPenetratePct)
			{

				//Apply the penetrating hit resistance value.
				iPenetratePct -= GetPoint(POINT_RESIST_PENETRATE);

				if (number(1, 100) <= iPenetratePct)
				{
					IsPenetrate = true;

					if (test_server)
						ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Additional Stabbing Weapon Damage %d"), GetPoint(POINT_DEF_GRADE) * (100 + GetPoint(POINT_DEF_BONUS)) / 100);
					dam += GetPoint(POINT_DEF_GRADE) * (100 + GetPoint(POINT_DEF_BONUS)) / 100;
				}
			}

 

where you see // simplified  it means I deleted code that wasn't related to critical calc

What you need to know, without reading the code(same for penetration)

if your critical chance is equal or over 10, then

criticalChance = 5 + (iCriticalPct - 10) / 4

if the chance is less than 10, then cut it in half

criticalChance = criticalPct/2

 

REGEN:

Spoiler
	{
		//
		// PC recovery
		//
		ch->CheckTarget();
		//ch->UpdateSectree(); // Why are we doing this here?
		ch->UpdateKillerMode();

		if (ch->IsAffectFlag(AFF_POISON))
		{
			// Prohibit automatic recovery in case of poisoning
			// In the case of divination, auto-recovery is prohibited
			return 3;
		}

		int iSec = (get_dword_time() - ch->GetLastMoveTime()) / 3000;

		// SP recovery routine.
		// Why did you leave this out as a function?!
		ch->DistributeSP(ch);

		if (ch->GetMaxHP() <= ch->GetHP())
			return PASSES_PER_SEC(3);

		int iPercent = 0;
		int iAmount = 0;

		{
			iPercent = aiRecoveryPercents[MIN(9, iSec)];
			iAmount = 15 + (ch->GetMaxHP() * iPercent) / 100;
		}

		iAmount += (iAmount * ch->GetPoint(POINT_HP_REGEN)) / 100;

		sys_log(1, "RECOVERY_EVENT: %s %d HP_REGEN %d HP +%d", ch->GetName(), iPercent, ch->GetPoint(POINT_HP_REGEN), iAmount);

		ch->PointChange(POINT_HP, iAmount, false);
		return PASSES_PER_SEC(3);
	}

 

The english parts are just translated from korean with google translate, so you can ignore them

The idea is:

HP Regen is disabled while poisoned.

If you're not poisoned, you'll regen every 3 seconds.

The important parts:

const int aiRecoveryPercents[10] = { 1, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
int iSec = (get_dword_time() - ch->GetLastMoveTime()) / 3000;
		{
			iPercent = aiRecoveryPercents[MIN(9, iSec)];
			iAmount = 15 + (ch->GetMaxHP() * iPercent) / 100;
		}

		iAmount += (iAmount * ch->GetPoint(POINT_HP_REGEN)) / 100;

Assuming your iPercent returns 5, with a max hp of 30k and 60% regen(from helmet and necklace) we'll get this:

15 + (30.000 * 5) / 100 = 1515

The amount of hp recovered will be of (1515 * 60) / 100 = 909 every 3 seconds

 

Hope it helps

Link to comment
Share on other sites

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.