コード例 #1
0
bool CShieldClass::GetReferenceDamageAdj (const CItem *pItem, CSpaceObject *pInstalled, int *retiHP, int *retArray) const

//	GetReferenceDamageAdj
//
//	Returns an array of damage adj values

	{
	CItemCtx Ctx(pItem, pInstalled);
	int i;

	const CItemEnhancement &Mods = Ctx.GetMods();

	int iMinHP, iMaxHP;
	CalcMinMaxHP(Ctx, m_iMaxCharges, 0, 0, &iMinHP, &iMaxHP);

	if (retiHP)
		*retiHP = iMaxHP;

	if (retArray)
		{
		for (i = 0; i < damageCount; i++)
			{
			DamageDesc Damage((DamageTypes)i, DiceRange(0, 0, 0));
			int iAdj = GetDamageAdj(Mods, Damage);
			if (iAdj == 0)
				retArray[i] = -1;
			else
				retArray[i] = (int)((iMaxHP * 100.0 / iAdj) + 0.5);
			}
		}

	return true;
	}
コード例 #2
0
int CArmorClass::CalcAverageRelativeDamageAdj (void)

//	CalcAverageRelativeDamageAdj
//
//	Compares this armor against standard damage adj for the level and returns
//	the average damage adj relative to the standard.

	{
	int i;
	Metric rTotalAdj = 0.0;
	int iCount = 0;
	int iArmorLevel = m_pItemType->GetLevel();

	for (i = damageLaser; i < damageCount; i++)
		{
		//	If this damage type is within two levels of the armor level,
		//	then we include it in our calculations.

		int iDamageLevel = ::GetDamageTypeLevel((DamageTypes)i);
		if (iArmorLevel < iDamageLevel + 5
				&& iArmorLevel > iDamageLevel - 3)
			{
			int iStdAdj = GetStdDamageAdj(iArmorLevel, (DamageTypes)i);
			int iDamageAdj = GetDamageAdj((DamageTypes)i);

			rTotalAdj += (iStdAdj > 0.0 ? (Metric)iDamageAdj * 100.0 / iStdAdj : 1000.0);
			iCount++;
			}
		}

	//	Return average

	return (iCount > 0 ? (int)((rTotalAdj / iCount) + 0.5) : 100);
	}
コード例 #3
0
void CArmorClass::CalcAdjustedDamage (CItemCtx &ItemCtx, SDamageCtx &Ctx)

//	CalcAdjustedDamage
//
//	Modifies Ctx.iDamage to account for damage type adjustments, etc.

	{
	CInstalledArmor *pArmor = ItemCtx.GetArmor();

	//	Adjust for special armor damage:
	//
	//	<0	=	2.5x damage
	//	0	=	2x damage
	//	1	=	1.5x damage
	//	2	=	1.25x damage
	//	>2	=	1x damage

	int iDamageLevel = Ctx.Damage.GetArmorDamageLevel();
	if (iDamageLevel > 0)
		Ctx.iDamage = (CalcArmorDamageAdj(Ctx.Damage) * Ctx.iDamage + 50) / 100;

	//	Adjust for damage type

	int iDamageAdj = GetDamageAdj((pArmor ? pArmor->GetMods() : CItemEnhancement()), Ctx.Damage);
	Ctx.iDamage = (iDamageAdj * Ctx.iDamage + 50) / 100;
	}
コード例 #4
0
bool CArmorClass::GetReferenceDamageAdj (const CItem *pItem, CSpaceObject *pInstalled, int *retiHP, int *retArray)

//	GetReferenceDamageAdj
//
//	Returns armor HP after adjustment for damage type

	{
	int i;

	CItemCtx ItemCtx(pItem, pInstalled);
	int iHP = GetMaxHP(ItemCtx);

	if (retiHP)
		*retiHP = iHP;

	for (i = 0; i < damageCount; i++)
		{
		DamageDesc Damage((DamageTypes)i, DiceRange(0, 0, 0));
		int iAdj = GetDamageAdj(ItemCtx.GetMods(), Damage);

		if (retArray)
			retArray[i] = CalcHPDamageAdj(iHP, iAdj);
		}

	return true;
	}
コード例 #5
0
ファイル: CArmorClass.cpp プロジェクト: dogguts/Transcendence
void CArmorClass::CalcAdjustedDamage (CItemCtx &ItemCtx, SDamageCtx &Ctx)

//	CalcAdjustedDamage
//
//	Modifies Ctx.iDamage to account for damage type adjustments, etc.

	{
	CInstalledArmor *pArmor = ItemCtx.GetArmor();

	//	Adjust for special armor damage:
	//
	//	<0	=	2.5x damage
	//	0	=	2x damage
	//	1	=	1.5x damage
	//	2	=	1.25x damage
	//	>2	=	1x damage

	int iDamageLevel = Ctx.Damage.GetArmorDamageLevel();
	if (iDamageLevel > 0)
		{
		int iDiff = m_pItemType->GetLevel() - iDamageLevel;
		int iAdj;

		switch (iDiff)
			{
			case 0:
				iAdj = 200;
				break;

			case 1:
				iAdj = 150;
				break;

			case 2:
				iAdj = 125;
				break;

			default:
				if (iDiff < 0)
					iAdj = 250;
				else
					iAdj = 100;
			}

		Ctx.iDamage = (iAdj * Ctx.iDamage + 50) / 100;
		}

	//	Adjust for damage type

	int iDamageAdj = GetDamageAdj((pArmor ? pArmor->GetMods() : CItemEnhancement()), Ctx.Damage);
	Ctx.iDamage = (iDamageAdj * Ctx.iDamage + 50) / 100;
	}
コード例 #6
0
ファイル: CArmorClass.cpp プロジェクト: dogguts/Transcendence
int CArmorClass::GetDamageAdj (CItemEnhancement Mods, const DamageDesc &Damage)

//	GetDamageAdj
//
//	Returns the damage adjustment for the given damage type

	{
	int iDamageAdj = GetDamageAdj(Damage.GetDamageType());

	if (Mods.IsNotEmpty())
		return iDamageAdj * Mods.GetDamageAdj(Damage) / 100;
	else
		return iDamageAdj;
	}
コード例 #7
0
ファイル: CArmorClass.cpp プロジェクト: dogguts/Transcendence
int CArmorClass::GetDamageAdjForWeaponLevel (int iLevel)

//	GetDamageAdjForWeaponLevel
//
//	Returns the least effective damage adjustment of all damage types appropriate
//	to the given level.

	{
	int i;

	int iBestAdj = 0;
	for (i = 0; i < damageCount; i++)
		{
		if (CWeaponClass::IsStdDamageType((DamageTypes)i, iLevel))
			{
			int iDamageAdj = GetDamageAdj((DamageTypes)i);
			if (iDamageAdj > iBestAdj)
				iBestAdj = iDamageAdj;
			}
		}

	return iBestAdj;
	}
コード例 #8
0
bool CShieldClass::AbsorbDamage (CInstalledDevice *pDevice, CSpaceObject *pShip, SDamageCtx &Ctx)

//	AbsorbDamage
//
//	Absorbs damage.
//	NOTE: We always set Ctx.iAbsorb properly, regardless of the return value.

	{
	DEBUG_TRY

	//	If we're depleted then we cannot absorb anything

	Ctx.iHPLeft = GetHPLeft(pDevice, pShip);
	if (Ctx.iHPLeft == 0)
		{
		Ctx.iAbsorb = 0;
		return false;
		}

	//	Calculate how much we will absorb

	int iAbsorbAdj = (Ctx.Damage.GetDamageType() == damageGeneric ? 100 : m_iAbsorbAdj[Ctx.Damage.GetDamageType()]);
	Ctx.iAbsorb = (Ctx.iDamage * iAbsorbAdj) / 100;
	if (pDevice->GetMods().IsNotEmpty())
		Ctx.iAbsorb = Ctx.iAbsorb * pDevice->GetMods().GetAbsorbAdj(Ctx.Damage) / 100;

	//	Compute how much damage we take (based on the type of damage)

	int iAdj = GetDamageAdj(pDevice->GetMods(), Ctx.Damage);
	Ctx.iShieldDamage = (Ctx.iAbsorb * iAdj) / 100;

	//	If shield generator is damaged then sometimes we take extra damage

	if (pDevice->IsDamaged() || pDevice->IsDisrupted())
		{
		int iRoll = mathRandom(1, 100);

		if (iRoll <= 10)
			Ctx.iAbsorb = 75 * Ctx.iAbsorb / 100;
		else if (iRoll <= 25)
			Ctx.iShieldDamage *= 2;
		}

	//	If the amount of shield damage is greater than HP left, then scale
	//	the amount of HP that we aborb

	if (Ctx.iShieldDamage > Ctx.iHPLeft)
		{
		//	ASSERT: We know that iShieldDamage is > 0 because iHPLeft is > 0.

		Ctx.iAbsorb = Ctx.iHPLeft * Ctx.iAbsorb / Ctx.iShieldDamage;
		Ctx.iShieldDamage = Ctx.iHPLeft;
		}

	//	See if we're reflective

	int iReflectChance;
	if (!pDevice->GetMods().IsReflective(Ctx.Damage, &iReflectChance))
		iReflectChance = 0;
	if (m_Reflective.InSet(Ctx.Damage.GetDamageType()))
		iReflectChance = Max(iReflectChance, MAX_REFLECTION_CHANCE);
	if (iReflectChance 
			&& Ctx.pCause 
			&& Ctx.Damage.GetShieldDamageLevel() == 0)
		{
		//	Compute the chance that we will reflect (based on the strength of
		//	our shields)

		int iMaxHP = GetMaxHP(pDevice, pShip);
		int iEfficiency = (iMaxHP == 0 ? 100 : 50 + (Ctx.iHPLeft * 50 / iMaxHP));
		int iChance = iEfficiency * iReflectChance / 100;

		//	See if we reflect

		if (Ctx.bReflect = (mathRandom(1, 100) <= iChance))
			{
			Ctx.iOriginalAbsorb = Ctx.iAbsorb;
			Ctx.iOriginalShieldDamage = Ctx.iShieldDamage;
			Ctx.iAbsorb = Ctx.iDamage;
			Ctx.iShieldDamage = 0;
			}
		}
	else
		Ctx.bReflect = false;

	//	Give custom damage a chance to react. These events can modify the
	//	following variables:
	//
	//	Ctx.bReflect
	//	Ctx.iAbsorb
	//	Ctx.iShieldDamage
	//
	//	OR
	//
	//	Ctx.iDamage (if we skip further processing)

	if (Ctx.pDesc->FireOnDamageShields(Ctx, pDevice->GetDeviceSlot()))
		return (Ctx.iDamage == 0);

	FireOnShieldDamage(CItemCtx(pShip, pDevice), Ctx);

	//	If we reflect, then create the reflection

	if (Ctx.bReflect)
		Ctx.pCause->CreateReflection(Ctx.vHitPos, (Ctx.iDirection + 120 + mathRandom(0, 120)) % 360);

	//	Create shield effect

	if (Ctx.iAbsorb || Ctx.bReflect)
		{
		if (m_pHitEffect)
			m_pHitEffect->CreateEffect(pShip->GetSystem(),
					NULL,
					Ctx.vHitPos,
					pShip->GetVel(),
					Ctx.iDirection);
		}

	//	Shield takes damage

	if (Ctx.iShieldDamage > 0)
		{
		if (Ctx.iShieldDamage >= Ctx.iHPLeft)
			SetDepleted(pDevice, pShip);
		else
			SetHPLeft(pDevice, Ctx.iHPLeft - Ctx.iShieldDamage);

		pShip->OnComponentChanged(comShields);
		}

	//	Set the remaining damage

	Ctx.iDamage -= Ctx.iAbsorb;
	return (Ctx.iDamage == 0);

	DEBUG_CATCH
	}