コード例 #1
0
        private void OnTick()
        {
            var now = DateTime.Now;

            if (nextStatsTime < now)
            {
                nextStatsTime = now.AddMilliseconds(statsInterval);
                lastStats     = currentStats;
                currentStats  = new Stats();
            }
            // Never use more than half the available tick time
            // but always process at least one queued block.
            var maxTime = (1000 / ConVar.Server.tickrate) / 2;
            var n       = 0;

            while (stabilityQueue.Count > 0 && (n == 0 || (DateTime.Now - now).TotalMilliseconds < maxTime))
            {
                var block = stabilityQueue[0];
                stabilityQueue.RemoveAt(0);
                if (!BuildingBlockHelpers.IsValidBlock(block))
                {
                    continue;
                }
                UpdateStability(block);
                ++n;
            }
            // Always delay queued updates until the next tick.
            // This also gives us a nice bottom up effect.
            while (stabilityQueueDelayed.Count > 0)
            {
                stabilityQueue.Add(stabilityQueueDelayed[0]);
                stabilityQueueDelayed.RemoveAt(0);
            }
        }
コード例 #2
0
        private void OnEntityBuilt(Planner planner, GameObject obj)
        {
            if (obj == null)
            {
                return;
            }
            var block = obj.GetComponent <BuildingBlock>();

            if (!BuildingBlockHelpers.IsValidBlock(block))
            {
                return;
            }
#if DEBUG
            Log("Placing block " + block.blockDefinition.hierachyName);
#endif
            ++currentStats.blocksBuilt;
            try {
                var defaultGrade = block.blockDefinition.defaultGrade;
                if (!UpdateStability(block, false))
                {
                    ++currentStats.blocksFailedBuilding;
                    // If this isn't stable, refund.
                    var player = planner.ownerPlayer;
                    foreach (var cost in defaultGrade.costToBuild)
                    {
                        var item = ItemManager.CreateByItemID(cost.itemid, (int)cost.amount, false);
                        player.GiveItem(item, BaseEntity.GiveItemReason.Generic);
                    }
                    player.ChatMessage(_(buildingFailedMessages[rng.Next(0, buildingFailedMessages.Length)]));
                    return;
                }
            } catch (Exception ex) {
                Error("OnEntityBuilt failed", ex);
            }
        }
コード例 #3
0
 private void OnBuildingBlockDemolish(BuildingBlock block, BasePlayer player)
 {
     if (!BuildingBlockHelpers.IsValidBlock(block))
     {
         return;
     }
     OnDemolish(block);
 }
コード例 #4
0
        private void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
        {
            var block = entity as BuildingBlock;

            if (!BuildingBlockHelpers.IsValidBlock(block))
            {
                return;
            }
            OnDemolish(block);
        }
コード例 #5
0
        // Enqueues a stability update for the next tick
        private void EnqueueUpdate(BuildingBlock block)
        {
            ++currentStats.blocksEnqueued;
            if (!stabilityQueueDelayed.Contains(block))
            {
                ++currentStats.blocksEnqueuedUnique;
#if DEBUG
                Log("Enqueued " + BuildingBlockHelpers.Name(block));
#endif
                stabilityQueueDelayed.Add(block);
            }
        }
コード例 #6
0
        // Updates the stability of a block and returns false if the block has just been destroyed
        private bool UpdateStability(BuildingBlock block, bool propagate = true)
        {
            ++currentStats.blocksUpdated;
            if (block.isDestroyed)
            {
#if DEBUG
                Log("Skipped " + BuildingBlockHelpers.Name(block) + ": Already destroyed");
#endif
                return(true);
            }
            // Log("Updating stability on " + block.Name());
            // Exclude foundations from stability updates.
            if (BuildingBlockHelpers.IsFoundation(block))
            {
#if DEBUG
                Log("Skipped " + BuildingBlockHelpers.Name(block) + ": Is foundation");
#endif
                return(true);
            }
            List <BuildingBlock> supports;
            List <BuildingBlock> supported;
            BuildingBlockHelpers.GetAdjacentBlocks(block, out supports, out supported);
            if (supports.Count > 0)
            {
#if DEBUG
                Log("Skipped " + BuildingBlockHelpers.Name(block) + ": Still has " + supports.Count + " supports");
#endif
                return(true);
            }
            // If this block has no more supports, destroy it.
#if DEBUG
            Log(BuildingBlockHelpers.Name(block) + " has no (more) supports, killing (supported " + supported.Count + ")" + (propagate ? " - propagating" : " - not propagating"));
#endif
            DemolishBlock(block);
            var deployables = BuildingBlockHelpers.GetOrphanedDeployables(block);
            foreach (var deployable in deployables)
            {
                if (!deployable.isDestroyed)
                {
                    DemolishDeployable(deployable);
                }
            }
            if (propagate)
            {
                foreach (var supportedBlock in supported)
                {
                    EnqueueUpdate(supportedBlock);
                }
            }
            return(false);
        }
コード例 #7
0
        void cmdConsoleUpdateAll(ConsoleSystem.Arg arg)
        {
            if (arg.connection != null && arg.connection.authLevel < 2)
            {
                return;
            }
            var allBlocks = UnityEngine.Object.FindObjectsOfType <BuildingBlock>();

            foreach (var block in allBlocks)
            {
                if (!BuildingBlockHelpers.IsValidBlock(block))
                {
                    continue;
                }
                UpdateStability(block, true);
            }
            SendReply(arg, "Updating stability on ALL " + allBlocks.Length + " blocks in the background now, this will take a while.");
        }
コード例 #8
0
        private void OnServerInitialized()
        {
            LoadConfig();
            var customMessages = (Dictionary <string, object>)Config["messages"];

            if (customMessages != null)
            {
                foreach (var pair in customMessages)
                {
                    messages[pair.Key] = Convert.ToString(pair.Value);
                }
                Log("Loaded " + customMessages.Count + " translation strings");
            }

            // Initialize helpers
            BuildingBlockHelpers.Initialize();

            // Force an update on all blocks when first started
            var  fs         = Interface.GetMod().DataFileSystem;
            var  data       = fs.GetDatafile("BetterStability");
            bool firstStart = false;

            if (data["firststart"] == null)
            {
                Log("Starting the first time, forcing update on ALL blocks");
                firstStart         = true;
                data["firststart"] = false;
                fs.SaveDatafile("BetterStability");
            }

            // Schedule stability updates for all blocks that support anything
            var allBlocks = UnityEngine.Object.FindObjectsOfType <BuildingBlock>();
            int n         = 0;

            foreach (var block in allBlocks)
            {
                if (firstStart || (!BuildingBlockHelpers.IsFoundation(block) && BuildingBlockHelpers.IsSupportForAnything(block)))
                {
                    EnqueueUpdate(block);
                    ++n;
                }
            }
            Log("Queued " + n + " blocks for stability updates");
        }
コード例 #9
0
        // Updates supported blocks once a block has been demolished
        private void OnDemolish(BuildingBlock block)
        {
            ++currentStats.blocksDemolished;
            List <BuildingBlock> supports;
            List <BuildingBlock> supported;

            BuildingBlockHelpers.GetAdjacentBlocks(block, out supports, out supported);
#if DEBUG
            Log("OnDemolish called for " + BuildingBlockHelpers.Name(block) + " (support for " + supported.Count + " blocks)");
#endif
            foreach (var supportedBlock in supported)
            {
                EnqueueUpdate(supportedBlock); // Must be queued as this block is still alive
            }
            var deployables = BuildingBlockHelpers.GetOrphanedDeployables(block);
            foreach (var entity in deployables)
            {
                DemolishDeployable(entity);
            }
        }