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.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
|
||||
protected void configure() {
|
||||
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
|
||||
}
|
||||
|
||||
public MatchPlayer getCarrier() {
|
||||
return carrier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRecoverable() {
|
||||
return true;
|
||||
@ -191,7 +195,7 @@ public class Carried extends Spawned implements Missing {
|
||||
|
||||
@Override
|
||||
protected boolean canSeeParticles(Player player) {
|
||||
return player != this.carrier.getBukkit();
|
||||
return super.canSeeParticles(player) && player != this.carrier.getBukkit();
|
||||
}
|
||||
|
||||
protected void dropFlag() {
|
||||
|
@ -5,6 +5,7 @@ import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
import tc.oc.commons.bukkit.util.NMSHacks;
|
||||
import tc.oc.minecraft.protocol.MinecraftVersion;
|
||||
import tc.oc.pgm.flag.Flag;
|
||||
import tc.oc.pgm.flag.Post;
|
||||
import tc.oc.pgm.flag.event.FlagCaptureEvent;
|
||||
@ -67,7 +68,7 @@ public abstract class Spawned extends BaseState {
|
||||
}
|
||||
|
||||
protected boolean canSeeParticles(Player player) {
|
||||
return true;
|
||||
return MinecraftVersion.atLeast(MinecraftVersion.MINECRAFT_1_8, player.getProtocolVersion());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -203,7 +203,22 @@ public interface Match extends Audience, IMatchQuery, Filterable<IMatchQuery>, M
|
||||
* @see #registerEvents
|
||||
* @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.
|
||||
|
@ -352,14 +352,6 @@ public class MatchImpl implements Match, ForwardingAudience {
|
||||
runningScheduler.unregisterRepeatables(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEventsAndRepeatables(Object thing) {
|
||||
registerRepeatable(thing);
|
||||
if(thing instanceof Listener) {
|
||||
registerEvents((Listener) thing);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------
|
||||
// ---- Modules/Features/Contexts ----
|
||||
|
@ -7,6 +7,7 @@ import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import org.bukkit.entity.Player;
|
||||
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)
|
||||
@ -26,4 +27,8 @@ public class BukkitPlayerModule extends AbstractModule {
|
||||
@Provides UUID uuid(Player player) {
|
||||
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.EntityArmorStand;
|
||||
import net.minecraft.server.EntityChicken;
|
||||
import net.minecraft.server.EntityFallingBlock;
|
||||
import net.minecraft.server.EntityFireworks;
|
||||
import net.minecraft.server.EntityItem;
|
||||
import net.minecraft.server.EntityLiving;
|
||||
@ -90,10 +91,10 @@ import org.bukkit.craftbukkit.util.Skins;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Egg;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.Firework;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.entity.Wither;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.material.MaterialData;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
@ -102,6 +103,9 @@ import org.bukkit.potion.PotionEffectTypeWrapper;
|
||||
import org.bukkit.registry.Key;
|
||||
import org.bukkit.util.Vector;
|
||||
import java.time.Duration;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import tc.oc.commons.core.util.TimeUtils;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
@ -114,7 +118,8 @@ public class NMSHacks {
|
||||
// There is no nice way to get at them.
|
||||
private static final Map<Class<? extends Entity>, Integer> ENTITY_TYPE_IDS = ImmutableMap.of(
|
||||
org.bukkit.entity.Item.class, 2,
|
||||
ArmorStand.class, 78
|
||||
ArmorStand.class, 78,
|
||||
FallingBlock.class, 70
|
||||
);
|
||||
|
||||
private static EntityTrackerEntry getTrackerEntry(net.minecraft.server.Entity nms) {
|
||||
@ -272,8 +277,12 @@ public class NMSHacks {
|
||||
metadata);
|
||||
}
|
||||
|
||||
public static Packet setPassengerPacket(int vehicleId, IntStream riderIds) {
|
||||
return new PacketPlayOutMount(vehicleId, riderIds.toArray());
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -292,6 +301,10 @@ public class NMSHacks {
|
||||
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) {
|
||||
return new PacketPlayOutEntityMetadata(entityId, nmsEntity.getDataWatcher(), complete);
|
||||
}
|
||||
@ -304,8 +317,12 @@ public class NMSHacks {
|
||||
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) {
|
||||
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 {
|
||||
int entityId();
|
||||
|
||||
Entity entity();
|
||||
|
||||
void spawn(Player viewer, Location location, Vector velocity);
|
||||
|
||||
default void spawn(Player viewer, Location location) {
|
||||
@ -336,8 +355,20 @@ public class NMSHacks {
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity entity() {
|
||||
return entity.getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int entityId() {
|
||||
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> {
|
||||
|
||||
protected FakeLivingEntity(T entity) {
|
||||
@ -440,12 +496,22 @@ public class NMSHacks {
|
||||
}
|
||||
|
||||
public static class FakeZombie extends FakeLivingEntity<EntityZombie> {
|
||||
|
||||
public FakeZombie(World world, boolean invisible) {
|
||||
this(world, invisible, false);
|
||||
}
|
||||
|
||||
public FakeZombie(World world, boolean invisible, boolean baby) {
|
||||
super(new EntityZombie(((CraftWorld) world).getHandle()));
|
||||
|
||||
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> {
|
||||
@ -494,6 +560,11 @@ public class NMSHacks {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity entity() {
|
||||
return prototype().getBukkitEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int entityId() {
|
||||
return entityId;
|
||||
|
Loading…
x
Reference in New Issue
Block a user