public void SetTarget(int x, int y, int randomHitRange, LogicGameObject target, bool randomHitPosition) { this.m_target = target; this.m_targetPosition.m_x = target.GetMidX() * 8; this.m_targetPosition.m_y = target.GetMidY() * 8; if (target.GetGameObjectType() == LogicGameObjectType.CHARACTER) { LogicCharacter character = (LogicCharacter)target; if (character.IsFlying()) { LogicCombatComponent combatComponent = target.GetCombatComponent(); this.m_randomHitRange = combatComponent != null && combatComponent.IsHealer() ? 200 : 1000; this.m_flyingTarget = true; } if (randomHitPosition) { LogicVector2 pos = new LogicVector2(this.m_targetPosition.m_x >> 3, this.m_targetPosition.m_y >> 3); int distance = pos.GetDistance(this.GetPosition()); this.m_unk168.m_x = this.m_targetPosition.m_x - 8 * this.GetMidX(); this.m_unk168.m_y = this.m_targetPosition.m_y - 8 * this.GetMidY(); this.m_unk168.Rotate(90); this.m_unk168.Normalize(64); int rnd = ((distance / 10) & this.Rand(randomHitRange)) - distance / 20; this.m_unk168.m_x = this.m_unk168.m_x * rnd / 64; this.m_unk168.m_y = this.m_unk168.m_y * rnd / 64; pos.Destruct(); } } else { int range = target.IsWall() ? 1016 : 2040; this.m_unk168.m_x = 8 * x - this.m_targetPosition.m_x; this.m_unk168.m_y = 8 * y - this.m_targetPosition.m_y; this.m_unk168.Normalize(((target.GetWidthInTiles() - target.PassableSubtilesAtEdge()) << 12) / 3); this.m_unk168.m_x += (range & this.Rand(randomHitRange)) * (2 * (this.Rand(randomHitRange + 1) & 1) - 1); this.m_unk168.m_y += (range & this.Rand(randomHitRange + 2)) * (2 * (this.Rand(randomHitRange + 3) & 1) - 1); this.m_targetPosition.Add(this.m_unk168); this.m_randomHitRange = 150; } }
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); } } } } } } }
public void UpdatePenetrating(int damageMultiplier) { LogicVector2 pos1 = new LogicVector2((this.m_targetPosition.m_x >> 3) - this.m_unk248.m_x, (this.m_targetPosition.m_y >> 3) - this.m_unk248.m_y); pos1.Normalize(512); LogicVector2 pos2 = new LogicVector2(-pos1.m_y, pos1.m_x); int distance = ((200 - this.m_areaShieldDelay) * (8 * this.GetSpeed() - 8 * this.m_areaShieldSpeed) / 200 + 8 * this.m_areaShieldSpeed) >> 3; LogicArrayList <LogicComponent> components = this.GetComponentManager().GetComponents(LogicComponentType.MOVEMENT); for (int i = 0, damage = damageMultiplier * this.m_damage / 100; i < components.Size(); i++) { LogicMovementComponent component = (LogicMovementComponent)components[i]; LogicGameObject parent = component.GetParent(); LogicHitpointComponent hitpointComponent = parent.GetHitpointComponent(); if (!parent.IsHidden() && hitpointComponent.GetTeam() != this.m_myTeam && hitpointComponent.GetHitpoints() > 0) { int distanceX = parent.GetMidX() - this.GetMidX(); int distanceY = parent.GetMidY() - this.GetMidY(); if (parent.GetGameObjectType() == LogicGameObjectType.CHARACTER) { distanceX += parent.GetWidthInTiles() << 8; distanceY += parent.GetHeightInTiles() << 8; } if ((!component.IsFlying() || this.m_flyingTarget) && LogicMath.Abs(distanceX) <= this.m_penetratingRadius && LogicMath.Abs(distanceY) <= this.m_penetratingRadius && distanceX * distanceX + distanceY * distanceY <= (uint)(this.m_penetratingRadius * this.m_penetratingRadius)) { LogicVector2 position = new LogicVector2(); if (parent.GetGameObjectType() == LogicGameObjectType.CHARACTER && hitpointComponent.GetMaxHitpoints() <= damage) { int rnd = (byte)this.Rand(parent.GetGlobalID()); if (rnd > 170u) { position.Set((pos1.m_x >> 2) + pos2.m_x, (pos1.m_y >> 2) + pos2.m_y); } else { if (rnd > 85) { position.Set(pos1.m_x, pos1.m_y); } else { position.Set((pos1.m_x >> 2) - pos2.m_x, (pos1.m_y >> 2) - pos2.m_y); } } if (hitpointComponent.GetInvulnerabilityTime() <= 0) { ((LogicCharacter)parent).Eject(position); } position.Destruct(); } else { position.Set(pos1.m_x, pos1.m_y); position.Normalize(distance); if (parent.GetMovementComponent().GetMovementSystem().ManualPushTrap(position, 150, this.m_globalId) || parent.IsHero()) { this.UpdateTargetDamage(parent, damage); } } } } } pos1.Destruct(); pos2.Destruct(); }