Пример #1
0
        public static void Postfix(Block __instance, ItemSlot slot, EntityAgent byEntity)
        {
            if (byEntity.World.Side.IsClient())
            {
                if (!(slot is DummySlot) && slot is ItemSlotOffhand)
                {
                    return;
                }

                if ((byEntity.World as ClientMain).ElapsedMilliseconds % 4 == 0)
                {
                    var player = (byEntity as EntityPlayer).Player;

                    if (!KnownBroken.Contains(__instance.GetType()) && player?.CurrentBlockSelection != null && slot?.Itemstack != null)
                    {
                        SetBlockRedirect.setBlock = false;

                        var      blockSel = player.CurrentBlockSelection;
                        Block    onBlock  = byEntity.World.BlockAccessor.GetBlock(blockSel.Position);
                        BlockPos buildPos = blockSel.Position;

                        if (onBlock == null || !onBlock.IsReplacableBy(__instance))
                        {
                            buildPos           = buildPos.Offset(blockSel.Face);
                            blockSel.DidOffset = true;
                        }

                        string fail = "";

                        bool works = false;

                        try
                        {
                            works = __instance.TryPlaceBlock(byEntity.World, player, slot.Itemstack, blockSel, ref fail);
                        }
                        catch (Exception)
                        {
                            KnownBroken.Add(__instance.GetType());
                        }

                        if (blockSel.DidOffset)
                        {
                            buildPos.Offset(blockSel.Face.Opposite);
                            blockSel.DidOffset = false;
                        }

                        if (!works)
                        {
                            SetBlockRedirect.blockId = 0;
                        }
                        SetBlockRedirect.setBlock = true;
                    }
                    else
                    {
                        SetBlockRedirect.blockId = 0;
                    }
                }
            }
        }
        public void PlaceBlock()
        {
            MouseOverObject moo = SharpCraft.Instance.MouseOverObject;

            if (moo.hit != HitType.Block)
            {
                return;
            }

            ItemStack stack = GetEquippedItemStack();

            if (!(stack?.Item is ItemBlock itemBlock))
            {
                return;
            }

            Block air   = BlockRegistry.GetBlock <BlockAir>();
            Block glass = BlockRegistry.GetBlock <BlockGlass>();
            Block grass = BlockRegistry.GetBlock <BlockGrass>();
            Block dirt  = BlockRegistry.GetBlock <BlockDirt>();


            BlockState clickedState = World.GetBlockState(moo.blockPos);

            bool replacing;

            BlockPos pos = (replacing = clickedState.Block.IsReplaceable && itemBlock.Block != clickedState.Block) ? moo.blockPos : moo.blockPos.Offset(moo.sideHit);

            Block         heldBlock = itemBlock.Block;
            AxisAlignedBB blockBb   = heldBlock.BoundingBox.offset(pos.ToVec());

            if (!replacing && World.GetBlockState(pos).Block != air || World.GetIntersectingEntitiesBBs(blockBb).Count > 0 && heldBlock.IsSolid)
            {
                return;
            }

            BlockPos posUnder = pos.Offset(FaceSides.Down);

            BlockState stateUnder = World.GetBlockState(posUnder);
            BlockState stateAbove = World.GetBlockState(pos.Offset(FaceSides.Up));

            if (stateUnder.Block == grass && heldBlock != glass && heldBlock.IsSolid)
            {
                World.SetBlockState(posUnder, dirt.GetState());
            }
            if (stateAbove.Block != air && stateAbove.Block != glass && heldBlock == grass && stateAbove.Block.IsSolid)
            {
                World.SetBlockState(pos, dirt.GetState());
            }
            else
            {
                World.SetBlockState(pos, heldBlock.GetState(stack.Meta));
            }

            stack.Count--;

            SharpCraft.Instance.GetMouseOverObject();
        }
        public static IMechanicalPowerDevice getNeighbourDevice(IWorldAccessor world, BlockPos pos, BlockFacing facing, bool connected)
        {
            if (facing == null)
            {
                return(null);
            }

            BlockEntity te = world.BlockAccessor.GetBlockEntity(pos.Offset(facing));

            if (te is IMechanicalPowerDevice)
            {
                IMechanicalPowerDevice mechdevice = (IMechanicalPowerDevice)te;
                if (!mechdevice.exists())
                {
                    return(null);
                }

                if (!connected && mechdevice.hasConnectorAt(facing.GetOpposite()))
                {
                    return(mechdevice);
                }
                if (connected && mechdevice.isConnectedAt(facing.GetOpposite()))
                {
                    return(mechdevice);
                }
            }

            return(null);
        }
Пример #4
0
        public int FindGround(BlockPos pos)
        {
            int seekLimit = 256;
            int y         = 0;

            if (GetBlock(pos).PhysicsMaterial.IsSolid)
            {
                while (GetBlock(pos.Offset(0, y + 1, 0)).PhysicsMaterial.IsSolid)
                {
                    y++;
                }
            }
            else
            {
                while (seekLimit-- > 0 && !GetBlock(pos.Offset(0, y, 0)).PhysicsMaterial.IsSolid)
                {
                    y--;
                }
            }
            return(pos.Y + y);
        }
Пример #5
0
        public int GetHeightAtPos(int x, int z)
        {
            BlockPos pos = new BlockPos(x, 256, z);

            for (int y = ChunkHeight - 1; y >= 0; y--)
            {
                if (!IsAir(pos = pos.Offset(FaceSides.Down)))
                {
                    return(y + 1);
                }
            }

            return(0);
        }
Пример #6
0
        public static BlockPos GetRecommendedPos(this BlockSelection sel)
        {
            BlockPos adjPos = sel.Position.Copy();

            return(adjPos.Offset(sel.Face));
        }
Пример #7
0
        public override void Update()
        {
            _ticksLast = _ticks;

            if (OnGround)
            {
                _ticks = (_ticks + 1) % 90;

                if (_ticksLast > _ticks)
                {
                    _ticksLast = _ticks - 1;
                }
            }

            LastPos = Pos;

            Motion.Y -= 0.04f * Gravity;

            Move();

            Motion.Xz *= 0.8664021f;

            List <AxisAlignedBb> bbs = SharpCraft.Instance.World.GetBlockCollisionBoxes(BoundingBox);

            if (bbs.Count > 0)
            {
                BlockPos bp = new BlockPos(Pos);

                FaceSides lastFace     = FaceSides.Up;
                bool      blocksAround = FaceSides.YPlane.All(face => World.IsAir(bp.Offset(lastFace = face))) &&
                                         World.IsAir(bp.Offset(lastFace = FaceSides.Up)) &&
                                         World.IsAir(bp.Offset(lastFace = FaceSides.Down)); //has to be in this order

                if (!blocksAround)
                {
                    Motion += lastFace.ToVec() * 0.1f;
                }
            }

            if (OnGround)
            {
                Motion.Xz *= 0.6676801f;
            }

            if (++_entityAge >= 20 * 50 * 60 + 10) //stay on ground for a minute, 20 ticks as a pick up delay
            {
                SetDead();
                return;
            }

            if (_entityAge < 5)
            {
                return;
            }

            List <EntityItem> inAttractionArea = World.Entities.OfType <EntityItem>().Where(e => e != this && e.IsAlive && e._stack.ItemSame(_stack)).OrderByDescending(e => e._stack.Count).ToList();
            float             attractionRange  = 1.8F;
            float             mergeRange       = 0.15F;

            foreach (EntityItem entity in inAttractionArea)
            {
                if (_stack.IsEmpty || entity._stack.IsEmpty || entity._stack.Count == entity._stack.Item.GetMaxStackSize())
                {
                    continue;
                }

                Vector3 distanceVector = entity.Pos - Pos;
                float   distance       = distanceVector.Length;
                if (distance >= attractionRange)
                {
                    continue;
                }

                int ammountToTake = Math.Min(_stack.Item.GetMaxStackSize() - _stack.Count, entity._stack.Count);
                if (ammountToTake == 0)
                {
                    continue;
                }

                if (distance <= mergeRange)
                {
                    //Motion -= entity.Motion * MathUtil.Remap(entity.stack.Count / (float)stack.Count, 1, 64, 1, 3);
                    //entity.Motion -= Motion * MathUtil.Remap(stack.Count / (float)entity.stack.Count, 1, 64, 1, 3);

                    entity._stack.Count -= ammountToTake;
                    if (entity._stack.IsEmpty)
                    {
                        entity.SetDead();
                    }
                    _stack.Count += ammountToTake;

                    _entityAge        = 3;
                    entity._entityAge = 1;
                    continue;
                }

                distanceVector.Normalize();

                float distanceMul = (float)Math.Sqrt(1 - distance / attractionRange);
                if (distanceMul > 0.8)
                {
                    distanceMul = ((1 - distanceMul) / 0.2F) * 0.6F + 0.2F;
                }
                Vector3 baseForce = distanceVector * 0.02f * distanceMul * MathUtil.Remap(_stack.Count / (float)entity._stack.Count, 1, entity._stack.Item.GetMaxStackSize(), 2, 5);

                Motion        += baseForce * entity._stack.Count / Math.Max(entity._stack.Count, _stack.Count);
                entity.Motion -= baseForce * _stack.Count / Math.Max(entity._stack.Count, _stack.Count);
            }

            if (_entityAge < 15 || !IsAlive)
            {
                return;
            }

            //TODO change this for multiplayer
            IEnumerable <EntityPlayerSp> players = World.Entities.OfType <EntityPlayerSp>()
                                                   .OrderBy(entity => Vector3.Distance(entity.Pos, Pos))
                                                   .Where(e => Vector3.Distance(e.Pos, Pos) <= attractionRange);

            foreach (EntityPlayerSp player in players)
            {
                if (!player.CanPickUpStack(_stack))
                {
                    continue;
                }

                Vector3 attrTarget = player.Pos;
                attrTarget.Y += player.GetCollisionBoundingBox().Size.Y / 2;

                Vector3 distanceVector = attrTarget - Pos;

                if (distanceVector.Length <= 0.35f)
                {
                    if (player.OnPickup(_stack))
                    {
                        SetDead();
                    }

                    Motion *= -1f;
                }

                Motion = distanceVector.Normalized() * 0.45f;
            }
            if (_stack.IsEmpty)
            {
                SetDead();
            }
        }
Пример #8
0
        public void BuildChunkModelNow()
        {
            if (ModelBuilding || !QueuedForModelBuild)
            {
                return;
            }

            ModelBuilding = true;

            //ConcurrentDictionary<Shader<ModelBlock>, List<RawQuad>> modelRaw = new ConcurrentDictionary<Shader<ModelBlock>, List<RawQuad>>();

            //List<RawQuad> quads;

            Stopwatch sw = Stopwatch.StartNew(); //this is just a debug thing....

            var air = BlockRegistry.GetBlock <BlockAir>();

            var vertexes = new List <float>();
            var normals  = new List <float>();
            var uvs      = new List <float>();

            object locker = new object();

            //generate the model - fill MODEL_RAW
            Enumerable.Range(0, ChunkHeight).AsParallel().ForAll(y =>
            {
                for (int x = 0; x < ChunkSize; x++)
                {
                    for (int z = 0; z < ChunkSize; z++)
                    {
                        BlockPos worldPos = new BlockPos(x + Pos.WorldSpaceX(), y, z + Pos.WorldSpaceZ());

                        BlockState state = World.GetBlockState(worldPos);
                        if (state.Block == air)
                        {
                            continue;
                        }

                        BlockPos localPos = new BlockPos(x, y, z);

                        ModelBlockRaw mbr = (ModelBlockRaw)state.Model?.RawModel;

                        if (mbr == null)
                        {
                            continue;
                        }

                        if (!state.Block.IsFullCube)
                        {
                            lock (locker)
                                mbr.AppendAllVertexData(vertexes, normals, uvs, localPos);

                            continue;
                        }

                        for (var index = 0; index < FaceSides.AllSides.Count; index++)
                        {
                            FaceSides dir = FaceSides.AllSides[index];

                            BlockPos worldPosO = worldPos.Offset(dir);
                            BlockState stateO  = World.GetBlockState(worldPosO);

                            if (!(stateO.Block == air ||
                                  stateO.Block.HasTransparency && !state.Block.HasTransparency) &&
                                stateO.Block.IsFullCube)
                            {
                                continue;
                            }

                            lock (locker)
                            {
                                mbr.AppendVertexDataForSide(dir, vertexes, normals, uvs, localPos);
                                //mbr.AppendNormalsForSide(dir, normals);
                                //mbr.AppendUvsForSide(dir, uvs);
                            }
                        }
                    }
                }
            });

            sw.Stop();
            Console.WriteLine($"DEBUG: built chunk model [{sw.Elapsed.TotalMilliseconds:F}ms]");

            float[] vtx = vertexes.ToArray(); //this is here because this takes time and I don't want it to slow down the main thread by running it in GlContext
            float[] nrm = normals.ToArray();
            float[] uv  = uvs.ToArray();

            SharpCraft.Instance.RunGlContext(() =>
            {
                if (_model == null)
                {
                    _model = new ModelChunk(vtx, nrm, uv, Block.DefaultShader);
                }
                else
                {
                    _model.OverrideData(vtx, nrm, uv);
                }

                ModelBuilding = false;
            });

            QueuedForModelBuild = false;
        }