Skip to content

Commit

Permalink
Bell API (#6456)
Browse files Browse the repository at this point in the history
* feat(events): add events for bells

* feat(test): bell events junit tests

* feat(syntax): bell related properties

* fix(bells): fix incorrect values

* feat(bells): add ring effect

* fix(test): don't test ringing time pre-1.19.4

* fix(bells): check if Bells exist before using them

* fix(bells): more checking if bells exist

* chore(docs): specify Spigot instead of Minecraft

Co-authored-by: LimeGlass <[email protected]>

* fix(docs): specify Bell in syntax names

Co-authored-by: LimeGlass <[email protected]>

* chore(codestyle): non-invasive codestyle changes

Co-authored-by: LimeGlass <[email protected]>

* chore(codestyle): import ParseResult

* chore: suggestions from code review

Co-authored-by: Patrick Miller <[email protected]>

* fix(docs): clarify event-direction as missing from paper 1.16.5

* fix: remove reflective call to necessarily non-existent constructor

---------

Co-authored-by: LimeGlass <[email protected]>
Co-authored-by: Patrick Miller <[email protected]>
Co-authored-by: Moderocky <[email protected]>
  • Loading branch information
4 people authored Apr 8, 2024
1 parent 0827e01 commit b5160e2
Show file tree
Hide file tree
Showing 11 changed files with 556 additions and 2 deletions.
42 changes: 40 additions & 2 deletions src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@
import org.bukkit.event.block.BlockIgniteEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.block.BellRingEvent;
import org.bukkit.event.block.BellResonateEvent;
import org.bukkit.event.enchantment.EnchantItemEvent;
import org.bukkit.event.enchantment.PrepareItemEnchantEvent;
import org.bukkit.event.entity.AreaEffectCloudApplyEvent;
Expand Down Expand Up @@ -1799,6 +1801,44 @@ public TransformReason get(EntityTransformEvent event) {
}
}, EventValues.TIME_NOW);

// BellRingEvent - these are BlockEvents and not EntityEvents, so they have declared methods for getEntity()
if (Skript.classExists("org.bukkit.event.block.BellRingEvent")) {
EventValues.registerEventValue(BellRingEvent.class, Entity.class, new Getter<Entity, BellRingEvent>() {
@Override
@Nullable
public Entity get(BellRingEvent event) {
return event.getEntity();
}
}, EventValues.TIME_NOW);

EventValues.registerEventValue(BellRingEvent.class, Direction.class, new Getter<Direction, BellRingEvent>() {
@Override
public Direction get(BellRingEvent event) {
return new Direction(event.getDirection(), 1);
}
}, EventValues.TIME_NOW);
} else if (Skript.classExists("io.papermc.paper.event.block.BellRingEvent")) {
EventValues.registerEventValue(
io.papermc.paper.event.block.BellRingEvent.class, Entity.class,
new Getter<Entity, io.papermc.paper.event.block.BellRingEvent>() {
@Override
@Nullable
public Entity get(io.papermc.paper.event.block.BellRingEvent event) {
return event.getEntity();
}
}, EventValues.TIME_NOW);
}

if (Skript.classExists("org.bukkit.event.block.BellResonateEvent")) {
EventValues.registerEventValue(BellResonateEvent.class, Entity[].class, new Getter<Entity[], BellResonateEvent>() {
@Override
@Nullable
public Entity[] get(BellResonateEvent event) {
return event.getResonatedEntities().toArray(new LivingEntity[0]);
}
}, EventValues.TIME_NOW);
}

// InventoryMoveItemEvent
EventValues.registerEventValue(InventoryMoveItemEvent.class, Inventory.class, new Getter<Inventory, InventoryMoveItemEvent>() {
@Override
Expand Down Expand Up @@ -1830,7 +1870,5 @@ public ItemStack get(InventoryMoveItemEvent event) {
return event.getItem();
}
}, EventValues.TIME_NOW);

}

}
58 changes: 58 additions & 0 deletions src/main/java/ch/njol/skript/conditions/CondIsResonating.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* This file is part of Skript.
*
* Skript is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Skript is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package ch.njol.skript.conditions;

import ch.njol.skript.Skript;
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.RequiredPlugins;
import ch.njol.skript.doc.Since;
import org.bukkit.block.Bell;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;

@Name("Bell Is Resonating")
@Description({
"Checks to see if a bell is currently resonating.",
"A bell will start resonating five game ticks after being rung, and will continue to resonate for 40 game ticks."
})
@Examples("target block is resonating")
@RequiredPlugins("Spigot 1.19.4+")
@Since("INSERT VERSION")
public class CondIsResonating extends PropertyCondition<Block> {

static {
if (Skript.classExists("org.bukkit.block.Bell") && Skript.methodExists(Bell.class, "isResonating"))
register(CondIsResonating.class, "resonating", "blocks");
}

@Override
public boolean check(Block value) {
BlockState state = value.getState(false);
return state instanceof Bell && ((Bell) state).isResonating();
}

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

}
55 changes: 55 additions & 0 deletions src/main/java/ch/njol/skript/conditions/CondIsRinging.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* This file is part of Skript.
*
* Skript is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Skript is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package ch.njol.skript.conditions;

import ch.njol.skript.Skript;
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.RequiredPlugins;
import ch.njol.skript.doc.Since;
import org.bukkit.block.Bell;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;

@Name("Bell Is Ringing")
@Description("Checks to see if a bell is currently ringing. A bell typically rings for 50 game ticks.")
@Examples("target block is ringing")
@RequiredPlugins("Spigot 1.19.4+")
@Since("INSERT VERSION")
public class CondIsRinging extends PropertyCondition<Block> {

static {
if (Skript.classExists("org.bukkit.block.Bell") && Skript.methodExists(Bell.class, "isShaking"))
register(CondIsRinging.class, "ringing", "blocks");
}

@Override
public boolean check(Block value) {
BlockState state = value.getState(false);
return state instanceof Bell && ((Bell) state).isShaking();
}

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

}
110 changes: 110 additions & 0 deletions src/main/java/ch/njol/skript/effects/EffRing.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/**
* This file is part of Skript.
*
* Skript is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Skript is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
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.RequiredPlugins;
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.block.Bell;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
import org.bukkit.event.Event;
import org.eclipse.jdt.annotation.Nullable;

@Name("Ring Bell")
@Description({
"Causes a bell to ring.",
"Optionally, the entity that rang the bell and the direction the bell should ring can be specified.",
"A bell can only ring in two directions, and the direction is determined by which way the bell is facing.",
"By default, the bell will ring in the direction it is facing.",
})
@Examples({"make player ring target-block"})
@RequiredPlugins("Spigot 1.19.4+")
@Since("INSERT VERSION")
public class EffRing extends Effect {

static {
if (Skript.classExists("org.bukkit.block.Bell") && Skript.methodExists(Bell.class, "ring", Entity.class, BlockFace.class))
Skript.registerEffect(EffRing.class,
"ring %blocks% [from [the]] [%-direction%]",
"(make|let) %entity% ring %blocks% [from [the]] [%-direction%]"
);
}

@Nullable
private Expression<Entity> entity;

@SuppressWarnings("NotNullFieldNotInitialized")
private Expression<Block> blocks;

@Nullable
private Expression<Direction> direction;

@Override
@SuppressWarnings("unchecked")
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
entity = matchedPattern == 0 ? null : (Expression<Entity>) exprs[0];
blocks = (Expression<Block>) exprs[matchedPattern];
direction = (Expression<Direction>) exprs[matchedPattern + 1];
return true;
}

@Nullable
private BlockFace getBlockFace(Event event) {
if (this.direction == null)
return null;

Direction direction = this.direction.getSingle(event);
if (direction == null)
return null;

return Direction.getFacing(direction.getDirection(), true);
}

@Override
protected void execute(Event event) {
BlockFace blockFace = getBlockFace(event);
Entity actualEntity = entity == null ? null : entity.getSingle(event);

for (Block block : blocks.getArray(event)) {
BlockState state = block.getState(false);
if (state instanceof Bell) {
Bell bell = (Bell) state;
bell.ring(actualEntity, blockFace);
}
}
}

@Override
public String toString(@Nullable Event event, boolean debug) {
return (entity != null ? "make " + entity.toString(event, debug) + " " : "") +
"ring " + blocks.toString(event, debug) + " from " + (direction != null ? direction.toString(event, debug) : "");
}

}
40 changes: 40 additions & 0 deletions src/main/java/ch/njol/skript/events/SimpleEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import io.papermc.paper.event.player.PlayerDeepSleepEvent;
import io.papermc.paper.event.player.PlayerInventorySlotChangeEvent;
import io.papermc.paper.event.player.PlayerTradeEvent;
import org.bukkit.event.Event;
import org.bukkit.event.block.BlockCanBuildEvent;
import org.bukkit.event.block.BlockDamageEvent;
import org.bukkit.event.block.BlockFertilizeEvent;
Expand Down Expand Up @@ -740,6 +741,45 @@ public class SimpleEvents {
)
.since("2.7");

{
final Class<? extends Event> eventClass;
if (Skript.classExists("org.bukkit.event.block.BellRingEvent")) {
eventClass = org.bukkit.event.block.BellRingEvent.class;
} else if (Skript.classExists("io.papermc.paper.event.block.BellRingEvent")) {
//noinspection deprecation
eventClass = io.papermc.paper.event.block.BellRingEvent.class;
} else {
eventClass = null;
}

if (eventClass != null) {
Skript.registerEvent("Bell Ring", SimpleEvent.class, eventClass, "bell ring[ing]")
.description("Called when a bell is rung.")
.examples(
"on bell ring:",
"\tsend \"<gold>Ding-dong!<reset>\" to all players in radius 10 of event-block"
)
.since("INSERT VERSION")
.requiredPlugins("Spigot 1.19.4+ or Paper 1.16.5+ (no event-direction)");
}
}

/*
* Paper supported this in 1.16.5 via io.papermc.paper.event.block.BellRevealRaiderEvent.
* The Paper event, however, is called for each raider, while the Spigot event is called once for all raiders.
* Supporting both would cause confusing behaviour, with the event being triggered in different ways depending
* on the server software and version, so we're only supporting the Spigot event.
*/
if (Skript.classExists("org.bukkit.event.block.BellResonateEvent")) {
Skript.registerEvent("Bell Resonate", SimpleEvent.class, org.bukkit.event.block.BellResonateEvent.class, "bell resonat(e|ing)")
.description("Called when a bell resonates, highlighting nearby raiders.")
.examples(
"on bell resonate:",
"\tsend \"<red>Raiders are nearby!\" to all players in radius 32 around event-block"
)
.since("INSERT VERSION")
.requiredPlugins("Spigot 1.19.4+");
}
}

}
Loading

0 comments on commit b5160e2

Please sign in to comment.