Пример #1
0
        public override void Initialize(ICoreAPI api)
        {
            base.Initialize(api);

            inv.LateInitialize(InventoryClassName + "-" + Pos, api);

            capi = api as ICoreClientAPI;

            if (api.Side == EnumAppSide.Client)
            {
                RegisterGameTickListener(onClientTick50ms, 50);
            }
            else
            {
                RegisterGameTickListener(onServerTick1s, 1000);
            }


            ms    = Block.Attributes["multiblockStructure"].AsObject <MultiblockStructure>();
            msOpp = Block.Attributes["multiblockStructure"].AsObject <MultiblockStructure>();
            int rotYDeg    = 0;
            int rotYDegOpp = 180;

            if (Block.Variant["side"] == "east")   //BlockStoneCoffin only has a BE on north and east variants
            {
                rotYDeg    = 270;
                rotYDegOpp = 90;
            }

            ms.InitForUse(rotYDeg);
            msOpp.InitForUse(rotYDegOpp);

            blockScs = Block as BlockStoneCoffinSection;
            updateSelectiveElements();



            particlePositions[0] = Pos.DownCopy(2);
            particlePositions[1] = particlePositions[0].AddCopy(blockScs.Orientation.Opposite);

            particlePositions[2] = Pos.AddCopy(blockScs.Orientation.GetCW());
            particlePositions[3] = Pos.AddCopy(blockScs.Orientation.GetCCW());

            particlePositions[4] = Pos.AddCopy(blockScs.Orientation.GetCW()).Add(blockScs.Orientation.Opposite);
            particlePositions[5] = Pos.AddCopy(blockScs.Orientation.GetCCW()).Add(blockScs.Orientation.Opposite);

            particlePositions[6] = Pos.UpCopy(1).Add(blockScs.Orientation.Opposite);

            inv.SetSecondaryPos(Pos.AddCopy(blockScs.Orientation.Opposite));
        }
Пример #2
0
        public override void Initialize(ICoreAPI api)
        {
            base.Initialize(api);

            inv.LateInitialize(InventoryClassName + "-" + Pos, api);

            capi = api as ICoreClientAPI;

            structure = Block.Attributes["multiBlockStructure"].AsObject <MultiblockStructure>();
            structure.InitForUse(0);

            if (processing && !processComplete && api.Side == EnumAppSide.Server)
            {
                tickListener = RegisterGameTickListener(onServerTick3s, 3000);
            }
        }
Пример #3
0
        private void GenMarkedMultiblockCode(IServerPlayer player)
        {
            BlockPos centerPos = player.CurrentBlockSelection.Position;
            OrderedDictionary <int, int> blocks = new OrderedDictionary <int, int>();
            List <Vec4i> offsets = new List <Vec4i>();

            MultiblockStructure ms = new MultiblockStructure();

            sapi.World.BlockAccessor.WalkBlocks(workspace.StartMarker, workspace.EndMarker, (block, x, y, z) =>
            {
                if (block.Id == 0)
                {
                    return;
                }

                int blockNum = ms.GetOrCreateBlockNumber(block);
                BlockOffsetAndNumber offset = new BlockOffsetAndNumber(x - centerPos.X, y - centerPos.Y, z - centerPos.Z, blockNum);
                ms.Offsets.Add(offset);
            }, true);

            StringBuilder sb = new StringBuilder();

            sb.AppendLine("multiblockStructure: {");
            sb.AppendLine("\tblockNumbers: {");
            foreach (var val in ms.BlockNumbers)
            {
                sb.AppendLine(string.Format("\t\t\"{0}\": {1},", val.Key.ToShortString(), val.Value));
            }
            sb.AppendLine("\t},");
            sb.AppendLine("\toffsets: [");

            foreach (var val in ms.Offsets)
            {
                sb.AppendLine(string.Format("\t\t{{ x: {0}, y: {1}, z: {2}, w: {3} }},", val.X, val.Y, val.Z, val.W));
            }

            sb.AppendLine("\t]");
            sb.AppendLine("}");


            sapi.World.Logger.Notification("Multiblockstructure centered around {0}:\n{1}", centerPos, sb.ToString());

            Good("Json code written to server-main.txt");
        }
Пример #4
0
    void NatureCreation(Chunk chunk)
    {
        byte x = (byte)(Random.value * (Chunk.CHUNK_SIZE - 2) + 1);
        byte z = (byte)(Random.value * (Chunk.CHUNK_SIZE - 2) + 1);

        x = (byte)(Chunk.CHUNK_SIZE / 2); z = (byte)(Chunk.CHUNK_SIZE / 2);
        //surface[x,z].ReplaceMaterial(PoolMaster.grass_material);
        //chunk.SpreadBlocks(x,z, PoolMaster.GRASS_ID);

        MultiblockStructure ms = null;

        if (Random.value > 0.5f)
        {
            ms = Structure.GetStructureByID(Structure.TREE_OF_LIFE_ID) as MultiblockStructure;
        }
        else
        {
            ms = Structure.GetStructureByID(Structure.LIFESTONE_ID) as MultiblockStructure;
        }
        SurfaceBlock sb = chunk.GetSurfaceBlock(x, z);

        ms.SetBasement(sb, PixelPosByte.zero);
        chunk.GenerateNature(ms.transform.position);
    }
Пример #5
0
        private void onServerTick3s(float dt)
        {
            BlockPos coalPilePos      = Pos.DownCopy(2);
            BlockPos othercoalPilePos = coalPilePos.AddCopy(blockScs.Orientation.Opposite);

            bool beforeReceiveHeat       = receivesHeat;
            bool beforeStructureComplete = structureComplete;

            if (!receivesHeat)
            {
                totalHoursLastUpdate = Api.World.Calendar.TotalHours;
            }

            BlockEntityCoalPile becp = Api.World.BlockAccessor.GetBlockEntity(coalPilePos) as BlockEntityCoalPile;
            float leftHeatHoursLeft  = (becp != null && becp.IsBurning) ? becp.GetHoursLeft(totalHoursLastUpdate) : 0f;

            becp = Api.World.BlockAccessor.GetBlockEntity(othercoalPilePos) as BlockEntityCoalPile;
            float rightHeatHoursLeft = (becp != null && becp.IsBurning) ? becp.GetHoursLeft(totalHoursLastUpdate) : 0f;

            receivesHeat = leftHeatHoursLeft > 0 && rightHeatHoursLeft > 0;


            if (processComplete || !IsFull || !hasLid())
            {
                return;
            }

            MultiblockStructure msInUse  = null;
            BlockPos            posInUse = null;

            structureComplete = false;
            if (ms.InCompleteBlockCount(Api.World, Pos) == 0)
            {
                msInUse           = ms;
                posInUse          = Pos;
                structureComplete = true;
            }
            else if (msOpp.InCompleteBlockCount(Api.World, Pos.AddCopy(blockScs.Orientation.Opposite)) == 0)
            {
                msInUse           = msOpp;
                posInUse          = Pos.AddCopy(blockScs.Orientation.Opposite);
                structureComplete = true;
            }

            if (beforeReceiveHeat != receivesHeat || beforeStructureComplete != structureComplete)
            {
                MarkDirty();
            }

            if (receivesHeat)
            {
                if (!structureComplete)
                {
                    return;
                }

                double hoursPassed       = Api.World.Calendar.TotalHours - totalHoursLastUpdate;
                double heatHoursReceived = Math.Max(0, Math.Min(hoursPassed, Math.Min(leftHeatHoursLeft, rightHeatHoursLeft)));

                progress            += heatHoursReceived / 160f;
                totalHoursLastUpdate = Api.World.Calendar.TotalHours;
                MarkDirty();
            }

            if (progress >= 1.0)
            {
                int stacksize = inv[1].Itemstack.StackSize;

                JsonItemStack jstack = inv[1].Itemstack.ItemAttributes?["carburizableProps"]["carburizedOutput"].AsObject <JsonItemStack>(null, Block.Code.Domain);
                if (jstack.Resolve(Api.World, "carburizable output"))
                {
                    inv[0].Itemstack.StackSize -= 8;
                    inv[1].Itemstack            = jstack.ResolvedItemstack.Clone();
                    inv[1].Itemstack.StackSize  = stacksize;
                }
                MarkDirty();

                msInUse.WalkMatchingBlocks(Api.World, posInUse, (block, pos) =>
                {
                    float resis = block.Attributes?["heatResistance"].AsFloat(1) ?? 1;

                    if (Api.World.Rand.NextDouble() > resis)
                    {
                        Block nowblock = Api.World.GetBlock(block.CodeWithVariant("state", "damaged"));
                        Api.World.BlockAccessor.SetBlock(nowblock.Id, pos);
                    }
                });

                processComplete = true;
            }
        }
Пример #6
0
        public bool Interact(IPlayer byPlayer, bool preferThis)
        {
            bool sneaking = byPlayer.WorldData.EntityControls.Sneak;

            int      damagedTiles    = 0;
            int      wrongTiles      = 0;
            int      incompleteCount = 0;
            BlockPos posMain         = Pos;

            // set up incompleteCount (etc) for both orientations and pick whichever is more complete
            if (sneaking)
            {
                int ic    = 0;
                int icOpp = int.MaxValue;
                int dt    = 0;
                int wt    = 0;
                int dtOpp = 0;
                int wtOpp = 0;

                ic = ms.InCompleteBlockCount(Api.World, Pos,
                                             (haveBlock, wantLoc) => { if (haveBlock.FirstCodePart() == "refractorybricks" && haveBlock.Variant["state"] == "damaged")
                                                                       {
                                                                           dt++;
                                                                       }
                                                                       else
                                                                       {
                                                                           wt++;
                                                                       } }
                                             );
                if (ic > 0 && blockScs.IsCompleteCoffin(Pos))
                {
                    icOpp = msOpp.InCompleteBlockCount(Api.World, Pos.AddCopy(blockScs.Orientation.Opposite),
                                                       (haveBlock, wantLoc) => { if (haveBlock.FirstCodePart() == "refractorybricks" && haveBlock.Variant["state"] == "damaged")
                                                                                 {
                                                                                     dtOpp++;
                                                                                 }
                                                                                 else
                                                                                 {
                                                                                     wtOpp++;
                                                                                 } }
                                                       );
                }

                // This logic aims to figure out which structure to show - if one is almost complete (3 wrong tiles or less) that one will be shown; preferThis has a preference if both are equally incomplete (newly placed stonecoffin) or if one is not much more complete than the other (allows for building errors of 1-3 tiles before the shown structure flips)
                if (wtOpp <= 3 && wt < wtOpp || wtOpp > 3 && wt < wtOpp - 3 || preferThis && wt <= wtOpp || preferThis && wt > 3 && wt <= wtOpp + 3)
                {
                    incompleteCount = ic;
                    damagedTiles    = dt;
                    wrongTiles      = wt;
                    if (ic > 0)
                    {
                        msHighlighted = ms;
                    }
                }
                else
                {
                    incompleteCount = icOpp;
                    damagedTiles    = dtOpp;
                    wrongTiles      = wtOpp;
                    msHighlighted   = msOpp;
                    posMain         = Pos.AddCopy(blockScs.Orientation.Opposite);
                }
            }

            if (sneaking && incompleteCount > 0)
            {
                if (wrongTiles > 0 && damagedTiles > 0)
                {
                    capi?.TriggerIngameError(this, "incomplete", Lang.Get("Structure is not complete, {0} blocks are missing or wrong, {1} tiles are damaged!", wrongTiles, damagedTiles));
                }
                else
                {
                    if (wrongTiles > 0)
                    {
                        capi?.TriggerIngameError(this, "incomplete", Lang.Get("Structure is not complete, {0} blocks are missing or wrong!", wrongTiles));
                    }
                    else
                    {
                        if (damagedTiles == 1)
                        {
                            capi?.TriggerIngameError(this, "incomplete", Lang.Get("Structure is not complete, {0} tile is damaged!", damagedTiles));
                        }
                        else
                        {
                            capi?.TriggerIngameError(this, "incomplete", Lang.Get("Structure is not complete, {0} tiles are damaged!", damagedTiles));
                        }
                    }
                }

                if (Api.Side == EnumAppSide.Client)
                {
                    msHighlighted.HighlightIncompleteParts(Api.World, byPlayer, posMain);
                }
                return(false);
            }
            else
            {
                if (Api.Side == EnumAppSide.Client)
                {
                    msHighlighted?.ClearHighlights(Api.World, byPlayer);
                }
            }

            if (!sneaking)
            {
                return(false);
            }

            if (!blockScs.IsCompleteCoffin(Pos))
            {
                capi?.TriggerIngameError(this, "incomplete", Lang.Get("Cannot fill an incomplete coffin, place the other half first"));
                return(false);
            }

            ItemSlot slot = byPlayer.InventoryManager.ActiveHotbarSlot;


            if (!slot.Empty)
            {
                if (IngotCount / 4 >= CoalLayerCount)
                {
                    return(AddCoal(slot));
                }
                else
                {
                    return(AddIngot(slot));
                }
            }

            return(true);
        }