Ejemplo n.º 1
0
int CItemEnhancement::GetDamageAdj (const DamageDesc &Damage) const

//	GetDamageAdj
//
//	Returns the damage adjustment confered by this mod

{
    switch (GetType())
    {
    case etResist:
        return Level2DamageAdj(GetLevel(), IsDisadvantage());

    case etResistEnergy:
        return (Damage.IsEnergyDamage() ? Level2DamageAdj(GetLevel(), IsDisadvantage()) : 100);

    case etResistMatter:
        return (Damage.IsMatterDamage() ? Level2DamageAdj(GetLevel(), IsDisadvantage()) : 100);

    case etResistByLevel:
    {
        if (Damage.GetDamageType() == GetDamageType()
                || Damage.GetDamageType() == GetDamageType() + 1)
            return Level2DamageAdj(GetLevel(), IsDisadvantage());
        else
            return 100;
    }

    case etResistByDamage:
        return (Damage.GetDamageType() == GetDamageType() ? Level2DamageAdj(GetLevel(), IsDisadvantage()) : 100);

    case etResistByDamage2:
    {
        if (Damage.GetDamageType() == GetDamageType())
            //	0 = 100			100
            //	1 = 90			111
            //	2 = 80			125
            //	3 = 70			143
            return Level2DamageAdj(GetLevel(), IsDisadvantage());
        else if (Damage.GetDamageType() == GetDamageType() + 2)
            //	0 = 100			100
            //	1 = 95			105
            //	2 = 90			112
            //	3 = 85			121
            return 100 + ((Level2DamageAdj(GetLevel(), IsDisadvantage()) - 100) / 2);
        else
            return 100;
    }

    default:
        return 100;
    }
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTFGrenadePipebombProjectile::PipebombTouch( CBaseEntity *pOther )
{
	if ( pOther == GetThrower() )
		return;

	// Verify a correct "other."
	if ( !pOther->IsSolid() || pOther->IsSolidFlagSet( FSOLID_VOLUME_CONTENTS ) )
		return;

	// Handle hitting skybox (disappear).
	trace_t pTrace;
	Vector velDir = GetAbsVelocity();
	VectorNormalize( velDir );
	Vector vecSpot = GetAbsOrigin() - velDir * 32;
	UTIL_TraceLine( vecSpot, vecSpot + velDir * 64, MASK_SOLID, this, COLLISION_GROUP_NONE, &pTrace );

	if ( pTrace.fraction < 1.0 && pTrace.surface.flags & SURF_SKY )
	{
		UTIL_Remove( this );
		return;
	}

	//If we already touched a surface then we're not exploding on contact anymore.
	if ( m_bTouched == true )
		return;

	// Blow up if we hit an enemy we can damage
	if ( pOther->GetTeamNumber() && pOther->GetTeamNumber() != GetTeamNumber() && pOther->m_takedamage != DAMAGE_NO )
	{
		// Check to see if this is a respawn room.
		if ( !pOther->IsPlayer() )
		{
			CFuncRespawnRoom *pRespawnRoom = dynamic_cast<CFuncRespawnRoom*>( pOther );
			if ( pRespawnRoom )
			{
				if ( !pRespawnRoom->PointIsWithin( GetAbsOrigin() ) )
					return;
			}
		}

		// Restore damage. See comment in CTFGrenadePipebombProjectile::Create() above to understand this.
		m_flDamage = m_flFullDamage;
		Explode( &pTrace, GetDamageType() );
	}

	// Train hack!
	if ( pOther->GetModelName() == s_iszTrainName && ( pOther->GetAbsVelocity().LengthSqr() > 1.0f ) )
	{
		Explode( &pTrace, GetDamageType() );
	}
}
//-----------------------------------------------------------------------------
// Purpose: Try and find an entity to lock onto
//-----------------------------------------------------------------------------
CBaseEntity *CWeaponCombat_ChargeablePlasma::GetLockTarget( void )
{
	CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)GetOwner();
	if ( !pPlayer )
		return NULL;

	Vector vecSrc = pPlayer->Weapon_ShootPosition( );
	Vector vecAiming;
	pPlayer->EyeVectors( &vecAiming );
	Vector vecEnd = vecSrc + vecAiming * MAX_TRACE_LENGTH;

	trace_t tr;
	TFGameRules()->WeaponTraceLine( vecSrc, vecEnd, MASK_SHOT, pPlayer, GetDamageType(), &tr );

	if ( (tr.fraction < 1.0f) && tr.m_pEnt )
	{
		CBaseEntity *pTargetEntity = tr.m_pEnt;

		// Don't guide on same team or on anything other than players, objects, and NPCs
		if ( pTargetEntity->InSameTeam(pPlayer) || (!pTargetEntity->IsPlayer() 
			&& (pTargetEntity->MyNPCPointer() == NULL)) )
			return NULL;

		// Compute the target offset relative to the target
		Vector vecWorldOffset;
		VectorSubtract( tr.endpos, pTargetEntity->GetAbsOrigin(), vecWorldOffset );
		VectorIRotate( vecWorldOffset, pTargetEntity->EntityToWorldTransform(), m_vecTargetOffset ); 
		m_flLockedAt = gpGlobals->curtime + 0.2;
		return pTargetEntity;
	}

	return NULL;
}
Ejemplo n.º 4
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CBaseProjectile::ProjectileTouch( CBaseEntity *pOther )
{
	// Verify a correct "other."
	Assert( pOther );
	if ( !pOther->IsSolid() || pOther->IsSolidFlagSet( FSOLID_VOLUME_CONTENTS ) )
		return;

	// Handle hitting skybox (disappear).
	const trace_t *pTrace = &CBaseEntity::GetTouchTrace();
	trace_t *pNewTrace = const_cast<trace_t*>( pTrace );

	if( pTrace->surface.flags & SURF_SKY )
	{
		UTIL_Remove( this );
		return;
	}

	CTakeDamageInfo info;
	info.SetAttacker( GetOwnerEntity() );
	info.SetInflictor( this );
	info.SetDamage( GetDamage() );
	info.SetDamageType( GetDamageType() );
	CalculateMeleeDamageForce( &info, GetAbsVelocity(), GetAbsOrigin(), GetDamageScale() );

	Vector dir;
	AngleVectors( GetAbsAngles(), &dir );

	pOther->DispatchTraceAttack( info, dir, pNewTrace );
	ApplyMultiDamage();

	UTIL_Remove( this );
}
Ejemplo n.º 5
0
bool CItemEnhancement::IsReflective (const DamageDesc &Damage, int *retiReflectChance) const

//	IsReflective
//
//	Returns TRUE if we reflect the given damage

{
    switch (GetType())
    {
    case etReflect:
    {
        if (!IsDisadvantage() && Damage.GetDamageType() == GetDamageType())
        {
            if (retiReflectChance)
                *retiReflectChance = 50 + (GetLevel() * 5);

            return true;
        }
        else
            return false;
    }

    default:
        return false;
    }
}
Ejemplo n.º 6
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTFBaseRocket::Explode( trace_t *pTrace, CBaseEntity *pOther )
{
	// Save this entity as enemy, they will take 100% damage.
	m_hEnemy = pOther;

	// Invisible.
	SetModelName( NULL_STRING );
	AddSolidFlags( FSOLID_NOT_SOLID );
	m_takedamage = DAMAGE_NO;

	// Pull out a bit.
	if ( pTrace->fraction != 1.0 )
	{
		SetAbsOrigin( pTrace->endpos + ( pTrace->plane.normal * 1.0f ) );
	}

	// Play explosion sound and effect.
	Vector vecOrigin = GetAbsOrigin();
	CPVSFilter filter( vecOrigin );
	TE_TFExplosion( filter, 0.0f, vecOrigin, pTrace->plane.normal, GetWeaponID(), pOther->entindex() );
	CSoundEnt::InsertSound ( SOUND_COMBAT, vecOrigin, 1024, 3.0 );

	// Damage.
	CBaseEntity *pAttacker = GetOwnerEntity();
	IScorer *pScorerInterface = dynamic_cast<IScorer*>( pAttacker );
	if ( pScorerInterface )
	{
		pAttacker = pScorerInterface->GetScorer();
	}

	CTakeDamageInfo info( this, pAttacker, vec3_origin, vecOrigin, GetDamage(), GetDamageType() );
	float flRadius = GetRadius();
	RadiusDamage( info, vecOrigin, flRadius, CLASS_NONE, NULL );

	// Debug!
	if ( tf_rocket_show_radius.GetBool() )
	{
		DrawRadius( flRadius );
	}

	// Don't decal players with scorch.
	if ( !pOther->IsPlayer() )
	{
		UTIL_DecalTrace( pTrace, "Scorch" );
	}

	// Remove the rocket.
	UTIL_Remove( this );
}
Ejemplo n.º 7
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTFWeaponBaseGrenadeProj::Detonate( void )
{
	trace_t		tr;
	Vector		vecSpot;// trace starts here!

	SetThink( NULL );

	vecSpot = GetAbsOrigin() + Vector ( 0 , 0 , 8 );
	UTIL_TraceLine ( vecSpot, vecSpot + Vector ( 0, 0, -32 ), MASK_SHOT_HULL, this, COLLISION_GROUP_NONE, & tr);

	Explode( &tr, GetDamageType() );

	if ( GetShakeAmplitude() )
	{
		UTIL_ScreenShake( GetAbsOrigin(), GetShakeAmplitude(), 150.0, 1.0, GetShakeRadius(), SHAKE_START );
	}
}
//-----------------------------------------------------------------------------
// Purpose: Sap the health from the object I'm attached to
//-----------------------------------------------------------------------------
void CGrenadeObjectSapper::SapperThink( void )
{
	SetNextThink( gpGlobals->curtime + 0.1f );

	// Not armed yet?
	if ( !GetArmed() )
		return;

	// Remove myself if I'm armed, but don't have an object to sap
	if ( !m_hTargetObject )
	{
		UTIL_Remove( this );
		return;
	}

	m_bSapping = true;

	// Damage our target (add DMG_CRUSH to prevent physics damage)
	m_hTargetObject->TakeDamage( CTakeDamageInfo( this, GetOwnerEntity(), GetDamage(), GetDamageType() | DMG_CRUSH ) );
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CBasePlasmaProjectile::MissileTouch( CBaseEntity *pOther )
{
	Assert( pOther );
	if ( !pOther->IsSolid() )
		return;

	// Create a plasma effect
	trace_t	tr;
	Vector velDir = GetAbsVelocity();
	VectorNormalize( velDir );
	Vector vecSpot = GetLocalOrigin() - velDir * 32;

	// First, just clip to the box
	Ray_t ray;
	ray.Init( vecSpot, vecSpot + velDir * 64 );
	enginetrace->ClipRayToEntity( ray, MASK_SHOT, pOther, &tr );

	// Create the appropriate impact
	bool bHurtTarget = ( !InSameTeam( pOther ) && pOther->m_takedamage != DAMAGE_NO );
	WeaponImpact( &tr, velDir, bHurtTarget, pOther, GetDamageType() );

#if !defined( CLIENT_DLL )
	CBaseEntity *pOwner = m_hOwner;

	// Do damage (unless I'm explosive, in which case I'll do damage later)
	if ( m_flDamage && !m_flExplosiveRadius )
	{
		ClearMultiDamage();
		// Assume it's a projectile, so use its velocity instead
		Vector vecDamageOrigin = GetAbsVelocity();
		VectorNormalize( vecDamageOrigin );
		vecDamageOrigin = GetAbsOrigin() - (vecDamageOrigin * 32);
		CTakeDamageInfo info( this, pOwner, m_flDamage, m_DamageType );
		CalculateBulletDamageForce( &info, GetAmmoDef()->Index("MediumRound"), GetAbsVelocity(), vecDamageOrigin );
		pOther->DispatchTraceAttack( info, velDir, &tr );
		ApplyMultiDamage();
	}
#endif

	Detonate();
}
Ejemplo n.º 10
0
int CItemEnhancement::GetAbsorbAdj (const DamageDesc &Damage) const

//	GetAbsorbAdj
//
//	Returns damage absorbed

{
    switch (GetType())
    {
    case etReflect:
    {
        if (IsDisadvantage() && Damage.GetDamageType() == GetDamageType())
            return Level2DamageAdj(GetLevel());
        else
            return 100;
    }

    default:
        return 100;
    }
}
Ejemplo n.º 11
0
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFBaseRocket::Explode( trace_t *pTrace, CBaseEntity *pOther )
{
    // Save this entity as enemy, they will take 100% damage.
    m_hEnemy = pOther;

    // Invisible.
    SetModelName( NULL_STRING );
    AddSolidFlags( FSOLID_NOT_SOLID );
    m_takedamage = DAMAGE_NO;

    // Figure out Econ ID.
    int iItemID = -1;
    if ( m_hLauncher.Get() )
    {
        CTFWeaponBase *pWeapon = dynamic_cast<CTFWeaponBase *>( m_hLauncher.Get() );
        if ( pWeapon )
        {
            iItemID = pWeapon->GetItemID();
        }
    }

    // Pull out a bit.
    if ( pTrace->fraction != 1.0 )
    {
        SetAbsOrigin( pTrace->endpos + ( pTrace->plane.normal * 1.0f ) );
    }

    CBaseEntity *pAttacker = GetOwnerEntity();
    IScorer *pScorerInterface = dynamic_cast<IScorer*>( pAttacker );
    if ( pScorerInterface )
    {
        pAttacker = pScorerInterface->GetScorer();
    }

    // Play explosion sound and effect.
    Vector vecOrigin = GetAbsOrigin();
    CPVSFilter filter( vecOrigin );
    bool bCrit = ( GetDamageType() & DMG_CRITICAL ) != 0;
    TE_TFExplosion( filter, 0.0f, vecOrigin, pTrace->plane.normal, GetWeaponID(), pOther->entindex(), ToBasePlayer( pAttacker ), GetTeamNumber(), bCrit, iItemID );
    CSoundEnt::InsertSound( SOUND_COMBAT, vecOrigin, 1024, 3.0 );

    // Damage.
    float flRadius = GetRadius();

    CTFRadiusDamageInfo radiusInfo;
    radiusInfo.info.Set( this, pAttacker, m_hLauncher, vec3_origin, vecOrigin, GetDamage(), GetDamageType() );
    radiusInfo.m_vecSrc = vecOrigin;
    radiusInfo.m_flRadius = flRadius;
    radiusInfo.m_flSelfDamageRadius = 121.0f; // Original rocket radius?

    TFGameRules()->RadiusDamage( radiusInfo );

    // Debug!
    if ( tf_rocket_show_radius.GetBool() )
    {
        DrawRadius( flRadius );
    }

    // Don't decal players with scorch.
    if ( !pOther->IsPlayer() )
    {
        UTIL_DecalTrace( pTrace, "Scorch" );
    }

    // Remove the rocket.
    UTIL_Remove( this );
}
Ejemplo n.º 12
0
CString CItemEnhancement::GetEnhancedDesc (const CItem &Item, CSpaceObject *pInstalled, CInstalledDevice *pDevice) const

//	GetEnhancedDesc
//
//	Get short description of enhancement.
//
//	NOTE: This currently include bonuses confered by other ship systems (stored in
//	the device structure. In the future we need a better mechanism)

{
    CItemEnhancementStack *pAllEnhancements = (pDevice ? pDevice->GetEnhancements() : NULL);

    switch (GetType())
    {
    case etHPBonus:
    case etStrengthen:
    {
        switch (Item.GetType()->GetCategory())
        {
        case itemcatWeapon:
        case itemcatLauncher:
        case itemcatShields:
        {
            int iDamageBonus;

            //	See if this device is installed; if so, then the bonus is
            //	calculated and cached in the device; we do this so that we can
            //	include bonuses from all sources.

            if (pAllEnhancements)
                iDamageBonus = pAllEnhancements->GetBonus();
            else
                iDamageBonus = GetHPBonus();

            //	Bonus

            if (iDamageBonus < 0)
                return strPatternSubst(CONSTLIT("%d%%"), iDamageBonus);
            else
                return strPatternSubst(CONSTLIT("+%d%%"), iDamageBonus);
        }

        default:
            if (IsDisadvantage())
                return strPatternSubst(CONSTLIT("-%d%%"), 100 - GetHPAdj());
            else
                return strPatternSubst(CONSTLIT("+%d%%"), GetHPAdj() - 100);
        }
    }

    case etRegenerate:
        return (IsDisadvantage() ? CONSTLIT("-Decay") : CONSTLIT("+Regen"));

    case etReflect:
        return strPatternSubst((IsDisadvantage() ? CONSTLIT("-%s Trans") : CONSTLIT("+%s Reflect")),
                               strCapitalizeWords(::GetDamageShortName(GetDamageType())));

    case etRepairOnHit:
        return strPatternSubst(CONSTLIT("+%s Repair"), strCapitalizeWords(::GetDamageShortName(GetDamageType())));

    case etResist:
        return (IsDisadvantage() ? CONSTLIT("-Vulnerable") : CONSTLIT("+Resistant"));

    case etResistEnergy:
        return (IsDisadvantage() ? CONSTLIT("-Energy Vulnerable") : CONSTLIT("+Energy Resistant"));

    case etResistMatter:
        return (IsDisadvantage() ? CONSTLIT("-Matter Vulnerable") : CONSTLIT("+Matter Resistant"));

    case etResistByLevel:
    {
        if (IsDisadvantage())
            return strPatternSubst(CONSTLIT("-%s -%s"), strCapitalizeWords(::GetDamageShortName(GetDamageType())), strCapitalizeWords(::GetDamageShortName((DamageTypes)(GetDamageType() + 1))));
        else
            return strPatternSubst(CONSTLIT("+%s +%s"), strCapitalizeWords(::GetDamageShortName(GetDamageType())), strCapitalizeWords(::GetDamageShortName((DamageTypes)(GetDamageType() + 1))));
    }

    case etResistByDamage:
        return strPatternSubst((IsDisadvantage() ? CONSTLIT("-%s") : CONSTLIT("+%s")),
                               strCapitalizeWords(::GetDamageShortName(GetDamageType())));

    case etResistByDamage2:
    {
        if (IsDisadvantage())
            return strPatternSubst(CONSTLIT("-%s -%s"), strCapitalizeWords(::GetDamageShortName(GetDamageType())), strCapitalizeWords(::GetDamageShortName((DamageTypes)(GetDamageType() + 2))));
        else
        {
            switch (GetDamageType())
            {
            case damageLaser:
                return CONSTLIT("+Ablative");

            case damageKinetic:
                return CONSTLIT("+Reactive");

            default:
                return strPatternSubst(CONSTLIT("+%s +%s"),
                                       strCapitalizeWords(::GetDamageShortName(GetDamageType())),
                                       strCapitalizeWords(::GetDamageShortName((DamageTypes)(GetDamageType() + 2))));
            }
        }
    }

    case etSpecialDamage:
    {
        switch (GetLevel2())
        {
        case specialRadiation:
            return CONSTLIT("+Rad Immune");

        case specialBlinding:
            return CONSTLIT("+Blind Immune");

        case specialEMP:
            return CONSTLIT("+EMP Immune");

        case specialDeviceDamage:
            return CONSTLIT("+Dev Protect");

        case specialDisintegration:
            return CONSTLIT("+Dis Immune");

        default:
            return CONSTLIT("+Unk Immune");
        }
    }

    case etImmunityIonEffects:
        return (IsDisadvantage() ? CONSTLIT("-No Shields") : CONSTLIT("+Ionization Immune"));

    case etPhotoRegenerate:
        return CONSTLIT("+SolRegen");

    case etPhotoRecharge:
        return CONSTLIT("+SolPower");

    case etPowerEfficiency:
        return (IsDisadvantage() ? CONSTLIT("-Drain") : CONSTLIT("+Efficient"));

    case etSpeed:
    case etSpeedOld:
        return (IsDisadvantage() ? CONSTLIT("-Slow") : CONSTLIT("+Fast"));

    default:
        return CONSTLIT("+Unknown");
    }
}
Ejemplo n.º 13
0
EnhanceItemStatus CItemEnhancement::Combine (const CItem &Item, CItemEnhancement Enhancement)

//	Combine
//
//	Combine the current enhancement with the given one

{
    DWORD dwNewMods = Enhancement.m_dwMods;

    //	If we're losing the enhancement, then clear it

    if (dwNewMods == etLoseEnhancement)
    {
        if (IsEnhancement())
        {
            *this = CItemEnhancement();
            return eisEnhancementRemoved;
        }
        else
            return eisNoEffect;
    }

    //	If the item is not currently enhanced, then we take the new enhancement

    else if (m_dwMods == etNone)
    {
        //	For strength/hpBonus, use the following rules:
        //
        //	etStrengthen 0 -> Min(10%, maxHPBonus)
        //	etStrengthen {level} -> Min( {level} * 10, maxHPBonus )

        if (Enhancement.GetType() == etStrengthen
                || Enhancement.GetType() == etHPBonus)
        {
            int iMaxBonus = Item.GetType()->GetMaxHPBonus();
            int iNewBonus = Min((Enhancement.IsStacking() ? 10 : Enhancement.GetHPBonus()), iMaxBonus);
            if (iNewBonus > 0)
            {
                SetModBonus(iNewBonus);
                return eisOK;
            }
            else
                return eisNoEffect;
        }

        //	For all others, take the enhancement

        else
            *this = Enhancement;

        return eisOK;
    }

    //	If already enhanced

    else if (m_dwMods == dwNewMods)
    {
        if (IsDisadvantage())
            return eisNoEffect;
        else
            return eisAlreadyEnhanced;
    }

    //	We currently have a disadvantage

    else if (IsDisadvantage())
    {
        //	We have a disadvantage and the enhancement is another
        //	disadvantage.

        if (Enhancement.IsDisadvantage())
        {
            switch (Enhancement.GetType())
            {
            //	If we're making the disadvantage worse, then
            //	continue; otherwise, no effect.

            case etRegenerate:
            case etResist:
            case etResistEnergy:
            case etResistMatter:
            case etPowerEfficiency:
            {
                if (Enhancement.GetType() == GetType()
                        && Enhancement.GetLevel() > GetLevel())
                {
                    *this = Enhancement;
                    return eisWorse;
                }
                else
                    return eisNoEffect;
            }

            case etHPBonus:
            case etStrengthen:
            {
                if ((GetType() == etHPBonus || GetType() == etStrengthen)
                        && Enhancement.GetHPBonus() < GetHPBonus())
                {
                    *this = Enhancement;
                    return eisWorse;
                }
                else
                    return eisNoEffect;
            }

            case etSpeed:
            case etSpeedOld:
            {
                if ((GetType() == etSpeed || GetType() == etSpeedOld)
                        && Enhancement.GetActivateRateAdj() > GetActivateRateAdj())
                {
                    *this = Enhancement;
                    return eisWorse;
                }
                else
                    return eisNoEffect;
            }

            case etResistByLevel:
            case etResistByDamage:
            case etResistByDamage2:
            {
                if (Enhancement.GetType() == GetType()
                        && Enhancement.GetDamageType() == GetDamageType()
                        && Enhancement.GetLevel() > GetLevel())
                {
                    *this = Enhancement;
                    return eisWorse;
                }
                else
                    return eisNoEffect;
            }

            //	Otherwise, a disadvantage does not affect a disadvantage

            default:
                return eisNoEffect;
            }
        }

        //	We have a disadvantage and we use an enhancement.

        else
        {
            switch (Enhancement.GetType())
            {
            //	Regeneration enhancement always repairs a disadvantage

            case etRegenerate:
            {
                *this = CItemEnhancement();
                return eisRepaired;
            }

            //	If the enhancement is the opposite of the disadvantage
            //	then the disadvantage is repaired.

            case etResist:
            case etResistEnergy:
            case etResistMatter:
            case etPowerEfficiency:
            case etResistByLevel:
            case etResistByDamage:
            case etResistByDamage2:
            case etReflect:
            {
                if (GetType() == Enhancement.GetType())
                {
                    *this = CItemEnhancement();
                    return eisRepaired;
                }
                else
                    return eisNoEffect;
            }

            case etHPBonus:
            case etStrengthen:
            {
                if (GetType() == etHPBonus || GetType() == etStrengthen)
                {
                    *this = CItemEnhancement();
                    return eisRepaired;
                }
                else
                    return eisNoEffect;
            }

            case etSpeed:
            case etSpeedOld:
            {
                if (GetType() == etSpeed || GetType() == etSpeedOld)
                {
                    *this = CItemEnhancement();
                    return eisRepaired;
                }
                else
                    return eisNoEffect;
            }

            //	Otherwise, no effect

            default:
                return eisNoEffect;
            }
        }
    }

    //	We currently have an enhancement

    else
    {
        if (!Enhancement.IsDisadvantage())
        {
            switch (Enhancement.GetType())
            {
            case etHPBonus:
            case etStrengthen:
            {
                if (GetType() != etHPBonus
                        && GetType() != etStrengthen)
                    return eisNoEffect;

                //	If improving...

                int iOldBonus = GetHPBonus();
                int iMaxBonus = Item.GetType()->GetMaxHPBonus();
                int iNewBonus = Min((Enhancement.IsStacking() ? iOldBonus + 10 : Enhancement.GetHPBonus()), iMaxBonus);
                if (iNewBonus > iOldBonus)
                {
                    SetModBonus(iNewBonus);
                    return eisBetter;
                }
                else
                    return eisNoEffect;
            }

            //	If this is the same type of enhancement and it is better,
            //	then take it (otherwise, no effect)

            case etRegenerate:
            case etResist:
            case etResistEnergy:
            case etResistMatter:
            case etPowerEfficiency:
            {
                if (Enhancement.GetType() == GetType()
                        && Enhancement.GetLevel() > GetLevel())
                {
                    *this = Enhancement;
                    return eisBetter;
                }
                else
                    return eisNoEffect;
            }

            case etSpeed:
            case etSpeedOld:
            {
                if (Enhancement.GetType() == GetType()
                        && Enhancement.GetActivateRateAdj() < GetActivateRateAdj())
                {
                    *this = Enhancement;
                    return eisBetter;
                }
                else
                    return eisNoEffect;
            }

            case etResistByLevel:
            case etResistByDamage:
            case etResistByDamage2:
            {
                if (Enhancement.GetType() != GetType())
                    return eisNoEffect;
                else if (Enhancement.GetDamageType() != GetDamageType())
                {
                    *this = Enhancement;
                    return eisEnhancementReplaced;
                }
                else if (Enhancement.GetLevel() > GetLevel())
                {
                    *this = Enhancement;
                    return eisBetter;
                }
                else
                    return eisNoEffect;
            }

            default:
                return eisNoEffect;
            }
        }
        else
        {
            //	A disadvantage always destroys any enhancement

            *this = CItemEnhancement();
            return eisEnhancementRemoved;
        }
    }
}
Ejemplo n.º 14
0
EnhanceItemStatus CItemEnhancement::Combine (CItemEnhancement Enhancement)

//	Combine
//
//	Combine the current enhancement with the given one

	{
	DWORD dwNewMods = Enhancement.m_dwMods;

	//	If we're losing the enhancement, then clear it

	if (dwNewMods == etLoseEnhancement)
		{
		if (IsEnhancement())
			{
			*this = CItemEnhancement();
			return eisEnhancementRemoved;
			}
		else
			return eisNoEffect;
		}

	//	If the item is not currently enhanced, then we take the new enhancement

	else if (m_dwMods == etNone)
		{
		//	For stackable strengthening, start at 1

		if (Enhancement.GetType() == etStrengthen
				&& Enhancement.GetLevel() == 0
				&& Enhancement.GetEnhancementType() == GetEnhancementType())
			m_dwMods = dwNewMods + 1;

		//	For all others, take the enhancement

		else
			*this = Enhancement;

		return eisOK;
		}

	//	If already enhanced

	else if (m_dwMods == dwNewMods)
		{
		if (IsDisadvantage())
			return eisNoEffect;
		else
			return eisAlreadyEnhanced;
		}

	//	We currently have a disadvantage

	else if (IsDisadvantage())
		{
		//	We have a disadvantage and the enhancement is another
		//	disadvantage.

		if (Enhancement.IsDisadvantage())
			{
			switch (Enhancement.GetType())
				{
				//	If we're making the disadvantage worse, then
				//	continue; otherwise, no effect.

				case etStrengthen:
				case etRegenerate:
				case etResist:
				case etResistEnergy:
				case etResistMatter:
				case etPowerEfficiency:
				case etSpeed:
					{
					if (Enhancement.GetType() == GetType()
							&& Enhancement.GetLevel() > GetLevel())
						{
						*this = Enhancement;
						return eisWorse;
						}
					else
						return eisNoEffect;
					}

				case etResistByLevel:
				case etResistByDamage:
				case etResistByDamage2:
					{
					if (Enhancement.GetType() == GetType()
							&& Enhancement.GetDamageType() == GetDamageType()
							&& Enhancement.GetLevel() > GetLevel())
						{
						*this = Enhancement;
						return eisWorse;
						}
					else
						return eisNoEffect;
					}

				//	Otherwise, a disadvantage does not affect a disadvantage

				default:
					return eisNoEffect;
				}
			}

		//	We have a disadvantage and we use an enhancement.

		else
			{
			switch (Enhancement.GetType())
				{
				//	Regeneration enhancement always repairs a disadvantage

				case etRegenerate:
					{
					*this = CItemEnhancement();
					return eisRepaired;
					}

				//	If the enhancement is the opposite of the disadvantage
				//	then the disadvantage is repaired.

				case etStrengthen:
				case etResist:
				case etResistEnergy:
				case etResistMatter:
				case etPowerEfficiency:
				case etResistByLevel:
				case etResistByDamage:
				case etResistByDamage2:
				case etReflect:
				case etSpeed:
					{
					if (GetType() == Enhancement.GetType())
						{
						*this = CItemEnhancement();
						return eisRepaired;
						}
					else
						return eisNoEffect;
					}

				//	Otherwise, no effect

				default:
					return eisNoEffect;
				}
			}
		}

	//	We currently have an enhancement

	else
		{
		if (!Enhancement.IsDisadvantage())
			{
			if (Enhancement.GetType() == GetType())
				{
				switch (Enhancement.GetType())
					{
					case etStrengthen:
						{
						//	If stackable...

						if (Enhancement.GetLevel() == 0)
							{
							if (GetLevel() == 15)
								return eisNoEffect;
							else
								{
								m_dwMods++;
								return eisBetter;
								}
							}

						//	If improving...

						else if (Enhancement.GetLevel() > GetLevel())
							{
							*this = Enhancement;
							return eisBetter;
							}
						else
							return eisNoEffect;
						}

					//	If this is the same type of enhancement and it is better,
					//	then take it (otherwise, no effect)

					case etRegenerate:
					case etResist:
					case etResistEnergy:
					case etResistMatter:
					case etPowerEfficiency:
					case etSpeed:
						{
						if (Enhancement.GetLevel() > GetLevel())
							{
							*this = Enhancement;
							return eisBetter;
							}
						else
							return eisNoEffect;
						}

					case etResistByLevel:
					case etResistByDamage:
					case etResistByDamage2:
						{
						if (Enhancement.GetDamageType() != GetDamageType())
							{
							*this = Enhancement;
							return eisEnhancementReplaced;
							}
						else if (Enhancement.GetLevel() > GetLevel())
							{
							*this = Enhancement;
							return eisBetter;
							}
						else
							return eisNoEffect;
						}

					default:
						return eisNoEffect;
					}
				}

			//	No effect if we're already enhanced

			else
				{
				return eisNoEffect;
				}
			}
		else
			{
			//	A disadvantage always destroys any enhancement

			*this = CItemEnhancement();
			return eisEnhancementRemoved;
			}
		}
	}