diff --git a/pom.xml b/pom.xml
index c971f15..2bbec56 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,19 +4,18 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- example-expansion
+ pinata
1.0.0-SNAPSHOT
jar
- ExampleExpansion
- An Example expansion for GamesInTheBox
+ Pinata
+ A mob to punch
- me.hsgamer.gamesinthebox.exampleexpansion.ExampleExpansion
+ me.hsgamer.gamesinthebox.pinata.Pinata
true
-
jitpack.io
@@ -36,28 +35,4 @@
provided
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/main/java/me/hsgamer/gamesinthebox/exampleexpansion/ExampleExpansion.java b/src/main/java/me/hsgamer/gamesinthebox/exampleexpansion/ExampleExpansion.java
deleted file mode 100644
index cb9ac4f..0000000
--- a/src/main/java/me/hsgamer/gamesinthebox/exampleexpansion/ExampleExpansion.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package me.hsgamer.gamesinthebox.exampleexpansion;
-
-import me.hsgamer.hscore.expansion.common.Expansion;
-
-public class ExampleExpansion implements Expansion {
- @Override
- public boolean onLoad() {
- return true;
- }
-
- @Override
- public void onEnable() {
- // Do something
- }
-
- @Override
- public void onDisable() {
- // Do something
- }
-}
diff --git a/src/main/java/me/hsgamer/gamesinthebox/pinata/GameArenaLogic.java b/src/main/java/me/hsgamer/gamesinthebox/pinata/GameArenaLogic.java
new file mode 100644
index 0000000..144b199
--- /dev/null
+++ b/src/main/java/me/hsgamer/gamesinthebox/pinata/GameArenaLogic.java
@@ -0,0 +1,89 @@
+package me.hsgamer.gamesinthebox.pinata;
+
+import me.hsgamer.gamesinthebox.game.feature.BoundingFeature;
+import me.hsgamer.gamesinthebox.game.feature.PointFeature;
+import me.hsgamer.gamesinthebox.game.simple.feature.SimpleBoundingFeature;
+import me.hsgamer.gamesinthebox.game.simple.feature.SimpleBoundingOffsetFeature;
+import me.hsgamer.gamesinthebox.game.simple.feature.SimpleRewardFeature;
+import me.hsgamer.gamesinthebox.game.template.TemplateGameArena;
+import me.hsgamer.gamesinthebox.game.template.TemplateGameArenaLogic;
+import me.hsgamer.gamesinthebox.pinata.feature.ListenerFeature;
+import me.hsgamer.gamesinthebox.pinata.feature.PinataFeature;
+import me.hsgamer.gamesinthebox.pinata.feature.SpawnFeature;
+import me.hsgamer.minigamecore.base.Feature;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+public class GameArenaLogic extends TemplateGameArenaLogic {
+ private final Pinata expansion;
+
+ public GameArenaLogic(Pinata expansion, TemplateGameArena arena) {
+ super(arena);
+ this.expansion = expansion;
+ }
+
+ @Override
+ public void forceEnd() {
+ PinataFeature pinataFeature = arena.getFeature(PinataFeature.class);
+ pinataFeature.setClearAllEntities(false);
+ pinataFeature.stopTask();
+ pinataFeature.clearAllEntities();
+
+ arena.getFeature(ListenerFeature.class).unregister();
+ }
+
+ @Override
+ public List loadFeatures() {
+ SimpleBoundingFeature boundingFeature = new SimpleBoundingFeature(arena);
+ return Arrays.asList(
+ boundingFeature,
+ new SimpleBoundingOffsetFeature(arena, boundingFeature, true),
+ new PinataFeature(arena),
+ new ListenerFeature(expansion, arena),
+ new SpawnFeature(arena)
+ );
+ }
+
+ @Override
+ public void postInit() {
+ BoundingFeature boundingFeature = arena.getFeature(BoundingFeature.class);
+ arena.getFeature(PinataFeature.class).addEntityClearCheck(entity -> !boundingFeature.checkBounding(entity.getLocation(), true));
+ }
+
+ @Override
+ public void onInGameStart() {
+ arena.getFeature(ListenerFeature.class).register();
+ arena.getFeature(PinataFeature.class).startTask();
+ }
+
+ @Override
+ public void onInGameUpdate() {
+ arena.getFeature(SpawnFeature.class).checkAndSpawn();
+ }
+
+ @Override
+ public void onEndingStart() {
+ List topList = arena.getFeature(PointFeature.class).getTopUUID().collect(Collectors.toList());
+ arena.getFeature(SimpleRewardFeature.class).tryReward(topList);
+
+ arena.getFeature(PinataFeature.class).setClearAllEntities(true);
+ }
+
+ @Override
+ public boolean isEndingOver() {
+ return super.isEndingOver() && arena.getFeature(PinataFeature.class).isAllEntityCleared();
+ }
+
+ @Override
+ public void onEndingOver() {
+ PinataFeature pinataFeature = arena.getFeature(PinataFeature.class);
+ pinataFeature.setClearAllEntities(false);
+ pinataFeature.stopTask();
+ pinataFeature.clearAllEntities();
+
+ arena.getFeature(ListenerFeature.class).unregister();
+ }
+}
diff --git a/src/main/java/me/hsgamer/gamesinthebox/pinata/GameEditor.java b/src/main/java/me/hsgamer/gamesinthebox/pinata/GameEditor.java
new file mode 100644
index 0000000..f38eb47
--- /dev/null
+++ b/src/main/java/me/hsgamer/gamesinthebox/pinata/GameEditor.java
@@ -0,0 +1,207 @@
+package me.hsgamer.gamesinthebox.pinata;
+
+import com.google.common.base.Enums;
+import me.hsgamer.gamesinthebox.game.GameArena;
+import me.hsgamer.gamesinthebox.game.simple.action.ValueAction;
+import me.hsgamer.gamesinthebox.game.simple.feature.SimpleBoundingFeature;
+import me.hsgamer.gamesinthebox.game.simple.feature.SimpleBoundingOffsetFeature;
+import me.hsgamer.gamesinthebox.game.template.TemplateGame;
+import me.hsgamer.gamesinthebox.game.template.TemplateGameArenaLogic;
+import me.hsgamer.gamesinthebox.game.template.TemplateGameEditor;
+import me.hsgamer.gamesinthebox.game.template.feature.ArenaLogicFeature;
+import me.hsgamer.gamesinthebox.pinata.feature.ListenerFeature;
+import me.hsgamer.gamesinthebox.pinata.feature.PinataFeature;
+import me.hsgamer.hscore.bukkit.utils.MessageUtils;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.EntityType;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class GameEditor extends TemplateGameEditor {
+ private final SimpleBoundingFeature.Editor simpleBoundingFeatureEditor = SimpleBoundingFeature.editor(true);
+ private final SimpleBoundingOffsetFeature.Editor simpleBoundingOffsetFeatureEditor = SimpleBoundingOffsetFeature.editor();
+ private final List nameTags = new ArrayList<>();
+ private EntityType entityType = EntityType.SHEEP;
+ private boolean damageAsScore = false;
+
+ public GameEditor(@NotNull TemplateGame game) {
+ super(game);
+ }
+
+ @Override
+ protected @NotNull Map createActionMap() {
+ Map map = super.createActionMap();
+
+ map.putAll(simpleBoundingFeatureEditor.getActions());
+ map.putAll(simpleBoundingOffsetFeatureEditor.getActions());
+
+ map.put("add-name-tag", new SimpleAction() {
+ @Override
+ public @NotNull String getDescription() {
+ return "Add a name tag to the list";
+ }
+
+ @Override
+ public boolean performAction(@NotNull CommandSender sender, @NotNull String... args) {
+ if (args.length == 0) {
+ return false;
+ }
+ nameTags.add(String.join(" ", args));
+ return true;
+ }
+
+ @Override
+ public @NotNull String getArgsUsage() {
+ return "";
+ }
+ });
+ map.put("clear-name-tags", new SimpleAction() {
+ @Override
+ public @NotNull String getDescription() {
+ return "Clear the name tags list";
+ }
+
+ @Override
+ public boolean performAction(@NotNull CommandSender sender, @NotNull String... args) {
+ nameTags.clear();
+ return true;
+ }
+ });
+ map.put("set-pinata-type", new ValueAction() {
+ @Override
+ public @NotNull String getDescription() {
+ return "Set the pinata type";
+ }
+
+ @Override
+ protected boolean performAction(@NotNull CommandSender sender, @NotNull EntityType value, String... args) {
+ entityType = value;
+ return true;
+ }
+
+ @Override
+ protected int getValueArgCount() {
+ return 1;
+ }
+
+ @Override
+ protected Optional parseValue(@NotNull CommandSender sender, String... args) {
+ return Optional.ofNullable(args[0])
+ .map(String::toUpperCase)
+ .flatMap(s -> Enums.getIfPresent(EntityType.class, s).toJavaUtil())
+ .filter(EntityType::isAlive);
+ }
+
+ @Override
+ protected @NotNull List getValueArgs(@NotNull CommandSender sender, String... args) {
+ return Arrays.stream(EntityType.values())
+ .filter(EntityType::isAlive)
+ .map(Enum::name)
+ .collect(Collectors.toList());
+ }
+ });
+ map.put("set-damage-as-score", new ValueAction() {
+ @Override
+ protected boolean performAction(@NotNull CommandSender sender, @NotNull Boolean value, String... args) {
+ damageAsScore = value;
+ return true;
+ }
+
+ @Override
+ protected int getValueArgCount() {
+ return 1;
+ }
+
+ @Override
+ protected Optional parseValue(@NotNull CommandSender sender, String... args) {
+ return Optional.of(Boolean.parseBoolean(args[0]));
+ }
+
+ @Override
+ protected @NotNull List getValueArgs(@NotNull CommandSender sender, String... args) {
+ return Arrays.asList("true", "false");
+ }
+
+ @Override
+ public @NotNull String getDescription() {
+ return "Set whether to use damage as score";
+ }
+
+ @Override
+ public @NotNull String getArgsUsage() {
+ return "";
+ }
+ });
+
+ return map;
+ }
+
+ @Override
+ protected @NotNull List<@NotNull SimpleEditorStatus> createEditorStatusList() {
+ List<@NotNull SimpleEditorStatus> list = super.createEditorStatusList();
+ list.add(simpleBoundingFeatureEditor.getStatus());
+ list.add(simpleBoundingOffsetFeatureEditor.getStatus());
+ list.add(new SimpleEditorStatus() {
+ @Override
+ public void sendStatus(@NotNull CommandSender sender) {
+ MessageUtils.sendMessage(sender, "&6&lPinata");
+ MessageUtils.sendMessage(sender, "&6Type: &f" + entityType.name());
+ MessageUtils.sendMessage(sender, "&6Damage As Score: &f" + damageAsScore);
+ MessageUtils.sendMessage(sender, "&6Name Tags: ");
+ nameTags.forEach(nameTag -> MessageUtils.sendMessage(sender, "&f- " + nameTag));
+ }
+
+ @Override
+ public void reset(@NotNull CommandSender sender) {
+ nameTags.clear();
+ entityType = EntityType.SHEEP;
+ damageAsScore = false;
+ }
+
+ @Override
+ public boolean canSave(@NotNull CommandSender sender) {
+ return true;
+ }
+
+ @Override
+ public Map toPathValueMap(@NotNull CommandSender sender) {
+ Map map = new LinkedHashMap<>();
+ if (!nameTags.isEmpty()) {
+ map.put("pinata.name-tag", nameTags);
+ }
+ if (entityType != EntityType.SHEEP) {
+ map.put("pinata.type", entityType.name());
+ }
+ if (damageAsScore) {
+ map.put("damage-as-score", true);
+ }
+ return map;
+ }
+ });
+ return list;
+ }
+
+ @Override
+ public boolean migrate(@NotNull CommandSender sender, @NotNull GameArena gameArena) {
+ ArenaLogicFeature arenaLogicFeature = gameArena.getFeature(ArenaLogicFeature.class);
+ if (arenaLogicFeature == null) {
+ return false;
+ }
+ TemplateGameArenaLogic templateGameArenaLogic = arenaLogicFeature.getArenaLogic();
+ if (!(templateGameArenaLogic instanceof GameArenaLogic)) {
+ return false;
+ }
+
+ nameTags.clear();
+ nameTags.addAll(gameArena.getFeature(PinataFeature.class).getNameTags());
+
+ entityType = gameArena.getFeature(PinataFeature.class).getEntityType();
+ damageAsScore = gameArena.getFeature(ListenerFeature.class).isDamageAsScore();
+
+ simpleBoundingFeatureEditor.migrate(gameArena.getFeature(SimpleBoundingFeature.class));
+ simpleBoundingOffsetFeatureEditor.migrate(gameArena.getFeature(SimpleBoundingOffsetFeature.class));
+ return super.migrate(sender, gameArena);
+ }
+}
diff --git a/src/main/java/me/hsgamer/gamesinthebox/pinata/MessageConfig.java b/src/main/java/me/hsgamer/gamesinthebox/pinata/MessageConfig.java
new file mode 100644
index 0000000..cff6f9e
--- /dev/null
+++ b/src/main/java/me/hsgamer/gamesinthebox/pinata/MessageConfig.java
@@ -0,0 +1,43 @@
+package me.hsgamer.gamesinthebox.pinata;
+
+import me.hsgamer.hscore.config.annotation.ConfigPath;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public interface MessageConfig {
+ @ConfigPath("display-name")
+ default String getDisplayName() {
+ return "Pinata";
+ }
+
+ @ConfigPath("default-hologram-lines")
+ default Map getDefaultHologramLines() {
+ Map map = new LinkedHashMap<>();
+ map.put("description", Arrays.asList(
+ "&c&lPINATA",
+ "&fA pinata will be spawned at the game arena",
+ "&fYou need to hit it to get points",
+ "&fThe player with the most points will win"
+ ));
+ map.put("points", Collections.singletonList(
+ "&fPoints when you hit the pinata: &a{game_point_hit}"
+ ));
+ map.put("top", Arrays.asList(
+ "&a#1 &f{game_top_name_1} &7- &f{game_top_value_1}",
+ "&a#2 &f{game_top_name_2} &7- &f{game_top_value_2}",
+ "&a#3 &f{game_top_name_3} &7- &f{game_top_value_3}",
+ "&a#4 &f{game_top_name_4} &7- &f{game_top_value_4}",
+ "&a#5 &f{game_top_name_5} &7- &f{game_top_value_5}"
+ ));
+ map.put("status", Arrays.asList(
+ "&fStatus: &a{planner_game_state}",
+ "&fTime left: &a{game_time_left}"
+ ));
+ return map;
+ }
+
+ void reloadConfig();
+}
diff --git a/src/main/java/me/hsgamer/gamesinthebox/pinata/Pinata.java b/src/main/java/me/hsgamer/gamesinthebox/pinata/Pinata.java
new file mode 100644
index 0000000..ba65e9f
--- /dev/null
+++ b/src/main/java/me/hsgamer/gamesinthebox/pinata/Pinata.java
@@ -0,0 +1,66 @@
+package me.hsgamer.gamesinthebox.pinata;
+
+import me.hsgamer.gamesinthebox.game.simple.feature.SimplePointFeature;
+import me.hsgamer.gamesinthebox.game.template.TemplateGame;
+import me.hsgamer.gamesinthebox.game.template.TemplateGameArena;
+import me.hsgamer.gamesinthebox.game.template.TemplateGameArenaLogic;
+import me.hsgamer.gamesinthebox.game.template.TemplateGameEditor;
+import me.hsgamer.gamesinthebox.game.template.expansion.TemplateGameExpansion;
+import me.hsgamer.gamesinthebox.util.UpdateUtil;
+import me.hsgamer.hscore.bukkit.config.BukkitConfig;
+import me.hsgamer.hscore.common.CollectionUtils;
+import me.hsgamer.hscore.config.proxy.ConfigGenerator;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+public class Pinata extends TemplateGameExpansion {
+ public static final SimplePointFeature.PointValue POINT_HIT = new SimplePointFeature.PointValue("hit", 1, false);
+ private final MessageConfig messageConfig = ConfigGenerator.newInstance(MessageConfig.class, new BukkitConfig(new File(getDataFolder(), "messages.yml")));
+
+ @Override
+ protected @NotNull String @NotNull [] getGameType() {
+ return new String[]{"pinata"};
+ }
+
+ @Override
+ public TemplateGameArenaLogic createArenaLogic(TemplateGameArena templateGameArena) {
+ return new GameArenaLogic(this, templateGameArena);
+ }
+
+ @Override
+ public TemplateGameEditor getEditor(TemplateGame game) {
+ return new GameEditor(game);
+ }
+
+ @Override
+ public List getPointValues() {
+ return Collections.singletonList(POINT_HIT);
+ }
+
+ @Override
+ public List getDefaultHologramLines(String name) {
+ return Optional.ofNullable(messageConfig.getDefaultHologramLines().get(name))
+ .map(CollectionUtils::createStringListFromObject)
+ .orElseGet(() -> super.getDefaultHologramLines(name));
+ }
+
+ @Override
+ public String getDisplayName() {
+ return messageConfig.getDisplayName();
+ }
+
+ @Override
+ public void onReload() {
+ super.onReload();
+ messageConfig.reloadConfig();
+ }
+
+ @Override
+ protected void enable() {
+ UpdateUtil.notifyUpdate(this, "GamesInTheBox-MC/Pinata");
+ }
+}
diff --git a/src/main/java/me/hsgamer/gamesinthebox/pinata/feature/ListenerFeature.java b/src/main/java/me/hsgamer/gamesinthebox/pinata/feature/ListenerFeature.java
new file mode 100644
index 0000000..a105d2a
--- /dev/null
+++ b/src/main/java/me/hsgamer/gamesinthebox/pinata/feature/ListenerFeature.java
@@ -0,0 +1,87 @@
+package me.hsgamer.gamesinthebox.pinata.feature;
+
+import me.hsgamer.gamesinthebox.game.feature.GameConfigFeature;
+import me.hsgamer.gamesinthebox.game.simple.SimpleGameArena;
+import me.hsgamer.gamesinthebox.game.simple.feature.SimplePointFeature;
+import me.hsgamer.gamesinthebox.pinata.Pinata;
+import me.hsgamer.minigamecore.base.Feature;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.Listener;
+import org.bukkit.event.entity.EntityDamageByEntityEvent;
+import org.bukkit.event.entity.EntityDeathEvent;
+
+import java.util.Optional;
+
+public class ListenerFeature implements Feature, Listener {
+ private final Pinata expansion;
+ private final SimpleGameArena arena;
+ private PinataFeature pinataFeature;
+ private SimplePointFeature pointFeature;
+ private boolean damageAsScore = false;
+
+ public ListenerFeature(Pinata expansion, SimpleGameArena arena) {
+ this.expansion = expansion;
+ this.arena = arena;
+ }
+
+ @Override
+ public void init() {
+ this.pinataFeature = this.arena.getFeature(PinataFeature.class);
+ this.pointFeature = this.arena.getFeature(SimplePointFeature.class);
+ }
+
+ @Override
+ public void postInit() {
+ GameConfigFeature gameConfigFeature = arena.getFeature(GameConfigFeature.class);
+
+ if (gameConfigFeature != null) {
+ damageAsScore = Optional.ofNullable(gameConfigFeature.getString("damage-as-score"))
+ .map(Boolean::parseBoolean)
+ .orElse(false);
+ }
+ }
+
+ public void register() {
+ Bukkit.getPluginManager().registerEvents(this, expansion.getPlugin());
+ }
+
+ public void unregister() {
+ HandlerList.unregisterAll(this);
+ }
+
+ public boolean isDamageAsScore() {
+ return damageAsScore;
+ }
+
+ @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
+ public void onPinataDamage(EntityDamageByEntityEvent event) {
+ Entity entity = event.getEntity();
+ if (!pinataFeature.contains(entity)) return;
+ event.setCancelled(true);
+
+ Entity damager = event.getDamager();
+ if (damager instanceof Player) {
+ Player player = (Player) damager;
+
+ if (damageAsScore) {
+ pointFeature.applyPoint(player.getUniqueId(), (int) event.getFinalDamage());
+ } else {
+ pointFeature.applyPoint(player.getUniqueId(), Pinata.POINT_HIT);
+ }
+ }
+ }
+
+ @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
+ public void onPinataDeath(EntityDeathEvent event) {
+ Entity entity = event.getEntity();
+ if (!pinataFeature.contains(entity)) return;
+
+ event.setDroppedExp(0);
+ event.getDrops().clear();
+ }
+}
diff --git a/src/main/java/me/hsgamer/gamesinthebox/pinata/feature/PinataFeature.java b/src/main/java/me/hsgamer/gamesinthebox/pinata/feature/PinataFeature.java
new file mode 100644
index 0000000..c684b02
--- /dev/null
+++ b/src/main/java/me/hsgamer/gamesinthebox/pinata/feature/PinataFeature.java
@@ -0,0 +1,63 @@
+package me.hsgamer.gamesinthebox.pinata.feature;
+
+import com.google.common.base.Enums;
+import me.hsgamer.gamesinthebox.game.feature.EntityFeature;
+import me.hsgamer.gamesinthebox.game.feature.GameConfigFeature;
+import me.hsgamer.gamesinthebox.game.simple.SimpleGameArena;
+import me.hsgamer.gamesinthebox.util.Util;
+import me.hsgamer.hscore.common.CollectionUtils;
+import org.bukkit.Location;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.LivingEntity;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+public class PinataFeature extends EntityFeature {
+ private final SimpleGameArena arena;
+ private List nameTags = Collections.emptyList();
+ private EntityType entityType = EntityType.SHEEP;
+
+ public PinataFeature(SimpleGameArena arena) {
+ this.arena = arena;
+ }
+
+ @Override
+ public void postInit() {
+ GameConfigFeature config = arena.getFeature(GameConfigFeature.class);
+
+ nameTags = Optional.ofNullable(config.get("pinata.name-tag"))
+ .map(CollectionUtils::createStringListFromObject)
+ .orElse(nameTags);
+
+ entityType = Optional.ofNullable(config.get("pinata.type"))
+ .map(Objects::toString)
+ .map(String::toUpperCase)
+ .flatMap(s -> Enums.getIfPresent(EntityType.class, s).toJavaUtil())
+ .filter(EntityType::isAlive)
+ .orElse(entityType);
+ }
+
+ @Override
+ protected @Nullable Entity createEntity(Location location) {
+ LivingEntity entity = (LivingEntity) location.getWorld().spawnEntity(location, entityType);
+ String nameTag = Util.getRandomColorizedString(nameTags, "");
+ if (!nameTag.isEmpty()) {
+ entity.setCustomName(nameTag);
+ entity.setCustomNameVisible(true);
+ }
+ return entity;
+ }
+
+ public List getNameTags() {
+ return nameTags;
+ }
+
+ public EntityType getEntityType() {
+ return entityType;
+ }
+}
diff --git a/src/main/java/me/hsgamer/gamesinthebox/pinata/feature/SpawnFeature.java b/src/main/java/me/hsgamer/gamesinthebox/pinata/feature/SpawnFeature.java
new file mode 100644
index 0000000..75e5494
--- /dev/null
+++ b/src/main/java/me/hsgamer/gamesinthebox/pinata/feature/SpawnFeature.java
@@ -0,0 +1,31 @@
+package me.hsgamer.gamesinthebox.pinata.feature;
+
+import me.hsgamer.gamesinthebox.game.feature.BoundingOffsetFeature;
+import me.hsgamer.gamesinthebox.game.simple.SimpleGameArena;
+import me.hsgamer.minigamecore.base.Feature;
+import org.bukkit.entity.Entity;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+public class SpawnFeature implements Feature {
+ private final SimpleGameArena arena;
+ private final AtomicReference entity = new AtomicReference<>();
+ private PinataFeature pinataFeature;
+ private BoundingOffsetFeature boundingOffsetFeature;
+
+ public SpawnFeature(SimpleGameArena arena) {
+ this.arena = arena;
+ }
+
+ @Override
+ public void init() {
+ this.pinataFeature = this.arena.getFeature(PinataFeature.class);
+ this.boundingOffsetFeature = this.arena.getFeature(BoundingOffsetFeature.class);
+ }
+
+ public void checkAndSpawn() {
+ Entity entity = this.entity.get();
+ if (entity != null && entity.isValid()) return;
+ pinataFeature.spawn(boundingOffsetFeature.getRandomLocation(), this.entity::set);
+ }
+}
diff --git a/src/main/resources/expansion.yml b/src/main/resources/expansion.yml
index 35c0e83..e33e961 100644
--- a/src/main/resources/expansion.yml
+++ b/src/main/resources/expansion.yml
@@ -2,8 +2,4 @@ name: ${project.name}
version: ${project.version}
main: ${project.mainClass}
description: ${project.description}
-
-# authors:
-# depend:
-# soft-depend:
-# plugin-depend:
\ No newline at end of file
+authors: "HSGamer"
\ No newline at end of file