public static Data.ChunkData Load(Utils.Vector3i position, out string error) { var chunk = LoadChunkWithoutBlockData(position, out error); if (!string.IsNullOrWhiteSpace(error) || chunk == null) { return(null); } return(Load(chunk.DataBaseID, out error)); }
/// <summary> /// Busca na aplicação o chunk indexado pela posição /// </summary> /// <param name="position">X,Y,Z do chunk</param> /// <returns>Caso exista retorna chunk encontrado caso contrário null</returns> public Data.ChunkData ChunkByPosition(Utils.Vector3i position) { List <Data.ChunkData> chunks; int hashKey = position.GetHashCode(); if (this.PositionIndexedChunks.TryGetValue(hashKey, out chunks) && chunks != null) { lock (chunks) { foreach (var chunk in chunks) { if (chunk.Position.Equals(position)) { return(chunk); } } } } if (AllInMemory) { return(null); } //caso não encontre busca no banco string error; //caso não encontre verifica se existe no banco fora do cache var databaseChunk = DAO.Terrain.ChunkData.Load(position, out error); if (!string.IsNullOrWhiteSpace(error)) { throw new Exception(error); } if (databaseChunk == null) { return(null); } return(databaseChunk); }
private static Data.ChunkData LoadChunkWithoutBlockData(Utils.Vector3i position, out string error) { error = null; SqlConnection conn = GameApplication.Current.ConnectionManager.OpenConnection(); try { SqlCommand comm = new SqlCommand("select * from dbo.Chunk where X = @X and Y = @Y and Z = @Z", conn); comm.Parameters.AddWithValue("X", position.x); comm.Parameters.AddWithValue("Y", position.y); comm.Parameters.AddWithValue("Z", position.z); using (var reader = comm.ExecuteReader()) { if (!reader.Read()) { return(null); } long DataBaseID = (long)reader["ID"]; int x = (int)reader["X"]; int y = (int)reader["Y"]; int z = (int)reader["Z"]; int MapID = (int)reader["MapID"]; return(new Data.ChunkData(MapID, DataBaseID, new SandBoxEngine.Terrain.Utils.Vector3i(x, y, z))); } } catch (Exception ex) { error = ex.ToString(); return(null); } finally { GameApplication.Current.ConnectionManager.CloseConnection(conn); } }
public bool Start(out string error) { error = null; //Start instance and loading resources AllInMemory = true;// tudo em memoria BlockSet = new Map.BlockSet(); LastChunkMemoryID = -1; WorldMap = new Map.Map(); WorldMap.MapID = 1; WorldMap.MapCustomer = new WorldMapCustomer(); WorldMap.MinSize = new Utils.Vector3i(6, 6, 6); //224 blocos altura max, 10x10 chunks de area WorldMap.MaxSize = new Utils.Vector3i(10, 224, 10); MapLimits = Utils.Vector3i.zero; Console.WriteLine("Loading BlockSet..."); BlockSet = DAO.Terrain.Block.LoadBlockSet(out error); if (!String.IsNullOrWhiteSpace(error)) { return(false); } var first = BlockSet.Blocks.Values.FirstOrDefault(); WorldMap.DefaultBlock = first; Console.WriteLine("Loading Chunks and Blocks..."); long totalChunks = DAO.Terrain.ChunkData.DataBaseCount(out error); if (!String.IsNullOrWhiteSpace(error)) { return(false); } //define capacidade do cache em memoria int ChunkIndexCapacity; if (totalChunks > int.MaxValue) { ChunkIndexCapacity = int.MaxValue; } else { ChunkIndexCapacity = (int)totalChunks; } ChunksByMemoryID = new ConcurrentDictionary <int, List <Data.ChunkData> >(8, ChunkIndexCapacity); ChunksByDataBaseID = new ConcurrentDictionary <int, List <Data.ChunkData> >(16, ChunkIndexCapacity); PositionIndexedChunks = new ConcurrentDictionary <int, List <Data.ChunkData> >(8, ChunkIndexCapacity); //define capacidade da fila de insert e update de terrenos ChunkInsertQueue = new Queue <Data.ChunkData>(10000); BlockInsertOrUpdateQueue = new Queue <Data.BlockData>(100000); if (!DAO.Terrain.ChunkData.LoadAllToApplication(out error)) { return(false); } Console.WriteLine("Terrain loaded!"); return(true); }
public static Vector3i GetNeighbourDirection(Vector3i a, Vector3i b) { return(b - a); }
/// <summary> /// Adiciona novo chunk no cache de memoria /// </summary> /// <param name="chunk">Chunk a ser adiciona no cache de memoria</param> /// <returns>Retorna ID na memoria gerado para o chunk ou -1 caso não consiga adicionar o id de memoria do chunk é atualizado no objeto caso tenha sucesso</returns> public long AddChunk(Data.ChunkData chunk) { if (chunk == null) { return(-1); } int maxX = MapLimits.x; int maxZ = MapLimits.z; int maxY = MapLimits.y; if (MapLimits.x < chunk.Position.x) { maxX = chunk.Position.x; } if (MapLimits.y < chunk.Position.y) { maxY = chunk.Position.y; } if (MapLimits.z < chunk.Position.z) { maxZ = chunk.Position.z; } MapLimits = new Vector3i(maxX, maxY, maxZ); int positionHashKey = chunk.Position.GetHashCode(); //busca ou cria index para o hash var positionIndexedChunks = this.PositionIndexedChunks.GetOrAdd(positionHashKey, new List <Data.ChunkData>()); long MemoryID = -1; //incrementa ID lock (LockChunkMemoryIDIncrement) { LastChunkMemoryID++; MemoryID = LastChunkMemoryID; } var hashKey = MemoryID.GetHashCode(); //Tenta adicionar na memoria e no hashIndex var chunks = this.ChunksByMemoryID.GetOrAdd(hashKey, new List <Data.ChunkData>()); lock (chunks) { chunks.Add(chunk); } chunk.MemoryID = MemoryID; lock (positionIndexedChunks) { //adiciona no index positionIndexedChunks.Add(chunk); } if (chunk.DataBaseID <= -1) { lock (ChunkInsertQueue) { ChunkInsertQueue.Enqueue(chunk); } } else { //adiciona no index de base de dados caso ja exista o ID do banco var dataBaseHashKey = chunk.DataBaseID.GetHashCode(); var dataBaseChunks = this.ChunksByDataBaseID.GetOrAdd(dataBaseHashKey, new List <Data.ChunkData>()); lock (dataBaseChunks) { dataBaseChunks.Add(chunk); } } return(MemoryID); }
public static bool AreNeighbours(Vector3i a, Vector3i b) { return((a.x == b.x || a.x == b.x + 1 || a.x == b.x - 1) && (a.y == b.y || a.y == b.y + 1 || a.y == b.y - 1) && (a.z == b.z || a.z == b.z + 1 || a.z == b.z - 1)); }
public static int IndexOfDirection(Vector3i direction) { return(System.Array.IndexOf(allDirections, direction)); }
public bool Equals(Vector3i vector) { return(x == vector.x && y == vector.y && z == vector.z); }
public float Distance(Vector3i v) { return(Distance(this, v)); }
public int FlatDistanceSquared(Vector3i v) { return(FlatDistanceSquared(this, v)); }