コード例 #1
0
        public override void FromTreeAtributes(ITreeAttribute tree, IWorldAccessor worldAccessForResolve)
        {
            base.FromTreeAtributes(tree, worldAccessForResolve);

            long nowNetworkId = tree.GetLong("networkid");

            if (worldAccessForResolve.Side == EnumAppSide.Client)
            {
                propagationDir = BlockFacing.ALLFACES[tree.GetInt("turnDirFromFacing")];
                gearedRatio    = tree.GetFloat("g");

                if (NetworkId != nowNetworkId)   //don't ever change network settings from tree on server side - networkId is not data to be saved  (otherwise would mess up networks on chunk loading, if BE tree loaded after a BE has already had network assigned on the server by propagation from a neighbour)
                {
                    NetworkId = 0;
                    if (worldAccessForResolve.Side == EnumAppSide.Client)
                    {
                        NetworkId = nowNetworkId;
                        if (NetworkId == 0)
                        {
                            LeaveNetwork();
                            network = null;
                        }
                        else if (manager != null)
                        {
                            network = manager.GetOrCreateNetwork(NetworkId);
                            JoinNetwork(network);
                            Blockentity.MarkDirty();
                        }
                    }
                }
            }
        }
コード例 #2
0
        private void onTrackLoaded(ILoadedSound sound)
        {
            if (track == null)
            {
                sound?.Dispose();
                return;
            }
            if (sound == null)
            {
                return;
            }

            track.Sound = sound;

            // Needed so that the music engine does not dispose the sound
            Api.Event.EnqueueMainThreadTask(() => track.loading = true, "settrackloading");

            long longMsPassed = Api.World.ElapsedMilliseconds - startLoadingMs;

            handlerId = Blockentity.RegisterDelayedCallback((dt) =>
            {
                if (sound.IsDisposed)
                {
                    Api.World.Logger.Notification("firepit track is diposed? o.O");
                }

                if (!wasStopped)
                {
                    sound.Start();
                }

                track.loading = false;
            }, (int)Math.Max(0, 500 - longMsPassed));
        }
コード例 #3
0
        private void initSoundsAndTicking()
        {
            fuelBlock = Api.World.BlockAccessor.GetBlock(FuelPos);

            l1 = Blockentity.RegisterGameTickListener(OnTick, 25);
            if (Api.Side == EnumAppSide.Server)
            {
                l2 = Blockentity.RegisterGameTickListener(OnSlowServerTick, 1000);
            }

            wsys = Api.ModLoader.GetModSystem <WeatherSystemBase>();

            if (ambientSound == null && Api.Side == EnumAppSide.Client)
            {
                ambientSound = ((IClientWorldAccessor)Api.World).LoadSound(new SoundParams()
                {
                    Location        = new AssetLocation("sounds/environment/fire.ogg"),
                    ShouldLoop      = true,
                    Position        = FirePos.ToVec3f().Add(0.5f, 0.25f, 0.5f),
                    DisposeOnFinish = false,
                    Volume          = 1f
                });

                if (ambientSound != null)
                {
                    ambientSound.PlaybackPosition = ambientSound.SoundLengthSeconds * (float)Api.World.Rand.NextDouble();
                    ambientSound.Start();
                }
            }

            particleFacing = BlockFacing.FromNormal(new Vec3i(FirePos.X - FuelPos.X, FirePos.Y - FuelPos.Y, FirePos.Z - FuelPos.Z));
        }
コード例 #4
0
        public override void Initialize(ICoreAPI api, JsonObject properties)
        {
            base.Initialize(api, properties);

            //sound = new AssetLocation("game:sounds/effect/swoosh");
            Blockentity.RegisterGameTickListener(CheckWaterSpeed, 1000);
        }
コード例 #5
0
        public override void Initialize(ICoreAPI api, JsonObject properties)
        {
            base.Initialize(api, properties);

            if (Api.Side == EnumAppSide.Server)
            {
                listenerId = Blockentity.RegisterGameTickListener(OnTick, callbackTimeMs + Api.World.Rand.Next(callbackTimeMs));
            }

            stemBlock   = Api.World.GetBlock(ownBe.Block.CodeWithVariant("type", "stem"));
            branchBlock = Api.World.GetBlock(ownBe.Block.CodeWithVariant("type", "branch")) as BlockFruitTreeBranch;
            leavesBlock = Api.World.GetBlock(AssetLocation.Create(ownBe.Block.Attributes["foliageBlock"].AsString(), ownBe.Block.Code.Domain)) as BlockFruitTreeFoliage;

            if (ownBe.Block == leavesBlock)
            {
                ownBe.PartType = EnumTreePartType.Leaves;
            }
            if (ownBe.Block == branchBlock)
            {
                ownBe.PartType = EnumTreePartType.Branch;
            }

            if (ownBe.lastGrowthAttemptTotalDays == 0)
            {
                ownBe.lastGrowthAttemptTotalDays = api.World.Calendar.TotalDays;
            }
        }
コード例 #6
0
        public override void Initialize(ICoreAPI api, JsonObject properties)
        {
            base.Initialize(api, properties);

            if (api.Side == EnumAppSide.Server)
            {
                Blockentity.RegisterGameTickListener(onRootTick, 5000, api.World.Rand.Next(5000));
            }

            roomreg = api.ModLoader.GetModSystem <RoomRegistry>();

            blockBranch = be.Block as BlockFruitTreeBranch;

            RegisterTreeType(bebr.TreeType);

            double totalDays = api.World.Calendar.TotalDays;

            if (TreePlantedTotalDays == 0)
            {
                TreePlantedTotalDays  = totalDays;
                LastRootTickTotalDays = totalDays;
            }
            else
            {
                // In case this block was imported from another older world. In that case lastCheckAtTotalDays would be a future date.
                TreePlantedTotalDays  = Math.Min(TreePlantedTotalDays, totalDays);
                LastRootTickTotalDays = Math.Min(LastRootTickTotalDays, totalDays);
            }
        }
コード例 #7
0
 public override void Initialize(ICoreAPI api, JsonObject properties)
 {
     base.Initialize(api, properties);
     this.sound    = new AssetLocation("sounds/effect/swoosh");
     weatherSystem = Api.ModLoader.GetModSystem <WeatherSystemBase>();
     Blockentity.RegisterGameTickListener(CheckWindSpeed, 1000);
 }
コード例 #8
0
        private void ChangeState(bool newEngaged)
        {
            if (newEngaged)
            {
                CreateJoinAndDiscoverNetwork(orients[0]);
                CreateJoinAndDiscoverNetwork(orients[1]);
                this.tryConnect(orients[0]);

                ////Test for connection on opposite side as well
                //pos = Position.AddCopy(orients[1]);
                //block = Api.World.BlockAccessor.GetBlock(pos) as IMechanicalPowerBlock;
                //if (block != null && this.network != block.GetNetwork(Api.World, pos))
                //{
                //    block.DidConnectAt(Api.World, pos, orients[0]);
                //    this.WasPlaced(orients[1]);
                //}
                Blockentity.MarkDirty(true);
            }
            else
            {
                if (network != null)
                {
                    manager.OnNodeRemoved(this);
                }
            }
        }
コード例 #9
0
 public void KillFire(bool consumeFuel)
 {
     IsBurning = false;
     Blockentity.UnregisterGameTickListener(l1);
     Blockentity.UnregisterGameTickListener(l2);
     ambientSound?.FadeOutAndStop(1);
     OnFireDeath(consumeFuel);
 }
コード例 #10
0
        private void CheckForGrowth(float dt)
        {
            double timeFactor = GameMath.Clamp(Api.World.Calendar.SpeedOfTime / 60, 0.1, 5);
            double now = Api.World.Calendar.TotalDays;
            bool fastForwarded = now > dateLastChecked + 0.5;
            dateLastChecked = now;
            if (Api.World.Rand.NextDouble() > 0.2 * timeFactor && !fastForwarded) return;

            int count = 0;
            bool dirty = false;
            foreach (var val in fruitPoints)
            {
                if (val.variant >= 0)
                {
                    if (val.transitionDate == 0)
                    {
                        val.transitionDate = GetGerminationDate();  // probably this code path is never reached, but just in case something went wrong reading a BlockEntity from a save etc.
                        dirty = true;
                    }

                    if (val.currentStage > 0) count++;
                }
            }

            bool finalStagePlant = false;
            if (this.Blockentity.Block is BlockCrop crop)
            {
                finalStagePlant = (crop.CurrentCropStage == crop.CropProps.GrowthStages);
            }
            foreach (var val in fruitPoints)
            {
                if (val.variant >= 0)
                {
                    if (now > val.transitionDate)
                    {
                        if (val.currentStage == 0 && count >= maxFruit) continue;     // Suppress growth for now - too many fruits already on this plant - but try again soon

                        if (finalStagePlant && val.currentStage < fruitStages - 3) continue;    // No small green fruit growth on final stage crop, except ripe fruit can become overripe

                        if (++val.currentStage > fruitStages)
                        {
                            // reached final stage
                            val.transitionDate = Double.MaxValue;
                            val.currentStage = fruitStages;
                        }
                        else
                        {
                            // set up next transition - take 2.5 times as long for the final stage
                            val.transitionDate = now + transitionDays * (1 + Api.World.Rand.NextDouble()) / 1.5 / PlantHealth() * (val.currentStage == fruitStages - 1 ? 2.5 : 1);
                        }
                        dirty = true;
                    }
                }
            }

            if (dirty) Blockentity.MarkDirty();
        }
コード例 #11
0
 internal bool OnInteract(IPlayer byPlayer)
 {
     if (++this.powerSetting > 10)
     {
         this.powerSetting = 1;
     }
     Blockentity.MarkDirty(true);
     return(true);
 }
コード例 #12
0
        public override void Initialize(ICoreAPI api, JsonObject properties)
        {
            base.Initialize(api, properties);

            if (Blockentity.Api.Side == EnumAppSide.Client)
            {
                Blockentity.RegisterGameTickListener(OnTick3s, 3000);
            }
        }
コード例 #13
0
 public virtual void LeaveNetwork()
 {
     if (DEBUG)
     {
         Api.Logger.Notification("Leaving network " + NetworkId + " at " + this.Position);
     }
     network?.Leave(this);
     network   = null;
     NetworkId = 0;
     Blockentity.MarkDirty();
 }
コード例 #14
0
ファイル: Waterwheel.cs プロジェクト: Niker323/VS-mods
    public override void Initialize(ICoreAPI api, JsonObject properties)
    {
        base.Initialize(api, properties);

        if (api.Side.IsServer())
        {
            face = BlockFacing.FromCode(Block.Variant["side"]);
            CheckWater(0);
            Blockentity.RegisterGameTickListener(CheckWater, 1000);
        }
    }
コード例 #15
0
        public override void Initialize(ICoreAPI api, JsonObject properties)
        {
            base.Initialize(api, properties);

            this.AxisSign = new int[3] {
                0, 1, 0
            };

            if (api.Side == EnumAppSide.Client)
            {
                Blockentity.RegisterGameTickListener(onEverySecond, 1000);
            }
        }
コード例 #16
0
        private void CheckWindSpeed(float dt)
        {
            windSpeed = weatherSystem.WeatherDataSlowAccess.GetWindSpeed(Blockentity.Pos.ToVec3d());
            if (Api.World.BlockAccessor.GetLightLevel(Blockentity.Pos, EnumLightLevelType.OnlySunLight) < 5 && Api.World.Config.GetString("undergroundWindmills", "false") != "true")
            {
                windSpeed = 0;
            }

            if (Api.Side == EnumAppSide.Server && sailLength > 0 && Api.World.Rand.NextDouble() < 0.2)
            {
                // Todo: Entity Fling and Damage thing

                /*Cuboidd cuboid = new Cuboidd(-sailLength + 0.1, -sailLength + 0.1, 0.2, sailLength - 0.2, sailLength - 0.2, 0.8);
                 * float rot = (ownFacing.HorizontalAngleIndex+1) * 90;
                 *
                 * cuboid = cuboid.RotatedCopy(0, rot, 0, new Vec3d(0.5, 0.5, 0.5));
                 * cuboid = cuboid.OffsetCopy(Position.X, Position.Y, Position.Z);
                 *
                 * Api.World.SpawnParticles(100, ColorUtil.WhiteArgb, cuboid.Start, cuboid.End, new Vec3f(), new Vec3f(), 2f, 0);
                 *
                 * Vec3d centerPos = Position.ToVec3d().Add(0.5, 0.5, 0.5);
                 *
                 * partitionUtil.WalkEntityPartitions(centerPos, SailLength + 1, (e) =>
                 * {
                 *  if (!e.IsInteractable) return;
                 *  if (cuboid.IntersectsOrTouches(e.CollisionBox, e.ServerPos.X, e.ServerPos.Y, e.ServerPos.Z))
                 *  {
                 *      e.ReceiveDamage(new DamageSource() { SourceBlock = Block, SourcePos = Position.ToVec3d().Add(0.5, 0.5, 0.5), Type = EnumDamageType.BluntAttack, Source = EnumDamageSource.Block }, 0.5f);
                 *
                 *      float dx = (float)(centerPos.X - e.ServerPos.X);
                 *      float dy = (float)(centerPos.Y - e.ServerPos.Y);
                 *      float dz = (float)(centerPos.Y - e.ServerPos.Z);
                 *
                 *      e.ServerPos.Motion.Add(dx, dy, dz);
                 *  }
                 * });*/

                if (obstructed(sailLength + 1))
                {
                    Api.World.PlaySoundAt(new AssetLocation("sounds/effect/toolbreak"), Position.X + 0.5, Position.Y + 0.5, Position.Z + 0.5, null, false, 20, 1f);
                    while (sailLength-- > 0)
                    {
                        ItemStack stacks = new ItemStack(Api.World.GetItem(new AssetLocation("sail")), 4);
                        Api.World.SpawnItemEntity(stacks, Blockentity.Pos.ToVec3d().Add(0.5, 0.5, 0.5));
                    }
                    sailLength = 0;
                    Blockentity.MarkDirty(true);
                    this.network.updateNetwork(manager.getTickNumber());
                }
            }
        }
コード例 #17
0
        internal bool OnInteract(IPlayer byPlayer)
        {
            if (++this.powerSetting > 10)
            {
                this.powerSetting = 1;
            }
            Blockentity.MarkDirty(true);

            var pos = Blockentity.Pos.ToVec3d().Add(0.5, 0, 0.5);

            Api.World.PlaySoundAt(new AssetLocation("sounds/toggleswitch"), pos.X, pos.Y, pos.Z, byPlayer, false, 16);

            return(true);
        }
コード例 #18
0
        public virtual void OnPlayerInteractStop(float secondsUsed, IPlayer player, Vec3d hit)
        {
            if (secondsUsed < 0.2f) return;

            for (int i = 0; i < fruitPoints.Length; i++)
            {
                FruitData val = fruitPoints[i];
                if (val.variant >= 0 && val.currentStage >= this.ripeStage)
                {
                    Item item = Api.World.GetItem(new AssetLocation(fruitCodeBases[val.variant] + val.currentStage));
                    if (item == null) continue;
                    if (item.Attributes != null && item.Attributes["onGround"].AsBool(false)) continue;  // ignore fruits already on the ground

                    if (Api.Side == EnumAppSide.Client) manager.RemoveFruit(fruitCodeBases[val.variant] + val.currentStage, positions[i]);
                    val.variant = -1;   // Flag this fruit as picked
                    val.transitionDate = Double.MaxValue;

                    if (val.currentStage >= this.ripeStage)  // allow both ripe and overripe fruits to be picked
                    {
                        // Play snickety sound
                        double posx = Blockentity.Pos.X + hit.X;
                        double posy = Blockentity.Pos.Y + hit.Y;
                        double posz = Blockentity.Pos.Z + hit.Z;
                        player.Entity.World.PlaySoundAt(new AssetLocation("sounds/effect/squish1"), posx, posy, posz, player, 1.1f + (float)Api.World.Rand.NextDouble() * 0.4f, 16, 0.25f);

                        // Update transition time of any non-started fruit, otherwise they may all start immediately
                        double now = Api.World.Calendar.TotalDays;
                        for (int j = 0; j < fruitPoints.Length; j++)
                        {
                            val = fruitPoints[j];
                            if (val.variant >= 0 && val.currentStage == 0 && val.transitionDate < now)
                            {
                                val.transitionDate = now + Api.World.Rand.NextDouble() * maxGerminationDays / 2;
                            }
                        }

                        // Give the player one item
                        ItemStack stack = new ItemStack(Api.World.GetItem(dropCode), 1);

                        if (!player.InventoryManager.TryGiveItemstack(stack))
                        {
                            Api.World.SpawnItemEntity(stack, Blockentity.Pos.ToVec3d().Add(0.5, 0.25, 0.5));
                        }
                    }
                    Blockentity.MarkDirty();
                    break;
                }
            }
        }
コード例 #19
0
        public override void FromTreeAtributes(ITreeAttribute tree, IWorldAccessor worldForResolving)
        {
            base.FromTreeAtributes(tree, worldForResolving);
            Circuit.FromTreeAttributes(tree.GetTreeAttribute("circuit"), worldForResolving);
            Blockentity.MarkDirty(true);

            if (Api == null)
            {
                return;
            }
            if (Api.Side == EnumAppSide.Client)
            {
                renderer.RegenCircuitMesh(this.Circuit);
            }
        }
コード例 #20
0
        public override void Initialize(ICoreAPI api, JsonObject properties)
        {
            base.Initialize(api, properties);

            if (api.Side == EnumAppSide.Client)
            {
                Blockentity.RegisterGameTickListener(onEverySecond, 1000);
            }

            if (largeGear != null)
            {
                if (largeGear.AngledGearNotAlreadyAdded(this.Position))  // during chunk loading it's random whether the angled gear or the large gear gets initialised first
                {
                    this.tryConnect(this.orientation.Opposite);
                }
            }
        }
コード例 #21
0
        public void OnUseOver(IPlayer byPlayer, Vec3i voxelHitPos, Vec3i voxelBoxPos, BlockFacing facing, bool mouseBreakMode)
        {
            // Send a custom network packet for server side, because
            // serverside blockselection index is inaccurate


            if (Api.Side == EnumAppSide.Client)
            {
                SendUseOverPacket(byPlayer, voxelHitPos, voxelBoxPos, facing, mouseBreakMode);
                return;
            }

            ItemStack itemStack = byPlayer?.InventoryManager?.ActiveHotbarSlot?.Itemstack;

            Circuit.OnUseOver(byPlayer, voxelHitPos, voxelBoxPos, facing, itemStack, mouseBreakMode);
            Api.World.PlaySoundAt(new AssetLocation("signals:sounds/buzz_short"), Pos.X, Pos.Y, Pos.Z);
            Blockentity.MarkDirty();
        }
コード例 #22
0
        internal bool OnInteract(IPlayer byPlayer)
        {
            if (sailLength >= 5)
            {
                return(false);
            }

            ItemSlot slot = byPlayer.InventoryManager.ActiveHotbarSlot;

            if (slot.Empty || slot.StackSize < 4)
            {
                return(false);
            }

            ItemStack sailStack = new ItemStack(Api.World.GetItem(new AssetLocation("sail")));

            if (!slot.Itemstack.Equals(Api.World, sailStack, GlobalConstants.IgnoredStackAttributes))
            {
                return(false);
            }

            int len = sailLength + 2;

            if (obstructed(len))
            {
                if (Api.Side == EnumAppSide.Client)
                {
                    (Api as ICoreClientAPI).TriggerIngameError(this, "notenoughspace", Lang.Get("Cannot add more sails. Make sure there's space for the sails to rotate freely"));
                }
                return(false);
            }

            if (byPlayer.WorldData.CurrentGameMode != EnumGameMode.Creative)
            {
                slot.TakeOut(4);
                slot.MarkDirty();
            }
            sailLength++;
            updateShape();

            Blockentity.MarkDirty(true);
            return(true);
        }
コード例 #23
0
        public override void Initialize(ICoreAPI api, JsonObject properties)
        {
            base.Initialize(api, properties);
            Circuit.Initialize(api);
            listenerId = Blockentity.RegisterGameTickListener(Update, 50);
            block      = Blockentity.Block;
            Pos        = this.Blockentity.Pos;
            //facing = BlockFacing.FromCode(block?.LastCodePart(0)?.ToString());
            //orientation = BlockFacing.FromCode(block?.LastCodePart(1)?.ToString());
            facing      = BlockFacing.FromCode(properties["side"]?.AsString("down"));
            orientation = BlockFacing.FromCode(properties["orientation"]?.AsString("north"));

            if (api.Side == EnumAppSide.Client)
            {
                ICoreClientAPI capi = (ICoreClientAPI)api;
                capi.Event.RegisterRenderer(renderer = new CircuitBoardRenderer(this.Blockentity.Pos, facing, orientation, capi), EnumRenderStage.Opaque, "circuitboard");
                renderer.RegenCircuitMesh(Circuit);
            }
        }
コード例 #24
0
        public override void Initialize(ICoreAPI api, JsonObject properties)
        {
            base.Initialize(api, properties);
            //this.Api = api;
            //Shape = GetShape();

            //manager = Api.ModLoader.GetModSystem<MechanicalPowerMod>();

            //if (Api.World.Side == EnumAppSide.Client)
            //{
            //    lightRbs = Api.World.BlockAccessor.GetLightRGBs(Blockentity.Pos);
            //    if (NetworkId > 0)
            //    {
            //        network = manager.GetOrCreateNetwork(NetworkId);
            //        JoinNetwork(network);
            //    }
            //}

            //manager.AddDeviceForRender(this);

            //AxisSign = new int[3] { 0, 0, 1 };

            //SetOrientations();
            //if (api.Side == EnumAppSide.Server && OutFacingForNetworkDiscovery != null)
            //{
            //    CreateJoinAndDiscoverNetwork(OutFacingForNetworkDiscovery);
            //}

            if (api.Side == EnumAppSide.Client)
            {
                Blockentity.RegisterGameTickListener(onEverySecond, 1000);
            }

            if (largeGear != null)
            {
                if (largeGear.AngledGearNotAlreadyAdded(this.Position))  // during chunk loading it's random whether the angled gear or the large gear gets initialised first
                {
                    this.tryConnect(this.orientation.Opposite);
                }
            }
        }
コード例 #25
0
        public virtual void JoinNetwork(MechanicalNetwork network)
        {
            if (this.network != null && this.network != network)
            {
                LeaveNetwork();
            }

            if (this.network == null)
            {
                this.network = network;
                network?.Join(this);
            }

            if (network == null)
            {
                NetworkId = 0;
            }
            else
            {
                NetworkId = network.networkId;
            }

            Blockentity.MarkDirty();
        }
コード例 #26
0
        private void onRootTick(float dt)
        {
            double totalDays = Api.World.Calendar.TotalDays;

            if (totalDays - LastRootTickTotalDays < stateUpdateIntervalDays)
            {
                return;
            }

            int   prevIntDays = -99;
            float temp        = 0;

            while (totalDays - LastRootTickTotalDays >= stateUpdateIntervalDays)
            {
                foreach (var val in propsByType)
                {
                    var props = val.Value;

                    if (props.State == EnumFruitTreeState.Dead)
                    {
                        continue;
                    }

                    // Avoid reading the same temp over and over again
                    if (prevIntDays != (int)LastRootTickTotalDays)
                    {
                        // For roughly daily average temps

                        double midday = (int)LastRootTickTotalDays + 0.5;
                        temp = Api.World.BlockAccessor.GetClimateAt(be.Pos, EnumGetClimateMode.ForSuppliedDate_TemperatureOnly, midday).Temperature;
                        temp = applyGreenhouseTempBonus(temp);

                        prevIntDays = (int)LastRootTickTotalDays;
                        Blockentity.MarkDirty(true);
                    }

                    double yearrel = (LastRootTickTotalDays % Api.World.Calendar.DaysPerYear) / Api.World.Calendar.DaysPerYear;

                    if (props.DieBelowTemp > temp)
                    {
                        props.State = EnumFruitTreeState.Dead;
                        props.lastStateChangeTotalDays = Api.World.Calendar.TotalDays;
                        break;
                    }

                    if (props.State == EnumFruitTreeState.Dormant && props.CycleType == EnumTreeCycleType.Deciduous)
                    {
                        updateVernalizedHours(props, temp);

                        if (props.vernalizedHours > props.VernalizationHours)
                        {
                            props.State = EnumFruitTreeState.DormantVernalized;
                            props.lastStateChangeTotalDays = LastRootTickTotalDays;
                            Blockentity.MarkDirty(true);
                        }

                        if (temp >= 20 || (temp > 15 && LastRootTickTotalDays - props.lastCheckAtTotalDays > 3))
                        {
                            props.State = EnumFruitTreeState.Empty;
                            props.lastStateChangeTotalDays = LastRootTickTotalDays;
                            Blockentity.MarkDirty(true);
                        }
                    }
                    else if (props.State == EnumFruitTreeState.DormantVernalized)
                    {
                        if (temp >= 20 || (temp > 15 && LastRootTickTotalDays - props.lastCheckAtTotalDays > 3))
                        {
                            props.State = EnumFruitTreeState.Flowering;
                            props.lastStateChangeTotalDays = LastRootTickTotalDays;
                            Blockentity.MarkDirty(true);
                        }
                    }
                    else if (props.CycleType == EnumTreeCycleType.Evergreen && (props.State == EnumFruitTreeState.Empty || props.State == EnumFruitTreeState.Young))
                    {
                        if (props.State == EnumFruitTreeState.Young && (LastRootTickTotalDays - TreePlantedTotalDays) < nonFloweringYoungDays)
                        {
                            continue;
                        }

                        double yearRel = (LastRootTickTotalDays / Api.World.Calendar.DaysPerYear) % 1.0;
                        if (Math.Abs(yearRel - props.BlossomAtYearRel) < 0.125)
                        {
                            props.State = EnumFruitTreeState.Flowering;
                            props.lastCheckAtTotalDays = LastRootTickTotalDays;
                            Blockentity.MarkDirty(true);
                        }
                    }
                    else if (props.State == EnumFruitTreeState.Flowering && props.lastStateChangeTotalDays + props.FloweringDays < LastRootTickTotalDays)
                    {
                        props.State = EnumFruitTreeState.Fruiting;
                        props.lastStateChangeTotalDays = LastRootTickTotalDays;

                        if (temp < props.EnterDormancyTemp)
                        {
                            props.State = EnumFruitTreeState.Empty;
                        }

                        Blockentity.MarkDirty(true);
                    }
                    else if (props.State == EnumFruitTreeState.Fruiting && props.lastStateChangeTotalDays + props.FruitingDays < LastRootTickTotalDays)
                    {
                        props.State = EnumFruitTreeState.Ripe;
                        props.lastStateChangeTotalDays = LastRootTickTotalDays;
                        Blockentity.MarkDirty(true);
                    }
                    else if (props.State == EnumFruitTreeState.Ripe && props.lastStateChangeTotalDays + props.RipeDays < LastRootTickTotalDays)
                    {
                        props.State = EnumFruitTreeState.Empty;
                        props.lastStateChangeTotalDays = LastRootTickTotalDays;
                        Blockentity.MarkDirty(true);
                    }
                    else if (props.CycleType == EnumTreeCycleType.Deciduous && (props.State == EnumFruitTreeState.Young || props.State == EnumFruitTreeState.Empty) && temp < props.EnterDormancyTemp)
                    {
                        props.State = EnumFruitTreeState.EnterDormancy;
                        props.lastStateChangeTotalDays = LastRootTickTotalDays;
                        Blockentity.MarkDirty(true);
                    }
                    else if (props.CycleType == EnumTreeCycleType.Deciduous && props.State == EnumFruitTreeState.EnterDormancy && props.lastStateChangeTotalDays + 3 < LastRootTickTotalDays)
                    {
                        props.State = EnumFruitTreeState.Dormant;
                        props.lastStateChangeTotalDays = LastRootTickTotalDays;
                        Blockentity.MarkDirty(true);
                    }
                }


                LastRootTickTotalDays += stateUpdateIntervalDays;
            }
        }
コード例 #27
0
        public override void Initialize(ICoreAPI api, JsonObject properties)
        {
            base.Initialize(api, properties);
            dateLastChecked = Api.World.Calendar.TotalDays;

            // Read the properties

            fruitCodeBases = properties["fruitCodeBases"].AsArray<string>(new string[0]);
            if (fruitCodeBases.Length == 0) return;

            positionsCount = properties["positions"].AsInt(0);
            if (positionsCount <= 0) return;

            string maturePlant = properties["maturePlant"].AsString(null);
            if (maturePlant == null) return;
            Block mature = api.World.GetBlock(new AssetLocation(maturePlant));
            if (!(mature is BlockFruiting matureCrop)) return;
            if (Api.Side == EnumAppSide.Client)
            {
                points = matureCrop.GetFruitingPoints();
            }

            maxFruit = properties["maxFruit"].AsInt(5);
            fruitStages = properties["fruitStages"].AsInt(6);
            maxGerminationDays = properties["maxGerminationDays"].AsFloat(6);
            transitionDays = properties["transitionDays"].AsFloat(1);
            successfulGrowthChance = properties["successfulGrowthChance"].AsFloat(0.75f);
            ripeStage = properties["ripeStage"].AsInt(fruitStages - 1);
            dropCode = new AssetLocation(properties["dropCode"].AsString(null));


            // Set up the manager - used for the instanced renderer

            manager = Api.ModLoader.GetModSystem<FruitingSystem>();


            // If initialising client-side after reading from tree attributes, send fruits to the renderer

            bool addToManager = false;
            if (Api.Side == EnumAppSide.Client && fruitPoints != null)
            {
                LightRgba = Api.World.BlockAccessor.GetLightRGBs(Blockentity.Pos);
                addToManager = true;
            }

            InitializeArrays();

            if (addToManager)
            {
                for (int i = 0; i < positionsCount; i++)
                {
                    FruitData val = fruitPoints[i];
                    if (val.variant >= fruitCodeBases.Length) val.variant %= fruitCodeBases.Length;
                    if (val.variant >= 0 && val.currentStage > 0)
                    {
                        val.SetRandomRotation(Api.World, i, positions[i], this.Blockentity.Pos);
                        manager.AddFruit(new AssetLocation(fruitCodeBases[val.variant] + val.currentStage), positions[i], val);
                    }
                }
            }

            // Tick the blockEntity server-side only

            if (Api.Side == EnumAppSide.Server) Blockentity.RegisterGameTickListener(CheckForGrowth, 2250);
        }