Esempio n. 1
0
        /// <summary>
        /// Called by GrowableBlockManager to process an update to a block
        /// Also called very soon after block creation
        /// </summary>
        /// <param name="timeNextUpdateHours">The time in timecycle hours when to call UpdateBlock again</param>
        /// <returns>True if there should be another UpdateBlock call at 'timeNextUpdateHours'</returns>
        public virtual bool UpdateBlock(IGrowableBlock block, double timeNowHours, out double timeNextUpdateHours)
        {
            timeNextUpdateHours = 0.0;
            if (block == null)
            {
                return(false);                // discard null blocks
            }
            if (block.CurrentStageIndex >= Stages.Count)
            {
                return(false);                // completed growth, discard
            }
            if (!block.IsValid)
            {
                return(false);
            }

            switch (GrowthType)
            {
            case EGrowthType.FirstNightRandom:
                return(DoUpdateFirstNightRandom(block, timeNowHours, out timeNextUpdateHours));

            case EGrowthType.Always:
                return(DoUpdateAlways(block, timeNowHours, out timeNextUpdateHours));

            default:
                Log.WriteError("Unexpected growthType: {0}", GrowthType);
                return(false);
            }
        }
Esempio n. 2
0
 /// <summary>
 /// Reports which blocks are tracked in a first iteration to prepare for saving.
 /// Track how many blocks there are to initialize the array at proper capacity later
 /// </summary>
 public virtual void PrepareSaving(IGrowableBlock block)
 {
     if (block.IsValid)
     {
         BlockCountToSave++;
     }
 }
Esempio n. 3
0
        /// <summary>
        /// Process update from a block that grows every night at a random time (wheat, flax)
        /// </summary>
        protected virtual bool DoUpdateFirstNightRandom(IGrowableBlock block, double timeNowHours, out double timeNextUpdateHours)
        {
            timeNextUpdateHours = 0.0;
            double timeDif = timeNowHours - block.LastUpdateHours;

            if (timeDif > 0.0)
            {
                block.Growth = block.Growth + (float)timeDif;
            }

            block.LastUpdateHours = timeNowHours;

            float growthLeft = Stages[block.CurrentStageIndex].GrowthTime - block.Growth;

            if (growthLeft <= 0f)
            {
                if (TryAdvanceStage(block, block.CurrentStageIndex))
                {
                    if (!block.IsValid)
                    {
                        return(false);
                    }
                    // block grew, update again randomly in next night
                    timeNextUpdateHours = timeNowHours + TimeCycle.TimeTillSunSet + Random.NextDouble(0.5, TimeCycle.NightLength - 0.5);
                    return(true);
                }
                else
                {
                    // area not loaded, check again in 0.5 - 1.5 ingame hours
                    timeNextUpdateHours = timeNowHours + Random.NextDouble(0.5, 1.5);
                    return(true);
                }
            }

            // growth not completed
            float timeTillSunRise = TimeCycle.TimeTillSunRise;

            if (growthLeft <= timeTillSunRise)
            {
                // can grow this night
                float nightLength = TimeCycle.NightLength;
                if (timeTillSunRise < nightLength)
                {
                    // night already started
                    timeNextUpdateHours = timeNowHours + Random.NextDouble(growthLeft, timeTillSunRise);
                }
                else
                {
                    // night not started yet
                    timeNextUpdateHours = timeNowHours + Random.NextDouble(timeTillSunRise - nightLength + 0.5f, timeTillSunRise - 0.5);
                }
            }
            else
            {
                // can't grow this/coming night, wait a day ish
                timeNextUpdateHours = timeNowHours + Random.NextDouble(18.0, 24.0);
            }
            return(true);
        }
Esempio n. 4
0
 /// <summary>
 /// Called to save this specific block
 /// </summary>
 public virtual void SaveBlock(IGrowableBlock block)
 {
     if (SaveArray == null)
     {
         SaveArray = new JSONNode(NodeType.Array);
         SaveArray.SetArrayCapacity(BlockCountToSave);
         BlockCountToSave = 0;                 // reset capacity for next autosave/quit
     }
     SaveArray.AddToArray(block.GetJSON());
 }
Esempio n. 5
0
        public override bool TryAdvanceStage(IGrowableBlock block, byte currentStageIndex)
        {
            Logger.Log("{0} TryAdvanceStage", filename);
            Vector3Int pos = block.Position;

            if (currentStageIndex == 0 && pos.IsValid)
            {
                for (int i = 0; i < logs.Count; i++)
                {
                    ushort currentType;
                    if (World.TryGetTypeAt(pos + logs[i], out currentType))
                    {
                        if (currentType == 0 || currentType == saplingIndex)
                        {
                            if (!ServerManager.TryChangeBlock(pos + logs[i], logIndex))
                            {
                                return(false);                                // not loaded
                            }
                        }
                    }
                    else
                    {
                        return(false);                        // not loaded
                    }
                }
                for (int i = 0; i < leaves.Count; i++)
                {
                    ushort currentType;
                    if (World.TryGetTypeAt(pos + leaves[i], out currentType))
                    {
                        if (currentType == 0)
                        {
                            if (!ServerManager.TryChangeBlock(pos + leaves[i], leavesIndex))
                            {
                                return(false);                                // not loaded
                            }
                        }
                    }
                    else
                    {
                        return(false);                        // not loaded
                    }
                }
            }
            // succesfully grew, or invalid stage index. Either case, done.
            block.SetInvalid();
            return(true);
        }
Esempio n. 6
0
 public override bool TryAdvanceStage(IGrowableBlock block, byte currentStageIndex)
 {
     if (currentStageIndex == 0)
     {
         Vector3Int pos = block.Position;
         for (int i = 0; i < logs.Count; i++)
         {
             ushort currentType;
             if (World.TryGetTypeAt(pos + logs[i], out currentType))
             {
                 if (currentType == 0 || currentType == BuiltinBlocks.CherrySapling)
                 {
                     if (!ServerManager.TryChangeBlock(pos + logs[i], BuiltinBlocks.LogTemperate))
                     {
                         return(false);                                // not loaded
                     }
                 }
             }
             else
             {
                 return(false);                        // not loaded
             }
         }
         for (int i = 0; i < leaves.Count; i++)
         {
             ushort currentType;
             if (World.TryGetTypeAt(pos + leaves[i], out currentType))
             {
                 if (currentType == 0)
                 {
                     if (!ServerManager.TryChangeBlock(pos + leaves[i], BuiltinBlocks.CherryBlossom))
                     {
                         return(false);                                // not loaded
                     }
                 }
             }
             else
             {
                 return(false);                        // not loaded
             }
         }
     }
     // succesfully grew, or invalid stage index. Either case, done.
     block.SetInvalid();
     return(true);
 }
Esempio n. 7
0
        /// <summary>
        /// Process update from a block that grows 24/7 (saplings)
        /// </summary>
        protected virtual bool DoUpdateAlways(IGrowableBlock block, double timeNowHours, out double timeNextUpdateHours)
        {
            timeNextUpdateHours = 0.0;
            double timeDif = timeNowHours - block.LastUpdateHours;

            if (timeDif > 0.0)
            {
                block.Growth = block.Growth + (float)timeDif;
            }

            block.LastUpdateHours = timeNowHours;

            float growthLeft = Stages[block.CurrentStageIndex].GrowthTime - block.Growth;

            if (growthLeft <= 0f)
            {
                if (TryAdvanceStage(block, block.CurrentStageIndex))
                {
                    if (!block.IsValid)
                    {
                        return(false);
                    }
                    growthLeft          = Stages[block.CurrentStageIndex].GrowthTime - block.Growth;
                    timeNextUpdateHours = timeNowHours + growthLeft;
                    return(true);
                }
                else
                {
                    // area not loaded, check again in 0.5 - 1.5 ingame hours
                    timeNextUpdateHours = timeNowHours + Random.NextDouble(0.5, 1.5);
                    return(true);
                }
            }

            // growth not completed
            timeNextUpdateHours = timeNowHours + growthLeft + 0.1f;
            return(true);
        }
Esempio n. 8
0
        /// <summary>
        /// Called when a stage is grown.
        /// By default places the BlockType of the stage at the position
        /// </summary>
        public virtual bool TryAdvanceStage(IGrowableBlock block, byte currentStageIndex)
        {
            byte nextStageIndex = (byte)(currentStageIndex + 1);

            if (nextStageIndex < Stages.Count)
            {
                // more stages to go
                IGrowableStage nextStage = Stages[nextStageIndex];
                ushort         oldType;
                if (World.TryGetTypeAt(block.Position, out oldType))
                {
                    if (oldType == 0)
                    {
                        // no block... certainly not a valid stage
                        block.SetInvalid();
                        return(true);
                    }
                    if (oldType != Stages[currentStageIndex].BlockTypeIndex)
                    {
                        // ?? current block type does not match current stage type.
                        // Probably legacy imported blocks
                        // Try to recover what stage to be

                        for (int i = 0; i < Stages.Count; i++)
                        {
                            if (Stages[i].BlockTypeIndex == oldType)
                            {
                                block.CurrentStageIndex = (byte)i;
                                return(false);
                            }
                        }
                        block.SetInvalid();
                        return(true);
                    }
                }
                else
                {
                    return(false);
                }

                if (ServerManager.TryChangeBlock(block.Position, nextStage.BlockTypeIndex))
                {
                    if (nextStageIndex == Stages.Count - 1)
                    {
                        // reached last stage
                        block.SetInvalid();
                    }
                    else
                    {
                        block.CurrentStageIndex = nextStageIndex;
                        block.Growth            = Random.NextFloat(0f, RandomStartGrowthMax * Stages[nextStageIndex].GrowthTime);
                    }
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                // at last stage already
                block.SetInvalid();
                return(true);
            }
        }