Skip to content

Commit

Permalink
new event: block destroyed by explosion
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Aug 30, 2021
1 parent 0205859 commit b360aeb
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 16 deletions.
Expand Up @@ -29,6 +29,7 @@ public static void registerMainEvents() {
// Block events
ScriptEvent.registerScriptEvent(new BlockBuiltScriptEvent());
ScriptEvent.registerScriptEvent(new BlockBurnsScriptEvent());
ScriptEvent.registerScriptEvent(new BlockDestroyedByExplosionEvent());
ScriptEvent.registerScriptEvent(new BlockDispensesScriptEvent());
ScriptEvent.registerScriptEvent(new BlockExplodesScriptEvent());
ScriptEvent.registerScriptEvent(new BlockFadesScriptEvent());
Expand Down
@@ -0,0 +1,129 @@
package com.denizenscript.denizen.events.block;

import com.denizenscript.denizen.events.BukkitScriptEvent;
import com.denizenscript.denizen.objects.EntityTag;
import com.denizenscript.denizen.objects.LocationTag;
import com.denizenscript.denizencore.objects.ObjectTag;
import com.denizenscript.denizencore.objects.core.ElementTag;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockExplodeEvent;
import org.bukkit.event.entity.EntityExplodeEvent;

import java.util.ArrayList;
import java.util.List;

public class BlockDestroyedByExplosionEvent extends BukkitScriptEvent implements Listener {

// <--[event]
// @Events
// block destroyed by explosion
// <block> destroyed by explosion
//
// @Regex ^on [^\s]+ destroyed by explosion$
//
// @Group Block
//
// @Location true
//
// @Cancellable true
//
// @Warning This event fires extremely rapidly. One single TNT detonation can destroy a hundred blocks.
//
// @Triggers when a block is destroyed by an explosion (caused by either an entity or a block exploding).
//
// @Switch source_entity:<matcher> to only fire the event if the source is an entity that matches the given type. Note that "Primed_Tnt" is an entity, not a block.
// @Switch source_block:<matcher> to only fire the event if the source is a block that matches the given type.
//
// @Context
// <context.block> returns the block that exploded.
// <context.source_location> returns the location of the source block or entity.
// <context.source_entity> returns the entity that exploded, if any.
// <context.strength> returns an ElementTag(Decimal) of the strength of the explosion.
//
// -->

public BlockDestroyedByExplosionEvent() {
instance = this;
}

public static BlockDestroyedByExplosionEvent instance;
public BlockExplodeEvent blockEvent;
public EntityExplodeEvent entityEvent;
public Block block;
public List<Block> rawList;

@Override
public boolean couldMatch(ScriptPath path) {
if (!path.eventArgLowerAt(1).equals("destroyed") || !path.eventArgLowerAt(2).equals("by") || !path.eventArgLowerAt(3).equals("explosion")) {
return false;
}
if (!couldMatchBlock(path.eventArgLowerAt(0))) {
return false;
}
return true;
}

@Override
public boolean matches(ScriptPath path) {
if (!tryMaterial(block.getType(), path.eventArgLowerAt(0))) {
return false;
}
if (!runInCheck(path, block.getLocation())) {
return false;
}
if (path.switches.containsKey("source_entity") && (entityEvent == null || !tryEntity(new EntityTag(entityEvent.getEntity()), path.switches.get("source_entity")))) {
return false;
}
if (path.switches.containsKey("source_block") && (blockEvent == null || !tryMaterial(blockEvent.getBlock().getType(), path.switches.get("source_block")))) {
return false;
}
return super.matches(path);
}

@Override
public String getName() {
return "BlockDestroyedByExplosion";
}

@Override
public ObjectTag getContext(String name) {
switch (name) {
case "block": return new LocationTag(block.getLocation());
case "source_location": return new LocationTag(blockEvent != null ? blockEvent.getBlock().getLocation() : entityEvent.getLocation());
case "source_entity": return entityEvent == null ? null : new EntityTag(entityEvent.getEntity());
case "strength": return new ElementTag(blockEvent != null ? blockEvent.getYield() : entityEvent.getYield());
default: return super.getContext(name);
}
}

@Override
public void cancellationChanged() {
if (cancelled) {
rawList.remove(block);
}
}

@EventHandler
public void onBlockExplodes(BlockExplodeEvent event) {
this.blockEvent = event;
this.entityEvent = null;
this.rawList = event.blockList();
for (Block block : new ArrayList<>(rawList)) {
this.block = block;
fire(event);
}
}

@EventHandler
public void onEntityExplodes(EntityExplodeEvent event) {
this.entityEvent = event;
this.blockEvent = null;
this.rawList = event.blockList();
for (Block block : new ArrayList<>(rawList)) {
this.block = block;
fire(event);
}
}
}
Expand Up @@ -2,7 +2,6 @@

import com.denizenscript.denizen.events.BukkitScriptEvent;
import com.denizenscript.denizen.objects.LocationTag;
import com.denizenscript.denizen.objects.MaterialTag;
import com.denizenscript.denizen.utilities.debugging.Debug;
import com.denizenscript.denizencore.objects.ArgumentHelper;
import com.denizenscript.denizencore.objects.ObjectTag;
Expand Down Expand Up @@ -30,10 +29,11 @@ public class BlockExplodesScriptEvent extends BukkitScriptEvent implements Liste
//
// @Cancellable true
//
// @Triggers when a block explodes (like a bed in the nether. For TNT, refer to the "entity explodes" event instead).
// @Triggers when a block explodes (like a bed in the nether. For TNT, refer to the "entity explodes" event instead). For a block being destroyed by an explosion, refer to the "block destroyed by explosion" event instead.
//
// @Context
// <context.blocks> returns a ListTag of blocks that the entity blew up.
// <context.block> returns the location of the exploding block.
// <context.blocks> returns a ListTag of blocks that blew up.
// <context.strength> returns an ElementTag(Decimal) of the strength of the explosion.
//
// @Determine
Expand Down Expand Up @@ -63,20 +63,10 @@ public boolean couldMatch(ScriptPath path) {

@Override
public boolean matches(ScriptPath path) {
String target = path.eventArgLowerAt(0);
if (!target.equals("block")) {
boolean matched = false;
for (Block block : blocks) {
if (tryMaterial(new MaterialTag(block.getType()), target)) {
matched = true;
break;
}
}
if (!matched) {
return false;
}
if (!tryMaterial(event.getBlock().getType(), path.eventArgAt(0))) {
return false;
}
if (blocks.size() > 0 && !runInCheck(path, blocks.get(0).getLocation())) {
if (!runInCheck(path, event.getBlock().getLocation())) {
return false;
}
return super.matches(path);
Expand Down Expand Up @@ -112,6 +102,9 @@ public boolean applyDetermination(ScriptPath path, ObjectTag determinationObj) {

@Override
public ObjectTag getContext(String name) {
if (name.equals("block")) {
return new LocationTag(event.getBlock().getLocation());
}
if (name.equals("blocks")) {
ListTag blocks = new ListTag();
for (Block block : this.blocks) {
Expand Down
Expand Up @@ -64,6 +64,9 @@ else if (cmd.equals("destroyed")) {
if (!exactMatchesVehicle(path.eventArgLowerAt(0))) {
return false;
}
if (path.eventArgLowerAt(2).equals("by")) {
return false;
}
}
else {
return false;
Expand Down

0 comments on commit b360aeb

Please sign in to comment.