-
Notifications
You must be signed in to change notification settings - Fork 2
Introduction to Game Mode Development
AthenaGM's core principle is to do as much as possible to cover functionality shared by many game modes, while employing a modular philosophy to game mode specific logic. Each game mode is implemented as a separate Bukkit plugin that shares AthenaGM's Events and public class APIs. So if you want a King of the Hill game, you need to implement that specific gameplay in a plugin that works with AthenaGM.
This guide will illustrate the basics of developing a game mode plugin for AthenaGM, using the very simple example of "Sponge King" as an example. The goal: build a game mode where one team wins if they place ten sponge blocks on top of a beacon before the other team can.
- Starting Your Plugin
This guide assumes that you already are familiar with Bukkit plugin development and have already set up a basic skeleton project. Once you have your SpongeKing project created, you'll need to add AthenaGM as a Maven dependency in your pom.xml:
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.9-R0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.github.redwallhp</groupId>
<artifactId>AthenaGM</artifactId>
<version>1.0.4</version>
</dependency>
</dependencies>
You'll first have to check out the AthenaGM source, and then build and install it so Maven can find the dependency. Only then will your plugin build.
git clone https://github.com/redwallhp/AthenaGM.git
cd AthenaGM
mvn clean package
mvn install
- Basic Plugin Structure
A game mode plugin has two important responsibilities:
- It must check to see if AthenaGM is running, and safely not do anything if that check fails.
- It must ensure, in every Bukkit event it listens to, that it only applies its custom logic in a Match with the game mode name specific to the plugin. (Maps define a
gamemode
key that determines which game mode plugin should spring into action to handle the Match created from the Map.)
Here is an example of a basic plugin class:
public class SpongeKing extends JavaPlugin {
AthenaGM athena;
@Override
public void onEnable() {
if (checkAthena()) {
new SpongeListener(this);
}
}
/**
* Load the server's AthenaGM instance, returning false if AthenaGM is not installed.
* @return true if AthenaGM is installed and active, false otherwise
*/
private boolean checkAthena() {
Plugin plugin = getServer().getPluginManager().getPlugin("AthenaGM");
if (plugin == null || !(plugin instanceof AthenaGM)) {
this.setEnabled(false);
return false;
} else {
athena = (AthenaGM) plugin;
return true;
}
}
/**
* Get the server's AthenaGM instance
* @return AthenaGM instance
*/
public AthenaGM getAthena() {
return athena;
}
}
- Example Listener Class
This example class illustrates the use of AthenaGM events and methods, including safety checks to ensure that we're not operating on an event from a different Match.
Using a regular BlockPlaceEvent, we increment a team's score every time they place a sponge block. At the end of the Match, Athena will declare a winner based on this score.
public class SpongeListener implements Listener {
private AthenaKOTH plugin;
public KOTHListener(AthenaKOTH plugin) {
this.plugin = plugin;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void onMatchCreate(MatchCreateEvent event) {
if (!isSK(event.getMatch())) return; //return early if this isn't a Sponge King Match
//do any setup needed here
}
@EventHandler
public void onMatchStateChanged(MatchStateChangedEvent event) {
if (!isSK(event.getMatch())) return;
if (event.getCurrentState().equals(MatchState.ENDED)) {
//do end of match things and clean up any objects we won't need after this Match
}
}
@EventHandler
public void onBlockPlace(BlockPlaceEvent event) {
if (!isSK(event.getMatch())) return;
if (event.getItemInHand().getType().equals(Material.SPONGE)) {
Team playerTeam = PlayerUtil.getTeamForPlayer(plugin.getAthena().getArenaHandler(), event.getPlayer());
PlayerScorePointEvent event = new PlayerScorePointEvent(event.getPlayer(), playerTeam, 1);
Bukkit.getPluginManager().callEvent(event);
}
}
/**
* Check if a given Match/Map is calling for a KOTH gamemode
* @param match The Match to check
*/
private boolean isSK(Match match) {
return (match.getMap().getGameMode().equalsIgnoreCase("spongeking"));
}
/**
* Check if a given Player is in a Match/Map calling for a KOTH gamemode
* @param player The Player to check
*/
private boolean isSK(Player player) {
Arena arena = PlayerUtil.getArenaForPlayer(plugin.getAthena().getArenaHandler(), player);
return (arena != null && isSK(arena.getMatch()));
}
}