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

EntityBlockStorage + Beehive #7316

Open
wants to merge 22 commits into
base: dev/feature
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package ch.njol.skript.conditions;

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.Condition;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.SyntaxStringBuilder;
import ch.njol.util.Kleenean;
import org.bukkit.block.Block;
import org.bukkit.block.EntityBlockStorage;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

@Name("Entity Storage Is Full")
@Description("Checks to see if the stored entities of an entity block storage (i.e beehive) is full.")
@Examples({
"if the stored entities of {_beehive} is full:",
"\trelease the stored entities of {_beehive}"
})
@Since("INSERT VERSION")
public class CondEntityStorageIsFull extends Condition {

static {
Skript.registerCondition(CondEntityStorageIsFull.class, ConditionType.PROPERTY,
"[the] stored entities of %blocks% (is|are) full",
"[the] stored entities of %blocks% (isn't|is not|aren't|are not) full");
Efnilite marked this conversation as resolved.
Show resolved Hide resolved
}

private Expression<Block> blocks;
private boolean checkFull;

@Override
public boolean init(Expression<?>[] exrps, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
checkFull = matchedPattern % 2 == 0;
//noinspection unchecked
blocks = (Expression<Block>) exrps[0];
return true;
}

@Override
public boolean check(Event event) {
return blocks.check(event, block -> {
if (!(block.getState() instanceof EntityBlockStorage<?> blockStorage))
return false;
return blockStorage.isFull() == checkFull;
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
});
}

@Override
public String toString(@Nullable Event event, boolean debug) {
SyntaxStringBuilder builder = new SyntaxStringBuilder(event, debug);
builder.append("the stored entities of", blocks);
if (blocks.isSingle()) {
builder.append("is");
} else {
builder.append("are");
}
if (!checkFull)
builder.append("not");
builder.append("full");
return builder.toString();
}

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

import ch.njol.skript.conditions.base.PropertyCondition;
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 org.bukkit.block.Beehive;
import org.bukkit.block.Block;

@Name("Is Sedated")
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
@Description("Checks if a beehive is sedated from a nearby campfire.")
@Examples("if {_beehive} is sedated:")
@Since("INSERT VERSION")
public class CondIsSedated extends PropertyCondition<Block> {

static {
PropertyCondition.register(CondIsSedated.class, PropertyType.BE, "sedated", "blocks");
}

@Override
public boolean check(Block block) {
if (!(block.getState() instanceof Beehive beehive))
return false;
return beehive.isSedated();
}

@Override
protected String getPropertyName() {
return "sedated";
}

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

import ch.njol.skript.Skript;
import ch.njol.skript.doc.*;
import ch.njol.skript.lang.Effect;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.SyntaxStringBuilder;
import ch.njol.skript.util.Timespan;
import ch.njol.skript.util.Timespan.TimePeriod;
import ch.njol.util.Kleenean;
import org.bukkit.block.Block;
import org.bukkit.block.EntityBlockStorage;
import org.bukkit.entity.Bee;
import org.bukkit.entity.Entity;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

import java.util.List;

@Name("Release Entity Storage")
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
@Description({
"Release the stored entities in an entity block storage (i.e. beehive).",
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
"Providing a timespan will make the released entities unable to go back into the entity block storage for that amount of time.",
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
"Due to unstable behaviour on older versions, this effect requires Minecraft version 1.21+."
})
@Examples({
"release the stored entities of {_beehive}",
"release the stored entities of {_hive} for 5 seconds"
})
@RequiredPlugins("Minecraft 1.21")
@Since("INSERT VERSION")
public class EffReleaseEntityStorage extends Effect {

/*
Minecraft versions 1.19.4 -> 1.20.6 have unstable behavior.
Either entities are not released or are released and not clearing the stored entities.
Adding entities into EntityBlockStorage's are also unstable.
Entities are either not added, or added but still exist.
*/

static {
if (Skript.isRunningMinecraft(1, 21, 0)) {
Skript.registerEffect(EffReleaseEntityStorage.class,
"(release|evict) [the] stored entities of %blocks% [for %-timespan%]");
}
}

private Expression<Block> blocks;
private @Nullable Expression<Timespan> timespan;

@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
//noinspection unchecked
blocks = (Expression<Block>) exprs[0];
return true;
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
}

@Override
protected void execute(Event event) {
Integer ticks = null;
if (timespan != null) {
Timespan time = timespan.getSingle(event);
if (time != null)
ticks = (int) time.getAs(TimePeriod.TICK);
}
for (Block block : blocks.getArray(event)) {
if (!(block.getState() instanceof EntityBlockStorage<?> blockStorage))
continue;
List<? extends Entity> released = blockStorage.releaseEntities();
if (ticks != null) {
for (Entity entity : released) {
if (entity instanceof Bee bee) {
bee.setCannotEnterHiveTicks(ticks);
}
}
}
}
}

@Override
public String toString(@Nullable Event event, boolean debug) {
SyntaxStringBuilder builder = new SyntaxStringBuilder(event, debug);
builder.append("release the stored entities of", blocks);
if (timespan != null)
builder.append("for", timespan);
return builder.toString();
}

}
71 changes: 71 additions & 0 deletions src/main/java/ch/njol/skript/expressions/ExprBeehiveFlower.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
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.Location;
import org.bukkit.block.Beehive;
import org.bukkit.block.Block;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

@Name("Beehive Target Flower")
@Description("The flower a beehive has selected to pollinate from.")
@Examples({
"set the target flower of {_beehive} to location(0, 0, 0)",
"clear the target flower of {_beehive}"
})
@Since("INSERT VERSION")
public class ExprBeehiveFlower extends SimplePropertyExpression<Block, Location> {

static {
registerDefault(ExprBeehiveFlower.class, Location.class, "target flower", "blocks");
}

@Override
public @Nullable Location convert(Block block) {
if (!(block.getState() instanceof Beehive beehive))
return null;
return beehive.getFlower();
}

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

@Override
public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
Location location = null;
if (delta != null) {
if (delta[0] instanceof Location loc) {
location = loc;
} else if (delta[0] instanceof Block block) {
location = block.getLocation();
}
}
for (Block block : getExpr().getArray(event)) {
if (!(block.getState() instanceof Beehive beehive))
continue;
beehive.setFlower(location);
beehive.update(true, false);
}
}

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

@Override
protected String getPropertyName() {
return "target flower";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
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.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.util.Kleenean;
import ch.njol.util.Math2;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.block.Block;
import org.bukkit.block.data.type.Beehive;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

import java.util.function.Consumer;

@Name("Beehive Honey Level")
@Description({
"The current or max honey level of a beehive.",
"The max level is 5, which cannot be changed."
})
@Examples("set the honey level of {_beehive} to the max honey level of {_beehive}")
@Since("INSERT VERSION")
public class ExprBeehiveHoneyLevel extends SimplePropertyExpression<Block, Integer> {

static {
registerDefault(ExprBeehiveHoneyLevel.class, Integer.class, "[max:max[imum]] honey level", "blocks");
}

private boolean isMax;

@Override
public boolean init(Expression<?>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
isMax = parseResult.hasTag("max");
return super.init(expressions, matchedPattern, isDelayed, parseResult);
}

@Override
public @Nullable Integer convert(Block block) {
if (!(block.getBlockData() instanceof Beehive beehive))
return null;
if (isMax)
return beehive.getMaximumHoneyLevel();
return beehive.getHoneyLevel();
}

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

@Override
public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
int value = delta != null ? (int) delta[0] : 0;
Consumer<Beehive> consumer = switch (mode) {
case SET -> beehive -> beehive.setHoneyLevel(Math2.fit(0, value, 5));
case ADD -> beehive -> {
int current = beehive.getHoneyLevel();
beehive.setHoneyLevel(Math2.fit(0, current + value, 5));
};
case REMOVE -> beehive -> {
int current = beehive.getHoneyLevel();
beehive.setHoneyLevel(Math2.fit(0, current - value, 5));
};
default -> throw new IllegalStateException("Unexpected value: " + mode);
};
for (Block block : getExpr().getArray(event)) {
if (!(block.getBlockData() instanceof Beehive beehive))
continue;
consumer.accept(beehive);
block.setBlockData(beehive);
}
}

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

@Override
protected String getPropertyName() {
return (isMax ? "maximum " : "") + "honey level";
}

}
Loading
Loading