diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/christmas/Christmas.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/christmas/Christmas.java index 3b40cc291..1c2dde63f 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/christmas/Christmas.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/christmas/Christmas.java @@ -3,7 +3,9 @@ package nautilus.game.arcade.game.games.christmas; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; +import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Arrays; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -33,6 +35,8 @@ import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilTime; +import mineplex.core.packethandler.IPacketHandler; +import mineplex.core.packethandler.PacketInfo; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.minecraft.game.core.damage.CustomDamageEvent; @@ -44,7 +48,9 @@ import nautilus.game.arcade.game.SoloGame; import nautilus.game.arcade.game.games.christmas.kits.KitPlayer; import nautilus.game.arcade.game.games.christmas.parts.*; import nautilus.game.arcade.kit.Kit; +import net.minecraft.server.v1_7_R4.PacketPlayOutEntityDestroy; import net.minecraft.server.v1_7_R4.PacketPlayOutNamedSoundEffect; +import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntityLiving; public class Christmas extends SoloGame { @@ -59,6 +65,65 @@ public class Christmas extends SoloGame private long _gameTime = 900000; + private IPacketHandler _reindeerPackets = new IPacketHandler() + { + + @Override + public void handle(PacketInfo packetInfo) + { + if (_sleigh == null) + return; + + if (packetInfo.getPacket() instanceof PacketPlayOutSpawnEntityLiving) + { + PacketPlayOutSpawnEntityLiving spawnPacket = (PacketPlayOutSpawnEntityLiving) packetInfo.getPacket(); + + for (SleighHorse horse : _sleigh.getHorses()) + { + if (horse.horseId == spawnPacket.a) + { + horse.spawnHorns(packetInfo.getPlayer()); + break; + } + } + } + else if (packetInfo.getPacket() instanceof PacketPlayOutEntityDestroy) + { + try + { + PacketPlayOutEntityDestroy destroyPacket = (PacketPlayOutEntityDestroy) packetInfo.getPacket(); + Field f = destroyPacket.getClass().getDeclaredField("a"); + f.setAccessible(true); + int[] entityIds = (int[]) f.get(destroyPacket); + int origLength = entityIds.length; + for (int a = 0; a < entityIds.length; a++) + { + for (SleighHorse horse : _sleigh.getHorses()) + { + if (horse.horseId == a) + { + int p = entityIds.length; + entityIds = Arrays.copyOf(entityIds, entityIds.length + 3); + for (int i = 0; i < 3; i++) + { + entityIds[p + i] = horse.hornsAndNose[i]; + } + break; + } + } + } + if (entityIds.length != origLength) + { + f.set(destroyPacket, entityIds); + } + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + } + }; public Christmas(ArcadeManager manager) { @@ -218,7 +283,10 @@ public class Christmas extends SoloGame public Sleigh GetSleigh() { if (_sleigh == null) - _sleigh = new Sleigh(this, _sleighSpawn); + { + _sleigh = new Sleigh(); + _sleigh.setupSleigh(this, _sleighSpawn); + } return _sleigh; } @@ -237,6 +305,8 @@ public class Christmas extends SoloGame { public void run() { + getArcadeManager().getPacketHandler().addPacketHandler(_reindeerPackets); + GetSleigh(); Location loc = christmas.GetSleigh().GetLocation(); @@ -262,11 +332,18 @@ public class Christmas extends SoloGame @EventHandler public void SleighUpdate(UpdateEvent event) { + if (event.getType() != UpdateType.TICK || _sleigh == null) + return; + + for (SleighHorse horse : _sleigh.getHorses()) + { + horse.onTick(); + } + if (!IsLive()) return; - if (event.getType() == UpdateType.TICK) - GetSleigh().Update(); + GetSleigh().Update(); } @EventHandler @@ -551,6 +628,7 @@ public class Christmas extends SoloGame if (event.GetState() != GameState.End && event.GetState() != GameState.Dead) return; + this.getArcadeManager().getPacketHandler().removePacketHandler(_reindeerPackets); if (_part != null) HandlerList.unregisterAll(_part); } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/christmas/Sleigh.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/christmas/Sleigh.java index 808e797ab..6c3668f67 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/christmas/Sleigh.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/christmas/Sleigh.java @@ -35,7 +35,7 @@ public class Sleigh //This is the central entity, all other sleigh entities have location relative to this. private Entity CentralEntity; private ArrayList SleighEnts; - private ArrayList SleighHorses; + private ArrayList SleighHorses = new ArrayList(); private ArrayList PresentSlots; @@ -43,7 +43,7 @@ public class Sleigh private Location Target; - public Sleigh(Christmas host, Location loc) + public void setupSleigh(Christmas host, Location loc) { Host = host; @@ -126,14 +126,15 @@ public class Sleigh santa.AddSanta(); SleighEnts.add(santa); - SleighHorses = new ArrayList(); - SleighHorses.add(new SleighHorse(loc.clone(), -1.5, 8)); SleighHorses.add(new SleighHorse(loc.clone(), 1.5, 8)); SleighHorses.add(new SleighHorse(loc.clone(), -1.5, 11)); SleighHorses.add(new SleighHorse(loc.clone(), 1.5, 11)); + for (SleighHorse horse : SleighHorses) { + horse.spawnHorse(); + } //for (SleighHorse horse : SleighHorses) // UtilEnt.Leash(horse.Ent, santa.GetTop(), false, false); } @@ -262,4 +263,9 @@ public class Sleigh } } } + + public ArrayList getHorses() + { + return SleighHorses; + } } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/christmas/SleighHorse.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/christmas/SleighHorse.java index adc267bad..e7ccbba89 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/christmas/SleighHorse.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/christmas/SleighHorse.java @@ -1,38 +1,194 @@ package nautilus.game.arcade.game.games.christmas; +import java.util.HashSet; + import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilPlayer; +import net.minecraft.server.v1_7_R4.DataWatcher; +import net.minecraft.server.v1_7_R4.EntityPlayer; +import net.minecraft.server.v1_7_R4.EntityTrackerEntry; +import net.minecraft.server.v1_7_R4.Packet; +import net.minecraft.server.v1_7_R4.PacketPlayOutEntity; +import net.minecraft.server.v1_7_R4.PacketPlayOutEntityEquipment; +import net.minecraft.server.v1_7_R4.PacketPlayOutEntityTeleport; +import net.minecraft.server.v1_7_R4.PacketPlayOutRelEntityMove; +import net.minecraft.server.v1_7_R4.PacketPlayOutRelEntityMoveLook; +import net.minecraft.server.v1_7_R4.PacketPlayOutSpawnEntityLiving; import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.craftbukkit.v1_7_R4.CraftWorld; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_7_R4.inventory.CraftItemStack; import org.bukkit.entity.Horse; +import org.bukkit.entity.Player; import org.bukkit.entity.Horse.Color; import org.bukkit.entity.Horse.Style; import org.bukkit.entity.LivingEntity; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; -public class SleighHorse +public class SleighHorse { - public Horse Ent; - public double OffsetX; - public double OffsetZ; - - public SleighHorse(Location loc, double x, double z) - { - Ent = loc.getWorld().spawn(loc.add(x, 0, z), Horse.class); - - UtilEnt.Vegetate(Ent); - UtilEnt.ghost(Ent, true, false); - - Ent.setStyle(Style.WHITE_DOTS); - Ent.setColor(Color.CHESTNUT); - - OffsetX = x; - OffsetZ = z; - } - - public boolean HasEntity(LivingEntity ent) - { - if (Ent.equals(ent)) - return true; - - return false; - } + public Horse Ent; + public double OffsetX; + public double OffsetZ; + private Location lastFacing; + private Vector _lastMovement = new Vector(); + public int[] hornsAndNose = new int[] + { + UtilEnt.getNewEntityId(), UtilEnt.getNewEntityId() + }; + public int horseId; + private int[] previousDir = new int[4]; + + public SleighHorse(Location loc, double x, double z) + { + OffsetX = x; + OffsetZ = z; + lastFacing = loc.add(x, 0.5, z); + } + + public void spawnHorse() + { + horseId = UtilEnt.getNewEntityId(false); + previousDir = getAngles(lastFacing.getYaw()); + Ent = lastFacing.getWorld().spawn(lastFacing.subtract(0, 0.5, 0), Horse.class); + UtilEnt.Vegetate(Ent); + UtilEnt.ghost(Ent, true, false); + + Ent.setStyle(Style.BLACK_DOTS); + Ent.setColor(Color.BROWN); + } + + public void onTick() + { + EntityTrackerEntry entityTrackerEntry = (EntityTrackerEntry) ((CraftWorld) Ent.getWorld()).getHandle().tracker.trackedEntities + .get(Ent.getEntityId()); + if (entityTrackerEntry != null) + { + Location newLocation = Ent.getLocation().add(0, 0.5, 0); + newLocation.setPitch(lastFacing.getPitch()); + + if (!newLocation.equals(lastFacing)) + { + Packet[] packets1_8 = new Packet[2]; + _lastMovement.add(new Vector(newLocation.getX() - lastFacing.getX(), newLocation.getY() - lastFacing.getY(), + newLocation.getZ() - lastFacing.getZ())); + final int xP = (int) Math.floor(32 * _lastMovement.getX()); + final int yP = (int) Math.floor(32 * _lastMovement.getY()); + final int zP = (int) Math.floor(32 * _lastMovement.getZ()); + _lastMovement.subtract(new Vector(xP / 32D, yP / 32D, zP / 32D)); + lastFacing = newLocation; + int[] angles = getAngles(lastFacing.getYaw()); + boolean tp = false; + for (int i = 0; i < 2; i++) + { + int pX = angles[i * 2] - previousDir[i * 2]; + int pZ = angles[(i * 2) + 1] - previousDir[(i * 2) + 1]; + int x = xP + pX; + int y = yP; + int z = zP + pZ; + if (x >= -128 && x <= 127 && y >= -128 && y <= 127 && z >= -128 && z <= 127) + { + PacketPlayOutEntity relMove = pX != 0 || pZ != 0 ? new PacketPlayOutRelEntityMoveLook() + : new PacketPlayOutRelEntityMove(); + relMove.a = hornsAndNose[i]; + relMove.b = (byte) x; + relMove.c = (byte) y; + relMove.d = (byte) z; + relMove.e = ((byte) (int) (newLocation.getYaw() * 256.0F / 360.0F)); + packets1_8[i] = relMove; + } + else + { + x = (int) Math.floor(32 * newLocation.getX()); + y = (int) Math.floor(32 * newLocation.getY()); + z = (int) Math.floor(32 * newLocation.getZ()); + tp = true; + PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(); + teleportPacket.a = hornsAndNose[i]; + teleportPacket.b = x + pX; + teleportPacket.c = y; + teleportPacket.d = z + pZ; + teleportPacket.e = ((byte) (int) (newLocation.getYaw() * 256.0F / 360.0F)); + packets1_8[i] = teleportPacket; + } + } + if (tp) + { + int x = (int) Math.floor(32 * newLocation.getX()); + int y = (int) Math.floor(32 * newLocation.getY()); + int z = (int) Math.floor(32 * newLocation.getZ()); + _lastMovement = new Vector(newLocation.getX() - (x / 32D), newLocation.getY() - (y / 32D), newLocation.getZ() + - (z / 32D)); + } + previousDir = angles; + HashSet trackedPlayers = (HashSet) entityTrackerEntry.trackedPlayers; + HashSet cloned = (HashSet) trackedPlayers.clone(); + for (EntityPlayer p : cloned) + { + if (!UtilPlayer.is1_8(p.getBukkitEntity())) + continue; + for (Packet packet : packets1_8) + { + p.playerConnection.sendPacket(packet); + } + } + } + } + } + + private int[] getAngles(float yaw) + { + double angle = ((2 * Math.PI) / 360D) * (yaw + 90); + double dist = 0.7; + double angleMod = 0.19; + int pX1 = (int) Math.floor(dist * Math.cos(angle + angleMod) * 32); + int pZ1 = (int) Math.floor(dist * Math.sin(angle + angleMod) * 32); + int pX2 = (int) Math.floor(dist * Math.cos(angle - angleMod) * 32); + int pZ2 = (int) Math.floor(dist * Math.sin(angle - angleMod) * 32); + return new int[] + { + pX1, pZ1, pX2, pZ2 + }; + } + + public void spawnHorns(Player player) + { + if (!UtilPlayer.is1_8(player)) + return; + Location loc = Ent == null ? lastFacing : Ent.getLocation().add(0, 0.5, 0); + for (int i = 0; i < 2; i++) + { + int id = hornsAndNose[i]; + PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving(); + packet.a = id; + packet.b = 30; + packet.c = (int) (loc.getX() * 32) + this.previousDir[i * 2]; + packet.d = (int) (loc.getY() * 32); + packet.e = (int) (loc.getZ() * 32) + this.previousDir[(i * 2) + 1]; + packet.f = ((byte) (int) (loc.getYaw() * 256.0F / 360.0F)); + // Setup datawatcher for armor stand + DataWatcher watcher = new DataWatcher(null); + watcher.a(0, (byte) 32); + watcher.a(10, (byte) 4); + watcher.a(11, new Vector(0, i * 180, (i == 0 ? -1 : 1) * 60f)); + packet.l = watcher; + PacketPlayOutEntityEquipment enquipPacket = new PacketPlayOutEntityEquipment(); + enquipPacket.a = id; + enquipPacket.b = 4; + enquipPacket.c = CraftItemStack.asNMSCopy(new ItemStack(Material.DEAD_BUSH)); + ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); + ((CraftPlayer) player).getHandle().playerConnection.sendPacket(enquipPacket); + } + } + + public boolean HasEntity(LivingEntity ent) + { + if (Ent.equals(ent)) + return true; + + return false; + } }