Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warden+ #7314

Open
wants to merge 11 commits into
base: dev/feature
Choose a base branch
from
65 changes: 65 additions & 0 deletions src/main/java/ch/njol/skript/effects/EffWardenDisturbance.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package ch.njol.skript.effects;

import ch.njol.skript.Skript;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.Effect;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.util.Direction;
import ch.njol.util.Kleenean;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Warden;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

@Name("Make Disturbance")
@Description({
"Make a warden sense a disturbance at a location, causing the warden to investigate that area.",
"The warden will not investigate if the warden is aggressive towards an entity.",
"This effect does not add anger to the warden."
})
@Examples("make last spawned warden sense a disturbance at location(0, 0, 0)")
@Since("INSERT VERSION")
public class EffWardenDisturbance extends Effect {

static {
Skript.registerEffect(EffWardenDisturbance.class,
"make %livingentities% sense [a] disturbance %direction% %location%");
}

private Expression<LivingEntity> wardens;
private Expression<Location> location;

@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
//noinspection unchecked
wardens = (Expression<LivingEntity>) exprs[0];
//noinspection unchecked
Expression<Direction> direction = (Expression<Direction>) exprs[1];
//noinspection unchecked
Expression<Location> location = (Expression<Location>) exprs[2];
this.location = Direction.combine(direction, location);
return true;
}

@Override
protected void execute(Event event) {
Location finalLocation = location.getSingle(event);
if (finalLocation == null)
return;
for (LivingEntity livingEntity : wardens.getArray(event)) {
if (livingEntity instanceof Warden warden)
warden.setDisturbanceLocation(finalLocation);
}
}

@Override
public String toString(@Nullable Event event, boolean debug) {
return "make " + wardens.toString(event, debug) + " sense a disturbance " + location.toString(event, debug);
}

}
65 changes: 65 additions & 0 deletions src/main/java/ch/njol/skript/expressions/ExprWardenAngryAt.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package ch.njol.skript.expressions;

import ch.njol.skript.classes.Changer.ChangeMode;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.expressions.base.SimplePropertyExpression;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Warden;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

@Name("Warden Most Angered At")
@Description({
"The entity a warden is most angry at.",
"A warden can be angry towards multiple entities with different anger levels.",
})
@Examples({
"if the most angered entity of last spawned warden is not player:",
"\tset the most angered entity of last spawned warden to player"
})
@Since("INSERT VERSION")
public class ExprWardenAngryAt extends SimplePropertyExpression<LivingEntity, LivingEntity> {

static {
register(ExprWardenAngryAt.class, LivingEntity.class, "most angered entity", "livingentities");
}

@Override
public @Nullable LivingEntity convert(LivingEntity livingEntity) {
if (!(livingEntity instanceof Warden warden))
return null;
return warden.getEntityAngryAt();
}

@Override
public Class<?> @Nullable [] acceptChange(ChangeMode mode) {
if (mode == ChangeMode.SET)
return CollectionUtils.array(LivingEntity.class);
return null;
}

@Override
public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
assert delta != null;
LivingEntity target = (LivingEntity) delta[0];
for (LivingEntity livingEntity : getExpr().getArray(event)) {
if (livingEntity instanceof Warden warden)
warden.setAnger(target, 150);
}
}

@Override
public Class<LivingEntity> getReturnType() {
return LivingEntity.class;
}

@Override
protected String getPropertyName() {
return "most angered entity";
}

}
123 changes: 123 additions & 0 deletions src/main/java/ch/njol/skript/expressions/ExprWardenEntityAnger.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package ch.njol.skript.expressions;

import ch.njol.skript.Skript;
import ch.njol.skript.classes.Changer.ChangeMode;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.util.Kleenean;
import ch.njol.util.Math2;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Warden;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;

@Name("Warden Anger Level")
@Description({
"The anger level a warden feels towards an entity.",
"A warden can be angry towards multiple entities with different anger levels.",
"If an entity reaches an anger level of 80+, the warden will pursue it.",
"Anger level maxes out at 150."
})
@Examples({
"set the anger level of last spawned warden towards player to 20",
"clear the last spawned warden's anger level towards player"
})
@Since("INSERT VERSION")
public class ExprWardenEntityAnger extends SimpleExpression<Integer> {

static {
Skript.registerExpression(ExprWardenEntityAnger.class, Integer.class, ExpressionType.COMBINED,
"[the] anger level [of] %livingentities% towards %livingentities%",
"%livingentities%'[s] anger level towards %livingentities%");
}

private Expression<LivingEntity> wardens;
private Expression<LivingEntity> targets;

@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
//noinspection unchecked
wardens = (Expression<LivingEntity>) exprs[0];
//noinspection unchecked
targets = (Expression<LivingEntity>) exprs[1];
return true;
}

@Override
protected Integer @Nullable [] get(Event event) {
List<Integer> list = new ArrayList<>();
Entity[] entities = this.targets.getArray(event);
for (LivingEntity livingEntity : wardens.getArray(event)) {
if (!(livingEntity instanceof Warden warden))
continue;
for (Entity entity : entities) {
list.add(warden.getAnger(entity));
}
}
return list.toArray(new Integer[0]);
}

@Override
public Class<?> @Nullable [] acceptChange(ChangeMode mode) {
return switch (mode) {
case SET, DELETE, ADD, REMOVE -> CollectionUtils.array(Integer.class);
default -> null;
};
}

@Override
public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
int value = delta != null ? (Integer) delta[0] : 0;
BiConsumer<Warden, Entity> consumer = switch (mode) {
case SET -> (warden, entity) -> warden.setAnger(entity, Math2.fit(0, value, 150));
case DELETE -> Warden::clearAnger;
case ADD -> (warden, entity) -> {
int current = warden.getAnger(entity);
int newValue = Math2.fit(0, current + value, 150);
warden.setAnger(entity, newValue);
};
case REMOVE -> (warden, entity) -> {
int current = warden.getAnger(entity);
int newValue = Math2.fit(0, current - value, 150);
warden.setAnger(entity, newValue);
};
default -> throw new IllegalStateException("Unexpected value: " + mode);
};
Entity[] entities = this.targets.getArray(event);
for (LivingEntity livingEntity : wardens.getArray(event)) {
if (!(livingEntity instanceof Warden warden))
continue;
for (Entity entity : entities) {
consumer.accept(warden, entity);
}
}
}

@Override
public boolean isSingle() {
return wardens.isSingle() && targets.isSingle();
}

@Override
public Class<Integer> getReturnType() {
return Integer.class;
}

@Override
public String toString(@Nullable Event event, boolean debug) {
return "the anger level of " + wardens.toString(event, debug) + " towards " + targets.toString(event, debug);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
test "warden entity anger":
spawn a warden at test-location:
set {_warden} to entity

spawn a pig, a sheep and a cow at test-location:
add entity to {_entities::*}

loop {_entities::*}:
set {_rng} to a random integer between 1 and 79
set the anger level of {_warden} towards loop-value to {_rng}
assert the anger level of {_warden} towards loop-value is {_rng} with "Anger level was not correctly set"
remove 99999 from the anger level of {_warden} towards loop-value
assert the anger level of {_warden} towards loop-value is 0 with "Anger level should be clamped to 0 min"
add 99999 to the anger level of {_warden} towards loop-value
assert the anger level of {_warden} towards loop-value is 150 with "Anger level should be clamped to 150 max"
clear the anger level of {_warden} towards loop-value
assert the anger level of {_warden} towards loop-value is 0 with "Anger level was not cleared"

set the most angered entity of {_warden} to {_entities::1}
assert the most angered entity of {_warden} is {_entities::1} with "Most angered entity was not correctly set"

clear entity within {_warden}
clear entities within {_entities::*}
Loading