Skip to main content

Adding Game Logic

Now that you have a basic understanding of how the event system works, along with a base to work off of. It's time to implement some game logic!

Game logic can be implemented in two places: the Arena, or your Competition class. While we do not have a Competition class yet, it is typically recommended to leave most code inside of your Arena class, with a custom Competition class being responsible for storing values that change throughout the game (i.e. the number of blocks broken). We will get to this later.

Using Events

Going from our previous example of a grace period, let's add some listeners to make this functional!

public class MyArena extends Arena {
    private static final String INFECTED_METADATA = "infected";

    @ArenaOption(name = "infection-time", description = "How long a player should be infected once hit.")
    private Duration infectionTime = Duration.ofSeconds(5);

    @ArenaEventHandler
    public void onDamageEntity(EntityDamageByEntityEvent event) {
        if (event.getDamager() instanceof Player damager && event.getEntity() instanceof Player player) {
            // Player is not infected, let's infect them :)
            if (!player.hasMetadata(INFECTED_METADATA)) {
                player.setMetadata(INFECTED_METADATA, new FixedMetadataValue(MyPlugin.getInstance(), true));
                player.sendMessage("You have been infected!");
                damager.sendMessage("You have infected " + player.getName() + "!");

                // Infect the player for the given duration
                Bukkit.getScheduler().runTaskLater(MyPlugin.getInstance(), () -> {
                    player.removeMetadata(INFECTED_METADATA, MyPlugin.getInstance());
                    player.sendMessage("You are no longer infected!");
                }, this.infectionTime.toMillis() / 50);
            }
        }
    }

    @ArenaEventHandler
    public void onMove(PlayerMoveEvent event) {
        if (event.getPlayer().hasMetadata(INFECTED_METADATA)) {
            event.getPlayer().sendMessage("You are infected! You cannot move!");
            event.setCancelled(true);
        }
    }
}

In this example, if a player is hit by another player while in a MyArena, they will be "infected" for a short period of time. The duration for which they are infected is pulled from the infectionTime variable specified in your arena YML. While this is a very simple example, it demonstrates how to use the event system in BattleArena.

Up next is creating a custom map and competition class, which will further extend the functionality above.