Exemple #1
0
        private string GetSuggestedKnobOrientation(IBlockAccessor ba, BlockPos pos, BlockFacing facing)
        {
            string leftOrRight = "left";

            Block nBlock1 = ba.GetBlock(pos.AddCopy(facing.GetCCW()));
            Block nBlock2 = ba.GetBlock(pos.AddCopy(facing.GetCW()));

            bool isDoor1 = IsSameDoor(nBlock1);
            bool isDoor2 = IsSameDoor(nBlock2);

            if (isDoor1 && isDoor2)
            {
                leftOrRight = "left";
            }
            else
            {
                if (isDoor1)
                {
                    leftOrRight = GetKnobOrientation(nBlock1) == "right" ? "left" : "right";
                }
                else if (isDoor2)
                {
                    leftOrRight = GetKnobOrientation(nBlock2) == "right" ? "left" : "right";
                }
            }
            return(leftOrRight);
        }
Exemple #2
0
        protected override BlockPos TryGetConnectedDoorPos(BlockPos pos)
        {
            string      knob = GetKnobOrientation();
            BlockFacing dir  = GetDirection();

            return(knob == "left" ? pos.AddCopy(dir.GetCW()) : pos.AddCopy(dir.GetCCW()));
        }
Exemple #3
0
 //Take a block code (that ends in a cardinal direction) and a BlockFacing,
 //and rotate it, returning the appropriate blockfacing
 public static BlockFacing OrientFace(string checkBlockCode, BlockFacing toChange)
 {
     if (!toChange.IsHorizontal)
     {
         return(toChange);
     }
     if (checkBlockCode.EndsWith("east"))
     {
         toChange = toChange.GetCW();
     }
     else if (checkBlockCode.EndsWith("south"))
     {
         toChange = toChange.GetCW().GetCW();
     }
     else if (checkBlockCode.EndsWith("west"))
     {
         toChange = toChange.GetCCW();
     }
     return(toChange);
 }
Exemple #4
0
        private string GetSuggestedKnobOrientation(IBlockAccessor ba, BlockPos pos, BlockFacing facing, out bool neighbourOpen)
        {
            string leftOrRight = "left";

            Block nBlock1 = ba.GetBlock(pos.AddCopy(facing.GetCW()));
            Block nBlock2 = ba.GetBlock(pos.AddCopy(facing.GetCCW()));
            bool  invert  = facing == BlockFacing.EAST || facing == BlockFacing.SOUTH; //doors and gates assets are setup for n or w orientations

            bool isDoor1 = IsSameDoor(nBlock1);
            bool isDoor2 = IsSameDoor(nBlock2);

            if (isDoor1 && isDoor2)
            {
                leftOrRight   = "left";
                neighbourOpen = (nBlock1 as BlockBaseDoor).IsOpened();
            }
            else
            {
                if (isDoor1)
                {
                    if (GetKnobOrientation(nBlock1) == "right")   //facing gate: the gate to the right, has its hinge away from us
                    {
                        leftOrRight   = invert ? "left" : "right";
                        neighbourOpen = false;
                    }
                    else
                    {
                        leftOrRight   = invert ? "right" : "left";
                        neighbourOpen = (nBlock1 as BlockBaseDoor).IsOpened();
                    }
                }
                else if (isDoor2)
                {
                    if (GetKnobOrientation(nBlock2) == "right")   //facing gate: the gate to the left, has its hinge towards us ("knob" is hinge apparently)
                    {
                        leftOrRight   = invert ? "right" : "left";
                        neighbourOpen = false;
                    }
                    else
                    {
                        leftOrRight   = invert ? "left" : "right";
                        neighbourOpen = (nBlock2 as BlockBaseDoor).IsOpened();
                    }
                }
                else
                {
                    //no neighbouring gate, but some AI for trying to guess which side the player wants the hinge (including potentially the first gate to be placed of a double gate)
                    neighbourOpen = false;
                    if (nBlock1.Attributes?.IsTrue("isFence") == true ^ nBlock2.Attributes?.IsTrue("isFence") == true)
                    {
                        leftOrRight = (invert ^ nBlock2.Attributes?.IsTrue("isFence") == true) ? "left" : "right";
                    }
                    else if (nBlock2.Replaceable >= 6000 && nBlock1.Replaceable < 6000)  //empty space on left, place hinge on right
                    {
                        leftOrRight = invert ? "left" : "right";
                    }
                    else if (nBlock1.Replaceable >= 6000 && nBlock2.Replaceable < 6000)  //empty space on right, place hinge on left
                    {
                        leftOrRight = invert ? "right" : "left";
                    }
                }
            }
            return(leftOrRight);
        }
Exemple #5
0
        protected override BlockPos TryGetConnectedDoorPos(BlockPos pos)
        {
            BlockFacing dir = GetDirection();

            return(pos.AddCopy(dir.GetCW()));
        }
        protected virtual BlockFacing[] OrientForPlacement(IBlockAccessor worldmap, IPlayer player, BlockSelection bs)
        {
            BlockFacing[] facings    = SuggestedHVOrientation(player, bs);
            BlockPos      pos        = bs.Position;
            BlockFacing   horizontal = null;
            BlockFacing   face       = bs.Face.Opposite;
            BlockFacing   vert       = null;

            //If player is placing against a block horizontally, check that one and all other horizontals for connectors
            if (face.IsHorizontal)
            {
                if (HasConnector(worldmap, pos.AddCopy(face), bs.Face, out vert))
                {
                    horizontal = face;
                }
                else
                {
                    face = face.GetCW();
                    if (HasConnector(worldmap, pos.AddCopy(face), face.Opposite, out vert))
                    {
                        horizontal = face;
                    }
                    else if (HasConnector(worldmap, pos.AddCopy(face.Opposite), face, out vert))
                    {
                        horizontal = face.Opposite;
                    }
                    else if (HasConnector(worldmap, pos.AddCopy(bs.Face), bs.Face.Opposite, out vert))
                    {
                        horizontal = bs.Face;
                    }
                }
                //Special case: the 3way has two connectors but the directional attribute covers only one of them
                if (Type == "3way" && horizontal != null)
                {
                    face = horizontal.GetCW();
                    BlockFacing unused = null;
                    if (HasConnector(worldmap, pos.AddCopy(face), face.Opposite, out unused) && !HasConnector(worldmap, pos.AddCopy(face.Opposite), face, out unused))
                    {
                        horizontal = face;
                    }
                }
            }
            else
            {
                //Player is placing against a block vertically, use that as the vertical connection and check all horizontals for connectors
                vert = face;
                bool moreThanOne = false;
                horizontal = HasConnector(worldmap, pos.EastCopy(), BlockFacing.WEST, out vert) ? BlockFacing.EAST : null;
                if (HasConnector(worldmap, pos.WestCopy(), BlockFacing.EAST, out vert))
                {
                    moreThanOne = horizontal != null;
                    horizontal  = BlockFacing.WEST;
                }
                if (HasConnector(worldmap, pos.NorthCopy(), BlockFacing.SOUTH, out vert))
                {
                    moreThanOne = horizontal != null;
                    horizontal  = BlockFacing.NORTH;
                }
                if (HasConnector(worldmap, pos.SouthCopy(), BlockFacing.NORTH, out vert))
                {
                    moreThanOne = horizontal != null;
                    horizontal  = BlockFacing.SOUTH;
                }
                if (moreThanOne)
                {
                    horizontal = null;
                }
            }
            if (vert == null)
            {
                //If vertical orientation not already chosen, see whether there is an existing open connector up or down
                BlockFacing unused = null;
                bool        up     = HasConnector(worldmap, pos.UpCopy(), BlockFacing.DOWN, out unused);
                bool        down   = HasConnector(worldmap, pos.DownCopy(), BlockFacing.UP, out unused);
                if (up && !down)
                {
                    vert = BlockFacing.UP;
                }
                else if (down && !up)
                {
                    vert = BlockFacing.DOWN;
                }
            }
            if (vert != null)
            {
                facings[1] = vert;
            }
            facings[0] = horizontal ?? facings[0].Opposite;
            return(facings);
        }
Exemple #7
0
        /// <summary>
        /// Attempts to transform each block as they are placed in directions different from the schematic.
        /// </summary>
        /// <param name="worldForResolve"></param>
        /// <param name="aroundOrigin"></param>
        /// <param name="angle"></param>
        /// <param name="flipAxis"></param>
        public virtual void TransformWhilePacked(IWorldAccessor worldForResolve, EnumOrigin aroundOrigin, int angle, EnumAxis?flipAxis = null)
        {
            BlockPos curPos   = new BlockPos();
            BlockPos startPos = new BlockPos(1024, 1024, 1024);

            BlocksUnpacked.Clear();
            BlockEntitiesUnpacked.Clear();
            DecorsUnpacked.Clear();
            EntitiesUnpacked.Clear();

            angle = GameMath.Mod(angle, 360);

            for (int i = 0; i < Indices.Count; i++)
            {
                uint index         = Indices[i];
                int  storedBlockid = BlockIds[i];

                int dx = (int)(index & 0x1ff);
                int dy = (int)((index >> 20) & 0x1ff);
                int dz = (int)((index >> 10) & 0x1ff);

                AssetLocation blockCode = BlockCodes[storedBlockid];

                Block newBlock = worldForResolve.GetBlock(blockCode);
                if (newBlock == null)
                {
                    BlockEntities.Remove(index);
                    continue;
                }

                if (flipAxis != null)
                {
                    if (flipAxis == EnumAxis.Y)
                    {
                        dy = SizeY - dy;

                        AssetLocation newCode = newBlock.GetVerticallyFlippedBlockCode();
                        newBlock = worldForResolve.GetBlock(newCode);
                    }

                    if (flipAxis == EnumAxis.X)
                    {
                        dx = SizeX - dx;

                        AssetLocation newCode = newBlock.GetHorizontallyFlippedBlockCode((EnumAxis)flipAxis);
                        newBlock = worldForResolve.GetBlock(newCode);
                    }

                    if (flipAxis == EnumAxis.Z)
                    {
                        dz = SizeZ - dz;

                        AssetLocation newCode = newBlock.GetHorizontallyFlippedBlockCode((EnumAxis)flipAxis);
                        newBlock = worldForResolve.GetBlock(newCode);
                    }
                }

                if (angle != 0)
                {
                    AssetLocation newCode = newBlock.GetRotatedBlockCode(angle);
                    newBlock = worldForResolve.GetBlock(newCode);
                }

                if (aroundOrigin != EnumOrigin.StartPos)
                {
                    dx -= SizeX / 2;
                    dz -= SizeZ / 2;
                }

                BlockPos pos = new BlockPos(dx, dy, dz);

                // 90 deg:
                // xNew = -yOld
                // yNew = xOld

                // 180 deg:
                // xNew = -xOld
                // yNew = -yOld

                // 270 deg:
                // xNew = yOld
                // yNew = -xOld

                switch (angle)
                {
                case 90:
                    pos.Set(-dz, dy, dx);
                    break;

                case 180:
                    pos.Set(-dx, dy, -dz);
                    break;

                case 270:
                    pos.Set(dz, dy, -dx);
                    break;
                }

                if (aroundOrigin != EnumOrigin.StartPos)
                {
                    pos.X += SizeX / 2;
                    pos.Z += SizeZ / 2;
                }

                BlocksUnpacked[pos] = newBlock.BlockId;
            }


            for (int i = 0; i < DecorIndices.Count; i++)
            {
                uint index         = DecorIndices[i];
                int  storedBlockid = DecorIds[i];
                byte faceIndex     = (byte)(storedBlockid >> 24);
                if (faceIndex > 5)
                {
                    continue;
                }
                BlockFacing face = BlockFacing.ALLFACES[faceIndex];

                int dx = (int)(index & 0x1ff);
                int dy = (int)((index >> 20) & 0x1ff);
                int dz = (int)((index >> 10) & 0x1ff);

                AssetLocation blockCode = BlockCodes[storedBlockid & 0xFFFFFF];

                Block newBlock = worldForResolve.GetBlock(blockCode);
                if (newBlock == null)
                {
                    continue;
                }

                if (flipAxis != null)
                {
                    if (flipAxis == EnumAxis.Y)
                    {
                        dy = SizeY - dy;

                        AssetLocation newCode = newBlock.GetVerticallyFlippedBlockCode();
                        newBlock = worldForResolve.GetBlock(newCode);
                        if (face.IsVertical)
                        {
                            face = face.Opposite;
                        }
                    }

                    if (flipAxis == EnumAxis.X)
                    {
                        dx = SizeX - dx;

                        AssetLocation newCode = newBlock.GetHorizontallyFlippedBlockCode((EnumAxis)flipAxis);
                        newBlock = worldForResolve.GetBlock(newCode);
                        if (face.Axis == EnumAxis.X)
                        {
                            face = face.Opposite;
                        }
                    }

                    if (flipAxis == EnumAxis.Z)
                    {
                        dz = SizeZ - dz;

                        AssetLocation newCode = newBlock.GetHorizontallyFlippedBlockCode((EnumAxis)flipAxis);
                        newBlock = worldForResolve.GetBlock(newCode);
                        if (face.Axis == EnumAxis.Z)
                        {
                            face = face.Opposite;
                        }
                    }
                }

                if (angle != 0)
                {
                    AssetLocation newCode = newBlock.GetRotatedBlockCode(angle);
                    newBlock = worldForResolve.GetBlock(newCode);
                }

                if (aroundOrigin != EnumOrigin.StartPos)
                {
                    dx -= SizeX / 2;
                    dz -= SizeZ / 2;
                }

                BlockPos pos = new BlockPos(dx, dy, dz);

                // 90 deg:
                // xNew = -yOld
                // yNew = xOld

                // 180 deg:
                // xNew = -xOld
                // yNew = -yOld

                // 270 deg:
                // xNew = yOld
                // yNew = -xOld

                switch (angle)
                {
                case 90:
                    pos.Set(-dz, dy, dx);
                    if (face.IsHorizontal)
                    {
                        face = face.GetCW();
                    }
                    break;

                case 180:
                    pos.Set(-dx, dy, -dz);
                    if (face.IsHorizontal)
                    {
                        face = face.Opposite;
                    }
                    break;

                case 270:
                    pos.Set(dz, dy, -dx);
                    if (face.IsHorizontal)
                    {
                        face = face.GetCCW();
                    }
                    break;
                }

                if (aroundOrigin != EnumOrigin.StartPos)
                {
                    pos.X += SizeX / 2;
                    pos.Z += SizeZ / 2;
                }

                DecorsUnpacked.TryGetValue(pos, out Block[] decorsTmp);
                if (decorsTmp == null)
                {
                    decorsTmp           = new Block[6];
                    DecorsUnpacked[pos] = decorsTmp;
                }
                decorsTmp[face.Index] = newBlock;
            }


            foreach (var val in BlockEntities)
            {
                uint index = val.Key;
                int  dx    = (int)(index & 0x1ff);
                int  dy    = (int)((index >> 20) & 0x1ff);
                int  dz    = (int)((index >> 10) & 0x1ff);

                dx -= SizeX / 2;
                dz -= SizeZ / 2;

                BlockPos pos = new BlockPos(dx, dy, dz);

                // 90 deg:
                // xNew = -yOld
                // yNew = xOld

                // 180 deg:
                // xNew = -xOld
                // yNew = -yOld

                // 270 deg:
                // xNew = yOld
                // yNew = -xOld

                switch (angle)
                {
                case 90:
                    pos.Set(-dz, dy, dx);
                    break;

                case 180:
                    pos.Set(-dx, dy, -dz);
                    break;

                case 270:
                    pos.Set(dz, dy, -dx);
                    break;
                }

                pos.X += SizeX / 2;
                pos.Z += SizeZ / 2;

                curPos.Set(pos.X + startPos.X, pos.Y + startPos.Y, pos.Z + startPos.Z);

                string beData = val.Value;


                string entityclass = worldForResolve.GetBlock(BlocksUnpacked[pos]).EntityClass;

                if (entityclass != null)
                {
                    BlockEntity be = worldForResolve.ClassRegistry.CreateBlockEntity(entityclass);
                    if (be is IBlockEntityRotatable)
                    {
                        ITreeAttribute tree = DecodeBlockEntityData(beData);
                        (be as IBlockEntityRotatable).OnTransformed(tree, angle, flipAxis);
                        beData = StringEncodeTreeAttribute(tree);
                    }

                    BlockEntitiesUnpacked[pos] = beData;
                }
            }


            foreach (string entityData in Entities)
            {
                using (MemoryStream ms = new MemoryStream(Ascii85.Decode(entityData)))
                {
                    BinaryReader reader = new BinaryReader(ms);

                    string className = reader.ReadString();
                    Entity entity    = worldForResolve.ClassRegistry.CreateEntity(className);

                    entity.FromBytes(reader, false);
                    entity.DidImportOrExport(startPos);

                    double dx = entity.ServerPos.X - startPos.X;
                    double dy = entity.ServerPos.Y - startPos.Y;
                    double dz = entity.ServerPos.Z - startPos.Z;

                    dx -= SizeX / 2;
                    dz -= SizeZ / 2;

                    Vec3d pos = new Vec3d();

                    // 90 deg:
                    // xNew = -yOld
                    // yNew = xOld

                    // 180 deg:
                    // xNew = -xOld
                    // yNew = -yOld

                    // 270 deg:
                    // xNew = yOld
                    // yNew = -xOld

                    switch (angle)
                    {
                    case 90:
                        pos.Set(-dz, dy, dx);
                        break;

                    case 180:
                        pos.Set(-dx, dy, -dz);
                        break;

                    case 270:
                        pos.Set(dz, dy, -dx);
                        break;
                    }

                    pos.X += SizeX / 2;
                    pos.Z += SizeZ / 2;

                    entity.ServerPos.SetPos(startPos.X + pos.X, entity.ServerPos.Y, startPos.Z + pos.Z);
                    entity.Pos.SetPos(startPos.X + pos.X, entity.Pos.Y, startPos.Z + pos.Z);
                    entity.PositionBeforeFalling.Set(startPos.X + pos.X, entity.PositionBeforeFalling.Y, startPos.Z + pos.Z);

                    EntitiesUnpacked.Add(entity);
                }
            }


            Pack(worldForResolve, startPos);
        }
Exemple #8
0
    private void CheckWater(float dt)
    {
        willSpeed = 0;
        BlockPos block1pos = Position.AddCopy(face.GetCCW()).AddCopy(face.GetCCW());
        Block    block1    = Api.World.BlockAccessor.GetBlock(block1pos);
        Block    block2    = Api.World.BlockAccessor.GetBlock(block1pos.AddCopy(BlockFacing.DOWN));
        Block    block3    = Api.World.BlockAccessor.GetBlock(block1pos.AddCopy(BlockFacing.UP));

        if (block1.Code.BeginsWith("game", "water-d"))
        {
            willSpeed++;
        }
        if (block2.Code.BeginsWith("game", "water-d"))
        {
            willSpeed++;
        }
        if (block3.Code.BeginsWith("game", "water-d"))
        {
            willSpeed++;
        }
        BlockPos block2pos = Position.AddCopy(face.GetCW()).AddCopy(face.GetCW());
        Block    block21   = Api.World.BlockAccessor.GetBlock(block2pos);
        Block    block22   = Api.World.BlockAccessor.GetBlock(block2pos.AddCopy(BlockFacing.DOWN));
        Block    block23   = Api.World.BlockAccessor.GetBlock(block2pos.AddCopy(BlockFacing.UP));

        if (block21.Code.BeginsWith("game", "water-d"))
        {
            willSpeed--;
        }
        if (block22.Code.BeginsWith("game", "water-d"))
        {
            willSpeed--;
        }
        if (block23.Code.BeginsWith("game", "water-d"))
        {
            willSpeed--;
        }
        BlockPos block4pos  = Position.AddCopy(BlockFacing.DOWN).AddCopy(BlockFacing.DOWN);
        Block    block4     = Api.World.BlockAccessor.GetBlock(block4pos);
        Block    block5     = Api.World.BlockAccessor.GetBlock(block4pos.AddCopy(face.GetCCW()));
        Block    block6     = Api.World.BlockAccessor.GetBlock(block4pos.AddCopy(face.GetCW()));
        string   waterpath  = "water-" + face.GetCW().Code[0];
        string   waterpath2 = "water-" + face.GetCCW().Code[0];

        if (block4.Code.BeginsWith("game", waterpath))
        {
            willSpeed++;
        }
        else if (block4.Code.BeginsWith("game", waterpath2))
        {
            willSpeed--;
        }
        if (block5.Code.BeginsWith("game", waterpath))
        {
            willSpeed++;
        }
        else if (block5.Code.BeginsWith("game", waterpath2))
        {
            willSpeed--;
        }
        if (block6.Code.BeginsWith("game", waterpath))
        {
            willSpeed++;
        }
        else if (block6.Code.BeginsWith("game", waterpath2))
        {
            willSpeed--;
        }
        if (willSpeed < 0)
        {
            willSpeed = Math.Abs(willSpeed);
            //SetPropagationDirection(new MechPowerPath(face.Opposite, 1 /*GearedRatio*/, null, true));
            propagationDir = OutFacingForNetworkDiscovery.Opposite;
        }
        else
        {
            //SetPropagationDirection(new MechPowerPath(face.Opposite, 1 /*GearedRatio*/, null, false));
            propagationDir = OutFacingForNetworkDiscovery;
        }
    }