public static void AppendFace(TextureType side, float[] from, float[] to, Vector3 rotation, Vector3 rotationOrigin,
                                      ref float[] vertexes, ref float[] normals, int startIndex)
        {
            FaceSides faceSide = FaceSides.Parse(side); //TextureType parsed to FaceSides, also a normal of this face
            Vector3   normal   = faceSide.ToVec();

            float[] unitFace = _cube[faceSide]; //one side of the cube in unit size

            float x = from[0] / 16f;
            float y = from[1] / 16f;
            float z = from[2] / 16f;

            float sx = to[0] / 16f - x; //the size of the cube part
            float sy = to[1] / 16f - y;
            float sz = to[2] / 16f - z;

            for (var i = 0; i < unitFace.Length; i += 3)
            {
                var vertex = RotateVertex(new Vector3(
                                              x + unitFace[i] * sx,
                                              y + unitFace[i + 1] * sy,
                                              z + unitFace[i + 2] * sz), rotation, rotationOrigin);

                vertexes[startIndex + i]     = vertex.X;
                vertexes[startIndex + i + 1] = vertex.Y;
                vertexes[startIndex + i + 2] = vertex.Z;

                var nrm = RotateVertex(normal, rotation, rotationOrigin);

                normals[startIndex + i]     = nrm.X;
                normals[startIndex + i + 1] = nrm.Y;
                normals[startIndex + i + 2] = nrm.Z;
            }
        }
Example #2
0
        public static void AppendFace(Facing side, float[] from, float[] to, Vector3 rotation, Vector3 rotationOrigin,
                                      ref List <float> vertexes, ref List <float> normals)
        {
            FaceSides faceSide = FaceSides.Parse(side); //TextureType parsed to FaceSides, also a normal of this face
            Vector3   normal   = faceSide.ToVec();

            float[] unitFace = _cubeTriangles[faceSide]; //one side of the cube in unit size

            float x = from[0] / 16f;
            float y = from[1] / 16f;
            float z = from[2] / 16f;

            float sx = to[0] / 16f - x; //the size of the cube part
            float sy = to[1] / 16f - y;
            float sz = to[2] / 16f - z;

            for (var i = 0; i < unitFace.Length; i += 3)
            {
                var vertex = RotateVertex(new Vector3(
                                              x + unitFace[i] * sx,
                                              y + unitFace[i + 1] * sy,
                                              z + unitFace[i + 2] * sz), rotation, rotationOrigin);

                vertexes.Add(vertex.X);
                vertexes.Add(vertex.Y);
                vertexes.Add(vertex.Z);

                var nrm = RotateVertex(normal, rotation, rotationOrigin);

                normals.Add(nrm.X);
                normals.Add(nrm.Y);
                normals.Add(nrm.Z);
            }
        }
Example #3
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();
            }
        }