Skip to content

Commit

Permalink
Add minecart visual, change curved rail behavior
Browse files Browse the repository at this point in the history
Signed-off-by: Pablete1234 <[email protected]>
  • Loading branch information
Pablete1234 committed Sep 24, 2022
1 parent 9cefcb6 commit eb25595
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,28 @@
import tc.oc.pgm.api.match.Match;
import tc.oc.pgm.api.match.MatchModule;
import tc.oc.pgm.api.match.MatchScope;
import tc.oc.pgm.payload.PayloadListener;

public class ControlPointMatchModule implements MatchModule {

private final Match match;
private final List<ControlPoint> controlPoints = new ArrayList<>();
private final ControlPointAnnouncer announcer;
private final PayloadListener payloadListener;

public ControlPointMatchModule(Match match, List<ControlPoint> points) {
this.match = match;
this.controlPoints.addAll(points);

this.announcer = new ControlPointAnnouncer(this.match);
this.payloadListener = new PayloadListener();
match.addTickable(new ControlPointTickTask(this.controlPoints), MatchScope.RUNNING);
}

@Override
public void load() {
this.match.addListener(this.announcer, MatchScope.RUNNING);
this.match.addListener(this.payloadListener, MatchScope.RUNNING);
for (ControlPoint controlPoint : this.controlPoints) {
controlPoint.registerEvents();
}
Expand All @@ -35,5 +39,6 @@ public void unload() {
controlPoint.unregisterEvents();
}
HandlerList.unregisterAll(this.announcer);
HandlerList.unregisterAll(this.payloadListener);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
/** Tracks which players are on a control point and answers some queries about them */
public class RegionPlayerTracker implements Listener {
private final Match match;
private final Set<MatchPlayer> playersOnPoint = Sets.newHashSet();
private final Set<MatchPlayer> players = Sets.newHashSet();

private Region region;

Expand All @@ -28,7 +28,7 @@ public RegionPlayerTracker(Match match, Region region) {
}

public Set<MatchPlayer> getPlayers() {
return this.playersOnPoint;
return this.players;
}

public void setRegion(Region region) {
Expand All @@ -53,14 +53,14 @@ public void handlePlayerMove(Player bukkit, Vector to) {
if (!MatchPlayers.canInteract(player)) return;

if (!player.getBukkit().isDead() && this.region.contains(to.toBlockVector())) {
this.playersOnPoint.add(player);
this.players.add(player);
} else {
this.playersOnPoint.remove(player);
this.players.remove(player);
}
}

@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerDespawn(final ParticipantDespawnEvent event) {
playersOnPoint.remove(event.getPlayer());
players.remove(event.getPlayer());
}
}
109 changes: 79 additions & 30 deletions core/src/main/java/tc/oc/pgm/payload/Payload.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,39 @@
package tc.oc.pgm.payload;

import java.time.Duration;
import org.bukkit.ChatColor;
import org.bukkit.Color;
import org.bukkit.DyeColor;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Minecart;
import org.bukkit.material.Wool;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.Vector;
import tc.oc.pgm.api.PGM;
import tc.oc.pgm.api.match.Match;
import tc.oc.pgm.api.party.Competitor;
import tc.oc.pgm.api.region.Region;
import tc.oc.pgm.controlpoint.ControlPoint;
import tc.oc.pgm.payload.track.Track;
import tc.oc.pgm.util.bukkit.BukkitUtils;

public class Payload extends ControlPoint {

private static final int PARTICLE_AMOUNT = 6; // 6 particles
private static final int PARTICLE_ROTATION = 20; // ticks per full rotation

private static final String METADATA_KEY = "payload";

private static final Vector MINECART_OFFSET = new Vector(0, 0.0625, 0);
private static final double MAX_OFFSET_SQ = Math.pow(0.25, 2); // Max offset of 0.25

private final Match match;
private final PayloadDefinition definition;

private final Track track;
private final Minecart minecart;
private final PayloadRegion captureRegion;

private Competitor dominantTeam;
Expand All @@ -30,12 +44,25 @@ public Payload(Match match, PayloadDefinition definition) {
this.match = match;
this.definition = definition;

this.track = new Track(match, definition.getLocation());
this.position = definition.getLocation();

this.track = new Track(match, definition.getLocation());
this.minecart = spawnMinecart();
this.captureRegion = new PayloadRegion(this::getCenterPoint, definition.getRadius());

this.playerTracker.setRegion(captureRegion);
}

private Minecart spawnMinecart() {
Minecart minecart =
match.getWorld().spawn(position.toLocation(match.getWorld()), Minecart.class);

minecart.setDisplayBlock(new Wool(DyeColor.WHITE));
minecart.setSlowWhenEmpty(true);
minecart.setMetadata(METADATA_KEY, new FixedMetadataValue(PGM.get(), true));
return minecart;
}

@Override
public Region getCaptureRegion() {
return captureRegion;
Expand All @@ -58,23 +85,23 @@ public void tick(Duration duration) {
if (!oldPos.toBlockVector().equals(position.toBlockVector()))
playerTracker.setRegion(captureRegion);

tickDisplay(match.getTick().tick);
tickParticles(match.getTick().tick);
tickMinecart();
}

private void tickDisplay(long tick) {
if (!definition.getDisplayFilter().query(match).isAllowed()) return;
Color color =
dominantTeam != null
? dominantTeam.getFullColor()
: controllingTeam != null ? controllingTeam.getFullColor() : Color.WHITE;
private Competitor getDisplayTeam() {
return dominantTeam != null ? dominantTeam : controllingTeam != null ? controllingTeam : null;
}

Location loc = position.toLocation(match.getWorld()).add(0, 0.5, 0);
spawnParticle(loc, color);
private void tickParticles(long tick) {
if (!definition.getDisplayFilter().query(match).isAllowed()) return;
Competitor display = getDisplayTeam();
Color color = display != null ? display.getFullColor() : Color.WHITE;

double diff = Math.PI * 2 / PARTICLE_AMOUNT;
double offset = (double) tick * diff / PARTICLE_ROTATION;

// Each iteration of this loop is one particle
Location loc = new Location(match.getWorld(), 0, 0, 0);
for (int i = 0; i < PARTICLE_AMOUNT; i++) {
double angle = i * diff + offset;
// Height between 0.2 and 0.8
Expand All @@ -85,34 +112,56 @@ private void tickDisplay(long tick) {
height,
definition.getRadius() * Math.sin(angle));
loc.add(position);
spawnParticle(loc, color);
match
.getWorld()
.spigot()
.playEffect(
loc,
Effect.COLOURED_DUST,
0,
(byte) 0,
rgbToParticle(color.getRed()),
rgbToParticle(color.getGreen()),
rgbToParticle(color.getBlue()),
1,
0,
50);
}
}

private void spawnParticle(Location loc, Color color) {
match
.getWorld()
.spigot()
.playEffect(
loc,
Effect.COLOURED_DUST,
0,
(byte) 0,
rgbToParticle(color.getRed()),
rgbToParticle(color.getGreen()),
rgbToParticle(color.getBlue()),
1,
0,
200);
}

private float rgbToParticle(int rgb) {
return (float) Math.max(0.001, rgb / 255.0);
}

private void tickMinecart() {
Vector current = minecart.getLocation().toVector();
Vector desired = position.clone().add(MINECART_OFFSET);

if (current.distanceSquared(desired) > MAX_OFFSET_SQ)
minecart.teleport(desired.toLocation(minecart.getWorld()));
else minecart.setVelocity(desired.subtract(current));
}

private void updateWool() {
Competitor display = getDisplayTeam();
DyeColor color =
BukkitUtils.chatColorToDyeColor(display != null ? display.getColor() : ChatColor.WHITE);

Wool data = (Wool) minecart.getDisplayBlock();
data.setColor(color);
minecart.setDisplayBlock(data);
}

@Override
protected void dominate(Competitor dominantTeam, Duration dominantTime, boolean contested) {
this.dominantTeam = dominantTeam;
if (this.dominantTeam != dominantTeam) {
this.dominantTeam = dominantTeam;
updateWool();
}
super.dominate(dominantTeam, dominantTime, contested);
}

public static boolean isPayload(Entity entity) {
return entity.hasMetadata(METADATA_KEY);
}
}
25 changes: 25 additions & 0 deletions core/src/main/java/tc/oc/pgm/payload/PayloadListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package tc.oc.pgm.payload;

import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.vehicle.VehicleDamageEvent;
import org.bukkit.event.vehicle.VehicleDestroyEvent;
import org.bukkit.event.vehicle.VehicleEnterEvent;

public class PayloadListener implements Listener {

@EventHandler
public void onVehicleDamage(final VehicleDamageEvent event) {
if (Payload.isPayload(event.getVehicle())) event.setCancelled(true);
}

@EventHandler
public void onVehicleEnter(final VehicleEnterEvent event) {
if (Payload.isPayload(event.getVehicle())) event.setCancelled(true);
}

@EventHandler
public void onVehicleDestroy(final VehicleDestroyEvent event) {
if (Payload.isPayload(event.getVehicle())) event.setCancelled(true);
}
}
22 changes: 14 additions & 8 deletions core/src/main/java/tc/oc/pgm/payload/PayloadRegion.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,29 @@
import tc.oc.pgm.regions.AbstractRegion;
import tc.oc.pgm.regions.Bounds;

/** This is a region that is not immutable. The origin point of the sphere can move. */
/** This is a region that is not immutable. The origin point of the cylinder can move. */
public class PayloadRegion extends AbstractRegion {

private final Supplier<Vector> origin;
private final Supplier<Vector> base;
private final double radius;
private final double radiusSq;

public PayloadRegion(Supplier<Vector> origin, double radius) {
public PayloadRegion(Supplier<Vector> base, double radius) {
checkArgument(radius >= 0);

this.origin = origin;
this.base = base;
this.radius = radius;
this.radiusSq = Math.pow(radius, 2);
}

@Override
public boolean contains(Vector point) {
return origin.get().distanceSquared(point) <= radiusSq;
Vector base = this.base.get();

return point.getY() >= (base.getY() - 2.5)
&& point.getY() <= (base.getY() + 2.5)
&& Math.pow(point.getX() - base.getX(), 2) + Math.pow(point.getZ() - base.getZ(), 2)
< this.radiusSq;
}

@Override
Expand All @@ -34,13 +39,14 @@ public boolean isBlockBounded() {

@Override
public Bounds getBounds() {
Vector diagonal = new Vector(this.radius, this.radius, this.radius);
Vector base = this.base.get();
return new Bounds(
origin.get().clone().subtract(diagonal), this.origin.get().clone().add(diagonal));
new Vector(base.getX() - this.radius, base.getY() - 2.5, base.getZ() - this.radius),
new Vector(base.getX() + this.radius, base.getY() + 2.5, base.getZ() + this.radius));
}

@Override
public String toString() {
return "PayloadRegion{origin=[" + this.origin.get() + "],radiusSq=" + this.radiusSq + "}";
return "PayloadRegion{base=[" + this.base.get() + "],radiusSq=" + this.radiusSq + "}";
}
}
13 changes: 9 additions & 4 deletions core/src/main/java/tc/oc/pgm/payload/track/CurvedRail.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@ public CurvedRail(BlockFace from, BlockFace to) {

@Override
public Vector getOffset(double progress) {
BlockFace direction = progress < 0.5 ? from : to;
// Frame progress between 0.5 -> 0 -> 0.5, but in different directions
progress = Math.abs(progress - 0.5);
return new Vector(direction.getModX(), 0, direction.getModZ()).multiply(progress).setY(-0.5);
double remaining = 1 - progress;

progress *= 0.5;
remaining *= 0.5;

return new Vector(
remaining * from.getModX() + progress * to.getModX(),
-0.5,
remaining * from.getModZ() + progress * to.getModZ());
}

@Override
Expand Down

0 comments on commit eb25595

Please sign in to comment.