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 1 commit
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
97 changes: 97 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,97 @@
/**
* 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.events;

import ch.njol.skript.Skript;
import ch.njol.skript.entity.EntityData;
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.SkriptEvent;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.log.ErrorQuality;
import ch.njol.skript.registrations.Classes;
import ch.njol.util.StringUtils;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.entity.Entity;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Event;
import org.bukkit.event.block.BlockEvent;
import org.bukkit.event.block.BlockExplodeEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntitySpawnEvent;
import org.eclipse.jdt.annotation.Nullable;

/**
* @author Peter Güttinger
*/
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
@SuppressWarnings("unchecked")
public final class EvtExplode extends SkriptEvent {
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved

private final static int ENTITY = 1, BLOCK = 2, ANY = ENTITY | BLOCK;
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved

static {
Class<? extends Event>[] eventTypes = CollectionUtils.array(EntityExplodeEvent.class, BlockExplodeEvent.class);

Skript.registerEvent("entity/block explode", EvtExplode.class, eventTypes, "[(1¦entity|2¦block)] explo(d(e|ing)|sion)")
.description(
"Called when an entity (a primed TNT or a creeper) explodes " +
"OR Called when a block explodes. (Also triggered by <a href='effects.html#EffExplosion'>create explosion effect</a>)" +
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
" " +
"If explosion type is specified only that type of explosion will trigger the event.")
.examples("on explode:",
"\tbroadcast \"a(n) %explosion type% just exploded.\"",
"on block explode:",

"\tbroadcast \"A block just exploded\"",
"on entity explode:",

"\tbroadcast \"An entity just exploded\"")
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
.since("1.0, INSERT VERSION (block explode)");
}

@Nullable
private int type;

@SuppressWarnings("null")
@Override
public boolean init(final Literal<?>[] args, final int matchedPattern, final ParseResult parser) {
type = parser.mark == 0 ? ANY : parser.mark;
return true;
}

@SuppressWarnings("null")
@Override
public boolean check(final Event e) {
if (type == ENTITY)
return e instanceof EntityExplodeEvent ? true : false;

if (type == BLOCK)
return e instanceof BlockExplodeEvent ? true : false;
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved

else // Any
return true;
}

@Override
public String toString(final @Nullable Event e, final boolean debug) {
return (type == ENTITY ? "entity" : type == BLOCK ? "block" : "any") + (" explode");
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
}

}
12 changes: 0 additions & 12 deletions src/main/java/ch/njol/skript/events/SimpleEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

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 All @@ -38,10 +37,8 @@
import org.bukkit.event.entity.CreeperPowerEvent;
import org.bukkit.event.entity.EntityBreakDoorEvent;
import org.bukkit.event.entity.EntityCombustEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntityPortalEnterEvent;
import org.bukkit.event.entity.EntityPortalEvent;
import org.bukkit.event.entity.EntityPortalExitEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.entity.EntityResurrectEvent;
import org.bukkit.event.entity.EntityTameEvent;
Expand Down Expand Up @@ -194,10 +191,6 @@ 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, "[entity] explo(d(e|ing)|sion)")
.description("Called when an entity (a primed TNT or a creeper) explodes.")
.examples("on explosion:")
.since("1.0");
// Skript.registerEvent(SimpleEvent.class, EntityInteractEvent.class, "interact");// = entity interacts with block, e.g. endermen?; player -> PlayerInteractEvent // likely tripwires, pressure plates, etc.
Skript.registerEvent("Portal Enter", SimpleEvent.class, EntityPortalEnterEvent.class, "portal enter[ing]", "entering [a] portal")
.description("Called when an entity enters a nether portal or an end portal. Please note that this event will be fired many times for a nether portal.")
Expand Down Expand Up @@ -608,10 +601,5 @@ 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");
}
}
125 changes: 66 additions & 59 deletions src/main/java/ch/njol/skript/expressions/ExprExplodedBlocks.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@
*/
package ch.njol.skript.expressions;

import java.util.ArrayList;
import java.util.Iterator;
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;
Expand All @@ -39,26 +40,31 @@
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.SkriptParser;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.util.Kleenean;

@Name("Exploded Blocks")
@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::*}",
@Description("Get all the blocks that were destroyed in an entity/block explode event (Can be set/removed from/deleted/added to)")
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
@Examples({
"on block explode:",
"\tadd exploded blocks to {_exploded-blocks::*}",
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
"\t",
"\tloop 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",
"\tremove 3 stone from exploded blocks # will remove only 3 stone blocks",
"\tremove stone from exploded blocks # will remove all stones blocks - 'any' and 'all' will do the same",
"\tadd blocks in radius 3 around event-location to exploded blocks",
"\tdelete exploded blocks # will clear exploded blocks",
"\t",
"on entity explode:",
"\tremove all stone from exploded blocks",
"\t",
"on explode:",
"\tremove all stone from exploded blocks"})
@Events("explode")
@Since("2.5")
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -68,13 +74,9 @@ public class ExprExplodedBlocks extends SimpleExpression<Block> {
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) {
if (getParser().isCurrentEvent(EntityExplodeEvent.class)) {
isEntity = true;
} else if (!getParser().isCurrentEvent(BlockExplodeEvent.class)) {
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
if (!getParser().isCurrentEvent(BlockExplodeEvent.class, EntityExplodeEvent.class)) {
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;
}
Expand All @@ -85,16 +87,24 @@ public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelaye
@Override
protected Block[] get(Event e) {
List<Block> blockList;
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
if (isEntity)

if (e instanceof EntityExplodeEvent) {
blockList = ((EntityExplodeEvent) e).blockList();
}

else
blockList = ((BlockExplodeEvent) e).blockList();

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



@Nullable
@Override
public Iterator<? extends Block> iterator(Event e) {
List<Block> blocks = e instanceof EntityExplodeEvent ? ((EntityExplodeEvent) e).blockList() : ((BlockExplodeEvent) e).blockList();
return new ArrayList(blocks).iterator();
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
}

@Override
@Nullable
public Class<?>[] acceptChange(final ChangeMode mode) {
Expand All @@ -115,66 +125,63 @@ public Class<?>[] acceptChange(final ChangeMode mode) {
@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)
if (e instanceof EntityExplodeEvent) {
blocks = ((EntityExplodeEvent) e).blockList();
}
else
blocks = ((BlockExplodeEvent) e).blockList();

switch (mode) {
case SET:
assert delta != null;
blocks.clear();
for (Object de : delta) {
if (de instanceof ItemType)
break;

if (((Block) de).getType() != Material.AIR) // Performance
blocks.add((Block) de);
}
break;

case DELETE:
blocks.clear();
break;

case SET:
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);
if (mode != ChangeMode.ADD)
blocks.clear();

for (Object o : delta) {
if (o instanceof ItemType)
continue;

if (((Block) o).getType() != Material.AIR) // Performance
blocks.add((Block) o);
}
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) {
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()) {
blocks.remove(b);
int amountReached = 0;

for (Object o : delta) {
if (o instanceof Block) {
blocks.remove((Block) o); // no need to check whether they are equals, since blocks are only passed by reference

} else if (o instanceof ItemType) {
ItemType item = ((ItemType) o);
int amount = item.getInternalAmount(); // -1 when using 'all' or 'any' of alias

if (amount == -1 || mode == ChangeMode.REMOVE_ALL) { // all %itemtype% OR REMOVE_ALL
blocks.removeIf(item::isOfType);
break;
}

else if (amount > 0)
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
for (Block b : new ArrayList<>(blocks)) {
if (amountReached >= amount)
break;
else if (item.isOfType(b)) {
blocks.remove(b);
amountReached++; // only ++ if a matched item was removed
}
}
}

} else {
blocks.removeIf(b -> b.equals((Block) de));
}
}
break;
}
}


@Override
public boolean isSingle() {
return false;
Expand All @@ -187,7 +194,7 @@ public Class<? extends Block> getReturnType() {

@Override
public String toString(@Nullable Event e, boolean d) {
return "exploded blocks";
return e instanceof EntityExplodeEvent ? "entity" : "block" + " event's exploded blocks";
AyhamAl-Ali marked this conversation as resolved.
Show resolved Hide resolved
}

}
Loading