namespace Supercell.Laser.Logic.Battle.Objects { using Supercell.Laser.Logic.Battle.Level; using Supercell.Laser.Logic.Battle.Structures; using Supercell.Laser.Logic.Data.Helper; using Supercell.Laser.Logic.Helper; using Supercell.Laser.Titan.DataStream; using Supercell.Laser.Titan.Math; using Supercell.Laser.Logic.Util; public class GameObjectManager // +32 type 64 encode 48IsAlive { public Queue AddObjects; private Queue RemoveObjects; private BattleMode Battle; public List GameObjects; public List Petrols; private int ObjectCounter; public int Ended = -1; public GameObjectManager(BattleMode battle) { Battle = battle; GameObjects = new List(); Petrols = new List(); AddObjects = new Queue(); RemoveObjects = new Queue(); } public GameObject[] GetGameObjects() { return GameObjects.ToArray(); } public Projectile[] GetProjectiles() { List objects = new List(); foreach (GameObject obj in GameObjects) { if (obj != null && obj.GetObjectType() == 1) { objects.Add((Projectile)obj); } } return objects.ToArray(); } public Character[] GetCharacters() { List objects = new List(); foreach (GameObject obj in GameObjects) { if (obj != null && obj.GetObjectType() == 0) { objects.Add((Character)obj); } } foreach (GameObject obj in AddObjects) { if (obj != null && obj.GetObjectType() == 0) { objects.Add((Character)obj); } } return objects.ToArray(); } public Item[] GetItems() { List objects = new List(); foreach (GameObject obj in GameObjects) { if (obj.GetObjectType() == 3) { objects.Add((Item)obj); } } foreach (GameObject obj in AddObjects) { if (obj != null && obj.GetObjectType() == 3) { objects.Add((Item)obj); } } return objects.ToArray(); } public AreaEffect[] GetAreaEffects() { List objects = new List(); foreach (GameObject obj in GameObjects) { if (obj != null && obj.GetObjectType() == 2) { objects.Add((AreaEffect)obj); } } foreach (GameObject obj in AddObjects) { if (obj != null && obj.GetObjectType() == 2) { objects.Add((AreaEffect)obj); } } return objects.ToArray(); } public Projectile[] GetSpecificProjectiles(GameObject gameObject) { List objects = new List(); foreach (GameObject obj in GameObjects) { if (obj != null && obj.GetObjectType() == 1 && obj.GetIndex() / 16 != gameObject.GetIndex() / 16 && obj.GetPosition().GetDistance(gameObject.GetPosition()) <= 600) { objects.Add((Projectile)obj); } } return objects.ToArray(); } public BattleMode GetBattle() { return Battle; } public void PreTick() { for (int i = 0; i < GameObjects.Count; i++) { GameObject gameObject = GameObjects[i]; if (gameObject == null) { GameObjects.Remove(gameObject); i--; continue; } if (gameObject.ShouldDestruct()) { gameObject.OnDestruct(); RemoveGameObject(gameObject); } else { gameObject.ResetEventsOnTick(); } } while (AddObjects.Count > 0) { GameObjects.Add(AddObjects.Dequeue()); } for (int i = 0; i < GameObjects.Count; i++) { GameObject gameObject = GameObjects[i]; if (gameObject == null) { GameObjects.Remove(gameObject); i--; continue; } } while (RemoveObjects.Count > 0) { GameObjects.Remove(RemoveObjects.Dequeue()); } } public Character FindObject(string name) { foreach (Character character in GetCharacters()) { if (character.CharacterData.Name != name) return null; return character; } return null; } public void Tick() { { for (int i = 0; i < GameObjects.Count; i++) { GameObject gameObject = GameObjects[i]; if (gameObject == null) { GameObjects.Remove(gameObject); i--; continue; } gameObject.Tick(); } } } public void AddGameObject(GameObject gameObject) { if (gameObject != null) { gameObject.AttachGameObjectManager(this, GlobalId.CreateGlobalId(gameObject.GetObjectType(), ObjectCounter++)); AddObjects.Enqueue(gameObject); } } public void RemoveGameObject(GameObject gameObject) { RemoveObjects.Enqueue(gameObject); } public GameObject GetGameObjectByID(int globalId) { GameObject gameObject = GameObjects.Find(obj => obj != null && obj.GetGlobalID() == globalId); if (gameObject == null) gameObject = AddObjects.ToList().Find(obj => obj != null && obj.GetGlobalID() == globalId); return gameObject; } public GameObject[] GetGameObjectsByID(int globalId) { List objects = new List(); foreach (GameObject obj in GameObjects) { if (obj != null && obj.GetGlobalID() == globalId) { objects.Add(obj); } } foreach (GameObject obj in AddObjects) { if (obj != null && obj.GetGlobalID() == globalId) { objects.Add(obj); } } return objects.ToArray(); } public List GetGameObjectByCloneOfObjectGlobalId(int globalId) { return GameObjects.FindAll(obj => obj.GetCloneOfObjectGlobalId() == globalId); } public List GetVisibleGameObjects(int teamIndex, int ownObjectGlobalId) { List objects = new List(); try { bool IsInRealm = false; GameObject character = GetGameObjectByID(ownObjectGlobalId); if (character != null) { IsInRealm = character.IsInRealm; } foreach (GameObject obj in GameObjects) { if (obj.IsInRealm ^ IsInRealm) continue; if (obj.GetFadeCounter() > 0 || obj.GetIndex() / 16 == teamIndex) { objects.Add(obj); } } foreach (GameObject obj in AddObjects) { try { if (obj == null) { Parallel.ForEach(GetBattle().m_players, player => { if (player.GameListener != null) { ; } }); GetBattle().m_updateTimer.Dispose(); GetBattle().IsGameOver = true; } if (obj == null) continue; if (obj.IsInRealm ^ IsInRealm) continue; } catch (Exception ex) { Parallel.ForEach(GetBattle().m_players, player => { if (player.GameListener != null) { ; } }); GetBattle().m_updateTimer.Dispose(); GetBattle().IsGameOver = true; } if (obj.GetFadeCounter() > 0 || obj.GetIndex() / 16 == teamIndex) { objects.Add(obj); } } } catch (Exception e) { Console.WriteLine("Battle stopped with exception! Message: " + e.Message + " Trace: " + e.StackTrace); GetBattle().m_updateTimer.Dispose(); GetBattle().IsGameOver = true; } return objects; } //сав сравл 32 /* public void Encode(BitStream bitStream, TileMap tileMap, int ownObjectGlobalId, int playerIndex, int teamIndex) { BattlePlayer[] players = Battle.GetPlayers(); List visibleGameObjects = GetVisibleGameObjects(teamIndex, ownObjectGlobalId); int GameModeVariation = Battle.GetGameModeVariation(); bitStream.WritePositiveInt(ownObjectGlobalId, 21); if (GameModeVariation == 0) { bitStream.WritePositiveVInt(Battle.GetGemGrabCountdown(), 4); } else if (GameModeVariation == 17) { bitStream.WritePositiveIntMax7(1); // if ( *(int *)(v246 + 456) >= 1 ) { bitStream.WritePositiveIntMax127(Battle.GetZone1Score()); bitStream.WritePositiveIntMax127(Battle.GetZone2Score()); } } bitStream.WriteBoolean(false); bitStream.WriteInt(-1, 4); bitStream.WriteBoolean(true); bitStream.WriteBoolean(true); bitStream.WriteBoolean(true); bitStream.WriteBoolean(true); if (tileMap.Width < 22) { bitStream.WritePositiveInt(0, 5); // 0xa820a8 bitStream.WritePositiveInt(0, 6); // 0xa820b4 bitStream.WritePositiveInt(tileMap.Width - 1, 5); // 0xa820c0 } else { bitStream.WritePositiveInt(0, 6); // 0xa820a8 bitStream.WritePositiveInt(0, 6); // 0xa820b4 bitStream.WritePositiveInt(tileMap.Width - 1, 6); // 0xa820c0 } bitStream.WritePositiveInt(tileMap.Height - 1, 6); // 0xa820d0 for (int i = 0; i < tileMap.Width; i++) { for (int j = 0; j < tileMap.Height; j++) { var tile = tileMap.GetTile(i, j, true); if (tile.Data.RespawnSeconds > 0 || tile.Data.IsDestructible || tile.Data.TileCode == "I") { //if (j == 13) //{ // bitStream.WriteBoolean(false); // continue; //} bitStream.WriteBoolean(tile.IsDestructed() && tileMap.GetTile(i, j, true).IsDestructed()); } } } bitStream.WritePositiveVIntMax65535OftenZero(0); bitStream.WritePositiveVIntMax65535OftenZero(Petrols.Count); if (Petrols.Count >= 1) { for (int i = 0; i < Petrols.Count; i++) { bitStream.WritePositiveIntMax63(Petrols[i].X); bitStream.WritePositiveIntMax63(Petrols[i].Y); bitStream.WriteIntMax15(Petrols[i].TeamIndex); } } for (int i = 0; i < players.Length; i++) { bitStream.WriteBoolean(false); bitStream.WriteBoolean(players[i].HasUlti()); if (GameModeVariation == 6) bitStream.WritePositiveIntMax15(0); if (GameModeVariation == 3) bitStream.WriteBoolean(false); // Blue Star bitStream.WriteBoolean(false); bitStream.WriteBoolean(players[i].IsUsingPin(GetBattle().GetTicksGone())); if (players[i].IsUsingPin(GetBattle().GetTicksGone())) { bitStream.WriteIntMax7(players[i].PinIndex); bitStream.WritePositiveIntMax16383(players[i].StartUsingPinTicks); } if (i == playerIndex) { bitStream.WritePositiveIntMax4095(LogicMath.Clamp(players[i].GetUltiCharge(), 0,4000)); bitStream.WriteBoolean(false); bitStream.WriteBoolean(false); } } bitStream.WritePositiveVIntMax255OftenZero(0); switch (GameModeVariation) { case 5: bitStream.WriteBoolean(true); bitStream.WriteIntMax1(1); break; case 6: bitStream.WritePositiveInt(Battle.GetPlayersAliveCountForBattleRoyale(), 4); break; case 9: bitStream.WritePositiveIntMax7(Battle.GetAliveTeams()); break; case 13: bitStream.WritePositiveIntMax131071(0); // DMP break; case 16: bitStream.WritePositiveIntMax8191(0); bitStream.WritePositiveIntMax8191(0); break; } if (GameModeUtil.HasTwoBases(GameModeVariation)) { int hp1 = 0; int hp2 = 0; foreach (Character character in GetCharacters()) { if (!character.CharacterData.IsBase()) continue; if (!character.IsAlive()) continue; if (character.GetIndex() / 16 == 0) hp1 = character.GetHitpointPercentage(); else hp2 = character.GetHitpointPercentage(); } bitStream.WritePositiveIntMax127(hp1); bitStream.WritePositiveIntMax127(hp2); } for (int i = 0; i < players.Length; i++) { if (GameModeVariation != 6 && GameModeVariation != 9) { bitStream.WriteBoolean(true); bitStream.WritePositiveVIntMax255(players[i].GetScore()); } else { bitStream.WriteBoolean(false); } if (GameModeVariation != 6 && GameModeVariation != 9) { if (bitStream.WriteBoolean(players[i].KillList.Count > 0)) { bitStream.WritePositiveIntMax15(players[i].KillList.Count); for (int j = 0; j < players[i].KillList.Count; j++) { bitStream.WritePositiveIntMax15(players[i].KillList[j].PlayerIndex); bitStream.WriteIntMax7(players[i].KillList[j].BountyStarsEarned); } } } else { bitStream.WriteBoolean(false); } } bitStream.WritePositiveVIntMax65535(visibleGameObjects.Count); foreach (GameObject gameObject in visibleGameObjects) { ByteStreamHelper.WriteDataReference(bitStream, gameObject.GetDataId()); } foreach (GameObject gameObject in visibleGameObjects) { bitStream.WritePositiveVIntMax65535(GlobalId.GetInstanceId(gameObject.GetGlobalID())); // 0x2381b4 } foreach (GameObject gameObject in visibleGameObjects) { gameObject.Encode(bitStream, gameObject.GetGlobalID() == ownObjectGlobalId, teamIndex); } }*/ public void Encode(BitStream bitStream, TileMap tileMap, int ownObjectId, int playerIndex, int teamIndex) { // BattlePlayer[] players = Battle.GetPlayers(); List visibleGameObjects = GetVisibleGameObjects(teamIndex, ownObjectId); var GameMode = Battle.GetGameModeVariation(); // List visibleGameObjects = GetVisibleGameObjects(teamIndex, ownObjectId); // var index = (teamIndex * 16) + playerIndex; // var tileMap = Battle.GetTileMap(); // var v1 = LogicMath.Clamp(tileMap.RenderSystem.GetTilemapWidth(), 0, tileMap.RenderSystem.GetTilemapWidth() - 1); // var v2 = LogicMath.Clamp(tileMap.RenderSystem.GetTilemapHeight(), 0, // tileMap.RenderSystem.GetTilemapHeight() - 1); // var v3 = v1 >= 22 - 1; // var v5 = false; // var v5 = Battle.IsPlayFieldMirroredForPlayer(teamIndex); // var v7 = -1; /* var v11 = _gameObjects.Where(obj => obj != null! && (obj.GetType() == ObjectTypeHelperTable.Projectile.GetObjectType() || obj.GetFadeCounterClient() > 0 || obj.ShowedInInvisibleForTeams[teamIndex] || obj.GetIndex() / 16 == teamIndex) && obj.GetObjectGlobalId() > 0).ToList();*/ //var index = v11.gameObject.GetIndex(); // var players = Battle.m_players.Where(obj => obj.OwnObjectId > 0).ToList(); var players = Battle.GetPlayers(); bitStream.WritePositiveIntMax2097151(ownObjectId); switch (GameMode) { case 0: bitStream.WritePositiveVIntMax65535(Battle.GetGemGrabCountdown()); break; case 100: //что курил разраб велосрак bitStream.WritePositiveIntMax7(0); break; case 17: bitStream.WritePositiveIntMax7(1); bitStream.WritePositiveIntMax127(Battle.GetZone1Score()); bitStream.WritePositiveIntMax127(Battle.GetZone2Score()); break; case 20: //нокаут)) //bitStream.WritePositiveIntMax2047(Math.Min(GetBattle().RoundTicks, 2047)); //дым bitStream.WritePositiveIntMax2047(0); //ПОШЕЛ ОН НАХУЙ СЫН ШЛЮХИ bitStream.WriteBoolean(Battle.IsRoundEnding); //раунд окончен bitStream.WriteBoolean(true); //only true bitStream.WritePositiveIntMax3(Battle.CurrentRound); //какой сейчас раунд идет bitStream.WriteBoolean(true);//финал боя???? чо это int[] KnockoutWinners = Battle.GetKnockoutRoundWinners(teamIndex); bitStream.WriteIntMax127(KnockoutWinners[0]); //состояние первого раунда bitStream.WriteIntMax127(KnockoutWinners[1]); //состояние второго раунда bitStream.WriteIntMax127(KnockoutWinners[2]); //состояние третьего раунда break; /* case 0x14u: v34 = ZNK21LogicBattleModeServer18getRoundResetTimerEv(v26); ZN9BitStream23writePositiveIntMax2047Ei(a2, *(unsigned int *)(v26 + 308)); ZN9BitStream12writeBooleanEb(a2, v34 > 0); ZN9BitStream12writeBooleanEb(a2, (unsigned int)(v34 - 10) > 0xA); v35 = ZN17LogicGameModeUtil17getNumberOfRoundsEi(20); v36 = ZN9LogicMath3minEii((unsigned int)(v35 - 1), *(unsigned int *)(v26 + 304)); ZN9BitStream20writePositiveIntMax3Ei(a2, v36); v37 = v34 >= 1 && *(_BYTE *)(v26 + 312) != 0; ZN9BitStream12writeBooleanEb(a2, v37); if ( v35 >= 1 ) { for ( i = 0; i != v35; ++i ) { if ( i < *(int *)(v26 + 828) ) v52 = *(unsigned int *)(*(_QWORD *)(v26 + 816) + 4 * i); else v52 = 0xFFFFFFFFLL; ZN9BitStream14writeIntMax127Ei(a2, v52); } } break;*/ } bitStream.WriteBoolean(false); //что то с тимами bitStream.WriteIntMax15(-1); //хз bitStream.WriteBoolean(false); bitStream.WriteBoolean(false); bitStream.WriteBoolean(false); bitStream.WriteBoolean(false); var v1 = LogicMath.Clamp(tileMap.Width, 0, tileMap.Width - 1); var v2 = LogicMath.Clamp(tileMap.Height, 0, tileMap.Height - 1); if (v1 > 21) { //big bitStream.WritePositiveIntMax63(0); bitStream.WritePositiveIntMax63(0); bitStream.WritePositiveIntMax63(v1); } else { bitStream.WritePositiveIntMax31(0); // 5 бит bitStream.WritePositiveIntMax63(0); // 6 бит bitStream.WritePositiveIntMax31(v1); // 5 бит } bitStream.WritePositiveIntMax63(v2); for (int i = 0; i < tileMap.Width; i++) { for (int j = 0; j < tileMap.Height; j++) { var tile = tileMap.GetTile(i, j, true, true); if (tile.Data.RespawnSeconds > 0 || tile.Data.IsDestructible || tile.Data.TileCode == "I") { //if (j == 13) //{ // bitStream.WriteBoolean(false); // continue; //} bitStream.WriteBoolean(tile.IsDestructed() && tileMap.GetTile(i, j, true).IsDestructed()); } } } bitStream.WritePositiveVIntMax65535OftenZero(tileMap.NewTiles.Count); { for (int i = 0; i < tileMap.NewTiles.Count; i++) { bitStream.WritePositiveIntMax4095(tileMap.NewTiles[i].TileX + tileMap.Width * tileMap.NewTiles[i].TileY); bitStream.WritePositiveIntMax7(tileMap.NewTiles[i].Data.DynamicCode); } } bitStream.WritePositiveVIntMax65535OftenZero(Petrols.Count);//amber's cum if (Petrols.Count >= 1) { for (int i = 0; i < Petrols.Count; i++) { bitStream.WritePositiveIntMax63(Petrols[i].X); bitStream.WritePositiveIntMax63(Petrols[i].Y); //bitStream.WriteIntMax15(Petrols[i].TeamIndex); bitStream.WriteIntMax15(Petrols[i].PlayerIndex); } } for (var i = 0; i < players.Length; i++) { var logicCharacterServer = (Character)GetGameObjectByID(players[i].OwnObjectId); bitStream.WriteBoolean(players[i].IsAlive); bitStream.WriteBoolean(players[i].HasUlti()); if (GameMode == 6) bitStream.WritePositiveIntMax15(0); // players[i].Accessory = null; if (players[i].Accessory != null) { players[i].Accessory.Encode(bitStream, players[i].OwnObjectId == ownObjectId); } // if (players[i].Accessory != null) players[i].Accessory.Encode(bitStream, players[i].OwnObjectId == ownObjectId); if (GameMode == 3) bitStream.WriteBoolean(false); if (players[i].Accessory != null) { bitStream.WritePositiveVIntMax255OftenZero(0); // bitStream.WritePositiveVIntMax255OftenZero(players[i].Accessory.IsActive == true ? 1 : 0); } else { bitStream.WritePositiveVIntMax255OftenZero(0); } bitStream.WriteBoolean(false);//хз bitStream.WriteBoolean(players[i].IsUsingPin(GetBattle().GetTicksGone())); if (players[i].IsUsingPin(GetBattle().GetTicksGone())) { bitStream.WriteIntMax7(players[i].PinIndex); bitStream.WritePositiveIntMax16383(players[i].StartUsingPinTicks); } // bitStream.WriteBoolean(false); // bitStream.WriteBoolean(false); // { // bitStream.WriteIntMax7(0); // bitStream.WritePositiveIntMax16383(0); // } if (i != playerIndex) continue; bitStream.WritePositiveIntMax4095(LogicMath.Clamp(players[i].GetUltiCharge(), 0, 4000)); bitStream.WriteBoolean(players[i].HasUlti()); bitStream.WriteBoolean(false); } bitStream.WritePositiveVIntMax255OftenZero(0); if (GameModeUtil.ModeHasCarryables(GameMode)) { bitStream.WriteBoolean(!(GetBattle().GetGoalTeam() != -1) || GetBattle()._SetStopTicks); bitStream.WriteIntMax1(GetBattle().GetGoalTeam() != -1 ? GetBattle().GetGoalTeam() : 0); } switch (GameMode) { case 6: bitStream.WritePositiveIntMax15(Battle.GetPlayersAliveCountForBattleRoyale()); break; case 8: bitStream.WritePositiveIntMax127(0);//hp safe RoboRumble bitStream.WritePositiveIntMax127(0); bitStream.WriteBoolean(true); break; case 9: bitStream.WritePositiveIntMax7(Battle.GetAliveTeams()); break; case 16: //CTF bitStream.WritePositiveIntMax8191(0); bitStream.WritePositiveIntMax8191(0); break; default: if (GameModeUtil.HasTwoBases(GameMode)) { int hp1 = 0; int hp2 = 0; foreach (Character character in GetCharacters()) { if (!character.CharacterData.IsBase()) continue; if (!character.IsAlive()) continue; if (character.GetIndex() / 16 == 0) hp1 = character.GetHitpointPercentage(); else hp2 = character.GetHitpointPercentage(); } bitStream.WritePositiveIntMax127(hp1); bitStream.WritePositiveIntMax127(hp2); if (GameMode == 11) { bitStream.WritePositiveIntMax255(0); bitStream.WritePositiveIntMax255(0); bitStream.WritePositiveIntMax7(0); bitStream.WritePositiveIntMax7(0); bitStream.WritePositiveIntMax63(0); bitStream.WritePositiveIntMax63(0); bitStream.WriteBoolean(false); } else { // bitStream.WritePositiveIntMax127(0); //bitStream.WriteBoolean(true); } } else { switch (GameMode) { //case 16: //CTF // bitStream.WritePositiveIntMax127(0); // bitStream.WritePositiveIntMax127(0); // break; case 18: bitStream.WritePositiveIntMax127(0); break; case 14: bitStream.WritePositiveIntMax127(0); bitStream.WritePositiveIntMax16383(0); break; case 13: bitStream.WritePositiveIntMax131071(1337); //damage per second break; case 10: // Console.WriteLine("BOSS FIGHT"); bitStream.WritePositiveIntMax127(10); //hp big boss break; case 7: bitStream.WritePositiveIntMax127(0); break; } } break; } for (int i = 0; i < players.Length; i++) { if (GameMode != 6 && GameMode != 9) { bitStream.WriteBoolean(true); bitStream.WritePositiveVIntMax255(players[i].GetScore()); } else { bitStream.WriteBoolean(false); } if (GameMode != 6 && GameMode != 9) { if (bitStream.WriteBoolean(players[i].KillList.Count > 0)) { bitStream.WritePositiveIntMax15(players[i].KillList.Count); for (int j = 0; j < players[i].KillList.Count; j++) { bitStream.WritePositiveIntMax15(players[i].KillList[j].PlayerIndex); bitStream.WriteIntMax7(players[i].KillList[j].BountyStarsEarned); } } } else { bitStream.WriteBoolean(false); } } bitStream.WritePositiveVIntMax65535(visibleGameObjects.Count); //objects if (visibleGameObjects.Count > 0) { foreach (var gameObject in visibleGameObjects) ByteStreamHelper.WriteDataReference(bitStream, gameObject.GetDataId()); foreach (var gameObject in visibleGameObjects) ByteStreamHelper.WriteObjectRunningId(bitStream, gameObject.GetGlobalID()); foreach (var gameObject in visibleGameObjects) gameObject.Encode(bitStream, ownObjectId == gameObject.GetGlobalID(), teamIndex); } if (GameMode != 7) return; if (!bitStream.WriteBoolean(false)) return; bitStream.WritePositiveIntMax32767(0); bitStream.WritePositiveIntMax65535(0); } } }