Skip to content

Commit

Permalink
init commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Efnilite committed Dec 29, 2024
1 parent 69fba6b commit fdbf0d1
Show file tree
Hide file tree
Showing 7 changed files with 316 additions and 134 deletions.
125 changes: 88 additions & 37 deletions src/main/java/ch/njol/skript/effects/EffExplosion.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package ch.njol.skript.effects;

import org.bukkit.Location;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

import ch.njol.skript.Skript;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
Expand All @@ -12,70 +8,125 @@
import ch.njol.skript.lang.Effect;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.registrations.EventValues;
import ch.njol.skript.util.Direction;
import ch.njol.util.Kleenean;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* @author Peter Güttinger
*/
@Name("Explosion")
@Description({"Creates an explosion of a given force. The Minecraft Wiki has an <a href='https://www.minecraft.wiki/w/Explosion'>article on explosions</a> " +
"which lists the explosion forces of TNT, creepers, etc.",
"Hint: use a force of 0 to create a fake explosion that does no damage whatsoever, or use the explosion effect introduced in Skript 2.0.",
"Starting with Bukkit 1.4.5 and Skript 2.0 you can use safe explosions which will damage entities but won't destroy any blocks."})
@Examples({"create an explosion of force 10 at the player",
"create an explosion of force 0 at the victim"})
@Description({
"Creates an explosion of a given force. The Minecraft Wiki has an <a href='https://www.minecraft.wiki/w/Explosion'>article on explosions</a> " +
"which lists the explosion forces of TNT, creepers, etc.",
"Use a force of 0 to create a fake explosion that does no damage whatsoever, or use the 'fake explosion' effect.",
"Use safe explosions to create an explosion which damages entities but won't destroy any blocks."})
@Examples({
"create an explosion of force 10 at the player with fire",
"create a safe explosion with force 10",
"create a fake explosion at the player",
})
@Since("1.0")
public class EffExplosion extends Effect {

static {
Skript.registerEffect(EffExplosion.class,
"[(create|make)] [an] explosion (of|with) (force|strength|power) %number% [%directions% %locations%] [(1¦with fire)]",
"[(create|make)] [a] safe explosion (of|with) (force|strength|power) %number% [%directions% %locations%]",
"[(create|make)] [a] fake explosion [%directions% %locations%]",
"[(create|make)] [an] explosion[ ]effect [%directions% %locations%]");
"[create|make] [an] explosion (of|with) (force|strength|power) %number% [%directions% %locations%] [fire:with fire]",
"[create|make] [a] safe explosion (of|with) (force|strength|power) %number% [%directions% %locations%]",
"[create|make] [a] fake explosion [%directions% %locations%]",
"[create|make] [an] explosion[ ]effect [%directions% %locations%]");

EventValues.registerEventValue(ScriptExplodeEvent.class, Location.class, ScriptExplodeEvent::getLocation);
EventValues.registerEventValue(ScriptExplodeEvent.class, Number.class, ScriptExplodeEvent::getPower);
}

@Nullable
private Expression<Number> force;
@SuppressWarnings("null")
private Expression<Location> locations;

private boolean blockDamage;

private boolean setFire;

@SuppressWarnings({"unchecked", "null"})
@Override
public boolean init(final Expression<?>[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parser) {
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parser) {
//noinspection unchecked
force = matchedPattern <= 1 ? (Expression<Number>) exprs[0] : null;
blockDamage = matchedPattern != 1;
setFire = parser.mark == 1;
locations = Direction.combine((Expression<? extends Direction>) exprs[exprs.length - 2], (Expression<? extends Location>) exprs[exprs.length - 1]);
setFire = parser.hasTag("fire");
//noinspection unchecked
locations = Direction.combine((Expression<? extends Direction>) exprs[exprs.length - 2],
(Expression<? extends Location>) exprs[exprs.length - 1]);
return true;
}

@Override
public void execute(final Event e) {
final Number power = force != null ? force.getSingle(e) : 0;
if (power == null)
public void execute(Event event) {
Number optionalForce = force != null ? force.getSingle(event) : 0;
if (optionalForce == null)
return;
for (Location location : locations.getArray(e)) {

float power = optionalForce.floatValue();

for (Location location : locations.getArray(event)) {
if (location.getWorld() == null)
continue;
if (!blockDamage)
location.getWorld().createExplosion(location.getX(), location.getY(), location.getZ(), power.floatValue(), false, false);
else
location.getWorld().createExplosion(location, power.floatValue(), setFire);

boolean cancelled;
if (!blockDamage) {
cancelled = location.getWorld().createExplosion(location.getX(), location.getY(), location.getZ(),
power, false, false);
} else {
cancelled = location.getWorld().createExplosion(location, power, setFire);
}

if (!cancelled)
Bukkit.getPluginManager().callEvent(new ScriptExplodeEvent(location, power));
}
}

@Override
public String toString(final @Nullable Event e, final boolean debug) {
if (force != null)
return "create explosion of force " + force.toString(e, debug) + " " + locations.toString(e, debug);
else
return "create explosion effect " + locations.toString(e, debug);
public String toString(@Nullable Event event, boolean debug) {
if (force != null) {
return "create explosion of force " + force.toString(event, debug) + " " + locations.toString(event, debug);
} else {
return "create explosion effect " + locations.toString(event, debug);
}
}

/**
* Event for handling explosions created by this effect.
*/
public static class ScriptExplodeEvent extends Event {

private static final HandlerList HANDLER_LIST = new HandlerList();

private final Location at;
private final float power;

public ScriptExplodeEvent(@NotNull Location at, float power) {
this.at = at;
this.power = power;
}

public @NotNull Location getLocation() {
return at;
}

public float getPower() {
return power;
}

@Override
public @NotNull HandlerList getHandlers() {
return HANDLER_LIST;
}

public static HandlerList getHandlerList() {
return HANDLER_LIST;
}

}

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

import ch.njol.skript.Skript;
import ch.njol.skript.effects.EffExplosion;
import ch.njol.skript.entity.EntityType;
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.SkriptEvent;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.util.Color;
import ch.njol.skript.util.ColorRGB;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.FireworkEffect;
import org.bukkit.event.Event;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.FireworkExplodeEvent;
import org.bukkit.inventory.meta.FireworkMeta;
import org.jetbrains.annotations.Nullable;

import java.util.Set;
import java.util.stream.Collectors;

public class EvtExplode extends SkriptEvent {

static {
Skript.registerEvent("Explode", EvtExplode.class,
CollectionUtils.array(EffExplosion.ScriptExplodeEvent.class, FireworkExplodeEvent.class, EntityExplodeEvent.class),
"[a] script[ed] explo(d(e|ing)|sion)",
"[a] firework explo(d(e|ing)|sion) [colo[u]red %-colors%]",
"[a] [%entitytypes%] explo(d(e|ing)|sion)"
)
.description(
"Called when an entity explodes, or when an explosion is created by a script.",
"Entity and script explosions have a power value, obtained by using `event-number`.",
"Fireworks have an optional specifier for the exploded color."
)
.examples(
"on explosion:",
"on script explosion:",
"on tnt explosion:",
"on firework explode:",
"\tif event-colors contains red:",
"on firework exploding colored red, light green and black:",
"on firework explosion colored rgb 0, 255, 0:",
"\tbroadcast \"A firework colored %colors% was exploded at %location%!\""
)
.since("1.0, INSERT VERSION (script)");
}

private State state;

@Override
public boolean init(Literal<?>[] args, int matchedPattern, ParseResult parseResult) {
switch (matchedPattern) {
case 0 -> state = State.SCRIPT;
case 1 -> state = State.FIREWORK;
default -> state = State.ENTITY;
}

return state.init(args, matchedPattern, parseResult);
}

@Override
public boolean check(Event event) {
return state.check(event);
}

@Override
public String toString(@Nullable Event event, boolean debug) {
return state.toString(event, debug);
}

private enum State {

SCRIPT {
@Override
boolean init(Literal<?>[] args, int matchedPattern, ParseResult parseResult) {
return true;
}

@Override
boolean check(Event event) {
return event instanceof EffExplosion.ScriptExplodeEvent;
}

@Override
String toString(@Nullable Event event, boolean debug) {
return "script explosion";
}
},
FIREWORK {
private @Nullable Literal<Color> colors;

@Override
boolean init(Literal<?>[] args, int matchedPattern, ParseResult parseResult) {
if (args[0] != null)
//noinspection unchecked
colors = (Literal<Color>) args[0];
return true;
}

@Override
boolean check(Event event) {
if (!(event instanceof FireworkExplodeEvent fireworkExplodeEvent))
return false;

if (colors == null)
return true;

Set<org.bukkit.Color> colours = colors.stream(event)
.map(color -> {
if (color instanceof ColorRGB)
return color.asBukkitColor();
return color.asDyeColor().getFireworkColor();
})
.collect(Collectors.toSet());

FireworkMeta meta = fireworkExplodeEvent.getEntity().getFireworkMeta();
for (FireworkEffect effect : meta.getEffects()) {
if (colours.containsAll(effect.getColors()))
return true;
}
return false;
}

@Override
String toString(@Nullable Event event, boolean debug) {
return "firework explode " + (colors != null ? " with colors " + colors.toString(event, debug) : "");
}
},
ENTITY {
private @Nullable Literal<? extends EntityType> typesLiteral;
private EntityType @Nullable [] types;

@Override
boolean init(Literal<?>[] args, int matchedPattern, ParseResult parseResult) {
//noinspection unchecked
Literal<? extends EntityType> arg = (Literal<? extends EntityType>) args[0];
if (arg == null)
return false;

typesLiteral = arg;
types = arg.getAll();
return true;
}

@Override
boolean check(Event event) {
if (!(event instanceof EntityExplodeEvent explodeEvent))
return false;
if (types == null)
return true;

for (EntityType type : types) {
if (type.isInstance(explodeEvent.getEntity()))
return true;
}
return false;
}

@Override
String toString(@Nullable Event event, boolean debug) {
if (typesLiteral != null)
return typesLiteral.toString(event, debug) + " explosion";

return "explosion";
}
};

abstract boolean init(Literal<?>[] args, int matchedPattern, ParseResult parseResult);

abstract boolean check(Event event);

abstract String toString(@Nullable Event event, boolean debug);

}

}
Loading

0 comments on commit fdbf0d1

Please sign in to comment.