예제 #1
0
        //will check and see if there is an appropriate heated block in order to generator power
        bool CheckHeat()
        {
            //find heated blocks - firepits, furnaces, burning coal piles
            heated = false;
            BlockPos    bp         = Pos.Copy().Offset(heatFace);
            BlockEntity checkblock = Api.World.BlockAccessor.GetBlockEntity(bp);

            if (checkblock == null)
            {
                return(false);
            }
            //check for hot firepit
            var checkFirePit = checkblock as BlockEntityFirepit;

            if (checkFirePit != null)
            {
                if (checkFirePit.furnaceTemperature >= requiredHeat)
                {
                    heated = true; return(true);
                }
            }
            //check for coal piles: Note need to add check for how hot
            var checkCoalPile = checkblock as BlockEntityCoalPile;

            if (checkCoalPile != null)
            {
                if (checkCoalPile.IsBurning)
                {
                    heated = true; return(true);
                }
            }
            return(false);
        }
예제 #2
0
        void TryStart()
        {
            BlockPos    bp         = Pos.Copy().Offset(rmInputFace);
            BlockEntity checkblock = Api.World.BlockAccessor.GetBlockEntity(bp);

            deviceState = enDeviceState.MATERIALHOLD;
            if (Api.World is IServerWorldAccessor)
            {
                workingitem = null;
                var inputContainer = checkblock as BlockEntityContainer;
                if (inputContainer == null)
                {
                    return;
                }
                if (inputContainer.Inventory.Empty)
                {
                    return;
                }
                for (int c = 0; c < inputContainer.Inventory.Count; c++)
                {
                    ItemSlot checkslot = inputContainer.Inventory[c];
                    if (checkslot == null)
                    {
                        continue;
                    }
                    if (checkslot.StackSize == 0)
                    {
                        continue;
                    }

                    Item  checkitem   = checkslot.Itemstack.Item;
                    Block checkiblock = checkslot.Itemstack.Block;

                    if (checkitem == null && checkiblock == null)
                    {
                        continue;
                    }
                    CollectibleObject co;
                    if (checkitem != null)
                    {
                        co = checkitem as CollectibleObject;
                    }
                    else
                    {
                        co = checkiblock as CollectibleObject;
                    }

                    if (!MacerationRecipe.CanMacerate(co, Api, MachineName))
                    {
                        continue;
                    }
                    workingitem = co;
                    //Item has been set, need to pull one item from the stack
                    deviceState = enDeviceState.RUNNING;
                    checkslot.TakeOut(1);
                    checkslot.MarkDirty();
                    break;
                }
            }
        }
예제 #3
0
    protected void transferEnergy(BlockFacing side, float dt)
    {
        BlockPos    outPos     = Pos.Copy().Offset(side);
        BlockEntity tileEntity = Api.World.BlockAccessor.GetBlockEntity(outPos);

        if (tileEntity == null)
        {
            return;
        }
        if (!(tileEntity is IFluxStorage))
        {
            return;
        }
        if (tileEntity is IEnergyPoint && ((IEnergyPoint)tileEntity).GetCore() == GetCore())
        {
            return;
        }
        float eout = Math.Min(MyMiniLib.GetAttributeInt(Block, "transfer", 500) * dt, core.storage.getEnergyStored() * dt);

        eout = ((IFluxStorage)tileEntity).receiveEnergy(side.Opposite, eout, false, dt);
        if (tileEntity is IEnergyPoint && eout > 0)
        {
            ((IEnergyPoint)tileEntity).AddSkipSide(side.Opposite);
        }
        core.storage.modifyEnergyStored(-eout);
    }
예제 #4
0
        protected override void DoDeviceComplete()
        {
            deviceState = enDeviceState.IDLE;
            BlockPos    bp              = Pos.Copy().Offset(outputFace);
            BlockEntity checkblock      = Api.World.BlockAccessor.GetBlockEntity(bp);
            var         outputContainer = checkblock as BlockEntityContainer;

            if (Api.World is IServerWorldAccessor)
            {
                DummyInventory dummy = new DummyInventory(Api);

                List <ItemStack> outputitems = MacerationRecipe.GetMacerate(workingitem, Api, MachineName);
                foreach (ItemStack outitem in outputitems)
                {
                    if (outitem == null)
                    {
                        continue;
                    }
                    dummy[0].Itemstack = outitem;
                    //no output conatiner, spitout stuff
                    if (outputContainer != null)
                    {
                        bool stoptrying    = false;
                        int  safetycounter = 0;
                        while (!stoptrying)
                        {
                            WeightedSlot tryoutput = outputContainer.Inventory.GetBestSuitedSlot(dummy[0]);

                            if (tryoutput.slot != null)
                            {
                                ItemStackMoveOperation op = new ItemStackMoveOperation(Api.World, EnumMouseButton.Left, 0, EnumMergePriority.DirectMerge, dummy[0].StackSize);

                                dummy[0].TryPutInto(tryoutput.slot, ref op);
                                tryoutput.slot.MarkDirty();
                                if (dummy[0] == null)
                                {
                                    stoptrying = true;
                                }
                                else if (dummy[0].StackSize == 0)
                                {
                                    stoptrying = true;
                                }
                            }
                            else
                            {
                                stoptrying = true;
                            }
                            safetycounter++;
                            if (safetycounter > 24)
                            {
                                stoptrying = true;
                            }
                        }
                    }
                    Vec3d pos = bp.ToVec3d();

                    dummy.DropAll(pos);
                }
            }
        }
예제 #5
0
        protected override void DoDeviceComplete()
        {
            deviceState = enDeviceState.IDLE;
            string userecipe = recipe;

            if (ingredient_subtype != "")
            {
                userecipe += "-" + ingredient_subtype;
            }
            Block outputBlock = Api.World.GetBlock(new AssetLocation(userecipe));
            Item  outputItem  = Api.World.GetItem(new AssetLocation(userecipe));

            if (outputBlock == null && outputItem == null)
            {
                deviceState = enDeviceState.ERROR; return;
            }
            ItemStack outputStack;

            if (outputBlock != null)
            {
                outputStack = new ItemStack(outputBlock, outputQuantity);
            }
            else
            {
                outputStack = new ItemStack(outputItem, outputQuantity);
            }

            dummy[0].Itemstack = outputStack;
            outputStack.Collectible.SetTemperature(Api.World, outputStack, lastheatreading);
            BlockPos    bp              = Pos.Copy().Offset(outputFace);
            BlockEntity checkblock      = Api.World.BlockAccessor.GetBlockEntity(bp);
            var         outputContainer = checkblock as BlockEntityContainer;

            if (outputContainer != null)
            {
                WeightedSlot tryoutput = outputContainer.Inventory.GetBestSuitedSlot(dummy[0]);

                if (tryoutput.slot != null)
                {
                    ItemStackMoveOperation op = new ItemStackMoveOperation(Api.World, EnumMouseButton.Left, 0, EnumMergePriority.DirectMerge, outputQuantity);

                    dummy[0].TryPutInto(tryoutput.slot, ref op);
                }
            }

            if (!dummy.Empty)
            {
                //If no storage then spill on the ground
                Vec3d pos = Pos.ToVec3d();

                dummy.DropAll(pos);
            }
            Api.World.PlaySoundAt(new AssetLocation("sounds/doorslide"), Pos.X, Pos.Y, Pos.Z, null, false, 8, 1);
            if (Api.World.Side == EnumAppSide.Client && animUtil != null)
            {
                animUtil.StopAnimation(Pos.ToString() + animationName);
            }
        }
예제 #6
0
        protected void FetchMaterial()
        {
            internalQuantity = Math.Min(internalQuantity, inputQuantity); //this shouldn't be necessary
            Item rm = Api.World.GetItem(new AssetLocation(ingredient));

            if (rm == null)
            {
                deviceState = enDeviceState.ERROR;
                return;
            }

            BlockPos    bp             = Pos.Copy().Offset(rmInputFace);
            BlockEntity checkblock     = Api.World.BlockAccessor.GetBlockEntity(bp);
            var         inputContainer = checkblock as BlockEntityContainer;

            if (inputContainer == null)
            {
                return;
            }
            if (inputContainer.Inventory.Empty)
            {
                return;
            }
            for (int c = 0; c < inputContainer.Inventory.Count; c++)
            {
                ItemSlot checkslot = inputContainer.Inventory[c];
                if (checkslot == null)
                {
                    continue;
                }
                if (checkslot.StackSize == 0)
                {
                    continue;
                }
                bool match = false;
                if (checkslot.Itemstack.Item != null && checkslot.Itemstack.Item.FirstCodePart() == rm.FirstCodePart())
                {
                    match = true;
                }
                else if (checkslot.Itemstack.Block != null && checkslot.Itemstack.Block.FirstCodePart() == rm.FirstCodePart())
                {
                    match = true;
                }
                if (match)
                {
                    int reqQty = Math.Min(checkslot.StackSize, inputQuantity - internalQuantity);
                    checkslot.TakeOut(reqQty);
                    internalQuantity += reqQty;
                    checkslot.MarkDirty();
                }
            }


            return;
        }
예제 #7
0
        public void TryIgnite(IPlayer byPlayer)
        {
            BurningUntilTotalHours = Api.World.Calendar.TotalHours + BurnTimeHours;

            var bh = GetBehavior <BEBehaviorBurning>();

            Lit = true;
            bh.OnFirePlaced(Pos.UpCopy(), Pos.Copy(), byPlayer?.PlayerUID);

            Api.World.BlockAccessor.ExchangeBlock(Block.Id, Pos); // Forces a relight of this block

            MarkDirty(true);
        }
        private void exitChunkLoaded(BlockPos exitPos)
        {
            BlockStaticTranslocator exitBlock = Api.World.BlockAccessor.GetBlock(exitPos) as BlockStaticTranslocator;

            if (exitBlock == null)
            {
                // Cheap hax: Pre v1.10 chunks do not have translocators at the same location and maybe future versions will also have a changed location
                // So let's still try to find something useful in the chunk we generated, with any luck we come across an old one.
                exitPos = HasExitPoint(exitPos);
                if (exitPos != null)
                {
                    exitBlock = Api.World.BlockAccessor.GetBlock(exitPos) as BlockStaticTranslocator;
                }
            }

            if (exitBlock != null && !exitBlock.Repaired)
            {
                // Repair it
                Api.World.BlockAccessor.SetBlock(ownBlock.Id, exitPos);
                BlockEntityStaticTranslocator beExit = Api.World.BlockAccessor.GetBlockEntity(exitPos) as BlockEntityStaticTranslocator;

                // Connect remote
                beExit.tpLocation    = Pos.Copy();
                beExit.canTeleport   = true;
                beExit.findNextChunk = false;
                beExit.activated     = true;
                if (!beExit.FullyRepaired)
                {
                    beExit.repairState = 4;
                    beExit.setupGameTickers();
                }
                Api.World.BlockAccessor.MarkBlockEntityDirty(exitPos);
                Api.World.BlockAccessor.MarkBlockDirty(exitPos);

                Api.World.Logger.Debug("Connected translocator at {0} (chunkpos: {2}) to my location: {1}", exitPos, Pos, exitPos / 32);

                // Connect self
                MarkDirty(true);
                tpLocation  = exitPos;
                canTeleport = true;
            }
            else
            {
                Api.World.Logger.Warning("Translocator: Regen chunk but broken translocator is gone. Structure generation perhaps seed not consistent? May also just be pre-v1.10 chunk, so probably nothing to worry about. Searching again...");
                findNextChunk = true;
            }
        }
예제 #9
0
    protected void transferEnergy(BlockFacing side, float dt)
    {
        BlockPos    outPos     = Pos.Copy().Offset(side);
        BlockEntity tileEntity = Api.World.BlockAccessor.GetBlockEntity(outPos);

        if (tileEntity == null)
        {
            return;
        }
        if (!(tileEntity is IFluxStorage))
        {
            return;
        }
        float eout = Math.Min(energyStorage.getLimitExtract() * dt, energyStorage.getEnergyStored() * dt);

        energyStorage.modifyEnergyStored(-((IFluxStorage)tileEntity).receiveEnergy(side.Opposite, eout, false, dt));
    }
예제 #10
0
        protected virtual void FindOutputConnections()
        {
            //BlockFacing probably has useful stuff to do this right

            foreach (BlockFacing bf in distributionFaces)
            {
                BlockPos    bp         = Pos.Copy().Offset(bf);
                BlockEntity checkblock = Api.World.BlockAccessor.GetBlockEntity(bp);
                var         bee        = checkblock as IElectricity;
                if (bee == null)
                {
                    continue;
                }
                if (bee.TryInputConnection(this) && !outputConnections.Contains(bee))
                {
                    outputConnections.Add(bee);
                }
            }
        }
예제 #11
0
        public override void Initialize(ICoreAPI api)
        {
            var bh = GetBehavior <BEBehaviorBurning>();

            // Make sure the kiln doesn't burn longer than intended (e.g. when exported from an old world and imported into a new world)
            if (Lit)
            {
                BurningUntilTotalHours = Math.Min(api.World.Calendar.TotalHours + BurnTimeHours, BurningUntilTotalHours);
            }

            bh.OnFireTick = (dt) => {
                if (api.World.Calendar.TotalHours >= BurningUntilTotalHours)
                {
                    if (IsAreaLoaded()) // Wait until nearby chunks area loaded before firing fully
                    {
                        OnFired();
                    }
                }
            };
            bh.OnFireDeath = KillFire;

            bh.ShouldBurn = () => Lit;
            bh.OnCanBurn  = (pos) =>
            {
                if (pos == Pos && !Lit && IsComplete)
                {
                    return(true);
                }

                Block block   = Api.World.BlockAccessor.GetBlock(pos);
                Block upblock = Api.World.BlockAccessor.GetBlock(Pos.UpCopy());

                return(block?.CombustibleProps != null && block.CombustibleProps.BurnDuration > 0 && (!IsAreaLoaded() || upblock.Replaceable >= 6000));
            };

            base.Initialize(api);

            DetermineBuildStages();

            bh.FuelPos = Pos.Copy();
            bh.FirePos = Pos.UpCopy();
        }
예제 #12
0
        public virtual float GetPerishRate()
        {
            BlockPos sealevelpos = Pos.Copy();

            sealevelpos.Y = Api.World.SeaLevel;

            ClimateCondition cond = Api.World.BlockAccessor.GetClimateAt(sealevelpos);

            if (cond == null)
            {
                return(1);
            }

            float soilTempWeight = 0f;

            if (room.ExitCount == 0)
            {
                soilTempWeight = 0.5f + 0.5f * (1 - GameMath.Clamp((float)room.NonCoolingWallCount / Math.Max(1, room.CoolingWallCount), 0, 1));
            }

            int lightlevel = Api.World.BlockAccessor.GetLightLevel(Pos, EnumLightLevelType.OnlySunLight);

            // light level above 12 makes it additionally warmer, especially when part of a cellar
            float airTemp = cond.Temperature + GameMath.Clamp(lightlevel - 11, 0, 10) * (1f + 5 * soilTempWeight);


            // Lets say deep soil temperature is a constant 5°C
            float cellarTemp = 5;

            // How good of a cellar it is depends on how much rock or soil was used on he cellars walls
            float hereTemp = GameMath.Lerp(airTemp, cellarTemp, soilTempWeight);

            // For fairness lets say if its colder outside, use that temp instead
            hereTemp = Math.Min(hereTemp, airTemp);

            // Some neat curve to turn the temperature into a spoilage rate
            // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJtYXgoMC4xLG1pbigyLjUsM14oeC8xOS0xLjIpKS0wLjEpIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTIwIiwiNDAiLCIwIiwiMyJdLCJncmlkIjpbIjIuNSIsIjAuMjUiXX1d
            // max(0.1, min(2.5, 3^(x/15 - 1.2))-0.1)
            float rate = Math.Max(0.1f, Math.Min(2.4f, (float)Math.Pow(3, hereTemp / 19 - 1.2) - 0.1f));

            return(rate);
        }
예제 #13
0
        protected override void DoDeviceComplete()
        {
            deviceState = enDeviceState.IDLE;
            Block outputItem = Api.World.GetBlock(new AssetLocation(recipe));

            if (outputItem == null)
            {
                deviceState = enDeviceState.ERROR; return;
            }

            ItemStack outputStack = new ItemStack(outputItem, outputQuantiy);

            dummy[0].Itemstack = outputStack;

            BlockPos    bp              = Pos.Copy().Offset(outputFace);
            BlockEntity checkblock      = Api.World.BlockAccessor.GetBlockEntity(bp);
            var         outputContainer = checkblock as BlockEntityContainer;

            if (outputContainer != null)
            {
                WeightedSlot tryoutput = outputContainer.Inventory.GetBestSuitedSlot(dummy[0]);
                if (tryoutput != null)
                {
                    ItemStackMoveOperation op = new ItemStackMoveOperation(Api.World, EnumMouseButton.Left, 0, EnumMergePriority.DirectMerge, outputQuantiy);
                    int qmoved = dummy[0].TryPutInto(tryoutput.slot, ref op);
                }
            }

            if (!dummy.Empty)
            {
                //If no storage then spill on the ground
                Vec3d pos = Pos.ToVec3d();

                dummy.DropAll(pos);
            }
            Api.World.PlaySoundAt(new AssetLocation("sounds/doorslide"), Pos.X, Pos.Y, Pos.Z, null, false, 8, 1);
            if (Api.World.Side == EnumAppSide.Client && animUtil != null)
            {
                animUtil.StopAnimation("process");
            }
        }
예제 #14
0
    private static List <Pos> GenShape(int cells)
    {
        var pos = new Pos(0, 0);
        var res = new List <Pos> {
        };

        for (var i = 0; i < cells; i++)
        {
            res.Add(pos);
            pos = pos.Copy();
            if (UnityEngine.Random.value > 0.5f)
            {
                pos.X++;
            }
            else
            {
                pos.Y++;
            }
        }
        return(res);
    }
예제 #15
0
파일: Relay.cs 프로젝트: Niker323/VS-mods
    protected void transferEnergy(BlockFacing side, float dt)
    {
        if (sideConfig[side] != IOEnergySideConfig.OUTPUT)
        {
            return;
        }
        BlockPos    outPos     = Pos.Copy().Offset(side);
        BlockEntity tileEntity = Api.World.BlockAccessor.GetBlockEntity(outPos);

        if (tileEntity == null)
        {
            return;
        }
        if (!(tileEntity is IFluxStorage))
        {
            return;
        }
        float eout = Math.Min(MyMiniLib.GetAttributeInt(Block, "transfer", 10000) * dt, energyStorage.getEnergyStored() * dt);

        energyStorage.modifyEnergyStored(-((IFluxStorage)tileEntity).receiveEnergy(side.Opposite, eout, false, dt));
    }
예제 #16
0
파일: BEPowerFlag.cs 프로젝트: wqpvs/qptech
        public void OnTick(float df)
        {
            //check for an IElectricty block below, and if it has power mark true
            //  flag block to update if necessary
            bool        currentstate = false;
            BlockPos    bp           = Pos.Copy().Offset(BlockFacing.DOWN);
            BlockEntity checkblock   = Api.World.BlockAccessor.GetBlockEntity(bp);
            var         bee          = checkblock as IElectricity;

            if (bee != null)
            {
                if (bee.IsPowered)
                {
                    currentstate = true;
                }
            }
            if (laststate != currentstate)
            {
                laststate = currentstate; MarkDirty(true);
            }                                                                            //update the block
        }
예제 #17
0
        public void MakeAutonomousMove()
        {
            Room room = findRoom();

            Room heroRoom = Dungeon.Hero.findRoom();

            bool heroInNextRoom = false;

            if (room == heroRoom)
            {
                target = Dungeon.Hero.Pos.Copy();
                Console.WriteLine("");
            }
            else
            {
                foreach (KeyValuePair <Point, Room> pair in room.Doors)
                {
                    if (pair.Value == heroRoom)
                    {
                        heroInNextRoom = true;
                        target         = pair.Key;
                        break;
                    }
                }
            }

            /* if (!heroInNextRoom) {
             *  if (target.X != -1000) {
             *
             *  }
             *  int numberOfDoors = room.Doors.Count;
             *  var random = new Random();
             *  if (numberOfDoors == 1)
             *  {
             *      target = room.Doors[1];
             *  };
             * } */

            if (Pos.Copy() == target)
            {
                if (heroRoom.isInside(new Point(target.X + 1, target.Y)))
                {
                    target = new Point(target.X + 1, target.Y);
                }
                else if (heroRoom.isInside(new Point(target.X, target.Y + 1)))
                {
                    target = new Point(target.X, target.Y + 1);
                }
                else if (heroRoom.isInside(new Point(target.X - 1, target.Y)))
                {
                    target = new Point(target.X - 1, target.Y);
                }
                else if (heroRoom.isInside(new Point(target.X, target.Y - 1)))
                {
                    target = new Point(target.X, target.Y - 1);
                }
            }

            if (target.X == -1000)
            {
                return;
            }

            Point oldPos    = Pos;
            int   distNorth = Math.Abs(target.X - Pos.X) + Math.Abs(target.Y - Pos.Y - 1);
            int   distSouth = Math.Abs(target.X - Pos.X) + Math.Abs(target.Y - Pos.Y + 1);
            int   distWest  = Math.Abs(target.X - Pos.X - 1) + Math.Abs(target.Y - Pos.Y);
            int   distEast  = Math.Abs(target.X - Pos.X + 1) + Math.Abs(target.Y - Pos.Y);

            if (heroInNextRoom)
            {
                target = new Point(-1000, -1000);
            }

            int       min = Math.Min(Math.Min(distNorth, distSouth), Math.Min(distEast, distWest));
            Direction dir;

            if (min == distNorth)
            {
                dir = Direction.SOUTH;
            }
            else if (min == distSouth)
            {
                dir = Direction.NORTH;
            }
            else if (min == distWest)
            {
                dir = Direction.EAST;
            }
            else
            {
                dir = Direction.WEST;
            }
            TryMove(dir);
            previousDoor = target.Copy();

            if (Dungeon.Hero.Pos == Pos)
            {
                Dungeon.Hero.TakeDamage(GetDamageLevel());

                Console.WriteLine("Hero health at {0}", Dungeon.Hero.Health);
                if (!Dungeon.Hero.IsDead())
                {
                    Pos = oldPos;
                }
                else
                {
                    Console.WriteLine("GAME OVER");
                }
            }
        }
예제 #18
0
        protected void FetchMaterial()
        {
            internalQuantity = Math.Min(internalQuantity, inputQuantity); //this shouldn't be necessary


            BlockPos    bp             = Pos.Copy().Offset(rmInputFace);
            BlockEntity checkblock     = Api.World.BlockAccessor.GetBlockEntity(bp);
            var         inputContainer = checkblock as BlockEntityContainer;

            if (inputContainer == null)
            {
                return;
            }
            if (inputContainer.Inventory.Empty)
            {
                return;
            }
            for (int c = 0; c < inputContainer.Inventory.Count; c++)
            {
                ItemSlot checkslot = inputContainer.Inventory[c];
                if (checkslot == null)
                {
                    continue;
                }
                if (checkslot.StackSize < inputQuantity)
                {
                    continue;
                }
                bool  match       = false;
                Item  checkitem   = checkslot.Itemstack.Item;
                Block checkiblock = checkslot.Itemstack.Block;
                ingredient_subtype = "";

                if (checkitem == null && checkiblock == null)
                {
                    continue;
                }
                if (checkitem != null)
                {
                    string fcp = checkitem.FirstCodePart().ToString();
                    string lcp = checkitem.LastCodePart().ToString();
                    //no materials list so we don't need check for subtypes
                    if (checkitem.Code.ToString() == ingredient)
                    {
                        match = true;
                    }
                    else if (checkitem.FirstCodePart() == ingredient && (materials == null || materials.Length == 0))
                    {
                        match = true;
                    }
                    else if (checkitem.FirstCodePart().ToString() == ingredient && materials.Contains(checkitem.LastCodePart().ToString()))
                    {
                        match = true;
                        ingredient_subtype = checkitem.LastCodePart();
                    }
                }
                else if (checkiblock != null)
                {
                    if (checkiblock.Code.ToString() == ingredient)
                    {
                        match = true;
                    }
                    else if (checkiblock.FirstCodePart().ToString() == ingredient && (materials == null || materials.Length == 0))
                    {
                        match = true;
                    }
                    else if (checkiblock.FirstCodePart().ToString() == ingredient && materials.Contains(checkiblock.LastCodePart().ToString()))
                    {
                        match = true;
                        ingredient_subtype = checkiblock.LastCodePart();
                    }
                }
                if (match)
                {
                    bool heatok = true;
                    lastheatreading = checkslot.Itemstack.Collectible.GetTemperature(Api.World, checkslot.Itemstack);
                    if (heatRequirement > 0 && lastheatreading < heatRequirement)
                    {
                        heatok = false;
                    }
                    if (heatok)
                    {
                        int reqQty = Math.Min(checkslot.StackSize, inputQuantity - internalQuantity);
                        checkslot.TakeOut(reqQty);
                        internalQuantity += reqQty;
                        checkslot.MarkDirty();
                    }
                }
            }


            return;
        }
예제 #19
0
        internal void UpdateVoxel(IPlayer byPlayer, ItemSlot itemslot, Vec3i voxelPos, BlockFacing facing, bool isBreak)
        {
            if (!Api.World.Claims.TryAccess(byPlayer, Pos, EnumBlockAccessFlags.Use))
            {
                MarkDirty(true, byPlayer);
                return;
            }


            EnumChiselMode mode = GetChiselMode(byPlayer);

            bool wasChanged = false;

            byte[] lightHsv = this.LightHsv;

            switch (mode)
            {
            case EnumChiselMode.Rename:
                IClientWorldAccessor clientWorld = (IClientWorldAccessor)Api.World;

                string prevName = BlockName;
                GuiDialogBlockEntityTextInput dlg = new GuiDialogBlockEntityTextInput(Lang.Get("Block name"), Pos, BlockName, Api as ICoreClientAPI, 500);
                dlg.OnTextChanged = (text) => BlockName = text;
                dlg.OnCloseCancel = () => BlockName = prevName;
                dlg.TryOpen();
                break;

            case EnumChiselMode.Flip:
                FlipVoxels(Block.SuggestedHVOrientation(byPlayer, new BlockSelection()
                {
                    Position = Pos.Copy(), HitPosition = new Vec3d(voxelPos.X / 16.0, voxelPos.Y / 16.0, voxelPos.Z / 16.0)
                })[0]);
                wasChanged = true;
                break;

            case EnumChiselMode.Rotate:
                RotateModel(isBreak ? 90 : -90, null);
                wasChanged = true;
                break;


            default:
                int   size     = GetChiselSize(byPlayer);
                Vec3i addAtPos = voxelPos.Clone().Add(size * facing.Normali.X, size * facing.Normali.Y, size * facing.Normali.Z);

                if (isBreak)
                {
                    wasChanged = SetVoxel(voxelPos, false, byPlayer, nowmaterialIndex);
                }
                else
                {
                    if (addAtPos.X >= 0 && addAtPos.X < 16 && addAtPos.Y >= 0 && addAtPos.Y < 16 && addAtPos.Z >= 0 && addAtPos.Z < 16)
                    {
                        wasChanged = SetVoxel(addAtPos, true, byPlayer, nowmaterialIndex);
                    }
                }

                break;
            }


            if (!wasChanged)
            {
                return;
            }

            if (Api.Side == EnumAppSide.Client)
            {
                RegenMesh();
            }

            RegenSelectionBoxes(byPlayer);
            MarkDirty(true, byPlayer);

            // Send a custom network packet for server side, because
            // serverside blockselection index is inaccurate
            if (Api.Side == EnumAppSide.Client)
            {
                SendUseOverPacket(byPlayer, voxelPos, facing, isBreak);
            }

            double posx = Pos.X + voxelPos.X / 16f;
            double posy = Pos.Y + voxelPos.Y / 16f;
            double posz = Pos.Z + voxelPos.Z / 16f;

            Api.World.PlaySoundAt(new AssetLocation("sounds/player/knap" + (Api.World.Rand.Next(2) > 0 ? 1 : 2)), posx, posy, posz, byPlayer, true, 12, 1);

            if (byPlayer.WorldData.CurrentGameMode != EnumGameMode.Creative && Api.World.Rand.Next(3) == 0)
            {
                itemslot.Itemstack?.Collectible.DamageItem(Api.World, byPlayer.Entity, itemslot);
            }


            if (VoxelCuboids.Count == 0)
            {
                Api.World.BlockAccessor.SetBlock(0, Pos);
                Api.World.BlockAccessor.RemoveBlockLight(LightHsv, Pos);
                return;
            }
        }
예제 #20
0
        //will check and see if there's enough water, and will use water if necessary
        bool CheckWater()
        {
            //find a block with water
            //if there is water check and see if it's time to use up some water

            //assume if we had water before (or just started) that there is water
            //TODO - need to add haswater, lastwaterused to treeattributes
            double nextwater   = lastwaterused + waterUsePeriod;
            double currenttime = Api.World.Calendar.TotalHours;

            if (currenttime < nextwater && haswater)
            {
                return(true);
            }
            haswater      = false;
            lastwaterused = currenttime;
            BlockPos    bp         = Pos.Copy().Offset(waterFace);
            BlockEntity checkblock = Api.World.BlockAccessor.GetBlockEntity(bp);

            if (checkblock == null)
            {
                haswater = false; return(false);
            }
            var checkcontainer = checkblock as BlockEntityContainer;

            if (checkcontainer != null)
            {
                for (int c = 0; c < checkcontainer.Inventory.Count; c++)
                {
                    ItemSlot checkslot = checkcontainer.Inventory[c];
                    if (checkslot == null)
                    {
                        continue;
                    }
                    if (checkslot.StackSize == 0)
                    {
                        continue;
                    }

                    bool match = false;
                    if (checkslot.Itemstack.Item != null && checkslot.Itemstack.Item.Code.ToString().Contains("waterportion"))
                    {
                        match = true;
                    }

                    if (match && checkslot.StackSize > 0)
                    {
                        checkslot.TakeOut(1);
                        if (checkslot.StackSize < 5)
                        {
                            Api.World.PlaySoundAt(new AssetLocation("sounds/waterslosh"), Pos.X, Pos.Y, Pos.Z, null, false, 8, 1);
                        }
                        else
                        {
                            Api.World.PlaySoundAt(new AssetLocation("sounds/steamburst"), Pos.X, Pos.Y, Pos.Z, null, false, 8, 1);
                        }
                        checkslot.MarkDirty();
                        haswater = true;
                        break;
                    }
                }
            }

            return(haswater);
        }
예제 #21
0
        public virtual bool DoGeneratePower()
        {
            if (!isOn)
            {
                return(false);
            }
            if (!usesFuel)
            {
                return(true);
            }                               //if we don't use fuel, we can make power
            if (capacitor == capacitance && !usesFuelWhileOn)
            {
                return(false);
            }                                      //not necessary to generate power
            if (fueled && fuelCounter < fuelTicks) //on going burning of current fuel item
            {
                fuelCounter++;
                return(true);
            }
            //Now we begin trying to fuel
            fueled = false; fuelCounter = 0;
            BlockPos    bp             = Pos.Copy().Offset(fuelHopperFace);
            BlockEntity checkblock     = Api.World.BlockAccessor.GetBlockEntity(bp);
            var         inputContainer = checkblock as BlockEntityContainer;

            if (inputContainer == null)
            {
                return(false);
            }                                             //no fuel container at all
            if (inputContainer.Inventory.Empty)
            {
                return(false);
            }                                                     //the fuel container is empty
            //check each inventory slot in the container
            for (int c = 0; c < inputContainer.Inventory.Count; c++)
            {
                ItemSlot checkslot = inputContainer.Inventory[c];
                if (checkslot == null)
                {
                    continue;
                }
                if (checkslot.StackSize == 0)
                {
                    continue;
                }

                bool match = false;
                if (checkslot.Itemstack.Item != null && fuelCodes.Contains(checkslot.Itemstack.Item.Code.ToString()))
                {
                    match = true;
                }
                else if (checkslot.Itemstack.Block != null && fuelCodes.Contains(checkslot.Itemstack.Block.Code.ToString()))
                {
                    match = true;
                }
                if (match && checkslot.StackSize > 0)
                {
                    checkslot.TakeOut(1);
                    checkslot.MarkDirty();
                    fueled = true;
                }
            }
            return(fueled);
        }
예제 #22
0
        public virtual float GetPerishRate()
        {
            // ##TODO: for performance the cond.Temperature can be saved in a field for each BlockEntityContainer, worldgen climage values at a position will not change
            // ##TODO: for performance, perishRate can be cached instead of being re-calculated for each separate slot which is updated

            BlockPos sealevelpos = Pos.Copy();

            sealevelpos.Y = Api.World.SeaLevel;

            // ##TODO: this ought to be season specific, i.e. perishrate should rise on a hot summer day
            ClimateCondition cond = Api.World.BlockAccessor.GetClimateAt(sealevelpos);

            if (cond == null)
            {
                return(1);
            }

            if (room == null)
            {
                room = roomReg.GetRoomForPosition(Pos);
            }

            float soilTempWeight     = 0f;
            float skyLightProportion = (float)room.SkylightCount / Math.Max(1, room.SkylightCount + room.NonSkylightCount);   // avoid any risk of divide by zero

            if (room.IsSmallRoom)
            {
                soilTempWeight = 1f;
                // If there's too much skylight, it's less cellar-like
                soilTempWeight -= 0.4f * skyLightProportion;
                // If non-cooling blocks exceed cooling blocks, it's less cellar-like
                soilTempWeight -= 0.5f * GameMath.Clamp((float)room.NonCoolingWallCount / Math.Max(1, room.CoolingWallCount), 0f, 1f);
            }

            int lightlevel = Api.World.BlockAccessor.GetLightLevel(Pos, EnumLightLevelType.OnlySunLight);

            // light level above 12 makes it additionally warmer, especially when part of a cellar or a greenhouse
            float lightImportance = 0.1f;

            // light in small fully enclosed rooms has a big impact
            if (room.IsSmallRoom)
            {
                lightImportance += 0.3f * soilTempWeight + 1.75f * skyLightProportion;
            }
            // light in large most enclosed rooms (e.g. houses, greenhouses) has medium impact
            else if (room.ExitCount <= 0.1f * (room.CoolingWallCount + room.NonCoolingWallCount))
            {
                lightImportance += 1.25f * skyLightProportion;
            }
            // light outside rooms (e.g. chests on world surface) has low impact but still warms them above base air temperature
            else
            {
                lightImportance += 0.5f * skyLightProportion;
            }
            lightImportance = GameMath.Clamp(lightImportance, 0f, 1.5f);
            float airTemp = cond.Temperature + GameMath.Clamp(lightlevel - 11, 0, 10) * lightImportance;


            // Lets say deep soil temperature is a constant 5°C
            // ##TODO: this ought to depend on worldgen climate: in the Arctic for example, deep soil temperature is going to be lower ...
            // ##TODO: this ought to be based on depth below worldgen original world surface
            float cellarTemp = 5;

            // How good of a cellar it is depends on how much rock or soil was used on he cellars walls
            float hereTemp = GameMath.Lerp(airTemp, cellarTemp, soilTempWeight);

            // For fairness lets say if its colder outside, use that temp instead
            hereTemp = Math.Min(hereTemp, airTemp);

            // Some neat curve to turn the temperature into a spoilage rate
            // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJtYXgoMC4xLG1pbigyLjUsM14oeC8xOS0xLjIpKS0wLjEpIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTIwIiwiNDAiLCIwIiwiMyJdLCJncmlkIjpbIjIuNSIsIjAuMjUiXX1d
            // max(0.1, min(2.5, 3^(x/15 - 1.2))-0.1)
            float rate = Math.Max(0.1f, Math.Min(2.4f, (float)Math.Pow(3, hereTemp / 19 - 1.2) - 0.1f));

            return(rate);
        }