public static float GetSpellStrength(LogicSpellData data, int upgLevel) { if (data.IsProductionEnabled()) { int damage = data.GetDamage(upgLevel); if (!data.IsDamageSpell()) { damage = -damage; } int buildingDamage = data.GetBuildingDamagePermil(upgLevel); int troopDamage = data.GetTroopDamagePermil(upgLevel); int sumDamage = damage / 100 + buildingDamage + troopDamage; if (data.GetDamageBoostPercent(upgLevel) > 0) { sumDamage += data.GetDamageBoostPercent(upgLevel) - 100; } int damageStrength = sumDamage + data.GetSpeedBoost(upgLevel); if (damageStrength == 0) { if (data.GetJumpBoostMS(upgLevel) != 0) { damageStrength = data.GetJumpBoostMS(upgLevel) / 1000; } if (data.GetFreezeTimeMS(upgLevel) != 0) { damageStrength = data.GetFreezeTimeMS(upgLevel) / 1000; } if (data.GetDuplicateHousing(upgLevel) != 0) { damageStrength = data.GetDuplicateHousing(upgLevel); } if (data.GetUnitsToSpawn(upgLevel) != 0) { damageStrength = data.GetUnitsToSpawn(upgLevel); } } return(damageStrength * 0.014286f * data.GetStrengthWeight(upgLevel)); } return(0f); }
public override void SubTick() { base.SubTick(); LogicSpellData data = this.GetSpellData(); if (!this.m_preDeployEffectPlayed) { this.GetListener().PlayEffect(data.GetPreDeployEffect(this.m_upgradeLevel)); this.m_preDeployEffectPlayed = true; } if (++this.m_deployTime >= data.GetDeployTimeMS() * 60 / 1000) { if (!this.m_deployed) { this.GetListener().PlayEffect(this.m_team != 0 && data.GetEnemyDeployEffect(this.m_upgradeLevel) != null ? data.GetEnemyDeployEffect(this.m_upgradeLevel) : data.GetDeployEffect(this.m_upgradeLevel), this.m_playEffectOffsetX, this.m_playEffectOffsetY); this.m_deployEffect2Cooldown = data.GetDeployEffect2Delay(); if (this.m_deployEffect2Cooldown <= 0) { this.GetListener().PlayEffect(data.GetDeployEffect2(this.m_upgradeLevel), this.m_playEffectOffsetX, this.m_playEffectOffsetY); this.m_deployEffect2Cooldown = 0; } this.m_deployed = true; } if (++this.m_chargingTime >= (data.GetChargingTimeMS() * 60 / 1000) + this.m_chargingCount * (data.GetTimeBetweenHitsMS(this.m_upgradeLevel) * 60 / 1000) && this.m_chargingCount < data.GetNumberOfHits(this.m_upgradeLevel)) { this.CalculateRandomOffset(this.m_chargingCount); this.GetListener().PlayTargetedEffect(data.GetChargingEffect(this.m_upgradeLevel), this, this.m_randomOffset); ++this.m_chargingCount; } if (++this.m_hitTime >= (data.GetHitTimeMS() * 60 / 1000) + this.m_hitCount * (data.GetTimeBetweenHitsMS(this.m_upgradeLevel) * 60 / 1000) && this.m_hitCount < data.GetNumberOfHits(this.m_upgradeLevel)) { this.CalculateRandomOffset(this.m_hitCount); this.GetListener().PlayTargetedEffect(data.GetHitEffect(this.m_upgradeLevel), this, this.m_randomOffset); int randomRadiusX = 0; int randomRadiusY = 0; if (!data.GetRandomRadiusAffectsOnlyGfx()) { randomRadiusX = this.m_randomOffset.m_x; randomRadiusY = this.m_randomOffset.m_y; } int damage = data.GetDamage(this.m_upgradeLevel); if (damage != 0 && data.IsScaleByTownHall()) { int scaledDamage = damage * (700 * this.m_level.GetPlayerAvatar().GetTownHallLevel() / (LogicDataTables.GetTownHallLevelCount() - 1) / 10 + 30) / 100; damage = 1; if (scaledDamage > 0) { damage = scaledDamage; } } if (damage != 0 && data.GetRadius(this.m_upgradeLevel) > 0) { int areaDamageX = randomRadiusX + this.GetMidX(); int areaDamageY = randomRadiusY + this.GetMidY(); int preferredTargetDamagePercent = 100 * data.GetPreferredTargetDamageMod(); if (data.GetTroopsOnly()) { this.m_level.AreaDamage(0, areaDamageX, areaDamageY, data.GetRadius(this.m_upgradeLevel), damage, data.GetPreferredTarget(), preferredTargetDamagePercent, null, this.m_team, null, 2, 2, 0, true, damage < 0, data.GetHeroDamageMultiplier(), data.GetMaxUnitsHit(this.m_upgradeLevel), null, data.GetDamageTHPercent(), data.GetPauseCombatComponentMs()); } else { this.m_level.AreaDamage(0, areaDamageX, areaDamageY, data.GetRadius(this.m_upgradeLevel), damage, data.GetPreferredTarget(), preferredTargetDamagePercent, null, this.m_team, null, 2, 1, 0, true, damage < 0, data.GetHeroDamageMultiplier(), data.GetMaxUnitsHit(this.m_upgradeLevel), null, data.GetDamageTHPercent(), data.GetPauseCombatComponentMs()); } } if (data.GetDuplicateHousing(this.m_upgradeLevel) != 0 && data.GetRadius(this.m_upgradeLevel) > 0) { this.SelectDuplicableCharacters(); this.DuplicateCharacter(); } if ((data.GetBuildingDamagePermil(this.m_upgradeLevel) != 0 || data.GetTroopDamagePermil(this.m_upgradeLevel) != 0) && data.GetRadius(this.m_upgradeLevel) > 0) { this.ApplyDamagePermil(randomRadiusX + this.GetMidX(), randomRadiusY + this.GetMidY(), 0, this.m_team, 0, 2, 1, 0, data.GetTroopDamagePermil(this.m_upgradeLevel) < 0); } if (data.GetPoisonDamage(this.m_upgradeLevel) != 0 && data.GetRadius(this.m_upgradeLevel) > 0) { int areaDamageX = randomRadiusX + this.GetMidX(); int areaDamageY = randomRadiusY + this.GetMidY(); int poisonDamage = data.GetPoisonDamage(this.m_upgradeLevel); if (data.GetTroopsOnly()) { this.m_level.AreaPoison(0, areaDamageX, areaDamageY, data.GetRadius(this.m_upgradeLevel), data.GetPoisonDamage(this.m_upgradeLevel), null, 0, null, this.m_team, null, data.GetPoisonAffectAir() ? 2 : 1, 2, 0, poisonDamage < 0, data.GetHeroDamageMultiplier(), data.GetPoisonIncreaseSlowly()); } else { this.m_level.AreaPoison(0, areaDamageX, areaDamageY, data.GetRadius(this.m_upgradeLevel), data.GetPoisonDamage(this.m_upgradeLevel), null, 0, null, this.m_team, null, data.GetPoisonAffectAir() ? 2 : 1, 1, 0, poisonDamage < 0, data.GetHeroDamageMultiplier(), data.GetPoisonIncreaseSlowly()); } } if (data.GetSpeedBoost(this.m_upgradeLevel) != 0 || data.GetAttackSpeedBoost(this.m_upgradeLevel) != 0) { this.m_level.AreaBoost(randomRadiusX + this.GetMidX(), randomRadiusY + this.GetMidY(), data.GetRadius(this.m_upgradeLevel), data.GetSpeedBoost(this.m_upgradeLevel), data.GetSpeedBoost2(this.m_upgradeLevel), data.GetDamageBoostPercent(this.m_upgradeLevel), data.GetAttackSpeedBoost(this.m_upgradeLevel), 60 * data.GetBoostTimeMS(this.m_upgradeLevel) / 1000, data.GetBoostDefenders() ? this.m_team != 1 ? 1 : 0 : this.m_team, data.GetBoostLinkedToPoison()); } if (data.GetJumpBoostMS(this.m_upgradeLevel) != 0) { if (this.m_team == 0) { this.m_level.AreaJump(randomRadiusX + this.GetMidX(), randomRadiusY + this.GetMidY(), data.GetRadius(this.m_upgradeLevel), data.GetJumpBoostMS(this.m_upgradeLevel), data.GetJumpHousingLimit(this.m_upgradeLevel), this.m_team); if (this.m_hitCount == 0) { if (LogicDataTables.GetGlobals().UseWallWeightsForJumpSpell()) { int numberOfHits = data.GetNumberOfHits(this.m_upgradeLevel); int timeBetweenHitsMS = data.GetTimeBetweenHitsMS(this.m_upgradeLevel); int radius = data.GetRadius(this.m_upgradeLevel); int jumpTime = numberOfHits * timeBetweenHitsMS - LogicDataTables.GetGlobals().GetForgetTargetTime(); LogicArrayList <LogicGameObject> buildings = this.GetGameObjectManager().GetGameObjects(LogicGameObjectType.BUILDING); for (int i = 0; i < buildings.Size(); i++) { LogicBuilding building = (LogicBuilding)buildings[i]; if (building.IsWall() && building.IsAlive()) { int distanceX = this.GetMidX() - building.GetMidX(); int distanceY = this.GetMidY() - building.GetMidY(); if (LogicMath.Abs(distanceX) < radius && LogicMath.Abs(distanceY) < radius && distanceX * distanceX + distanceY * distanceY < (uint)(radius * radius)) { building.SetHitWallDelay(jumpTime); } } } this.m_level.GetTileMap().GetPathFinder().InvalidateCache(); LogicArrayList <LogicComponent> components = this.GetComponentManager().GetComponents(LogicComponentType.MOVEMENT); for (int i = 0; i < components.Size(); i++) { LogicMovementComponent movementComponent = (LogicMovementComponent)components[i]; LogicGameObject parent = movementComponent.GetParent(); LogicCombatComponent combatComponent = parent.GetCombatComponent(); if (combatComponent != null && combatComponent.GetTarget(0) != null) { if (combatComponent.GetTarget(0).IsWall()) { combatComponent.ForceNewTarget(); } } } } } } } if (data.GetShrinkReduceSpeedRatio() != 0 || data.GetShrinkHitpointsRatio() != 0) { this.m_level.AreaShrink(randomRadiusX + this.GetMidX(), randomRadiusY + this.GetMidY(), data.GetRadius(this.m_upgradeLevel), data.GetShrinkReduceSpeedRatio(), data.GetShrinkHitpointsRatio(), 1000 * LogicDataTables.GetGlobals().GetShrinkSpellDurationSeconds() / 64, this.m_team); } if (data.GetFreezeTimeMS(this.m_upgradeLevel) != 0) { this.m_level.AreaFreeze(randomRadiusX + this.GetMidX(), randomRadiusY + this.GetMidY(), data.GetRadius(this.m_upgradeLevel), 60 * data.GetFreezeTimeMS(this.m_upgradeLevel) / 1000, this.m_team); } if (data.GetBuildingDamageBoostPercent(this.m_upgradeLevel) != 0) { this.m_level.AreaBoost(randomRadiusX + this.GetMidX(), randomRadiusY + this.GetMidY(), data.GetRadius(this.m_upgradeLevel), data.GetBuildingDamageBoostPercent(this.m_upgradeLevel), 0, 60 * data.GetBoostTimeMS(this.m_upgradeLevel) / 1000); } if (data.GetSummonTroop() != null) { this.SpawnSummon(randomRadiusX + this.GetMidX(), randomRadiusY + this.GetMidY()); } if (data.GetSpawnObstacle() != null) { this.SpawnObstacle(randomRadiusX + this.GetMidX(), randomRadiusY + this.GetMidY(), 5); } if (data.GetExtraHealthPermil(this.m_upgradeLevel) != 0) { this.ApplyExtraHealthPermil(randomRadiusX + this.GetMidX(), randomRadiusY + this.GetMidY(), data.GetRadius(this.m_upgradeLevel), this.m_team, data.GetExtraHealthPermil(this.m_upgradeLevel), data.GetExtraHealthMin(this.m_upgradeLevel), data.GetExtraHealthMax(this.m_upgradeLevel), data.GetHitTimeMS() + 64, 2); } if (data.GetInvulnerabilityTime(this.m_upgradeLevel) != 0) { this.m_level.AreaShield(randomRadiusX + this.GetMidX(), randomRadiusY + this.GetMidY(), data.GetRadius(this.m_upgradeLevel), data.GetInvulnerabilityTime(this.m_upgradeLevel), this.m_team); } if (++this.m_hitCount >= data.GetNumberOfHits(this.m_upgradeLevel)) { this.m_hitsCompleted = true; this.m_level.UpdateBattleStatus(); } } } }
public void ApplyDamagePermil(int x, int y, int unk1, int team, int unk2, int targetType, int damageType, int unk3, bool healing) { LogicSpellData spellData = this.GetSpellData(); int radius = spellData.GetRadius(this.m_upgradeLevel); int troopDamagePermil = spellData.GetTroopDamagePermil(this.m_upgradeLevel); int buildingDamagePermil = spellData.GetBuildingDamagePermil(this.m_upgradeLevel); int executeHealthPermil = spellData.GetExecuteHealthPermil(this.m_upgradeLevel); int damagePermilMin = spellData.GetDamagePermilMin(this.m_upgradeLevel); int preferredTargetDamageMod = spellData.GetPreferredTargetDamageMod(); int preferredDamagePermilMin = spellData.GetPreferredDamagePermilMin(this.m_upgradeLevel); LogicData preferredTarget = spellData.GetPreferredTarget(); LogicVector2 pushBackPosition = new LogicVector2(); LogicArrayList <LogicComponent> components = this.GetComponentManager().GetComponents(LogicComponentType.HITPOINT); int tmp = troopDamagePermil + 2 * buildingDamagePermil; for (int i = 0; i < components.Size(); i++) { LogicHitpointComponent hitpointComponent = (LogicHitpointComponent)components[i]; LogicGameObject parent = hitpointComponent.GetParent(); if (!parent.IsHidden() && hitpointComponent.GetHitpoints() != 0) { if (hitpointComponent.GetTeam() == team) { if (tmp > 0 || tmp < 0 && parent.IsPreventsHealing()) { continue; } } else if (tmp < 0) { continue; } if (damageType == 2 && parent.GetGameObjectType() != LogicGameObjectType.CHARACTER) { continue; } int parentX; int parentY; LogicMovementComponent movementComponent = parent.GetMovementComponent(); if (movementComponent != null || parent.IsFlying()) { if (parent.IsFlying()) { if (targetType == 1) { continue; } } else if (targetType == 0) { continue; } parentX = parent.GetMidX(); parentY = parent.GetMidY(); } else { int posX = parent.GetX(); int posY = parent.GetY(); parentX = LogicMath.Clamp(x, posX, posX + (parent.GetWidthInTiles() << 9)); parentY = LogicMath.Clamp(y, posY, posY + (parent.GetHeightInTiles() << 9)); } int distanceX = x - parentX; int distanceY = y - parentY; if (LogicMath.Abs(distanceX) <= radius && LogicMath.Abs(distanceY) <= radius && distanceX * distanceX + distanceY * distanceY < (uint)(radius * radius)) { if (damageType == 1 && parent.GetGameObjectType() == LogicGameObjectType.BUILDING) { LogicBuilding building = (LogicBuilding)parent; if (building.GetResourceStorageComponentComponent() != null && !building.GetBuildingData().IsTownHall() && !building.GetBuildingData().IsTownHallVillage2()) { parent.SetDamageTime(10); continue; } } if (parent.GetGameObjectType() == LogicGameObjectType.BUILDING || parent.GetGameObjectType() == LogicGameObjectType.CHARACTER) { int dataDamagePermil = parent.GetGameObjectType() == LogicGameObjectType.BUILDING ? buildingDamagePermil : troopDamagePermil; if (dataDamagePermil != 0) { int permil = 10 * hitpointComponent.GetMaxHitpoints() * dataDamagePermil / 10000; if (10 * hitpointComponent.GetMaxHitpoints() * dataDamagePermil <= -10000) { if (parent.IsHero()) { permil = LogicDataTables.GetGlobals().GetHeroHealMultiplier() * permil / 100; } } bool isPreferredTarget = LogicCombatComponent.IsPreferredTarget(preferredTarget, parent); int numberOfHits = spellData.GetNumberOfHits(this.m_upgradeLevel); int completePermil = hitpointComponent.GetDamagePermilCount() / spellData.GetNumberOfHits(this.m_upgradeLevel); int calculateDamage = isPreferredTarget ? permil / (completePermil + 1) + preferredTargetDamageMod * hitpointComponent.GetMaxHitpoints() / (100 * numberOfHits) * completePermil * completePermil : permil / (2 * completePermil + 1); int permilMin = isPreferredTarget ? preferredDamagePermilMin : damagePermilMin; int damage = hitpointComponent.GetMaxHitpoints() * permilMin / 10000; if (calculateDamage >= damage) { damage = calculateDamage; } if (executeHealthPermil > 0 && 1000 * (hitpointComponent.GetHitpoints() - damage) <= executeHealthPermil) { damage = hitpointComponent.GetHitpoints(); } hitpointComponent.CauseDamagePermil(damage); if (healing) { // Listener. } if ((distanceX | distanceX) == 0) { distanceX = 1; } pushBackPosition.m_x = -distanceX; pushBackPosition.m_y = -distanceY; pushBackPosition.Normalize(512); if (unk3 > 0 && movementComponent != null) { movementComponent.GetMovementSystem().PushBack(pushBackPosition, damage, unk3, 0, false, true); } } } } } } }