/// <summary> /// Constructs a new mesh for a landblock /// </summary> public LandblockMesh(LandblockId id) { LandblockId = id; BuildVertices(); BuildTriangles(); }
/// <summary> /// Loads the backing store landblock structure<para /> /// This function is thread safe /// </summary> /// <param name="blockCellID">Any landblock + cell ID within the landblock</param> public static Landblock get_landblock(uint blockCellID) { // client implementation /*if (Landblocks == null || Landblocks.Count == 0) * return null; * * if (!LandDefs.inbound_valid_cellid(cellID) || cellID >= 0x100) * return null; * * var local_lcoord = LandDefs.blockid_to_lcoord(LoadedCellID); * var global_lcoord = LandDefs.gid_to_lcoord(cellID); * * var xDiff = ((int)global_lcoord.Value.X + 8 * MidRadius - (int)local_lcoord.Value.X) / 8; * var yDiff = ((int)global_lcoord.Value.Y + 8 * MidRadius - (int)local_lcoord.Value.Y) / 8; * * if (xDiff < 0 || yDiff < 0 || xDiff < MidWidth || yDiff < MidWidth) * return null; * * return Landblocks[yDiff + xDiff * MidWidth];*/ var landblockID = blockCellID | 0xFFFF; // check if landblock is already cached if (Landblocks.TryGetValue(landblockID, out var landblock)) { return(landblock); } lock (landblockMutex) { // check if landblock is already cached, this time under the lock. if (Landblocks.TryGetValue(landblockID, out landblock)) { return(landblock); } // if not, load into cache landblock = new Landblock(DBObj.GetCellLandblock(landblockID)); if (Landblocks.TryAdd(landblockID, landblock)) { landblock.PostInit(); // ensure landblock manager loaded var lbid = new LandblockId(landblockID); if (!LandblockManager.IsLoaded(lbid)) { // this can happen from encounter spawns sliding down walkable slopes... //log.Debug($"{landblockID:X8} requested from LScape, but not loaded from LandblockManager, adding"); LandblockManager.GetLandblock(lbid, false, false); } } else { Landblocks.TryGetValue(landblockID, out landblock); } return(landblock); } }
/// <summary> /// gets the landblock specified, creating it if it is not already loaded. will create all /// adjacent landblocks if propagate is true (outdoor world roaming). /// </summary> private static Landblock GetLandblock(LandblockId landblockId, bool propagate) { var landblock = landblocks[landblockId.LandblockX, landblockId.LandblockY]; var autoLoad = propagate && landblockId.MapScope == MapScope.Outdoors; // standard check/lock/recheck pattern if (landblock == null || autoLoad && !landblock.AdjacenciesLoaded) { lock (landblockMutex) { landblock = landblocks[landblockId.LandblockX, landblockId.LandblockY]; if (landblock == null || autoLoad && !landblock.AdjacenciesLoaded) { if (landblock == null) { // load up this landblock landblock = landblocks[landblockId.LandblockX, landblockId.LandblockY] = new Landblock(landblockId); // kick off the landblock use time thread // block.StartUseTime(); ActiveLandblocks.Add(landblock); } SetAdjacencies(landblockId, autoLoad); if (autoLoad) { landblock.AdjacenciesLoaded = true; } } } } return(landblock); }
/// <summary> /// gets the landblock specified, creating it if it is not already loaded. will create all /// adjacent landblocks if propagate is true (outdoor world roaming). /// </summary> private static Landblock GetLandblock(LandblockId landblockId, bool propagate) { lock (landblockMutex) { var landblock = landblocks[landblockId.LandblockX, landblockId.LandblockY]; var autoLoad = propagate && landblockId.MapScope == MapScope.Outdoors; // standard check/lock/recheck pattern if (landblock == null || autoLoad && !landblock.AdjacenciesLoaded) { landblock = landblocks[landblockId.LandblockX, landblockId.LandblockY]; if (landblock == null || autoLoad && !landblock.AdjacenciesLoaded) { if (landblock == null) { // load up this landblock landblock = landblocks[landblockId.LandblockX, landblockId.LandblockY] = new Landblock(landblockId); if (!activeLandblocks.Add(landblock)) { log.Error("LandblockManager: failed to add " + (landblock.Id.Raw | 0xFFFF).ToString("X8") + " to active landblocks!"); return(landblock); } } SetAdjacencies(landblockId, autoLoad); if (autoLoad) { landblock.AdjacenciesLoaded = true; } } } return(landblock); } }
/// <summary> /// sets the adjacencies of the specified landblocks. nulls are allowed in the use case of deleting /// or unloading a landblock. Landblock2 is {adjacency} of Landblock1. if autoLoad is true, and /// landblock2 is null, it will be auto loaded. /// /// NOTE: ASSUMES A LOCK ON landblockMutex /// </summary> /// <param name="landblock1">a landblock</param> /// <param name="landblock2">a landblock</param> /// <param name="adjacency">the adjacency of landblock2 relative to landblock1</param> /// <param name="autoLoad">Will load landBlock2 if it's not loaded already</param> private static void SetAdjacency(LandblockId landblock1, LandblockId landblock2, Adjacency adjacency, bool autoLoad = false) { // suppress adjacency logic for indoor areas if (landblock1.MapScope != Entity.Enum.MapScope.Outdoors || landblock2.MapScope != Entity.Enum.MapScope.Outdoors) { return; } Landblock lb1 = landblocks[landblock1.LandblockX, landblock1.LandblockY]; Landblock lb2 = landblocks[landblock2.LandblockX, landblock2.LandblockY]; if (autoLoad && lb2 == null) { lb2 = GetLandblock(landblock2, false); } lb1.SetAdjacency(adjacency, lb2); if (lb2 != null) { int inverse = (((int)adjacency) + 4) % 8; // go halfway around the horn (+4) and mod 8 to wrap around Adjacency inverseAdjacency = (Adjacency)Enum.ToObject(typeof(Adjacency), inverse); lb2.SetAdjacency(inverseAdjacency, lb1); } }
private static void PreloadLandblock(uint landblock, PreloadedLandblocks preloadLandblock) { var landblockID = new LandblockId(landblock); GetLandblock(landblockID, preloadLandblock.IncludeAdjacents, preloadLandblock.Permaload); log.DebugFormat("Landblock {0:X4}, ({1}) preloaded. IncludeAdjacents = {2}, Permaload = {3}", landblockID.Landblock, preloadLandblock.Description, preloadLandblock.IncludeAdjacents, preloadLandblock.Permaload); }
/// <summary> /// Permaloads a list of configurable landblocks if server option is set /// </summary> public static void PreloadConfigLandblocks() { if (ConfigManager.Config.Server.PreloadedLandblocks == null) { log.Info("No configuration found for PreloadedLandblocks, please refer to Config.json.example"); log.Warn("Initializing PreloadedLandblocks with single default for Hebian-To (Global Events)"); log.Warn("Add a PreloadedLandblocks section to your Config.json file and adjust to meet your needs"); ConfigManager.Config.Server.PreloadedLandblocks = new List <PreloadedLandblocks> { new PreloadedLandblocks { Id = "E74EFFFF", Description = "Hebian-To (Global Events)", Permaload = true, IncludeAdjacents = true, Enabled = true } }; } log.InfoFormat("Found {0} landblock entries in PreloadedLandblocks configuration, {1} are set to preload.", ConfigManager.Config.Server.PreloadedLandblocks.Count, ConfigManager.Config.Server.PreloadedLandblocks.Where(x => x.Enabled == true).Count()); foreach (var preloadLandblock in ConfigManager.Config.Server.PreloadedLandblocks) { if (!preloadLandblock.Enabled) { log.DebugFormat("Landblock {0:X4} specified but not enabled in config, skipping", preloadLandblock.Id); continue; } if (uint.TryParse(preloadLandblock.Id, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out uint landblock)) { var landblockID = new LandblockId(landblock); GetLandblock(landblockID, preloadLandblock.IncludeAdjacents, preloadLandblock.Permaload); log.DebugFormat("Landblock {0:X4}, ({1}) preloaded. IncludeAdjacents = {2}, Permaload = {3}", landblockID.Landblock, preloadLandblock.Description, preloadLandblock.IncludeAdjacents, preloadLandblock.Permaload); } } }
/// <summary> /// Loads the backing store landblock structure<para /> /// This function is thread safe /// </summary> /// <param name="blockCellID">Any landblock + cell ID within the landblock</param> public static Landblock get_landblock(uint blockCellID) { var landblockID = blockCellID | 0xFFFF; if (PhysicsEngine.Instance.Server) { var lbid = new LandblockId(landblockID); var lbmLandblock = LandblockManager.GetLandblock(lbid, false, false); return(lbmLandblock.PhysicsLandblock); } // client implementation /*if (Landblocks == null || Landblocks.Count == 0) * return null; * * if (!LandDefs.inbound_valid_cellid(cellID) || cellID >= 0x100) * return null; * * var local_lcoord = LandDefs.blockid_to_lcoord(LoadedCellID); * var global_lcoord = LandDefs.gid_to_lcoord(cellID); * * var xDiff = ((int)global_lcoord.Value.X + 8 * MidRadius - (int)local_lcoord.Value.X) / 8; * var yDiff = ((int)global_lcoord.Value.Y + 8 * MidRadius - (int)local_lcoord.Value.Y) / 8; * * if (xDiff < 0 || yDiff < 0 || xDiff < MidWidth || yDiff < MidWidth) * return null; * * return Landblocks[yDiff + xDiff * MidWidth];*/ // check if landblock is already cached if (Landblocks.TryGetValue(landblockID, out var landblock)) { return(landblock); } lock (landblockMutex) { // check if landblock is already cached, this time under the lock. if (Landblocks.TryGetValue(landblockID, out landblock)) { return(landblock); } // if not, load into cache landblock = new Landblock(DBObj.GetCellLandblock(landblockID)); if (Landblocks.TryAdd(landblockID, landblock)) { landblock.PostInit(); } else { Landblocks.TryGetValue(landblockID, out landblock); } return(landblock); } }
public Landblock(LandblockId id) { Id = id; //Console.WriteLine("Landblock constructor(" + (id.Raw | 0xFFFF).ToString("X8") + ")"); UpdateStatus(LandBlockStatusFlag.IdleUnloaded); // initialize adjacency array adjacencies.Add(Adjacency.North, null); adjacencies.Add(Adjacency.NorthEast, null); adjacencies.Add(Adjacency.East, null); adjacencies.Add(Adjacency.SouthEast, null); adjacencies.Add(Adjacency.South, null); adjacencies.Add(Adjacency.SouthWest, null); adjacencies.Add(Adjacency.West, null); adjacencies.Add(Adjacency.NorthWest, null); UpdateStatus(LandBlockStatusFlag.IdleLoading); actionQueue = new NestedActionQueue(WorldManager.LandblockActionQueue); // create world objects (monster locations, generators) var objects = DatabaseManager.World.GetCachedInstancesByLandblock(Id.Landblock); var factoryObjects = WorldObjectFactory.CreateNewWorldObjects(objects); foreach (var fo in factoryObjects) { AddWorldObject(fo); fo.ActivateLinks(); } // create shard objects (corpses after unloading) DatabaseManager.Shard.GetObjectsByLandblock(Id.Landblock, ((List <Biota> biotas) => { var shardObjects = (WorldObjectFactory.CreateWorldObjects(biotas)); foreach (var so in shardObjects) { AddWorldObject(so); } })); _landblock = LScape.get_landblock(Id.Raw); //LoadMeshes(objects); SpawnEncounters(); UpdateStatus(LandBlockStatusFlag.IdleLoaded); // FIXME(ddevec): Goal: get rid of UseTime() function... actionQueue.EnqueueAction(new ActionEventDelegate(() => UseTimeWrapper())); motionQueue = new NestedActionQueue(WorldManager.LandblockMotionQueue); LastActiveTime = Timer.CurrentTime; QueueNextHeartBeat(); }
public static void ForceLoadLandBlock(LandblockId blockid) { Stopwatch sw = Stopwatch.StartNew(); GetLandblock(blockid, false); sw.Stop(); log.DebugFormat("Loaded Landblock {0} in {1} milliseconds ", blockid.Landblock.ToString("X4"), sw.ElapsedMilliseconds); Console.WriteLine("Loaded Landblock {0} in {1} milliseconds ", blockid.Landblock.ToString("X4"), sw.ElapsedMilliseconds); }
/// <summary> /// Determines the split line direction /// for a cell triangulation /// </summary> /// <param name="id">A reference to the landblock ID</param> /// <param name="cellX">The horizontal cell position within the landblock</param> /// <param name="cellY">The vertical cell position within the landblock</param> /// <returns>TRUE if NW-SE split, FALSE if NE-SW split</returns> public bool GetSplitDir(LandblockId id, int cellX, int cellY) { // get the global tile offsets var x = (id.LandblockX * 8) + cellX; var y = (id.LandblockY * 8) + cellY; // Thanks to https://github.com/deregtd/AC2D for this bit var dw = x * y * 0x0CCAC033 - x * 0x421BE3BD + y * 0x6C1AC587 - 0x519B8F25; return((dw & 0x80000000) == 0); }
/// <summary> /// Returns a reference to a landblock, loading the landblock if not already active /// </summary> public static Landblock GetLandblock(LandblockId landblockId, bool loadAdjacents, bool permaload = false) { Landblock landblock; lock (landblockMutex) { bool setAdjacents = false; landblock = landblocks[landblockId.LandblockX, landblockId.LandblockY]; if (landblock == null) { // load up this landblock landblock = landblocks[landblockId.LandblockX, landblockId.LandblockY] = new Landblock(landblockId); if (!loadedLandblocks.Add(landblock)) { log.Error($"LandblockManager: failed to add {landblock.Id.Raw:X8} to active landblocks!"); return(landblock); } landblockGroupPendingAdditions.Add(landblock); landblock.Init(); setAdjacents = true; } if (permaload) { landblock.Permaload = true; } // load adjacents, if applicable if (loadAdjacents) { var adjacents = GetAdjacentIDs(landblock); foreach (var adjacent in adjacents) { GetLandblock(adjacent, false, permaload); } setAdjacents = true; } // cache adjacencies if (setAdjacents) { SetAdjacents(landblock, true, true); } } return(landblock); }
/// <summary> /// Returns an adjacent landblock ID for a landblock /// </summary> private static LandblockId?GetAdjacentID(LandblockId landblock, Adjacency adjacency) { int lbx = landblock.LandblockX; int lby = landblock.LandblockY; switch (adjacency) { case Adjacency.North: lby += 1; break; case Adjacency.South: lby -= 1; break; case Adjacency.West: lbx -= 1; break; case Adjacency.East: lbx += 1; break; case Adjacency.NorthWest: lby += 1; lbx -= 1; break; case Adjacency.NorthEast: lby += 1; lbx += 1; break; case Adjacency.SouthWest: lby -= 1; lbx -= 1; break; case Adjacency.SouthEast: lby -= 1; lbx += 1; break; } if (lbx < 0 || lbx > 254 || lby < 0 || lby > 254) { return(null); } return(new LandblockId((byte)lbx, (byte)lby)); }
public static List <Landblock> GetAdjacents(LandblockId landblockID) { Landblock landblock; lock (landblockMutex) landblock = landblocks[landblockID.LandblockX, landblockID.LandblockY]; if (landblock == null) { return(null); } return(GetAdjacents(landblock)); }
public Landblock(LandblockId id) { Id = id; //Console.WriteLine("Landblock constructor(" + (id.Raw | 0xFFFF).ToString("X8") + ")"); UpdateStatus(LandBlockStatusFlag.IdleUnloaded); // initialize adjacency array adjacencies.Add(Adjacency.North, null); adjacencies.Add(Adjacency.NorthEast, null); adjacencies.Add(Adjacency.East, null); adjacencies.Add(Adjacency.SouthEast, null); adjacencies.Add(Adjacency.South, null); adjacencies.Add(Adjacency.SouthWest, null); adjacencies.Add(Adjacency.West, null); adjacencies.Add(Adjacency.NorthWest, null); UpdateStatus(LandBlockStatusFlag.IdleLoading); // create world objects (monster locations, generators) var objects = DatabaseManager.World.GetCachedInstancesByLandblock(Id.Landblock); var factoryObjects = WorldObjectFactory.CreateNewWorldObjects(objects); foreach (var fo in factoryObjects) { AddWorldObject(fo); fo.ActivateLinks(); } // create shard objects (corpses after unloading) DatabaseManager.Shard.GetObjectsByLandblock(Id.Landblock, ((List <Biota> biotas) => { var shardObjects = (WorldObjectFactory.CreateWorldObjects(biotas)); foreach (var so in shardObjects) { AddWorldObject(so); } })); _landblock = LScape.get_landblock(Id.Raw); //LoadMeshes(objects); SpawnEncounters(); UpdateStatus(LandBlockStatusFlag.IdleLoaded); lastActiveTime = DateTime.UtcNow; }
public House GetDungeonHouse() { var landblockId = new LandblockId(House.DungeonLandblockID); var isLoaded = LandblockManager.IsLoaded(landblockId); if (!isLoaded) { return(null); } var loaded = LandblockManager.GetLandblock(landblockId, false); var wos = loaded.GetWorldObjectsForPhysicsHandling(); return(wos.FirstOrDefault(wo => wo.WeenieClassId == House.WeenieClassId) as House); }
public static void CreateState() { WorldObjects = new Dictionary <ObjectGuid, WorldObject>(); var landblock = new LandblockId(0x7D64FFFF); var player = new Player(); player.Guid = new ObjectGuid(1); //player.Name = "gmriggs"; //player.Radius = 5.0f; player.Location.landblockId = landblock; player.Location.Pos = new Vector3(66, 130, 12); player.Location.Rotation = Quaternion.Identity; WorldObjects.Add(player.Guid, player); }
/// <summary> /// Sets the adjacencies for a landblock /// </summary> /// <param name="landblockId">The landblock to set the adjacencies for</param> /// <param name="autoLoad">Flag indicates if unloaded adjacencies should be instantiated</param> private static void SetAdjacencies(LandblockId landblockId, bool autoLoad) { int x = landblockId.LandblockX; int y = landblockId.LandblockY; if (x > 0) { SetAdjacency(landblockId, landblockId.West, Adjacency.West, autoLoad); if (y > 0) { SetAdjacency(landblockId, landblockId.SouthWest, Adjacency.SouthWest, autoLoad); } if (y < 254) { SetAdjacency(landblockId, landblockId.NorthWest, Adjacency.NorthWest, autoLoad); } } if (x < 254) { SetAdjacency(landblockId, landblockId.East, Adjacency.East, autoLoad); if (y > 0) { SetAdjacency(landblockId, landblockId.SouthEast, Adjacency.SouthEast, autoLoad); } if (y < 254) { SetAdjacency(landblockId, landblockId.NorthEast, Adjacency.NorthEast, autoLoad); } } if (y > 0) { SetAdjacency(landblockId, landblockId.South, Adjacency.South, autoLoad); } if (y < 254) { SetAdjacency(landblockId, landblockId.North, Adjacency.North, autoLoad); } }
/// <summary> /// If the landblock is loaded, return a reference to the current House object /// else return a copy of the House biota from the latest info in the db /// /// <param name="callback">called when the slumlord inventory is fully loaded</param> public static void GetHouse(uint houseGuid, Action <House> callback) { var landblock = (ushort)((houseGuid >> 12) & 0xFFFF); var landblockId = new LandblockId((uint)(landblock << 16 | 0xFFFF)); var isLoaded = LandblockManager.IsLoaded(landblockId); if (!isLoaded) { // landblock is unloaded // return a copy of the House biota from the latest info in the db var houseBiota = House.Load(houseGuid); RegisterCallback(houseBiota, callback); return; } // landblock is loaded, return a reference to the current House object var loaded = LandblockManager.GetLandblock(landblockId, false); var house = loaded.GetObject(new ObjectGuid(houseGuid)) as House; if (house != null && house.SlumLord != null) { if (!house.SlumLord.InventoryLoaded) { RegisterCallback(house, callback); } else { callback(house); } } else if (!loaded.CreateWorldObjectsCompleted) { var houseBiota = House.Load(houseGuid); RegisterCallback(houseBiota, callback); } else { log.Error($"[HOUSE] HouseManager.GetHouse({houseGuid:X8}): couldn't find house on loaded landblock"); } }
private void picImage_Click(object sender, EventArgs e) { txtDetail.Clear(); // this is used for unloaded and loaded landblocks LandblockId landblockid = new LandblockId((byte)selrow, (byte)selcol); txtDetail.Text = string.Format("Landblock: {0} ", landblockid.Raw.ToString("X")); // this only works if the landblock is loaded.. LandBlockStatus status = new LandBlockStatus(); status = Diagnostics.GetLandBlockKey(selrow, selcol); if (status != null) { txtDetail.Text += Environment.NewLine + string.Format("Status: {0} ", status.LandBlockStatusFlag.ToString()); txtDetail.Text += Environment.NewLine + string.Format("Players: {0} ", status.PlayerCount); } }
public Landblock(LandblockId id) { this.Id = id; UpdateStatus(LandBlockStatusFlag.IdleUnloaded); // initialize adjacency array adjacencies.Add(Adjacency.North, null); adjacencies.Add(Adjacency.NorthEast, null); adjacencies.Add(Adjacency.East, null); adjacencies.Add(Adjacency.SouthEast, null); adjacencies.Add(Adjacency.South, null); adjacencies.Add(Adjacency.SouthWest, null); adjacencies.Add(Adjacency.West, null); adjacencies.Add(Adjacency.NorthWest, null); UpdateStatus(LandBlockStatusFlag.IdleLoading); actionQueue = new NestedActionQueue(WorldManager.ActionQueue); var objects = DatabaseManager.World.GetWeenieInstancesByLandblock(this.Id.Landblock); // Instances var factoryObjects = WorldObjectFactory.CreateWorldObjects(objects); factoryObjects.ForEach(fo => { if (!worldObjects.ContainsKey(fo.Guid)) { worldObjects.Add(fo.Guid, fo); fo.SetParent(this); } }); LoadMeshes(objects); UpdateStatus(LandBlockStatusFlag.IdleLoaded); // FIXME(ddevec): Goal: get rid of UseTime() function... actionQueue.EnqueueAction(new ActionEventDelegate(() => UseTimeWrapper())); motionQueue = new NestedActionQueue(WorldManager.MotionQueue); }
/// <summary> /// Returns a reference to a landblock, loading the landblock if not already active /// </summary> public static Landblock GetLandblock(LandblockId landblockId, bool loadAdjacents, bool permaload = false) { Landblock landblock = null; lock (landblockMutex) { landblock = landblocks[landblockId.LandblockX, landblockId.LandblockY]; if (landblock == null) { // load up this landblock landblock = landblocks[landblockId.LandblockX, landblockId.LandblockY] = new Landblock(landblockId); if (!activeLandblocks.Add(landblock)) { log.Error($"LandblockManager: failed to add {landblock.Id:X8} to active landblocks!"); return(landblock); } } if (permaload) { landblock.Permaload = true; } } // load adjacents, if applicable if (loadAdjacents) { var adjacents = GetAdjacentIDs(landblock); foreach (var adjacent in adjacents) { GetLandblock(adjacent, false, permaload); } } // cache adjacencies SetAdjacents(landblock, true, true); return(landblock); }
public House GetHouse() { if (HouseInstance == null) { return(House); } var houseGuid = HouseInstance.Value; var landblock = (ushort)((houseGuid >> 12) & 0xFFFF); var landblockId = new LandblockId((uint)(landblock << 16 | 0xFFFF)); var isLoaded = LandblockManager.IsLoaded(landblockId); if (!isLoaded) { return(House); } var loaded = LandblockManager.GetLandblock(landblockId, false); return(loaded.GetObject(new ObjectGuid(houseGuid)) as House); }
public Landblock(LandblockId id) { Id = id; CellLandblock = DatManager.CellDat.ReadFromDat <CellLandblock>(Id.Raw >> 16 | 0xFFFF); LandblockInfo = DatManager.CellDat.ReadFromDat <LandblockInfo>((uint)Id.Landblock << 16 | 0xFFFE); lastActiveTime = DateTime.UtcNow; Task.Run(() => { _landblock = LScape.get_landblock(Id.Raw); CreateWorldObjects(); SpawnDynamicShardObjects(); SpawnEncounters(); }); //LoadMeshes(objects); }
/// <summary> /// gets the landblock specified, creating it if it is not already loaded. will create all /// adjacent landblocks if propagate is true (outdoor world roaming). /// </summary> private static Landblock GetLandblock(LandblockId landblockId, bool propagate) { var landblock = landblocks[landblockId.LandblockX, landblockId.LandblockY]; var autoLoad = propagate && landblockId.MapScope == MapScope.Outdoors; // standard check/lock/recheck pattern if (landblock == null || autoLoad && !landblock.AdjacenciesLoaded) { lock (landblockMutex) { landblock = landblocks[landblockId.LandblockX, landblockId.LandblockY]; if (landblock == null || autoLoad && !landblock.AdjacenciesLoaded) { if (landblock == null) { // load up this landblock landblock = landblocks[landblockId.LandblockX, landblockId.LandblockY] = new Landblock(landblockId); // kick off the landblock use time thread // block.StartUseTime(); if (!ActiveLandblocks.TryAdd(landblock, true)) { Console.WriteLine("LandblockManager: failed to add " + (landblock.Id.Raw | 0xFFFF).ToString("X8") + " to active landblocks!"); return(landblock); } } SetAdjacencies(landblockId, autoLoad); if (autoLoad) { landblock.AdjacenciesLoaded = true; } } } } return(landblock); }
/// <summary> /// gets the landblock specified, creating it if it is not already loaded. will create all /// adjacent landblocks if propogate is true (outdoor world roaming). /// </summary> private static Landblock GetLandblock(LandblockId landblockId, bool propogate) { int x = landblockId.LandblockX; int y = landblockId.LandblockY; // standard check/lock/recheck pattern if (landblocks[x, y] == null) { lock (landblockMutex) { if (landblocks[x, y] == null) { // load up this landblock Landblock block = new Landblock(landblockId); landblocks[x, y] = block; bool autoLoad = propogate && landblockId.MapScope == Entity.Enum.MapScope.Outdoors; if (x > 0) { SetAdjacency(landblockId, landblockId.West, Adjacency.West, autoLoad); if (y > 0) { SetAdjacency(landblockId, landblockId.SouthWest, Adjacency.SouthWest, autoLoad); } if (y < 255) { SetAdjacency(landblockId, landblockId.NorthWest, Adjacency.NorthWest, autoLoad); } } if (x < 255) { SetAdjacency(landblockId, landblockId.East, Adjacency.East, autoLoad); if (y > 0) { SetAdjacency(landblockId, landblockId.SouthEast, Adjacency.SouthEast, autoLoad); } if (y < 255) { SetAdjacency(landblockId, landblockId.NorthEast, Adjacency.NorthEast, autoLoad); } } if (y > 0) { SetAdjacency(landblockId, landblockId.South, Adjacency.South, autoLoad); } if (y < 255) { SetAdjacency(landblockId, landblockId.North, Adjacency.North, autoLoad); } // kick off the landblock use time thread block.StartUseTime(); } } } return(landblocks[x, y]); }
/// <summary> /// This should only be used for debugging/development purposes. /// </summary> public static void ForceLoadLandBlock(LandblockId blockid) { GetLandblock(blockid, false); }
public Landblock(LandblockId id) { Id = id; UpdateStatus(LandBlockStatusFlag.IdleUnloaded); // initialize adjacency array adjacencies.Add(Adjacency.North, null); adjacencies.Add(Adjacency.NorthEast, null); adjacencies.Add(Adjacency.East, null); adjacencies.Add(Adjacency.SouthEast, null); adjacencies.Add(Adjacency.South, null); adjacencies.Add(Adjacency.SouthWest, null); adjacencies.Add(Adjacency.West, null); adjacencies.Add(Adjacency.NorthWest, null); UpdateStatus(LandBlockStatusFlag.IdleLoading); actionQueue = new NestedActionQueue(WorldManager.ActionQueue); var objects = DatabaseManager.World.GetCachedInstancesByLandblock(Id.Landblock); // Instances var factoryObjects = WorldObjectFactory.CreateNewWorldObjects(objects); factoryObjects.ForEach(fo => { AddWorldObject(fo); fo.ActivateLinks(); }); _landblock = LScape.get_landblock(Id.Raw); // Many thanks for GDL cache and GDL coding for loading into landblock and gmriggs assistance with taking the byte arrays and turning them in to more easy to follow (for me) data structures var encounters = DatabaseManager.World.GetCachedEncountersByLandblock(Id.Landblock); encounters.ForEach(encounter => { var wo = WorldObjectFactory.CreateNewWorldObject(encounter.WeenieClassId); if (wo != null) { float x_shift = 24.0f * encounter.CellX; float y_shift = 24.0f * encounter.CellY; var pos = new Physics.Common.Position(); pos.ObjCellID = (uint)(id.Landblock << 16) | 1; pos.Frame = new Physics.Animation.AFrame(new Vector3(x_shift, y_shift, 0), new Quaternion(0, 0, 0, 1)); pos.adjust_to_outside(); pos.Frame.Origin.Z = _landblock.GetZ(pos.Frame.Origin); wo.Location = new Position(pos.ObjCellID, pos.Frame.Origin.X, pos.Frame.Origin.Y, pos.Frame.Origin.Z, pos.Frame.Orientation.X, pos.Frame.Orientation.Y, pos.Frame.Orientation.Z, pos.Frame.Orientation.W); if (!worldObjects.ContainsKey(wo.Guid)) { AddWorldObject(wo); } } }); //LoadMeshes(objects); UpdateStatus(LandBlockStatusFlag.IdleLoaded); // FIXME(ddevec): Goal: get rid of UseTime() function... actionQueue.EnqueueAction(new ActionEventDelegate(() => UseTimeWrapper())); motionQueue = new NestedActionQueue(WorldManager.MotionQueue); }
public static bool IsLoaded(LandblockId landblockId) { lock (landblockMutex) return(landblocks[landblockId.LandblockX, landblockId.LandblockY] != null); }