mirror of
https://github.com/OvercastNetwork/ProjectAres.git
synced 2025-04-11 22:56:08 +02:00
Add legacy CTF support
This commit is contained in:
parent
25353865b4
commit
52c82a81e7
@ -2,10 +2,19 @@ package tc.oc.pgm.flag;
|
|||||||
|
|
||||||
import tc.oc.commons.core.inject.HybridManifest;
|
import tc.oc.commons.core.inject.HybridManifest;
|
||||||
import tc.oc.pgm.map.inject.MapBinders;
|
import tc.oc.pgm.map.inject.MapBinders;
|
||||||
|
import tc.oc.pgm.match.MatchPlayerFacetBinder;
|
||||||
|
import tc.oc.pgm.match.inject.MatchBinders;
|
||||||
|
|
||||||
|
public class FlagManifest extends HybridManifest implements MapBinders, MatchBinders {
|
||||||
|
|
||||||
public class FlagManifest extends HybridManifest implements MapBinders {
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
rootParsers().addBinding().to(FlagParser.class);
|
rootParsers().addBinding().to(FlagParser.class);
|
||||||
|
|
||||||
|
installPlayerModule(binder -> {
|
||||||
|
final MatchPlayerFacetBinder facets = new MatchPlayerFacetBinder(binder);
|
||||||
|
facets.register(LegacyFlagPlayerFacet.class);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
150
PGM/src/main/java/tc/oc/pgm/flag/LegacyFlagPlayerFacet.java
Normal file
150
PGM/src/main/java/tc/oc/pgm/flag/LegacyFlagPlayerFacet.java
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
package tc.oc.pgm.flag;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import tc.oc.commons.bukkit.item.ItemBuilder;
|
||||||
|
import tc.oc.commons.bukkit.util.NMSHacks;
|
||||||
|
import tc.oc.commons.core.stream.Collectors;
|
||||||
|
import tc.oc.pgm.events.ListenerScope;
|
||||||
|
import tc.oc.pgm.flag.event.FlagStateChangeEvent;
|
||||||
|
import tc.oc.pgm.flag.state.Carried;
|
||||||
|
import tc.oc.pgm.flag.state.Spawned;
|
||||||
|
import tc.oc.pgm.match.Match;
|
||||||
|
import tc.oc.pgm.match.MatchPlayerFacet;
|
||||||
|
import tc.oc.pgm.match.MatchScope;
|
||||||
|
import tc.oc.pgm.match.Repeatable;
|
||||||
|
import tc.oc.time.Time;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static java.util.stream.IntStream.range;
|
||||||
|
import static tc.oc.minecraft.protocol.MinecraftVersion.*;
|
||||||
|
|
||||||
|
@ListenerScope(MatchScope.LOADED)
|
||||||
|
public class LegacyFlagPlayerFacet implements MatchPlayerFacet, Listener {
|
||||||
|
|
||||||
|
private final Match match;
|
||||||
|
private final Player bukkit;
|
||||||
|
private final Map<Flag, Beam> beams;
|
||||||
|
|
||||||
|
@Inject LegacyFlagPlayerFacet(Match match, Player bukkit) {
|
||||||
|
this.match = match;
|
||||||
|
this.bukkit = bukkit;
|
||||||
|
this.beams = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Stream<Flag> flags() {
|
||||||
|
return (Stream<Flag>) match.features().all(Flag.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void trackFlag(Flag flag) {
|
||||||
|
if(lessThan(MINECRAFT_1_8, bukkit.getProtocolVersion())) {
|
||||||
|
beams.put(flag, beams.getOrDefault(flag, new Beam(flag)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void untrackFlag(Flag flag) {
|
||||||
|
if(beams.containsKey(flag)) {
|
||||||
|
beams.remove(flag).hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enable() {
|
||||||
|
flags().filter(flag -> flag.state() instanceof Spawned)
|
||||||
|
.forEach(this::trackFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disable() {
|
||||||
|
flags().forEach(this::untrackFlag);
|
||||||
|
beams.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||||
|
public void onFlagStateChange(FlagStateChangeEvent event) {
|
||||||
|
Flag flag = event.getFlag();
|
||||||
|
untrackFlag(flag);
|
||||||
|
if(event.getNewState() instanceof Spawned) {
|
||||||
|
trackFlag(flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Repeatable(interval = @Time(seconds = 1))
|
||||||
|
public void onSecond() {
|
||||||
|
ImmutableList.copyOf(beams.values()).forEach(Beam::update);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Beam {
|
||||||
|
|
||||||
|
final Flag flag;
|
||||||
|
final List<NMSHacks.FakeZombie> segments;
|
||||||
|
|
||||||
|
Beam(Flag flag) {
|
||||||
|
this.flag = flag;
|
||||||
|
this.segments = range(0, 32).mapToObj(i -> new NMSHacks.FakeZombie(match.getWorld(), true, true))
|
||||||
|
.collect(Collectors.toImmutableList());
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<Player> carrier() {
|
||||||
|
return Optional.ofNullable(flag.state() instanceof Carried ? ((Carried) flag.state()).getCarrier().getBukkit() : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Location location() {
|
||||||
|
Location location = flag.getLocation().get().clone();
|
||||||
|
location.setPitch(0);
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack wool() {
|
||||||
|
return new ItemBuilder().material(Material.WOOL)
|
||||||
|
.enchant(Enchantment.DURABILITY, 1)
|
||||||
|
.color(flag.getDyeColor())
|
||||||
|
.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void show() {
|
||||||
|
if(carrier().map(carrier -> carrier.equals(bukkit)).orElse(false)) return;
|
||||||
|
segments.forEach(segment -> {
|
||||||
|
segment.spawn(bukkit, location());
|
||||||
|
segment.wear(bukkit, EquipmentSlot.HEAD, wool());
|
||||||
|
});
|
||||||
|
range(1, segments.size()).forEachOrdered(i -> {
|
||||||
|
segments.get(i - 1).ride(bukkit, segments.get(i).entity());
|
||||||
|
});
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void update() {
|
||||||
|
Optional<Player> carrier = carrier();
|
||||||
|
NMSHacks.FakeZombie base = segments.get(0);
|
||||||
|
if(carrier.isPresent()) {
|
||||||
|
base.mount(bukkit, carrier.get());
|
||||||
|
} else {
|
||||||
|
base.teleport(bukkit, location());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hide() {
|
||||||
|
for(int i = segments.size() - 1; i >= 0; i--) {
|
||||||
|
segments.get(i).destroy(bukkit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -61,6 +61,10 @@ public class Carried extends Spawned implements Missing {
|
|||||||
this.dropLocations.add(dropLocation); // Need an initial dropLocation in case the carrier never generates ones
|
this.dropLocations.add(dropLocation); // Need an initial dropLocation in case the carrier never generates ones
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MatchPlayer getCarrier() {
|
||||||
|
return carrier;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRecoverable() {
|
public boolean isRecoverable() {
|
||||||
return true;
|
return true;
|
||||||
@ -191,7 +195,7 @@ public class Carried extends Spawned implements Missing {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean canSeeParticles(Player player) {
|
protected boolean canSeeParticles(Player player) {
|
||||||
return player != this.carrier.getBukkit();
|
return super.canSeeParticles(player) && player != this.carrier.getBukkit();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void dropFlag() {
|
protected void dropFlag() {
|
||||||
|
@ -5,6 +5,7 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
import tc.oc.commons.bukkit.util.NMSHacks;
|
import tc.oc.commons.bukkit.util.NMSHacks;
|
||||||
|
import tc.oc.minecraft.protocol.MinecraftVersion;
|
||||||
import tc.oc.pgm.flag.Flag;
|
import tc.oc.pgm.flag.Flag;
|
||||||
import tc.oc.pgm.flag.Post;
|
import tc.oc.pgm.flag.Post;
|
||||||
import tc.oc.pgm.flag.event.FlagCaptureEvent;
|
import tc.oc.pgm.flag.event.FlagCaptureEvent;
|
||||||
@ -67,7 +68,7 @@ public abstract class Spawned extends BaseState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected boolean canSeeParticles(Player player) {
|
protected boolean canSeeParticles(Player player) {
|
||||||
return true;
|
return MinecraftVersion.atLeast(MinecraftVersion.MINECRAFT_1_8, player.getProtocolVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -203,7 +203,22 @@ public interface Match extends Audience, IMatchQuery, Filterable<IMatchQuery>, M
|
|||||||
* @see #registerEvents
|
* @see #registerEvents
|
||||||
* @see #registerRepeatable
|
* @see #registerRepeatable
|
||||||
*/
|
*/
|
||||||
void registerEventsAndRepeatables(Object thing);
|
default void registerEventsAndRepeatables(Object thing) {
|
||||||
|
registerRepeatable(thing);
|
||||||
|
if(thing instanceof Listener) registerEvents((Listener) thing);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregister {@link Repeatable} methods on the given object, and also
|
||||||
|
* unregister it for events if it is a {@link Listener}.
|
||||||
|
*
|
||||||
|
* @see #unregisterEvents
|
||||||
|
* @see #unregisterRepeatable
|
||||||
|
*/
|
||||||
|
default void unregisterEventsAndRepeatables(Object thing) {
|
||||||
|
unregisterRepeatable(thing);
|
||||||
|
if(thing instanceof Listener) unregisterEvents((Listener) thing);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the {@link MapModuleContext} that was used to load this match.
|
* Return the {@link MapModuleContext} that was used to load this match.
|
||||||
|
@ -352,14 +352,6 @@ public class MatchImpl implements Match, ForwardingAudience {
|
|||||||
runningScheduler.unregisterRepeatables(object);
|
runningScheduler.unregisterRepeatables(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void registerEventsAndRepeatables(Object thing) {
|
|
||||||
registerRepeatable(thing);
|
|
||||||
if(thing instanceof Listener) {
|
|
||||||
registerEvents((Listener) thing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// ---- Modules/Features/Contexts ----
|
// ---- Modules/Features/Contexts ----
|
||||||
|
@ -7,6 +7,7 @@ import com.google.inject.AbstractModule;
|
|||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.PlayerInventory;
|
import org.bukkit.inventory.PlayerInventory;
|
||||||
|
import tc.oc.minecraft.protocol.MinecraftVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Binds various services provided through a {@link Player} (but does not bind {@link Player} itself)
|
* Binds various services provided through a {@link Player} (but does not bind {@link Player} itself)
|
||||||
@ -26,4 +27,8 @@ public class BukkitPlayerModule extends AbstractModule {
|
|||||||
@Provides UUID uuid(Player player) {
|
@Provides UUID uuid(Player player) {
|
||||||
return player.getUniqueId();
|
return player.getUniqueId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides MinecraftVersion version(Player player) {
|
||||||
|
return MinecraftVersion.byProtocol(player.getProtocolVersion());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import net.minecraft.server.DataWatcher;
|
|||||||
import net.minecraft.server.Enchantment;
|
import net.minecraft.server.Enchantment;
|
||||||
import net.minecraft.server.EntityArmorStand;
|
import net.minecraft.server.EntityArmorStand;
|
||||||
import net.minecraft.server.EntityChicken;
|
import net.minecraft.server.EntityChicken;
|
||||||
|
import net.minecraft.server.EntityFallingBlock;
|
||||||
import net.minecraft.server.EntityFireworks;
|
import net.minecraft.server.EntityFireworks;
|
||||||
import net.minecraft.server.EntityItem;
|
import net.minecraft.server.EntityItem;
|
||||||
import net.minecraft.server.EntityLiving;
|
import net.minecraft.server.EntityLiving;
|
||||||
@ -90,10 +91,10 @@ import org.bukkit.craftbukkit.util.Skins;
|
|||||||
import org.bukkit.entity.ArmorStand;
|
import org.bukkit.entity.ArmorStand;
|
||||||
import org.bukkit.entity.Egg;
|
import org.bukkit.entity.Egg;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.FallingBlock;
|
||||||
import org.bukkit.entity.Firework;
|
import org.bukkit.entity.Firework;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.entity.TNTPrimed;
|
import org.bukkit.entity.TNTPrimed;
|
||||||
import org.bukkit.entity.Wither;
|
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.material.MaterialData;
|
import org.bukkit.material.MaterialData;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
@ -102,6 +103,9 @@ import org.bukkit.potion.PotionEffectTypeWrapper;
|
|||||||
import org.bukkit.registry.Key;
|
import org.bukkit.registry.Key;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import tc.oc.commons.core.util.TimeUtils;
|
import tc.oc.commons.core.util.TimeUtils;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
@ -114,7 +118,8 @@ public class NMSHacks {
|
|||||||
// There is no nice way to get at them.
|
// There is no nice way to get at them.
|
||||||
private static final Map<Class<? extends Entity>, Integer> ENTITY_TYPE_IDS = ImmutableMap.of(
|
private static final Map<Class<? extends Entity>, Integer> ENTITY_TYPE_IDS = ImmutableMap.of(
|
||||||
org.bukkit.entity.Item.class, 2,
|
org.bukkit.entity.Item.class, 2,
|
||||||
ArmorStand.class, 78
|
ArmorStand.class, 78,
|
||||||
|
FallingBlock.class, 70
|
||||||
);
|
);
|
||||||
|
|
||||||
private static EntityTrackerEntry getTrackerEntry(net.minecraft.server.Entity nms) {
|
private static EntityTrackerEntry getTrackerEntry(net.minecraft.server.Entity nms) {
|
||||||
@ -272,8 +277,12 @@ public class NMSHacks {
|
|||||||
metadata);
|
metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Packet setPassengerPacket(int vehicleId, IntStream riderIds) {
|
||||||
|
return new PacketPlayOutMount(vehicleId, riderIds.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
public static Packet setPassengerPacket(int vehicleId, int riderId) {
|
public static Packet setPassengerPacket(int vehicleId, int riderId) {
|
||||||
return new PacketPlayOutMount(vehicleId, riderId);
|
return setPassengerPacket(vehicleId, IntStream.of(riderId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Packet moveEntityRelativePacket(int entityId, Vector delta, boolean onGround) {
|
public static Packet moveEntityRelativePacket(int entityId, Vector delta, boolean onGround) {
|
||||||
@ -292,6 +301,10 @@ public class NMSHacks {
|
|||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Packet entityVelocityPacket(int entityId, Vector velocity) {
|
||||||
|
return new PacketPlayOutEntityVelocity(entityId, velocity.getX(), velocity.getY(), velocity.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
private static Packet entityMetadataPacket(int entityId, net.minecraft.server.Entity nmsEntity, boolean complete) {
|
private static Packet entityMetadataPacket(int entityId, net.minecraft.server.Entity nmsEntity, boolean complete) {
|
||||||
return new PacketPlayOutEntityMetadata(entityId, nmsEntity.getDataWatcher(), complete);
|
return new PacketPlayOutEntityMetadata(entityId, nmsEntity.getDataWatcher(), complete);
|
||||||
}
|
}
|
||||||
@ -304,8 +317,12 @@ public class NMSHacks {
|
|||||||
return entityMetadataPacket(nmsEntity.getId(), nmsEntity, complete);
|
return entityMetadataPacket(nmsEntity.getId(), nmsEntity, complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Packet entityEquipmentPacket(int entityId, EquipmentSlot slot, org.bukkit.inventory.ItemStack armor) {
|
||||||
|
return new PacketPlayOutEntityEquipment(entityId, EnumItemSlot.values()[slot.ordinal()], CraftItemStack.asNMSCopy(armor));
|
||||||
|
}
|
||||||
|
|
||||||
public static Packet entityHelmetPacket(int entityId, org.bukkit.inventory.ItemStack helmet) {
|
public static Packet entityHelmetPacket(int entityId, org.bukkit.inventory.ItemStack helmet) {
|
||||||
return new PacketPlayOutEntityEquipment(entityId, EnumItemSlot.HEAD, CraftItemStack.asNMSCopy(helmet));
|
return entityEquipmentPacket(entityId, EquipmentSlot.HEAD, helmet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -318,6 +335,8 @@ public class NMSHacks {
|
|||||||
public interface FakeEntity {
|
public interface FakeEntity {
|
||||||
int entityId();
|
int entityId();
|
||||||
|
|
||||||
|
Entity entity();
|
||||||
|
|
||||||
void spawn(Player viewer, Location location, Vector velocity);
|
void spawn(Player viewer, Location location, Vector velocity);
|
||||||
|
|
||||||
default void spawn(Player viewer, Location location) {
|
default void spawn(Player viewer, Location location) {
|
||||||
@ -336,8 +355,20 @@ public class NMSHacks {
|
|||||||
sendPacket(viewer, teleportEntityPacket(entityId(), location));
|
sendPacket(viewer, teleportEntityPacket(entityId(), location));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default void ride(Player viewer, Stream<Entity> riders) {
|
||||||
|
sendPacket(viewer, setPassengerPacket(entityId(), riders.mapToInt(Entity::getEntityId)));
|
||||||
|
}
|
||||||
|
|
||||||
default void ride(Player viewer, Entity rider) {
|
default void ride(Player viewer, Entity rider) {
|
||||||
sendPacket(viewer, setPassengerPacket(entityId(), rider.getEntityId()));
|
ride(viewer, Stream.of(rider));
|
||||||
|
}
|
||||||
|
|
||||||
|
default void mount(Player viewer, Entity vehicle) {
|
||||||
|
sendPacket(viewer, setPassengerPacket(vehicle.getEntityId(), entityId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
default void wear(Player viewer, EquipmentSlot slot, org.bukkit.inventory.ItemStack item) {
|
||||||
|
sendPacket(viewer, entityEquipmentPacket(entityId(), slot, item));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,6 +379,11 @@ public class NMSHacks {
|
|||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity entity() {
|
||||||
|
return entity.getBukkitEntity();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int entityId() {
|
public int entityId() {
|
||||||
return entity.getId();
|
return entity.getId();
|
||||||
@ -385,6 +421,26 @@ public class NMSHacks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class FakeFallingBlock extends FakeEntityImpl<EntityFallingBlock> {
|
||||||
|
|
||||||
|
private final MaterialData data;
|
||||||
|
|
||||||
|
public FakeFallingBlock(World world, @Nullable MaterialData data) {
|
||||||
|
super(new EntityFallingBlock(((CraftWorld) world).getHandle()));
|
||||||
|
this.data = data != null ? data : new MaterialData(Material.SAND);
|
||||||
|
entity.setNoGravity(true);
|
||||||
|
entity.formBlock = false;
|
||||||
|
entity.dropItem = false;
|
||||||
|
entity.ticksLived = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void spawn(Player viewer, Location location, Vector velocity) {
|
||||||
|
sendPacket(viewer, spawnEntityPacket(FallingBlock.class, data.getItemTypeId() + (data.getData() << 12), entityId(), entity.getUniqueID(), location, velocity));
|
||||||
|
sendPacket(viewer, entityMetadataPacket(entity, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class FakeLivingEntity<T extends EntityLiving> extends FakeEntityImpl<T> {
|
private static class FakeLivingEntity<T extends EntityLiving> extends FakeEntityImpl<T> {
|
||||||
|
|
||||||
protected FakeLivingEntity(T entity) {
|
protected FakeLivingEntity(T entity) {
|
||||||
@ -440,12 +496,22 @@ public class NMSHacks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class FakeZombie extends FakeLivingEntity<EntityZombie> {
|
public static class FakeZombie extends FakeLivingEntity<EntityZombie> {
|
||||||
|
|
||||||
public FakeZombie(World world, boolean invisible) {
|
public FakeZombie(World world, boolean invisible) {
|
||||||
|
this(world, invisible, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FakeZombie(World world, boolean invisible, boolean baby) {
|
||||||
super(new EntityZombie(((CraftWorld) world).getHandle()));
|
super(new EntityZombie(((CraftWorld) world).getHandle()));
|
||||||
|
|
||||||
entity.setInvisible(invisible);
|
entity.setInvisible(invisible);
|
||||||
entity.setNoAI(false);
|
entity.setBaby(baby);
|
||||||
|
entity.setNoAI(true);
|
||||||
|
entity.setNoGravity(true);
|
||||||
|
entity.setInvulnerable(true);
|
||||||
|
entity.setSilent(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FakeChicken extends FakeLivingEntity<EntityChicken> {
|
public static class FakeChicken extends FakeLivingEntity<EntityChicken> {
|
||||||
@ -494,6 +560,11 @@ public class NMSHacks {
|
|||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity entity() {
|
||||||
|
return prototype().getBukkitEntity();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int entityId() {
|
public int entityId() {
|
||||||
return entityId;
|
return entityId;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user