diff --git a/src/main/java/fr/openmc/core/OMCPlugin.java b/src/main/java/fr/openmc/core/OMCPlugin.java index a8ef81f23..3a10bd5e4 100644 --- a/src/main/java/fr/openmc/core/OMCPlugin.java +++ b/src/main/java/fr/openmc/core/OMCPlugin.java @@ -118,6 +118,7 @@ public class OMCPlugin extends JavaPlugin { MailboxManager::new, DiscordLinkManager::new, ProfileManager::new, + () -> new fr.openmc.core.features.events.contents.halloween.halloween.HalloweenManager(), () -> new ElevatorManager(), () -> new CorpseManager(), QuestsManager::new, diff --git a/src/main/java/fr/openmc/core/OMCRegistry.java b/src/main/java/fr/openmc/core/OMCRegistry.java index 40c654aeb..693ec54aa 100644 --- a/src/main/java/fr/openmc/core/OMCRegistry.java +++ b/src/main/java/fr/openmc/core/OMCRegistry.java @@ -14,6 +14,7 @@ import fr.openmc.core.registry.loottable.CustomLootTableRegistry; import fr.openmc.core.registry.mobs.CustomMobRegistry; import fr.openmc.core.registry.regions.CustomRegionRegistry; +import fr.openmc.core.registry.structures.CustomStructureRegistry; import fr.openmc.core.registry.worldtemplates.WorldTemplateRegistry; import io.papermc.paper.plugin.bootstrap.BootstrapContext; @@ -31,6 +32,7 @@ public final class OMCRegistry { public static CustomLootTableRegistry CUSTOM_LOOT_TABLES; public static CustomAmbientRegistry CUSTOM_AMBIENTS; public static CustomLootboxRegistry CUSTOM_LOOTBOXES; + public static CustomStructureRegistry CUSTOM_STRUCTURES; public static CustomRegionRegistry CUSTOM_REGIONS; public static WorldTemplateRegistry WORLD_TEMPLATES; @@ -58,6 +60,8 @@ public final class OMCRegistry { RegistryLoadingType.AFTER_IA), new RegistryContext(() -> CUSTOM_MOBS = new CustomMobRegistry(), RegistryLoadingType.AFTER_IA), + new RegistryContext(() -> CUSTOM_STRUCTURES = new CustomStructureRegistry(), + RegistryLoadingType.RUNTIME), new RegistryContext(() -> WORLD_TEMPLATES = new WorldTemplateRegistry(), RegistryLoadingType.BOOTSTRAP, RegistryLoadingType.RUNTIME), new RegistryContext(() -> WEEKLY_EVENTS = new WeeklyEventsRegistry(), diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/commands/HalloweenCommands.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/commands/HalloweenCommands.java index 11bde75c0..4bc8a71b3 100644 --- a/src/main/java/fr/openmc/core/features/events/contents/halloween/commands/HalloweenCommands.java +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/commands/HalloweenCommands.java @@ -1,6 +1,8 @@ package fr.openmc.core.features.events.contents.halloween.commands; +import fr.openmc.core.features.events.contents.halloween.halloween.shop.menu.WitchShopMainMenu; import fr.openmc.core.features.events.contents.halloween.managers.HalloweenManager; +import org.bukkit.entity.Player; import revxrsal.commands.annotation.Command; import revxrsal.commands.annotation.Subcommand; import revxrsal.commands.bukkit.annotation.CommandPermission; @@ -12,4 +14,9 @@ public class HalloweenCommands { public void endHalloweenCommand() { HalloweenManager.endEvent(); } + + @Subcommand("test") + public void tst(Player player) { + new WitchShopMainMenu(player).open(); + } } diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/CandyItem.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/CandyItem.java new file mode 100644 index 000000000..ea0698f7e --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/CandyItem.java @@ -0,0 +1,37 @@ +package fr.openmc.core.features.events.contents.halloween.halloween; + +import fr.openmc.core.registry.items.CustomItem; +import fr.openmc.core.registry.items.CustomItemMeta; +import fr.openmc.core.utils.text.messages.TranslationManager; +import lombok.Getter; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.jspecify.annotations.NonNull; + +import java.util.HashMap; +import java.util.Map; + +public class CandyItem extends CustomItem { + + @Getter + public int diabetesIndex; + public Material baseItem; + + public static final Map candies = new HashMap<>(); + + public CandyItem(String candyID , int diabetesIndex, Material baseItem) { + super(new CustomItemMeta(candyID)); + this.diabetesIndex = diabetesIndex; + this.baseItem = baseItem; + candies.put(candyID, this); + } + + @Override + public @NonNull ItemStack getVanilla() { + ItemStack item = new ItemStack(baseItem); + item.editMeta(meta -> meta.itemName( + TranslationManager.translation("feature." + super.getId().replace(":", ".") + ".name") + )); + return item; + } +} diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/HalloweenManager.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/HalloweenManager.java new file mode 100644 index 000000000..b331c4c97 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/HalloweenManager.java @@ -0,0 +1,87 @@ +package fr.openmc.core.features.events.contents.halloween.halloween; + +import com.j256.ormlite.dao.Dao; +import com.j256.ormlite.dao.DaoManager; +import com.j256.ormlite.support.ConnectionSource; +import com.j256.ormlite.table.TableUtils; +import fr.openmc.core.bootstrap.features.Feature; +import fr.openmc.core.bootstrap.features.types.HasCommands; +import fr.openmc.core.bootstrap.features.types.HasDatabase; +import fr.openmc.core.bootstrap.features.types.HasListeners; +import fr.openmc.core.bootstrap.features.types.LoadAfterItemsAdder; +import fr.openmc.core.bootstrap.integration.OMCLogger; +import fr.openmc.core.bootstrap.listeners.ListenerFactory; +import fr.openmc.core.features.events.contents.halloween.halloween.dimension.advancement.Advancements; +import fr.openmc.core.features.events.contents.halloween.halloween.model.HalloweenDB; +import fr.openmc.core.features.events.contents.halloween.halloween.shop.WitchShopManager; +import lombok.Getter; + +import java.sql.SQLException; +import java.util.*; + +public class HalloweenManager extends Feature implements LoadAfterItemsAdder, HasDatabase, HasListeners, HasCommands { + + @Getter + private static HalloweenDB halloweenDB; + + private static Dao halloweenDao; + + public static List unlockedRooms; + + @Override + public void init() { + halloweenDB = loadEvent(); + unlockedRooms = halloweenDB.getUnlockedRooms(); + WitchShopManager.init(); + } + + @Override + public void initDB(ConnectionSource connectionSource) throws SQLException { + TableUtils.createTableIfNotExists(connectionSource, HalloweenDB.class); + halloweenDao = DaoManager.createDao(connectionSource, HalloweenDB.class); + } + + @Override + protected void save() { + saveEvent(); + } + + public static HalloweenDB loadEvent() { + try { + HalloweenDB halloweenDB = halloweenDao.queryForFirst(); + if (halloweenDB == null) + halloweenDB = new HalloweenDB(0, List.of(Advancements.ROOM_1.name()), false); + return halloweenDB; + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + + private static void saveEvent() { + try { + halloweenDao.createOrUpdate(halloweenDB); + } catch (Exception e) { + OMCLogger.error("Impossible de sauvegarder les corpses pendant l'arret.", e); + } + } + + public static boolean hasUnlock(Advancements advancements) { + return unlockedRooms.contains(advancements.name()); + } + + public static boolean unlockNewRoom(Advancements advancements) { + return unlockedRooms.add(advancements.name()); + } + + @Override + public Set getListeners() { + return Set.of(); + } + + @Override + public Set getCommands() { + return Set.of( + + ); + } +} diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/dimension/DimensionManager.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/dimension/DimensionManager.java new file mode 100644 index 000000000..ac7c714df --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/dimension/DimensionManager.java @@ -0,0 +1,66 @@ +package fr.openmc.core.features.events.contents.halloween.halloween.dimension; + +import fr.openmc.core.bootstrap.integration.OMCLogger; +import org.bukkit.Bukkit; +import org.bukkit.GameRules; +import org.bukkit.World; +import org.bukkit.entity.SpawnCategory; + +public class DimensionManager { + + public static final String DIMENSION_NAME = "world_omc_halloween_witch_house"; + public static World HALLOWEEN_WORLD; + + public static void init() { + HALLOWEEN_WORLD = Bukkit.getWorld(DIMENSION_NAME); + + setupDimension(); +// loadRegions(); + } + + //TODO setup la dimension : + // - monde vide + ajout de la structure de Mcross + // - ambiant custom + + private static void setupDimension() { + if (!HALLOWEEN_WORLD.getName().equals(DIMENSION_NAME)) return; + + // ** SPAWNING RULES ** + HALLOWEEN_WORLD.setSpawnLimit(SpawnCategory.MONSTER, 10); + HALLOWEEN_WORLD.setSpawnLimit(SpawnCategory.AMBIENT, 10); + HALLOWEEN_WORLD.setSpawnLimit(SpawnCategory.ANIMAL, 6); + + HALLOWEEN_WORLD.setTicksPerSpawns(SpawnCategory.MONSTER, 30); + HALLOWEEN_WORLD.setTicksPerSpawns(SpawnCategory.AMBIENT, 15); + HALLOWEEN_WORLD.setTicksPerSpawns(SpawnCategory.ANIMAL, 30); + + // ** SET GAMERULE FOR THE WORLD ** + HALLOWEEN_WORLD.setGameRule(GameRules.ADVANCE_TIME, false); + HALLOWEEN_WORLD.setGameRule(GameRules.SHOW_ADVANCEMENT_MESSAGES, false); + HALLOWEEN_WORLD.setGameRule(GameRules.ADVANCE_WEATHER, false); + HALLOWEEN_WORLD.setGameRule(GameRules.RAIDS, true); + HALLOWEEN_WORLD.setGameRule(GameRules.SPAWN_PATROLS, false); + HALLOWEEN_WORLD.setGameRule(GameRules.SPAWN_WANDERING_TRADERS, false); + HALLOWEEN_WORLD.setGameRule(GameRules.NATURAL_HEALTH_REGENERATION, false); + HALLOWEEN_WORLD.setGameRule(GameRules.LOCATOR_BAR, false); + HALLOWEEN_WORLD.setGameRule(GameRules.ALLOW_ENTERING_NETHER_USING_PORTALS, false); + + // ** SET WORLD BORDER AND TIME ** + HALLOWEEN_WORLD.getWorldBorder().setSize(500); + HALLOWEEN_WORLD.setTime(14000); + + OMCLogger.infoFormatted("Dimension de la Maison de la Sorcière setup (gamerules, worldborder, time)"); + } + + //TODO modifier avec les region de bibi +// private static void loadRegions() { +// MultiRegion multiRegion = new MultiRegion( +// HALLOWEEN_WORLD, +// new SquareRegion(0.0, 60.0, 0.0, 6.0, 70.0, 3.0, HALLOWEEN_WORLD), +// new SquareRegion(0.0, 60.0, 6.0, 3.0, 70.0, 3.0, HALLOWEEN_WORLD) +// ); +// +// multiRegion.addDetection(); +// } + +} diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/dimension/WitchHouseManager.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/dimension/WitchHouseManager.java new file mode 100644 index 000000000..e96a767fc --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/dimension/WitchHouseManager.java @@ -0,0 +1,7 @@ +package fr.openmc.core.features.events.contents.halloween.halloween.dimension; + +public class WitchHouseManager { + + + +} diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/dimension/advancement/Advancements.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/dimension/advancement/Advancements.java new file mode 100644 index 000000000..8c47fa78d --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/dimension/advancement/Advancements.java @@ -0,0 +1,16 @@ +package fr.openmc.core.features.events.contents.halloween.halloween.dimension.advancement; + +import lombok.Getter; + +@Getter +public enum Advancements { + ROOM_1(0), + ROOM_2(1000) + ; + + private final int require; + + Advancements(int require) { + this.require = require; + } +} diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/dimension/advancement/HouseRoom.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/dimension/advancement/HouseRoom.java new file mode 100644 index 000000000..653e97276 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/dimension/advancement/HouseRoom.java @@ -0,0 +1,11 @@ +package fr.openmc.core.features.events.contents.halloween.halloween.dimension.advancement; + +import fr.openmc.core.registry.regions.types.Region; + +public class HouseRoom { + + public Region region; + + + +} diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/listeners/CandyListener.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/listeners/CandyListener.java new file mode 100644 index 000000000..0170731a1 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/listeners/CandyListener.java @@ -0,0 +1,46 @@ +package fr.openmc.core.features.events.contents.halloween.halloween.listeners; + +import dev.lone.itemsadder.api.CustomStack; +import fr.openmc.core.OMCRegistry; +import fr.openmc.core.features.events.contents.halloween.halloween.CandyItem; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerItemConsumeEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class CandyListener implements Listener { + + private final Map diabetes = new HashMap<>(); + + @EventHandler + public void onCandyEat(PlayerItemConsumeEvent event) { + Player player = event.getPlayer(); + ItemStack item = event.getItem(); + + CustomStack stack = CustomStack.byItemStack(item); + + if (stack == null) return; + + if (!CandyItem.candies.containsKey(stack.getId())) return; + + CandyItem candy = CandyItem.candies.get(stack.getId()); + + UUID uuid = player.getUniqueId(); + + int diabete = diabetes.computeIfAbsent(uuid, key -> 0); + + diabete += candy.getDiabetesIndex(); + + if (diabete >= 20) { + //TODO faire un truc + diabetes.put(uuid, 0); + } else + diabetes.put(uuid, diabete); + } + +} diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/model/HalloweenDB.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/model/HalloweenDB.java new file mode 100644 index 000000000..a80866c35 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/model/HalloweenDB.java @@ -0,0 +1,51 @@ +package fr.openmc.core.features.events.contents.halloween.halloween.model; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@DatabaseTable(tableName = "halloween_season_event_data") +public class HalloweenDB { + + @DatabaseField(columnName = "advancement") + private int currentAdvancement; + + @DatabaseField(columnName = "unlocked_room") + private String unlockedRooms; + + @DatabaseField(columnName = "is_active") + private boolean active; + + private static final Gson GSON = new Gson(); + + public HalloweenDB() { + } + + public HalloweenDB(int currentAdvancement, List unlockedRooms, boolean active) { + this.currentAdvancement = currentAdvancement; + this.unlockedRooms = GSON.toJson(unlockedRooms); + this.active = active; + } + + public void setUnlockedRooms(List unlockedRooms) { + this.unlockedRooms = GSON.toJson(unlockedRooms); + } + + public List getUnlockedRooms() { + if (unlockedRooms == null || unlockedRooms.isBlank()) { + return new ArrayList<>(); + } + + return GSON.fromJson( + unlockedRooms, + new TypeToken>() {}.getType() + ); + } +} diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/ShopMoney.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/ShopMoney.java new file mode 100644 index 000000000..e16e67881 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/ShopMoney.java @@ -0,0 +1,24 @@ +package fr.openmc.core.features.events.contents.halloween.halloween.shop; + +import fr.openmc.core.OMCRegistry; +import fr.openmc.core.registry.items.CustomItem; +import lombok.Getter; + +@Getter +public enum ShopMoney { + //TODO rajouter les crafts des bonbons et les autre dans le shopMoney + RED_CANDY(WitchShopManager.getMoneyItemIcon("candy_brown"), OMCRegistry.CUSTOM_ITEMS.CANDY_RED), + YELLOW_CANDY(WitchShopManager.getMoneyItemIcon("candy_brown"), OMCRegistry.CUSTOM_ITEMS.CANDY_YELLOW), + GREEN_CANDY(WitchShopManager.getMoneyItemIcon("candy_brown"), OMCRegistry.CUSTOM_ITEMS.CANDY_GREEN), + BLUE_CANDY(WitchShopManager.getMoneyItemIcon("candy_brown"), OMCRegistry.CUSTOM_ITEMS.CANDY_BLUE), + MONSTER_CANDY(WitchShopManager.getMoneyItemIcon("candy_brown"), OMCRegistry.CUSTOM_ITEMS.CANDY_BROWN), + ; + + private final String icon; + private final CustomItem item; + + ShopMoney(String icon, CustomItem item) { + this.icon = icon; + this.item = item; + } +} diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/WitchShopItem.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/WitchShopItem.java new file mode 100644 index 000000000..31e1ecbd7 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/WitchShopItem.java @@ -0,0 +1,38 @@ +package fr.openmc.core.features.events.contents.halloween.halloween.shop; + +import fr.openmc.core.features.events.contents.halloween.halloween.HalloweenManager; +import fr.openmc.core.features.events.contents.halloween.halloween.dimension.advancement.Advancements; +import fr.openmc.core.registry.items.CustomItem; +import lombok.Getter; +import net.kyori.adventure.text.Component; + +public class WitchShopItem { + + @Getter public final Advancements advancements; + @Getter public final CustomItem item; + public final Component name; + @Getter public final ShopMoney shopMoney; + @Getter public final int price; + + + public WitchShopItem(Advancements advancements, CustomItem item, Component name, ShopMoney moneyItem, int price) { + this.advancements = advancements; + this.item = item; + this.name = name; + this.shopMoney = moneyItem; + this.price = price; + } + public WitchShopItem(Advancements advancements, CustomItem item, Component name, int price) { + this(advancements, item, name, ShopMoney.MONSTER_CANDY, price); + } + + public WitchShopItem(Advancements advancements, CustomItem item, int price) { + this(advancements, item, item.getBest().displayName(), price); + } + + public Component getName() { + if (HalloweenManager.hasUnlock(advancements)) + return name; + return Component.text("§knotunlockyet"); + } +} diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/WitchShopManager.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/WitchShopManager.java new file mode 100644 index 000000000..64573ea10 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/WitchShopManager.java @@ -0,0 +1,156 @@ +package fr.openmc.core.features.events.contents.halloween.halloween.shop; + +import dev.lone.itemsadder.api.FontImages.FontImageWrapper; +import fr.openmc.core.OMCRegistry; +import fr.openmc.core.features.adminshop.AdminShopUtils; +import fr.openmc.core.features.events.contents.halloween.halloween.HalloweenManager; +import fr.openmc.core.features.events.contents.halloween.halloween.dimension.advancement.Advancements; +import fr.openmc.core.hooks.itemsadder.ItemsAdderHook; +import fr.openmc.core.utils.bukkit.ItemUtils; +import fr.openmc.core.utils.text.messages.MessageType; +import fr.openmc.core.utils.text.messages.MessagesManager; +import fr.openmc.core.utils.text.messages.Prefix; +import fr.openmc.core.utils.text.messages.TranslationManager; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import org.bukkit.Sound; +import org.bukkit.entity.Player; + +import java.util.*; + +public class WitchShopManager { + + public static LinkedHashSet witchStoreItems; + public static Map> paginateWitchStoreItems; + + public static int maxPage; + + public static int SLOT_FACTOR = 28; + private static final Sound BUY_SOUND = Sound.ENTITY_WITCH_CELEBRATE; + private static final Sound ERROR_SOUND = Sound.ENTITY_WITCH_AMBIENT; + + public static void init() { + witchStoreItems = getWitchStoreItems(); + paginateWitchStoreItems = getPaginateWitchStoreItems(); + maxPage = getWitchStorePages(); + } + + private static Map> getPaginateWitchStoreItems() { + Map> paginateItems = new HashMap<>(); + + List list = new ArrayList<>(witchStoreItems); + + int page = 1; + + for (int i = 0; i < list.size(); i += SLOT_FACTOR) { + + List subList = list.subList(i, Math.min(i + SLOT_FACTOR, list.size())); + + paginateItems.put(page++, new HashSet<>(subList)); + } + + return paginateItems; + } + + public static Set getStoreContent(int page) { + if (paginateWitchStoreItems == null) + paginateWitchStoreItems = getPaginateWitchStoreItems(); + + if (page > maxPage) + page = maxPage; + + return paginateWitchStoreItems.get(page); + } + + private static int getWitchStorePages() { + return (int) Math.ceil((double) witchStoreItems.size() / SLOT_FACTOR); + } + + public static void buyItem(Player player, WitchShopItem item, int amount) { + if (item == null) return; + + if (amount <= 0) { + sendError(player, TranslationManager.translation("feature.adminshop.amount_sup")); //TODO + return; + } + + if (!ItemUtils.hasEnoughSpace(player, item.getItem().getBest(), amount)) { + sendError(player, TranslationManager.translation("feature.adminshop.inventory_full")); //TODO + return; + } + + if (item.getPrice() <= 0) { + sendError(player, TranslationManager.translation("feature.adminshop.item_not_sellable")); //TODO + return; + } + + int totalPrice = item.getPrice() * amount; + if (ItemUtils.hasEnoughItems(player, item.getItem().getBest(), totalPrice)) { + + ItemUtils.giveItem(player, item.getItem().getBest(), amount); + + sendInfo(player, TranslationManager.translation("feature.adminshop.player_buy_item", //TODO + Component.text(amount), item.getName(), Component.text(AdminShopUtils.formatPrice(totalPrice)) + )); + + player.playSound(player, BUY_SOUND, 1f, new Random().nextFloat(0.6f, 1.4f)); + } else { + sendError(player, TranslationManager.translation("feature.adminshop.have_enough_money")); //TODO + } + } + + private static void sendError(Player player, Component message) { + MessagesManager.sendMessage(player, message, Prefix.HALLOWEEN, MessageType.ERROR, true); + player.playSound(player, ERROR_SOUND, 1f,1f); + } + + private static void sendInfo(Player player, Component message) { + MessagesManager.sendMessage(player, message, Prefix.HALLOWEEN, MessageType.INFO, true); + } + + public static List extractLoreForItem(WitchShopItem item) { + List lore = new ArrayList<>(); + + if (HalloweenManager.hasUnlock(item.getAdvancements())) { + lore.add(TranslationManager.translation("feature.adminshop.lore_item.buy", //TODO + getPrice(item) + ).color(NamedTextColor.GREEN).decoration(TextDecoration.ITALIC, false)); + + } + else { + lore.add(TranslationManager.translation("feature.adminshop.lore_item.buy." + item.getAdvancements().name().toLowerCase()) //TODO change key + .color(NamedTextColor.GREEN).decoration(TextDecoration.ITALIC, false)); + } + + return lore; + } + + public static Component getPrice(WitchShopItem item) { + return Component.text(item.getPrice() + " " + item.getShopMoney().getIcon()); + } + + public static String getMoneyItemIcon(String icon) { + if (ItemsAdderHook.isEnable()) { + return FontImageWrapper.replaceFontImages("§f:"+icon+":"); + } else { + return "Ⓐ"; //TODO Translationmanager.translate("<...>." + icon) + } + } + + //TODO mettre les vrais items + private static LinkedHashSet getWitchStoreItems() { + LinkedHashSet items = new LinkedHashSet<>(); + + items.add(new WitchShopItem( + Advancements.ROOM_1, OMCRegistry.CUSTOM_ITEMS.AYWENITE, 10)); + + items.add(new WitchShopItem( + Advancements.ROOM_2, OMCRegistry.CUSTOM_ITEMS.KEBAB, 10)); + + items.add(new WitchShopItem( + Advancements.ROOM_2, OMCRegistry.CUSTOM_ITEMS.NETHERITE_HAMMER, 1000)); + + return items; + } +} diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/menu/ConfirmMenu.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/menu/ConfirmMenu.java new file mode 100644 index 000000000..e2bda17a3 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/menu/ConfirmMenu.java @@ -0,0 +1,209 @@ +package fr.openmc.core.features.events.contents.halloween.halloween.shop.menu; + +import dev.lone.itemsadder.api.FontImages.FontImageWrapper; +import fr.openmc.api.input.dialog.DialogInput; +import fr.openmc.api.menulib.Menu; +import fr.openmc.api.menulib.utils.InventorySize; +import fr.openmc.api.menulib.utils.ItemMenuBuilder; +import fr.openmc.core.OMCRegistry; +import fr.openmc.core.features.adminshop.AdminShopManager; +import fr.openmc.core.features.adminshop.ShopItem; +import fr.openmc.core.features.economy.EconomyManager; +import fr.openmc.core.features.events.contents.halloween.halloween.shop.WitchShopItem; +import fr.openmc.core.features.events.contents.halloween.halloween.shop.WitchShopManager; +import fr.openmc.core.registry.items.CustomItem; +import fr.openmc.core.utils.bukkit.ItemUtils; +import fr.openmc.core.utils.text.messages.TranslationManager; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +public class ConfirmMenu extends Menu { + + private final WitchShopItem shopItem; + private int quantity; + private final int maxQuantity; + + public ConfirmMenu(Player owner, WitchShopItem shopItem) { + super(owner); + this.shopItem = shopItem; + this.quantity = 1; + this.maxQuantity = getMaxBuyQuantity(owner, shopItem); + } + + @Override + public @NotNull Component getName() { + return TranslationManager.translation("feature.adminshop.menu.confirm.name"); + } + + @Override + public String getTexture() { + return FontImageWrapper.replaceFontImages("§r§f:offset_-11::adminshop:"); + } + + @Override + public @NotNull InventorySize getInventorySize() { + return InventorySize.NORMAL; + } + + @Override + public void onInventoryClick(InventoryClickEvent inventoryClickEvent) {} + + @Override + public @NotNull Map getContent() { + Map content = new HashMap<>(); + int pricePerUnit = shopItem.getPrice(); + int totalPrice = pricePerUnit * quantity; + int quantityToStack = Math.max(0, quantity / 64); + + List lore = TranslationManager.translationLore("feature.adminshop.menu.confirm.lore", + Component.text(String.valueOf(quantity), NamedTextColor.WHITE), + Component.text(String.valueOf(quantityToStack), NamedTextColor.WHITE), + quantityToStack > 1 ? Component.text("s", NamedTextColor.WHITE) : Component.empty(), + Component.text(AdminShopManager.priceFormat.format(pricePerUnit), NamedTextColor.GREEN), + Component.text(shopItem.getShopMoney().getIcon(), NamedTextColor.GREEN), + Component.text(AdminShopManager.priceFormat.format(totalPrice), NamedTextColor.GREEN), + Component.text(shopItem.getShopMoney().getIcon(), NamedTextColor.GREEN) + + ); + + content.put(9, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.REFUSE_BTN, true)); + + content.put(10, createQuantityButton("-64", OMCRegistry.CUSTOM_ITEMS.BTN_64, event -> { + if (quantity > 64) quantity -= 64; + else quantity = 1; + this.open(); + })); + + content.put(11, createQuantityButton("-10", OMCRegistry.CUSTOM_ITEMS.MINUS_BTN, event -> { + if (quantity > 10) quantity -= 10; + else quantity = 1; + this.open(); + })); + + content.put(12, createQuantityButton("-1", OMCRegistry.CUSTOM_ITEMS.BTN_1, event -> { + if (quantity > 1) quantity--; + else quantity = 1; + this.open(); + })); + + content.put(13, new ItemMenuBuilder(this, shopItem.getItem(), meta -> { + meta.displayName(shopItem.getName().color(NamedTextColor.WHITE).decoration(TextDecoration.ITALIC, false)); + meta.lore(lore); + }).setOnClick(event -> { + if (event.getClick() == ClickType.MIDDLE) { + DialogInput.sendFloat( + getOwner(), + TranslationManager.translation("feature.adminshop.menu.confirm.input"), + 1, + maxQuantity, + quantity, + input -> { + if (input != null) { + int inputQuantity = (int) input.doubleValue(); + if (inputQuantity > 0) { + quantity = Math.min(inputQuantity, maxQuantity); + this.open(); + } + } + } + ); + } + })); + + content.put(14, createQuantityButton("+1", OMCRegistry.CUSTOM_ITEMS.BTN_1, event -> increaseQuantity(1))); + + content.put(15, createQuantityButton("+10", OMCRegistry.CUSTOM_ITEMS.BTN_10, event -> increaseQuantity(10))); + + content.put(16, createQuantityButton("+64", OMCRegistry.CUSTOM_ITEMS.BTN_64, event -> increaseQuantity(64))); + + content.put(17, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.ACCEPT_BTN, meta -> { + meta.displayName(TranslationManager.translation("messages.global.accept")); + }).setOnClick(event -> { + getOwner().closeInventory(); + WitchShopManager.buyItem(getOwner(), shopItem, quantity); + })); + + return content; + } + + /** + * Creates a quantity button with the specified text and item stack. + * + * @param text The text to display on the button. + * @param itemStack The item stack to use for the button. + * @param action The action to perform when the button is clicked. + * @return The created item stack. + */ + private ItemMenuBuilder createQuantityButton(String text, ItemStack itemStack, Consumer action) { + boolean plus = text.contains("+"); + return new ItemMenuBuilder(this, itemStack, meta -> + meta.displayName(TranslationManager.translation("feature.adminshop.menu.confirm.quantity", + plus ? + TranslationManager.translation("feature.adminshop.menu.confirm.add") : + TranslationManager.translation("feature.adminshop.menu.confirm.remove"), + Component.text(text.replace("+", "").replace("-", ""))) + .color(plus ? NamedTextColor.GREEN : NamedTextColor.RED) + .decoration(TextDecoration.ITALIC, false))) + .setItemId("quantity_" + text.replace("+", "plus").replace("-", "minus")) + .setOnClick(action); + } + + /** + * Creates a quantity button with the specified text and item stack. + * + * @param text The text to display on the button. + * @param customItem The CustomItem to use for the button. + * @param action The action to perform when the button is clicked. + * @return The created item stack. + */ + private ItemMenuBuilder createQuantityButton(String text, CustomItem customItem, Consumer action) { + return this.createQuantityButton(text, customItem.getBest(), action); + } + + /** + * Increases the quantity by the specified amount, ensuring it does not exceed the maximum allowed quantity. + * + * @param amount The amount to increase the quantity by. + */ + private void increaseQuantity(int amount) { + quantity = Math.min(quantity + amount, maxQuantity); + this.open(); + } + + private int getMaxBuyQuantity(Player player, WitchShopItem shopItem) { + int freePlaces = ItemUtils.getFreePlacesForItem(player, shopItem.getItem().getBest()); + + double buyPrice = shopItem.getPrice(); + if (buyPrice <= 0) return freePlaces; + + double balance = ItemUtils.countItems(player, shopItem.getItem().getBest()); + int affordable = (int) Math.floor(balance / buyPrice); + + return Math.min(freePlaces, affordable); + } + + + @Override + public void onClose(InventoryCloseEvent event) { + //empty + } + + @Override + public List getTakableSlot() { + return List.of(); + } +} diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/menu/WitchShopMainMenu.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/menu/WitchShopMainMenu.java new file mode 100644 index 000000000..3b0b700be --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/menu/WitchShopMainMenu.java @@ -0,0 +1,72 @@ +package fr.openmc.core.features.events.contents.halloween.halloween.shop.menu; + +import fr.openmc.api.menulib.Menu; +import fr.openmc.api.menulib.utils.InventorySize; +import fr.openmc.api.menulib.utils.ItemMenuBuilder; +import fr.openmc.core.features.events.contents.halloween.halloween.shop.menu.buttons.WitchHouseButton; +import fr.openmc.core.features.events.contents.halloween.halloween.shop.menu.buttons.WitchStoreButton; +import fr.openmc.core.utils.text.messages.TranslationManager; +import net.kyori.adventure.text.Component; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class WitchShopMainMenu extends Menu { + + private static final int[] WITCH_HOUSE_SLOTS = {9, 10, 11, 12, 13, 18, 19, 20, 21, 22, 27, 28, 29, 30, 31, 36, 37, 38, 39, 40, 45, 46, 47, 48, 49}; + private static final int[] WITCH_SHOP_SLOTS = {23, 24, 25, 26, 32, 33, 34, 35, 41, 42, 43, 44, 50, 51, 52, 53}; + private static final Sound WITCH_MENU_CLOSE = Sound.ENTITY_WITCH_AMBIENT; + + public WitchShopMainMenu(Player owner) { + super(owner); + } + + @Override + public @NotNull Component getName() { + return TranslationManager.translation("feature.city.menus.main.name"); //TODO + } + + @Override + public String getTexture() { + return "§r§f:offset_-48::halloween_event_main_menu:"; + } + + @Override + public @NotNull InventorySize getInventorySize() { + return InventorySize.LARGEST; + } + + @Override + public @NotNull Map getContent() { + Map inventory = new HashMap<>(); + + // ** Witch House Button + WitchHouseButton.init(this, inventory, WITCH_HOUSE_SLOTS); + + // ** Witch Store Button + WitchStoreButton.init(this, inventory, WITCH_SHOP_SLOTS); + + return inventory; + } + + @Override + public List getTakableSlot() { + return List.of(); + } + + @Override + public void onClose(InventoryCloseEvent event) { + Player player = getOwner(); + player.playSound(player, WITCH_MENU_CLOSE, 1f, 1f); + } + + @Override + public void onInventoryClick(InventoryClickEvent click) { + } +} diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/menu/WitchShopStoreMenu.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/menu/WitchShopStoreMenu.java new file mode 100644 index 000000000..a6e92ac56 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/menu/WitchShopStoreMenu.java @@ -0,0 +1,180 @@ +package fr.openmc.core.features.events.contents.halloween.halloween.shop.menu; + +import fr.openmc.api.menulib.MenuLib; +import fr.openmc.api.menulib.PaginatedMenu; +import fr.openmc.api.menulib.utils.InventorySize; +import fr.openmc.api.menulib.utils.ItemMenuBuilder; +import fr.openmc.api.menulib.utils.MenuUtils; +import fr.openmc.api.menulib.utils.StaticSlots; +import fr.openmc.core.OMCPlugin; +import fr.openmc.core.OMCRegistry; +import fr.openmc.core.bootstrap.integration.OMCLogger; +import fr.openmc.core.commands.utils.Restart; +import fr.openmc.core.features.city.City; +import fr.openmc.core.features.city.CityManager; +import fr.openmc.core.features.city.CityPermission; +import fr.openmc.core.features.city.actions.CityChestAction; +import fr.openmc.core.features.city.menu.CityChestMenu; +import fr.openmc.core.features.city.sub.milestone.rewards.ChestPageLimitRewards; +import fr.openmc.core.features.economy.EconomyManager; +import fr.openmc.core.features.events.contents.halloween.halloween.shop.WitchShopItem; +import fr.openmc.core.features.events.contents.halloween.halloween.shop.WitchShopManager; +import fr.openmc.core.utils.text.messages.TranslationManager; +import lombok.Getter; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.minecraft.world.level.levelgen.Column; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import static fr.openmc.core.features.city.conditions.CityChestConditions.*; + +public class WitchShopStoreMenu extends PaginatedMenu { + + @Getter + private final int page; + + private final Column.Range line = new Column.Range(10, 16); + private final int column = 4; + + public WitchShopStoreMenu(Player owner, int page) { + super(owner); + this.page = page; + + if (this.page < 1) { + throw new IllegalArgumentException("Page must be greater than 0"); + } + + if (this.page > WitchShopManager.maxPage) { + throw new IllegalArgumentException("Page must be less than or equal to " + WitchShopManager.maxPage); + } + } + + @Override + public @Nullable Material getBorderMaterial() { + return Material.AIR; + } + + @Override + public @NotNull List getStaticSlots() { + return StaticSlots.getStandardSlots(getInventorySize()); + } + + @Override + public List getItems() { + + List items = new ArrayList<>(); + + Iterator contents = WitchShopManager.getStoreContent(this.page).iterator(); + + for (int c = 0; c < column; c++) { + for (int l = line.floor(); l <= line.ceiling(); l++) { + + if (!contents.hasNext()) break; + + WitchShopItem item = contents.next(); + + items.add(new ItemMenuBuilder(this, item.getItem(), itemMeta -> { + itemMeta.displayName(item.getName()); + itemMeta.lore(WitchShopManager.extractLoreForItem(item)); + }).setOnClick(event -> { + //TODO open confirm menu if has enough moneyItem + })); + } + } + + return items; + } + + @Override + public Map getButtons() { + if (Restart.isRestarting) return null; + + Map map = new HashMap<>(); + + if (hasPreviousPage()) { + map.put(45, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_BACK_ORANGE, itemMeta -> { + itemMeta.displayName(TranslationManager.translation("messages.menus.previous_page")); + }).setPreviousPageButton()); + } + + map.put(49, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_CANCEL, itemMeta -> { + itemMeta.displayName(TranslationManager.translation("messages.menus.close")); + }).setOnClick(event -> { + new WitchShopMainMenu(getOwner()).open(); + })); + + //TODO filter : + // - room + // - unlocked + // - lower cost + // - highest cost + + if (hasNextPage()) { + map.put(53, new ItemMenuBuilder(this, OMCRegistry.CUSTOM_ITEMS.ICON_NEXT_ORANGE, itemMeta -> { + itemMeta.displayName(TranslationManager.translation("messages.menus.next_page")); + }).setNextPageButton()); + } + + return map; + } + + @Override + public @NotNull Component getName() { + return TranslationManager.translation("feature.city.menus.chest.name", + Component.text(""), Component.text(this.page)); //TODO + } + + @Override + public String getTexture() { + return "§r§f:offset_-48::city_template6x9:"; //TODO + } + + @Override + public void onInventoryClick(InventoryClickEvent inventoryClickEvent) { + } + + @Override + public @NotNull InventorySize getInventorySize() { + return InventorySize.LARGEST; + } + + @Override + public int getSizeOfItems() { + return getItems().size(); + } + + @Override + public void onClose(InventoryCloseEvent event) { + if (Restart.isRestarting) return; + HumanEntity humanEntity = event.getPlayer(); + if (!(humanEntity instanceof Player player)) return; + // fixes #1007 + Bukkit.getScheduler().runTaskLater(OMCPlugin.getInstance(), ()-> MenuLib.updateMenu(player), 5L); + } + + @Override + public List getTakableSlot() { + return List.of(); + } + + public boolean hasNextPage() { + return this.page < WitchShopManager.maxPage; + } + + public boolean hasPreviousPage() { + return this.page > 1; + } +} diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/menu/buttons/WitchHouseButton.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/menu/buttons/WitchHouseButton.java new file mode 100644 index 000000000..73d49c62f --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/menu/buttons/WitchHouseButton.java @@ -0,0 +1,34 @@ +package fr.openmc.core.features.events.contents.halloween.halloween.shop.menu.buttons; + +import fr.openmc.api.menulib.Menu; +import fr.openmc.api.menulib.utils.ItemMenuBuilder; +import fr.openmc.api.menulib.utils.MenuUtils; +import fr.openmc.core.utils.text.messages.TranslationManager; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Player; + +import java.util.Map; + +public class WitchHouseButton { + public static void init(Menu menu, Map contents, int[] slots) { + Player player = menu.getOwner(); + + MenuUtils.createButtonItem( + contents, + slots, + new ItemMenuBuilder(menu, Material.PAPER, itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.city.menus.main.ranks.title"));//TODO + itemMeta.lore(TranslationManager.translationLore( + "feature.city.menus.main.ranks.lore.unlocked", //TODO + Component.text("").color(NamedTextColor.LIGHT_PURPLE) + )); + itemMeta.setItemModel(NamespacedKey.minecraft("air")); + }).setCloseButton()//.setOnClick(inventoryClickEvent -> { //TODO tp dans la dimension +// inventoryClickEvent.getClickedInventory().close(); +// }) + ); + } +} diff --git a/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/menu/buttons/WitchStoreButton.java b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/menu/buttons/WitchStoreButton.java new file mode 100644 index 000000000..0266329a2 --- /dev/null +++ b/src/main/java/fr/openmc/core/features/events/contents/halloween/halloween/shop/menu/buttons/WitchStoreButton.java @@ -0,0 +1,42 @@ +package fr.openmc.core.features.events.contents.halloween.halloween.shop.menu.buttons; + +import fr.openmc.api.menulib.Menu; +import fr.openmc.api.menulib.utils.ItemMenuBuilder; +import fr.openmc.api.menulib.utils.MenuUtils; +import fr.openmc.core.features.city.City; +import fr.openmc.core.features.city.sub.milestone.rewards.FeaturesRewards; +import fr.openmc.core.features.city.sub.rank.menus.CityRanksMenu; +import fr.openmc.core.features.events.contents.halloween.halloween.shop.menu.WitchShopStoreMenu; +import fr.openmc.core.utils.text.messages.MessageType; +import fr.openmc.core.utils.text.messages.MessagesManager; +import fr.openmc.core.utils.text.messages.Prefix; +import fr.openmc.core.utils.text.messages.TranslationManager; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.Map; + +public class WitchStoreButton { + public static void init(Menu menu, Map contents, int[] slots) { + Player player = menu.getOwner(); + + MenuUtils.createButtonItem( + contents, + slots, + new ItemMenuBuilder(menu, Material.PAPER, itemMeta -> { + itemMeta.displayName(TranslationManager.translation("feature.city.menus.main.ranks.title")); //TODO + itemMeta.lore(TranslationManager.translationLore( + "feature.city.menus.main.ranks.lore.unlocked", //TODO + Component.text("").color(NamedTextColor.LIGHT_PURPLE) + )); + itemMeta.setItemModel(NamespacedKey.minecraft("air")); + }).setOnClick(inventoryClickEvent -> { + new WitchShopStoreMenu(player, 1).open(); + }) + ); + } +} diff --git a/src/main/java/fr/openmc/core/registry/items/CustomItemRegistry.java b/src/main/java/fr/openmc/core/registry/items/CustomItemRegistry.java index 597c02ab5..d44d5d2f4 100644 --- a/src/main/java/fr/openmc/core/registry/items/CustomItemRegistry.java +++ b/src/main/java/fr/openmc/core/registry/items/CustomItemRegistry.java @@ -15,6 +15,7 @@ import fr.openmc.core.features.events.contents.dailyevents.contents.miraculousfishing.contents.items.FishingFurnitureLootbox; import fr.openmc.core.features.events.contents.dailyevents.contents.miraculousfishing.contents.items.LegendaryFishingTreasureLootbox; import fr.openmc.core.features.events.contents.dailyevents.contents.miraculousfishing.contents.items.RareFishingTreasureLootbox; +import fr.openmc.core.features.events.contents.halloween.halloween.CandyItem; import fr.openmc.core.features.itemsadder.elevator.ElevatorBlock; import fr.openmc.core.features.itemsadder.elevator.ElevatorColor; import fr.openmc.core.hooks.itemsadder.ItemsAdderHook; @@ -194,6 +195,13 @@ public class CustomItemRegistry extends Registry public final CustomItem ABONDANCE_LEGGINGS = register("omc_daily_events:abondance_leggings", Material.IRON_LEGGINGS); public final CustomItem ABONDANCE_BOOTS = register("omc_daily_events:abondance_boots", Material.IRON_BOOTS); + public final CustomItem CANDY_RED = register(new CandyItem("omc_halloween:candy_red", 4, Material.APPLE)); + public final CustomItem CANDY_YELLOW = register(new CandyItem("omc_halloween:candy_yellow", 2, Material.APPLE)); + public final CustomItem CANDY_GREEN = register(new CandyItem("omc_halloween:candy_green", 3, Material.APPLE)); + public final CustomItem CANDY_BLUE = register(new CandyItem("omc_halloween:candy_blue", 5, Material.APPLE)); + public final CustomItem CANDY_BROWN = register(new CandyItem("omc_halloween:candy_brown", 20, Material.APPLE)); + + /* Lootbox */ public final CustomItem KITCHEN_BARSTOOL = register("kitchen:kitchen_barstool", Material.PAPER); public final CustomItem KITCHEN_BIN = register("kitchen:kitchen_bin", Material.PAPER); public final CustomItem KITCHEN_CHAIR = register("kitchen:kitchen_chair", Material.PAPER); diff --git a/src/main/java/fr/openmc/core/registry/regions/preset/SquareRegion.java b/src/main/java/fr/openmc/core/registry/regions/preset/SquareRegion.java new file mode 100644 index 000000000..ab809e99b --- /dev/null +++ b/src/main/java/fr/openmc/core/registry/regions/preset/SquareRegion.java @@ -0,0 +1,59 @@ +package fr.openmc.core.registry.regions.preset; + +import com.sk89q.worldedit.math.BlockVector3; +import fr.openmc.core.registry.regions.CustomRegion; +import net.kyori.adventure.key.Key; +import org.bukkit.World; + +public class SquareRegion extends CustomRegion { + + public World world; + public BlockVector3 min; + public BlockVector3 max; + public Key key; + + public SquareRegion(World world, BlockVector3 min, BlockVector3 max) { + this(world, min, max, null); + } + + public SquareRegion(World world, BlockVector3 min, BlockVector3 max, Key key) { + this.world = world; + this.min = min; + this.max = max; + this.key = key; + } + + @Override + public Key getKey() { + return key; + } + + @Override + public World getWorld() { + return world; + } + + @Override + public boolean contains(BlockVector3 pos) { + double x = pos.x(); + double y = pos.y(); + double z = pos.z(); + + return x >= Math.min(getMin().x(), getMax().x()) && + x <= Math.max(getMin().x(), getMax().x()) && + y >= Math.min(getMin().y(), getMax().y()) && + y <= Math.max(getMin().y(), getMax().y()) && + z >= Math.min(getMin().z(), getMax().z()) && + z <= Math.max(getMin().z(), getMax().z()); + } + + @Override + public BlockVector3 getMin() { + return min; + } + + @Override + public BlockVector3 getMax() { + return max; + } +} diff --git a/src/main/java/fr/openmc/core/registry/structures/CustomStructure.java b/src/main/java/fr/openmc/core/registry/structures/CustomStructure.java new file mode 100644 index 000000000..9c5741f0d --- /dev/null +++ b/src/main/java/fr/openmc/core/registry/structures/CustomStructure.java @@ -0,0 +1,69 @@ +package fr.openmc.core.registry.structures; + +import lombok.Getter; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtAccounter; +import net.minecraft.nbt.NbtIo; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; +import org.bukkit.Location; +import org.bukkit.craftbukkit.CraftWorld; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; + +public class CustomStructure { + + @Getter + String id; + File file; + + public CustomStructure(String id, File file) { + this.id = id; + this.file = file; + } + + public void placeStructure(Location origin, boolean mirrorX, boolean mirrorZ) { + ServerLevel level = ((CraftWorld) origin.getWorld()).getHandle(); + + try (InputStream in = new FileInputStream(file)) { + + CompoundTag tag = NbtIo.readCompressed(in, NbtAccounter.unlimitedHeap()); + + StructureTemplate template = new StructureTemplate(); + + template.load( + level.registryAccess().lookupOrThrow(Registries.BLOCK), + tag + ); + + StructurePlaceSettings settings = new StructurePlaceSettings(); + + if (mirrorX) settings.setMirror(Mirror.FRONT_BACK); + if (mirrorZ) settings.setMirror(Mirror.LEFT_RIGHT); + + settings.setRotation(Rotation.NONE); + + BlockPos pos = new BlockPos(origin.getBlockX(), origin.getBlockY(), origin.getBlockZ()); + + template.placeInWorld( + level, + pos, + pos, + settings, + level.getRandom(), + 2 + ); + + } catch (Exception e) { + e.printStackTrace(); + } + } +} + diff --git a/src/main/java/fr/openmc/core/registry/structures/CustomStructureRegistry.java b/src/main/java/fr/openmc/core/registry/structures/CustomStructureRegistry.java new file mode 100644 index 000000000..002f6a35b --- /dev/null +++ b/src/main/java/fr/openmc/core/registry/structures/CustomStructureRegistry.java @@ -0,0 +1,36 @@ +package fr.openmc.core.registry.structures; + +import fr.openmc.core.OMCPlugin; +import fr.openmc.core.bootstrap.registries.KeyedRegistry; +import fr.openmc.core.bootstrap.registries.Registry; +import fr.openmc.core.utils.FilesUtils; + +import java.io.File; + +public class CustomStructureRegistry extends Registry + implements KeyedRegistry { + + private static final File structureFolder = new File(OMCPlugin.getInstance().getDataFolder(), "data/omc_structure"); + + // ** REGISTER STRUCTURES ** + public final CustomStructure TEST = register("omc_structure:test","pillar.nbt"); + + public CustomStructureRegistry() { + FilesUtils.createDirectoryIfNotExists(structureFolder); + } + + @Override + public String key(CustomStructure registryObject) { + return registryObject.getId(); + } + + public CustomStructure register(String name, String fileName) { + return register(name, new File(structureFolder, fileName)); + } + + public CustomStructure register(String name, File file) { + if (file == null || name == null) return null; + if (!file.exists()) return null; + return KeyedRegistry.super.register(new CustomStructure(name, file)); + } +} \ No newline at end of file diff --git a/src/main/java/fr/openmc/core/utils/text/messages/Prefix.java b/src/main/java/fr/openmc/core/utils/text/messages/Prefix.java index bf240ee3b..ee8651e4e 100644 --- a/src/main/java/fr/openmc/core/utils/text/messages/Prefix.java +++ b/src/main/java/fr/openmc/core/utils/text/messages/Prefix.java @@ -37,7 +37,8 @@ public enum Prefix { HALLOWEEN("halloween"), DIMOPENER("dimopener"), GOLDEN_HARVEST("golden harvest"), - MIRACULOUS_FISHING("miraculous fishing"); + MIRACULOUS_FISHING("miraculous fishing"), + LUCKYBLOCK("luckyblock"); @Getter private final Component prefix; diff --git a/src/main/resources/contents/omc_daily_events/items.yml b/src/main/resources/contents/omc_daily_events/items.yml index 8bd96d2aa..f96c925bf 100644 --- a/src/main/resources/contents/omc_daily_events/items.yml +++ b/src/main/resources/contents/omc_daily_events/items.yml @@ -66,6 +66,71 @@ items: - - + candy_red: + display_name: + resource: + generate: true + textures: + - candy/candy_red + material: PAPER + lore: + - + consumable: + nutrition: 1 + saturation: 0.6 + + candy_yellow: + display_name: + resource: + generate: true + textures: + - candy/candy_yellow + material: PAPER + lore: + - + consumable: + nutrition: 1 + saturation: 0.6 + + candy_green: + display_name: + resource: + generate: true + textures: + - candy/candy_green + material: PAPER + lore: + - + consumable: + nutrition: 1 + saturation: 0.6 + + candy_blue: + display_name: + resource: + generate: true + textures: + - candy/candy_blue + material: PAPER + lore: + - + consumable: + nutrition: 1 + saturation: 0.6 + + candy_brown: + display_name: + resource: + generate: true + textures: + - candy/candy_brown + material: PAPER + lore: + - + consumable: + nutrition: 1 + saturation: 0.6 + recipes: iaa_crafting_table: fermentum: diff --git a/src/main/resources/contents/omc_halloween/configs/fonts.yml b/src/main/resources/contents/omc_halloween/configs/fonts.yml new file mode 100644 index 000000000..e17c69365 --- /dev/null +++ b/src/main/resources/contents/omc_halloween/configs/fonts.yml @@ -0,0 +1,33 @@ +info: + namespace: omc_halloween +font_images: + candy_red: + permission: candy_red + show_in_gui: true + path: "candy/candy_red.png" + scale_ratio: 12 + y_position: 9 + candy_yellow: + permission: candy_yellow + show_in_gui: true + path: "candy/candy_yellow.png" + scale_ratio: 12 + y_position: 9 + candy_green: + permission: candy_green + show_in_gui: true + path: "candy/candy_green.png" + scale_ratio: 12 + y_position: 9 + candy_blue: + permission: candy_blue + show_in_gui: true + path: "candy/candy_blue.png" + scale_ratio: 12 + y_position: 9 + candy_brown: + permission: candy_brown + show_in_gui: true + path: "candy/candy_brown.png" + scale_ratio: 12 + y_position: 9 \ No newline at end of file diff --git a/src/main/resources/contents/omc_halloween/configs/items.yml b/src/main/resources/contents/omc_halloween/configs/items.yml new file mode 100644 index 000000000..040fa93ed --- /dev/null +++ b/src/main/resources/contents/omc_halloween/configs/items.yml @@ -0,0 +1,110 @@ +info: + namespace: omc_halloween + +items: + candy_red: + display_name: + resource: + generate: true + textures: + - candy/candy_red + material: PAPER + lore: + - + consumable: + nutrition: 1 + saturation: 0.6 + + candy_yellow: + display_name: + resource: + generate: true + textures: + - candy/candy_yellow + material: PAPER + lore: + - + consumable: + nutrition: 1 + saturation: 0.6 + + candy_green: + display_name: + resource: + generate: true + textures: + - candy/candy_green + material: PAPER + lore: + - + consumable: + nutrition: 1 + saturation: 0.6 + + candy_blue: + display_name: + resource: + generate: true + textures: + - candy/candy_blue + material: PAPER + lore: + - + consumable: + nutrition: 1 + saturation: 0.6 + + candy_brown: + display_name: + resource: + generate: true + textures: + - candy/candy_brown + material: PAPER + lore: + - + consumable: + nutrition: 1 + saturation: 0.6 + +recipes: + iaa_crafting_table: + fermentum: + shapeless: true + ingredients: + - item: omc_daily_events:golden_wheat + amount: 5 + - item: omc_daily_events:golden_beetroot + amount: 5 + - item: omc_daily_events:really_golden_carrot + amount: 5 + - item: omc_daily_events:golden_potato + amount: 5 + - item: omc_daily_events:golden_melon + amount: 5 + - item: omc_daily_events:golden_pumpkin + amount: 5 + result: + item: omc_daily_events:fermentum + + blessed_bread: + enabled: true + pattern: + - FFF + - XXX + - XXX + pattern_2: + - XXX + - FFF + - XXX + pattern_3: + - XXX + - XXX + - FFF + ingredients: + F: + item: omc_daily_events:golden_wheat + amount: 192 + result: + item: omc_daily_events:blessed_bread + amount: 1 \ No newline at end of file diff --git a/src/main/resources/contents/omc_halloween/textures/candy/candy_blue.png b/src/main/resources/contents/omc_halloween/textures/candy/candy_blue.png new file mode 100644 index 000000000..be6fd4e73 Binary files /dev/null and b/src/main/resources/contents/omc_halloween/textures/candy/candy_blue.png differ diff --git a/src/main/resources/contents/omc_halloween/textures/candy/candy_brown.png b/src/main/resources/contents/omc_halloween/textures/candy/candy_brown.png new file mode 100644 index 000000000..fcfae29a3 Binary files /dev/null and b/src/main/resources/contents/omc_halloween/textures/candy/candy_brown.png differ diff --git a/src/main/resources/contents/omc_halloween/textures/candy/candy_green.png b/src/main/resources/contents/omc_halloween/textures/candy/candy_green.png new file mode 100644 index 000000000..acac6625f Binary files /dev/null and b/src/main/resources/contents/omc_halloween/textures/candy/candy_green.png differ diff --git a/src/main/resources/contents/omc_halloween/textures/candy/candy_red.png b/src/main/resources/contents/omc_halloween/textures/candy/candy_red.png new file mode 100644 index 000000000..8e564fb23 Binary files /dev/null and b/src/main/resources/contents/omc_halloween/textures/candy/candy_red.png differ diff --git a/src/main/resources/contents/omc_halloween/textures/candy/candy_yellow.png b/src/main/resources/contents/omc_halloween/textures/candy/candy_yellow.png new file mode 100644 index 000000000..55ef12b3d Binary files /dev/null and b/src/main/resources/contents/omc_halloween/textures/candy/candy_yellow.png differ diff --git a/src/main/resources/contents/omc_icons/configs/fonts.yml b/src/main/resources/contents/omc_icons/configs/fonts.yml index d72d0d785..2a214f727 100644 --- a/src/main/resources/contents/omc_icons/configs/fonts.yml +++ b/src/main/resources/contents/omc_icons/configs/fonts.yml @@ -30,4 +30,4 @@ font_images: show_in_gui: true path: "font/bits.png" scale_ratio: 12 - y_position: 9 \ No newline at end of file + y_position: 9 diff --git a/src/main/resources/contents/omc_menus/configs/menus.yml b/src/main/resources/contents/omc_menus/configs/menus.yml index 6732011ac..411ed932c 100644 --- a/src/main/resources/contents/omc_menus/configs/menus.yml +++ b/src/main/resources/contents/omc_menus/configs/menus.yml @@ -61,6 +61,12 @@ font_images: suggestion_in_command: false path: "city_template6x9.png" y_position: 30 + halloween_event_main_menu: + permission: halloween.event_main_menu + show_in_gui: true + suggestion_in_command: false + path: "halloween_event_main_menu.png" + y_position: 30 home_mailbox: permission: mailbox.home show_in_gui: true diff --git a/src/main/resources/contents/omc_menus/textures/halloween_event_main_menu.png b/src/main/resources/contents/omc_menus/textures/halloween_event_main_menu.png new file mode 100644 index 000000000..dbf83e2ba Binary files /dev/null and b/src/main/resources/contents/omc_menus/textures/halloween_event_main_menu.png differ diff --git a/src/main/resources/datapacks/omc_halloween/data/omc_halloween/dimension/witch_house.json b/src/main/resources/datapacks/omc_halloween/data/omc_halloween/dimension/witch_house.json new file mode 100644 index 000000000..25b5d79f6 --- /dev/null +++ b/src/main/resources/datapacks/omc_halloween/data/omc_halloween/dimension/witch_house.json @@ -0,0 +1,12 @@ +{ + "type": "minecraft:overworld", + "generator": { + "type": "minecraft:flat", + "settings": { + "biome": "draft:draft", + "lakes": false, + "features": false, + "layers": [] + } + } +} \ No newline at end of file diff --git a/src/main/resources/datapacks/omc_halloween/pack.mcmeta b/src/main/resources/datapacks/omc_halloween/pack.mcmeta new file mode 100644 index 000000000..a409a42ca --- /dev/null +++ b/src/main/resources/datapacks/omc_halloween/pack.mcmeta @@ -0,0 +1,8 @@ +{ + "pack": { + "description": "Le Pack de données de la Witch House d'OpenMC", + "pack_format": 107.1, + "min_format": 107.1, + "max_format": 107.1 + } +} \ No newline at end of file