Skip to content

Commit

Permalink
Add new spleef gamemodes
Browse files Browse the repository at this point in the history
  • Loading branch information
Redned235 committed Jul 3, 2024
1 parent 2b3be1f commit 7e9e729
Show file tree
Hide file tree
Showing 20 changed files with 551 additions and 120 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@

A spleef plugin using [BattleArena](https://github.com/BattlePlugins/BattleArena)

ArenaSpleef is the classic spleef plugin that dates back to the early days of Minecraft. Players are given a shovel and must break blocks under other players to make them fall into the void. The last player standing wins!
ArenaSpleef is the classic spleef plugin that dates back to the early days of Minecraft, but features multiple modes!

## Spleef Modes
- **Classic**: The classic spleef mode where players are given a shovel to break blocks and knock other players into the void.
- **Splegg**: A spleef mode where players are given an egg cannon to shoot eggs at the ground to break blocks.
- **Decay**: A spleef mode where blocks decay underneath the player. This is commonly played as "TNT Run", but any block can be used.
- **Bow Spleef**: A spleef mode where players are given a bow to shoot arrows at the ground to break blocks.

## Documentation
Full documentation for ArenaSpleef can be found on the [BattleDocs](https://docs.battleplugins.org/books/additional-gamemodes/chapter/spleef) website.

## Commands
| Command | Description |
|---------------------------------------|------------------------------------------------|
| /spleef deathregion <map> <region> | Sets the death region for a spleef arena. |
| /spleef layer add <map> | Adds a layer to a spleef arena. |
| /spleef layer remove <map> <index> | Removes a layer from a spleef arena. |
| /spleef layer clear <map> | Clears all layers from a spleef arena. |
Expand All @@ -19,6 +26,7 @@ Full documentation for ArenaSpleef can be found on the [BattleDocs](https://docs
## Permissions
| Permission | Command |
|-----------------------------------------|----------------------|
| battlearena.command.spleef.deathregion | /spleef deathregion |
| battlearena.command.spleef.layer.add | /spleef layer add |
| battlearena.command.spleef.layer.remove | /spleef layer remove |
| battlearena.command.spleef.layer.clear | /spleef layer clear |
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/org/battleplugins/arena/spleef/ArenaSpleef.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import org.battleplugins.arena.config.ArenaConfigParser;
import org.battleplugins.arena.config.ParseException;
import org.battleplugins.arena.event.action.EventActionType;
import org.battleplugins.arena.spleef.action.GiveShovelAction;
import org.battleplugins.arena.spleef.action.PasteLayersAction;
import org.battleplugins.arena.spleef.arena.SpleefArena;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.Configuration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
Expand All @@ -13,13 +17,16 @@
import java.nio.file.Path;

public class ArenaSpleef extends JavaPlugin {

public static EventActionType<GiveShovelAction> GIVE_SHOVEL = EventActionType.create("give-shovel", GiveShovelAction.class, GiveShovelAction::new);
public static EventActionType<PasteLayersAction> PASTE_LAYERS = EventActionType.create("paste-layers", PasteLayersAction.class, PasteLayersAction::new);

private static ArenaSpleef instance;

private SpleefConfig config;

private final NamespacedKey spleefItemKey = new NamespacedKey(this, "spleef_item");

@Override
public void onEnable() {
instance = this;
Expand Down Expand Up @@ -51,6 +58,10 @@ public SpleefConfig getMainConfig() {
return this.config;
}

public NamespacedKey getSpleefItemKey() {
return this.spleefItemKey;
}

public static ArenaSpleef getInstance() {
return instance;
}
Expand Down
81 changes: 0 additions & 81 deletions src/main/java/org/battleplugins/arena/spleef/SpleefArena.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ public class SpleefConfig {

@Nullable
public ItemStack getShovel(String name) {
return this.shovels == null ? null : this.shovels.get(name);
return this.shovels == null ? null : this.shovels.get(name).clone();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package org.battleplugins.arena.spleef;

import com.destroystokyo.paper.event.entity.ThrownEggHatchEvent;
import org.battleplugins.arena.ArenaPlayer;
import org.battleplugins.arena.BattleArena;
import org.battleplugins.arena.competition.Competition;
import org.battleplugins.arena.competition.LiveCompetition;
import org.battleplugins.arena.event.ArenaEventHandler;
import org.battleplugins.arena.spleef.arena.SpleefArena;
import org.battleplugins.arena.spleef.arena.SpleefCompetition;
import org.battleplugins.arena.spleef.arena.SpleefGame;
import org.bukkit.entity.Egg;
import org.bukkit.entity.Player;
import org.bukkit.event.block.TNTPrimeEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.projectiles.ProjectileSource;

import java.util.List;
import java.util.function.Function;

/**
* Contains custom event resolvers for Spleef events.
* <p>
* The events below would normally not be captured by the
* {@link ArenaEventHandler} annotation since there is no default
* logic for them to link back to a {@link Competition}. However,
* these custom resolvers allow for these events to be listened
* on, along with segmenting the logic to the appropriate arena
* and spleef game mode.
*/
public final class SpleefEventResolvers {

public static final Function<ProjectileHitEvent, LiveCompetition<?>> PROJECTILE_HIT = event -> {
if (!(event.getEntity() instanceof Egg egg)) {
return null;
}

if (event.getHitBlock() == null) {
return null;
}

if (!egg.hasMetadata("splegg")) {
return null;
}

ProjectileSource shooter = egg.getShooter();
if (!(shooter instanceof Player player)) {
return null;
}

ArenaPlayer arenaPlayer = ArenaPlayer.getArenaPlayer(player);
if (arenaPlayer == null || !(arenaPlayer.getArena() instanceof SpleefArena)) {
return null;
}

return arenaPlayer.getCompetition();
};

public static final Function<ThrownEggHatchEvent, LiveCompetition<?>> THROWN_EGG_HATCH = event -> {
if (!event.getEgg().hasMetadata("splegg")) {
return null;
}

ProjectileSource shooter = event.getEgg().getShooter();
if (!(shooter instanceof Player player)) {
return null;
}

ArenaPlayer arenaPlayer = ArenaPlayer.getArenaPlayer(player);
if (arenaPlayer == null || !(arenaPlayer.getArena() instanceof SpleefArena)) {
return null;
}

return arenaPlayer.getCompetition();
};

public static final Function<SpleefArena, Function<TNTPrimeEvent, LiveCompetition<?>>> TNT_PRIME = arena -> event -> {
if (arena.getGame() != SpleefGame.BOW_SPLEEF) {
return null;
}

List<Competition<?>> competitions = BattleArena.getInstance().getCompetitions(arena);
for (Competition<?> competition : competitions) {
if (!(competition instanceof SpleefCompetition spleefCompetition)) {
continue;
}

if (!spleefCompetition.getMap().getWorld().equals(event.getBlock().getWorld())) {
continue;
}

if (spleefCompetition.getMap().getBounds() != null && spleefCompetition.getMap().getBounds().isInside(event.getBlock().getLocation())) {
return spleefCompetition;
}
}

return null;
};
}
11 changes: 11 additions & 0 deletions src/main/java/org/battleplugins/arena/spleef/SpleefExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import org.battleplugins.arena.command.Argument;
import org.battleplugins.arena.competition.map.CompetitionMap;
import org.battleplugins.arena.competition.map.options.Bounds;
import org.battleplugins.arena.spleef.arena.SpleefArena;
import org.battleplugins.arena.spleef.arena.SpleefMap;
import org.battleplugins.arena.spleef.editor.SpleefEditorWizards;
import org.bukkit.entity.Player;

Expand Down Expand Up @@ -97,4 +99,13 @@ public void listLayers(Player player, CompetitionMap map) {
SpleefMessages.LAYER_INFO.send(player, Integer.toString(i + 1), minBounds, maxBounds, layer.getBlockData().getAsString());
}
}

@ArenaCommand(commands = "deathregion", description = "Sets the death region for a spleef arena.", permissionNode = "deathregion")
public void setDeathRegion(Player player, CompetitionMap map) {
if (!(map instanceof SpleefMap spleefMap)) {
return; // Should not happen but just incase
}

SpleefEditorWizards.DEATH_REGION.openWizard(player, this.arena, ctx -> ctx.setMap(spleefMap));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ public final class SpleefMessages {
public static final Message LAYER_SET_MAX_POSITION = Messages.info("spleef-editor-layer-set-max-position", "Click a block to set the maximum (second) position of the layer.");
public static final Message LAYER_SET_BLOCK_DATA = Messages.info("spleef-editor-set-block-data", "Enter the name of the block the layer should be made of. Type \"cancel\" to cancel.");
public static final Message LAYER_SET_BLOCK_DATA_INVALID = Messages.error("spleef-set-block-data-invalid", "Invalid block name. Please try again.");
public static final Message DEATH_REGION_SET_MIN_POSITION = Messages.info("spleef-editor-death-region-set-min-position", "Click a block to set the minimum (first) position of the death region.");
public static final Message DEATH_REGION_SET_MAX_POSITION = Messages.info("spleef-editor-death-region-set-max-position", "Click a block to set the maximum (second) position of the death region.");

public static final Message LAYER_ADDED = Messages.success("spleef-layer-added", "Layer added successfully!");
public static final Message LAYER_REMOVED = Messages.success("spleef-layer-removed", "Layer removed successfully!");
Expand All @@ -16,4 +18,5 @@ public final class SpleefMessages {
public static final Message LAYER_INFO = Messages.info("spleef-layer-info", "Layer <secondary>#{}</secondary>: <secondary>Min:</secondary> <primary>{}</primary>, <secondary>Max:</secondary> <primary>{}</primary>, <secondary>Block:</secondary> <primary>{}</primary>");
public static final Message INVALID_LAYER = Messages.error("spleef-invalid-layer", "Invalid layer! There are only <secondary>{}</secondary> layers.");
public static final Message NO_LAYERS = Messages.error("spleef-no-layers", "There are no layers in this map!");
public static final Message DEATH_REGION_SET = Messages.success("spleef-death-region-set", "Death region set successfully!");
}
40 changes: 40 additions & 0 deletions src/main/java/org/battleplugins/arena/spleef/SpleefUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.battleplugins.arena.spleef;

import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.util.NumberConversions;

public final class SpleefUtil {

public static Block getBlockUnderPlayer(int y, Location location) {
Location loc = location.clone();
loc.setY(y);

double boxWidth = 0.3;
Block block1 = getBlock(loc, +boxWidth, -boxWidth);
if (!block1.getType().isAir()) {
return block1;
}

Block block2 = getBlock(loc, -boxWidth, +boxWidth);
if (!block2.getType().isAir()) {
return block2;
}

Block block3 = getBlock(loc, +boxWidth, +boxWidth);
if (!block3.getType().isAir()) {
return block3;
}

Block block4 = getBlock(loc, -boxWidth, -boxWidth);
if (!block4.getType().isAir()) {
return block4;
}

return null;
}

private static Block getBlock(Location loc, double x, double z) {
return loc.getWorld().getBlockAt(NumberConversions.floor(loc.getX() + x), loc.getBlockY(), NumberConversions.floor(loc.getZ() + z));
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package org.battleplugins.arena.spleef;
package org.battleplugins.arena.spleef.action;

import org.battleplugins.arena.ArenaPlayer;
import org.battleplugins.arena.event.action.EventAction;
import org.battleplugins.arena.spleef.ArenaSpleef;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;

import java.util.Map;

Expand All @@ -21,6 +23,7 @@ public void call(ArenaPlayer arenaPlayer) {
return;
}

shovel.editMeta(meta -> meta.getPersistentDataContainer().set(ArenaSpleef.getInstance().getSpleefItemKey(), PersistentDataType.BOOLEAN, true));
arenaPlayer.getPlayer().getInventory().addItem(shovel);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package org.battleplugins.arena.spleef;
package org.battleplugins.arena.spleef.action;

import org.battleplugins.arena.Arena;
import org.battleplugins.arena.ArenaPlayer;
import org.battleplugins.arena.competition.Competition;
import org.battleplugins.arena.event.action.EventAction;
import org.battleplugins.arena.spleef.arena.SpleefCompetition;

import java.util.Map;

Expand Down
Loading

0 comments on commit 7e9e729

Please sign in to comment.