Massive Action and Siege Functionality Update

This commit is contained in:
Laika 2022-04-24 02:28:50 -07:00
parent af28678d2a
commit 6e707442cf
11 changed files with 281 additions and 11 deletions

View File

@ -2,13 +2,11 @@ package moe.oko.opennaw;
import moe.oko.opennaw.command.CityCommand;
import moe.oko.opennaw.command.NationCommand;
import moe.oko.opennaw.listener.ActionListener;
import moe.oko.opennaw.util.*;
import net.luckperms.api.LuckPerms;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.dynmap.DynmapCommonAPI;
import org.dynmap.DynmapCommonAPIListener;
import org.dynmap.bukkit.DynmapPlugin;
import static moe.oko.opennaw.util.CommandHelper.info;
@ -16,7 +14,13 @@ public final class OpenNAW extends JavaPlugin {
public static OpenNAW instance;
public NationHandler nationHandler;
public ActionLogger actionLogger;
public CityHandler cityHandler;
public ConfigHelper configHelper;
public GroupHandler groupHandler;
private LuckPerms luckPerms;
@ -38,7 +42,9 @@ public final class OpenNAW extends JavaPlugin {
public void onEnable() {
// Initialize internals
instance = this;
configHelper = new ConfigHelper(this.getConfig());
this.luckPerms = getServer().getServicesManager().load(LuckPerms.class);
actionLogger = new ActionLogger();
nationHandler = new NationHandler();
cityHandler = new CityHandler();
groupHandler = new GroupHandler(this.luckPerms);
@ -49,6 +55,7 @@ public final class OpenNAW extends JavaPlugin {
this.getCommand("nation").setExecutor(new NationCommand());
this.getCommand("city").setExecutor(new CityCommand());
getServer().getPluginManager().registerEvents(new ChatHandler(), this);
getServer().getPluginManager().registerEvents(new ActionListener(), this);
if(Bukkit.getPluginManager().isPluginEnabled("dynmap")) {
this.dynmapEnabled = true;
@ -69,4 +76,12 @@ public final class OpenNAW extends JavaPlugin {
public DynmapHandler getDynmapHandler() {
return dynmapHandler;
}
public ActionLogger getActionLogger() {
return actionLogger;
}
public ConfigHelper getConfigHelper() {
return configHelper;
}
}

View File

@ -0,0 +1,31 @@
package moe.oko.opennaw.listener;
import moe.oko.opennaw.OpenNAW;
import moe.oko.opennaw.model.action.CityAttackAction;
import moe.oko.opennaw.model.action.CityDefenseAction;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
public class ActionListener implements Listener {
@EventHandler
public void onBlockInteract(PlayerInteractEvent event) {
if(event.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
//Right Click Logic
if(OpenNAW.getInstance().getCityHandler().isLocationAPoint(event.getClickedBlock().getLocation())) {
var city = OpenNAW.getInstance().getCityHandler().fetchCityViaPoint(event.getClickedBlock().getLocation());
if(!OpenNAW.getInstance().getNationHandler().isPlayerInNation(event.getPlayer(), city.getOwner())) {
//Player is not in nation and just clicked point, attempt our interaction.
OpenNAW.getInstance().getActionLogger().tryAction(new CityAttackAction(event.getPlayer(), city));
} else {
if(city.underSiege()) {
//Under siege, try to defend.
OpenNAW.getInstance().getActionLogger().tryAction(new CityDefenseAction(event.getPlayer(), city));
}
}
}
}
}
}

View File

@ -2,17 +2,18 @@ package moe.oko.opennaw.model;
import moe.oko.opennaw.OpenNAW;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.*;
public class City {
private String name;
private String resource;
private CityState state;
private Nation owner;
//Null until its needed.
private Nation attacker;
private Location point;
private short health;
@ -40,7 +41,6 @@ public class City {
public void setOwner(Nation nation) {
this.owner = nation;
capture();
}
public Location getPoint() {
@ -55,7 +55,62 @@ public class City {
this.health -= damage;
}
public boolean underSiege() {
return state.equals(CityState.SIEGE);
}
public void startSiege(Nation nation) {
state = CityState.SIEGE;
Bukkit.broadcast(Component.text(ChatColor.RED + nation.getName() + ChatColor.GOLD + " has begun a siege against the city of " + ChatColor.AQUA + getName()));
for(var player : Bukkit.getOnlinePlayers()) {
player.playSound(player.getLocation(), Sound.ITEM_TRIDENT_THUNDER, 1F, 1F);
}
attacker = nation;
}
public void damage() {
//Ran each time a city is damaged by a capture event
//Makes an explosion of ash around a block
point.getWorld().spawnParticle(Particle.ASH, point, 4000, .5, .5, .5);
point.getWorld().playSound(point, Sound.ENTITY_GENERIC_EXPLODE, 1F, 1F);
health = (short) (health - OpenNAW.getInstance().getConfigHelper().cityDamageOnStrike());
switch (health) {
case 250:
case 200:
case 150:
case 100:
case 50:
for(var player : Bukkit.getOnlinePlayers()) {
if(player.getLocation().distance(point) < 100) {
player.sendMessage(ChatColor.BOLD + "" + ChatColor.RED + "THE CITY HAS FALLEN TO " + health + " HEALTH...");
}
}
case 10:
for(var player : Bukkit.getOnlinePlayers()) {
if(player.getLocation().distance(point) < 100) {
player.sendMessage(ChatColor.BOLD + "" + ChatColor.RED + "THE CITY IS ABOUT TO BE CAPTURED!");
}
}
}
if(health == 0 || health < 0) {
capture();
}
}
public void defend() {
//successful defense logic.
Bukkit.broadcast(Component.text(ChatColor.RED + attacker.getName() + ChatColor.GOLD + "'s siege against the city of "
+ ChatColor.AQUA + getName() + ChatColor.GOLD + " has " + ChatColor.RED + "failed"));
if(health < 250) {
health = (short) (health + 50);
}
OpenNAW.getInstance().getActionLogger().cancelDefenseActions(this);
attacker = null;
}
public void capture() {
setOwner(attacker);
attacker = null; //reset to null so there isn't any bugs
//This is our "capture" logic. So now we do shenanigans.
if(OpenNAW.getInstance().isDynmapEnabled()) {
//Dyn is enabled, we need to do setters.

View File

@ -2,6 +2,10 @@ package moe.oko.opennaw.model;
import net.luckperms.api.model.group.Group;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import java.util.HashMap;
import java.util.UUID;
public class Nation {
public static final Nation UNCLAIMED = new Nation("UNCLAIMED", null);
@ -10,16 +14,28 @@ public class Nation {
private Group group;
private Location spawn;
private HashMap<UUID, OfflinePlayer> players;
//The icon used for cities owned by this nation (default is a tower)
private String dynmapIcon;
public Nation(String name, Group group) {
this.name = name;
this.group = group;
this.players = new HashMap<>();
this.dynmapIcon = "tower";
this.spawn = null;
}
//Db Constructor
public Nation(String name, Group group, HashMap<UUID, OfflinePlayer> players, String dynmapIcon, Location spawn) {
this.name = name;
this.group = group;
this.players = players;
this.dynmapIcon = dynmapIcon;
this.spawn = spawn;
}
public String getName() { return name; }
public Group getGroup() { return group; }
public Location getSpawn() { return spawn; }
@ -31,6 +47,10 @@ public class Nation {
return dynmapIcon;
}
public HashMap<UUID, OfflinePlayer> getPlayerMap() {
return players;
}
public void setDynmapIcon(String dynmapIcon) {
this.dynmapIcon = dynmapIcon;
}

View File

@ -1,12 +1,19 @@
package moe.oko.opennaw.model.action;
import moe.oko.opennaw.OpenNAW;
import moe.oko.opennaw.model.City;
import moe.oko.opennaw.model.Nation;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.Sound;
public class CityAttackAction extends Action{
public static final long DELAY = 10000L;
public OfflinePlayer player;
public City city;
public OfflinePlayer getPlayer() {
return player;
}
@ -14,9 +21,23 @@ public class CityAttackAction extends Action{
public CityAttackAction(OfflinePlayer player, City city) {
this.timeOfAction = System.currentTimeMillis();
this.player = player;
this.city = city;
}
public void initiation() {
if(!city.underSiege()) {
var nation = OpenNAW.getInstance().getNationHandler().getNationByPlayer(player.getUniqueId());
//Initiate siege.
city.startSiege(nation);
}
city.getPoint().getWorld().playSound(city.getPoint(), Sound.ENTITY_FIREWORK_ROCKET_BLAST, 1, 1);
}
public void completion() {
//Completion logic...
if(!player.isOnline()) { return; }
var online = player.getPlayer();
online.sendMessage(ChatColor.GREEN + "Action Completed");
city.damage();
}
}

View File

@ -0,0 +1,40 @@
package moe.oko.opennaw.model.action;
import moe.oko.opennaw.OpenNAW;
import moe.oko.opennaw.model.City;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
public class CityDefenseAction extends Action {
//60 seconds for defense action
public static final long DELAY = 60000L;
public OfflinePlayer player;
public City city;
public CityDefenseAction(OfflinePlayer player, City city) {
this.timeOfAction = System.currentTimeMillis();
this.player = player;
this.city = city;
}
public void initiation() {
for(var player : Bukkit.getOnlinePlayers()) {
if(player.getLocation().distance(city.getPoint()) < 100) {
player.sendMessage(ChatColor.RED + "" + ChatColor.BOLD + player.getName() + " HAS STARTED DEFENDING THE POINT.");
}
}
}
public void completion() {
city.defend();
}
public OfflinePlayer getPlayer() {
return player;
}
}

View File

@ -1,9 +1,12 @@
package moe.oko.opennaw.util;
import moe.oko.opennaw.OpenNAW;
import moe.oko.opennaw.model.City;
import moe.oko.opennaw.model.action.Action;
import moe.oko.opennaw.model.action.CityAttackAction;
import moe.oko.opennaw.model.action.CityDefenseAction;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import java.util.HashMap;
import java.util.UUID;
@ -21,8 +24,10 @@ public class ActionLogger {
CityAttackAction CAA = (CityAttackAction) action;
if (actionByUuid.containsKey(CAA.getPlayer().getUniqueId())) {
actionByUuid.remove(CAA.getPlayer().getUniqueId());
CAA.getPlayer().getPlayer().sendMessage(ChatColor.YELLOW + "Action switched.");
}
actionByUuid.put(CAA.getPlayer().getUniqueId(), action);
CAA.initiation(); //Code to run when action started.
Bukkit.getScheduler().scheduleSyncDelayedTask(OpenNAW.getInstance(), () -> {
var actionCallback = actionByUuid.get(CAA.getPlayer().getUniqueId());
if (!actionCallback.isCancelled()) {
@ -33,10 +38,42 @@ public class ActionLogger {
return true;
}
return false;
} else if(action instanceof CityDefenseAction) {
if(enoughTimeElapsed(action.timeOfAction, CityDefenseAction.DELAY)) {
CityDefenseAction CDA = (CityDefenseAction) action;
if (actionByUuid.containsKey(CDA.getPlayer().getUniqueId())) {
actionByUuid.remove(CDA.getPlayer().getUniqueId());
CDA.getPlayer().getPlayer().sendMessage(ChatColor.YELLOW + "Action switched.");
}
actionByUuid.put(CDA.getPlayer().getUniqueId(), action);
CDA.initiation(); //Code to run when action started.
Bukkit.getScheduler().scheduleSyncDelayedTask(OpenNAW.getInstance(), () -> {
var actionCallback = actionByUuid.get(CDA.getPlayer().getUniqueId());
if (!actionCallback.isCancelled()) {
CDA.completion();
}
actionByUuid.remove(CDA.getPlayer().getUniqueId());
}, CityDefenseAction.DELAY);
return true;
}
}
return false;
}
public void cancelDefenseActions(City city) {
for(var action : actionByUuid.values()) {
if(action instanceof CityDefenseAction) {
var cda = (CityDefenseAction) action;
if(cda.city == city) {
if(cda.getPlayer().isOnline()) {
cda.getPlayer().getPlayer().sendMessage(ChatColor.RED + "Action failed.");
}
cda.setCancelled(true);
}
}
}
}
private boolean enoughTimeElapsed(long timestamp, long delay) {
return (System.currentTimeMillis() - timestamp) > delay;
}

View File

@ -21,6 +21,24 @@ public class CityHandler {
public void setCityOwner(City city, Nation nation) { cities.get(city.getName()).setOwner(nation); }
public boolean isLocationAPoint(Location loc) {
for(City cty : cities.values()) {
if(cty.getPoint().equals(loc)) {
return true;
}
}
return false;
}
public City fetchCityViaPoint(Location location) {
for(City cty : cities.values()) {
if(cty.getPoint().equals(location)) {
return cty;
}
}
return null;
}
public List<String> getCityList() {
List<String> cityList = new ArrayList<String>();
for (City city : cities.values()) {

View File

@ -0,0 +1,16 @@
package moe.oko.opennaw.util;
import org.bukkit.configuration.Configuration;
public class ConfigHelper {
private Configuration config;
public ConfigHelper(Configuration config) {
this.config = config;
}
//Damage a city takes when a point is striked
public int cityDamageOnStrike() {
return config.getConfigurationSection("city").getInt("damageOnStrike");
}
}

View File

@ -2,10 +2,12 @@ package moe.oko.opennaw.util;
import moe.oko.opennaw.model.Nation;
import net.luckperms.api.model.group.Group;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
public class NationHandler {
@ -23,6 +25,19 @@ public class NationHandler {
return nations.get(name).getGroup();
}
public boolean isPlayerInNation(Player player, Nation nation) {
return nation.getPlayerMap().containsKey(player.getUniqueId());
}
public Nation getNationByPlayer(UUID uuid) {
for(var nation : nations.values()) {
if(nation.getPlayerMap().containsKey(uuid)) {
return nation;
}
}
return null;
}
public List<String> getNationList() {
List<String> nationList = new ArrayList<String>();
for (Nation nation : nations.values()) {

View File

@ -1,2 +1,4 @@
# OpenNAW Configuration
city:
#The amount of damage a city takes on the point being striked
damageOnStrike: 5