Beispiel #1
0
        public static void SpawnEffectFor(Player p, string effectName, float x, float y, float z, float originX, float originY, float originZ)
        {
            EffectConfig effect;

            if (!effectAtEffectName.TryGetValue(effectName, out effect))
            {
                p.Message("%WCould not find effect named \"{0}\" !", effectName);
                return;
            }
            if (!p.Supports(CpeExt.CustomParticles))
            {
                return;
            }
            p.Send(Packet.SpawnEffect(effect.ID, x, y - effect.offset, z, originX, originY - effect.offset, originZ));
        }
Beispiel #2
0
        unsafe static void UpdatePosition(Player p)
        {
            Player[] players = PlayerInfo.Online.Items;
            byte *   src     = stackalloc byte[16 * 256]; // 16 = size of absolute update, with extended positions
            byte *   ptr     = src;

            foreach (Player pl in players)
            {
                if (p == pl || p.level != pl.level || !p.CanSeeEntity(pl))
                {
                    continue;
                }

                Orientation rot = pl.Rot; byte pitch = rot.HeadX;
                if (Server.flipHead || p.flipHead)
                {
                    pitch = FlippedPitch(pitch);
                }

                // flip head when infected, but doesn't support model
                if (!p.hasChangeModel)
                {
                    ZSData data = ZSGame.TryGet(p);
                    if (data != null && data.Infected)
                    {
                        pitch = FlippedPitch(pitch);
                    }
                }

                rot.HeadX = pitch;
                Entities.GetPositionPacket(ref ptr, pl.id, pl.hasExtPositions, p.hasExtPositions,
                                           pl.tempPos, pl.lastPos, rot, pl.lastRot);
            }

            int count = (int)(ptr - src);

            if (count == 0)
            {
                return;
            }

            byte[] packet = new byte[count];
            for (int i = 0; i < packet.Length; i++)
            {
                packet[i] = src[i];
            }
            p.Send(packet);
        }
Beispiel #3
0
        static void SendModelScale(Player pl, byte id, EntityProp axis, float value, float max)
        {
            if (value == 0)
            {
                return;
            }
            value = Math.Min(value, max);

            int packed = (int)(value * 1000);

            if (packed == 0)
            {
                return;
            }
            pl.Send(Packet.EntityProperty(id, axis, packed));
        }
Beispiel #4
0
        static void SendDefineBlockExt(Player p, BlockDefinition def, bool uniqueSideTexs)
        {
            byte[] buffer = new byte[uniqueSideTexs ? 88 : 85];
            int    index  = 0;

            buffer[index++] = Opcode.CpeDefineBlockExt;
            MakeDefineBlockStart(def, buffer, ref index, uniqueSideTexs);
            buffer[index++] = def.MinX;
            buffer[index++] = def.MinZ;
            buffer[index++] = def.MinY;
            buffer[index++] = def.MaxX;
            buffer[index++] = def.MaxZ;
            buffer[index++] = def.MaxY;
            MakeDefineBlockEnd(def, ref index, buffer);
            p.Send(buffer);
        }
Beispiel #5
0
        static void SendModel(Player pl, byte id, string model)
        {
            BlockID raw;

            if (BlockID.TryParse(model, out raw) && raw > pl.MaxRawBlock)
            {
                BlockID block = Block.FromRaw(raw);
                if (block >= Block.ExtendedCount)
                {
                    model = "humanoid"; // invalid block ids
                }
                else
                {
                    model = pl.ConvertBlock(block).ToString();
                }
            }
            pl.Send(Packet.ChangeModel(id, model, pl.hasCP437));
        }
        static void UndefineModel(Player p, string name)
        {
            lock (ModelNameToIdForPlayer) {
                bool hasV1 = p.Supports(CpeExt.CustomModels, 1);
                bool hasV2 = p.Supports(CpeExt.CustomModels, 2);
                if (hasV1 || hasV2)
                {
                    var modelId = GetModelId(p, name).Value;
                    Debug("UndefineModel {0} {1} {2}", modelId, p.name, name);

                    byte[] modelPacket = Packet.UndefineModel(modelId);
                    p.Send(modelPacket);

                    var modelNameToId = ModelNameToIdForPlayer[p.name];
                    modelNameToId.TryRemove(name, out _);
                }
            }
        }
Beispiel #7
0
        /// <summary> Adds the given player to that player's tab list (if their client supports it). </summary>
        public static void Add(Player dst, Player p, byte id)
        {
            if (!dst.hasExtList)
            {
                return;
            }
            byte grpPerm = (byte)(offset - p.Rank);

            if (!ServerConfig.TablistRankSorted)
            {
                grpPerm = 0;
            }

            string name, group;

            GetEntry(p, dst, out name, out group);

            name  = Colors.Cleanup(name, dst.hasTextColors);
            group = Colors.Cleanup(group, dst.hasTextColors);
            dst.Send(Packet.ExtAddPlayerName(id, p.truename, name, group, grpPerm, dst.hasCP437));
        }
Beispiel #8
0
        public static void HitPlayer(PlayerBot bot, Player p, Orientation rot)
        {
            // Send player backwards if hit
            // Code "borrowed" from PvP plugin

            int srcHeight = ModelInfo.CalcEyeHeight(bot);
            int dstHeight = ModelInfo.CalcEyeHeight(p);
            int dx2 = bot.Pos.X - p.Pos.X, dy2 = (bot.Pos.Y + srcHeight) - (p.Pos.Y + dstHeight), dz2 = bot.Pos.Z - p.Pos.Z;

            Vec3F32 dir2 = new Vec3F32(dx2, dy2, dz2);

            if (dir2.Length > 0)
            {
                dir2 = Vec3F32.Normalise(dir2);
            }

            float mult    = 1 / ModelInfo.GetRawScale(p.Model);
            float plScale = ModelInfo.GetRawScale(p.Model);

            float VelocityY = 1.0117f * mult;

            if (dir2.Length <= 0)
            {
                VelocityY = 0;
            }

            if (p.Supports(CpeExt.VelocityControl))
            {
                // Intensity of force is in part determined by model scale
                p.Send(Packet.VelocityControl((-dir2.X * mult) * 0.57f, VelocityY, (-dir2.Z * mult) * 0.57f, 0, 1, 0));
            }

            // If we are very close to a player, switch from trying to look
            // at them to just facing the opposite direction to them

            rot.RotY = (byte)(p.Rot.RotY + 128);
            bot.Rot  = rot;
        }
Beispiel #9
0
        static void SpawnRaw(Player dst, byte id, Entity e, Position pos, Orientation rot,
                             string skin, string name, string model)
        {
            // NOTE: Fix for standard clients
            if (id == Entities.SelfID)
            {
                pos.Y -= 22;
            }
            name = Colors.Cleanup(name, dst.hasTextColors);

            if (dst.Supports(CpeExt.ExtPlayerList, 2))
            {
                dst.Send(Packet.ExtAddEntity2(id, skin, name, pos, rot, dst.hasCP437, dst.hasExtPositions));
            }
            else if (dst.hasExtList)
            {
                dst.Send(Packet.ExtAddEntity(id, skin, name, dst.hasCP437));
                dst.Send(Packet.Teleport(id, pos, rot, dst.hasExtPositions));
            }
            else
            {
                dst.Send(Packet.AddEntity(id, name, pos, rot, dst.hasCP437, dst.hasExtPositions));
            }

            if (dst.hasChangeModel)
            {
                OnSendingModelEvent.Call(e, ref model, dst);
                if (!model.CaselessEq("humanoid"))
                {
                    SendModel(dst, id, model);
                }
            }

            if (dst.Supports(CpeExt.EntityProperty))
            {
                dst.Send(Packet.EntityProperty(id, EntityProp.RotX, Orientation.PackedToDegrees(rot.RotX)));
                dst.Send(Packet.EntityProperty(id, EntityProp.RotZ, Orientation.PackedToDegrees(rot.RotZ)));
                SendModelScales(dst, id, e);
            }
        }
Beispiel #10
0
        internal unsafe static void SendLevelInventoryOrder(Player pl)
        {
            BlockDefinition[] defs = pl.level.CustomBlockDefs;

            int  count           = pl.MaxRawBlock + 1;
            int *order_to_blocks = stackalloc int[Block.ExtendedCount];
            int *block_to_orders = stackalloc int[Block.ExtendedCount];

            for (int b = 0; b < Block.ExtendedCount; b++)
            {
                order_to_blocks[b] = -1;
                block_to_orders[b] = -1;
            }

            // Fill slots with explicit order
            for (int i = 0; i < defs.Length; i++)
            {
                BlockDefinition def = defs[i];
                if (def == null || def.RawID > pl.MaxRawBlock)
                {
                    continue;
                }
                if (def.InventoryOrder == -1)
                {
                    continue;
                }

                if (def.InventoryOrder != 0)
                {
                    if (order_to_blocks[def.InventoryOrder] != -1)
                    {
                        continue;
                    }
                    order_to_blocks[def.InventoryOrder] = def.RawID;
                }
                block_to_orders[def.RawID] = def.InventoryOrder;
            }

            // Put blocks into their default slot if slot is unused
            for (int i = 0; i < defs.Length; i++)
            {
                BlockDefinition def = defs[i];
                int             raw = def != null ? def.RawID : i;
                if (raw > pl.MaxRawBlock || (def == null && raw >= Block.CpeCount))
                {
                    continue;
                }

                if (def != null && def.InventoryOrder >= 0)
                {
                    continue;
                }
                if (order_to_blocks[raw] == -1)
                {
                    order_to_blocks[raw] = raw;
                    block_to_orders[raw] = raw;
                }
            }

            // Push blocks whose slots conflict with other blocks into free slots at end
            for (int i = defs.Length - 1; i >= 0; i--)
            {
                BlockDefinition def = defs[i];
                int             raw = def != null ? def.RawID : i;
                if (raw > pl.MaxRawBlock || (def == null && raw >= Block.CpeCount))
                {
                    continue;
                }

                if (block_to_orders[raw] != -1)
                {
                    continue;
                }
                for (int slot = count - 1; slot >= 1; slot--)
                {
                    if (order_to_blocks[slot] != -1)
                    {
                        continue;
                    }

                    block_to_orders[raw]  = slot;
                    order_to_blocks[slot] = raw;
                    break;
                }
            }

            for (int raw = 0; raw < count; raw++)
            {
                int order = block_to_orders[raw];
                if (order == -1)
                {
                    order = 0;
                }

                BlockDefinition def = defs[Block.FromRaw((BlockID)raw)];
                if (def == null && raw >= Block.CpeCount)
                {
                    continue;
                }
                // Special case, don't want 255 getting hidden by default
                if (raw == 255 && def.InventoryOrder == -1)
                {
                    continue;
                }

                pl.Send(Packet.SetInventoryOrder((BlockID)raw, (BlockID)order, pl.hasExtBlocks));
            }
        }