using VeloBrawl.Supercell.Titan.CommonUtils.Utils; using VeloBrawl.Titan.DataStream; using VeloBrawl.Titan.Mathematical; using VeloBrawl.Titan.Mathematical.Data; using VeloBrawl.Titan.Utilities; using VeloBrawl.Tools.LaserCsv; using VeloBrawl.Tools.LaserCsv.Manufacturer.Laser; namespace VeloBrawl.General.NetIsland.LaserBattle.Objects.Laser; public class LogicAreaEffectServer : LogicGameObjectServer { private readonly List _alreadyDamagedList; private readonly LogicAreaEffectData _logicAreaEffectData; private readonly LogicBattleModeServer _logicBattleModeServer; private readonly LogicAreaEffectData _logicParentAreaEffectData = null!; private int _lifeTime; private LogicCharacterServer _logicCharacterServerSource = null!; private int _preyDamage; private bool _staticSourcePosition; private int _tick; public bool IsPermanent; public int KohZoneId = -1; public int Payback; private int _kohLastTickTeam0; private int _kohLastTickTeam1; public LogicAreaEffectServer(LogicBattleModeServer logicBattleModeServer, int classId, int instanceId, int index) : base(logicBattleModeServer, classId, instanceId, 0, index) { _logicBattleModeServer = logicBattleModeServer; _logicAreaEffectData = ((LogicAreaEffectData?)LogicDataTables.GetDataById(GlobalId.CreateGlobalId(classId, instanceId)))!; _alreadyDamagedList = new List(); _staticSourcePosition = false; if (_logicAreaEffectData.GetParentAreaEffectForSkin() != "") _logicParentAreaEffectData = LogicDataTables.GetAreaEffectByName(_logicAreaEffectData.GetParentAreaEffectForSkin()); } public override void Tick() { _tick++; SetLifeTimeConsumedPercent((int)(_tick * 2.5)); if (_staticSourcePosition) SetPosition(_logicCharacterServerSource.GetPosition()); if (KohZoneId >= 0) TickKingOfHillZone(); } private void TickKingOfHillZone() { const int upTicks = 15; const int winScore = 100; var radius = _logicAreaEffectData.GetRadius(); var ticks = _logicBattleModeServer.GetTicksGone(); int team0Count = 0, team1Count = 0; foreach (var obj in GetLogicGameObjectManager().GetNumGameObjects()) { if (obj is not LogicCharacterServer hero) continue; if (!hero.GetCharacterData().IsHero()) continue; var player = hero.GetPlayer(); if (player == null) continue; var dist2 = LogicGamePlayUtil.GetDistanceSquaredBetween(GetX(), GetY(), hero.GetX(), hero.GetY()); if (dist2 > radius * radius) continue; if (player.GetTeamIndex() == 0) team0Count++; else team1Count++; } if (team0Count > 0 && team1Count == 0 && ticks >= _kohLastTickTeam0 + upTicks) { _logicBattleModeServer.ZoneScore[0]++; _kohLastTickTeam0 = ticks; } if (team1Count > 0 && team0Count == 0 && ticks >= _kohLastTickTeam1 + upTicks) { _logicBattleModeServer.ZoneScore[1]++; _kohLastTickTeam1 = ticks; } Payback = _logicBattleModeServer.ZoneScore[0] > _logicBattleModeServer.ZoneScore[1] ? _logicBattleModeServer.ZoneScore[0] : _logicBattleModeServer.ZoneScore[1]; } public void SetPreyOnTheWeak(int prayDamage) { _preyDamage = prayDamage; } public void SetSource(LogicCharacterServer logicCharacterServer, bool staticSourcePosition = false) { _logicCharacterServerSource = logicCharacterServer; _staticSourcePosition = staticSourcePosition; } public void SetLifeTimeConsumedPercent(int v1) { _lifeTime = v1; } public override int GetRadius() { return _logicAreaEffectData.GetRadius(); } public LogicAreaEffectData GetAreaEffectData(bool isGetterParent) { return isGetterParent ? _logicParentAreaEffectData : _logicAreaEffectData; } public override bool ShouldDestruct() { if (IsPermanent) return false; var timeMs = _logicAreaEffectData.GetTimeMs(); return timeMs > 0 && _tick >= timeMs / 50; } public override void Encode(BitStream bitStream, bool isOwnObject, int visionIndex, int visionTeam) { base.Encode(bitStream, isOwnObject, visionIndex, visionTeam); bitStream.WritePositiveIntMax127(_lifeTime); if (bitStream.WriteBoolean(_staticSourcePosition)) bitStream.WritePositiveIntMax134217727((int)_logicCharacterServerSource.GetPlayer()?.OwnObjectId!); bitStream.WritePositiveVIntMax65535OftenZero(Payback); } public override int GetType() { return ObjectTypeHelperTable.AreaEffect.GetObjectType(); } }