Skip to content

Commit

Permalink
Add new player variable components (#1483)
Browse files Browse the repository at this point in the history
Signed-off-by: Pablo Herrera <[email protected]>
  • Loading branch information
Pablete1234 authored Jan 20, 2025
1 parent 62f5dfb commit 3d1df1f
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 104 deletions.
6 changes: 3 additions & 3 deletions core/src/main/java/tc/oc/pgm/variables/VariableParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import tc.oc.pgm.variables.types.DummyVariable;
import tc.oc.pgm.variables.types.LivesVariable;
import tc.oc.pgm.variables.types.MaxBuildVariable;
import tc.oc.pgm.variables.types.PlayerLocationVariable;
import tc.oc.pgm.variables.types.PlayerVariable;
import tc.oc.pgm.variables.types.ScoreVariable;
import tc.oc.pgm.variables.types.TeamVariableAdapter;
import tc.oc.pgm.variables.types.TimeLimitVariable;
Expand Down Expand Up @@ -117,8 +117,8 @@ public Variable<Match> parseMaxBuild(Element el) {
@MethodParser("player-location")
public Variable<MatchPlayer> parsePlayerLocation(Element el) throws InvalidXMLException {
var component =
XMLUtils.parseEnum(Node.fromAttr(el, "component"), PlayerLocationVariable.Component.class);
return PlayerLocationVariable.INSTANCES.get(component);
XMLUtils.parseEnum(Node.fromAttr(el, "component"), PlayerVariable.Component.class);
return PlayerVariable.of(component);
}

@MethodParser("cuboid")
Expand Down
8 changes: 4 additions & 4 deletions core/src/main/java/tc/oc/pgm/variables/VariablesModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import tc.oc.pgm.util.xml.XMLUtils;
import tc.oc.pgm.variables.types.LivesVariable;
import tc.oc.pgm.variables.types.MaxBuildVariable;
import tc.oc.pgm.variables.types.PlayerLocationVariable;
import tc.oc.pgm.variables.types.PlayerVariable;
import tc.oc.pgm.variables.types.ScoreVariable;
import tc.oc.pgm.variables.types.TimeLimitVariable;

Expand Down Expand Up @@ -142,9 +142,9 @@ public VariablesModule parse(MapFactory factory, Logger logger, Document doc)
features.addFeature(null, "score", ScoreVariable.INSTANCE);
features.addFeature(null, "timelimit", TimeLimitVariable.INSTANCE);
features.addFeature(null, "maxbuildheight", MaxBuildVariable.INSTANCE);
for (var entry : PlayerLocationVariable.INSTANCES.entrySet()) {
String key = "player." + entry.getKey().name().toLowerCase(Locale.ROOT);
features.addFeature(null, key, entry.getValue());
for (var component : PlayerVariable.Component.values()) {
String key = "player." + component.name().toLowerCase(Locale.ROOT);
features.addFeature(null, key, PlayerVariable.of(component));
}
}

Expand Down

This file was deleted.

119 changes: 119 additions & 0 deletions core/src/main/java/tc/oc/pgm/variables/types/PlayerVariable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package tc.oc.pgm.variables.types;

import static java.lang.Math.toRadians;
import static tc.oc.pgm.util.nms.PlayerUtils.PLAYER_UTILS;

import java.util.Collections;
import java.util.EnumMap;
import java.util.Map;
import java.util.function.ObjDoubleConsumer;
import java.util.function.ToDoubleFunction;
import org.bukkit.Location;
import org.bukkit.entity.Damageable;
import org.bukkit.entity.Player;
import tc.oc.pgm.api.player.MatchPlayer;
import tc.oc.pgm.util.block.RayBlockIntersection;

public class PlayerVariable extends AbstractVariable<MatchPlayer> {

private static final Map<Component, PlayerVariable> INSTANCES;

static {
var values = new EnumMap<Component, PlayerVariable>(Component.class);
for (Component component : Component.values()) {
values.put(component, new PlayerVariable(component.getter, component.setter));
}
INSTANCES = Collections.unmodifiableMap(values);
}

private static final double NULL_VALUE = -1;
private static RayCastCache lastRaytrace;

record RayCastCache(Location location, RayBlockIntersection rayCast) {}

private final ToDoubleFunction<Player> getter;
private final ObjDoubleConsumer<Player> setter;

private PlayerVariable(ToDoubleFunction<Player> getter, ObjDoubleConsumer<Player> setter) {
super(MatchPlayer.class);
this.getter = getter;
this.setter = setter;
}

public static PlayerVariable of(Component component) {
return INSTANCES.get(component);
}

@Override
public boolean isReadonly() {
return setter == null;
}

@Override
protected double getValueImpl(MatchPlayer player) {
return getter.applyAsDouble(player.getBukkit());
}

@Override
protected void setValueImpl(MatchPlayer obj, double value) {
if (setter == null) throw new UnsupportedOperationException();
setter.accept(obj.getBukkit(), value);
}

public enum Component {
X(p -> p.getLocation().getX()),
Y(p -> p.getLocation().getY()),
Z(p -> p.getLocation().getZ()),
PITCH(p -> p.getLocation().getPitch()),
YAW(p -> p.getLocation().getYaw()),
DIR_X(p -> -Math.cos(toRadians(p.getLocation().getPitch()))
* Math.sin(toRadians(p.getLocation().getYaw()))),
DIR_Y(p -> -Math.sin(toRadians(p.getLocation().getPitch()))),
DIR_Z(p -> Math.cos(toRadians(p.getLocation().getPitch()))
* Math.cos(toRadians(p.getLocation().getYaw()))),
VEL_X(p -> p.getVelocity().getX()),
VEL_Y(p -> p.getVelocity().getY()),
VEL_Z(p -> p.getVelocity().getZ()),
TARGET_X(p -> intersection(p, i -> i.getBlock().getX())),
TARGET_Y(p -> intersection(p, i -> i.getBlock().getY())),
TARGET_Z(p -> intersection(p, i -> i.getBlock().getZ())),
PLACE_X(p -> intersection(p, i -> i.getPlaceAt().getX())),
PLACE_Y(p -> intersection(p, i -> i.getPlaceAt().getY())),
PLACE_Z(p -> intersection(p, i -> i.getPlaceAt().getZ())),
HAS_TARGET(p -> intersection(p) == null ? 0 : 1),
HEALTH(
Damageable::getHealth, (p, h) -> p.setHealth(Math.max(0, Math.min(p.getMaxHealth(), h)))),
MAX_HEALTH(Damageable::getMaxHealth, (p, h) -> p.setMaxHealth(Math.max(0.1f, h))),
FOOD(Player::getFoodLevel, (p, f) -> p.setFoodLevel((int) f)),
SATURATION(Player::getSaturation, (p, s) -> p.setSaturation((float) s)),
EXPERIENCE(Player::getTotalExperience, (p, ex) -> p.setTotalExperience((int) ex)),
EXP_PROGRESS(Player::getExp, (p, ex) -> p.setExp((float) ex)),
LEVEL(Player::getLevel, (p, l) -> p.setLevel((int) l));

private final ToDoubleFunction<Player> getter;
private final ObjDoubleConsumer<Player> setter;

Component(ToDoubleFunction<Player> getter, ObjDoubleConsumer<Player> setter) {
this.getter = getter;
this.setter = setter;
}

Component(ToDoubleFunction<Player> getter) {
this(getter, null);
}
}

private static RayBlockIntersection intersection(Player player) {
RayCastCache cache = lastRaytrace;
var loc = player.getLocation();
if (cache != null && loc.equals(cache.location)) return cache.rayCast;
lastRaytrace = cache = new RayCastCache(loc, PLAYER_UTILS.getTargetedBlock(player));
return cache.rayCast;
}

private static double intersection(
Player player, ToDoubleFunction<RayBlockIntersection> toDouble) {
var intersection = intersection(player);
return intersection == null ? NULL_VALUE : toDouble.applyAsDouble(intersection);
}
}

0 comments on commit 3d1df1f

Please sign in to comment.