// Project Lab - NHTV Igad #include "UnrealProject.h" #include "NetworkCharacter.h" #include "NetworkPlayer.h" #include "NativeModifiers.h" #include "EffectFunctionLibrary.h" #include "Effect.h" #define standardTicksPerSecond 20 //SpeedModifier ASpeedModifier::ASpeedModifier() { } void ASpeedModifier::ModifyCharacter() { UCharacterMovementComponent* characterMovement = target->GetCharacterMovement(); characterMovement->MaxWalkSpeed *= speedMultiplier; } //RegenModifier ARegenModifier::ARegenModifier() { ticksPerSecond = 5; } bool ARegenModifier::ShouldBeRemoved() const { return false; } void ARegenModifier::ModifierTick() { if ( m_noDamageTime < target->GetTimeSinceDamage()) target->AddHealth(regenPerTick); } //RegenModier AManaRegenModifier::AManaRegenModifier() { ticksPerSecond = standardTicksPerSecond; } bool AManaRegenModifier::ShouldBeRemoved() const { return false; } void AManaRegenModifier::ModifierTick() { target->AddMana(regenPerTick); } //DOTModifier ADOTModifier::ADOTModifier() { ticksPerSecond = 3; } void ADOTModifier::ModifierTick() { if (IsValid(target)) target->DealDamage(this, damagePerTick, 0.0f); } //ADModifier AADModifier::AADModifier() { } void AADModifier::ModifyCharacter() { float add = ScaleGraphCurve(scalingGraph); m_MultiplyAttackDamage(add); } //ADModifier AAPModifier::AAPModifier() { } void AAPModifier::ModifyCharacter() { float add = ScaleGraphCurve(scalingGraph); m_AddMagicDamage(add); } //MaxHealthModifier AMaxHealthModifier::AMaxHealthModifier() { } void AMaxHealthModifier::ModifyCharacter() { //m_AddMaxHealth(bonusMaxHealth); float add = ScaleGraphCurve(scalingGraph); m_AddMaxHealth(add); } //AConstMaxHealthModifier AConstMaxHealthModifier::AConstMaxHealthModifier() { } void AConstMaxHealthModifier::ModifyCharacter() { m_AddMaxHealth(add); } //BlockManaModifier ABlockManaModifier::ABlockManaModifier() { } void ABlockManaModifier::ModifyCharacter() { m_AddBlockedMana(Mana); } //ManaPerSecModifier AManaDrainModifier::AManaDrainModifier() { ticksPerSecond = standardTicksPerSecond; } void AManaDrainModifier::ModifierTick() { if (ManaPerTick > target->GetMana()) { ModifierManager* mod = character->GetModifierManager(); if (mod != nullptr) mod->BroadcastManaDrainFailed(); } else { target->RemoveMana(ManaPerTick); } } //ManaPerSecModifier AManaDrainCurveModifier::AManaDrainCurveModifier() { ticksPerSecond = standardTicksPerSecond; } void AManaDrainCurveModifier::ModifierTick() { float mana = ScaleGraphCurve(ManaPerTick); if (mana > target->GetMana()) { ModifierManager* mod = character->GetModifierManager(); if (mod != nullptr) mod->BroadcastManaDrainFailed(); } else { target->RemoveMana(mana); } } //HealthModifier AHealModifier::AHealModifier() { ticksPerSecond = standardTicksPerSecond; } void AHealModifier::ModifierTick() { target->AddHealth(health); m_shouldBeRemoved = true; } bool AHealModifier::ShouldBeRemoved() const { return m_shouldBeRemoved; } //stunModifier static TSubclassOf stunEffectType; AStunModifier::AStunModifier() { stunEffectType = ConstructorHelpers::FClassFinder(TEXT("/Game/Assets/Art/Effects/FX_Stunned")).Class; } void AStunModifier::ModifierStart() { if (target->CanBeStunned() && lifeTime > 0.0f) UEffectFunctionLibrary::CreateEffect(target, stunEffectType, target,0.0f, lifeTime); } void AStunModifier::ModifierEnd() { } void AStunModifier::ModifierTick() { } void AStunModifier::ModifyCharacter() { m_AddStunnedState(); } //stunModifier ASilenceModifier::ASilenceModifier() { } void ASilenceModifier::ModifierStart() { m_AddSilencedState(); } void ASilenceModifier::ModifierEnd() { m_RemoveSilencedState(); } //ADamageTakenModifier ADamageTakenModifier::ADamageTakenModifier() { } void ADamageTakenModifier::ModifyCharacter() { m_MultiplyDamageTakenMultiplier(damageTakenMultiplier); } bool ADamageTakenModifier::ShouldBeRemoved() const { return false; } //AVisibilityModifier AVisibilityModifier::AVisibilityModifier() { } bool AVisibilityModifier::ShouldBeRemoved() const { return false; } void AVisibilityModifier::ModifierTick() { m_timer -= m_tickRate; if (m_timer < 0 && visibleTime > 0 && visibleBreak> 0) { if (m_visible) { m_timer = visibleBreak; target->m_visible = false; } else { m_timer = visibleTime; target->m_visible = true; } m_visible = !m_visible; } } //ADodgeDeathModifier ADodgeDeathModifier::ADodgeDeathModifier() { } bool ADodgeDeathModifier::ShouldBeRemoved() const { return false; } void ADodgeDeathModifier::ModifierTick() { m_timer += m_tickRate; } bool ADodgeDeathModifier::OnDamage(int32& damage, ANetworkCharacter* damageDealer) { if (damage >= target->GetHealth() && m_timer > ScaleGraphCurve(cooldown)) { float chance = (float)(rand() % 100) / 100.0f; if (ScaleGraphCurve(dodgeChance) > chance) { target->AddHealth(ScaleGraphCurve(heal)); m_timer = 0; return false; } } return true; } //ACooldownReductionModifier ACooldownReductionModifier::ACooldownReductionModifier() { } void ACooldownReductionModifier::ModifyCharacter() { float add = ScaleGraphCurve(scalingGraph); m_AddCooldownReduction(add); } //AAttackSpeedModifier AAttackSpeedModifier::AAttackSpeedModifier() { } void AAttackSpeedModifier::ModifyCharacter() { float add = ScaleGraphCurve(scalingGraph); m_AddAttackSpeedMultiplier(add); } //AAttackSpeedModifierConstant AAttackSpeedModifierConstant::AAttackSpeedModifierConstant() { } void AAttackSpeedModifierConstant::ModifyCharacter() { m_AddAttackSpeedMultiplier(attackSpeedMultiplier); } bool AAttackSpeedModifierConstant::ShouldBeRemoved() const { return false; } //AArmorIgnoreModifier AArmorIgnoreModifier::AArmorIgnoreModifier() { } void AArmorIgnoreModifier::ModifyCharacter() { float add = ScaleGraphCurve(scalingGraph); m_AddIgnoreArmor(add); } //ADodgeDeathModifier ABeserkModifier::ABeserkModifier() { ticksPerSecond = standardTicksPerSecond; m_active = false; } bool ABeserkModifier::ShouldBeRemoved() const { return false; } void ABeserkModifier::AfterDamage(int32 damage) { float deltahealth = (float)target->GetHealth() / (float)target->GetMaxHealth(); if (deltahealth < ScaleGraphCurve(healthThreshold)) { if (!m_active) { m_hasToActivate = true; } } } void ABeserkModifier::ModifierTick() { float deltahealth = (float)target->GetHealth() / (float)target->GetMaxHealth(); if (m_hasToActivate) { m_hasToActivate = false; m_active = true; m_ASModifier = GetWorld()->SpawnActor(); m_ASModifier->lifeTime = 0.0f; m_ASModifier->target = target; m_ASModifier->attackSpeedMultiplier = ScaleGraphCurve(attackSpeedMultiplier); target->GetModifierManager()->AddModifier(m_ASModifier); } if (deltahealth > ScaleGraphCurve(healthThreshold)) { if (m_active) { m_active = false; m_ASModifier->ForceDestroy(); } } } //AArmorReductionModifier AArmorReductionModifier::AArmorReductionModifier() { } void AArmorReductionModifier::ModifyCharacter() { m_AddArmor(armorReduction); } //AHealthRegenModifier AHealthRegenModifier::AHealthRegenModifier() { ticksPerSecond = standardTicksPerSecond; } void AHealthRegenModifier::ModifierTick() { float add = ScaleGraphCurve(scalingGraph); target->AddHealth(add); } //AOnStandardAttackDOTModifier AOnStandardAttackDOTModifier::AOnStandardAttackDOTModifier() { ticksPerSecond = standardTicksPerSecond; } void AOnStandardAttackDOTModifier::ModifierTick() { m_cooldownTimer += m_tickRate; } void AOnStandardAttackDOTModifier::OnStandardAttack(ANetworkCharacter* targetcharacter) { if (!IsValid(targetcharacter)) return; ADOTModifier* DOTModifier = GetWorld()->SpawnActor(); DOTModifier->lifeTime = ScaleGraphCurve(damageDuration); DOTModifier->damagePerTick = ScaleGraphCurve(damagePerTick); // DOTModifier->target = targetcharacter; DOTModifier->character = character; DOTModifier->abilityInfo = abilityInfo; DOTModifier->target = targetcharacter; targetcharacter->GetModifierManager()->AddModifier(DOTModifier); m_cooldownTimer = ScaleGraphCurve(cooldown); } //AReturnDamageModifier AReturnDamageModifier::AReturnDamageModifier() { ticksPerSecond = standardTicksPerSecond; } bool AReturnDamageModifier::OnDamage(int32& damage, ANetworkCharacter* damageDealer) { if (damage >= 10 && IsValid(damageDealer)) { float returnDamage = ScaleGraphCurve(scalingGraph); damageDealer->DealDamage(this, damage * returnDamage, 0.0f); } return true; } //AReturnDamageModifier ARedirectDamageModifier::ARedirectDamageModifier() { ticksPerSecond = standardTicksPerSecond; } bool ARedirectDamageModifier::OnDamage(int32& damage, ANetworkCharacter* damageDealer) { if (damage >= 10 && IsValid(character)) { float redirect = ScaleGraphCurve(redirectScalingGraph); if (redirect > 1) { FWARNING("redirect > 1, will act as if it is 0.9f"); redirect = 0.9f; } if (redirect < 0) { FWARNING("redirect < 0, will act as if it is 0.0f"); redirect = 0.0f; } float absorb = ScaleGraphCurve(absorbScalingGraph); if (absorb > 1) { FWARNING("absorb > 1, will act as if it is 1.0f"); absorb = 1.0f; } if (absorb < 0.0f ) { FWARNING("absorb < 0, will act as if it is 0.0f"); absorb = 0.0f; } character->DealDamage(this, damage * (redirect * absorb), 0.0f); damage *= (1 - redirect); DamageEvent(); } return true; } //ATrustModifier //set delegate in gamestate to know when the teammate respawns. ATrustModifier::ATrustModifier() { ticksPerSecond = 2; } void ATrustModifier::ModifierTick() { if (IsValid(character)) { target->GetModifierManager()->RecalculateCharacter(); } else ForceDestroy(); } void ATrustModifier::ModifyCharacter() { if (IsValid(character)) { float add = ScaleGraphCurve(damageScalingGraph); float deltahealth =1 + ( 1.0f - ((float)character->GetHealth() / (float)character->GetMaxHealth())); m_MultiplyAttackDamage(add * deltahealth); } } //AArmorIncreaseModifier AArmorIncreaseModifier::AArmorIncreaseModifier() { ticksPerSecond = standardTicksPerSecond; } void AArmorIncreaseModifier::ModifyCharacter() { float add = ScaleGraphCurve(armorScalingGraph); m_AddArmor(add); } //AMoveToModifier AMoveToModifier::AMoveToModifier() { ticksPerSecond = standardTicksPerSecond; } void AMoveToModifier::ModifierStart() { m_movePerTick = (targetPos - target->GetActorLocation()) / (moveTime * ticksPerSecond); } void AMoveToModifier::ModifierTick() { target->AddActorWorldOffset(m_movePerTick, true); } //AHealthRegenPercentageModifier AHealthRegenPercentageModifier::AHealthRegenPercentageModifier() { ticksPerSecond = standardTicksPerSecond; } void AHealthRegenPercentageModifier::ModifierTick() { float add = ScaleGraphCurve(scalingGraph); add /= ticksPerSecond; int32 health = character->GetMaxHealth(); health *= add; target->AddHealth(health); } //AManaRegenMultiplierModifier AManaRegenMultiplierModifier::AManaRegenMultiplierModifier() { ticksPerSecond = standardTicksPerSecond; } void AManaRegenMultiplierModifier::ModifyCharacter() { float add = ScaleGraphCurve(manaRegenMultiplierScalingGraph); m_MultiplyManaRegenMultiplier(add); } //AManaCostMultiplierModifier AManaCostMultiplierModifier::AManaCostMultiplierModifier() { ticksPerSecond = standardTicksPerSecond; } void AManaCostMultiplierModifier::ModifyCharacter() { float add = ScaleGraphCurve(manaCostMultiplierScalingGraph); m_MultiplyManaUsageMultiplier(add); } //AManaCostMultiplierModifier AEffectMultiplierModifier::AEffectMultiplierModifier() { ticksPerSecond = standardTicksPerSecond; } void AEffectMultiplierModifier::ModifyCharacter() { float add = ScaleGraphCurve(effectMultiplierScalingGraph); if (positive) m_MultiplyPositiveEffectMultiplier(add); else m_MultiplyNegativeEffectMultiplier(add); } //ACastingMovementSpeedMultiplierModifier ACastingMovementSpeedMultiplierModifier::ACastingMovementSpeedMultiplierModifier() { ticksPerSecond = standardTicksPerSecond; } void ACastingMovementSpeedMultiplierModifier::ModifyCharacter() { float add = ScaleGraphCurve(movementSpeedMultiplierScalingGraph); m_addChannelMovementSpeedMultiplier(add); } //AReaperModifier AReaperModifier::AReaperModifier() { ticksPerSecond = standardTicksPerSecond; } bool AReaperModifier::OnDealDamage(int32& damage, ANetworkCharacter* damageTaker) { float multiplier = ScaleGraphCurve(damagemultiplier); float norm = ScaleGraphCurve(threshhold); float deltahealth = (float)damageTaker->GetHealth() / (float)damageTaker->GetMaxHealth(); if ((deltahealth < norm && smaller) || (deltahealth > norm && !smaller)) { damage *= multiplier; } return true; } //AMagicDamageMultiplierModifier AMagicDamageMultiplierModifier::AMagicDamageMultiplierModifier() { ticksPerSecond = standardTicksPerSecond; } void AMagicDamageMultiplierModifier::ModifyCharacter() { float add = ScaleGraphCurve(magicDamageMultiplierScalingGraph); m_MultiplyMagicDamageMultiplier(add); } //AStandardMeleeModifier AStandardMeleeModifier::AStandardMeleeModifier() { count = 0; ticksPerSecond = standardTicksPerSecond; } void AStandardMeleeModifier::ModifierTick() { m_timer += m_tickRate; if (m_timer >= maxTime) { ForceDestroy(); } } bool AStandardMeleeModifier::AddCount() { count++; count%=maxCount; m_timer = 0; return count == 0; } //ADamageToManaModifier ADamageToManaModifier::ADamageToManaModifier() { } void ADamageToManaModifier::AfterDamage(int32 damage) { float addMultiplier = ScaleGraphCurve(multiplier); target->AddMana(damage * addMultiplier); }