namespace Supercell.Laser.Logic.Battle.Objects { using Supercell.Laser.Logic.Data; using Supercell.Laser.Titan.DataStream; using Supercell.Laser.Titan.Math; public class AreaEffect : GameObject { private Character m_source; public int KOHUID; public int LifeTimeConsumedPercent; public bool ShouldBeDestructed; public bool IsActive; public int DisplayScale; public int Payback; public AreaEffectData AreaEffectData; private int m_ticksElapsed; private int m_damage; private List m_alreadyDamagedList; public AreaEffect(int classId, int instanceId) : base(classId, instanceId) { m_alreadyDamagedList = new List(); } public AreaEffectData EffectData => DataTables.Get(DataType.AreaEffect).GetDataByGlobalId(DataId); public override void Tick() { m_ticksElapsed++; if (EffectData.Name == "MummyUltiArea" && m_source != null && m_source.IsAlive()) { SetPosition(m_source.GetX(), m_source.GetY(), GetZ()); } if (EffectData.Type == "Damage") { if (m_damage == 0) m_damage = EffectData.Damage; GameObject[] objects = GameObjectManager.GetGameObjects(); foreach (GameObject gameObject in objects) { if (gameObject.GetObjectType() != 1) continue; Character character = (Character)gameObject; if (character == null) continue; if (m_alreadyDamagedList.Contains(character)) continue; if (character.GetIndex() / 16 == m_source.GetIndex() / 16) continue; if (character.GetPosition().GetDistance(Position) > GetRadius()) continue; character.CauseDamage(m_source, m_damage); m_alreadyDamagedList.Add(character); } } else if (EffectData.Type == "BulletExplosion") { if (m_ticksElapsed == 1) { ProjectileData projectileData = DataTables.Get(6).GetData(EffectData.BulletExplosionBullet); int a = 0; for (int i = 0; i < EffectData.CustomValue; i++) { Projectile projectile = new Projectile(6, projectileData.GetInstanceId()); projectile.ShootProjectile(a, m_source, 400, EffectData.BulletExplosionBulletDistance / 2, false); projectile.SetPosition(GetX(), GetY(), 400); a += 360 / EffectData.CustomValue; GameObjectManager.AddGameObject(projectile); } } } else if (EffectData.Type == "Dot") { if (m_damage == 0) { int tickCount = LogicMath.Max(1, EffectData.TimeMs / 1000); m_damage = LogicMath.Max(1, EffectData.Damage / tickCount); } if (m_ticksElapsed % 20 == 0) m_alreadyDamagedList.Clear(); GameObject[] objects = GameObjectManager.GetGameObjects(); foreach (GameObject gameObject in objects) { if (gameObject.GetObjectType() != 1) continue; Character character = (Character)gameObject; if (character == null) continue; if (m_alreadyDamagedList.Contains(character)) continue; if (character.GetIndex() / 16 == m_source.GetIndex() / 16) continue; if (character.GetPosition().GetDistance(Position) > GetRadius()) continue; if (EffectData.FreezeTicks > 0) { character.ApplySlow(EffectData.FreezeTicks, EffectData.FreezeStrength); } character.CauseDamage(m_source, m_damage); m_alreadyDamagedList.Add(character); } } else if (EffectData.Type == "Pushback") { foreach (GameObject gameObject in GameObjectManager.GetGameObjects()) { if (gameObject.GetObjectType() != 1) continue; Character character = (Character)gameObject; if (character == null || !character.IsAlive()) continue; if (m_source != null && character.GetIndex() / 16 == m_source.GetIndex() / 16) continue; int distance = character.GetPosition().GetDistance(Position); if (distance > GetRadius()) continue; if (distance <= EffectData.PushbackDeadzone) continue; if (!character.TryBeginGroupedControl(m_source)) continue; character.ApplyKnockback(GetX(), GetY(), EffectData.PushbackStrength); } } else if (EffectData.Type == "DelayedDamage") { if (m_ticksElapsed == EffectData.TimeMs / 50) { if (m_damage == 0) m_damage = EffectData.Damage; foreach (GameObject gameObject in GameObjectManager.GetGameObjects()) { if (gameObject.GetObjectType() != 1) continue; Character character = (Character)gameObject; if (character == null || !character.IsAlive()) continue; if (m_source != null && character.GetIndex() / 16 == m_source.GetIndex() / 16) continue; if (character.GetPosition().GetDistance(Position) > GetRadius()) continue; character.CauseDamage(m_source, m_damage); } } } else if (EffectData.Type == "WallSpawn") { if (m_ticksElapsed == 1) { int damage = m_damage == 0 ? EffectData.Damage : m_damage; if (damage > 0) { foreach (GameObject gameObject in GameObjectManager.GetGameObjects()) { if (gameObject.GetObjectType() != 1) continue; Character character = (Character)gameObject; if (character == null || !character.IsAlive()) continue; if (m_source != null && character.GetIndex() / 16 == m_source.GetIndex() / 16) continue; if (character.GetPosition().GetDistance(Position) > GetRadius()) continue; character.CauseDamage(m_source, damage); } } } // Blocking is handled by BlocksMovement/BlocksProjectiles. } else if (EffectData.Name == "KingOfHillArea") { // Battle.BattleMode battle = GameObjectManager.GetBattle(); // int _completePercetnage = 100; // int _UpTicks = 15; // int _count = battle.GetKOHZoneCount(); // switch (_count) // { // case 1: // _completePercetnage = 100; // _UpTicks = 15; // break; // case 2: // _completePercetnage = 50; // _UpTicks = 10; // break; // case 3: // _completePercetnage = 30; // _UpTicks = 5; // break; // default: // _completePercetnage = 100; // break; // } // if (battle.GetTicksGone() > 120) // { // var GetBattle = battle; // var state = GetBattle.GetZoneByUID(KOHUID); // var areaEffect = DataTables.Get(DataType.AreaEffect).GetData("KingOfHillArea"); // var captureData = DataTables.Get(DataType.AreaEffect).GetData("KingOfHillAreaCapture"); // var gaugeData = DataTables.Get(DataType.AreaEffect).GetData("KingOfHillAreaGauge"); // if (!state.CanContinueUpTeam0) // { // if (!state.HillCompleteEffectSpawnedTeam0) // { // GameObjectManager.RemoveGameObject(state.CurrentCaptureEffectTeam0); // GameObjectManager.RemoveGameObject(state.GaugeTeam0Effect); // AreaEffectData completeEffectData = DataTables.Get(DataType.AreaEffect).GetData("KingOfHillAreaComplete"); // AreaEffect completeEffect = new AreaEffect(17, completeEffectData.GetInstanceId()); // completeEffect.SetPosition(GetX(), GetY(), 0); // if (GetBattle.GetKOHZoneCount() == 1) // { // completeEffect.SetIndex(0); // } // else if (GetBattle.GetKOHZoneCount() == 2) // { // completeEffect.SetIndex(0); // state.CanContinueUpTeam0 = false; // } // GameObjectManager.AddGameObject(completeEffect); // completeEffect.SetForcedVisible(); // state.HillCompleteEffectSpawnedTeam0 = true; // } // } // if (!state.CanContinueUpTeam1) // { // if (!state.HillCompleteEffectSpawnedTeam1) // { // GameObjectManager.RemoveGameObject(state.CurrentCaptureEffectTeam1); // GameObjectManager.RemoveGameObject(state.GaugeTeam1Effect); // AreaEffectData completeEffectData = DataTables.Get(DataType.AreaEffect).GetData("KingOfHillAreaComplete"); // AreaEffect completeEffect = new AreaEffect(17, completeEffectData.GetInstanceId()); // completeEffect.SetPosition(GetX(), GetY(), 0); // if (GetBattle.GetKOHZoneCount() == 1) // { // completeEffect.SetIndex(1); // } // else if (GetBattle.GetKOHZoneCount() == 2) // { // completeEffect.SetIndex(1); // state.CanContinueUpTeam1 = false; // } // GameObjectManager.AddGameObject(completeEffect); // completeEffect.SetForcedVisible(); // state.HillCompleteEffectSpawnedTeam1 = true; // } // } // var playersInZone = GameObjectManager.GetGameObjects() // .Where(g => g.GetObjectType() == 1) // .Cast() // .Where(c => c.CharacterData.IsHero()) // .Where(c => Position.GetDistance(c.GetPosition()) <= areaEffect.Radius) // .ToList(); // var team0Players = playersInZone.Where(p => GetBattle.GetPlayerIndexesByTeam(0).Contains(p.GetPlayer().PlayerIndex)).ToList(); // var team1Players = playersInZone.Where(p => GetBattle.GetPlayerIndexesByTeam(1).Contains(p.GetPlayer().PlayerIndex)).ToList(); // if (team0Players.Count > 0 && !state.CaptureEffectActiveTeam0 && !state.HillCompleteEffectSpawnedTeam0 && state.CanContinueUpTeam0) // { // state.CurrentCaptureEffectTeam0 = new AreaEffect(17, captureData.GetInstanceId()); // state.CurrentCaptureEffectTeam0.SetPosition(GetX(), GetY(), 0); // state.CurrentCaptureEffectTeam0.SetIndex(0); // GameObjectManager.AddGameObject(state.CurrentCaptureEffectTeam0); // state.CurrentCaptureEffectTeam0.SetForcedVisible(); // state.CaptureEffectActiveTeam0 = true; // } // else if (team0Players.Count == 0 && state.CaptureEffectActiveTeam0 && state.CanContinueUpTeam0) // { // GameObjectManager.RemoveGameObject(state.CurrentCaptureEffectTeam0); // state.CurrentCaptureEffectTeam0 = null; // state.CaptureEffectActiveTeam0 = false; // } // if (team1Players.Count > 0 && !state.CaptureEffectActiveTeam1 && !state.HillCompleteEffectSpawnedTeam1 && state.CanContinueUpTeam1) // { // state.CurrentCaptureEffectTeam1 = new AreaEffect(captureData.GetClassId(), captureData.GetInstanceId()); // state.CurrentCaptureEffectTeam1.SetPosition(GetX(), GetY(), 0); // state.CurrentCaptureEffectTeam1.SetIndex(1); // GameObjectManager.AddGameObject(state.CurrentCaptureEffectTeam1); // state.CurrentCaptureEffectTeam1.SetForcedVisible(); // state.CaptureEffectActiveTeam1 = true; // } // else if (team1Players.Count == 0 && state.CaptureEffectActiveTeam1 && state.CanContinueUpTeam1) // { // GameObjectManager.RemoveGameObject(state.CurrentCaptureEffectTeam1); // state.CurrentCaptureEffectTeam1 = null; // state.CaptureEffectActiveTeam1 = false; // } // if (!state.GaugeTeam0 && state.GaugeTeam0Effect == null) // { // state.GaugeTeam0Effect = new AreaEffect(gaugeData.GetClassId(), gaugeData.GetInstanceId()); // state.GaugeTeam0Effect.SetPosition(GetX(), GetY(), 0); // state.GaugeTeam0Effect.SetIndex(0); // GameObjectManager.AddGameObject(state.GaugeTeam0Effect); // state.GaugeTeam0 = true; // } // if (!state.GaugeTeam1 && state.GaugeTeam1Effect == null) // { // state.GaugeTeam1Effect = new AreaEffect(gaugeData.GetClassId(), gaugeData.GetInstanceId()); // state.GaugeTeam1Effect.SetPosition(GetX(), GetY(), 0); // state.GaugeTeam1Effect.SetIndex(1); // GameObjectManager.AddGameObject(state.GaugeTeam1Effect); // state.GaugeTeam1Effect.SetForcedVisible(); // state.GaugeTeam1 = true; // } // if (state.GaugeTeam0Effect != null && state.GaugeTeam0) // { // state.GaugeTeam0Effect.SetForcedVisible(); // if(_count == 1) // { // state.GaugeTeam0Effect.Payback = GetBattle.GetZone1Score(); // } // else // { // state.GaugeTeam0Effect.Payback = state.ZonePercentageTeam0; // } // } // if (state.GaugeTeam1Effect != null && state.GaugeTeam1) // { // state.GaugeTeam1Effect.SetForcedVisible(); // if (_count == 1) // { // state.GaugeTeam1Effect.Payback = GetBattle.GetZone2Score(); // } // else // { // state.GaugeTeam1Effect.Payback = state.ZonePercentageTeam1; // } // } // int currentTicks = GetBattle.GetTicksGone(); // if (team0Players.Count > 0 && currentTicks >= state.LastUpTickTeam0 + _UpTicks && state.CanContinueUpTeam0) // { // if (team1Players.Count > 0) // { // if (_count != 1 && state.ZonePercentageTeam1 > 0) // { // state.ZonePercentageTeam1 = Math.Max(0, state.ZonePercentageTeam1 - 2); // } // state.LastUpTickTeam0 = currentTicks; // } // else // { // GetBattle.AddScoreTo1Zone(); // state.LastUpTickTeam0 = currentTicks; // if (_count != 1) // { // state.ZonePercentageTeam0 += 2; // } // } // } // if (team1Players.Count > 0 && currentTicks >= state.LastUpTickTeam1 + _UpTicks && state.CanContinueUpTeam1) // { // if (team0Players.Count > 0) // { // if (_count != 1 && state.ZonePercentageTeam0 > 0) // { // state.ZonePercentageTeam0 = Math.Max(0, state.ZonePercentageTeam0 - 2); // } // state.LastUpTickTeam1 = currentTicks; // } // else // { // GetBattle.AddScoreTo2Zone(); // state.LastUpTickTeam1 = currentTicks; // if (_count != 1) // { // state.ZonePercentageTeam1 += 2; // } // } // } // if (GetBattle.GetZone1Score() >= 100 || state.ZonePercentageTeam0 >= 100) // { // if (!state.HillCompleteEffectSpawnedTeam0) // { // GameObjectManager.RemoveGameObject(state.CurrentCaptureEffectTeam0); // GameObjectManager.RemoveGameObject(state.CurrentCaptureEffectTeam1); // GameObjectManager.RemoveGameObject(state.GaugeTeam0Effect); // GameObjectManager.RemoveGameObject(state.GaugeTeam1Effect); // AreaEffect completeEffect = new AreaEffect(DataTables.Get(DataType.AreaEffect).GetData("KingOfHillAreaComplete").GetClassId(), DataTables.Get(DataType.AreaEffect).GetData("KingOfHillAreaComplete").GetInstanceId()); // completeEffect.SetPosition(GetX(), GetY(), 0); // if (GetBattle.GetKOHZoneCount() == 1) // { // completeEffect.SetIndex(0); // } // else if (GetBattle.GetKOHZoneCount() == 2) // { // completeEffect.SetIndex(0); // state.CanContinueUpTeam0 = false; // } // GameObjectManager.AddGameObject(completeEffect); // completeEffect.SetForcedVisible(); // state.HillCompleteEffectSpawnedTeam0 = true; // GetBattle.GetPlayersByTeam(0)[0].AddScore(1); // } // } // if (GetBattle.GetZone2Score() >= 100 || state.ZonePercentageTeam1 >= 100) // { // if (!state.HillCompleteEffectSpawnedTeam1) // { // GameObjectManager.RemoveGameObject(state.CurrentCaptureEffectTeam0); // GameObjectManager.RemoveGameObject(state.CurrentCaptureEffectTeam1); // GameObjectManager.RemoveGameObject(state.GaugeTeam0Effect); // GameObjectManager.RemoveGameObject(state.GaugeTeam1Effect); // AreaEffect completeEffect = new AreaEffect(DataTables.Get(DataType.AreaEffect).GetData("KingOfHillAreaComplete").GetClassId(), DataTables.Get(DataType.AreaEffect).GetData("KingOfHillAreaComplete").GetInstanceId()); // completeEffect.SetPosition(GetX(), GetY(), 0); // if (GetBattle.GetKOHZoneCount() == 1) // { // completeEffect.SetIndex(1); // } // else if (GetBattle.GetKOHZoneCount() == 2) // { // completeEffect.SetIndex(1); // state.CanContinueUpTeam1 = false; // } // GameObjectManager.AddGameObject(completeEffect); // completeEffect.SetForcedVisible(); // state.HillCompleteEffectSpawnedTeam1 = true; // GetBattle.GetPlayersByTeam(1)[0].AddScore(1); // } // } // } Battle.BattleMode battle = GameObjectManager.GetBattle(); int _UpTicks = 15; int _count = battle.GetKOHZoneCount(); switch (_count) { case 2: _UpTicks = 10; break; case 3: _UpTicks = 5; break; } if (battle.GetTicksGone() > 120) { var state = battle.GetZoneByUID(KOHUID); var playersInZone = GameObjectManager.GetGameObjects() .Where(g => g.GetObjectType() == 1) .Cast() .Where(c => c.CharacterData.IsHero()) .Where(c => Position.GetDistance(c.GetPosition()) <= EffectData.Radius) .ToList(); var team0Players = playersInZone.Where(p => p.GetIndex() / 16 == 0).ToList(); var team1Players = playersInZone.Where(p => p.GetIndex() / 16 == 1).ToList(); int currentTicks = battle.GetTicksGone(); if (team0Players.Count > 0 && currentTicks >= state.LastUpTickTeam0 + _UpTicks) { if (team1Players.Count == 0) battle.AddScoreTo1Zone(); state.LastUpTickTeam0 = currentTicks; } if (team1Players.Count > 0 && currentTicks >= state.LastUpTickTeam1 + _UpTicks) { if (team0Players.Count == 0) battle.AddScoreTo2Zone(); state.LastUpTickTeam1 = currentTicks; } } } } public bool BlocksMovement(int x, int y, int radius) { if (EffectData.Name != "WallyUltiArea") { return false; } return Position.GetDistance(new Supercell.Laser.Titan.Math.LogicVector2(x, y)) <= GetRadius() + radius; } public bool BlocksProjectiles(int x, int y, int radius) { if (EffectData.Name != "WallyUltiArea") { return false; } return Position.GetDistance(new Supercell.Laser.Titan.Math.LogicVector2(x, y)) <= GetRadius() + radius; } public override void Encode(BitStream bitStream, bool isOwnObject, int visionTeam) { base.Encode(bitStream, isOwnObject, visionTeam); bitStream.WritePositiveInt(GetFadeCounter(), 4); bitStream.WritePositiveIntMax127(0); } public void SetSource(Character source) { m_source = source; } public void SetDamage(int damage) { m_damage = damage; } public override int GetRadius() { return EffectData.Radius; } public override bool ShouldDestruct() { return m_ticksElapsed >= EffectData.TimeMs / 50; } public override int GetObjectType() { return 3; } } }