@@ -17,8 +17,8 @@
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
<properties>
|
||||
<maven.compiler.source>25</maven.compiler.source>
|
||||
<maven.compiler.target>25</maven.compiler.target>
|
||||
<maven.compiler.source>26</maven.compiler.source>
|
||||
<maven.compiler.target>26</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<repositories>
|
||||
@@ -59,6 +59,15 @@
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.15.0</version>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.46</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
+3
-1
@@ -1,7 +1,8 @@
|
||||
package com.softwarerat.API.data;
|
||||
package com.softwarerat.API;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
@@ -34,6 +35,7 @@ public class GameData {
|
||||
public GameData(GameAPI gameapi) {
|
||||
this.gameapi = gameapi;
|
||||
this.gameStateManager = new GameStateManager();
|
||||
this.scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
|
||||
}
|
||||
|
||||
public String getGameHost(JavaPlugin javaPlugin){
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.softwarerat.API.data.entity;
|
||||
|
||||
import com.softwarerat.API.data.store.Flag;
|
||||
|
||||
public interface EntityFlag extends Flag {
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.softwarerat.API.data.entity;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
// Registry of EntityFlagHolders keyed by entity UUID, usable for NPCs and any other entity
|
||||
public class EntityFlagAPI {
|
||||
private final Map<UUID, EntityFlagHolder> holders = new ConcurrentHashMap<>();
|
||||
|
||||
public EntityFlagHolder get(Entity entity) {
|
||||
return this.holders.computeIfAbsent(entity.getUniqueId(), id -> new EntityFlagHolder(entity));
|
||||
}
|
||||
|
||||
public void setFlag(Entity entity, EntityFlag flag) {
|
||||
get(entity).setFlag(flag);
|
||||
}
|
||||
|
||||
public void removeFlag(Entity entity, EntityFlag flag) {
|
||||
get(entity).removeFlag(flag);
|
||||
}
|
||||
|
||||
public boolean hasFlag(Entity entity, EntityFlag... flags) {
|
||||
return get(entity).hasFlag(flags);
|
||||
}
|
||||
|
||||
public void clear(Entity entity) {
|
||||
this.holders.remove(entity.getUniqueId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.softwarerat.API.data.entity;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import com.softwarerat.API.data.store.CacheManager;
|
||||
import com.softwarerat.API.data.store.FlagManager;
|
||||
|
||||
// Per-entity flag storage. Unlike GamePlayer's single current PlayerFlag, entities
|
||||
// may carry several flags at once (e.g. NPC + PROTECTED + INTERACTABLE).
|
||||
public class EntityFlagHolder extends CacheManager implements FlagManager<EntityFlag> {
|
||||
private static final String FLAGS_KEY = "__flags__";
|
||||
|
||||
private final Entity entity;
|
||||
|
||||
public EntityFlagHolder(Entity entity) {
|
||||
this.entity = entity;
|
||||
addToCache(FLAGS_KEY, new LinkedHashSet<EntityFlag>());
|
||||
}
|
||||
|
||||
public Entity getEntity() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Set<EntityFlag> flags() {
|
||||
return (Set<EntityFlag>) getValueFromCache(FLAGS_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFlag(EntityFlag flag) {
|
||||
flags().add(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFlag(EntityFlag flag) {
|
||||
flags().remove(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFlag(EntityFlag... flag) {
|
||||
return Arrays.stream(flag).anyMatch(flags()::contains);
|
||||
}
|
||||
|
||||
public Set<EntityFlag> getFlags() {
|
||||
return Collections.unmodifiableSet(flags());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.softwarerat.API.data.entity;
|
||||
|
||||
public enum EntityFlags implements EntityFlag {
|
||||
NPC("marks the entity as a non-player character", 1),
|
||||
PROTECTED("entity cannot take damage or be targeted", 2),
|
||||
INTERACTABLE("entity runs an action when right-clicked", 3);
|
||||
|
||||
private final String description;
|
||||
|
||||
private final Integer number;
|
||||
|
||||
EntityFlags(String description, Integer number) {
|
||||
this.description = description;
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getInt() {
|
||||
return this.number;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
package com.softwarerat.API.data.location;
|
||||
|
||||
import com.softwarerat.API.data.GameData;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.softwarerat.API.GameData;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
// Game related Location building
|
||||
@AllArgsConstructor
|
||||
public class LocationAPI {
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.softwarerat.API.data.npc;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import com.softwarerat.API.data.entity.EntityFlag;
|
||||
import com.softwarerat.API.data.entity.EntityFlagHolder;
|
||||
|
||||
public class NPC {
|
||||
private final String name;
|
||||
private final Entity entity;
|
||||
private final NPCAction action;
|
||||
private final EntityFlagHolder flags;
|
||||
|
||||
public NPC(String name, Entity entity, NPCAction action, EntityFlagHolder flags) {
|
||||
this.name = name;
|
||||
this.entity = entity;
|
||||
this.action = action;
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
public UUID getEntityId() {
|
||||
return this.entity.getUniqueId();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Entity getEntity() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
public NPCAction getAction() {
|
||||
return this.action;
|
||||
}
|
||||
|
||||
public void setFlag(EntityFlag flag) {
|
||||
this.flags.setFlag(flag);
|
||||
}
|
||||
|
||||
public void removeFlag(EntityFlag flag) {
|
||||
this.flags.removeFlag(flag);
|
||||
}
|
||||
|
||||
public boolean hasFlag(EntityFlag... flag) {
|
||||
return this.flags.hasFlag(flag);
|
||||
}
|
||||
|
||||
public Set<EntityFlag> getFlags() {
|
||||
return this.flags.getFlags();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
this.entity.remove();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.softwarerat.API.data.npc;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Mob;
|
||||
|
||||
import com.softwarerat.API.data.entity.EntityFlagAPI;
|
||||
import com.softwarerat.API.data.entity.EntityFlagHolder;
|
||||
import com.softwarerat.API.data.entity.EntityFlags;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
// Spawns non-interactive NPC entities and dispatches an NPCAction when a player clicks them
|
||||
public class NPCAPI {
|
||||
private final Map<UUID, NPC> npcsByEntityId = new ConcurrentHashMap<>();
|
||||
private final EntityFlagAPI entityFlagAPI;
|
||||
|
||||
public NPCAPI(EntityFlagAPI entityFlagAPI) {
|
||||
this.entityFlagAPI = entityFlagAPI;
|
||||
}
|
||||
|
||||
public NPC spawnNPC(Location location, EntityType type, String name, NPCAction action) {
|
||||
Entity entity = location.getWorld().spawnEntity(location, type);
|
||||
entity.customName(Component.text(name));
|
||||
entity.setCustomNameVisible(true);
|
||||
entity.setPersistent(false);
|
||||
entity.setInvulnerable(true);
|
||||
|
||||
if (entity instanceof LivingEntity livingEntity) {
|
||||
livingEntity.setCollidable(false);
|
||||
livingEntity.setRemoveWhenFarAway(false);
|
||||
livingEntity.setCanPickupItems(false);
|
||||
livingEntity.setAI(false);
|
||||
}
|
||||
if (entity instanceof Mob mob) {
|
||||
mob.setAware(false);
|
||||
}
|
||||
|
||||
EntityFlagHolder flags = this.entityFlagAPI.get(entity);
|
||||
flags.setFlag(EntityFlags.NPC);
|
||||
flags.setFlag(EntityFlags.INTERACTABLE);
|
||||
|
||||
NPC npc = new NPC(name, entity, action, flags);
|
||||
this.npcsByEntityId.put(npc.getEntityId(), npc);
|
||||
return npc;
|
||||
}
|
||||
|
||||
public void removeNPC(NPC npc) {
|
||||
this.npcsByEntityId.remove(npc.getEntityId());
|
||||
this.entityFlagAPI.clear(npc.getEntity());
|
||||
npc.remove();
|
||||
}
|
||||
|
||||
public void removeAll() {
|
||||
this.npcsByEntityId.values().forEach(NPC::remove);
|
||||
this.npcsByEntityId.clear();
|
||||
}
|
||||
|
||||
public NPC getNPC(UUID entityId) {
|
||||
return this.npcsByEntityId.get(entityId);
|
||||
}
|
||||
|
||||
public Collection<NPC> getNPCs() {
|
||||
return this.npcsByEntityId.values();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.softwarerat.API.data.npc;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
// Callback executed when a player clicks an NPC, e.g. open an interactive inventory
|
||||
@FunctionalInterface
|
||||
public interface NPCAction {
|
||||
void onInteract(Player player, NPC npc);
|
||||
}
|
||||
@@ -3,8 +3,8 @@ package com.softwarerat.API.data.player;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import com.softwarerat.API.data.GameData;
|
||||
import com.softwarerat.GameAPI;
|
||||
import com.softwarerat.API.GameData;
|
||||
|
||||
|
||||
// Game related PlayerAPI for checking if a player is the GameHost
|
||||
@@ -18,4 +18,5 @@ JavaPlugin javaPlugin = gameAPI.getJavaPlugin();
|
||||
return p.getName().equals(s);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -17,36 +17,61 @@ import org.bukkit.util.io.BukkitObjectInputStream;
|
||||
import org.bukkit.util.io.BukkitObjectOutputStream;
|
||||
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
|
||||
|
||||
import com.softwarerat.API.GameData;
|
||||
|
||||
public class KitAPI {
|
||||
private final HashMap<String, ItemStack[]> kits;
|
||||
|
||||
private final GameData gameData;
|
||||
|
||||
private final HashMap<String, String> kits;
|
||||
|
||||
private final ConcurrentHashMap<UUID, String> playerKit;
|
||||
|
||||
|
||||
private final ArrayList<Player> playersWithKits;
|
||||
|
||||
|
||||
public KitAPI() {
|
||||
this.kits = (HashMap)new HashMap<>();
|
||||
|
||||
|
||||
public KitAPI(GameData gameData) {
|
||||
this.gameData = gameData;
|
||||
this.kits = new HashMap<>();
|
||||
this.playerKit = new ConcurrentHashMap<>();
|
||||
this.playersWithKits = new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
public ItemStack[] loadKit(String base64) {
|
||||
System.out.println("Loading Kit with data: " + base64);
|
||||
try {
|
||||
return itemStackArrayFromBase64(base64);
|
||||
} catch (IOException iOException) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ConcurrentHashMap<UUID, String> getPlayerKit() {
|
||||
return this.playerKit;
|
||||
}
|
||||
|
||||
public void giveKit(Player player, String base64) {
|
||||
|
||||
public boolean hasKit(String kitName) {
|
||||
return this.kits.containsKey(kitName);
|
||||
}
|
||||
|
||||
public void giveKit(Player player, String kitName) {
|
||||
String base64 = this.kits.get(kitName);
|
||||
if (base64 == null) {
|
||||
throw new IllegalArgumentException("No kit saved with name: " + kitName);
|
||||
}
|
||||
giveKitFromData(player, base64);
|
||||
this.playerKit.put(player.getUniqueId(), kitName);
|
||||
}
|
||||
|
||||
public void givePrimaryKit(Player player) {
|
||||
giveKit(player, this.gameData.getPrimaryKit());
|
||||
}
|
||||
|
||||
public void giveSecondaryKit(Player player) {
|
||||
giveKit(player, this.gameData.getSecondaryKit());
|
||||
}
|
||||
|
||||
public void giveKitFromData(Player player, String base64) {
|
||||
player.getInventory().clear();
|
||||
System.out.println(this.playerKit);
|
||||
ItemStack[] kit = loadKit(base64);
|
||||
for (int i = 0; i < kit.length; i++) {
|
||||
ItemStack itemStack = kit[i];
|
||||
@@ -122,13 +147,11 @@ public class KitAPI {
|
||||
|
||||
public void saveKit(Player player, String name) {
|
||||
String kitBase64 = itemStackArrayToBase64(player.getInventory().getContents());
|
||||
|
||||
|
||||
this.kits.put(name, player.getInventory().getContents());
|
||||
this.kits.put(name, kitBase64);
|
||||
}
|
||||
|
||||
|
||||
public HashMap<String,ItemStack[]> getKits() {
|
||||
public HashMap<String,String> getKits() {
|
||||
return this.kits;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,60 @@
|
||||
package com.softwarerat.API.data.scoreboard;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scoreboard.Criteria;
|
||||
import org.bukkit.scoreboard.DisplaySlot;
|
||||
import org.bukkit.scoreboard.Objective;
|
||||
import org.bukkit.scoreboard.Scoreboard;
|
||||
import org.bukkit.scoreboard.ScoreboardManager;
|
||||
|
||||
import com.softwarerat.API.GameData;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
// Sidebar scoreboard for the game, built on GameData's shared Scoreboard so it
|
||||
// coexists with PrefixAPI's teams instead of replacing the player's board.
|
||||
public class ScoreAPI {
|
||||
private final GameData gameData;
|
||||
private Objective objective;
|
||||
|
||||
public ScoreAPI(String minigameName, String mapName,Player player,String localName){
|
||||
ScoreboardManager manager = Bukkit.getScoreboardManager();
|
||||
Scoreboard board = manager.getNewScoreboard();
|
||||
Objective objective = board.registerNewObjective(localName, "dummy");
|
||||
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
|
||||
objective.setDisplayName(minigameName);
|
||||
player.setScoreboard(board);
|
||||
public ScoreAPI(GameData gameData) {
|
||||
this.gameData = gameData;
|
||||
}
|
||||
|
||||
public void createSidebar(String objectiveName, String title) {
|
||||
Scoreboard board = this.gameData.getScoreboard();
|
||||
Objective existing = board.getObjective(objectiveName);
|
||||
if (existing != null) {
|
||||
existing.unregister();
|
||||
}
|
||||
this.objective = board.registerNewObjective(objectiveName, Criteria.DUMMY, Component.text(title));
|
||||
this.objective.setDisplaySlot(DisplaySlot.SIDEBAR);
|
||||
}
|
||||
|
||||
public void showTo(Player player) {
|
||||
player.setScoreboard(this.gameData.getScoreboard());
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
if (this.objective == null) return;
|
||||
this.objective.displayName(Component.text(title));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void setScore(String line, int value) {
|
||||
if (this.objective == null) return;
|
||||
this.objective.getScore(line).setScore(value);
|
||||
}
|
||||
|
||||
public void removeScore(String line) {
|
||||
this.gameData.getScoreboard().resetScores(line);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
if (this.objective == null) return;
|
||||
this.objective.unregister();
|
||||
this.objective = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.softwarerat.API.event.listener;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
|
||||
import com.softwarerat.API.data.entity.EntityFlags;
|
||||
import com.softwarerat.API.data.npc.NPC;
|
||||
import com.softwarerat.API.data.npc.NPCAPI;
|
||||
|
||||
// Dispatches clicks on spawned NPCs to their registered NPCAction
|
||||
public class NPCInteractListener implements Listener {
|
||||
private final NPCAPI npcAPI;
|
||||
|
||||
public NPCInteractListener(NPCAPI npcAPI) {
|
||||
this.npcAPI = npcAPI;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteractNPC(PlayerInteractEntityEvent event) {
|
||||
NPC npc = this.npcAPI.getNPC(event.getRightClicked().getUniqueId());
|
||||
if (npc == null) return;
|
||||
if (!npc.hasFlag(EntityFlags.INTERACTABLE)) return;
|
||||
|
||||
event.setCancelled(true);
|
||||
Player player = event.getPlayer();
|
||||
npc.getAction().onInteract(player, npc);
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,15 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import com.softwarerat.API.data.GameData;
|
||||
import com.softwarerat.API.GameData;
|
||||
import com.softwarerat.API.data.entity.EntityFlagAPI;
|
||||
import com.softwarerat.API.data.location.LocationAPI;
|
||||
import com.softwarerat.API.data.npc.NPCAPI;
|
||||
import com.softwarerat.API.data.player.kit.KitAPI;
|
||||
import com.softwarerat.API.data.prefix.PrefixAPI;
|
||||
import com.softwarerat.API.data.scoreboard.ScoreAPI;
|
||||
import com.softwarerat.API.data.world.WorldAPI;
|
||||
import com.softwarerat.API.event.listener.NPCInteractListener;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@@ -23,13 +28,24 @@ GameData gameData;
|
||||
WorldAPI worldAPI;
|
||||
LocationAPI locationAPI;
|
||||
PrefixAPI prefixAPI;
|
||||
KitAPI kitAPI;
|
||||
EntityFlagAPI entityFlagAPI;
|
||||
NPCAPI npcAPI;
|
||||
ScoreAPI scoreAPI;
|
||||
|
||||
public void enableAPI(JavaPlugin jPlugin){
|
||||
javaPlugin = jPlugin;
|
||||
gameData = new GameData(this);
|
||||
worldAPI = new WorldAPI();
|
||||
System.out.println("Enabled GameAPI");
|
||||
PluginManager pluginManager = Bukkit.getPluginManager();
|
||||
locationAPI = new LocationAPI(gameData);
|
||||
kitAPI = new KitAPI(gameData);
|
||||
prefixAPI = new PrefixAPI(gameData.getScoreboard());
|
||||
scoreAPI = new ScoreAPI(gameData);
|
||||
entityFlagAPI = new EntityFlagAPI();
|
||||
npcAPI = new NPCAPI(entityFlagAPI);
|
||||
pluginManager.registerEvents(new NPCInteractListener(npcAPI), jPlugin);
|
||||
|
||||
//javaPlugin.getCommand("getNavigator").setExecutor(new Navigator(this));
|
||||
//if (gameData.getGameType().equals(GameType.GAME_TYPE_TYPELESS) || gameData.getCurrentGameState().equals(GameState.GAME_STATE_LOBBY)){
|
||||
|
||||
Reference in New Issue
Block a user