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

Add block explode event & fix exploded blocks change method #3990

Closed
Closed
Show file tree
Hide file tree
Changes from 3 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
8 changes: 7 additions & 1 deletion src/main/java/ch/njol/skript/events/SimpleEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import org.bukkit.event.block.BlockCanBuildEvent;
import org.bukkit.event.block.BlockDamageEvent;
import org.bukkit.event.block.BlockExplodeEvent;
import org.bukkit.event.block.BlockFertilizeEvent;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.block.BlockIgniteEvent;
Expand Down Expand Up @@ -193,7 +194,7 @@ public class SimpleEvents {
.description("Called when an entity is set on fire, e.g. by fire or lava, a fireball, or by standing in direct sunlight (zombies, skeletons).")
.examples("on combust:")
.since("1.0");
Skript.registerEvent("Explode", SimpleEvent.class, EntityExplodeEvent.class, "explo(d(e|ing)|sion)")
Skript.registerEvent("Explode", SimpleEvent.class, EntityExplodeEvent.class, "[entity] explo(d(e|ing)|sion)")
.description("Called when an entity (a primed TNT or a creeper) explodes.")
.examples("on explosion:")
.since("1.0");
Expand Down Expand Up @@ -607,5 +608,10 @@ public class SimpleEvents {
"\t\tsend \"Oops! Mending failed!\" to player")
.since("2.5.1");
}
Skript.registerEvent("Block Explode", SimpleEvent.class, BlockExplodeEvent.class, "block explo(d(e|ing)|sion)")
.description("Called when a block explodes. (Also triggered by <a href='effects.html#EffExplosion'>create explosion effect</a>)")
.examples("on block explode:",
"\tremove all chests from exploded blocks")
.since("INSERT VERSION");
}
}
126 changes: 119 additions & 7 deletions src/main/java/ch/njol/skript/expressions/ExprExplodedBlocks.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,16 @@

import java.util.List;

import ch.njol.skript.aliases.ItemType;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.Event;
import org.bukkit.event.block.BlockExplodeEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.eclipse.jdt.annotation.Nullable;
import ch.njol.skript.classes.Changer.ChangeMode;

import ch.njol.skript.ScriptLoader;
import ch.njol.skript.Skript;
Expand All @@ -39,22 +45,39 @@
import ch.njol.util.Kleenean;

@Name("Exploded Blocks")
@Description("Get all the blocks that were destroyed in an explode event")
@Examples({"on explode:",
@Description("Get all the blocks that were destroyed in an block/entity explode event (Can be set/removed from/deleted/added to)")
@Examples({"on block explode:",
"\tadd exploded blocks to {exploded-blocks::*}",
"\t",
"\tloop exploded blocks:",
"\t\tadd loop-block to {exploded::blocks::*}"})
"\t\tif loop-block is sand:",
"\t\t\tset loop-block to stone",
"\t",
"\tset exploded blocks to blocks in radius 3 around event-location # this will clear exploded blocks and set it to the specified blocks",
"\tremove all chests from exploded blocks",
"\tremove stone from exploded blocks # will remove only one block that equals to stone block type",
"\tdelete exploded blocks",
"\tadd blocks in radius 3 around event-location to exploded blocks",
"\t",
"on entity explode:",
"\tremove all stone from exploded blocks"})
@Events("explode")
@Since("2.5")
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
public class ExprExplodedBlocks extends SimpleExpression<Block> {

static {
Skript.registerExpression(ExprExplodedBlocks.class, Block.class, ExpressionType.COMBINED, "[the] exploded blocks");
Skript.registerExpression(ExprExplodedBlocks.class, Block.class, ExpressionType.SIMPLE, "[the] exploded blocks");
}

boolean isEntity = false;

@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) {
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
if (!ScriptLoader.isCurrentEvent(EntityExplodeEvent.class)) {
Skript.error("Exploded blocks can only be retrieved from an explode event.");
if (ScriptLoader.isCurrentEvent(EntityExplodeEvent.class)) {
isEntity = true;
}
else if (!ScriptLoader.isCurrentEvent(BlockExplodeEvent.class)) {
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
Skript.error("Exploded blocks can only be retrieved from an entity/block explode event.");
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
return false;
}
return true;
Expand All @@ -63,10 +86,99 @@ public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelaye
@Nullable
@Override
protected Block[] get(Event e) {
List<Block> blockList = ((EntityExplodeEvent) e).blockList();
List<Block> blockList;
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved

if (isEntity)
blockList = ((EntityExplodeEvent) e).blockList();
else
blockList = ((BlockExplodeEvent) e).blockList();

AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
return blockList.toArray(new Block[blockList.size()]);
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
}


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

@Override
public void change(Event e, final @Nullable Object[] delta, final ChangeMode mode) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public void change(Event e, final @Nullable Object[] delta, final ChangeMode mode) {
public void change(Event e, @Nullable Object[] delta, ChangeMode mode) {

List<Block> blocks;
if (isEntity)
blocks = ((EntityExplodeEvent) e).blockList();
else
blocks = ((BlockExplodeEvent) e).blockList();
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved

switch (mode) {
case SET:
assert delta != null;
blocks.clear();
for (Object de : delta) {
if (de instanceof ItemType) {
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
break;
}
if (((Block) de).getType() != Material.AIR) // Performance
blocks.add((Block) de);
}
break;

case DELETE:
blocks.clear();
break;

case ADD:
assert delta != null;
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
for (Object de : delta) {
if (de instanceof ItemType) {
break;
}
if (((Block) de).getType() != Material.AIR) // Performance
blocks.add((Block) de);
}
break;

case REMOVE:
case REMOVE_ALL: // ItemType here will allow `remove [all] %itemtypes% from exploded blocks` to remove all/specific amount of specific block type that matches an itemtype, a shortcut for looping
assert delta != null;
for (Object de : delta) {
if (de instanceof ItemType) {
Bukkit.broadcastMessage("!> " + ((ItemType) de).getAmount());
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
int loopLimit = ((ItemType) de).getAmount() == 0 ? blocks.size() : ((ItemType) de).getAmount();
if (((ItemType) de).isAll() || mode == ChangeMode.REMOVE_ALL) // all %itemtype% OR REMOVE_ALL
loopLimit = blocks.size();

for (int i = 0; i < loopLimit; i++) {
for (Block b : blocks) {
if (b.getType() == ((ItemType) de).getMaterial()) {
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
blocks.remove(b);
break;
}
}
}

} else {
blocks.removeIf(b -> b.equals((Block) de));
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
}
}

break;
}
}


@Override
public boolean isSingle() {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package ch.njol.skript.expressions;

import org.bukkit.event.Event;
import org.bukkit.event.block.BlockExplodeEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.eclipse.jdt.annotation.Nullable;

Expand Down Expand Up @@ -54,11 +55,16 @@ public class ExprExplosionBlockYield extends SimpleExpression<Number> {
"[the] percentage of blocks dropped"
);
}

boolean isEntity = false;

@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
if (!ScriptLoader.isCurrentEvent(EntityExplodeEvent.class)) {
Skript.error("The 'explosion block yield' is only usable in an explosion event", ErrorQuality.SEMANTIC_ERROR);
if (ScriptLoader.isCurrentEvent(EntityExplodeEvent.class)) {
isEntity = true;
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
}
else if (!ScriptLoader.isCurrentEvent(BlockExplodeEvent.class)) {
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
Skript.error("The 'explosion block yield' is only usable in an entity/block explosion event", ErrorQuality.SEMANTIC_ERROR);
return false;
}
return true;
Expand All @@ -67,7 +73,7 @@ public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelaye
@Override
@Nullable
protected Number[] get(Event e) {
return new Number[]{((EntityExplodeEvent) e).getYield()};
return new Number[]{ (isEntity ? ((EntityExplodeEvent) e).getYield() : ((BlockExplodeEvent) e).getYield()) };
}

@Override
Expand All @@ -89,32 +95,47 @@ public void change(final Event event, final @Nullable Object[] delta, final Chan
float n = delta == null ? 0 : ((Number) delta[0]).floatValue();
if (n < 0) // Yield can't be negative
return;
EntityExplodeEvent e = (EntityExplodeEvent) event;
// Yield can be a value from 0 to 1
switch (mode) {
case SET:
e.setYield(n);
typeSetYield(event, n);
break;
case ADD:
float add = e.getYield() + n;
float add = typeGetYield(event) + n;
if (add < 0)
return;
e.setYield(add);
typeSetYield(event, add);
break;
case REMOVE:
float subtract = e.getYield() - n;
float subtract = typeGetYield(event) - n;
if (subtract < 0)
return;
e.setYield(subtract);
typeSetYield(event, subtract);
break;
case DELETE:
e.setYield(0);
typeSetYield(event, 0);
break;
default:
assert false;
}
}

private float typeGetYield(Event e) {
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
if (isEntity) {
return ((EntityExplodeEvent) e).getYield();
} else {
return ((BlockExplodeEvent) e).getYield();
}
}
private void typeSetYield(Event e, float yield) {
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
if (isEntity) {
((EntityExplodeEvent) e).setYield(yield);
} else {
((BlockExplodeEvent) e).setYield(yield);
}
}

@Override
public boolean isSingle() {
return true;
Expand Down