diff --git a/ItemsAdder Example Config/item_frame/base.yml b/ItemsAdder Example Config/item_frame/base.yml deleted file mode 100644 index f83cd6b..0000000 --- a/ItemsAdder Example Config/item_frame/base.yml +++ /dev/null @@ -1,313 +0,0 @@ -info: - namespace: customcrops -items: -###################### -# Pot # -###################### - pot: - display_name: Pot - #display_name: 种植盆 - resource: - material: PAPER - generate: false - model_path: 'base/pot' - specific_properties: - block: - placed_model: - type: REAL_NOTE - break_particles: ITEM - sound: - place: - name: block.wood.place - break: - name: block.wood.break - watered_pot: - display_name: Watered Pot - #display_name: 湿润的种植盆 - resource: - material: PAPER - generate: false - model_path: 'base/watered_pot' - specific_properties: - block: - placed_model: - type: REAL_NOTE - break_particles: ITEM - cancel_drop: true - sound: - place: - name: block.wood.place - break: - name: block.wood.break - -############################################ -# # -# ItemFrame / ArmorStand # -# Recommend using armor_stand because # -# it's easier for player to interact # -# # -############################################ - sprinkler_1: - display_name: Sprinkler3D - #display_name: 洒水器 - resource: - material: PAPER - generate: false - model_path: 'base/sprinkler_1' - behaviours: - furniture: - entity: armor_stand - fixed_rotation: true - solid: false - cancel_drop: true - hitbox: - length: 1 - width: 1 - height: 0.6 - placeable_on: - walls: false - ceiling: false - floor: true - events: - placed_armorstand: - break: - drop_item: - item: sprinkler_1_item - sprinkler_1_item: - display_name: Sprinkler - #display_name: 洒水器 - resource: - generate: false - material: PAPER - model_path: base/sprinkler_1_item - sprinkler_2: - display_name: Sprinkler3D - #display_name: 优质洒水器 - resource: - material: PAPER - generate: false - model_path: 'base/sprinkler_2' - behaviours: - furniture: - entity: armor_stand - fixed_rotation: true - solid: false - cancel_drop: true - hitbox: - length: 1 - width: 1 - height: 0.6 - placeable_on: - walls: false - ceiling: false - floor: true - events: - placed_armorstand: - break: - drop_item: - item: sprinkler_2_item - sprinkler_2_item: - display_name: Sprinkler - #display_name: 优质洒水器 - resource: - generate: false - material: PAPER - model_path: base/sprinkler_2_item - -#################### -# GreenHouse # -#################### - greenhouse_glass: - display_name: Greenhouse Glass - #display_name: 温室玻璃 - resource: - material: PAPER - generate: false - model_path: 'base/greenhouse_glass' - specific_properties: - block: - placed_model: - type: REAL_TRANSPARENT - break_particles: ITEM - sound: - place: - name: block.glass.place - break: - name: block.glass.break - - -#################### -# Stage # -#################### - crop_stage_death: - display_name: Dead Crops - #display_name: 枯萎的农作物 - resource: - generate: false - material: PAPER - model_path: base/death_crop - behaviours: - furniture: - entity: item_frame - fixed_rotation: false - solid: false - cancel_drop: true - hitbox: - length: 1 - width: 1 - height: 1 - placeable_on: - walls: false - ceiling: false - floor: true - events: - placed_itemframe: - break: - play_sound: - name: block.azalea.break - volume: 1 - pitch: 1 - -#################### -# Watering Can # -#################### - watering_can_1: - display_name: Copper Watering Can - #display_name: 铜水壶 - resource: - generate: false - material: GOLDEN_HORSE_ARMOR - model_path: base/watering_can_1 - watering_can_2: - display_name: Steel Watering Can - #display_name: 钢水壶 - resource: - generate: false - material: GOLDEN_HORSE_ARMOR - model_path: base/watering_can_2 - watering_can_3: - display_name: Golden Watering Can - #display_name: 金水壶 - resource: - generate: false - material: GOLDEN_HORSE_ARMOR - model_path: base/watering_can_3 - watering_can_4: - display_name: Iridium Watering Can - #display_name: 铱金水壶 - resource: - generate: false - material: GOLDEN_HORSE_ARMOR - model_path: base/watering_can_4 - - -#################### -# Fertilizer # -#################### - speed_1: - display_name: Speed-Gro - #display_name: 生长激素 - resource: - generate: false - material: PAPER - model_path: base/speed_1 - speed_2: - display_name: Deluxe Speed-Gro - #display_name: 高级生长激素 - resource: - generate: false - material: PAPER - model_path: base/speed_2 - speed_3: - display_name: Hyper Speed-Gro - #display_name: 超级生长激素 - resource: - generate: false - material: PAPER - model_path: base/speed_3 - - retaining_1: - display_name: Basic Retaining Soil - #display_name: 基础保湿土壤 - resource: - generate: false - material: PAPER - model_path: base/retaining_1 - retaining_2: - display_name: Quality Retaining Soil - #display_name: 品质保湿土壤 - resource: - generate: false - material: PAPER - model_path: base/retaining_2 - retaining_3: - display_name: Deluxe Retaining Soil - #display_name: 高级保湿土壤 - resource: - generate: false - material: PAPER - model_path: base/retaining_3 - - quality_1: - display_name: Basic Fertilizer - #display_name: 基础肥料 - resource: - generate: false - material: PAPER - model_path: base/quality_1 - quality_2: - display_name: Quality Fertilizer - #display_name: 优质肥料 - resource: - generate: false - material: PAPER - model_path: base/quality_2 - quality_3: - display_name: Deluxe Fertilizer - #display_name: 高级肥料 - resource: - generate: false - material: PAPER - model_path: base/quality_3 - - quantity_1: - display_name: Basic Yield Increasing - #display_name: 基础增产 - resource: - generate: false - material: PAPER - model_path: base/quantity_1 - quantity_2: - display_name: Quality Yield Increasing - #display_name: 优质增产 - resource: - generate: false - material: PAPER - model_path: base/quantity_2 - quantity_3: - display_name: Deluxe Yield Increasing - #display_name: 高级增产 - resource: - generate: false - material: PAPER - model_path: base/quantity_3 - - soil_detector: - display_name: Soil Surveyor - #display_name: 肥料勘测器 - resource: - generate: false - material: PAPER - model_path: base/soil_detector - -loots: - blocks: - watered_pot: - type: customcrops:watered_pot - items: - result_1: - item: customcrops:pot - min_amount: 1 - max_amount: 1 - chance: 100 - ignore_fortune: true \ No newline at end of file diff --git a/ItemsAdder Example Config/item_frame/tomato.yml b/ItemsAdder Example Config/item_frame/tomato.yml deleted file mode 100644 index 40ea0dd..0000000 --- a/ItemsAdder Example Config/item_frame/tomato.yml +++ /dev/null @@ -1,156 +0,0 @@ -info: - namespace: customcrops -items: - tomato_stage_1: - display_name: "" - resource: - generate: false - material: PAPER - model_path: tomato/stage_1 - behaviours: - furniture: - entity: item_frame - fixed_rotation: false - solid: false - cancel_drop: true - hitbox: - length: 1 - width: 1 - height: 1 - placeable_on: - walls: false - ceiling: false - floor: true - events: - placed_itemframe: - break: - play_sound: - name: block.azalea.break - volume: 1 - pitch: 1 - drop_item: - item: tomato_seeds - tomato_stage_2: - display_name: "" - resource: - generate: false - material: PAPER - model_path: tomato/stage_2 - behaviours: - furniture: - entity: item_frame - fixed_rotation: false - solid: false - cancel_drop: true - hitbox: - length: 1 - width: 1 - height: 1 - placeable_on: - walls: false - ceiling: false - floor: true - events: - placed_itemframe: - break: - play_sound: - name: block.azalea.break - volume: 1 - pitch: 1 - drop_item: - item: tomato_seeds - tomato_stage_3: - display_name: "" - resource: - generate: false - material: PAPER - model_path: tomato/stage_3 - behaviours: - furniture: - entity: item_frame - fixed_rotation: false - solid: false - cancel_drop: true - hitbox: - length: 1 - width: 1 - height: 1 - placeable_on: - walls: false - ceiling: false - floor: true - events: - placed_itemframe: - break: - play_sound: - name: block.azalea.break - volume: 1 - pitch: 1 - drop_item: - item: tomato_seeds - tomato_stage_4: - display_name: "" - resource: - generate: false - material: PAPER - model_path: tomato/stage_4 - behaviours: - furniture: - entity: item_frame - fixed_rotation: false - solid: false - cancel_drop: true - hitbox: - length: 1 - width: 1 - height: 1 - placeable_on: - walls: false - ceiling: false - floor: true - events: - placed_itemframe: - break: - play_sound: - name: block.azalea.break - volume: 1 - pitch: 1 - tomato_seeds: - display_name: "Tomato Seeds" - #display_name: 番茄种子 - resource: - generate: false - material: PAPER - model_path: tomato/tomato_seeds - tomato: - display_name: "Tomato" - #display_name: 番茄 - resource: - generate: false - material: APPLE - model_path: tomato/tomato - tomato_silver_star: - display_name: "Tomato (Silver Star)" - #display_name: 番茄(银星) - resource: - generate: false - material: APPLE - model_path: tomato/tomato_silver_star - tomato_golden_star: - display_name: "Tomato (Golden Star)" - #display_name: 番茄(金星) - resource: - generate: false - material: APPLE - model_path: tomato/tomato_golden_star - gigantic_tomato: - display_name: "Overgrown Tomato" - #display_name: 巨型番茄 - resource: - generate: false - material: PAPER - model_path: tomato/gigantic_tomato - specific_properties: - block: - placed_model: - type: REAL_TRANSPARENT \ No newline at end of file diff --git a/ItemsAdder Example Config/tripwire/base.yml b/ItemsAdder Example Config/tripwire/base.yml deleted file mode 100644 index dee1f49..0000000 --- a/ItemsAdder Example Config/tripwire/base.yml +++ /dev/null @@ -1,302 +0,0 @@ -info: - namespace: customcrops -items: -###################### -# Pot # -###################### - pot: - display_name: Pot - #display_name: 种植盆 - resource: - material: PAPER - generate: false - model_path: 'base/pot' - specific_properties: - block: - placed_model: - type: REAL_NOTE - break_particles: ITEM - sound: - place: - name: block.wood.place - break: - name: block.wood.break - watered_pot: - display_name: Watered Pot - #display_name: 湿润的种植盆 - resource: - material: PAPER - generate: false - model_path: 'base/watered_pot' - specific_properties: - block: - placed_model: - type: REAL_NOTE - break_particles: ITEM - cancel_drop: true - sound: - place: - name: block.wood.place - break: - name: block.wood.break - -############################################ -# # -# ItemFrame / ArmorStand # -# Recommend using armor_stand because # -# it's easier for player to interact # -# # -############################################ - sprinkler_1: - display_name: Sprinkler3D - #display_name: 洒水器 - resource: - material: PAPER - generate: false - model_path: 'base/sprinkler_1' - behaviours: - furniture: - entity: armor_stand - fixed_rotation: true - solid: false - cancel_drop: true - hitbox: - length: 1 - width: 1 - height: 1 - placeable_on: - walls: false - ceiling: false - floor: true - events: - placed_armorstand: - break: - drop_item: - item: sprinkler_1_item - sprinkler_1_item: - display_name: Sprinkler - #display_name: 洒水器 - resource: - generate: false - material: PAPER - model_path: base/sprinkler_1_item - sprinkler_2: - display_name: Sprinkler3D - #display_name: 优质洒水器 - resource: - material: PAPER - generate: false - model_path: 'base/sprinkler_2' - behaviours: - furniture: - entity: armor_stand - fixed_rotation: true - solid: false - cancel_drop: true - hitbox: - length: 1 - width: 1 - height: 1 - placeable_on: - walls: false - ceiling: false - floor: true - events: - placed_armorstand: - break: - drop_item: - item: sprinkler_2_item - sprinkler_2_item: - display_name: Sprinkler - #display_name: 优质洒水器 - resource: - generate: false - material: PAPER - model_path: base/sprinkler_2_item - -#################### -# GreenHouse # -#################### - greenhouse_glass: - display_name: Greenhouse Glass - #display_name: 温室玻璃 - resource: - material: PAPER - generate: false - model_path: 'base/greenhouse_glass' - specific_properties: - block: - placed_model: - type: REAL_TRANSPARENT - break_particles: ITEM - sound: - place: - name: block.glass.place - break: - name: block.glass.break - - -#################### -# Stage # -#################### - crop_stage_death: - display_name: Dead Crops - #display_name: 枯萎的农作物 - resource: - generate: false - material: PAPER - model_path: base/death_crop - specific_properties: - block: - placed_model: - type: REAL_WIRE - cancel_drop: true - sound: - place: - name: block.azalea.place - break: - name: block.azalea.break - -#################### -# Watering Can # -#################### - watering_can_1: - display_name: Copper Watering Can - #display_name: 铜水壶 - resource: - generate: false - material: GOLDEN_HORSE_ARMOR - model_path: base/watering_can_1 - watering_can_2: - display_name: Steel Watering Can - #display_name: 钢水壶 - resource: - generate: false - material: GOLDEN_HORSE_ARMOR - model_path: base/watering_can_2 - watering_can_3: - display_name: Golden Watering Can - #display_name: 金水壶 - resource: - generate: false - material: GOLDEN_HORSE_ARMOR - model_path: base/watering_can_3 - watering_can_4: - display_name: Iridium Watering Can - #display_name: 铱金水壶 - resource: - generate: false - material: GOLDEN_HORSE_ARMOR - model_path: base/watering_can_4 - - -#################### -# Fertilizer # -#################### - speed_1: - display_name: Speed-Gro - #display_name: 生长激素 - resource: - generate: false - material: PAPER - model_path: base/speed_1 - speed_2: - display_name: Deluxe Speed-Gro - #display_name: 高级生长激素 - resource: - generate: false - material: PAPER - model_path: base/speed_2 - speed_3: - display_name: Hyper Speed-Gro - #display_name: 超级生长激素 - resource: - generate: false - material: PAPER - model_path: base/speed_3 - - retaining_1: - display_name: Basic Retaining Soil - #display_name: 基础保湿土壤 - resource: - generate: false - material: PAPER - model_path: base/retaining_1 - retaining_2: - display_name: Quality Retaining Soil - #display_name: 品质保湿土壤 - resource: - generate: false - material: PAPER - model_path: base/retaining_2 - retaining_3: - display_name: Deluxe Retaining Soil - #display_name: 高级保湿土壤 - resource: - generate: false - material: PAPER - model_path: base/retaining_3 - - quality_1: - display_name: Basic Fertilizer - #display_name: 基础肥料 - resource: - generate: false - material: PAPER - model_path: base/quality_1 - quality_2: - display_name: Quality Fertilizer - #display_name: 优质肥料 - resource: - generate: false - material: PAPER - model_path: base/quality_2 - quality_3: - display_name: Deluxe Fertilizer - #display_name: 高级肥料 - resource: - generate: false - material: PAPER - model_path: base/quality_3 - - quantity_1: - display_name: Basic Yield Increasing - #display_name: 基础增产 - resource: - generate: false - material: PAPER - model_path: base/quantity_1 - quantity_2: - display_name: Quality Yield Increasing - #display_name: 优质增产 - resource: - generate: false - material: PAPER - model_path: base/quantity_2 - quantity_3: - display_name: Deluxe Yield Increasing - #display_name: 高级增产 - resource: - generate: false - material: PAPER - model_path: base/quantity_3 - - soil_detector: - display_name: Soil Surveyor - #display_name: 肥料勘测器 - resource: - generate: false - material: PAPER - model_path: base/soil_detector - -loots: - blocks: - watered_pot: - type: customcrops:watered_pot - items: - result_1: - item: customcrops:pot - min_amount: 1 - max_amount: 1 - chance: 100 - ignore_fortune: true \ No newline at end of file diff --git a/ItemsAdder Example Config/tripwire/tomato.yml b/ItemsAdder Example Config/tripwire/tomato.yml deleted file mode 100644 index 73bbe8d..0000000 --- a/ItemsAdder Example Config/tripwire/tomato.yml +++ /dev/null @@ -1,143 +0,0 @@ -info: - namespace: customcrops -items: - tomato_stage_1: - display_name: "" - resource: - generate: false - material: PAPER - model_path: tomato/stage_1 - specific_properties: - block: - placed_model: - type: REAL_WIRE - cancel_drop: true - sound: - place: - name: block.azalea.place - break: - name: block.azalea.break - tomato_stage_2: - display_name: "" - resource: - generate: false - material: PAPER - model_path: tomato/stage_2 - specific_properties: - block: - placed_model: - type: REAL_WIRE - cancel_drop: true - sound: - place: - name: block.azalea.place - break: - name: block.azalea.break - tomato_stage_3: - display_name: "" - resource: - generate: false - material: PAPER - model_path: tomato/stage_3 - specific_properties: - block: - placed_model: - type: REAL_WIRE - cancel_drop: true - sound: - place: - name: block.azalea.place - break: - name: block.azalea.break - tomato_stage_4: - display_name: "" - resource: - generate: false - material: PAPER - model_path: tomato/stage_4 - specific_properties: - block: - placed_model: - type: REAL_WIRE - cancel_drop: true - sound: - place: - name: block.azalea.place - break: - name: block.azalea.break - tomato_seeds: - display_name: "Tomato Seeds" - #display_name: 番茄种子 - resource: - generate: false - material: PAPER - model_path: tomato/tomato_seeds - tomato: - display_name: "Tomato" - #display_name: 番茄 - resource: - generate: false - material: APPLE - model_path: tomato/tomato - tomato_silver_star: - display_name: "Tomato (Silver Star)" - #display_name: 番茄(银星) - resource: - generate: false - material: APPLE - model_path: tomato/tomato_silver_star - tomato_golden_star: - display_name: "Tomato (Golden Star)" - #display_name: 番茄(金星) - resource: - generate: false - material: APPLE - model_path: tomato/tomato_golden_star - gigantic_tomato: - display_name: "Overgrown Tomato" - #display_name: 巨型番茄 - resource: - generate: false - material: PAPER - model_path: tomato/gigantic_tomato - specific_properties: - block: - placed_model: - type: REAL_TRANSPARENT -loots: - blocks: - tomato_stage_1: - type: customcrops:tomato_stage_1 - items: - result_1: - item: customcrops:tomato_seeds - min_amount: 1 - max_amount: 1 - chance: 100 - ignore_fortune: true - tomato_stage_2: - type: customcrops:tomato_stage_2 - items: - result_1: - item: customcrops:tomato_seeds - min_amount: 1 - max_amount: 1 - chance: 100 - ignore_fortune: true - tomato_stage_3: - type: customcrops:tomato_stage_3 - items: - result_1: - item: customcrops:tomato_seeds - min_amount: 1 - max_amount: 1 - chance: 100 - ignore_fortune: true -# tomato_stage_4: -# type: customcrops:tomato_stage_4 -# items: -# result_1: -# item: customcrops:tomato -# min_amount: 1 -# max_amount: 3 -# chance: 100 \ No newline at end of file diff --git a/build.gradle b/build.gradle index 7b6ebc9..7a03e09 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group = 'net.momirealms' -version = '1.6.3.4' +version = '1.7-SNAPSHOT' repositories { mavenCentral() @@ -52,8 +52,8 @@ repositories { dependencies { compileOnly 'dev.dejvokep:boosted-yaml:1.3' - compileOnly 'redis.clients:jedis:4.2.3' compileOnly 'com.github.Archy-X:AureliumSkills:Beta1.3.6' + compileOnly 'commons-io:commons-io:2.11.0' compileOnly 'com.github.angeschossen:LandsAPI:6.5.1' compileOnly 'com.github.TechFortress:GriefPrevention:16.18' compileOnly 'io.papermc.paper:paper-api:1.17.1-R0.1-SNAPSHOT' diff --git a/src/main/java/net/momirealms/customcrops/ConfigReader.java b/src/main/java/net/momirealms/customcrops/ConfigReader.java deleted file mode 100644 index ec29a49..0000000 --- a/src/main/java/net/momirealms/customcrops/ConfigReader.java +++ /dev/null @@ -1,616 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops; - -import net.kyori.adventure.key.Key; -import net.kyori.adventure.sound.Sound; -import net.momirealms.customcrops.helper.Log; -import net.momirealms.customcrops.integrations.protection.*; -import net.momirealms.customcrops.integrations.skill.*; -import net.momirealms.customcrops.objects.Crop; -import net.momirealms.customcrops.objects.Sprinkler; -import net.momirealms.customcrops.objects.WateringCan; -import net.momirealms.customcrops.objects.fertilizer.*; -import net.momirealms.customcrops.requirements.Biome; -import net.momirealms.customcrops.requirements.Permission; -import net.momirealms.customcrops.requirements.Requirement; -import net.momirealms.customcrops.requirements.YPos; -import net.momirealms.customcrops.utils.*; -import org.apache.commons.lang.StringUtils; -import org.bukkit.Bukkit; -import org.bukkit.Particle; -import org.bukkit.World; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; - -import java.io.File; -import java.util.*; - -public class ConfigReader { - - public static HashMap CROPS = new HashMap<>(); - public static HashMap FERTILIZERS = new HashMap<>(); - public static HashMap CANS = new HashMap<>(); - public static HashMap SPRINKLERS = new HashMap<>(); - public static HashSet REALTIME = new HashSet<>(); - public static boolean useRedis; - - public static YamlConfiguration getConfig(String configName) { - File file = new File(CustomCrops.plugin.getDataFolder(), configName); - if (!file.exists()) CustomCrops.plugin.saveResource(configName, false); - return YamlConfiguration.loadConfiguration(file); - } - - public static void reloadConfig(){ - Sounds.loadSound(); - Config.loadConfig(); - Season.loadSeason(); - Message.loadMessage(); - Basic.loadBasic(); - fertilizerLoad(); - cropLoad(); - } - - public static class Config{ - - public static List worlds; - public static List worldNames; - public static List cropGrowTimeList; - public static List integration; - public static String referenceWorld; - public static String lang; - public static String version; - public static String cropMode; - public static int cropLimit; - public static int sprinklerLimit; - public static int yMin; - public static int yMax; - public static int sprinklerRefill; - public static int waterCanRefill; - public static int timeToGrow; - public static int timeToWork; - public static int growMode; - public static boolean asyncCheck; - public static boolean enableLimit; - public static boolean hasParticle; - public static boolean rightClickHarvest; - public static boolean quality; - public static boolean canAddWater; - public static boolean allWorld; - public static boolean pwSeason; - public static boolean nwSeason; - public static boolean needEmptyHand; - public static boolean boneMeal; - public static boolean realisticSeason; - public static boolean rotation; - public static boolean variant4; - public static boolean oneTry; - public static double boneMealChance; - public static double quality_1; - public static double quality_2; - public static SkillXP skillXP; - public static Particle boneMealSuccess; - - public static void loadConfig(){ - - CustomCrops.plugin.saveDefaultConfig(); - CustomCrops.plugin.reloadConfig(); - FileConfiguration config = CustomCrops.plugin.getConfig(); - - lang = config.getString("config.lang","chinese"); - - cropGrowTimeList = config.getLongList("config.grow-time"); - cropGrowTimeList.forEach(time -> {if(time < 0 || time > 23999){AdventureManager.consoleMessage("[CustomCrops] Grow time should be between 0 and 23999");}}); - timeToGrow = config.getInt("config.time-to-grow",60)*20; - timeToWork = config.getInt("config.time-to-work",30)*20; - asyncCheck = config.getBoolean("config.async-time-check",false); - growMode = config.getInt("config.grow-mode",3); if (growMode > 4 || growMode < 1) growMode = 3; - allWorld = config.getBoolean("config.all-world-grow",false); - hasParticle = config.getBoolean("config.water-particles", true); - rightClickHarvest = config.getBoolean("config.right-click-harvest", true); - needEmptyHand = config.getBoolean("config.harvest-with-empty-hand", true); - pwSeason = config.getBoolean("config.prevent-plant-if-wrong-season", true); - nwSeason = config.getBoolean("config.should-notify-if-wrong-season", true); - rotation = config.getBoolean("config.rotation.enable", false); - oneTry = config.getBoolean("config.gigantic-only-one-try", false); - variant4 = config.getInt("config.rotation.variant", 4) == 4; - if (config.contains("config.real-time")){ - - REALTIME.clear(); - REALTIME.addAll(config.getStringList("config.real-time")); - } - - boneMeal = config.getBoolean("config.bone-meal.enable", true); - if (boneMeal){ - boneMealChance = config.getDouble("config.bone-meal.chance",0.5); - boneMealSuccess = Particle.valueOf(config.getString("config.bone-meal.success-particle", "VILLAGER_HAPPY").toUpperCase()); - } - - enableLimit = config.getBoolean("config.limit.enable",true); - if (enableLimit){ - cropLimit = config.getInt("config.limit.crop",64); - sprinklerLimit = config.getInt("config.limit.sprinkler",16); - } - - String serverVersion = Bukkit.getServer().getClass().getPackage().getName(); - if (serverVersion.contains("16") || serverVersion.contains("17")){ - yMin = 0; yMax = 256; - }else { - yMin = -64; yMax = 320; - } - - quality = config.getBoolean("config.quality.enable",true); - if (quality){ - String[] split = StringUtils.split(config.getString("config.quality.default-ratio","17/2/1"), "/"); - double[] ratios = new double[3]; - ratios[0] = Double.parseDouble(split[0]); - ratios[1] = Double.parseDouble(split[1]); - ratios[2] = Double.parseDouble(split[2]); - double total = ratios[0] + ratios[1] + ratios[2]; - quality_1 = ratios[0]/total; - quality_2 = 1 - ratios[1]/total; - } - - sprinklerRefill = config.getInt("config.sprinkler-refill",2); - waterCanRefill = config.getInt("config.water-can-refill",1); - version = config.getString("config-version"); - cropMode = config.getString("config.crop-mode","tripwire"); - canAddWater = config.getBoolean("config.water-can-add-water-to-sprinkler",true); - - if (allWorld){ - if (config.getStringList("config.whitelist-worlds").size() > 1) AdventureManager.consoleMessage("[CustomCrops] Only one whitelist world is allowed when \"all-world-grow\" enabled!"); - referenceWorld = config.getStringList("config.whitelist-worlds").get(0); - } - - worlds = new ArrayList<>(); - worldNames = config.getStringList("config.whitelist-worlds"); - worldNames.forEach(worldName -> { - World world = Bukkit.getWorld(worldName); - if (world == null) AdventureManager.consoleMessage("[CustomCrops] World " + worldName + " doesn't exist"); - else worlds.add(world); - }); - - integration = new ArrayList<>(); - if (config.getBoolean("config.integration.Residence",false)){ - if (Bukkit.getPluginManager().getPlugin("Residence") == null) Log.warn("Failed to initialize Residence!"); - else {integration.add(new ResidenceIntegration());hookMessage("Residence");} - } - if (config.getBoolean("config.integration.Kingdoms",false)){ - if (Bukkit.getPluginManager().getPlugin("Kingdoms") == null) Log.warn("Failed to initialize Kingdoms!"); - else {integration.add(new KingdomsXIntegration());hookMessage("Kingdoms");} - } - if (config.getBoolean("config.integration.WorldGuard",false)){ - if (Bukkit.getPluginManager().getPlugin("WorldGuard") == null) Log.warn("Failed to initialize WorldGuard!"); - else {integration.add(new WorldGuardIntegration());hookMessage("WorldGuard");} - } - if (config.getBoolean("config.integration.GriefDefender",false)){ - if(Bukkit.getPluginManager().getPlugin("GriefDefender") == null) Log.warn("Failed to initialize GriefDefender!"); - else {integration.add(new GriefDefenderIntegration());hookMessage("GriefDefender");} - } - if (config.getBoolean("config.integration.PlotSquared",false)){ - if(Bukkit.getPluginManager().getPlugin("PlotSquared") == null) Log.warn("Failed to initialize PlotSquared!"); - else {integration.add(new PlotSquaredIntegration());hookMessage("PlotSquared");} - } - if (config.getBoolean("config.integration.Towny",false)){ - if (Bukkit.getPluginManager().getPlugin("Towny") == null) Log.warn("Failed to initialize Towny!"); - else {integration.add(new TownyIntegration());hookMessage("Towny");} - } - if (config.getBoolean("config.integration.Lands",false)){ - if (Bukkit.getPluginManager().getPlugin("Lands") == null) Log.warn("Failed to initialize Lands!"); - else {integration.add(new LandsIntegration());hookMessage("Lands");} - } - if (config.getBoolean("config.integration.GriefPrevention",false)){ - if (Bukkit.getPluginManager().getPlugin("GriefPrevention") == null) Log.warn("Failed to initialize GriefPrevention!"); - else {integration.add(new GriefPreventionIntegration());hookMessage("GriefPrevention");} - } - if (config.getBoolean("config.integration.CrashClaim",false)){ - if (Bukkit.getPluginManager().getPlugin("CrashClaim") == null) Log.warn("Failed to initialize CrashClaim!"); - else {integration.add(new CrashClaimIntegration());hookMessage("CrashClaim");} - } - if (config.getBoolean("config.integration.BentoBox",false)){ - if (Bukkit.getPluginManager().getPlugin("BentoBox") == null) Log.warn("Failed to initialize BentoBox!"); - else {integration.add(new BentoBoxIntegration());hookMessage("BentoBox");} - } - - realisticSeason = false; - if (config.getBoolean("config.integration.RealisticSeasons",false)){ - if (Bukkit.getPluginManager().getPlugin("RealisticSeasons") == null) Log.warn("Failed to initialize RealisticSeasons!"); - else {realisticSeason = true;hookMessage("RealisticSeasons");} - } - - skillXP = null; - if (config.getBoolean("config.integration.mcMMO",false)){ - if (Bukkit.getPluginManager().getPlugin("mcMMO") == null) Log.warn("Failed to initialize mcMMO!"); - else {skillXP = new mcMMOIntegration();hookMessage("mcMMO");} - } - if (config.getBoolean("config.integration.AureliumSkills",false)){ - if (Bukkit.getPluginManager().getPlugin("AureliumSkills") == null) Log.warn("Failed to initialize AureliumSkills!"); - else {skillXP = new AureliumIntegration();hookMessage("AureliumSkills");} - } - if(config.getBoolean("config.integration.MMOCore",false)){ - if(Bukkit.getPluginManager().getPlugin("MMOCore") == null) Log.warn("Failed to initialize MMOCore!"); - else {skillXP = new MMOCoreIntegration();hookMessage("MMOCore");} - } - if(config.getBoolean("config.integration.EcoSkills",false)){ - if(Bukkit.getPluginManager().getPlugin("EcoSkills") == null) Log.warn("Failed to initialize EcoSkills!"); - else {skillXP = new EcoSkillsIntegration();hookMessage("EcoSkills");} - } - if(config.getBoolean("config.integration.JobsReborn",false)){ - if(Bukkit.getPluginManager().getPlugin("Jobs") == null) Log.warn("Failed to initialize Jobs!"); - else {skillXP = new JobsRebornIntegration();hookMessage("JobsReborn");} - } - } - } - - public static class Basic{ - - public static String pot; - public static String watered_pot; - public static String glass; - public static String dead; - public static String soilDetector; - public static boolean hasWaterLore; - public static String waterLeft; - public static String waterFull; - public static String waterEmpty; - public static String waterRight; - public static List waterLore; - - public static void loadBasic(){ - - YamlConfiguration config = getConfig("basic.yml"); - - pot = config.getString("basic.pot","customcrops:pot"); - watered_pot = config.getString("basic.watered-pot","customcrops:watered_pot"); - glass = config.getString("basic.greenhouse-glass","customcrops:greenhouse_glass"); - dead = config.getString("basic.dead-crop","customcrops:crop_stage_death"); - soilDetector = config.getString("basic.soil-detector","customcrops:soil_detector"); - - hasWaterLore = config.getBoolean("lore.watering-can.enable",false); - if (hasWaterLore){ - waterLeft = config.getString("lore.watering-can.left"); - waterFull = config.getString("lore.watering-can.full"); - waterEmpty = config.getString("lore.watering-can.empty"); - waterRight = config.getString("lore.watering-can.right"); - waterLore = config.getStringList("lore.watering-can.lore"); - } - - CANS.clear(); - if (config.contains("water-can")){ - config.getConfigurationSection("water-can").getKeys(false).forEach(key -> { - int width = config.getInt("water-can." + key + ".width"); - if (width % 2 == 0){ - AdventureManager.consoleMessage("[CustomCrops] Watering Can " + key + "'s width should be odd!"); - return; - } - String namespacedID = config.getString("water-can." + key + ".item"); - WateringCan wateringCan = new WateringCan(config.getInt("water-can." + key + ".max"), width, config.getInt("water-can." + key + ".length")); - CANS.put(namespacedID, wateringCan); - }); - } - AdventureManager.consoleMessage("[CustomCrops] Loaded " + CANS.size() + " watering-cans"); - - SPRINKLERS.clear(); - if (config.contains("sprinkler")){ - config.getConfigurationSection("sprinkler").getKeys(false).forEach(key -> { - Sprinkler sprinklerData = new Sprinkler(config.getInt("sprinkler." + key + ".range"), config.getInt("sprinkler." + key + ".max-water")); - String threeD = config.getString("sprinkler." + key + ".3Ditem"); - sprinklerData.setNamespacedID_2(threeD); - String twoD = config.getString("sprinkler." + key + ".2Ditem"); - sprinklerData.setNamespacedID_1(twoD); - SPRINKLERS.put(threeD, sprinklerData); - SPRINKLERS.put(twoD, sprinklerData); - }); - } - AdventureManager.consoleMessage("[CustomCrops] Loaded " + SPRINKLERS.size()/2 + " sprinklers"); - } - } - - public static class Season{ - - public static boolean enable; - public static boolean greenhouse; - public static boolean seasonChange; - public static int range; - public static int duration; - - public static void loadSeason(){ - - YamlConfiguration config = getConfig("season.yml"); - enable = config.getBoolean("season.enable",false); - if (enable){ - if (Config.growMode == 4) AdventureManager.consoleMessage("[CustomCrops] Warining: It's not advised to enable season in mode 4"); - greenhouse = config.getBoolean("season.greenhouse.enable",false); - if (greenhouse) range = config.getInt("season.greenhouse.range",7); - seasonChange = config.getBoolean("season.auto-season-change.enable",false); - duration = config.getInt("season.auto-season-change.duration",28); - if (seasonChange) AdventureManager.consoleMessage("[CustomCrops] Season Change mode: Auto"); - else AdventureManager.consoleMessage("[CustomCrops] Season Change mode: Command"); - } - } - } - - public static class Message{ - - public static String prefix; - public static String reload; - public static String lackArgs; - public static String noPerm; - public static String spring; - public static String summer; - public static String autumn; - public static String winter; - public static String sprinkler_limit; - public static String crop_limit; - public static String not_configed; - public static String badY; - public static String badBiome; - public static String badWorld; - public static String badPerm; - public static String badSeason; - public static String forceGrow; - public static String forceWater; - public static String forceAll; - public static String backUp; - public static String setSeason; - public static String wrongArgs; - public static String forceSave; - public static String noSeason; - public static boolean hasCropInfo; - public static boolean hasSprinklerInfo; - public static boolean hasWaterInfo; - public static int cropTime; - public static int sprinklerTime; - public static String cropText; - public static String sprinklerLeft; - public static String sprinklerFull; - public static String sprinklerEmpty; - public static String sprinklerRight; - public static String beforePlant; - public static String waterLeft; - public static String waterFull; - public static String waterEmpty; - public static String waterRight; - public static double cropOffset; - public static double sprinklerOffset; - - public static void loadMessage(){ - - YamlConfiguration config = getConfig("messages/messages_" + Config.lang +".yml"); - prefix = config.getString("messages.prefix"); - reload = config.getString("messages.reload"); - lackArgs = config.getString("messages.lack-args"); - noPerm = config.getString("messages.no-perm"); - spring = config.getString("messages.spring"); - summer = config.getString("messages.summer"); - autumn = config.getString("messages.autumn"); - winter = config.getString("messages.winter"); - sprinkler_limit = config.getString("messages.sprinkler-limit"); - crop_limit = config.getString("messages.crop-limit"); - not_configed = config.getString("messages.not-configed"); - badY = config.getString("messages.bad-Y"); - badBiome = config.getString("messages.bad-biome"); - badWorld = config.getString("messages.bad-world"); - badPerm = config.getString("messages.bad-perm"); - badSeason = config.getString("messages.bad-season"); - forceGrow = config.getString("messages.force-grow"); - forceWater = config.getString("messages.force-water"); - forceAll = config.getString("messages.force-all","messages.force-all is missing"); - backUp = config.getString("messages.back-up"); - setSeason = config.getString("messages.set-season"); - wrongArgs = config.getString("messages.wrong-args"); - forceSave = config.getString("messages.force-save"); - beforePlant = config.getString("messages.before-plant"); - noSeason = config.getString("messages.no-season","Season Disabled"); - - hasCropInfo = config.getBoolean("hologram.grow-info.enable"); - if (hasCropInfo){ - cropTime = config.getInt("hologram.grow-info.duration"); - cropText = config.getString("hologram.grow-info.text"); - cropOffset = config.getDouble("hologram.grow-info.y-offset"); - } - hasSprinklerInfo = config.getBoolean("hologram.sprinkler-info.enable"); - if (hasSprinklerInfo){ - sprinklerTime = config.getInt("hologram.sprinkler-info.duration"); - sprinklerLeft = config.getString("hologram.sprinkler-info.left"); - sprinklerFull = config.getString("hologram.sprinkler-info.full"); - sprinklerEmpty = config.getString("hologram.sprinkler-info.empty"); - sprinklerRight = config.getString("hologram.sprinkler-info.right"); - sprinklerOffset = config.getDouble("hologram.sprinkler-info.y-offset"); - } - hasWaterInfo = config.getBoolean("actionbar.watering-can.enable"); - if (hasWaterInfo){ - waterLeft = config.getString("actionbar.watering-can.left"); - waterFull = config.getString("actionbar.watering-can.full"); - waterEmpty = config.getString("actionbar.watering-can.empty"); - waterRight = config.getString("actionbar.watering-can.right"); - } - } - } - - public static void cropLoad(){ - CROPS.clear(); - YamlConfiguration config = getConfig("crops.yml"); - Set keys = config.getConfigurationSection("crops").getKeys(false); - keys.forEach(key -> { - Crop cropInstance; - if (config.contains("crops." + key + ".amount")){ - String[] split = StringUtils.split(config.getString("crops." + key + ".amount"),"~"); - cropInstance = new Crop(Integer.parseInt(split[0]),Integer.parseInt(split[1])); - }else { - AdventureManager.consoleMessage("[CustomCrops] You forget to set " + key +"'s amount!"); - return; - } - cropInstance.setGrowChance(config.getDouble("crops." + key + ".grow-chance", 1)); - if (config.contains("crops." + key + ".gigantic")) - if (config.contains("crops." + key + ".gigantic.block")){ - cropInstance.setGiant(config.getString("crops." + key + ".gigantic.block")); - cropInstance.setIsBlock(true); - } - if (config.contains("crops." + key + ".gigantic.furniture")){ - cropInstance.setGiant(config.getString("crops." + key + ".gigantic.furniture")); - cropInstance.setIsBlock(false); - } - cropInstance.setGiantChance(config.getDouble("crops." + key + ".gigantic.chance",0.01)); - if (Season.enable && config.contains("crops." + key + ".season")) - cropInstance.setSeasons(config.getStringList("crops." + key + ".season")); - if (config.contains("crops." + key + ".return")) - cropInstance.setReturnStage(config.getString("crops." + key + ".return")); - if (config.contains("crops." + key + ".drop-other-loots")) - cropInstance.setOtherLoots(config.getStringList("crops." + key + ".drop-other-loots")); - if (config.contains("crops." + key + ".commands")) - cropInstance.setCommands(config.getStringList("crops." + key + ".commands")); - if (config.contains("crops." + key + ".skill-xp")) - cropInstance.setSkillXP(config.getDouble("crops." + key + ".skill-xp")); - if (config.contains("crops." + key + ".requirements")){ - List requirements = new ArrayList<>(); - config.getConfigurationSection("crops." + key + ".requirements").getValues(false).forEach((requirement, value) -> { - switch (requirement){ - case "world" -> requirements.add(new net.momirealms.customcrops.requirements.World((List) value)); - case "yPos" -> requirements.add(new YPos((List) value)); - case "biome" -> requirements.add(new Biome((List) value)); - case "permission" -> requirements.add(new Permission((String) value)); - } - }); - cropInstance.setRequirements(requirements); - } - if (Config.quality){ - cropInstance.setQuality_1(config.getString("crops." + key + ".quality.1")); - cropInstance.setQuality_2(config.getString("crops." + key + ".quality.2")); - cropInstance.setQuality_3(config.getString("crops." + key + ".quality.3")); - cropInstance.setDropIALoot(config.getBoolean("crops." + key + ".drop-ia-loots", false)); - }else {cropInstance.setDropIALoot(false);} - CROPS.put(key, cropInstance); - }); - AdventureManager.consoleMessage("[CustomCrops] Loaded " + CROPS.size() + " crops"); - } - - public static void fertilizerLoad(){ - FERTILIZERS.clear(); - YamlConfiguration config = getConfig("fertilizer.yml"); - if (config.contains("speed")){ - config.getConfigurationSection("speed").getKeys(false).forEach(key -> { - String id = StringUtils.split(config.getString("speed." + key + ".item"), ":")[1]; - SpeedGrow speedGrow = new SpeedGrow(id, config.getInt("speed." + key + ".times")); - speedGrow.setName(config.getString("speed." + key + ".name","")); - speedGrow.setBefore(config.getBoolean("speed." + key + ".before-plant",false)); - speedGrow.setChance(config.getDouble("speed." + key + ".chance")); - if (config.contains("speed." + key + ".particle")) - speedGrow.setParticle(Particle.valueOf(config.getString("speed." + key + ".particle").toUpperCase())); - FERTILIZERS.put(id, speedGrow); - }); - } - if (config.contains("retaining")){ - config.getConfigurationSection("retaining").getKeys(false).forEach(key -> { - String id = StringUtils.split(config.getString("retaining." + key + ".item"), ":")[1]; - RetainingSoil retainingSoil = new RetainingSoil(id, config.getInt("retaining." + key + ".times")); - retainingSoil.setBefore(config.getBoolean("retaining." + key + ".before-plant",false)); - retainingSoil.setChance(config.getDouble("retaining." + key + ".chance")); - retainingSoil.setName(config.getString("retaining." + key + ".name","")); - if (config.contains("retaining." + key + ".particle")) - retainingSoil.setParticle(Particle.valueOf(config.getString("retaining." + key + ".particle").toUpperCase())); - FERTILIZERS.put(id, retainingSoil); - }); - } - if (config.contains("quality")){ - config.getConfigurationSection("quality").getKeys(false).forEach(key -> { - String id = StringUtils.split(config.getString("quality." + key + ".item"), ":")[1]; - String[] split = StringUtils.split(config.getString("quality." + key + ".chance"), "/"); - int[] weight = new int[3]; - weight[0] = Integer.parseInt(split[0]); - weight[1] = Integer.parseInt(split[1]); - weight[2] = Integer.parseInt(split[2]); - QualityCrop qualityCrop = new QualityCrop(key, config.getInt("quality." + key + ".times")); - qualityCrop.setChance(weight); - qualityCrop.setName(config.getString("quality." + key + ".name","")); - qualityCrop.setBefore(config.getBoolean("quality." + key + ".before-plant",false)); - if (config.contains("quality." + key + ".particle")) - qualityCrop.setParticle(Particle.valueOf(config.getString("quality." + key + ".particle").toUpperCase())); - FERTILIZERS.put(id, qualityCrop); - }); - } - if (config.contains("quantity")){ - config.getConfigurationSection("quantity").getKeys(false).forEach(key -> { - String id = StringUtils.split(config.getString("quantity." + key + ".item"), ":")[1]; - YieldIncreasing yieldIncreasing = new YieldIncreasing(key, config.getInt("quantity." + key + ".times",14)); - yieldIncreasing.setBonus(config.getInt("quantity." + key + ".bonus",1)); - yieldIncreasing.setName(config.getString("quantity." + key + ".name","")); - yieldIncreasing.setBefore(config.getBoolean("quantity." + key + ".before-plant",false)); - yieldIncreasing.setChance(config.getDouble("quantity." + key + ".chance")); - if (config.contains("quantity." + key + ".particle")) - yieldIncreasing.setParticle(Particle.valueOf(config.getString("quantity." + key + ".particle").toUpperCase())); - FERTILIZERS.put(id, yieldIncreasing); - }); - } - AdventureManager.consoleMessage("[CustomCrops] Loaded " + FERTILIZERS.size() + " fertilizers"); - } - - public static class Sounds{ - - public static Key waterPotKey; - public static Sound.Source waterPotSource; - public static Key addWaterToCanKey; - public static Sound.Source addWaterToCanSource; - public static Key addWaterToSprinklerKey; - public static Sound.Source addWaterToSprinklerSource; - public static Key placeSprinklerKey; - public static Sound.Source placeSprinklerSource; - public static Key plantSeedKey; - public static Sound.Source plantSeedSource; - public static Key useFertilizerKey; - public static Sound.Source useFertilizerSource; - public static Key harvestKey; - public static Sound.Source harvestSource; - public static Key boneMealKey; - public static Sound.Source boneMealSource; - - public static void loadSound(){ - YamlConfiguration config = getConfig("sounds.yml"); - waterPotKey = Key.key(config.getString("water-pot.sound", "minecraft:block.water.ambient")); - waterPotSource = Sound.Source.valueOf(config.getString("water-pot.type","player").toUpperCase()); - addWaterToCanKey = Key.key(config.getString("add-water-to-can.sound", "minecraft:item.bucket.fill")); - addWaterToCanSource = Sound.Source.valueOf(config.getString("add-water-to-can.type","player").toUpperCase()); - addWaterToSprinklerKey = Key.key(config.getString("add-water-to-sprinkler.sound", "minecraft:item.bucket.fill")); - addWaterToSprinklerSource = Sound.Source.valueOf(config.getString("add-water-to-sprinkler.type","player").toUpperCase()); - placeSprinklerKey = Key.key(config.getString("place-sprinkler.sound", "minecraft:block.bone_block.place")); - placeSprinklerSource = Sound.Source.valueOf(config.getString("place-sprinkler.type","player").toUpperCase()); - plantSeedKey = Key.key(config.getString("plant-seed.sound", "minecraft:item.hoe.till")); - plantSeedSource = Sound.Source.valueOf(config.getString("plant-seed.type","player").toUpperCase()); - useFertilizerKey = Key.key(config.getString("use-fertilizer.sound", "minecraft:item.hoe.till")); - useFertilizerSource = Sound.Source.valueOf(config.getString("use-fertilizer.type","player").toUpperCase()); - harvestKey = Key.key(config.getString("harvest.sound", "minecraft:block.crop.break")); - harvestSource = Sound.Source.valueOf(config.getString("harvest.type", "player").toUpperCase()); - boneMealKey = Key.key(config.getString("bonemeal.sound", "minecraft:item.hoe.till")); - boneMealSource = Sound.Source.valueOf(config.getString("bonemeal.type","player").toUpperCase()); - } - } - - public static void tryEnableJedis(){ - YamlConfiguration configuration = ConfigReader.getConfig("redis.yml"); - if (configuration.getBoolean("redis.enable", false)){ - useRedis = true; - JedisUtil.initializeRedis(configuration); - }else { - useRedis = false; - } - } - - private static void hookMessage(String plugin){ - AdventureManager.consoleMessage("[CustomCrops] " + plugin + " Hooked!"); - } -} diff --git a/src/main/java/net/momirealms/customcrops/CustomCrops.java b/src/main/java/net/momirealms/customcrops/CustomCrops.java index bbbd1b0..f4e58af 100644 --- a/src/main/java/net/momirealms/customcrops/CustomCrops.java +++ b/src/main/java/net/momirealms/customcrops/CustomCrops.java @@ -18,30 +18,16 @@ package net.momirealms.customcrops; import net.kyori.adventure.platform.bukkit.BukkitAudiences; -import net.momirealms.customcrops.commands.Executor; -import net.momirealms.customcrops.commands.Completer; -import net.momirealms.customcrops.datamanager.*; -import net.momirealms.customcrops.datamanager.CropManager; -import net.momirealms.customcrops.datamanager.SprinklerManager; +import net.momirealms.customcrops.commands.PluginCommand; +import net.momirealms.customcrops.config.ConfigUtil; +import net.momirealms.customcrops.config.MainConfig; import net.momirealms.customcrops.helper.LibraryLoader; -import net.momirealms.customcrops.integrations.Placeholders; -import net.momirealms.customcrops.listener.*; -import net.momirealms.customcrops.listener.itemframe.BreakBlockI; -import net.momirealms.customcrops.listener.itemframe.BreakFurnitureI; -import net.momirealms.customcrops.listener.itemframe.InteractFurnitureI; -import net.momirealms.customcrops.listener.itemframe.RightClickI; -import net.momirealms.customcrops.listener.tripwire.BreakBlockT; -import net.momirealms.customcrops.listener.tripwire.BreakFurnitureT; -import net.momirealms.customcrops.listener.tripwire.InteractFurnitureT; -import net.momirealms.customcrops.listener.tripwire.RightClickT; -import net.momirealms.customcrops.timer.CropTimer; -import net.momirealms.customcrops.utils.*; +import net.momirealms.customcrops.integrations.papi.PlaceholderManager; +import net.momirealms.customcrops.managers.CropManager; +import net.momirealms.customcrops.utils.AdventureUtil; import org.bukkit.Bukkit; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.plugin.java.JavaPlugin; -import java.io.File; -import java.io.IOException; import java.util.Objects; public final class CustomCrops extends JavaPlugin { @@ -49,132 +35,76 @@ public final class CustomCrops extends JavaPlugin { public static BukkitAudiences adventure; public static CustomCrops plugin; - private CropTimer cropTimer; + private PlaceholderManager placeholderManager; private CropManager cropManager; - private SprinklerManager sprinklerManager; - private SeasonManager seasonManager; - private PotManager potManager; - public static Placeholders placeholders; - - public CropManager getCropManager() { return this.cropManager; } - public SprinklerManager getSprinklerManager() { return sprinklerManager; } - public SeasonManager getSeasonManager() { return seasonManager; } - public PotManager getPotManager() { return potManager; } + private PluginCommand pluginCommand; @Override public void onLoad(){ plugin = this; - LibraryLoader.load("redis.clients","jedis","4.2.3","https://repo.maven.apache.org/maven2/"); - LibraryLoader.load("org.apache.commons","commons-pool2","2.11.1","https://repo.maven.apache.org/maven2/"); LibraryLoader.load("dev.dejvokep","boosted-yaml","1.3","https://repo.maven.apache.org/maven2/"); + LibraryLoader.load("commons-io","commons-io","2.11.0","https://repo.maven.apache.org/maven2/"); } @Override public void onEnable() { adventure = BukkitAudiences.create(plugin); - AdventureManager.consoleMessage("[CustomCrops] Running on " + Bukkit.getVersion()); + AdventureUtil.consoleMessage("[CustomCrops] Running on " + Bukkit.getVersion()); - ConfigReader.reloadConfig(); - if (!Objects.equals(ConfigReader.Config.version, "6")){ - ConfigUtil.update(); + if (Bukkit.getPluginManager().getPlugin("ItemsAdder") != null) { + MainConfig.customPlugin = "itemsadder"; + MainConfig.OraxenHook = false; + AdventureUtil.consoleMessage("[CustomCrops] Custom Item Plugin Platform: <#BA55D3>ItemsAdder"); } - if(Bukkit.getPluginManager().getPlugin("PlaceHolderAPI") != null){ - placeholders = new Placeholders(); - placeholders.register(); - Bukkit.getPluginManager().registerEvents(new PapiReload(), this); + else if (Bukkit.getPluginManager().getPlugin("Oraxen") != null) { + MainConfig.customPlugin = "oraxen"; + MainConfig.OraxenHook = true; + AdventureUtil.consoleMessage("[CustomCrops] Custom Item Plugin Platform: <#6495ED>Oraxen"); + } + else { + AdventureUtil.consoleMessage("[CustomCrops] You need either ItemsAdder or Oraxen as CustomCrops' dependency"); + Bukkit.getPluginManager().disablePlugin(CustomCrops.plugin); + return; } - Objects.requireNonNull(Bukkit.getPluginCommand("customcrops")).setExecutor(new Executor(this)); - Objects.requireNonNull(Bukkit.getPluginCommand("customcrops")).setTabCompleter(new Completer()); + ConfigUtil.reloadConfigs(); - Bukkit.getPluginManager().registerEvents(new ItemSpawn(), this); - Bukkit.getPluginManager().registerEvents(new JoinAndQuit(), this); + this.pluginCommand = new PluginCommand(); + Objects.requireNonNull(Bukkit.getPluginCommand("customcrops")).setExecutor(pluginCommand); + Objects.requireNonNull(Bukkit.getPluginCommand("customcrops")).setTabCompleter(pluginCommand); - ConfigReader.tryEnableJedis(); + this.cropManager = new CropManager(); - if (ConfigReader.Season.enable){ - this.seasonManager = new SeasonManager(); - this.seasonManager.loadData(); + if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { + this.placeholderManager = new PlaceholderManager(); } - this.sprinklerManager = new SprinklerManager(); - this.sprinklerManager.loadData(); - this.potManager = new PotManager(); - this.potManager.loadData(); - this.cropTimer = new CropTimer(); - if (ConfigReader.Config.cropMode.equalsIgnoreCase("item_frame")){ - this.cropManager = new CropManager(true); - AdventureManager.consoleMessage("[CustomCrops] Crop Mode: ItemFrame"); - Bukkit.getPluginManager().registerEvents(new RightClickI(), this); - Bukkit.getPluginManager().registerEvents(new BreakBlockI(), this); - Bukkit.getPluginManager().registerEvents(new BreakFurnitureI(), this); - Bukkit.getPluginManager().registerEvents(new InteractFurnitureI(), this); - }else{ - this.cropManager = new CropManager(false); - AdventureManager.consoleMessage("[CustomCrops] Crop Mode: TripWire"); - Bukkit.getPluginManager().registerEvents(new RightClickT(), this); - Bukkit.getPluginManager().registerEvents(new BreakBlockT(), this); - Bukkit.getPluginManager().registerEvents(new BreakFurnitureT(), this); - Bukkit.getPluginManager().registerEvents(new InteractFurnitureT(), this); - checkIAConfig(); - } - this.cropManager.loadData(); - AdventureManager.consoleMessage("[CustomCrops] Plugin Enabled!"); + + AdventureUtil.consoleMessage("[CustomCrops] Plugin Enabled!"); } @Override public void onDisable() { - if (this.cropManager != null){ - this.cropManager.cleanData(); - this.cropManager.updateData(); - this.cropManager.saveData(); - this.cropManager = null; - } - if (this.sprinklerManager != null){ - this.sprinklerManager.cleanData(); - this.sprinklerManager.updateData(); - this.sprinklerManager.saveData(); - this.sprinklerManager = null; - } - if (this.potManager != null){ - this.potManager.saveData(); - this.potManager = null; - } - if (ConfigReader.Season.enable && !ConfigReader.Season.seasonChange && this.seasonManager != null){ - this.seasonManager.saveData(); - this.seasonManager = null; - } - if (placeholders != null){ - placeholders.unregister(); - placeholders = null; - } - - getLogger().info("Backing Up..."); - FileUtil.backUpData(); - getLogger().info("Done."); - - if (cropTimer != null) { - this.cropTimer.stopTimer(cropTimer.getTaskID()); - } if (adventure != null) { adventure.close(); } - if (plugin != null) { - plugin = null; + if (this.placeholderManager != null) { + this.placeholderManager.unload(); + } + if (this.cropManager != null) { + this.cropManager.unload(); } } - private void checkIAConfig(){ - FileConfiguration fileConfiguration = Bukkit.getPluginManager().getPlugin("ItemsAdder").getConfig(); - if (fileConfiguration.getBoolean("blocks.disable-REAL_WIRE")){ - fileConfiguration.set("blocks.disable-REAL_WIRE", false); - try { - fileConfiguration.save(new File(Bukkit.getPluginManager().getPlugin("ItemsAdder").getDataFolder(), "config.yml")); - } catch (IOException e) { - e.printStackTrace(); - } - AdventureManager.consoleMessage("[CustomCrops] Detected that you might have not set \"disable-REAL_WIRE\" false in ItemsAdder's config!"); - AdventureManager.consoleMessage("[CustomCrops] You need a restart to apply that config :)"); - } + public PlaceholderManager getPlaceholderManager() { + return placeholderManager; + } + + public boolean hasPapi() { + return placeholderManager != null; + } + + public CropManager getCropManager() { + return cropManager; } } diff --git a/src/main/java/net/momirealms/customcrops/requirements/Requirement.java b/src/main/java/net/momirealms/customcrops/Function.java similarity index 83% rename from src/main/java/net/momirealms/customcrops/requirements/Requirement.java rename to src/main/java/net/momirealms/customcrops/Function.java index c9c48de..38e0697 100644 --- a/src/main/java/net/momirealms/customcrops/requirements/Requirement.java +++ b/src/main/java/net/momirealms/customcrops/Function.java @@ -15,8 +15,13 @@ * along with this program. If not, see . */ -package net.momirealms.customcrops.requirements; +package net.momirealms.customcrops; -public interface Requirement { - boolean canPlant(PlantingCondition plantingCondition); +public class Function { + + public void load() { + } + + public void unload() { + } } diff --git a/src/main/java/net/momirealms/customcrops/api/CustomCropsAPI.java b/src/main/java/net/momirealms/customcrops/api/CustomCropsAPI.java deleted file mode 100644 index 7e8c16d..0000000 --- a/src/main/java/net/momirealms/customcrops/api/CustomCropsAPI.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.momirealms.customcrops.api; - -import net.momirealms.customcrops.CustomCrops; -import net.momirealms.customcrops.datamanager.SeasonManager; - -public class CustomCropsAPI { - - /** - * 获取插件实例 - * @return 插件实例 - */ - public static CustomCrops getPlugin(){ - return CustomCrops.plugin; - } - - /** - * 获取指定世界的季节 - * @param worldName 世界名 - * @return 那个世界的季节,若不存在则返回null - */ - public static String getSeason(String worldName){ - return SeasonManager.SEASON.get(worldName); - } -} diff --git a/src/main/java/net/momirealms/customcrops/api/crop/Crop.java b/src/main/java/net/momirealms/customcrops/api/crop/Crop.java new file mode 100644 index 0000000..bbdebbd --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/api/crop/Crop.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.api.crop; + +import net.momirealms.customcrops.integrations.season.CCSeason; +import net.momirealms.customcrops.objects.GiganticCrop; +import net.momirealms.customcrops.objects.OtherLoot; +import net.momirealms.customcrops.objects.QualityLoot; +import net.momirealms.customcrops.objects.actions.ActionInterface; +import net.momirealms.customcrops.objects.requirements.RequirementInterface; + +public interface Crop { + + public CCSeason[] getSeasons(); + + public RequirementInterface[] getRequirements(); + + public String getReturnStage(); + + public QualityLoot getQualityLoot(); + + public GiganticCrop getGiganticCrop(); + + public double getSkillXP(); + + public OtherLoot[] getOtherLoots(); + + public ActionInterface[] getActions(); + + public String getKey(); +} diff --git a/src/main/java/net/momirealms/customcrops/api/event/CropHarvestEvent.java b/src/main/java/net/momirealms/customcrops/api/event/CropHarvestEvent.java new file mode 100644 index 0000000..1034397 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/api/event/CropHarvestEvent.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.api.event; + +import net.momirealms.customcrops.api.crop.Crop; +import net.momirealms.customcrops.objects.fertilizer.Fertilizer; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class CropHarvestEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final Location location; + private final Crop crop; + private final Fertilizer fertilizer; + + public CropHarvestEvent(@NotNull Player who, Crop crop, Location location, @Nullable Fertilizer fertilizer) { + super(who); + this.crop = crop; + this.location = location; + this.cancelled = false; + this.fertilizer = fertilizer; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlers; + } + + /** + * Get the crop player is harvesting + * @return crop + */ + public Crop getCrop() { + return crop; + } + + public Location getLocation() { + return location; + } + + @Nullable + public Fertilizer getFertilizer() { + return fertilizer; + } +} diff --git a/src/main/java/net/momirealms/customcrops/api/event/CustomWorldEvent.java b/src/main/java/net/momirealms/customcrops/api/event/CustomWorldEvent.java new file mode 100644 index 0000000..cbc89d6 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/api/event/CustomWorldEvent.java @@ -0,0 +1,27 @@ +package net.momirealms.customcrops.api.event; + +import net.momirealms.customcrops.objects.WorldState; +import org.bukkit.World; +import org.bukkit.event.HandlerList; +import org.bukkit.event.world.WorldEvent; +import org.jetbrains.annotations.NotNull; + +public class CustomWorldEvent extends WorldEvent { + + private static final HandlerList handlers = new HandlerList(); + private final WorldState state; + + public CustomWorldEvent(@NotNull World world, WorldState worldState) { + super(world); + this.state = worldState; + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlers; + } + + public WorldState getState() { + return state; + } +} diff --git a/src/main/java/net/momirealms/customcrops/api/event/FertilizerUseEvent.java b/src/main/java/net/momirealms/customcrops/api/event/FertilizerUseEvent.java new file mode 100644 index 0000000..9aa3fa4 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/api/event/FertilizerUseEvent.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.api.event; + +import net.momirealms.customcrops.objects.fertilizer.Fertilizer; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.NotNull; + +public class FertilizerUseEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private Fertilizer fertilizer; + private final Location potLoc; + + public FertilizerUseEvent(@NotNull Player who, Fertilizer fertilizer, Location potLoc) { + super(who); + this.cancelled = false; + this.potLoc = potLoc; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlers; + } + + /** + * Get the fertilizer player is using + * @return fertilizer + */ + public Fertilizer getFertilizer() { + return fertilizer; + } + + public void setFertilizer(Fertilizer fertilizer) { + this.fertilizer = fertilizer; + } + + public Location getPotLoc() { + return potLoc; + } +} diff --git a/src/main/java/net/momirealms/customcrops/api/event/SeedPlantEvent.java b/src/main/java/net/momirealms/customcrops/api/event/SeedPlantEvent.java new file mode 100644 index 0000000..7f6f644 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/api/event/SeedPlantEvent.java @@ -0,0 +1,47 @@ +package net.momirealms.customcrops.api.event; + +import net.momirealms.customcrops.api.crop.Crop; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.NotNull; + +public class SeedPlantEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final Location seedLoc; + private final Crop crop; + + public SeedPlantEvent(@NotNull Player who, Location seedLoc, Crop crop) { + super(who); + this.cancelled = false; + this.seedLoc = seedLoc; + this.crop = crop; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlers; + } + + public Location getSeedLoc() { + return seedLoc; + } + + public Crop getCrop() { + return crop; + } +} diff --git a/src/main/java/net/momirealms/customcrops/api/event/SprinklerFillEvent.java b/src/main/java/net/momirealms/customcrops/api/event/SprinklerFillEvent.java new file mode 100644 index 0000000..3382cf5 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/api/event/SprinklerFillEvent.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.api.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +public class SprinklerFillEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final ItemStack itemStack; + + public SprinklerFillEvent(@NotNull Player who, ItemStack itemStack) { + super(who); + this.cancelled = false; + this.itemStack = itemStack; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlers; + } + + /** + * Get the itemStack player used to add water + * @return itemStack + */ + public ItemStack getItemStack() { + return itemStack; + } +} diff --git a/src/main/java/net/momirealms/customcrops/api/event/SprinklerPlaceEvent.java b/src/main/java/net/momirealms/customcrops/api/event/SprinklerPlaceEvent.java new file mode 100644 index 0000000..b5c5408 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/api/event/SprinklerPlaceEvent.java @@ -0,0 +1,40 @@ +package net.momirealms.customcrops.api.event; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.NotNull; + +public class SprinklerPlaceEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final Location location; + + public SprinklerPlaceEvent(@NotNull Player who, Location location) { + super(who); + this.cancelled = false; + this.location = location; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlers; + } + + public Location getLocation() { + return location; + } +} diff --git a/src/main/java/net/momirealms/customcrops/api/event/SurveyorUseEvent.java b/src/main/java/net/momirealms/customcrops/api/event/SurveyorUseEvent.java new file mode 100644 index 0000000..822e3a0 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/api/event/SurveyorUseEvent.java @@ -0,0 +1,49 @@ +package net.momirealms.customcrops.api.event; + +import net.momirealms.customcrops.objects.fertilizer.Fertilizer; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class SurveyorUseEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final Fertilizer fertilizer; + private final Location potLoc; + + public SurveyorUseEvent(@NotNull Player who, @Nullable Fertilizer fertilizer, Location potLoc) { + super(who); + this.cancelled = false; + this.fertilizer = fertilizer; + this.potLoc = potLoc; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlers; + } + + @Nullable + public Fertilizer getFertilizer() { + return fertilizer; + } + + public Location getPotLoc() { + return potLoc; + } +} diff --git a/src/main/java/net/momirealms/customcrops/api/event/WaterEvent.java b/src/main/java/net/momirealms/customcrops/api/event/WaterEvent.java new file mode 100644 index 0000000..07257a4 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/api/event/WaterEvent.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.api.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +public class WaterEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private ItemStack itemStack; + + public WaterEvent(@NotNull Player who, ItemStack itemStack) { + super(who); + this.cancelled = false; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlers; + } + + /** + * Get the item player use + * @return itemStack + */ + public ItemStack getItemStack() { + return itemStack; + } + + public void setItemStack(ItemStack itemStack) { + this.itemStack = itemStack; + } +} diff --git a/src/main/java/net/momirealms/customcrops/api/event/WateringCanFillEvent.java b/src/main/java/net/momirealms/customcrops/api/event/WateringCanFillEvent.java new file mode 100644 index 0000000..4b12a39 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/api/event/WateringCanFillEvent.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.api.event; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +public class WateringCanFillEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private ItemStack itemStack; + + public WateringCanFillEvent(@NotNull Player who, ItemStack itemStack) { + super(who); + this.cancelled = false; + this.itemStack = itemStack; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlers; + } + + /** + * Get the item player use + * @return itemStack + */ + public ItemStack getItemStack() { + return itemStack; + } + + public void setItemStack(ItemStack itemStack) { + this.itemStack = itemStack; + } +} diff --git a/src/main/java/net/momirealms/customcrops/api/utils/CropUtils.java b/src/main/java/net/momirealms/customcrops/api/utils/CropUtils.java new file mode 100644 index 0000000..0936161 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/api/utils/CropUtils.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.api.utils; + +import net.momirealms.customcrops.api.crop.Crop; +import net.momirealms.customcrops.config.CropConfig; +import org.jetbrains.annotations.Nullable; + +public class CropUtils { + + @Nullable + public static Crop getCrop(String crop) { + return CropConfig.CROPS.get(crop); + } +} diff --git a/src/main/java/net/momirealms/customcrops/listener/PapiReload.java b/src/main/java/net/momirealms/customcrops/api/utils/SeasonUtils.java similarity index 59% rename from src/main/java/net/momirealms/customcrops/listener/PapiReload.java rename to src/main/java/net/momirealms/customcrops/api/utils/SeasonUtils.java index be7d6ac..3de05a1 100644 --- a/src/main/java/net/momirealms/customcrops/listener/PapiReload.java +++ b/src/main/java/net/momirealms/customcrops/api/utils/SeasonUtils.java @@ -15,18 +15,21 @@ * along with this program. If not, see . */ -package net.momirealms.customcrops.listener; +package net.momirealms.customcrops.api.utils; import net.momirealms.customcrops.CustomCrops; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; +import net.momirealms.customcrops.integrations.season.CCSeason; +import org.bukkit.World; +import org.jetbrains.annotations.NotNull; -public class PapiReload implements Listener { +public class SeasonUtils { - @EventHandler - public void onReload(me.clip.placeholderapi.events.ExpansionUnregisterEvent event){ - if (CustomCrops.placeholders != null) - if (event.getExpansion().equals(CustomCrops.placeholders)) - CustomCrops.placeholders.register(); + public static void setSeason(World world, CCSeason season) { + CustomCrops.plugin.getCropManager().getSeasonAPI().setSeason(season, world); + } + + @NotNull + public static CCSeason getSeason(World world) { + return CustomCrops.plugin.getCropManager().getSeasonAPI().getSeason(world); } } diff --git a/src/main/java/net/momirealms/customcrops/commands/AbstractSubCommand.java b/src/main/java/net/momirealms/customcrops/commands/AbstractSubCommand.java new file mode 100644 index 0000000..3581cb7 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/commands/AbstractSubCommand.java @@ -0,0 +1,73 @@ +package net.momirealms.customcrops.commands; + +import net.momirealms.customcrops.config.MessageConfig; +import net.momirealms.customcrops.utils.AdventureUtil; +import org.bukkit.command.CommandSender; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public abstract class AbstractSubCommand implements SubCommand { + + private final String command; + private Map subCommandMap; + + public AbstractSubCommand(String command, Map subCommandMap) { + this.command = command; + this.subCommandMap = subCommandMap; + } + + @Override + public boolean onCommand(CommandSender sender, List args) { + if (subCommandMap == null || args.size() < 1) { + return true; + } + SubCommand subCommand = subCommandMap.get(args.get(0)); + if (subCommand == null) { + AdventureUtil.sendMessage(sender, MessageConfig.unavailableArgs); + } else { + subCommand.onCommand(sender, args.subList(1, args.size())); + } + return true; + } + + @Override + public List onTabComplete(CommandSender sender, List args) { + if (subCommandMap == null) + return Collections.singletonList(""); + if (args.size() <= 1) { + List returnList = new ArrayList<>(subCommandMap.keySet()); + returnList.removeIf(str -> !str.startsWith(args.get(0))); + return returnList; + } + SubCommand subCmd = subCommandMap.get(args.get(0)); + if (subCmd != null) + return subCommandMap.get(args.get(0)).onTabComplete(sender, args.subList(1, args.size())); + return Collections.singletonList(""); + } + + @Override + public String getSubCommand() { + return command; + } + + @Override + public Map getSubCommands() { + return Collections.unmodifiableMap(subCommandMap); + } + + @Override + public void regSubCommand(SubCommand command) { + if (subCommandMap == null) { + subCommandMap = new ConcurrentHashMap<>(); + } + subCommandMap.put(command.getSubCommand(), command); + } + + public void setSubCommandMap(Map subCommandMap) { + this.subCommandMap = subCommandMap; + } +} diff --git a/src/main/java/net/momirealms/customcrops/commands/Completer.java b/src/main/java/net/momirealms/customcrops/commands/Completer.java deleted file mode 100644 index 27c0970..0000000 --- a/src/main/java/net/momirealms/customcrops/commands/Completer.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.commands; - -import net.momirealms.customcrops.ConfigReader; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class Completer implements TabCompleter { - - @Override - public @Nullable List onTabComplete(CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) { - if (!(sender.isOp() || sender.hasPermission("customcrops.admin"))){ - return null; - } - if (args.length == 1) { - List arrayList = new ArrayList<>(); - for (String cmd : Arrays.asList("backup", "forcegrow", "forcesave", "forceall","forcewater", "reload", "setseason")) { - if (cmd.startsWith(args[0])) - arrayList.add(cmd); - } - return arrayList; - } - if(args[0].equalsIgnoreCase("setseason") && args.length == 2){ - List arrayList = new ArrayList<>(); - for (String cmd : ConfigReader.Config.worldNames) { - if (cmd.startsWith(args[1])) - arrayList.add(cmd); - } - return arrayList; - } - if(args[0].equalsIgnoreCase("forcesave") && args.length == 2){ - List arrayList = new ArrayList<>(); - if (ConfigReader.Season.enable){ - if (ConfigReader.Season.seasonChange){ - for (String cmd : Arrays.asList("all","crop","pot","sprinkler")) { - if (cmd.startsWith(args[1])) - arrayList.add(cmd); - } - }else{ - for (String cmd : Arrays.asList("all","crop","pot","season","sprinkler")) { - if (cmd.startsWith(args[1])) - arrayList.add(cmd); - } - } - }else { - for (String cmd : Arrays.asList("all","crop","pot","sprinkler")) { - if (cmd.startsWith(args[1])) - arrayList.add(cmd); - } - } - return arrayList; - } - if(args[0].equalsIgnoreCase("setseason") && args.length == 3){ - List arrayList = new ArrayList<>(); - for (String cmd : Arrays.asList("spring","summer","autumn","winter")) { - if (cmd.startsWith(args[2])) - arrayList.add(cmd); - } - return arrayList; - } - if(args[0].equalsIgnoreCase("forcegrow") || args[0].equalsIgnoreCase("forcewater") || args[0].equalsIgnoreCase("forceall")){ - List arrayList = new ArrayList<>(); - for (String cmd : ConfigReader.Config.worldNames) { - if (cmd.startsWith(args[1])) - arrayList.add(cmd); - } - return arrayList; - } - return null; - } -} diff --git a/src/main/java/net/momirealms/customcrops/commands/Executor.java b/src/main/java/net/momirealms/customcrops/commands/Executor.java deleted file mode 100644 index 7ad766e..0000000 --- a/src/main/java/net/momirealms/customcrops/commands/Executor.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.commands; - -import net.momirealms.customcrops.utils.AdventureManager; -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.CustomCrops; -import net.momirealms.customcrops.utils.FileUtil; -import org.bukkit.Bukkit; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; - - -public class Executor implements CommandExecutor { - - private final CustomCrops plugin; - - public Executor(CustomCrops plugin){ - this.plugin = plugin; - } - - @Override - public boolean onCommand(CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { - - if (!(sender.hasPermission("customcrops.admin") || sender.isOp())){ - AdventureManager.playerMessage((Player) sender, ConfigReader.Message.prefix + ConfigReader.Message.noPerm); - return true; - } - - if (args.length < 1) { - lackArgs(sender); - return true; - } - switch (args[0]){ - case "reload" -> { - long time = System.currentTimeMillis(); - ConfigReader.reloadConfig(); - if(sender instanceof Player){ - AdventureManager.playerMessage((Player) sender,ConfigReader.Message.prefix + ConfigReader.Message.reload.replace("{time}", String.valueOf(System.currentTimeMillis() - time))); - }else { - AdventureManager.consoleMessage(ConfigReader.Message.prefix + ConfigReader.Message.reload.replace("{time}", String.valueOf(System.currentTimeMillis() - time))); - } - return true; - } - case "forcegrow" -> { - if (args.length < 2) { - lackArgs(sender); - return true; - } - Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.plugin, ()-> { - switch (ConfigReader.Config.growMode){ - case 1 -> plugin.getCropManager().growModeOne(args[1]); - case 2 -> plugin.getCropManager().growModeTwo(args[1]); - case 3 -> plugin.getCropManager().growModeThree(args[1]); - case 4 -> plugin.getCropManager().growModeFour(args[1]); - } - }); - if (sender instanceof Player player){ - AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.forceGrow.replace("{world}",args[1])); - }else { - AdventureManager.consoleMessage(ConfigReader.Message.prefix + ConfigReader.Message.forceGrow.replace("{world}",args[1])); - } - return true; - } - case "forcewater" -> { - if (args.length < 2) { - lackArgs(sender); - return true; - } - Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.plugin, ()-> { - switch (ConfigReader.Config.growMode){ - case 1 -> plugin.getSprinklerManager().workModeOne(args[1]); - case 2 -> plugin.getSprinklerManager().workModeTwo(args[1]); - case 3 -> plugin.getSprinklerManager().workModeThree(args[1]); - case 4 -> plugin.getSprinklerManager().workModeFour(args[1]); - } - }); - if (sender instanceof Player player){ - AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.forceWater.replace("{world}",args[1])); - }else { - AdventureManager.consoleMessage(ConfigReader.Message.prefix + ConfigReader.Message.forceWater.replace("{world}",args[1])); - } - return true; - } - case "forceall" -> { - if (args.length < 2) { - lackArgs(sender); - return true; - } - Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.plugin, ()-> { - switch (ConfigReader.Config.growMode){ - case 1 -> plugin.getCropManager().growModeOne(args[1]); - case 2 -> plugin.getCropManager().growModeTwo(args[1]); - case 3 -> plugin.getCropManager().growModeThree(args[1]); - case 4 -> plugin.getCropManager().growModeFour(args[1]); - } - }); - Bukkit.getScheduler().runTaskLaterAsynchronously(CustomCrops.plugin, ()-> { - switch (ConfigReader.Config.growMode){ - case 1 -> plugin.getSprinklerManager().workModeOne(args[1]); - case 2 -> plugin.getSprinklerManager().workModeTwo(args[1]); - case 3 -> plugin.getSprinklerManager().workModeThree(args[1]); - case 4 -> plugin.getSprinklerManager().workModeFour(args[1]); - } - }, ConfigReader.Config.timeToGrow); - if (sender instanceof Player player){ - AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.forceAll.replace("{world}",args[1])); - }else { - AdventureManager.consoleMessage(ConfigReader.Message.prefix + ConfigReader.Message.forceAll.replace("{world}",args[1])); - } - return true; - } - case "forcesave" -> { - if (args.length < 2) { - lackArgs(sender); - return true; - } - Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.plugin, ()->{ - switch (args[1]){ - case "all" -> { - plugin.getSprinklerManager().updateData(); - plugin.getSprinklerManager().saveData(); - if (ConfigReader.Season.enable && !ConfigReader.Season.seasonChange){ - plugin.getSeasonManager().saveData(); - } - plugin.getCropManager().updateData(); - plugin.getCropManager().saveData(); - plugin.getPotManager().saveData(); - forceSave(sender); - } - case "crop" -> { - plugin.getCropManager().updateData(); - plugin.getCropManager().saveData(); - forceSave(sender); - } - case "pot" -> { - plugin.getPotManager().saveData(); - forceSave(sender); - } - case "season" -> { - plugin.getSeasonManager().saveData(); - forceSave(sender); - } - case "sprinkler" -> { - plugin.getSprinklerManager().updateData(); - plugin.getSprinklerManager().saveData(); - forceSave(sender); - } - } - }); - } - case "backup" -> { - FileUtil.backUpData(); - if (sender instanceof Player player){ - AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.backUp); - }else { - AdventureManager.consoleMessage(ConfigReader.Message.prefix + ConfigReader.Message.backUp); - } - return true; - } - case "cleandata" -> { - plugin.getCropManager().cleanData(); - plugin.getSprinklerManager().cleanData(); - return true; - } - case "setseason" -> { - if (args.length < 3) { - lackArgs(sender); - return true; - } - if (plugin.getSeasonManager().setSeason(args[1], args[2])){ - if (sender instanceof Player player){ - AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.setSeason.replace("{world}",args[1]).replace("{season}",args[2])); - }else { - AdventureManager.consoleMessage(ConfigReader.Message.prefix + ConfigReader.Message.setSeason.replace("{world}",args[1]).replace("{season}",args[2])); - } - }else { - if (sender instanceof Player player){ - AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.wrongArgs); - }else { - AdventureManager.consoleMessage(ConfigReader.Message.prefix + ConfigReader.Message.wrongArgs); - } - } - return true; - } - default -> { - if (sender instanceof Player player){ - AdventureManager.playerMessage(player,"/customcrops reload 重载插件"); - AdventureManager.playerMessage(player,"/customcrops setseason 设置某个世界的季节"); - AdventureManager.playerMessage(player,"/customcrops backup 备份数据"); - AdventureManager.playerMessage(player,"/customcrops forcegrow 强制某个世界的农作物进行生长判定"); - AdventureManager.playerMessage(player,"/customcrops forcewater 强制某个世界的洒水器进行工作判定"); - AdventureManager.playerMessage(player,"/customcrops forcesave 强制更新缓存并保存"); - }else { - AdventureManager.consoleMessage("/customcrops reload 重载插件"); - AdventureManager.consoleMessage("/customcrops setseason 设置某个世界的季节"); - AdventureManager.consoleMessage("/customcrops backup 备份数据"); - AdventureManager.consoleMessage("/customcrops forcegrow 强制某个世界的农作物进行生长判定"); - AdventureManager.consoleMessage("/customcrops forcewater 强制某个世界的洒水器进行工作判定"); - AdventureManager.consoleMessage("/customcrops forcesave 强制更新缓存并保存"); - } - } - } - return true; - } - - /** - * 缺少参数的提示语 - * @param sender 发送者 - */ - private void lackArgs(CommandSender sender){ - if (sender instanceof Player){ - AdventureManager.playerMessage((Player) sender,ConfigReader.Message.prefix + ConfigReader.Message.lackArgs); - }else { - AdventureManager.consoleMessage(ConfigReader.Message.prefix + ConfigReader.Message.lackArgs); - } - } - - /** - * 强制保存的提示语 - * @param sender 发送者 - */ - private void forceSave(CommandSender sender){ - if (sender instanceof Player player){ - AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.forceSave); - }else { - AdventureManager.consoleMessage(ConfigReader.Message.prefix + ConfigReader.Message.forceSave); - } - } -} diff --git a/src/main/java/net/momirealms/customcrops/commands/PluginCommand.java b/src/main/java/net/momirealms/customcrops/commands/PluginCommand.java new file mode 100644 index 0000000..21cd34d --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/commands/PluginCommand.java @@ -0,0 +1,67 @@ +package net.momirealms.customcrops.commands; + +import net.momirealms.customcrops.commands.subcmd.ReloadCommand; +import net.momirealms.customcrops.commands.subcmd.SetSeasonCommand; +import net.momirealms.customcrops.config.MessageConfig; +import net.momirealms.customcrops.utils.AdventureUtil; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +public class PluginCommand implements TabExecutor { + + private final Map subCommandMap; + + public PluginCommand() { + subCommandMap = new ConcurrentHashMap<>(); + regDefaultSubCommands(); + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + List argList = Arrays.asList(args); + if (argList.size() < 1) { + AdventureUtil.sendMessage(sender, MessageConfig.nonArgs); + return true; + } + SubCommand subCommand = subCommandMap.get(argList.get(0)); + if (subCommand != null) + return subCommand.onCommand(sender, argList.subList(1, argList.size())); + else { + AdventureUtil.sendMessage(sender, MessageConfig.unavailableArgs); + return true; + } + } + + private void regDefaultSubCommands() { + regSubCommand(ReloadCommand.INSTANCE); + regSubCommand(SetSeasonCommand.INSTANCE); + } + + public void regSubCommand(SubCommand executor) { + subCommandMap.put(executor.getSubCommand(), executor); + } + + @Override + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) { + List argList = Arrays.asList(args); + if (argList.size() <= 1) { + List returnList = new ArrayList<>(subCommandMap.keySet()); + returnList.removeIf(str -> !str.startsWith(args[0])); + return returnList; + } + SubCommand subCommand = subCommandMap.get(argList.get(0)); + if (subCommand != null) + return subCommand.onTabComplete(sender, argList.subList(1, argList.size())); + else + return Collections.singletonList(""); + } + + public Map getSubCommandMap() { + return subCommandMap; + } +} diff --git a/src/main/java/net/momirealms/customcrops/commands/SubCommand.java b/src/main/java/net/momirealms/customcrops/commands/SubCommand.java new file mode 100644 index 0000000..fd492c9 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/commands/SubCommand.java @@ -0,0 +1,20 @@ +package net.momirealms.customcrops.commands; + +import org.bukkit.command.CommandSender; + +import java.util.List; +import java.util.Map; + +public interface SubCommand { + + boolean onCommand(CommandSender sender, List args); + + List onTabComplete(CommandSender sender, List args); + + String getSubCommand(); + + Map getSubCommands(); + + void regSubCommand(SubCommand subCommand); + +} diff --git a/src/main/java/net/momirealms/customcrops/commands/subcmd/ReloadCommand.java b/src/main/java/net/momirealms/customcrops/commands/subcmd/ReloadCommand.java new file mode 100644 index 0000000..3657d95 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/commands/subcmd/ReloadCommand.java @@ -0,0 +1,38 @@ +package net.momirealms.customcrops.commands.subcmd; + +import net.momirealms.customcrops.commands.AbstractSubCommand; +import net.momirealms.customcrops.commands.SubCommand; +import net.momirealms.customcrops.config.ConfigUtil; +import net.momirealms.customcrops.config.MessageConfig; +import net.momirealms.customcrops.utils.AdventureUtil; +import org.bukkit.command.CommandSender; + +import java.util.List; + +public final class ReloadCommand extends AbstractSubCommand { + + public static final SubCommand INSTANCE = new ReloadCommand(); + + private ReloadCommand() { + super("reload", null); + regSubCommand(new AbstractSubCommand("config", null) { + @Override + public boolean onCommand(CommandSender sender, List args) { + ConfigUtil.reloadConfigs(); + AdventureUtil.sendMessage(sender, MessageConfig.prefix + MessageConfig.reload); + return true; + } + }); + } + + @Override + public boolean onCommand(CommandSender sender, List args) { + if (args.size() < 1) { + long time1 = System.currentTimeMillis(); + ConfigUtil.reloadConfigs(); + AdventureUtil.sendMessage(sender, MessageConfig.prefix + MessageConfig.reload.replace("{time}", String.valueOf(System.currentTimeMillis() - time1))); + return true; + } + return super.onCommand(sender, args); + } +} diff --git a/src/main/java/net/momirealms/customcrops/commands/subcmd/SetSeasonCommand.java b/src/main/java/net/momirealms/customcrops/commands/subcmd/SetSeasonCommand.java new file mode 100644 index 0000000..e86333b --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/commands/subcmd/SetSeasonCommand.java @@ -0,0 +1,65 @@ +package net.momirealms.customcrops.commands.subcmd; + +import net.momirealms.customcrops.api.utils.SeasonUtils; +import net.momirealms.customcrops.commands.AbstractSubCommand; +import net.momirealms.customcrops.commands.SubCommand; +import net.momirealms.customcrops.config.*; +import net.momirealms.customcrops.integrations.season.CCSeason; +import net.momirealms.customcrops.utils.AdventureUtil; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.command.CommandSender; + +import java.util.List; + +public class SetSeasonCommand extends AbstractSubCommand { + + public static final SubCommand INSTANCE = new SetSeasonCommand(); + + public SetSeasonCommand() { + super("setseason", null); + regSubCommand(new AbstractSubCommand("config", null) { + @Override + public boolean onCommand(CommandSender sender, List args) { + + AdventureUtil.sendMessage(sender, MessageConfig.prefix + MessageConfig.setSeason); + return true; + } + }); + } + + @Override + public boolean onCommand(CommandSender sender, List args) { + if (args.size() < 2) { + AdventureUtil.sendMessage(sender, MessageConfig.prefix + MessageConfig.lackArgs); + return true; + } + else { + World world = Bukkit.getWorld(args.get(0)); + if (world == null) { + AdventureUtil.sendMessage(sender, MessageConfig.prefix + MessageConfig.worldNotExists); + return true; + } + CCSeason ccSeason; + try { + ccSeason = CCSeason.valueOf(args.get(1).toUpperCase()); + } + catch (IllegalArgumentException e) { + AdventureUtil.sendMessage(sender, MessageConfig.prefix + MessageConfig.seasonNotExists); + return true; + } + SeasonUtils.setSeason(world, ccSeason); + AdventureUtil.sendMessage(sender, MessageConfig.prefix + MessageConfig.setSeason); + } + return super.onCommand(sender, args); + } + + public static void setSeason() { + MainConfig.load(); + FertilizerConfig.load(); + MessageConfig.load(); + SeasonConfig.load(); + SprinklerConfig.load(); + WaterCanConfig.load(); + } +} diff --git a/src/main/java/net/momirealms/customcrops/config/BasicItemConfig.java b/src/main/java/net/momirealms/customcrops/config/BasicItemConfig.java new file mode 100644 index 0000000..004ba45 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/config/BasicItemConfig.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.config; + +import org.bukkit.configuration.file.YamlConfiguration; + +public class BasicItemConfig { + + public static String dryPot; + public static String wetPot; + public static String deadCrop; + public static String soilSurveyor; + public static String greenHouseGlass; + public static String crow; + public static String scarecrow; + public static String waterEffect; + + public static void load() { + YamlConfiguration config = ConfigUtil.getConfig("basic_" + MainConfig.customPlugin + ".yml"); + dryPot = config.getString("dry-pot"); + wetPot = config.getString("wet-pot"); + greenHouseGlass = config.getString("greenhouse-glass"); + soilSurveyor = config.getString("soil-surveyor"); + deadCrop = config.getString("dead-crop"); + crow = config.getString("crow"); + scarecrow = config.getString("scarecrow"); + waterEffect = config.getString("water-effect"); + } +} diff --git a/src/main/java/net/momirealms/customcrops/config/ConfigUtil.java b/src/main/java/net/momirealms/customcrops/config/ConfigUtil.java new file mode 100644 index 0000000..d0ceec1 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/config/ConfigUtil.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.config; + +import dev.dejvokep.boostedyaml.YamlDocument; +import dev.dejvokep.boostedyaml.dvs.versioning.BasicVersioning; +import dev.dejvokep.boostedyaml.settings.dumper.DumperSettings; +import dev.dejvokep.boostedyaml.settings.general.GeneralSettings; +import dev.dejvokep.boostedyaml.settings.loader.LoaderSettings; +import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings; +import net.momirealms.customcrops.CustomCrops; +import net.momirealms.customcrops.helper.Log; +import net.momirealms.customcrops.utils.AdventureUtil; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.IOException; + +public class ConfigUtil { + + public static void update(String fileName){ + try { + YamlDocument.create(new File(CustomCrops.plugin.getDataFolder(), fileName), CustomCrops.plugin.getResource(fileName), GeneralSettings.DEFAULT, LoaderSettings.builder().setAutoUpdate(true).build(), DumperSettings.DEFAULT, UpdaterSettings.builder().setVersioning(new BasicVersioning("config-version")).build()); + } catch (IOException e){ + Log.warn(e.getMessage()); + } + } + + public static YamlConfiguration readData(File file) { + if (!file.exists()) { + try { + file.getParentFile().mkdirs(); + file.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + AdventureUtil.consoleMessage("[CustomCrops] Failed to generate data files!"); + } + } + return YamlConfiguration.loadConfiguration(file); + } + + public static YamlConfiguration getConfig(String configName) { + File file = new File(CustomCrops.plugin.getDataFolder(), configName); + if (!file.exists()) CustomCrops.plugin.saveResource(configName, false); + return YamlConfiguration.loadConfiguration(file); + } + + public static void reloadConfigs() { + MainConfig.load(); + BasicItemConfig.load(); + CropConfig.load(); + FertilizerConfig.load(); + MessageConfig.load(); + SeasonConfig.load(); + SprinklerConfig.load(); + WaterCanConfig.load(); + SoundConfig.load(); + if (CustomCrops.plugin.getPlaceholderManager() != null) { + CustomCrops.plugin.getPlaceholderManager().unload(); + CustomCrops.plugin.getPlaceholderManager().load(); + } + } +} diff --git a/src/main/java/net/momirealms/customcrops/config/CropConfig.java b/src/main/java/net/momirealms/customcrops/config/CropConfig.java new file mode 100644 index 0000000..0aa5717 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/config/CropConfig.java @@ -0,0 +1,157 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.config; + +import net.momirealms.customcrops.api.crop.Crop; +import net.momirealms.customcrops.integrations.season.CCSeason; +import net.momirealms.customcrops.objects.CCCrop; +import net.momirealms.customcrops.objects.GiganticCrop; +import net.momirealms.customcrops.objects.OtherLoot; +import net.momirealms.customcrops.objects.QualityLoot; +import net.momirealms.customcrops.objects.actions.*; +import net.momirealms.customcrops.objects.requirements.*; +import net.momirealms.customcrops.utils.AdventureUtil; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Objects; + +public class CropConfig { + + public static HashMap CROPS; + + public static void load() { + CROPS = new HashMap<>(16); + YamlConfiguration config = ConfigUtil.getConfig("crops_" + MainConfig.customPlugin + ".yml"); + for (String key : config.getKeys(false)) { + CCCrop crop = new CCCrop(key); + for (String option : config.getConfigurationSection(key).getKeys(false)) { + if (option.equals("quality-loots")) { + String amount = config.getString(key + ".quality-loots.amount", "1~2"); + QualityLoot qualityLoot = new QualityLoot( + Integer.parseInt(amount.split("~")[0]), + Integer.parseInt(amount.split("~")[1]), + config.getString(key + ".quality-loots.quality.1"), + config.getString(key + ".quality-loots.quality.2"), + config.getString(key + ".quality-loots.quality.3") + ); + crop.setQualityLoot(qualityLoot); + } + if (option.equals("other-loots")) { + List otherLoots = new ArrayList<>(); + for (String loot : Objects.requireNonNull(config.getConfigurationSection(key + ".other-loots")).getKeys(false)) { + OtherLoot otherLoot = new OtherLoot( + config.getInt(key + ".other-loots." + loot + ".min_amount", 1), + config.getInt(key + ".other-loots." + loot + ".max_amount", 1), + config.getString(key + ".other-loots." + loot + ".item"), + config.getDouble(key + ".other-loots." + loot + ".chance", 1d) + ); + otherLoots.add(otherLoot); + } + crop.setOtherLoots(otherLoots.toArray(new OtherLoot[0])); + } + if (option.equals("harvest-actions")) { + List actions = new ArrayList<>(); + for (String action : Objects.requireNonNull(config.getConfigurationSection(key + ".harvest-actions")).getKeys(false)) { + switch (action) { + case "xp" -> actions.add(new ActionXP(config.getInt(key + ".harvest-actions." + action))); + case "skill-xp" -> actions.add(new ActionSkillXP(config.getDouble(key + ".harvest-actions." + action))); + case "commands" -> actions.add(new ActionCommand(config.getStringList(key + ".harvest-actions." + action).toArray(new String[0]))); + case "messages" -> actions.add(new ActionMessage(config.getStringList(key + ".harvest-actions." + action).toArray(new String[0]))); + } + } + crop.setActions(actions.toArray(new ActionInterface[0])); + } + if (option.equals("season")) { + List seasonList = config.getStringList(key + ".season"); + CCSeason[] seasons = new CCSeason[seasonList.size()]; + for (int i = 0; i < seasonList.size(); i++) { + seasons[i] = CCSeason.valueOf(seasonList.get(i).toUpperCase()); + } + crop.setSeasons(seasons); + } + if (option.equals("gigantic-crop")) { + boolean isBlock = true; + String blockID = config.getString(key + ".gigantic-crop.block"); + if (blockID == null) { + blockID = config.getString(key + ".gigantic-crop.furniture"); + isBlock = false; + } + GiganticCrop giganticCrop = new GiganticCrop( + config.getDouble(key + ".gigantic-crop.chance"), + isBlock, + blockID + ); + crop.setGiganticCrop(giganticCrop); + } + if (option.equals("return")) { + crop.setReturnStage(config.getString(key + ".return")); + } + if (option.equals("requirements")) { + List requirementList = new ArrayList<>(); + for (String requirement : Objects.requireNonNull(config.getConfigurationSection(key + ".requirements")).getKeys(false)) { + String type = config.getString(key + ".requirements." + requirement + ".type"); + if (type == null) continue; + switch (type) { + case "time" -> requirementList.add(new RequirementTime( + config.getStringList(key + ".requirements." + requirement + ".value").toArray(new String[0]), + Objects.equals(config.getString(key + ".requirements." + requirement + ".mode"), "&&"), + config.getString(key + ".requirements." + requirement + ".message") + )); + case "weather" -> requirementList.add(new RequirementWeather( + config.getStringList(key + ".requirements." + requirement + ".value").toArray(new String[0]), + Objects.equals(config.getString(key + ".requirements." + requirement + ".mode"), "&&"), + config.getString(key + ".requirements." + requirement + ".message") + )); + case "yPos" -> requirementList.add(new RequirementYPos( + config.getStringList(key + ".requirements." + requirement + ".value").toArray(new String[0]), + Objects.equals(config.getString(key + ".requirements." + requirement + ".mode"), "&&"), + config.getString(key + ".requirements." + requirement + ".message") + )); + case "biome" -> requirementList.add(new RequirementBiome( + config.getStringList(key + ".requirements." + requirement + ".value").toArray(new String[0]), + Objects.equals(config.getString(key + ".requirements." + requirement + ".mode"), "&&"), + config.getString(key + ".requirements." + requirement + ".message") + )); + case "world" -> requirementList.add(new RequirementWorld( + config.getStringList(key + ".requirements." + requirement + ".value").toArray(new String[0]), + Objects.equals(config.getString(key + ".requirements." + requirement + ".mode"), "&&"), + config.getString(key + ".requirements." + requirement + ".message") + )); + case "permission" -> requirementList.add(new RequirementPermission( + config.getStringList(key + ".requirements." + requirement + ".value").toArray(new String[0]), + Objects.equals(config.getString(key + ".requirements." + requirement + ".mode"), "&&"), + config.getString(key + ".requirements." + requirement + ".message") + )); + case "papi-condition" -> requirementList.add(new CustomPapi( + Objects.requireNonNull(config.getConfigurationSection(key + ".requirements." + requirement + ".papi-condition")).getValues(false), + config.getString(key + ".requirements." + requirement + ".message") + )); + } + } + crop.setRequirements(requirementList.toArray(new RequirementInterface[0])); + } + } + + CROPS.put(key, crop); + } + AdventureUtil.consoleMessage("[CustomCrops] Loaded " + CROPS.size() + " crops"); + } +} diff --git a/src/main/java/net/momirealms/customcrops/config/FertilizerConfig.java b/src/main/java/net/momirealms/customcrops/config/FertilizerConfig.java new file mode 100644 index 0000000..c92f3d5 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/config/FertilizerConfig.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.config; + +import net.momirealms.customcrops.objects.QualityRatio; +import net.momirealms.customcrops.objects.fertilizer.*; +import net.momirealms.customcrops.utils.AdventureUtil; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Particle; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.util.HashMap; +import java.util.Objects; + +public class FertilizerConfig { + + public static HashMap FERTILIZERS; + + public static void load() { + FERTILIZERS = new HashMap<>(16); + YamlConfiguration config = ConfigUtil.getConfig("fertilizers_" + MainConfig.customPlugin + ".yml"); + for (String key : config.getKeys(false)) { + switch (key) { + case "speed" -> { + for (String fertilizer : Objects.requireNonNull(config.getConfigurationSection(key)).getKeys(false)) { + SpeedGrow speedGrow = new SpeedGrow( + fertilizer, + config.getInt(key + "." + fertilizer + ".times", 14), + config.getDouble(key + "." +fertilizer + ".chance", 0.01), + config.getBoolean(key + "." + fertilizer + ".before-plant", true), + config.getString(key + "." + fertilizer + ".name") + ); + if (config.contains(key + "." + fertilizer + ".particle")) { + speedGrow.setParticle(Particle.valueOf(config.getString(key + "." + fertilizer + ".particle", "VILLAGER_HAPPY").toUpperCase())); + } + FERTILIZERS.put(config.getString(key + "." + fertilizer + ".item"), speedGrow); + FERTILIZERS.put(fertilizer, speedGrow); + } + } + case "gigantic" -> { + for (String fertilizer : Objects.requireNonNull(config.getConfigurationSection(key)).getKeys(false)) { + Gigantic gigantic = new Gigantic( + fertilizer, + config.getInt(key + "." + fertilizer + ".times", 14), + config.getDouble(key + "." +fertilizer + ".chance", 0.01), + config.getBoolean(key + "." + fertilizer + ".before-plant", true), + config.getString(key + "." + fertilizer + ".name") + ); + if (config.contains(key + "." + fertilizer + ".particle")) { + gigantic.setParticle(Particle.valueOf(config.getString(key + "." + fertilizer + ".particle", "VILLAGER_HAPPY").toUpperCase())); + } + FERTILIZERS.put(config.getString(key + "." + fertilizer + ".item"), gigantic); + FERTILIZERS.put(fertilizer, gigantic); + } + } + case "retaining" -> { + for (String fertilizer : Objects.requireNonNull(config.getConfigurationSection(key)).getKeys(false)) { + RetainingSoil retainingSoil = new RetainingSoil( + fertilizer, + config.getInt(key + "." + fertilizer + ".times", 14), + config.getDouble(key + "." +fertilizer + ".chance", 0.01), + config.getBoolean(key + "." + fertilizer + ".before-plant", true), + config.getString(key + "." + fertilizer + ".name") + ); + if (config.contains(key + "." + fertilizer + ".particle")) { + retainingSoil.setParticle(Particle.valueOf(config.getString(key + "." + fertilizer + ".particle", "VILLAGER_HAPPY").toUpperCase())); + } + FERTILIZERS.put(config.getString(key + "." + fertilizer + ".item"), retainingSoil); + FERTILIZERS.put(fertilizer, retainingSoil); + } + } + case "quantity" -> { + for (String fertilizer : Objects.requireNonNull(config.getConfigurationSection(key)).getKeys(false)) { + YieldIncreasing yieldIncreasing = new YieldIncreasing( + fertilizer, + config.getInt(key + "." + fertilizer + ".times", 14), + config.getDouble(key + "." +fertilizer + ".chance", 0.01), + config.getInt(key + "." +fertilizer + ".bonus",1), + config.getBoolean(key + "." + fertilizer + ".before-plant", true), + config.getString(key + "." + fertilizer + ".name") + ); + if (config.contains(key + "." + fertilizer + ".particle")) { + yieldIncreasing.setParticle(Particle.valueOf(config.getString(key + "." + fertilizer + ".particle", "VILLAGER_HAPPY").toUpperCase())); + } + FERTILIZERS.put(config.getString(key + "." + fertilizer + ".item"), yieldIncreasing); + FERTILIZERS.put(fertilizer, yieldIncreasing); + } + } + case "quality" -> { + for (String fertilizer : Objects.requireNonNull(config.getConfigurationSection(key)).getKeys(false)) { + String[] split = StringUtils.split(config.getString(key + "." + fertilizer + ".ratio"), "/"); + double[] weight = new double[3]; + weight[0] = Double.parseDouble(split[0]); + weight[1] = Double.parseDouble(split[1]); + weight[2] = Double.parseDouble(split[2]); + double weightTotal = weight[0] + weight[1] + weight[2]; + QualityRatio qualityRatio = new QualityRatio(weight[0]/(weightTotal), 1 - weight[1]/(weightTotal)); + QualityCrop qualityCrop = new QualityCrop( + fertilizer, + config.getInt(key + "." + fertilizer + ".times", 14), + config.getDouble(key + "." +fertilizer + ".chance", 0.01), + qualityRatio, + config.getBoolean(key + "." + fertilizer + ".before-plant", true), + config.getString(key + "." + fertilizer + ".name") + ); + if (config.contains(key + "." + fertilizer + ".particle")) { + qualityCrop.setParticle(Particle.valueOf(config.getString(key + "." + fertilizer + ".particle", "VILLAGER_HAPPY").toUpperCase())); + } + FERTILIZERS.put(config.getString(key + "." + fertilizer + ".item"), qualityCrop); + FERTILIZERS.put(fertilizer, qualityCrop); + } + } + } + } + AdventureUtil.consoleMessage("[CustomCrops] Loaded " + FERTILIZERS.size() / 2 + " fertilizers"); + } +} diff --git a/src/main/java/net/momirealms/customcrops/config/MainConfig.java b/src/main/java/net/momirealms/customcrops/config/MainConfig.java new file mode 100644 index 0000000..6e0127f --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/config/MainConfig.java @@ -0,0 +1,222 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.config; + +import net.momirealms.customcrops.helper.Log; +import net.momirealms.customcrops.integrations.AntiGrief; +import net.momirealms.customcrops.integrations.SkillXP; +import net.momirealms.customcrops.integrations.protection.*; +import net.momirealms.customcrops.objects.QualityRatio; +import net.momirealms.customcrops.utils.AdventureUtil; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.Particle; +import org.bukkit.World; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.util.ArrayList; +import java.util.List; + +public class MainConfig { + + public static World[] worlds; + public static List worldList; + public static boolean whiteOrBlack; + public static boolean asyncTimeCheck; + public static String customPlugin; + public static boolean OraxenHook; + public static boolean realisticSeasonHook; + public static String cropMode; + public static List antiGriefs; + public static SkillXP skillXP; + public static double dryGrowChance; + public static boolean limitation; + public static int wireAmount; + public static int frameAmount; + public static QualityRatio qualityRatio; + public static boolean canRightClickHarvest; + public static boolean emptyHand; + public static int waterBucketToSprinkler; + public static int waterToWaterCan; + public static int wateringCanToSprinkler; + public static int timeToGrow; + public static String lang; + public static boolean preventInWrongSeason; + public static boolean notifyInWrongSeason; + public static boolean enableBoneMeal; + public static double boneMealChance; + public static Particle boneMealSuccess; + public static boolean enableCrow; + public static double crowChance; + public static boolean enableActionBar; + public static String actionBarLeft; + public static String actionBarFull; + public static String actionBarEmpty; + public static String actionBarRight; + public static boolean enableSprinklerInfo; + public static double sprinklerInfoY; + public static int sprinklerInfoDuration; + public static String sprinklerLeft; + public static String sprinklerFull; + public static String sprinklerEmpty; + public static String sprinklerRight; + public static boolean enableFertilizerInfo; + public static double fertilizerInfoY; + public static int fertilizerInfoDuration; + public static String fertilizerInfo; + + public static void load() { + ConfigUtil.update("config.yml"); + YamlConfiguration config = ConfigUtil.getConfig("config.yml"); + + lang = config.getString("lang","english"); + + whiteOrBlack = config.getString("worlds.mode","whitelist").equals("whitelist"); + List worldsName = config.getStringList("worlds.list"); + worlds = new World[worldsName.size()]; + for (int i = 0; i < worldsName.size(); i++) { + if (Bukkit.getWorld(worldsName.get(i)) != null) { + worlds[i] = Bukkit.getWorld(worldsName.get(i)); + } + } + worldList = List.of(worlds); + cropMode = config.getString("crops.mode", "tripwire"); + asyncTimeCheck = config.getBoolean("optimization.async-time-check", false); + limitation = config.getBoolean("optimization.limitation.enable", true); + wireAmount = config.getInt("optimization.limitation.tripwire-amount", 64); + frameAmount = config.getInt("optimization.limitation.itemframe-amount", 64); + + waterBucketToSprinkler = config.getInt("mechanics.fill.water-bucket-to-sprinkler", 3); + waterToWaterCan = config.getInt("mechanics.fill.waterblock-to-watering-can", 1); + wateringCanToSprinkler = config.getInt("mechanics.fill.watering-can-to-sprinkler", 1); + + canRightClickHarvest = config.getBoolean("mechanics.right-click-harvest.enable", true); + emptyHand = config.getBoolean("mechanics.right-click-harvest.require-empty-hand", true); + preventInWrongSeason = config.getBoolean("mechanics.prevent-plant-if-wrong-season", true); + notifyInWrongSeason = config.getBoolean("mechanics.should-notify-if-wrong-season", true); + + enableBoneMeal = config.getBoolean("mechanics.bone-meal", true); + boneMealChance = config.getDouble("mechanics.chance", 0.5); + + try { + boneMealSuccess = Particle.valueOf(config.getString("mechanics.success-particle", "VILLAGER_HAPPY")); + } + catch (IllegalArgumentException e) { + AdventureUtil.consoleMessage("[CustomCrops] Illegal Particle Argument for Bone Meal"); + } + + enableCrow = config.getBoolean("mechanics.crow.enable", false); + crowChance = config.getDouble("mechanics.crow.chance", 0.001); + + String[] split = StringUtils.split(config.getString("mechanics.default-quality-ratio", "17/2/1"), "/"); + double[] weight = new double[3]; + assert split != null; + weight[0] = Double.parseDouble(split[0]); + weight[1] = Double.parseDouble(split[1]); + weight[2] = Double.parseDouble(split[2]); + double weightTotal = weight[0] + weight[1] + weight[2]; + qualityRatio = new QualityRatio(weight[0]/(weightTotal), 1 - weight[1]/(weightTotal)); + + enableActionBar = config.getBoolean("actionbar.enable", true); + actionBarLeft = config.getString("actionbar.left", "뀂"); + actionBarFull = config.getString("actionbar.full", "뀁뀃"); + actionBarEmpty = config.getString("actionbar.empty", "뀁뀄"); + actionBarRight = config.getString("actionbar.right", "뀁뀅"); + + enableSprinklerInfo = config.getBoolean("hologram.sprinkler-info.enable", true); + sprinklerInfoY = config.getDouble("hologram.sprinkler-info.y-offset", -0.2); + sprinklerInfoDuration = config.getInt("hologram.sprinkler-info.duration", 1); + sprinklerLeft = config.getString("hologram.sprinkler-info.left", "뀂"); + sprinklerFull = config.getString("hologram.sprinkler-info.full", "뀁뀃"); + sprinklerEmpty = config.getString("hologram.sprinkler-info.empty", "뀁뀄"); + sprinklerRight = config.getString("hologram.sprinkler-info.right", "뀁뀅"); + + enableFertilizerInfo = config.getBoolean("hologram.fertilizer-info.enable", true); + fertilizerInfoY = config.getDouble("hologram.fertilizer-info.y-offset", -0.2); + fertilizerInfoDuration = config.getInt("hologram.fertilizer-info.duration", 1); + fertilizerInfo = config.getString("hologram.fertilizer-info.text", "{fertilizer} {times}/{max_times}"); + + antiGriefs = new ArrayList<>(); + if (config.getBoolean("config.integration.Residence",false)){ + if (Bukkit.getPluginManager().getPlugin("Residence") == null) Log.warn("Failed to initialize Residence!"); + else {antiGriefs.add(new ResidenceHook());hookMessage("Residence");} + } + if (config.getBoolean("config.integration.Kingdoms",false)){ + if (Bukkit.getPluginManager().getPlugin("Kingdoms") == null) Log.warn("Failed to initialize Kingdoms!"); + else {antiGriefs.add(new KingdomsXHook());hookMessage("Kingdoms");} + } + if (config.getBoolean("config.integration.WorldGuard",false)){ + if (Bukkit.getPluginManager().getPlugin("WorldGuard") == null) Log.warn("Failed to initialize WorldGuard!"); + else {antiGriefs.add(new WorldGuardHook());hookMessage("WorldGuard");} + } + if (config.getBoolean("config.integration.GriefDefender",false)){ + if(Bukkit.getPluginManager().getPlugin("GriefDefender") == null) Log.warn("Failed to initialize GriefDefender!"); + else {antiGriefs.add(new GriefDefenderHook());hookMessage("GriefDefender");} + } + if (config.getBoolean("config.integration.PlotSquared",false)){ + if(Bukkit.getPluginManager().getPlugin("PlotSquared") == null) Log.warn("Failed to initialize PlotSquared!"); + else {antiGriefs.add(new PlotSquaredHook());hookMessage("PlotSquared");} + } + if (config.getBoolean("config.integration.Towny",false)){ + if (Bukkit.getPluginManager().getPlugin("Towny") == null) Log.warn("Failed to initialize Towny!"); + else {antiGriefs.add(new TownyHook());hookMessage("Towny");} + } + if (config.getBoolean("config.integration.Lands",false)){ + if (Bukkit.getPluginManager().getPlugin("Lands") == null) Log.warn("Failed to initialize Lands!"); + else {antiGriefs.add(new LandsHook());hookMessage("Lands");} + } + if (config.getBoolean("config.integration.GriefPrevention",false)){ + if (Bukkit.getPluginManager().getPlugin("GriefPrevention") == null) Log.warn("Failed to initialize GriefPrevention!"); + else {antiGriefs.add(new GriefPreventionHook());hookMessage("GriefPrevention");} + } + if (config.getBoolean("config.integration.CrashClaim",false)){ + if (Bukkit.getPluginManager().getPlugin("CrashClaim") == null) Log.warn("Failed to initialize CrashClaim!"); + else {antiGriefs.add(new CrashClaimHook());hookMessage("CrashClaim");} + } + if (config.getBoolean("config.integration.BentoBox",false)){ + if (Bukkit.getPluginManager().getPlugin("BentoBox") == null) Log.warn("Failed to initialize BentoBox!"); + else {antiGriefs.add(new BentoBoxHook());hookMessage("BentoBox");} + } + } + + public static World[] getWorldsArray() { + if (MainConfig.whiteOrBlack) { + return worlds; + } + else { + List worldList = new ArrayList<>(Bukkit.getWorlds()); + worldList.removeAll(MainConfig.worldList); + return worldList.toArray(new World[0]); + } + } + + public static List getWorldsList() { + if (MainConfig.whiteOrBlack) { + return worldList; + } + else { + List worldList = new ArrayList<>(Bukkit.getWorlds()); + worldList.removeAll(MainConfig.worldList); + return worldList; + } + } + + private static void hookMessage(String plugin){ + AdventureUtil.consoleMessage("[CustomCrops] " + plugin + " Hooked!"); + } +} diff --git a/src/main/java/net/momirealms/customcrops/config/MessageConfig.java b/src/main/java/net/momirealms/customcrops/config/MessageConfig.java new file mode 100644 index 0000000..ad3e8f8 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/config/MessageConfig.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.config; + +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; + +public class MessageConfig { + + public static String spring; + public static String summer; + public static String autumn; + public static String winter; + public static String seasonDisabled; + public static String autoSeasonDisabled; + public static String prefix; + public static String nonArgs; + public static String wrongArgs; + public static String unavailableArgs; + public static String lackArgs; + public static String reload; + public static String noPerm; + public static String limitWire; + public static String limitFrame; + public static String growSimulation; + public static String backUp; + public static String setSeason; + public static String beforePlant; + public static String noSeason; + public static String worldNotExists; + public static String seasonNotExists; + + public static void load() { + YamlConfiguration config = ConfigUtil.getConfig("messages" + File.separator + "messages_" + MainConfig.lang +".yml"); + prefix = config.getString("messages.prefix"); + reload = config.getString("messages.reload"); + noPerm = config.getString("messages.no-perm"); + lackArgs = config.getString("messages.lack-args"); + wrongArgs = config.getString("messages.wrong-args"); + spring = config.getString("messages.spring"); + summer = config.getString("messages.summer"); + autumn = config.getString("messages.autumn"); + winter = config.getString("messages.winter"); + limitWire = config.getString("messages.limitation-tripwire"); + limitFrame = config.getString("messages.limitation-itemframe"); + growSimulation = config.getString("messages.grow-simulation"); + backUp = config.getString("messages.back-up"); + setSeason = config.getString("messages.set-season"); + beforePlant = config.getString("messages.before-plant"); + seasonDisabled = config.getString("messages.season-disabled"); + autoSeasonDisabled = config.getString("messages.auto-season-disabled"); + noSeason = config.getString("messages.no-season"); + worldNotExists = config.getString("messages.world-not-exist"); + seasonNotExists = config.getString("messages.season-not-exist"); + } +} diff --git a/src/main/java/net/momirealms/customcrops/config/SeasonConfig.java b/src/main/java/net/momirealms/customcrops/config/SeasonConfig.java new file mode 100644 index 0000000..18f1165 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/config/SeasonConfig.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.config; + +import org.bukkit.configuration.file.YamlConfiguration; + +public class SeasonConfig { + + public static boolean enable; + public static boolean auto; + public static int duration; + public static boolean greenhouse; + public static int effectiveRange; + + public static void load() { + + YamlConfiguration config = ConfigUtil.getConfig("config.yml"); + enable = config.getBoolean("mechanics.season.enable", true); + auto = config.getBoolean("mechanics.season.auto-season-change.enable", true); + duration = config.getInt("mechanics.season.auto-season-change.duration", 28); + greenhouse = config.getBoolean("mechanics.season.greenhouse.enable", true); + effectiveRange = config.getInt("mechanics.season.greenhouse.range", 5); + } +} diff --git a/src/main/java/net/momirealms/customcrops/config/SoundConfig.java b/src/main/java/net/momirealms/customcrops/config/SoundConfig.java new file mode 100644 index 0000000..562b363 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/config/SoundConfig.java @@ -0,0 +1,68 @@ +package net.momirealms.customcrops.config; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.sound.Sound; +import net.momirealms.customcrops.objects.WrappedSound; +import org.bukkit.configuration.file.YamlConfiguration; + +public class SoundConfig { + + public static WrappedSound waterPot; + public static WrappedSound addWaterToCan; + public static WrappedSound addWaterToSprinkler; + public static WrappedSound placeSprinkler; + public static WrappedSound plantSeed; + public static WrappedSound useFertilizer; + public static WrappedSound harvestCrop; + public static WrappedSound boneMeal; + public static WrappedSound surveyor; + + public static void load(){ + YamlConfiguration config = ConfigUtil.getConfig("config.yml"); + waterPot = new WrappedSound( + Sound.Source.valueOf(config.getString("sounds.water-pot.type","player").toUpperCase()), + Key.key(config.getString("sounds.water-pot.sound", "minecraft:block.water.ambient")), + config.getBoolean("sounds.water-pot.enable", true) + ); + addWaterToCan = new WrappedSound( + Sound.Source.valueOf(config.getString("sounds.add-water-to-can.type","player").toUpperCase()), + Key.key(config.getString("sounds.add-water-to-can.sound", "minecraft:item.bucket.fill")), + config.getBoolean("sounds.add-water-to-can.enable", true) + ); + addWaterToSprinkler = new WrappedSound( + Sound.Source.valueOf(config.getString("sounds.add-water-to-sprinkler.type","player").toUpperCase()), + Key.key(config.getString("sounds.add-water-to-sprinkler.sound", "minecraft:item.bucket.fill")), + config.getBoolean("sounds.add-water-to-sprinkler.enable", true) + ); + placeSprinkler = new WrappedSound( + Sound.Source.valueOf(config.getString("sounds.place-sprinkler.type","player").toUpperCase()), + Key.key(config.getString("sounds.place-sprinkler.sound", "minecraft:block.bone_block.place")), + config.getBoolean("sounds.place-sprinkler.enable", true) + ); + plantSeed = new WrappedSound( + Sound.Source.valueOf(config.getString("sounds.plant-seed.type","player").toUpperCase()), + Key.key(config.getString("sounds.plant-seed.sound", "minecraft:item.hoe.till")), + config.getBoolean("sounds.plant-seed.enable", true) + ); + useFertilizer = new WrappedSound( + Sound.Source.valueOf(config.getString("sounds.use-fertilizer.type","player").toUpperCase()), + Key.key(config.getString("sounds.use-fertilizer.sound", "minecraft:item.hoe.till")), + config.getBoolean("sounds.use-fertilizer.enable", true) + ); + harvestCrop = new WrappedSound( + Sound.Source.valueOf(config.getString("sounds.harvest-crops.type", "player").toUpperCase()), + Key.key(config.getString("sounds.harvest-crops.sound", "minecraft:block.crop.break")), + config.getBoolean("sounds.harvest-crops.enable", true) + ); + boneMeal = new WrappedSound( + Sound.Source.valueOf(config.getString("sounds.bonemeal.type","player").toUpperCase()), + Key.key(config.getString("sounds.bonemeal.sound", "minecraft:item.hoe.till")), + config.getBoolean("sounds.bonemeal.enable", true) + ); + surveyor = new WrappedSound( + Sound.Source.valueOf(config.getString("sounds.surveyor.type","player").toUpperCase()), + Key.key(config.getString("sounds.surveyor.sound", "minecraft:block.note_block.pling")), + config.getBoolean("sounds.surveyor.enable", true) + ); + } +} diff --git a/src/main/java/net/momirealms/customcrops/config/SprinklerConfig.java b/src/main/java/net/momirealms/customcrops/config/SprinklerConfig.java new file mode 100644 index 0000000..960d7ab --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/config/SprinklerConfig.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.config; + +import net.momirealms.customcrops.objects.Sprinkler; +import net.momirealms.customcrops.utils.AdventureUtil; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.util.HashMap; + +public class SprinklerConfig { + + public static HashMap SPRINKLERS_CONFIG; + public static HashMap SPRINKLERS_2D; + public static HashMap SPRINKLERS_3D; + + public static void load() { + SPRINKLERS_3D = new HashMap<>(8); + SPRINKLERS_2D = new HashMap<>(8); + SPRINKLERS_CONFIG = new HashMap<>(8); + YamlConfiguration config = ConfigUtil.getConfig("sprinklers_" + MainConfig.customPlugin + ".yml"); + + int amount = 0; + for (String key : config.getKeys(false)) { + + Sprinkler sprinkler = new Sprinkler( + key, + config.getInt(key + ".range", 1), + config.getInt(key + ".max-water-storage", 5) + ); + String twoD = config.getString(key + ".2Ditem"); + String threeD = config.getString(key + ".3Ditem"); + sprinkler.setTwoD(twoD); + sprinkler.setThreeD(threeD); + SPRINKLERS_CONFIG.put(key + "CONFIG", sprinkler); + SPRINKLERS_2D.put(twoD, sprinkler); + SPRINKLERS_3D.put(threeD, sprinkler); + amount++; + } + + AdventureUtil.consoleMessage("[CustomCrops] Loaded " + amount + " sprinklers"); + } +} diff --git a/src/main/java/net/momirealms/customcrops/config/WaterCanConfig.java b/src/main/java/net/momirealms/customcrops/config/WaterCanConfig.java new file mode 100644 index 0000000..044dbfd --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/config/WaterCanConfig.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.config; + +import net.momirealms.customcrops.objects.WaterCan; +import net.momirealms.customcrops.utils.AdventureUtil; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.util.HashMap; + +public class WaterCanConfig { + + public static HashMap CANS = new HashMap<>(); + + public static void load() { + CANS = new HashMap<>(8); + YamlConfiguration config = ConfigUtil.getConfig("watercans_" + MainConfig.customPlugin + ".yml"); + for (String key : config.getKeys(false)) { + WaterCan waterCan = new WaterCan( + config.getInt(key + ".max-water-storage"), + config.getInt(key + ".width"), + config.getInt(key + ".length") + ); + CANS.put(config.getString(key + ".item"), waterCan); + } + AdventureUtil.consoleMessage("[CustomCrops] Loaded " + CANS.size() + " watering cans"); + } +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/datamanager/CropManager.java b/src/main/java/net/momirealms/customcrops/datamanager/CropManager.java deleted file mode 100644 index ce721fa..0000000 --- a/src/main/java/net/momirealms/customcrops/datamanager/CropManager.java +++ /dev/null @@ -1,825 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.datamanager; - -import dev.lone.itemsadder.api.CustomBlock; -import dev.lone.itemsadder.api.CustomFurniture; -import net.momirealms.customcrops.listener.JoinAndQuit; -import net.momirealms.customcrops.objects.fertilizer.*; -import net.momirealms.customcrops.utils.AdventureManager; -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.CustomCrops; -import net.momirealms.customcrops.objects.Crop; -import net.momirealms.customcrops.utils.FurnitureUtil; -import net.momirealms.customcrops.utils.JedisUtil; -import net.momirealms.customcrops.objects.SimpleLocation; -import net.momirealms.customcrops.utils.LocUtil; -import org.apache.commons.lang.StringUtils; -import org.bukkit.Bukkit; -import org.bukkit.Chunk; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Entity; -import org.bukkit.scheduler.BukkitScheduler; - -import java.io.File; -import java.io.IOException; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; - -public class CropManager{ - - private YamlConfiguration data; - public static ConcurrentHashMap Cache = new ConcurrentHashMap<>(); - public static HashSet RemoveCache = new HashSet<>(); - private final BukkitScheduler bukkitScheduler; - private final boolean isEntity; - - public CropManager(boolean isEntity){ - this.bukkitScheduler = Bukkit.getScheduler(); - this.isEntity = isEntity; - } - - /** - * 载入数据 - */ - public void loadData() { - File file = new File(CustomCrops.plugin.getDataFolder(), "data" + File.separator + "crop.yml"); - if(!file.exists()){ - try { - file.getParentFile().mkdirs(); - file.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - AdventureManager.consoleMessage("[CustomCrops] 农作物数据文件生成失败!"); - } - } - this.data = YamlConfiguration.loadConfiguration(file); - } - - /** - * 保存数据 - */ - public void saveData() { - File file = new File(CustomCrops.plugin.getDataFolder(), "data" + File.separator + "crop.yml"); - try{ - data.save(file); - }catch (IOException e){ - e.printStackTrace(); - AdventureManager.consoleMessage("[CustomCrops] crop.yml保存出错!"); - } - } - - /** - * 将数据保存到data中 - */ - public void updateData(){ - Cache.forEach((location, String) -> { - int x = location.getX(); - int z = location.getZ(); - data.set(location.getWorldName() + "." + x / 16 + "," + z / 16 + "." + x + "," + location.getY() + "," + z, String); - }); - Cache.clear(); - HashSet set = new HashSet<>(RemoveCache); - for (SimpleLocation location : set) { - int x = location.getX(); - int z = location.getZ(); - data.set(location.getWorldName() + "." + x / 16 + "," + z / 16 + "." + x + "," + location.getY() + "," + z, null); - } - RemoveCache.clear(); - } - - /** - * 清除无用数据 - */ - public void cleanData(){ - data.getKeys(false).forEach(world -> { - data.getConfigurationSection(world).getKeys(false).forEach(chunk ->{ - if (data.getConfigurationSection(world + "." + chunk).getKeys(false).size() == 0){ - data.set(world + "." + chunk, null); - } - }); - }); - } - - /** - * 农作物生长,Mode 1 - * 仅加载区块生长 - * @param worldName 进行生长判定的世界名 - */ - public void growModeOne(String worldName){ - if(!ConfigReader.Config.allWorld) updateData(); - if(!ConfigReader.Config.allWorld) saveData(); - if (data.contains(worldName)){ - World world = Bukkit.getWorld(worldName); - if (!isEntity){ - data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{ - String[] split = StringUtils.split(chunk,","); - if (world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))){ - data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> { - String[] coordinate = StringUtils.split(key, ","); - Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2])); - int random = new Random().nextInt(ConfigReader.Config.timeToGrow); - bukkitScheduler.runTaskLaterAsynchronously(CustomCrops.plugin, ()-> { - if (growJudge(worldName, seedLocation)){ - data.set(worldName + "." + chunk + "." + key, null); - } - }, random); - }); - } - }); - } - else { - data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{ - String[] split = StringUtils.split(chunk,","); - if (world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))){ - data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> { - String[] coordinate = StringUtils.split(key, ","); - Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2])); - int random = new Random().nextInt(ConfigReader.Config.timeToGrow); - bukkitScheduler.runTaskLater(CustomCrops.plugin, ()-> { - growJudgeEntity(worldName, seedLocation, worldName + "." + chunk + "." + key); - }, random); - }); - } - }); - } - } - } - - /** - * 农作物生长,Mode 2 - * 仅在线玩家的农作物生长 - * @param worldName 进行生长判定的世界名 - */ - public void growModeTwo(String worldName){ - if(!ConfigReader.Config.allWorld) updateData(); - if(!ConfigReader.Config.allWorld) saveData(); - HashSet players = getPlayers(); - if (data.contains(worldName)){ - World world = Bukkit.getWorld(worldName); - if (!isEntity){ - data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{ - data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> { - if (!players.contains(value)) return; - String[] coordinate = StringUtils.split(key, ","); - Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2])); - int random = new Random().nextInt(ConfigReader.Config.timeToGrow); - bukkitScheduler.runTaskLaterAsynchronously(CustomCrops.plugin, ()-> { - if (growJudge(worldName, seedLocation)){ - data.set(worldName + "." + chunk + "." + key, null); - } - }, random); - }); - }); - } - else { - data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{ - data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> { - if (!players.contains(value)) return; - String[] coordinate = StringUtils.split(key, ","); - Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2])); - int random = new Random().nextInt(ConfigReader.Config.timeToGrow); - bukkitScheduler.runTaskLater(CustomCrops.plugin, ()-> { - growJudgeEntity(worldName, seedLocation, worldName + "." + chunk + "." + key); - }, random); - }); - }); - } - } - } - - /** - * 农作物生长,Mode 3 - * 仅在线玩家和加载区块的农作物生长 - * @param worldName 进行生长判定的世界名 - */ - public void growModeThree(String worldName){ - if(!ConfigReader.Config.allWorld) updateData(); - if(!ConfigReader.Config.allWorld) saveData(); - HashSet players = getPlayers(); - if (data.contains(worldName)){ - World world = Bukkit.getWorld(worldName); - if (!isEntity){ - data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{ - String[] split = StringUtils.split(chunk,","); - //区块被加载,则强行生长判定 - if (world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))){ - data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> { - String[] coordinate = StringUtils.split(key, ","); - Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2])); - int random = new Random().nextInt(ConfigReader.Config.timeToGrow); - bukkitScheduler.runTaskLaterAsynchronously(CustomCrops.plugin, ()-> { - if (growJudge(worldName, seedLocation)){ - data.set(worldName + "." + chunk + "." + key, null); - } - }, random); - }); - } - //区块未加载,玩家在线 - else{ - data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> { - if (!players.contains(value)) return; - String[] coordinate = StringUtils.split(key, ","); - Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2])); - int random = new Random().nextInt(ConfigReader.Config.timeToGrow); - bukkitScheduler.runTaskLaterAsynchronously(CustomCrops.plugin, ()-> { - if (growJudge(worldName, seedLocation)){ - data.set(worldName + "." + chunk + "." + key, null); - } - }, random); - }); - } - }); - } - else { - data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{ - String[] split = StringUtils.split(chunk,","); - //区块被加载,则强行生长判定 - if (world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))){ - data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> { - String[] coordinate = StringUtils.split(key, ","); - Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2])); - int random = new Random().nextInt(ConfigReader.Config.timeToGrow); - bukkitScheduler.runTaskLater(CustomCrops.plugin, ()-> { - growJudgeEntity(worldName, seedLocation, worldName + "." + chunk + "." + key); - }, random); - }); - } - //区块未加载,玩家在线 - else{ - data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> { - if (!players.contains(value)) return; - String[] coordinate = StringUtils.split(key, ","); - Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2])); - int random = new Random().nextInt(ConfigReader.Config.timeToGrow); - bukkitScheduler.runTaskLater(CustomCrops.plugin, ()-> { - growJudgeEntity(worldName, seedLocation, worldName + "." + chunk + "." + key); - }, random); - }); - } - }); - } - } - } - - /** - * 农作物生长,Mode 4 - * 全部农作物生长 - * @param worldName 进行生长判定的世界名 - */ - public void growModeFour(String worldName){ - if(!ConfigReader.Config.allWorld){updateData();} - if(!ConfigReader.Config.allWorld) saveData(); - if (data.contains(worldName)){ - World world = Bukkit.getWorld(worldName); - if (!isEntity){ - data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{ - data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> { - String[] coordinate = StringUtils.split(key, ","); - Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2])); - int random = new Random().nextInt(ConfigReader.Config.timeToGrow); - bukkitScheduler.runTaskLaterAsynchronously(CustomCrops.plugin, ()-> { - if (growJudge(worldName, seedLocation)){ - data.set(worldName + "." + chunk + "." + key, null); - } - }, random); - }); - }); - } - else { - data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{ - data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> { - String[] coordinate = StringUtils.split(key, ","); - Location seedLocation = new Location(world,Double.parseDouble(coordinate[0]),Double.parseDouble(coordinate[1]),Double.parseDouble(coordinate[2])); - int random = new Random().nextInt(ConfigReader.Config.timeToGrow); - bukkitScheduler.runTaskLater(CustomCrops.plugin, ()-> { - growJudgeEntity(worldName, seedLocation, worldName + "." + chunk + "." + key); - }, random); - }); - }); - } - } - } - - /** - * 全部世界农作物生长 - * 对于使用动态加载世界的服务器有效 - */ - public void cropGrowAll(){ - updateData(); - List worlds = Bukkit.getWorlds(); - for (int i = 0; i < worlds.size(); i++){ - String worldName = worlds.get(i).getName(); - bukkitScheduler.runTaskLaterAsynchronously(CustomCrops.plugin, () -> { - switch (ConfigReader.Config.growMode){ - case 1 -> growModeOne(worldName); - case 2 -> growModeTwo(worldName); - case 3 -> growModeThree(worldName); - case 4 -> growModeFour(worldName); - } - }, i * 40L); - } - saveData(); - } - - /** - * 对某个位置进行生长判定 - * @param worldName 世界名 - * @param seedLocation 种子位置 - * @return 是否消除数据 - */ - private boolean growJudge(String worldName, Location seedLocation) { - CustomBlock seedBlock = CustomBlock.byAlreadyPlaced(seedLocation.getBlock()); - //自定义农作物方块不存在 - if(seedBlock == null) { - return true; - } - String namespacedID = seedBlock.getNamespacedID(); - String id = seedBlock.getId(); - //已死亡或不是农作物 - if(namespacedID.equals(ConfigReader.Basic.dead) || !namespacedID.contains("_stage_")) { - return true; - } - //农作物下方自定义方块不存在 - Location potLocation = seedLocation.clone().subtract(0,1,0); - CustomBlock pot = CustomBlock.byAlreadyPlaced(potLocation.getBlock()); - if (pot == null){ - return true; - } - //农作物实例不存在 - String[] cropNameList = StringUtils.split(id,"_"); - Crop cropInstance = ConfigReader.CROPS.get(cropNameList[0]); - if (cropInstance == null){ - return true; - } - //获取自定义方块ID - String potNamespacedID = pot.getNamespacedID(); - if (potNamespacedID.equals(ConfigReader.Basic.watered_pot)){ - - //如果启用季节限制且农作物有季节需求 - if (ConfigReader.Season.enable && cropInstance.getSeasons() != null){ - if (isWrongSeason(seedLocation, cropInstance.getSeasons(), worldName)){ - bukkitScheduler.runTask(CustomCrops.plugin, () -> { - CustomBlock.remove(seedLocation); - CustomBlock.place(ConfigReader.Basic.dead, seedLocation); - }); - return true; - } - } - //获取下一阶段 - int nextStage = Integer.parseInt(cropNameList[2]) + 1; - //下一阶段存在 - if (CustomBlock.getInstance(StringUtils.chop(namespacedID) + nextStage) != null) { - //尝试获取肥料类型 - Fertilizer fertilizer = PotManager.Cache.get(LocUtil.fromLocation(potLocation)); - //有肥料 - if (fertilizer != null){ - //查询剩余使用次数 - int times = fertilizer.getTimes(); - if (times > 0){ - fertilizer.setTimes(times - 1); - - Fertilizer fertilizerConfig = ConfigReader.FERTILIZERS.get(fertilizer.getKey()); - //生长激素 - if (fertilizerConfig instanceof SpeedGrow speedGrow){ - if (cropInstance.getGrowChance() > Math.random()){ - //农作物存在下两个阶段 - if (Math.random() < speedGrow.getChance() && CustomBlock.getInstance(StringUtils.chop(namespacedID) + (nextStage + 1)) != null){ - addStage(potLocation, seedLocation, namespacedID, nextStage + 1); - }else { - addStage(potLocation, seedLocation, namespacedID, nextStage); - } - }else { - notAddStage(potLocation); - } - } - //保湿土壤 - else if(fertilizerConfig instanceof RetainingSoil retainingSoil){ - if (Math.random() < retainingSoil.getChance()){ - if (cropInstance.getGrowChance() > Math.random()){ - addStage(seedLocation, namespacedID, nextStage); - } - }else { - if (cropInstance.getGrowChance() > Math.random()){ - addStage(potLocation, seedLocation, namespacedID, nextStage); - }else { - notAddStage(potLocation); - } - } - } - //品质肥料 - else if(fertilizerConfig instanceof QualityCrop || fertilizerConfig instanceof YieldIncreasing){ - if (cropInstance.getGrowChance() > Math.random()){ - addStage(potLocation, seedLocation, namespacedID, nextStage); - }else { - notAddStage(potLocation); - } - }else { - //未知肥料类型处理 - AdventureManager.consoleMessage("[CustomCrops] Unknown fertilizer, Auto removed!"); - PotManager.Cache.remove(LocUtil.fromLocation(potLocation)); - - if (cropInstance.getGrowChance() > Math.random()){ - addStage(potLocation, seedLocation, namespacedID, nextStage); - }else { - notAddStage(potLocation); - } - } - //肥料的最后一次使用 - if (times == 1){ - PotManager.Cache.remove(LocUtil.fromLocation(potLocation)); - } - } - else { - //移除肥料信息,一般不会出现此情况 - PotManager.Cache.remove(LocUtil.fromLocation(potLocation)); - if (cropInstance.getGrowChance() > Math.random()){ - addStage(potLocation, seedLocation, namespacedID, nextStage); - }else { - notAddStage(potLocation); - } - } - } - //没有肥料 - else { - if (cropInstance.getGrowChance() > Math.random()){ - addStage(potLocation, seedLocation, namespacedID, nextStage); - }else { - notAddStage(potLocation); - } - } - } - //农作物是否存在巨大化 - else if(cropInstance.getGiant() != null){ - //巨大化判定 - if (cropInstance.getGiantChance() > Math.random()){ - - if (cropInstance.isBlock()){ - bukkitScheduler.runTask(CustomCrops.plugin, () ->{ - CustomBlock.remove(seedLocation); - CustomBlock.place(cropInstance.getGiant(), seedLocation); - CustomBlock.remove(potLocation); - CustomBlock.place(ConfigReader.Basic.pot, potLocation); - }); - }else { - bukkitScheduler.runTask(CustomCrops.plugin, () ->{ - //加载区块哦亲 - CustomBlock.remove(seedLocation); - CustomFurniture.spawn(cropInstance.getGiant(), seedLocation.getBlock()); - CustomBlock.remove(potLocation); - CustomBlock.place(ConfigReader.Basic.pot, potLocation); - }); - } - //成功巨大化,移除数据 - return true; - }else { - //失败,转湿为干 - bukkitScheduler.runTask(CustomCrops.plugin, () ->{ - CustomBlock.remove(potLocation); - CustomBlock.place(ConfigReader.Basic.pot, potLocation); - }); - return ConfigReader.Config.oneTry || ConfigReader.Config.growMode == 4; - } - }else { - //若无下一阶段,无巨大化,未启用季节,则移除无用数据 - if (!ConfigReader.Season.enable) return true; - bukkitScheduler.runTask(CustomCrops.plugin, () -> { - CustomBlock.remove(potLocation); - CustomBlock.place(ConfigReader.Basic.pot, potLocation); - }); - } - } - //干燥的种植盆 - else if(potNamespacedID.equals(ConfigReader.Basic.pot)){ - //未启用季节 - if(!ConfigReader.Season.enable) return false; - //农作物无视季节 - List seasons = cropInstance.getSeasons(); - if(seasons == null) return false; - //错误季节 - if(isWrongSeason(seedLocation, seasons, worldName)){ - bukkitScheduler.runTask(CustomCrops.plugin, () -> { - CustomBlock.remove(seedLocation); - CustomBlock.place(ConfigReader.Basic.dead, seedLocation); - }); - return true; - } - } - //不是种植盆 - else { - return true; - } - return false; - } - - /** - * 判定季节 - * @param worldName 世界名 - * @param seasons 农作物能生长的季节 - * @param seedLocation 农作物的位置 - */ - private boolean isWrongSeason(Location seedLocation, List seasons, String worldName){ - if(ConfigReader.Season.greenhouse){ - for(int i = 1; i <= ConfigReader.Season.range; i++){ - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(seedLocation.clone().add(0,i,0).getBlock()); - if (customBlock != null){ - if(customBlock.getNamespacedID().equals(ConfigReader.Basic.glass)){ - return false; - } - } - } - } - if (!ConfigReader.Config.allWorld){ - for(String season : seasons){ - if (season.equals(SeasonManager.SEASON.get(worldName))) { - return false; - } - } - }else { - for(String season : seasons){ - if (season.equals(SeasonManager.SEASON.get(ConfigReader.Config.referenceWorld))) { - return false; - } - } - } - return true; - } - - /** - * 对某个位置进行生长判定 - * @param worldName 世界名 - * @param seedLocation 种子位置 - */ - private void growJudgeEntity(String worldName, Location seedLocation, String path) { - Chunk chunk = seedLocation.getChunk(); - chunk.load(); - bukkitScheduler.runTaskLater(CustomCrops.plugin, ()-> { - if (chunk.isEntitiesLoaded()){ - CustomFurniture crop = FurnitureUtil.getFurniture(seedLocation.clone().add(0.5,0.1,0.5)); - //自定义农作物家具不存在 - if(crop == null) { - data.set(path, null); - return; - } - String namespacedID = crop.getNamespacedID(); - //已死亡或不是农作物 - if(namespacedID.equals(ConfigReader.Basic.dead) || !namespacedID.contains("_stage_")) { - data.set(path, null); - return; - } - //农作物下方自定义方块不存在 - Location potLocation = seedLocation.clone().subtract(0,1,0); - CustomBlock pot = CustomBlock.byAlreadyPlaced(potLocation.getBlock()); - if (pot == null){ - data.set(path, null); - return; - } - //农作物实例不存在 - String id = crop.getId(); - String[] cropNameList = StringUtils.split(id,"_"); - Crop cropInstance = ConfigReader.CROPS.get(cropNameList[0]); - if (cropInstance == null){ - data.set(path, null); - return; - } - //获取自定义方块ID - String potNamespacedID = pot.getNamespacedID(); - if (potNamespacedID.equals(ConfigReader.Basic.watered_pot)){ - //如果启用季节限制且农作物有季节需求 - if (ConfigReader.Season.enable && cropInstance.getSeasons() != null){ - if (isWrongSeason(seedLocation, cropInstance.getSeasons(), worldName)){ - seedLocation.getChunk().load(); - CustomFurniture.remove(crop.getArmorstand(), false); - FurnitureUtil.placeCrop(ConfigReader.Basic.dead, seedLocation); - data.set(path, null); - return; - } - } - //获取下一阶段 - int nextStage = Integer.parseInt(cropNameList[2]) + 1; - //下一阶段存在 - if (CustomFurniture.getInstance(StringUtils.chop(namespacedID) + nextStage) != null) { - //尝试获取肥料类型 - Fertilizer fertilizer = PotManager.Cache.get(LocUtil.fromLocation(potLocation)); - //有肥料 - if (fertilizer != null){ - //查询剩余使用次数 - int times = fertilizer.getTimes(); - if (times > 0){ - - fertilizer.setTimes(times - 1); - - Fertilizer fertilizerConfig = ConfigReader.FERTILIZERS.get(fertilizer.getKey()); - //生长激素 - if (fertilizerConfig instanceof SpeedGrow speedGrow){ - if (cropInstance.getGrowChance() > Math.random()){ - //农作物存在下两个阶段 - if (Math.random() < speedGrow.getChance() && CustomBlock.getInstance(StringUtils.chop(namespacedID) + (nextStage + 1)) != null){ - addStageEntity(potLocation, seedLocation, crop.getArmorstand(), StringUtils.chop(namespacedID) + (nextStage + 1)); - }else { - addStageEntity(potLocation, seedLocation, crop.getArmorstand(), StringUtils.chop(namespacedID) + nextStage); - } - } - else { - CustomBlock.remove(potLocation); - CustomBlock.place(ConfigReader.Basic.pot, potLocation); - } - } - //保湿土壤 - else if(fertilizerConfig instanceof RetainingSoil retainingSoil){ - if (Math.random() < retainingSoil.getChance()){ - if (cropInstance.getGrowChance() > Math.random()){ - addStageEntity(seedLocation, crop.getArmorstand(), StringUtils.chop(namespacedID) + nextStage); - } - }else { - if (cropInstance.getGrowChance() > Math.random()){ - addStageEntity(potLocation, seedLocation, crop.getArmorstand(), StringUtils.chop(namespacedID) + nextStage); - }else { - CustomBlock.remove(potLocation); - CustomBlock.place(ConfigReader.Basic.pot, potLocation); - } - } - } - //品质肥料 - else if(fertilizerConfig instanceof QualityCrop || fertilizerConfig instanceof YieldIncreasing){ - if (cropInstance.getGrowChance() > Math.random()){ - addStageEntity(potLocation, seedLocation, crop.getArmorstand(), StringUtils.chop(namespacedID) + nextStage); - }else { - CustomBlock.remove(potLocation); - CustomBlock.place(ConfigReader.Basic.pot, potLocation); - } - }else { - //未知肥料类型处理 - AdventureManager.consoleMessage("[CustomCrops] Unknown fertilizer, Auto removed!"); - PotManager.Cache.remove(LocUtil.fromLocation(potLocation)); - if (cropInstance.getGrowChance() > Math.random()){ - addStageEntity(potLocation, seedLocation, crop.getArmorstand(), StringUtils.chop(namespacedID) + nextStage); - }else { - CustomBlock.remove(potLocation); - CustomBlock.place(ConfigReader.Basic.pot, potLocation); - } - } - //肥料的最后一次使用 - if (times == 1){ - PotManager.Cache.remove(LocUtil.fromLocation(potLocation)); - } - } - else { - //移除肥料信息,一般不会出现此情况 - PotManager.Cache.remove(LocUtil.fromLocation(potLocation)); - if (cropInstance.getGrowChance() > Math.random()){ - addStageEntity(potLocation, seedLocation, crop.getArmorstand(), StringUtils.chop(namespacedID) + nextStage); - }else { - CustomBlock.remove(potLocation); - CustomBlock.place(ConfigReader.Basic.pot, potLocation); - } - } - } - //没有肥料 - else { - if (cropInstance.getGrowChance() > Math.random()){ - addStageEntity(potLocation, seedLocation, crop.getArmorstand(), StringUtils.chop(namespacedID) + nextStage); - }else { - CustomBlock.remove(potLocation); - CustomBlock.place(ConfigReader.Basic.pot, potLocation); - } - } - } - //农作物是否存在巨大化 - else if(cropInstance.getGiant() != null){ - //巨大化判定 - if (cropInstance.getGiantChance() > Math.random()){ - if (cropInstance.isBlock()){ - CustomBlock.remove(potLocation); - CustomBlock.place(ConfigReader.Basic.pot, potLocation); - CustomFurniture.remove(crop.getArmorstand(), false); - CustomBlock.place(cropInstance.getGiant(), seedLocation); - }else { - CustomBlock.remove(potLocation); - CustomBlock.place(ConfigReader.Basic.pot, potLocation); - CustomFurniture.remove(crop.getArmorstand(), false); - CustomFurniture.spawn(cropInstance.getGiant(), seedLocation.getBlock()); - } - //成功巨大化,移除数据 - data.set(path, null); - }else { - //失败,转湿为干 - CustomBlock.remove(potLocation); - CustomBlock.place(ConfigReader.Basic.pot, potLocation); - if (ConfigReader.Config.oneTry || ConfigReader.Config.growMode == 4){ - data.set(path, null); - } - } - }else { - //若无下一阶段,无巨大化,未启用季节,则移除无用数据 - if (!ConfigReader.Season.enable){ - data.set(path, null); - return; - } - CustomBlock.remove(potLocation); - CustomBlock.place(ConfigReader.Basic.pot, potLocation); - } - } - //干燥的种植盆 - else if(potNamespacedID.equals(ConfigReader.Basic.pot)){ - //未启用季节 - if(!ConfigReader.Season.enable) return; - //农作物无视季节 - List seasons = cropInstance.getSeasons(); - if(seasons == null) return; - //错误季节 - if(isWrongSeason(seedLocation, seasons, worldName)){ - CustomBlock.remove(seedLocation); - CustomBlock.place(ConfigReader.Basic.dead, seedLocation); - data.set(path, null); - } - } - } - },4); - } - - - /** - * 生长一个阶段(消耗水) - * @param potLocation 种植盆位置 - * @param seedLocation 农作物位置 - * @param namespacedID 农作物下一阶段的ID - * @param nextStage 农作物下一阶段的阶段数 - */ - private void addStage(Location potLocation, Location seedLocation, String namespacedID, int nextStage){ - String stage = StringUtils.chop(namespacedID) + nextStage; - bukkitScheduler.runTask(CustomCrops.plugin, () ->{ - CustomBlock.remove(potLocation); - CustomBlock.place(ConfigReader.Basic.pot, potLocation); - CustomBlock.remove(seedLocation); - CustomBlock.place(stage, seedLocation); - }); - } - - /** - * 生长一个阶段(不消耗水) - * @param seedLocation 农作物位置 - * @param namespacedID 农作物下一阶段的ID - * @param nextStage 农作物下一阶段的阶段数 - */ - private void addStage(Location seedLocation, String namespacedID, int nextStage){ - String stage = StringUtils.chop(namespacedID) + nextStage; - bukkitScheduler.runTask(CustomCrops.plugin, () ->{ - CustomBlock.remove(seedLocation); - CustomBlock.place(stage, seedLocation); - }); - } - - - private void addStageEntity(Location potLocation, Location seedLocation, Entity entity, String nextStage){ - CustomBlock.remove(potLocation); - CustomBlock.place(ConfigReader.Basic.pot, potLocation); - CustomFurniture.remove(entity,false); - if (FurnitureUtil.getFurniture(seedLocation.add(0.5,0.1,0.5)) == null){ - FurnitureUtil.placeCrop(nextStage, seedLocation); - } - } - - private void addStageEntity(Location seedLocation, Entity entity, String nextStage){ - CustomFurniture.remove(entity,false); - if (FurnitureUtil.getFurniture(seedLocation.add(0.5,0.1,0.5)) == null){ - FurnitureUtil.placeCrop(nextStage, seedLocation); - } - } - - /** - * 停滞阶段(消耗水) - * @param potLocation 种植盆位置 - */ - private void notAddStage(Location potLocation){ - bukkitScheduler.runTask(CustomCrops.plugin, () ->{ - CustomBlock.remove(potLocation); - CustomBlock.place(ConfigReader.Basic.pot, potLocation); - }); - } - - private HashSet getPlayers(){ - if (ConfigReader.useRedis){ - return JedisUtil.getPlayers(); - }else { - return new HashSet<>(JoinAndQuit.onlinePlayers); - } - } -} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/datamanager/PotManager.java b/src/main/java/net/momirealms/customcrops/datamanager/PotManager.java deleted file mode 100644 index dc0e7f1..0000000 --- a/src/main/java/net/momirealms/customcrops/datamanager/PotManager.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.datamanager; - -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.objects.fertilizer.*; -import net.momirealms.customcrops.utils.AdventureManager; -import net.momirealms.customcrops.CustomCrops; -import net.momirealms.customcrops.objects.SimpleLocation; -import org.apache.commons.lang.StringUtils; -import org.bukkit.configuration.MemorySection; -import org.bukkit.configuration.file.YamlConfiguration; - -import java.io.File; -import java.io.IOException; -import java.util.concurrent.ConcurrentHashMap; - -public class PotManager { - - public static ConcurrentHashMap Cache = new ConcurrentHashMap<>(); - - /** - * 载入数据 - */ - public void loadData(){ - File file = new File(CustomCrops.plugin.getDataFolder(), "data" + File.separator + "pot.yml"); - if(!file.exists()){ - try { - file.getParentFile().mkdirs(); - file.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - AdventureManager.consoleMessage("[CustomCrops] 种植盆数据文件生成失败!"); - } - } - YamlConfiguration data = YamlConfiguration.loadConfiguration(file); - data.getKeys(false).forEach(worldName -> { - data.getConfigurationSection(worldName).getValues(false).forEach((keys, value) ->{ - String[] split = StringUtils.split(keys, ","); - if (value instanceof MemorySection map){ - String key = map.getString("fertilizer"); - Fertilizer fertilizer = ConfigReader.FERTILIZERS.get(key); - if (fertilizer == null) return; - if (fertilizer instanceof SpeedGrow speedGrowConfig){ - SpeedGrow speedGrow = new SpeedGrow(key, map.getInt("times")); - speedGrow.setChance(speedGrowConfig.getChance()); - Cache.put(new SimpleLocation(worldName, Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2])), speedGrow); - }else if (fertilizer instanceof QualityCrop qualityCropConfig){ - QualityCrop qualityCrop = new QualityCrop(key, map.getInt("times")); - qualityCrop.setChance(qualityCropConfig.getChance()); - Cache.put(new SimpleLocation(worldName, Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2])), qualityCrop); - }else if (fertilizer instanceof RetainingSoil retainingSoilConfig){ - RetainingSoil retainingSoil = new RetainingSoil(key, map.getInt("times")); - retainingSoil.setChance(retainingSoilConfig.getChance()); - Cache.put(new SimpleLocation(worldName, Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2])), retainingSoil); - }else if(fertilizer instanceof YieldIncreasing yieldIncreasingConfig){ - YieldIncreasing yieldIncreasing = new YieldIncreasing(key, map.getInt("times")); - yieldIncreasing.setChance(yieldIncreasingConfig.getChance()); - yieldIncreasing.setBonus(yieldIncreasingConfig.getBonus()); - Cache.put(new SimpleLocation(worldName, Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2])), yieldIncreasing); - }else { - AdventureManager.consoleMessage("[CustomCrops] 未知肥料类型错误!"); - } - } - }); - }); - } - - /** - * 保存数据 - */ - public void saveData(){ - File file = new File(CustomCrops.plugin.getDataFolder(), "data" + File.separator + "pot.yml"); - YamlConfiguration data = new YamlConfiguration(); - Cache.forEach(((location, fertilizer) -> { - String world = location.getWorldName(); - int x = location.getX(); - int y = location.getY(); - int z = location.getZ(); - data.set(world + "." + x + "," + y + "," + z + ".fertilizer", fertilizer.getKey()); - data.set(world + "." + x + "," + y + "," + z + ".times", fertilizer.getTimes()); - })); - try { - data.save(file); - }catch (IOException e){ - e.printStackTrace(); - } - } -} diff --git a/src/main/java/net/momirealms/customcrops/datamanager/SeasonManager.java b/src/main/java/net/momirealms/customcrops/datamanager/SeasonManager.java deleted file mode 100644 index 52ecdf4..0000000 --- a/src/main/java/net/momirealms/customcrops/datamanager/SeasonManager.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.datamanager; - -import net.momirealms.customcrops.integrations.RealisticSeason; -import net.momirealms.customcrops.utils.AdventureManager; -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.CustomCrops; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.configuration.file.YamlConfiguration; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Set; - -public class SeasonManager{ - - public static HashMap SEASON = new HashMap<>(); - - /** - * 读取文件中的季节 - * @param file 季节数据文件 - */ - private YamlConfiguration readData(File file) { - if (!file.exists()) { - try { - file.getParentFile().mkdirs(); - file.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - AdventureManager.consoleMessage("[CustomCrops] 季节数据文件生成失败!"); - } - } - return YamlConfiguration.loadConfiguration(file); - } - - /** - * 载入数据 - */ - public void loadData() { - SEASON.clear(); - YamlConfiguration data = readData(new File(CustomCrops.plugin.getDataFolder(), "data" + File.separator + "season.yml")); - if (ConfigReader.Season.seasonChange) { - autoSeason(); - } else { - Set set = data.getKeys(false); - ConfigReader.Config.worldNames.forEach(worldName -> { - if (set.contains(worldName)) { - SEASON.put(worldName, data.getString(worldName)); - } else { - getSeason(Bukkit.getWorld(worldName)); - } - }); - } - } - - public void autoSeason() { - ConfigReader.Config.worlds.forEach(this::getSeason); - } - - /** - * 计算某个世界的季节 - * @param world 世界 - */ - public void getSeason(World world) { - if (ConfigReader.Config.realisticSeason){ - Bukkit.getScheduler().runTaskLater(CustomCrops.plugin, ()->{ - SEASON.put(world.getName(), RealisticSeason.getSeason(world)); - },60); - } - else { - int season = (int) ((world.getFullTime() / 24000L) % (ConfigReader.Season.duration * 4)) / ConfigReader.Season.duration; - switch (season) { - case 0 -> SEASON.put(world.getName(), "spring"); - case 1 -> SEASON.put(world.getName(), "summer"); - case 2 -> SEASON.put(world.getName(), "autumn"); - case 3 -> SEASON.put(world.getName(), "winter"); - default -> AdventureManager.consoleMessage("[CustomCrops] 自动季节计算错误!"); - } - } - } - - /** - * 保存数据 - */ - public void saveData() { - SEASON.forEach((key, value) -> { - File file = new File(CustomCrops.plugin.getDataFolder(), "data" + File.separator + "season.yml"); - YamlConfiguration data = readData(file); - data.set(key, value); - try { - data.save(file); - } catch (IOException e) { - e.printStackTrace(); - AdventureManager.consoleMessage("[CustomCrops] season.yml保存出错!"); - } - }); - } - - /** - * 设置季节 - * @param worldName 世界名 - * @param season 季节 - */ - public boolean setSeason(String worldName, String season){ - if (!ConfigReader.Config.worldNames.contains(worldName)){ - return false; - } - if (!Arrays.asList("spring","summer","autumn","winter").contains(season)){ - return false; - } - SEASON.put(worldName, season); - return true; - } -} diff --git a/src/main/java/net/momirealms/customcrops/datamanager/SprinklerManager.java b/src/main/java/net/momirealms/customcrops/datamanager/SprinklerManager.java deleted file mode 100644 index 06c2055..0000000 --- a/src/main/java/net/momirealms/customcrops/datamanager/SprinklerManager.java +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.datamanager; - -import dev.lone.itemsadder.api.CustomBlock; -import net.momirealms.customcrops.listener.JoinAndQuit; -import net.momirealms.customcrops.objects.SimpleLocation; -import net.momirealms.customcrops.objects.Sprinkler; -import net.momirealms.customcrops.utils.*; -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.CustomCrops; -import org.apache.commons.lang.StringUtils; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.configuration.MemorySection; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.scheduler.BukkitScheduler; - -import java.io.File; -import java.io.IOException; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; - -public class SprinklerManager { - - public static YamlConfiguration data; - public static ConcurrentHashMap Cache = new ConcurrentHashMap<>(); - public static HashSet RemoveCache = new HashSet<>(); - private final BukkitScheduler bukkitScheduler; - - public SprinklerManager(){ - this.bukkitScheduler = Bukkit.getScheduler(); - } - - /** - * 载入数据 - */ - public void loadData() { - File file = new File(CustomCrops.plugin.getDataFolder(), "data" + File.separator + "sprinkler.yml"); - if(!file.exists()){ - try { - file.getParentFile().mkdirs(); - file.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - AdventureManager.consoleMessage("[CustomCrops] 洒水器数据文件生成失败!"); - } - } - data = YamlConfiguration.loadConfiguration(file); - } - - /** - * 保存数据 - */ - public void saveData(){ - File file = new File(CustomCrops.plugin.getDataFolder(), "data" + File.separator + "sprinkler.yml"); - try{ - data.save(file); - }catch (IOException e){ - e.printStackTrace(); - AdventureManager.consoleMessage("[CustomCrops] sprinkler.yml保存出错!"); - } - } - - /** - * 清理无用数据 - */ - public void cleanData(){ - data.getKeys(false).forEach(world -> { - data.getConfigurationSection(world).getKeys(false).forEach(chunk ->{ - if (data.getConfigurationSection(world + "." + chunk).getKeys(false).size() == 0){ - data.set(world + "." + chunk, null); - } - }); - }); - } - - /** - * 将数据保存到data中 - */ - public void updateData(){ - Cache.forEach((location, sprinklerData) -> { - String world = location.getWorldName(); - int x = location.getX(); - int z = location.getZ(); - StringBuilder stringBuilder = new StringBuilder().append(world).append(".").append(x/16).append(",").append(z/16).append(".").append(x).append(",").append(location.getY()).append(",").append(z); - data.set(stringBuilder+".range", sprinklerData.getRange()); - data.set(stringBuilder+".water", sprinklerData.getWater()); - data.set(stringBuilder+".player", Optional.ofNullable(sprinklerData.getPlayer()).orElse("none")); - }); - Cache.clear(); - HashSet set = new HashSet<>(RemoveCache); - for (SimpleLocation location : set) { - String world = location.getWorldName(); - int x = location.getX(); - int z = location.getZ(); - data.set(world + "." + x / 16 + "," + z / 16 + "." + x + "," + location.getY() + "," + z, null); - } - RemoveCache.clear(); - } - - /** - * 洒水器工作,Mode 1 - * @param worldName 世界名 - */ - public void workModeOne(String worldName){ - if(!ConfigReader.Config.allWorld) updateData(); - if(!ConfigReader.Config.allWorld) saveData(); - if (data.contains(worldName)){ - World world = Bukkit.getWorld(worldName); - data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{ - String[] split = StringUtils.split(chunk,","); - if (world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))) { - data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> { - if (value instanceof MemorySection map){ - String[] coordinate = StringUtils.split(key, ","); - Location location = new Location(world,Double.parseDouble(coordinate[0])+0.5,Double.parseDouble(coordinate[1])+0.5,Double.parseDouble(coordinate[2])+0.5); - bukkitScheduler.runTask(CustomCrops.plugin, ()->{ - int water = (int) map.get("water"); - int range = (int) Optional.ofNullable(map.get("range")).orElse(0); - if(!FurnitureUtil.isSprinkler(location)){ - data.set(worldName + "." + chunk + "." + key, null); - return; - } - if (water > 0){ - data.set(worldName + "." + chunk + "." + key + ".water", water - 1); - bukkitScheduler.runTaskLater(CustomCrops.plugin, ()-> { - for(int i = -range; i <= range; i++){ - for (int j = -range; j <= range; j++){ - waterPot(location.clone().add(i,-1,j)); - } - } - }, new Random().nextInt(ConfigReader.Config.timeToWork)); - } - if (range == 0) data.set(worldName + "." + chunk + "." + key, null); - }); - } - }); - } - }); - } - } - - /** - * 洒水器工作,Mode 2 - * @param worldName 世界名 - */ - public void workModeTwo(String worldName){ - if(!ConfigReader.Config.allWorld) updateData(); - if(!ConfigReader.Config.allWorld) saveData(); - HashSet players = getPlayers(); - if (data.contains(worldName)){ - World world = Bukkit.getWorld(worldName); - data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{ - data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> { - if (value instanceof MemorySection map){ - String player = (String) map.get("player"); - if (player == null) { - data.set(worldName + "." + chunk + "." + key + ".player", "none"); - return; - } - if (!players.contains(player)) return; - String[] coordinate = StringUtils.split(key, ","); - Location location = new Location(world,Double.parseDouble(coordinate[0])+0.5,Double.parseDouble(coordinate[1])+0.5,Double.parseDouble(coordinate[2])+0.5); - bukkitScheduler.runTask(CustomCrops.plugin, ()->{ - int water = (int) map.get("water"); - int range = (int) Optional.ofNullable(map.get("range")).orElse(0); - if (water > 0){ - data.set(worldName + "." + chunk + "." + key + ".water", water - 1); - bukkitScheduler.runTaskLater(CustomCrops.plugin, ()-> { - for(int i = -range; i <= range; i++){ - for (int j = -range; j <= range; j++){ - waterPot(location.clone().add(i,-1,j)); - } - } - }, new Random().nextInt(ConfigReader.Config.timeToWork)); - } - if (range == 0) data.set(worldName + "." + chunk + "." + key, null); - }); - } - }); - }); - } - } - - /** - * 洒水器工作,Mode 3 - * @param worldName 世界名 - */ - public void workModeThree(String worldName){ - if(!ConfigReader.Config.allWorld) updateData(); - if(!ConfigReader.Config.allWorld) saveData(); - HashSet players = getPlayers(); - if (data.contains(worldName)){ - World world = Bukkit.getWorld(worldName); - data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{ - String[] split = StringUtils.split(chunk,","); - if (world.isChunkLoaded(Integer.parseInt(split[0]), Integer.parseInt(split[1]))) { - data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> { - if (value instanceof MemorySection map){ - int water = (int) map.get("water"); - int range = (int) Optional.ofNullable(map.get("range")).orElse(0); - String[] coordinate = StringUtils.split(key, ","); - Location location = new Location(world,Double.parseDouble(coordinate[0])+0.5,Double.parseDouble(coordinate[1])+0.5,Double.parseDouble(coordinate[2])+0.5); - bukkitScheduler.runTask(CustomCrops.plugin, ()->{ - if(!FurnitureUtil.isSprinkler(location)){ - data.set(worldName + "." + chunk + "." + key, null); - return; - } - if (water > 0){ - data.set(worldName + "." + chunk + "." + key + ".water", water - 1); - bukkitScheduler.runTaskLater(CustomCrops.plugin, ()-> { - for(int i = -range; i <= range; i++){ - for (int j = -range; j <= range; j++){ - waterPot(location.clone().add(i,-1,j)); - } - } - }, new Random().nextInt(ConfigReader.Config.timeToWork)); - } - if (range == 0) data.set(worldName + "." + chunk + "." + key, null); - }); - } - }); - } - else { - data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> { - if (value instanceof MemorySection map){ - String player = (String) map.get("player"); - if (player == null) { - data.set(worldName + "." + chunk + "." + key + ".player", "none"); - return; - } - if (!players.contains(player)) return; - int water = (int) map.get("water"); - int range = (int) Optional.ofNullable(map.get("range")).orElse(0); - if (water > 0){ - String[] coordinate = StringUtils.split(key, ","); - Location location = new Location(world,Double.parseDouble(coordinate[0])+0.5,Double.parseDouble(coordinate[1])+0.5,Double.parseDouble(coordinate[2])+0.5); - data.set(worldName + "." + chunk + "." + key + ".water", water - 1); - bukkitScheduler.runTaskLater(CustomCrops.plugin, ()-> { - for(int i = -range; i <= range; i++){ - for (int j = -range; j <= range; j++){ - waterPot(location.clone().add(i,-1,j)); - } - } - }, new Random().nextInt(ConfigReader.Config.timeToWork)); - } - if (range == 0) data.set(worldName + "." + chunk + "." + key, null); - } - }); - } - }); - } - } - - /** - * 洒水器工作,Mode 4 - * @param worldName 世界名 - */ - public void workModeFour(String worldName){ - if(!ConfigReader.Config.allWorld) updateData(); - if(!ConfigReader.Config.allWorld) saveData(); - if (data.contains(worldName)){ - World world = Bukkit.getWorld(worldName); - data.getConfigurationSection(worldName).getKeys(false).forEach(chunk ->{ - data.getConfigurationSection(worldName + "." + chunk).getValues(false).forEach((key, value) -> { - if (value instanceof MemorySection map){ - int water = (int) map.get("water"); - int range = (int) Optional.ofNullable(map.get("range")).orElse(0); - if (water > 0){ - String[] coordinate = StringUtils.split(key, ","); - Location location = new Location(world,Double.parseDouble(coordinate[0])+0.5,Double.parseDouble(coordinate[1])+0.5,Double.parseDouble(coordinate[2])+0.5); - data.set(worldName + "." + chunk + "." + key + ".water", water - 1); - bukkitScheduler.runTaskLater(CustomCrops.plugin, ()-> { - for(int i = -range; i <= range; i++){ - for (int j = -range; j <= range; j++){ - waterPot(location.clone().add(i,-1,j)); - } - } - }, new Random().nextInt(ConfigReader.Config.timeToWork)); - } - if (range == 0) data.set(worldName + "." + chunk + "." + key, null); - } - }); - }); - } - } - - - /** - * 所有世界的洒水器工作 - */ - public void sprinklerWorkAll(){ - updateData(); - List worlds = Bukkit.getWorlds(); - for (int i = 0; i < worlds.size(); i++){ - String worldName = worlds.get(i).getName(); - bukkitScheduler.runTaskLaterAsynchronously(CustomCrops.plugin, () -> { - switch (ConfigReader.Config.growMode){ - case 1 -> workModeOne(worldName); - case 2 -> workModeTwo(worldName); - case 3 -> workModeThree(worldName); - case 4 -> workModeFour(worldName); - } - }, i * 40L); - } - saveData(); - } - - /** - * 转干为湿 - * @param potLoc 种植盆的位置 - */ - private void waterPot(Location potLoc) { - CustomBlock cb = CustomBlock.byAlreadyPlaced(potLoc.getBlock()); - if(cb != null){ - if(cb.getNamespacedID().equals(ConfigReader.Basic.pot)){ - CustomBlock.remove(potLoc); - CustomBlock.place(ConfigReader.Basic.watered_pot, potLoc); - } - } - } - - private HashSet getPlayers(){ - if (ConfigReader.useRedis){ - return JedisUtil.getPlayers(); - }else { - return new HashSet<>(JoinAndQuit.onlinePlayers); - } - } - - - /** - * 获取某个洒水器的水量 - * @param location 洒水器位置 - * @param world 世界 - * @param x 坐标 - * @param z 坐标 - * @param sprinkler 洒水器类型 - * @return 水量 - */ - public static int getCurrentWater(Location location, String world, int x, int z, Sprinkler sprinkler) { - int currentWater; - if (sprinkler != null) currentWater = sprinkler.getWater(); - else { - String path = world + "." + x / 16 + "," + z / 16 + "." + x + "," + location.getBlockY() + "," + z + ".water"; - currentWater = data.getInt(path); - } - return currentWater; - } -} diff --git a/src/main/java/net/momirealms/customcrops/helper/LibraryLoader.java b/src/main/java/net/momirealms/customcrops/helper/LibraryLoader.java index 298bab1..6e03959 100644 --- a/src/main/java/net/momirealms/customcrops/helper/LibraryLoader.java +++ b/src/main/java/net/momirealms/customcrops/helper/LibraryLoader.java @@ -27,7 +27,6 @@ package net.momirealms.customcrops.helper; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; - import net.momirealms.customcrops.CustomCrops; import org.apache.commons.lang.StringUtils; diff --git a/src/main/java/net/momirealms/customcrops/helper/MavenLibraries.java b/src/main/java/net/momirealms/customcrops/helper/MavenLibraries.java index 8f13ff0..5b19c5f 100644 --- a/src/main/java/net/momirealms/customcrops/helper/MavenLibraries.java +++ b/src/main/java/net/momirealms/customcrops/helper/MavenLibraries.java @@ -27,11 +27,7 @@ package net.momirealms.customcrops.helper; import org.jetbrains.annotations.NotNull; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.lang.annotation.*; /** * Annotation to indicate the required libraries for a class. diff --git a/src/main/java/net/momirealms/customcrops/helper/MavenLibrary.java b/src/main/java/net/momirealms/customcrops/helper/MavenLibrary.java index 40c4884..360ae3c 100644 --- a/src/main/java/net/momirealms/customcrops/helper/MavenLibrary.java +++ b/src/main/java/net/momirealms/customcrops/helper/MavenLibrary.java @@ -27,12 +27,7 @@ package net.momirealms.customcrops.helper; import org.jetbrains.annotations.NotNull; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.lang.annotation.*; /** * Annotation to indicate a required library for a class. diff --git a/src/main/java/net/momirealms/customcrops/helper/Repository.java b/src/main/java/net/momirealms/customcrops/helper/Repository.java index b38215f..34e7feb 100644 --- a/src/main/java/net/momirealms/customcrops/helper/Repository.java +++ b/src/main/java/net/momirealms/customcrops/helper/Repository.java @@ -25,11 +25,7 @@ package net.momirealms.customcrops.helper; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.lang.annotation.*; /** * Represents a maven repository. diff --git a/src/main/java/net/momirealms/customcrops/integrations/AntiGrief.java b/src/main/java/net/momirealms/customcrops/integrations/AntiGrief.java new file mode 100644 index 0000000..46d3106 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/AntiGrief.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations; + +import net.momirealms.customcrops.config.MainConfig; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +public interface AntiGrief { + + boolean canBreak(Location location, Player player); + + boolean canPlace(Location location, Player player); + + static boolean testBreak(Player player, Location location) { + for (AntiGrief antiGrief : MainConfig.antiGriefs) { + if(!antiGrief.canBreak(location, player)) { + return false; + } + } + return true; + } + + static boolean testPlace(Player player, Location location) { + for (AntiGrief antiGrief : MainConfig.antiGriefs) { + if(!antiGrief.canPlace(location, player)) { + return false; + } + } + return true; + } +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/Placeholders.java b/src/main/java/net/momirealms/customcrops/integrations/Placeholders.java deleted file mode 100644 index d408b38..0000000 --- a/src/main/java/net/momirealms/customcrops/integrations/Placeholders.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.integrations; - -import me.clip.placeholderapi.expansion.PlaceholderExpansion; -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.datamanager.SeasonManager; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.jetbrains.annotations.NotNull; - -import java.util.Optional; - -public class Placeholders extends PlaceholderExpansion{ - - @Override - public @NotNull String getIdentifier() { - return "customcrops"; - } - - @Override - public @NotNull String getAuthor() { - return "XiaoMoMi"; - } - - @Override - public @NotNull String getVersion() { - return "1.3"; - } - - @Override - public String onRequest(OfflinePlayer player, String params) { - if (params.equalsIgnoreCase("season")){ - if (!ConfigReader.Season.enable) return "null"; - return Optional.ofNullable(SeasonManager.SEASON.get(player.getPlayer().getWorld().getName())).orElse(ConfigReader.Message.noSeason) - .replace("spring", ConfigReader.Message.spring) - .replace("summer", ConfigReader.Message.summer) - .replace("autumn", ConfigReader.Message.autumn) - .replace("winter", ConfigReader.Message.winter); - } - if (params.startsWith("season_")){ - if (!ConfigReader.Season.enable) return "null"; - return SeasonManager.SEASON.get(params.substring(7)) - .replace("spring", ConfigReader.Message.spring) - .replace("summer", ConfigReader.Message.summer) - .replace("autumn", ConfigReader.Message.autumn) - .replace("winter", ConfigReader.Message.winter); - } - if (params.equalsIgnoreCase("nextseason")){ - if (!ConfigReader.Season.enable) return "null"; - if (!ConfigReader.Config.worlds.contains(player.getPlayer().getWorld())) return ConfigReader.Message.noSeason; - return String.valueOf(ConfigReader.Season.duration - ((int) ((player.getPlayer().getWorld().getFullTime() / 24000L) % (ConfigReader.Season.duration * 4)) % ConfigReader.Season.duration)); - } - if (params.startsWith("nextseason_")){ - if (!ConfigReader.Season.enable) return "null"; - return String.valueOf(ConfigReader.Season.duration - ((int) ((Bukkit.getWorld(params.substring(11)).getFullTime() / 24000L) % (ConfigReader.Season.duration * 4)) % ConfigReader.Season.duration)); - } - if (params.equalsIgnoreCase("current")){ - if (!ConfigReader.Season.enable) return "null"; - if (!ConfigReader.Config.worlds.contains(player.getPlayer().getWorld())) return ConfigReader.Message.noSeason; - return String.valueOf((int) ((player.getPlayer().getWorld().getFullTime() / 24000L) % (ConfigReader.Season.duration * 4)) % ConfigReader.Season.duration + 1); - } - if (params.startsWith("current_")){ - if (!ConfigReader.Season.enable) return "null"; - return String.valueOf(((int) (Bukkit.getWorld(params.substring(8)).getFullTime() / 24000L) % (ConfigReader.Season.duration * 4)) % ConfigReader.Season.duration+ 1); - } - return null; - } -} diff --git a/src/main/java/net/momirealms/customcrops/integrations/skill/SkillXP.java b/src/main/java/net/momirealms/customcrops/integrations/SkillXP.java similarity index 93% rename from src/main/java/net/momirealms/customcrops/integrations/skill/SkillXP.java rename to src/main/java/net/momirealms/customcrops/integrations/SkillXP.java index 6d5768e..1868535 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/skill/SkillXP.java +++ b/src/main/java/net/momirealms/customcrops/integrations/SkillXP.java @@ -15,10 +15,12 @@ * along with this program. If not, see . */ -package net.momirealms.customcrops.integrations.skill; +package net.momirealms.customcrops.integrations; import org.bukkit.entity.Player; public interface SkillXP { + void addXp(Player player, double amount); + } \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/CustomInterface.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/CustomInterface.java new file mode 100644 index 0000000..36731ac --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/CustomInterface.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations.customplugin; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.ItemFrame; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Nullable; + +public interface CustomInterface { + + void removeBlock(Location location); + + void placeWire(Location location, String crop); + + void placeNoteBlock(Location location, String blockID); + + String getBlockID(Location location); + + @Nullable + ItemStack getItemStack(String id); + + @Nullable + String getItemID(ItemStack itemStack); + + @Nullable + ItemFrame placeFurniture(Location location, String id); + + void removeFurniture(Entity entity); + + boolean doesExist(String itemID); + +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/HandlerP.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/HandlerP.java new file mode 100644 index 0000000..554a18e --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/HandlerP.java @@ -0,0 +1,464 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations.customplugin; + +import de.tr7zw.changeme.nbtapi.NBTItem; +import net.momirealms.customcrops.CustomCrops; +import net.momirealms.customcrops.Function; +import net.momirealms.customcrops.api.crop.Crop; +import net.momirealms.customcrops.api.event.*; +import net.momirealms.customcrops.config.*; +import net.momirealms.customcrops.managers.CropManager; +import net.momirealms.customcrops.managers.CustomWorld; +import net.momirealms.customcrops.managers.listener.InteractListener; +import net.momirealms.customcrops.objects.Sprinkler; +import net.momirealms.customcrops.objects.WaterCan; +import net.momirealms.customcrops.objects.fertilizer.Fertilizer; +import net.momirealms.customcrops.utils.AdventureUtil; +import net.momirealms.customcrops.utils.FurnitureUtil; +import net.momirealms.customcrops.utils.HologramUtil; +import net.momirealms.customcrops.utils.LimitationUtil; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.List; + +public abstract class HandlerP extends Function { + + protected CropManager cropManager; + protected CustomInterface customInterface; + private final InteractListener interactListener; + protected HashMap coolDown = new HashMap<>(); + + public HandlerP(CropManager cropManager) { + this.cropManager = cropManager; + this.customInterface = cropManager.getCustomInterface(); + this.interactListener = new InteractListener(this); + } + + @Override + public void load() { + super.load(); + Bukkit.getPluginManager().registerEvents(interactListener, CustomCrops.plugin); + } + + @Override + public void unload() { + super.unload(); + HandlerList.unregisterAll(interactListener); + } + + public void onPlayerInteract(PlayerInteractEvent event) { + //null + } + + public void onInteractSprinkler(Location location, Player player, @Nullable ItemStack itemStack, Sprinkler config) { + + CustomWorld customWorld = cropManager.getCustomWorld(location.getWorld()); + if (customWorld == null) return; + + Sprinkler sprinkler = customWorld.getSprinkler(location); + if (sprinkler == null) { + sprinkler = new Sprinkler(config.getKey(), config.getRange(), 0); + customWorld.addSprinkler(location, sprinkler); + } + + if (itemStack != null) { + + if (itemStack.getType() == Material.WATER_BUCKET) { + + SprinklerFillEvent sprinklerFillEvent = new SprinklerFillEvent(player, itemStack); + Bukkit.getPluginManager().callEvent(sprinklerFillEvent); + if (sprinklerFillEvent.isCancelled()) { + return; + } + + itemStack.setType(Material.BUCKET); + int water = sprinkler.getWater() + MainConfig.waterBucketToSprinkler; + if (water > config.getWater()) water = config.getWater(); + sprinkler.setWater(water); + + if (SoundConfig.addWaterToSprinkler.isEnable()) { + AdventureUtil.playerSound( + player, + SoundConfig.addWaterToSprinkler.getSource(), + SoundConfig.addWaterToSprinkler.getKey(), + 1,1 + ); + } + } + else if (itemStack.getType() != Material.AIR) { + NBTItem nbtItem = new NBTItem(itemStack); + int canWater = nbtItem.getInteger("WaterAmount"); + if (canWater > 0) { + + SprinklerFillEvent sprinklerFillEvent = new SprinklerFillEvent(player, itemStack); + Bukkit.getPluginManager().callEvent(sprinklerFillEvent); + if (sprinklerFillEvent.isCancelled()) { + return; + } + + nbtItem.setInteger("WaterAmount", --canWater); + itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); + int water = sprinkler.getWater() + MainConfig.wateringCanToSprinkler; + if (water > config.getWater()) water = config.getWater(); + sprinkler.setWater(water); + + if (SoundConfig.addWaterToSprinkler.isEnable()) { + AdventureUtil.playerSound( + player, + SoundConfig.addWaterToSprinkler.getSource(), + SoundConfig.addWaterToSprinkler.getKey(), + 1,1 + ); + } + + if (MainConfig.enableActionBar) { + String canID = customInterface.getItemID(itemStack); + WaterCan canConfig = WaterCanConfig.CANS.get(canID); + if (canConfig == null) return; + + AdventureUtil.playerActionbar( + player, + (MainConfig.actionBarLeft + + MainConfig.actionBarFull.repeat(canWater) + + MainConfig.actionBarEmpty.repeat(canConfig.getMax() - canWater) + + MainConfig.actionBarRight) + .replace("{max_water}", String.valueOf(canConfig.getMax())) + .replace("{water}", String.valueOf(canWater)) + ); + } + } + } + } + + if (MainConfig.enableSprinklerInfo) + HologramUtil.showHolo( + (MainConfig.sprinklerLeft + + MainConfig.sprinklerFull.repeat(sprinkler.getWater()) + + MainConfig.sprinklerEmpty.repeat(config.getWater() - sprinkler.getWater()) + + MainConfig.sprinklerRight) + .replace("{max_water}", String.valueOf(config.getWater())) + .replace("{water}", String.valueOf(sprinkler.getWater())), + player, + location.add(0, MainConfig.sprinklerInfoY - 1,0), + MainConfig.sprinklerInfoDuration); + + } + + public boolean useSurveyor(Location potLoc, String id, Player player) { + + if (!id.equals(BasicItemConfig.soilSurveyor)) return false; + CustomWorld customWorld = cropManager.getCustomWorld(potLoc.getWorld()); + if (customWorld == null) return false; + Fertilizer fertilizer = customWorld.getFertilizer(potLoc); + + SurveyorUseEvent surveyorUseEvent = new SurveyorUseEvent(player, fertilizer, potLoc); + Bukkit.getPluginManager().callEvent(surveyorUseEvent); + if (surveyorUseEvent.isCancelled()) { + return true; + } + + if (fertilizer != null) { + + Fertilizer config = FertilizerConfig.FERTILIZERS.get(fertilizer.getKey()); + if (config == null) return true; + + if (SoundConfig.surveyor.isEnable()) { + AdventureUtil.playerSound( + player, + SoundConfig.surveyor.getSource(), + SoundConfig.surveyor.getKey(), + 0.5f,1 + ); + } + + HologramUtil.showHolo( + MainConfig.fertilizerInfo + .replace("{fertilizer}", fertilizer.getName()) + .replace("{times}", String.valueOf(fertilizer.getTimes())) + .replace("{max_times}", String.valueOf(config.getTimes())), + player, + potLoc.add(0.5, MainConfig.fertilizerInfoY, 0.5), + MainConfig.fertilizerInfoDuration); + } + return true; + } + + public void onBreakUnripeCrop(Location location) { + CustomWorld customWorld = cropManager.getCustomWorld(location.getWorld()); + if (customWorld == null) return; + //remove crop cache + customWorld.removeCrop(location); + } + + public void onBreakRipeCrop(Location location, String id, Player player, boolean instant, boolean hasNamespace) { + CustomWorld customWorld = cropManager.getCustomWorld(location.getWorld()); + if (customWorld == null) return; + //remove crop cache + customWorld.removeCrop(location); + + String[] cropNameList; + if (hasNamespace) cropNameList = StringUtils.split(StringUtils.split(id, ":")[1], "_"); + else cropNameList = StringUtils.split(id, "_"); + + Crop crop = CropConfig.CROPS.get(cropNameList[0]); + if (crop == null) return; + + Fertilizer fertilizer = customWorld.getFertilizer(location.clone().subtract(0,1,0)); + //double check to prevent dupe when there's no antiGrief integration + if (instant) { + Bukkit.getScheduler().runTaskLater(CustomCrops.plugin, ()-> { + if (location.getBlock().getType() != Material.AIR) return; + cropManager.proceedHarvest(crop, player, location, fertilizer); + },1); + } + else { + cropManager.proceedHarvest(crop, player, location, fertilizer); + } + } + + public boolean placeSprinkler(String id, Location location, Player player, ItemStack item) { + + Sprinkler config = SprinklerConfig.SPRINKLERS_2D.get(id); + if (config != null) { + + Location sprinklerLoc = location.clone().add(0.5, 1.5, 0.5); + + if (FurnitureUtil.hasFurniture(sprinklerLoc)) return false; + Sprinkler sprinkler = new Sprinkler(config.getKey(), config.getRange(), 0); + CustomWorld customWorld = cropManager.getCustomWorld(location.getWorld()); + if (customWorld == null) return false; + + if (MainConfig.limitation && LimitationUtil.reachFrameLimit(location)) { + AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.limitFrame.replace("{max}", String.valueOf(MainConfig.frameAmount))); + return true; + } + + SprinklerPlaceEvent sprinklerPlaceEvent = new SprinklerPlaceEvent(player, sprinklerLoc); + Bukkit.getPluginManager().callEvent(sprinklerPlaceEvent); + if (sprinklerPlaceEvent.isCancelled()) { + return true; + } + + if (SoundConfig.placeSprinkler.isEnable()) { + AdventureUtil.playerSound( + player, + SoundConfig.placeSprinkler.getSource(), + SoundConfig.placeSprinkler.getKey(), + 1,1 + ); + } + + if (player.getGameMode() != GameMode.CREATIVE) item.setAmount(item.getAmount() - 1); + customWorld.addSprinkler(sprinklerLoc, sprinkler); + customInterface.placeFurniture(sprinklerLoc, config.getThreeD()); + + return true; + } + return false; + } + + public boolean hasNextStage(String id) { + int nextStage = Integer.parseInt(id.substring(id.length()-1)) + 1; + return customInterface.doesExist(StringUtils.chop(id) + nextStage); + } + + public boolean fillWaterCan(String id, NBTItem nbtItem, ItemStack itemStack, Player player) { + WaterCan config = WaterCanConfig.CANS.get(id); + if (config != null) { + int water = nbtItem.getInteger("WaterAmount"); + List lineOfSight = player.getLineOfSight(null, 5); + + for (Block block : lineOfSight) { + if (block.getType() == Material.WATER) { + if (config.getMax() > water) { + + WateringCanFillEvent wateringCanFillEvent = new WateringCanFillEvent(player, itemStack); + Bukkit.getPluginManager().callEvent(wateringCanFillEvent); + if (wateringCanFillEvent.isCancelled()) { + return true; + } + + water += MainConfig.waterToWaterCan; + if (water > config.getMax()) water = config.getMax(); + nbtItem.setInteger("WaterAmount", water); + itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); + + if (SoundConfig.addWaterToCan.isEnable()) { + AdventureUtil.playerSound( + player, + SoundConfig.addWaterToCan.getSource(), + SoundConfig.addWaterToCan.getKey(), + 1,1 + ); + } + } + break; + } + } + + if (MainConfig.enableActionBar) { + AdventureUtil.playerActionbar( + player, + (MainConfig.actionBarLeft + + MainConfig.actionBarFull.repeat(water) + + MainConfig.actionBarEmpty.repeat(config.getMax() - water) + + MainConfig.actionBarRight) + .replace("{max_water}", String.valueOf(config.getMax())) + .replace("{water}", String.valueOf(water)) + ); + } + return true; + } + return false; + } + + public boolean useFertilizer(Location potLoc, String id, Player player, ItemStack itemStack) { + Fertilizer fertilizer = FertilizerConfig.FERTILIZERS.get(id); + if (fertilizer == null) return false; + CustomWorld customWorld = cropManager.getCustomWorld(potLoc.getWorld()); + if (customWorld == null) return false; + + if (fertilizer.isBefore()) { + Location above = potLoc.clone().add(0,1,0); + if (FurnitureUtil.hasFurniture(above)) { + AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.beforePlant); + return true; + } + if (above.getBlock().getType() == Material.TRIPWIRE) { + AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.beforePlant); + return true; + } + } + + FertilizerUseEvent fertilizerUseEvent = new FertilizerUseEvent(player, fertilizer, potLoc); + Bukkit.getPluginManager().callEvent(fertilizerUseEvent); + if (fertilizerUseEvent.isCancelled()) { + return true; + } + + if (SoundConfig.useFertilizer.isEnable()) { + AdventureUtil.playerSound( + player, + SoundConfig.useFertilizer.getSource(), + SoundConfig.useFertilizer.getKey(), + 1, 1 + ); + } + + if (player.getGameMode() != GameMode.CREATIVE) itemStack.setAmount(itemStack.getAmount() - 1); + customWorld.addFertilizer(potLoc, fertilizer); + return true; + } + + public void onBreakSprinkler(Location location) { + CustomWorld customWorld = cropManager.getCustomWorld(location.getWorld()); + if (customWorld == null) return; + customWorld.removeSprinkler(location); + } + + public void onBreakPot(Location location) { + CustomWorld customWorld = cropManager.getCustomWorld(location.getWorld()); + if (customWorld == null) return; + //remove fertilizer + customWorld.removeFertilizer(location); + } + + public void onQuit(Player player) { + coolDown.remove(player); + } + + public void waterPot(int width, int length, Location location, float yaw){ + int extend = width / 2; + if (yaw < 45 && yaw > -135) { + if (yaw > -45) { + for (int i = -extend; i <= extend; i++) { + Location tempLoc = location.clone().add(i, 0, -1); + for (int j = 0; j < length; j++){ + tempLoc.add(0,0,1); + String blockID = customInterface.getBlockID(tempLoc); + if(blockID != null){ + if(blockID.equals(BasicItemConfig.dryPot)){ + customInterface.removeBlock(tempLoc); + customInterface.placeNoteBlock(tempLoc, BasicItemConfig.wetPot); + } + } + } + } + } + else { + for (int i = -extend; i <= extend; i++) { + Location tempLoc = location.clone().add(-1, 0, i); + for (int j = 0; j < length; j++){ + tempLoc.add(1,0,0); + String blockID = customInterface.getBlockID(tempLoc); + if(blockID != null){ + if(blockID.equals(BasicItemConfig.dryPot)){ + customInterface.removeBlock(tempLoc); + customInterface.placeNoteBlock(tempLoc, BasicItemConfig.wetPot); + } + } + } + } + } + } + else { + if (yaw > 45 && yaw < 135) { + for (int i = -extend; i <= extend; i++) { + Location tempLoc = location.clone().add(1, 0, i); + for (int j = 0; j < length; j++){ + tempLoc.subtract(1,0,0); + String blockID = customInterface.getBlockID(tempLoc); + if(blockID != null){ + if(blockID.equals(BasicItemConfig.dryPot)){ + customInterface.removeBlock(tempLoc); + customInterface.placeNoteBlock(tempLoc, BasicItemConfig.wetPot); + } + } + } + } + } + else { + for (int i = -extend; i <= extend; i++) { + Location tempLoc = location.clone().add(i, 0, 1); + for (int j = 0; j < length; j++){ + tempLoc.subtract(0,0,1); + String blockID = customInterface.getBlockID(tempLoc); + if(blockID != null){ + if(blockID.equals(BasicItemConfig.dryPot)){ + customInterface.removeBlock(tempLoc); + customInterface.placeNoteBlock(tempLoc, BasicItemConfig.wetPot); + } + } + } + } + } + } + } +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderFrameHandler.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderFrameHandler.java new file mode 100644 index 0000000..e6a27c7 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderFrameHandler.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations.customplugin.itemsadder; + +import dev.lone.itemsadder.api.CustomFurniture; +import dev.lone.itemsadder.api.Events.CustomBlockBreakEvent; +import dev.lone.itemsadder.api.Events.CustomBlockInteractEvent; +import dev.lone.itemsadder.api.Events.FurnitureBreakEvent; +import dev.lone.itemsadder.api.Events.FurnitureInteractEvent; +import net.momirealms.customcrops.api.crop.Crop; +import net.momirealms.customcrops.config.BasicItemConfig; +import net.momirealms.customcrops.config.MainConfig; +import net.momirealms.customcrops.config.SprinklerConfig; +import net.momirealms.customcrops.integrations.AntiGrief; +import net.momirealms.customcrops.managers.CropManager; +import net.momirealms.customcrops.managers.CustomWorld; +import net.momirealms.customcrops.objects.Sprinkler; +import net.momirealms.customcrops.objects.fertilizer.Fertilizer; +import net.momirealms.customcrops.utils.FurnitureUtil; +import org.bukkit.Location; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Player; + +public class ItemsAdderFrameHandler extends ItemsAdderHandler { + + public ItemsAdderFrameHandler(CropManager cropManager) { + super(cropManager); + } + + //maybe crop or sprinkler + public void onInteractFurniture(FurnitureInteractEvent event) { + + if (event.isCancelled()) return; + String namespacedID = event.getNamespacedID(); + if (namespacedID == null) return; + Sprinkler sprinkler = SprinklerConfig.SPRINKLERS_3D.get(namespacedID); + if (sprinkler != null) { + super.onInteractSprinkler(event.getBukkitEntity().getLocation(), event.getPlayer(), event.getPlayer().getActiveItem(), sprinkler); + return; + } + + if (namespacedID.contains("_stage_")) { + if (!namespacedID.equals(BasicItemConfig.deadCrop)) { + + if (!hasNextStage(namespacedID) && MainConfig.canRightClickHarvest) { + CustomFurniture.remove(event.getBukkitEntity(), false); + this.onInteractRipeCrop(event.getBukkitEntity().getLocation(), namespacedID, event.getPlayer()); + } + + else { + Location potLoc = event.getBukkitEntity().getLocation().clone().subtract(0,1,0); + super.tryMisc(event.getPlayer(), event.getPlayer().getItemInUse(), potLoc); + } + } + } + } + + public void onBreakFurniture(FurnitureBreakEvent event) { + if (event.isCancelled()) return; + String namespacedId = event.getNamespacedID(); + if (namespacedId == null) return; + + Location location = event.getBukkitEntity().getLocation(); + Player player = event.getPlayer(); + //No need for antiGrief checks + Sprinkler sprinkler = SprinklerConfig.SPRINKLERS_3D.get(namespacedId); + if (sprinkler != null) { + super.onBreakSprinkler(location); + return; + } + + if (namespacedId.contains("_stage_")) { + if (namespacedId.equals(BasicItemConfig.deadCrop)) return; + if (hasNextStage(namespacedId)) { + super.onBreakUnripeCrop(location); + return; + } + super.onBreakRipeCrop(location, namespacedId, player, false, true); + } + } + + //This can only be pot + public void onInteractBlock(CustomBlockInteractEvent event) { + if (event.isCancelled()) return; + String blockID = event.getNamespacedID(); + if (blockID.equals(BasicItemConfig.dryPot) || blockID.equals(BasicItemConfig.wetPot)) { + Location potLoc = event.getBlockClicked().getLocation(); + super.tryMisc(event.getPlayer(), event.getItem(), potLoc); + } + } + + @Override + public void onBreakBlock(CustomBlockBreakEvent event) { + + if (event.isCancelled()) return; + String namespacedId = event.getNamespacedID(); + Player player = event.getPlayer(); + Location location = event.getBlock().getLocation(); + + //fix buggy chorus duplication + chorusFix(event.getBlock()); + + if (namespacedId.equals(BasicItemConfig.dryPot) + || namespacedId.equals(BasicItemConfig.wetPot)) { + + if (!AntiGrief.testBreak(player, location)) { + event.setCancelled(true); + return; + } + + super.onBreakPot(location); + + //Check if there's crop above + Location seedLocation = location.clone().add(0.5,1,0.5); + + ItemFrame itemFrame = FurnitureUtil.getItemFrame(seedLocation); + if (itemFrame == null) return; + CustomFurniture customFurniture = CustomFurniture.byAlreadySpawned(itemFrame); + if (customFurniture == null) return; + String seedID = customFurniture.getNamespacedID(); + if (seedID.contains("_stage_")) { + CustomFurniture.remove(itemFrame, false); + if (seedID.equals(BasicItemConfig.deadCrop)) return; + super.onBreakRipeCrop(seedLocation, seedID, player, false, true); + } + } + } + + private void onInteractRipeCrop(Location location, String id, Player player) { + + Crop crop = getCropFromID(id); + if (crop == null) return; + CustomWorld customWorld = cropManager.getCustomWorld(location.getWorld()); + if (customWorld == null) return; + + Fertilizer fertilizer = customWorld.getFertilizer(location.clone().subtract(0,1,0)); + cropManager.proceedHarvest(crop, player, location, fertilizer); + + if (crop.getReturnStage() == null) { + customWorld.removeCrop(location); + return; + } + customWorld.addCrop(location, crop.getKey()); + CustomFurniture.spawn(crop.getReturnStage(), location.getBlock()); + } +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderHandler.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderHandler.java new file mode 100644 index 0000000..67017fe --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderHandler.java @@ -0,0 +1,182 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations.customplugin.itemsadder; + +import de.tr7zw.changeme.nbtapi.NBTCompound; +import de.tr7zw.changeme.nbtapi.NBTItem; +import dev.lone.itemsadder.api.CustomBlock; +import dev.lone.itemsadder.api.CustomStack; +import dev.lone.itemsadder.api.Events.CustomBlockBreakEvent; +import dev.lone.itemsadder.api.Events.CustomBlockInteractEvent; +import dev.lone.itemsadder.api.Events.FurnitureBreakEvent; +import dev.lone.itemsadder.api.Events.FurnitureInteractEvent; +import net.momirealms.customcrops.CustomCrops; +import net.momirealms.customcrops.api.crop.Crop; +import net.momirealms.customcrops.api.event.WaterEvent; +import net.momirealms.customcrops.config.CropConfig; +import net.momirealms.customcrops.config.WaterCanConfig; +import net.momirealms.customcrops.integrations.customplugin.HandlerP; +import net.momirealms.customcrops.integrations.customplugin.itemsadder.listeners.ItemsAdderBlockListener; +import net.momirealms.customcrops.integrations.customplugin.itemsadder.listeners.ItemsAdderFurnitureListener; +import net.momirealms.customcrops.managers.CropManager; +import net.momirealms.customcrops.objects.WaterCan; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +public abstract class ItemsAdderHandler extends HandlerP { + + private final ItemsAdderBlockListener itemsAdderBlockListener; + private final ItemsAdderFurnitureListener itemsAdderFurnitureListener; + + public ItemsAdderHandler(CropManager cropManager) { + super(cropManager); + this.itemsAdderBlockListener = new ItemsAdderBlockListener(this); + this.itemsAdderFurnitureListener = new ItemsAdderFurnitureListener(this); + } + + @Override + public void load() { + super.load(); + Bukkit.getPluginManager().registerEvents(this.itemsAdderBlockListener, CustomCrops.plugin); + Bukkit.getPluginManager().registerEvents(this.itemsAdderFurnitureListener, CustomCrops.plugin); + } + + @Override + public void unload() { + super.unload(); + HandlerList.unregisterAll(this.itemsAdderBlockListener); + HandlerList.unregisterAll(this.itemsAdderFurnitureListener); + } + + @Override + public void onPlayerInteract(PlayerInteractEvent event) { + + final Player player = event.getPlayer(); + final Action action = event.getAction(); + + if (action == Action.RIGHT_CLICK_BLOCK || action == Action.RIGHT_CLICK_AIR) { + + Block block = event.getClickedBlock(); + if (block != null && (block.getType().isInteractable() || block.getType() == Material.TRIPWIRE)) return; + + ItemStack item = event.getItem(); + if (item == null || item.getType() == Material.AIR) return; + NBTItem nbtItem = new NBTItem(item); + NBTCompound iaCompound = nbtItem.getCompound("itemsadder"); + if (iaCompound == null) return; + String namespace = iaCompound.getString("namespace"); + String id = iaCompound.getString("id"); + String namespacedID = namespace + ":" + id; + + if (fillWaterCan(namespacedID, nbtItem, item, player)) { + return; + } + + if (block == null) return; + + if (event.getBlockFace() == BlockFace.UP && placeSprinkler(namespacedID, event.getClickedBlock().getLocation(), player, item)) { + return; + } + } + } + + public void tryMisc(Player player, ItemStack itemInHand, Location potLoc) { + if (itemInHand == null || itemInHand.getType() == Material.AIR) return; + CustomStack customStack = CustomStack.byItemStack(itemInHand); + + if (customStack == null) return; + String itemID = customStack.getNamespacedID(); + + if (useSurveyor(potLoc, itemID, player)) { + return; + } + if (useFertilizer(potLoc, itemID, player, itemInHand)){ + return; + } + if (useWateringCan(potLoc, itemID, player, customStack)) { + return; + } + //for future misc + } + + private boolean useWateringCan(Location potLoc, String namespacedID, Player player, @NotNull CustomStack can) { + WaterCan waterCan = WaterCanConfig.CANS.get(namespacedID); + if (waterCan == null) return false; + + if (can.hasCustomDurability()) { + if (can.getDurability() > 0) { + can.setDurability(can.getDurability() - 1); + } + else return true; + } + + NBTItem nbtItem = new NBTItem(can.getItemStack()); + int water = nbtItem.getInteger("WaterAmount"); + if (water > 0) { + + WaterEvent waterEvent = new WaterEvent(player, can.getItemStack()); + Bukkit.getPluginManager().callEvent(waterEvent); + if (waterEvent.isCancelled()) { + return true; + } + + nbtItem.setInteger("WaterAmount", water - 1); + //TODO check + can.getItemStack().setItemMeta(nbtItem.getItem().getItemMeta()); + super.waterPot(waterCan.width(), waterCan.getLength(), potLoc, player.getLocation().getYaw()); + } + + return true; + } + + public Crop getCropFromID(String namespacedID) { + String[] cropNameList = StringUtils.split(StringUtils.split(namespacedID, ":")[1], "_"); + return CropConfig.CROPS.get(cropNameList[0]); + } + + public void onBreakBlock(CustomBlockBreakEvent event) { + //null + } + + public void onInteractBlock(CustomBlockInteractEvent event) { + //null + } + + public void onInteractFurniture(FurnitureInteractEvent event) { + //null + } + + public void onBreakFurniture(FurnitureBreakEvent event) { + //null + } + + public void chorusFix(Block block) { + if (block.getType() != Material.CHORUS_PLANT) return; + CustomBlock.remove(block.getLocation()); + } +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderHook.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderHook.java new file mode 100644 index 0000000..37c689a --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderHook.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations.customplugin.itemsadder; + +import de.tr7zw.changeme.nbtapi.NBTCompound; +import de.tr7zw.changeme.nbtapi.NBTItem; +import dev.lone.itemsadder.api.CustomBlock; +import dev.lone.itemsadder.api.CustomFurniture; +import dev.lone.itemsadder.api.CustomStack; +import net.momirealms.customcrops.integrations.customplugin.CustomInterface; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.ItemFrame; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Nullable; + +public class ItemsAdderHook implements CustomInterface { + + @Override + public void removeBlock(Location location) { + CustomBlock.remove(location); + } + + @Override + public void placeWire(Location location, String crop) { + CustomBlock.place(crop, location); + } + + @Override + public void placeNoteBlock(Location location, String blockID) { + CustomBlock.place(blockID, location); + } + + @Override + @Nullable + public String getBlockID(Location location) { + CustomBlock cb = CustomBlock.byAlreadyPlaced(location.getBlock()); + if (cb == null) return null; + return cb.getNamespacedID(); + } + + @Override + @Nullable + public ItemStack getItemStack(String id) { + if (id == null) return null; + CustomStack cs = CustomStack.getInstance(id); + if (cs == null) return null; + return cs.getItemStack(); + } + + @Override + @Nullable + public String getItemID(ItemStack itemStack) { + if (itemStack == null || itemStack.getType() == Material.AIR) return null; + NBTItem nbtItem = new NBTItem(itemStack); + NBTCompound nbtCompound = nbtItem.getCompound("itemsadder"); + if (nbtCompound == null) return null; + return nbtCompound.getString("namespace") + ":" + nbtCompound.getString("id"); + } + + @Override + @Nullable + public ItemFrame placeFurniture(Location location, String id) { + CustomFurniture customFurniture = CustomFurniture.spawn(id, location.getBlock()); + Entity entity = customFurniture.getArmorstand(); + if (entity instanceof ItemFrame itemFrame) { + return itemFrame; + } + else { + customFurniture.remove(false); + return null; + } + } + + @Override + public void removeFurniture(Entity entity) { + CustomFurniture.remove(entity,false); + } + + @Override + public boolean doesExist(String itemID) { + return CustomStack.getInstance(itemID) != null; + } + +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderWireHandler.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderWireHandler.java new file mode 100644 index 0000000..8ea3a84 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/ItemsAdderWireHandler.java @@ -0,0 +1,354 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations.customplugin.itemsadder; + +import de.tr7zw.changeme.nbtapi.NBTCompound; +import de.tr7zw.changeme.nbtapi.NBTItem; +import dev.lone.itemsadder.api.CustomBlock; +import dev.lone.itemsadder.api.CustomStack; +import dev.lone.itemsadder.api.Events.CustomBlockBreakEvent; +import dev.lone.itemsadder.api.Events.CustomBlockInteractEvent; +import dev.lone.itemsadder.api.Events.FurnitureBreakEvent; +import dev.lone.itemsadder.api.Events.FurnitureInteractEvent; +import net.momirealms.customcrops.api.crop.Crop; +import net.momirealms.customcrops.api.event.SeedPlantEvent; +import net.momirealms.customcrops.config.*; +import net.momirealms.customcrops.integrations.AntiGrief; +import net.momirealms.customcrops.managers.CropManager; +import net.momirealms.customcrops.managers.CustomWorld; +import net.momirealms.customcrops.objects.Sprinkler; +import net.momirealms.customcrops.objects.fertilizer.Fertilizer; +import net.momirealms.customcrops.objects.requirements.PlantingCondition; +import net.momirealms.customcrops.objects.requirements.RequirementInterface; +import net.momirealms.customcrops.utils.AdventureUtil; +import net.momirealms.customcrops.utils.FurnitureUtil; +import net.momirealms.customcrops.utils.LimitationUtil; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; + +public class ItemsAdderWireHandler extends ItemsAdderHandler { + + public ItemsAdderWireHandler(CropManager cropManager) { + super(cropManager); + } + + //interact sprinkler + public void onInteractFurniture(FurnitureInteractEvent event) { + if (event.isCancelled()) return; + + long time = System.currentTimeMillis(); + if (time - (coolDown.getOrDefault(event.getPlayer(), time - 100)) < 100) return; + coolDown.put(event.getPlayer(), time); + + String namespacedID = event.getNamespacedID(); + if (namespacedID == null) return; + Sprinkler sprinkler = SprinklerConfig.SPRINKLERS_3D.get(namespacedID); + if (sprinkler != null) { + super.onInteractSprinkler(event.getBukkitEntity().getLocation(), event.getPlayer(), event.getPlayer().getInventory().getItemInMainHand(), sprinkler); + } + } + + //break sprinkler + public void onBreakFurniture(FurnitureBreakEvent event) { + if (event.isCancelled()) return; + + String namespacedID = event.getNamespacedID(); + if (namespacedID == null) return; + Sprinkler sprinkler = SprinklerConfig.SPRINKLERS_3D.get(namespacedID); + if (sprinkler != null) { + super.onBreakSprinkler(event.getBukkitEntity().getLocation()); + } + } + + + @Override + public void onPlayerInteract(PlayerInteractEvent event) { + + final Player player = event.getPlayer(); + long time = System.currentTimeMillis(); + if (time - (coolDown.getOrDefault(player, time - 50)) < 50) return; + coolDown.put(player, time); + + super.onPlayerInteract(event); + + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return; + Block block = event.getClickedBlock(); + if (block == null) return; + CustomBlock cb = CustomBlock.byAlreadyPlaced(block); + if (cb == null) return; + + final String blockID = cb.getNamespacedID(); + //interact crop + if (blockID.contains("_stage_")) { + + if (!blockID.equals(BasicItemConfig.deadCrop)) { + //ripe crops + if (!hasNextStage(blockID) && MainConfig.canRightClickHarvest) { + if (MainConfig.emptyHand && event.hasItem()) return; + Location seedLoc = block.getLocation(); + CustomBlock.remove(seedLoc); + this.onInteractRipeCrop(seedLoc, blockID, event.getPlayer()); + } + + else { + Location potLoc = block.getLocation().clone().subtract(0,1,0); + super.tryMisc(player, event.getItem(), potLoc); + } + } + } + + //interact pot (must have an item) + else if (blockID.equals(BasicItemConfig.wetPot) || blockID.equals(BasicItemConfig.dryPot)) { + + Location seedLoc = block.getLocation().clone().add(0,1,0); + if (!AntiGrief.testPlace(player, seedLoc)) return; + + ItemStack itemInHand = event.getItem(); + Location potLoc = block.getLocation(); + super.tryMisc(player, itemInHand, potLoc); + + if (event.getBlockFace() != BlockFace.UP) return; + if (itemInHand == null || itemInHand.getType() == Material.AIR) return; + CustomStack customStack = CustomStack.byItemStack(itemInHand); + if (customStack == null) return; + String namespacedID = customStack.getNamespacedID(); + if (namespacedID.endsWith("_seeds")) { + String cropName = customStack.getId().substring(0, customStack.getId().length() - 6); + Crop crop = CropConfig.CROPS.get(cropName); + if (crop == null) return; + + CustomWorld customWorld = cropManager.getCustomWorld(seedLoc.getWorld()); + if (customWorld == null) return; + + if (FurnitureUtil.hasFurniture(seedLoc)) return; + if (seedLoc.getBlock().getType() != Material.AIR) return; + + PlantingCondition plantingCondition = new PlantingCondition(seedLoc, player); + + if (crop.getRequirements() != null) { + for (RequirementInterface requirement : crop.getRequirements()) { + if (!requirement.isConditionMet(plantingCondition)) { + return; + } + } + } + + if (MainConfig.limitation && LimitationUtil.reachWireLimit(potLoc)) { + AdventureUtil.playerMessage(player, MessageConfig.prefix + MessageConfig.limitWire.replace("{max}", String.valueOf(MainConfig.wireAmount))); + return; + } + + SeedPlantEvent seedPlantEvent = new SeedPlantEvent(player, seedLoc, crop); + Bukkit.getPluginManager().callEvent(seedPlantEvent); + if (seedPlantEvent.isCancelled()) { + return; + } + + if (SoundConfig.plantSeed.isEnable()) { + AdventureUtil.playerSound( + player, + SoundConfig.plantSeed.getSource(), + SoundConfig.plantSeed.getKey(), + 1,1 + ); + } + + if (player.getGameMode() != GameMode.CREATIVE) itemInHand.setAmount(itemInHand.getAmount() - 1); + CustomBlock.place(namespacedID.substring(0, namespacedID.length() - 5) + "stage_1", seedLoc); + customWorld.addCrop(seedLoc, cropName); + } + } + } + + public void onInteractBlock(CustomBlockInteractEvent event) { + + // A broken API Event +// +// if (event.isCancelled()) return; +// if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return; +// +// final Player player = event.getPlayer(); +// final String blockID = event.getNamespacedID(); +// //interact crop +// if (blockID.contains("_stage_")) { +// +// if (!blockID.equals(BasicItemConfig.deadCrop)) { +// //ripe crops +// if (!hasNextStage(blockID) && MainConfig.canRightClickHarvest) { +// Location seedLoc = event.getBlockClicked().getLocation(); +// CustomBlock.remove(seedLoc); +// this.onInteractRipeCrop(seedLoc, blockID, event.getPlayer()); +// } +// +// else { +// Location potLoc = event.getBlockClicked().getLocation().clone().subtract(0,1,0); +// super.tryMisc(player, event.getItem(), potLoc); +// } +// } +// } +// +// //interact pot (must have an item) +// else if (blockID.equals(BasicItemConfig.wetPot) || blockID.equals(BasicItemConfig.dryPot)) { +// +// Location seedLoc = event.getBlockClicked().getLocation().clone().add(0,1,0); +// if (!AntiGrief.testPlace(player, seedLoc)) return; +// +// ItemStack itemInHand = event.getItem(); +// Location potLoc = event.getBlockClicked().getLocation(); +// super.tryMisc(player, itemInHand, potLoc); +// +// if (event.getBlockFace() != BlockFace.UP) return; +// if (itemInHand == null || itemInHand.getType() == Material.AIR) return; +// CustomStack customStack = CustomStack.byItemStack(itemInHand); +// if (customStack == null) return; +// String namespacedID = customStack.getNamespacedID(); +// if (namespacedID.endsWith("_seeds")) { +// String cropName = customStack.getId().substring(0, customStack.getId().length() - 6); +// Crop crop = CropConfig.CROPS.get(cropName); +// if (crop == null) return; +// +// CustomWorld customWorld = cropManager.getCustomWorld(seedLoc.getWorld()); +// if (customWorld == null) return; +// +// if (FurnitureUtil.hasFurniture(seedLoc)) return; +// if (seedLoc.getBlock().getType() != Material.AIR) return; +// +// PlantingCondition plantingCondition = new PlantingCondition(seedLoc, player); +// +// if (crop.getRequirements() != null) { +// for (RequirementInterface requirement : crop.getRequirements()) { +// if (!requirement.isConditionMet(plantingCondition)) { +// return; +// } +// } +// } +// +// if (SoundConfig.plantSeed.isEnable()) { +// AdventureUtil.playerSound( +// player, +// SoundConfig.plantSeed.getSource(), +// SoundConfig.plantSeed.getKey(), +// 1,1 +// ); +// } +// +// if (player.getGameMode() != GameMode.CREATIVE) itemInHand.setAmount(itemInHand.getAmount() - 1); +// CustomBlock.place(namespacedID.substring(0, namespacedID.length() - 5) + "stage_1", seedLoc); +// customWorld.addCrop(seedLoc, cropName); +// } +// } + } + + + private void onInteractRipeCrop(Location location, String id, Player player) { + + Crop crop = getCropFromID(id); + if (crop == null) return; + CustomWorld customWorld = cropManager.getCustomWorld(location.getWorld()); + if (customWorld == null) return; + + Fertilizer fertilizer = customWorld.getFertilizer(location.clone().subtract(0,1,0)); + cropManager.proceedHarvest(crop, player, location, fertilizer); + + if (crop.getReturnStage() == null) { + customWorld.removeCrop(location); + return; + } + customWorld.addCrop(location, crop.getKey()); + CustomBlock.place(crop.getReturnStage(), location); + } + + @Override + public void onBreakBlock(CustomBlockBreakEvent event) { + if (event.isCancelled()) return; + + Player player = event.getPlayer(); + long time = System.currentTimeMillis(); + if (time - (coolDown.getOrDefault(player, time - 50)) < 50) return; + coolDown.put(player, time); + + String namespacedId = event.getNamespacedID(); + Location location = event.getBlock().getLocation(); + + //fix buggy chorus duplication + super.chorusFix(event.getBlock()); + + //break crop + if (namespacedId.contains("_stage_")) { + + if (!AntiGrief.testBreak(player, location)) { + event.setCancelled(true); + return; + } + + //Drop seeds + if (player.getInventory().getItemInMainHand().containsEnchantment(Enchantment.SILK_TOUCH) || player.getInventory().getItemInMainHand().getType() == Material.SHEARS){ + event.setCancelled(true); + CustomBlock.place(namespacedId, location); + if (player.getGameMode() != GameMode.CREATIVE) + CustomBlock.byAlreadyPlaced(location.getBlock()).getLoot().forEach(itemStack -> location.getWorld().dropItem(location.clone().add(0.5,0.2,0.5), itemStack)); + CustomBlock.remove(location); + } + if (namespacedId.equals(BasicItemConfig.deadCrop)) return; + if (hasNextStage(namespacedId)) { + super.onBreakUnripeCrop(location); + return; + } + super.onBreakRipeCrop(location, namespacedId, player, true, true); + + } + + //break pot + else if (namespacedId.equals(BasicItemConfig.dryPot) + || namespacedId.equals(BasicItemConfig.wetPot)) { + + if (!AntiGrief.testBreak(player, location)) { + event.setCancelled(true); + return; + } + + super.onBreakPot(location); + + //Check if there's crop above + Location seedLocation = location.clone().add(0,1,0); + CustomBlock customBlock = CustomBlock.byAlreadyPlaced(seedLocation.getBlock()); + if (customBlock == null) return; + String seedID = customBlock.getNamespacedID(); + if (seedID.contains("_stage_")) { + CustomBlock.remove(seedLocation); + if (seedID.equals(BasicItemConfig.deadCrop)) return; + //ripe or not + if (hasNextStage(seedID)) { + customBlock.getLoot().forEach(loot -> location.getWorld().dropItemNaturally(seedLocation.getBlock().getLocation(), loot)); + } + else { + super.onBreakRipeCrop(seedLocation, seedID, player, false, true); + } + } + } + } +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/listeners/ItemsAdderBlockListener.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/listeners/ItemsAdderBlockListener.java new file mode 100644 index 0000000..48e4f89 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/listeners/ItemsAdderBlockListener.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations.customplugin.itemsadder.listeners; + +import dev.lone.itemsadder.api.Events.CustomBlockBreakEvent; +import dev.lone.itemsadder.api.Events.CustomBlockInteractEvent; +import net.momirealms.customcrops.integrations.customplugin.itemsadder.ItemsAdderHandler; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class ItemsAdderBlockListener implements Listener { + + private final ItemsAdderHandler handler; + + public ItemsAdderBlockListener(ItemsAdderHandler handler) { + this.handler = handler; + } + + @EventHandler + public void onBreakBlock(CustomBlockBreakEvent event) { + handler.onBreakBlock(event); + } + + @EventHandler + public void onInteractBlock(CustomBlockInteractEvent event) { + handler.onInteractBlock(event); + } +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/listeners/ItemsAdderFurnitureListener.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/listeners/ItemsAdderFurnitureListener.java new file mode 100644 index 0000000..267ddc0 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/itemsadder/listeners/ItemsAdderFurnitureListener.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations.customplugin.itemsadder.listeners; + +import dev.lone.itemsadder.api.Events.FurnitureBreakEvent; +import dev.lone.itemsadder.api.Events.FurnitureInteractEvent; +import net.momirealms.customcrops.integrations.customplugin.itemsadder.ItemsAdderHandler; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class ItemsAdderFurnitureListener implements Listener { + + private final ItemsAdderHandler handler; + + public ItemsAdderFurnitureListener(ItemsAdderHandler handler) { + this.handler = handler; + } + + @EventHandler + public void onInteractFurniture(FurnitureInteractEvent event) { + handler.onInteractFurniture(event); + } + + @EventHandler + public void onBreakFurniture(FurnitureBreakEvent event) { + handler.onBreakFurniture(event); + } +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenFrameHandler.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenFrameHandler.java new file mode 100644 index 0000000..113c29b --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenFrameHandler.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations.customplugin.oraxen; + +import io.th0rgal.oraxen.events.OraxenFurnitureBreakEvent; +import io.th0rgal.oraxen.events.OraxenFurnitureInteractEvent; +import io.th0rgal.oraxen.events.OraxenNoteBlockBreakEvent; +import io.th0rgal.oraxen.events.OraxenNoteBlockInteractEvent; +import net.momirealms.customcrops.api.crop.Crop; +import net.momirealms.customcrops.config.BasicItemConfig; +import net.momirealms.customcrops.config.MainConfig; +import net.momirealms.customcrops.config.SprinklerConfig; +import net.momirealms.customcrops.integrations.AntiGrief; +import net.momirealms.customcrops.managers.CropManager; +import net.momirealms.customcrops.managers.CustomWorld; +import net.momirealms.customcrops.objects.Sprinkler; +import net.momirealms.customcrops.objects.fertilizer.Fertilizer; +import net.momirealms.customcrops.utils.FurnitureUtil; +import org.bukkit.Location; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Player; +import org.bukkit.persistence.PersistentDataType; + +public class OraxenFrameHandler extends OraxenHandler { + + public OraxenFrameHandler(CropManager cropManager) { + super(cropManager); + } + + @Override + public void onBreakNoteBlock(OraxenNoteBlockBreakEvent event) { + if (event.isCancelled()) return; + + String id = event.getNoteBlockMechanic().getItemID(); + Player player = event.getPlayer(); + Location location = event.getBlock().getLocation(); + + if (id.equals(BasicItemConfig.dryPot) + || id.equals(BasicItemConfig.wetPot)) { + + if (!AntiGrief.testBreak(player, location)) { + event.setCancelled(true); + return; + } + + super.onBreakPot(location); + + Location seedLocation = location.clone().add(0.5,1,0.5); + ItemFrame itemFrame = FurnitureUtil.getItemFrame(seedLocation); + if (itemFrame == null) return; + String furnitureID = itemFrame.getPersistentDataContainer().get(OraxenHook.FURNITURE, PersistentDataType.STRING); + if (furnitureID == null) return; + if (furnitureID.contains("_stage_")) { + itemFrame.remove(); + if (furnitureID.equals(BasicItemConfig.deadCrop)) return; + super.onBreakRipeCrop(seedLocation, furnitureID, player, false, false); + } + } + } + + @Override + public void onBreakFurniture(OraxenFurnitureBreakEvent event) { + if (event.isCancelled()) return; + String id = event.getFurnitureMechanic().getItemID(); + if (id == null) return; + //TODO check if needs anti grief + Sprinkler sprinkler = SprinklerConfig.SPRINKLERS_3D.get(id); + if (sprinkler != null) { + super.onBreakSprinkler(event.getBlock().getLocation()); + return; + } + + if (id.contains("_stage_")) { + if (id.equals(BasicItemConfig.deadCrop)) return; + if (hasNextStage(id)) return; + super.onBreakRipeCrop(event.getBlock().getLocation(), id, event.getPlayer(), false, false); + } + } + + @Override + public void onInteractNoteBlock(OraxenNoteBlockInteractEvent event) { + if (event.isCancelled()) return; + String blockID = event.getNoteBlockMechanic().getItemID(); + if (blockID.equals(BasicItemConfig.dryPot) || blockID.equals(BasicItemConfig.wetPot)) { + Location potLoc = event.getBlock().getLocation(); + super.tryMisc(event.getPlayer(), event.getItemInHand(), potLoc); + } + } + + @Override + public void onInteractFurniture(OraxenFurnitureInteractEvent event) { + if (event.isCancelled()) return; + String id = event.getFurnitureMechanic().getItemID(); + if (id == null) return; + Sprinkler sprinkler = SprinklerConfig.SPRINKLERS_3D.get(id); + if (sprinkler != null) { + super.onInteractSprinkler(event.getBlock().getLocation(), event.getPlayer(), event.getPlayer().getActiveItem(), sprinkler); + return; + } + + if (id.contains("_stage_")) { + if (!id.equals(BasicItemConfig.deadCrop)) { + + if (!hasNextStage(id) && MainConfig.canRightClickHarvest) { + event.getItemFrame().remove(); + this.onInteractRipeCrop(event.getBlock().getLocation(), id, event.getPlayer()); + } + + else { + Location potLoc = event.getBlock().getLocation().clone().subtract(0,1,0); + super.tryMisc(event.getPlayer(), event.getPlayer().getItemInUse(), potLoc); + } + } + } + } + + private void onInteractRipeCrop(Location location, String id, Player player) { + + Crop crop = getCropFromID(id); + if (crop == null) return; + CustomWorld customWorld = cropManager.getCustomWorld(location.getWorld()); + if (customWorld == null) return; + + Fertilizer fertilizer = customWorld.getFertilizer(location.clone().subtract(0,1,0)); + cropManager.proceedHarvest(crop, player, location, fertilizer); + + if (crop.getReturnStage() == null) { + customWorld.removeCrop(location); + return; + } + customWorld.addCrop(location, crop.getKey()); + cropManager.getCustomInterface().placeFurniture(location, crop.getReturnStage()); + } +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenHandler.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenHandler.java new file mode 100644 index 0000000..0a2b56f --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenHandler.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations.customplugin.oraxen; + +import de.tr7zw.changeme.nbtapi.NBTItem; +import io.th0rgal.oraxen.events.*; +import io.th0rgal.oraxen.items.OraxenItems; +import net.momirealms.customcrops.CustomCrops; +import net.momirealms.customcrops.api.crop.Crop; +import net.momirealms.customcrops.api.event.WaterEvent; +import net.momirealms.customcrops.config.CropConfig; +import net.momirealms.customcrops.config.WaterCanConfig; +import net.momirealms.customcrops.integrations.customplugin.HandlerP; +import net.momirealms.customcrops.integrations.customplugin.oraxen.listeners.OraxenBlockListener; +import net.momirealms.customcrops.integrations.customplugin.oraxen.listeners.OraxenFurnitureListener; +import net.momirealms.customcrops.managers.CropManager; +import net.momirealms.customcrops.objects.WaterCan; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public abstract class OraxenHandler extends HandlerP { + + private final OraxenBlockListener oraxenBlockListener; + private final OraxenFurnitureListener oraxenFurnitureListener; + + public OraxenHandler(CropManager cropManager) { + super(cropManager); + this.oraxenBlockListener = new OraxenBlockListener(this); + this.oraxenFurnitureListener = new OraxenFurnitureListener(this); + } + + @Override + public void load() { + super.load(); + Bukkit.getPluginManager().registerEvents(this.oraxenBlockListener, CustomCrops.plugin); + Bukkit.getPluginManager().registerEvents(this.oraxenFurnitureListener, CustomCrops.plugin); + } + + @Override + public void unload() { + super.unload(); + HandlerList.unregisterAll(this.oraxenBlockListener); + HandlerList.unregisterAll(this.oraxenFurnitureListener); + } + + public void tryMisc(Player player, ItemStack itemInHand, Location potLoc) { + if (itemInHand == null || itemInHand.getType() == Material.AIR) return; + String id = OraxenItems.getIdByItem(itemInHand); + if (id == null) return; + + if (useSurveyor(potLoc, id, player)) { + return; + } + if (useFertilizer(potLoc, id, player, itemInHand)){ + return; + } + if (useWateringCan(potLoc, id, player, itemInHand)) { + return; + } + //for future misc + } + + private boolean useWateringCan(Location potLoc, String id, Player player, @NotNull ItemStack can) { + WaterCan waterCan = WaterCanConfig.CANS.get(id); + if (waterCan == null) return false; + + NBTItem nbtItem = new NBTItem(can); + int water = nbtItem.getInteger("WaterAmount"); + if (water > 0) { + + WaterEvent waterEvent = new WaterEvent(player, can); + Bukkit.getPluginManager().callEvent(waterEvent); + if (waterEvent.isCancelled()) { + return true; + } + nbtItem.setInteger("WaterAmount", water - 1); + + can.setItemMeta(nbtItem.getItem().getItemMeta()); + super.waterPot(waterCan.width(), waterCan.getLength(), potLoc, player.getLocation().getYaw()); + } + return true; + } + + @Nullable + public Crop getCropFromID(String id) { + return CropConfig.CROPS.get(StringUtils.split(id, "_")[0]); + } + + public void onBreakNoteBlock(OraxenNoteBlockBreakEvent event) { + } + + public void onBreakStringBlock(OraxenStringBlockBreakEvent event) { + } + + public void onInteractStringBlock(OraxenStringBlockInteractEvent event) { + } + + public void onInteractNoteBlock(OraxenNoteBlockInteractEvent event) { + } + + public void onBreakFurniture(OraxenFurnitureBreakEvent event) { + } + + public void onInteractFurniture(OraxenFurnitureInteractEvent event) { + } +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenHook.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenHook.java new file mode 100644 index 0000000..0e94fec --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenHook.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations.customplugin.oraxen; + +import io.th0rgal.oraxen.OraxenPlugin; +import io.th0rgal.oraxen.items.ItemBuilder; +import io.th0rgal.oraxen.items.OraxenItems; +import io.th0rgal.oraxen.mechanics.provided.gameplay.noteblock.NoteBlockMechanic; +import io.th0rgal.oraxen.mechanics.provided.gameplay.noteblock.NoteBlockMechanicFactory; +import io.th0rgal.oraxen.mechanics.provided.gameplay.noteblock.NoteBlockMechanicListener; +import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanic; +import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanicFactory; +import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanicListener; +import net.momirealms.customcrops.integrations.customplugin.CustomInterface; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.Rotation; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; +import org.bukkit.entity.ItemFrame; +import org.bukkit.inventory.ItemStack; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.Nullable; + +import java.util.Random; + +import static io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureMechanic.FURNITURE_KEY; + +public class OraxenHook implements CustomInterface { + + static Rotation[] rotations4 = {Rotation.NONE, Rotation.FLIPPED, Rotation.CLOCKWISE, Rotation.COUNTER_CLOCKWISE}; + + public static NamespacedKey FURNITURE = new NamespacedKey(OraxenPlugin.get(), "furniture"); + + @Override + public void removeBlock(Location location) { + location.getBlock().setType(Material.AIR); + } + + @Override + public void placeWire(Location location, String crop) { + StringBlockMechanicFactory.setBlockModel(location.getBlock(), crop); + } + + @Override + public void placeNoteBlock(Location location, String id) { + NoteBlockMechanicFactory.setBlockModel(location.getBlock(), id); + } + + @Override + @Nullable + public String getBlockID(Location location) { + Block block = location.getBlock(); + if (block.getType() == Material.TRIPWIRE) { + StringBlockMechanic mechanic = StringBlockMechanicListener.getStringMechanic(block); + if (mechanic == null) return null; + else return mechanic.getItemID(); + } + else if (block.getType() == Material.NOTE_BLOCK) { + NoteBlockMechanic mechanic = NoteBlockMechanicListener.getNoteBlockMechanic(block); + if (mechanic == null) return null; + else return mechanic.getItemID(); + } + return null; + } + + @Override + @Nullable + public ItemStack getItemStack(String id) { + ItemBuilder ib = OraxenItems.getItemById(id); + if (ib == null) return null; + return ib.build(); + } + + @Override + @Nullable + public String getItemID(ItemStack itemStack) { + return OraxenItems.getIdByItem(itemStack); + } + + @Override + @Nullable + public ItemFrame placeFurniture(Location location, String id) { + ItemBuilder itemBuilder = OraxenItems.getItemById(id); + if (itemBuilder == null) return null; + return location.getWorld().spawn(location, ItemFrame.class, (ItemFrame frame) -> { + frame.setVisible(false); + frame.setFixed(false); + frame.setPersistent(true); + frame.setItemDropChance(0); + frame.setItem(itemBuilder.build(), false); + frame.setRotation(rotations4[new Random().nextInt(rotations4.length-1)]); + frame.setFacingDirection(BlockFace.UP, true); + PersistentDataContainer pdc = frame.getPersistentDataContainer(); + pdc.set(FURNITURE_KEY, PersistentDataType.STRING, id); + }); + } + + @Override + public void removeFurniture(Entity entity) { + entity.remove(); + } + + @Override + public boolean doesExist(String itemID) { + return OraxenItems.getItemById(itemID) != null; + } +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenWireHandler.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenWireHandler.java new file mode 100644 index 0000000..79b0ffa --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/OraxenWireHandler.java @@ -0,0 +1,222 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations.customplugin.oraxen; + +import io.th0rgal.oraxen.events.*; +import io.th0rgal.oraxen.items.OraxenItems; +import io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureMechanic; +import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanic; +import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanicFactory; +import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanicListener; +import net.momirealms.customcrops.api.crop.Crop; +import net.momirealms.customcrops.config.BasicItemConfig; +import net.momirealms.customcrops.config.CropConfig; +import net.momirealms.customcrops.config.MainConfig; +import net.momirealms.customcrops.config.SprinklerConfig; +import net.momirealms.customcrops.integrations.AntiGrief; +import net.momirealms.customcrops.managers.CropManager; +import net.momirealms.customcrops.managers.CustomWorld; +import net.momirealms.customcrops.objects.Sprinkler; +import net.momirealms.customcrops.objects.fertilizer.Fertilizer; +import net.momirealms.customcrops.objects.requirements.PlantingCondition; +import net.momirealms.customcrops.objects.requirements.RequirementInterface; +import net.momirealms.customcrops.utils.FurnitureUtil; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class OraxenWireHandler extends OraxenHandler{ + + public OraxenWireHandler(CropManager cropManager) { + super(cropManager); + } + + @Override + public void onBreakNoteBlock(OraxenNoteBlockBreakEvent event) { + if (event.isCancelled()) return; + String id = event.getNoteBlockMechanic().getItemID(); + if (id.equals(BasicItemConfig.dryPot) || id.equals(BasicItemConfig.wetPot)) { + + Location location = event.getBlock().getLocation(); + Player player = event.getPlayer(); + + if (!AntiGrief.testBreak(player, location)) { + event.setCancelled(true); + return; + } + super.onBreakPot(location); + + Location seedLocation = location.clone().add(0,1,0); + StringBlockMechanic mechanic = StringBlockMechanicListener.getStringMechanic(seedLocation.getBlock()); + if (mechanic == null) return; + String seedID = mechanic.getItemID(); + if (seedID.contains("_stage_")) { + seedLocation.getBlock().setType(Material.AIR); + if (seedID.equals(BasicItemConfig.deadCrop)) return; + //ripe or not + if (hasNextStage(seedID)) { + for (ItemStack item : seedLocation.getBlock().getDrops()) + player.getWorld().dropItemNaturally(seedLocation, item); + } + else { + super.onBreakRipeCrop(seedLocation, seedID, player, false, false); + } + } + } + } + + @Override + public void onBreakStringBlock(OraxenStringBlockBreakEvent event) { + if (event.isCancelled()) return; + String id = event.getStringBlockMechanic().getItemID(); + if (id.contains("_stage_")) { + + final Player player = event.getPlayer(); + final Block block = event.getBlock(); + + if (!AntiGrief.testBreak(player, event.getBlock().getLocation())) { + event.setCancelled(true); + return; + } + + //Drop seeds + if (player.getInventory().getItemInMainHand().containsEnchantment(Enchantment.SILK_TOUCH) || player.getInventory().getItemInMainHand().getType() == Material.SHEARS){ + event.setCancelled(true); + if (player.getGameMode() != GameMode.CREATIVE) + for (ItemStack item : block.getDrops()) + player.getWorld().dropItemNaturally(block.getLocation(), item); + block.setType(Material.AIR); + } + + if (id.equals(BasicItemConfig.deadCrop)) return; + if (hasNextStage(id)) return; + super.onBreakRipeCrop(block.getLocation(), id, player, true, false); + } + } + + @Override + public void onBreakFurniture(OraxenFurnitureBreakEvent event) { + if (event.isCancelled()) return; + FurnitureMechanic mechanic = event.getFurnitureMechanic(); + if (mechanic == null) return; + Sprinkler sprinkler = SprinklerConfig.SPRINKLERS_3D.get(mechanic.getItemID()); + if (sprinkler != null) { + super.onBreakSprinkler(event.getBlock().getLocation()); + } + } + + @Override + public void onInteractFurniture(OraxenFurnitureInteractEvent event) { + if (event.isCancelled()) return; + FurnitureMechanic mechanic = event.getFurnitureMechanic(); + if (mechanic == null) return; + String id = mechanic.getItemID(); + Sprinkler sprinkler = SprinklerConfig.SPRINKLERS_3D.get(id); + if (sprinkler != null) { + super.onInteractSprinkler(event.getBlock().getLocation(), event.getPlayer(), event.getPlayer().getActiveItem(), sprinkler); + } + } + + @Override + public void onInteractNoteBlock(OraxenNoteBlockInteractEvent event) { + if (event.isCancelled()) return; + + ItemStack itemInHand = event.getItemInHand(); + Location potLoc = event.getBlock().getLocation(); + Player player = event.getPlayer(); + + if (!AntiGrief.testPlace(player, potLoc)) return; + + super.tryMisc(event.getPlayer(), itemInHand, potLoc); + + if (event.getBlockFace() != BlockFace.UP) return; + if (itemInHand == null || itemInHand.getType() == Material.AIR) return; + String id = OraxenItems.getIdByItem(itemInHand); + + if (id.endsWith("_seeds")) { + String cropName = id.substring(0, id.length() - 6); + Crop crop = CropConfig.CROPS.get(cropName); + if (crop == null) return; + + Location seedLoc = potLoc.clone().add(0,1,0); + CustomWorld customWorld = cropManager.getCustomWorld(seedLoc.getWorld()); + if (customWorld == null) return; + + if (FurnitureUtil.hasFurniture(seedLoc)) return; + if (seedLoc.getBlock().getType() != Material.AIR) return; + + PlantingCondition plantingCondition = new PlantingCondition(seedLoc, player); + + for (RequirementInterface requirement : crop.getRequirements()) { + if (!requirement.isConditionMet(plantingCondition)) { + return; + } + } + StringBlockMechanicFactory.setBlockModel(seedLoc.getBlock(), id.substring(0, id.length() - 5) + "stage_1"); + customWorld.addCrop(seedLoc, cropName); + } + } + + @Override + public void onInteractStringBlock(OraxenStringBlockInteractEvent event) { + if (event.isCancelled()) return; + + String id = event.getStringBlockMechanic().getItemID(); + Player player = event.getPlayer(); + + if (id.contains("_stage_")) { + if (!id.equals(BasicItemConfig.deadCrop)) { + //ripe crops + if (!hasNextStage(id) && MainConfig.canRightClickHarvest) { + Block seedBlock = event.getBlock(); + Location seedLoc = seedBlock.getLocation(); + seedBlock.setType(Material.AIR); + this.onInteractRipeCrop(seedLoc, id, event.getPlayer()); + } + + else { + Location potLoc = event.getBlock().getLocation().clone().subtract(0,1,0); + super.tryMisc(player, event.getItemInHand(), potLoc); + } + } + } + } + + private void onInteractRipeCrop(Location location, String id, Player player) { + + Crop crop = getCropFromID(id); + if (crop == null) return; + CustomWorld customWorld = cropManager.getCustomWorld(location.getWorld()); + if (customWorld == null) return; + + Fertilizer fertilizer = customWorld.getFertilizer(location.clone().subtract(0,1,0)); + cropManager.proceedHarvest(crop, player, location, fertilizer); + + if (crop.getReturnStage() == null) { + customWorld.removeCrop(location); + return; + } + customWorld.addCrop(location, crop.getKey()); + StringBlockMechanicFactory.setBlockModel(location.getBlock(), crop.getReturnStage()); + } +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/listeners/OraxenBlockListener.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/listeners/OraxenBlockListener.java new file mode 100644 index 0000000..cc4e41b --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/listeners/OraxenBlockListener.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations.customplugin.oraxen.listeners; + +import io.th0rgal.oraxen.events.OraxenNoteBlockBreakEvent; +import io.th0rgal.oraxen.events.OraxenNoteBlockInteractEvent; +import io.th0rgal.oraxen.events.OraxenStringBlockBreakEvent; +import io.th0rgal.oraxen.events.OraxenStringBlockInteractEvent; +import net.momirealms.customcrops.integrations.customplugin.oraxen.OraxenHandler; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class OraxenBlockListener implements Listener { + + private final OraxenHandler handler; + + public OraxenBlockListener(OraxenHandler handler) { + this.handler = handler; + } + + @EventHandler + public void onBreakNote(OraxenNoteBlockBreakEvent event) { + handler.onBreakNoteBlock(event); + } + + @EventHandler + public void onInteractNote(OraxenNoteBlockInteractEvent event) { + } + + @EventHandler + public void onBreakString(OraxenStringBlockBreakEvent event) { + handler.onBreakStringBlock(event); + } + + @EventHandler + public void onInteractString(OraxenStringBlockInteractEvent event) { + } +} diff --git a/src/main/java/net/momirealms/customcrops/timer/CropTimer.java b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/listeners/OraxenFurnitureListener.java similarity index 50% rename from src/main/java/net/momirealms/customcrops/timer/CropTimer.java rename to src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/listeners/OraxenFurnitureListener.java index 8e6b524..eb537ef 100644 --- a/src/main/java/net/momirealms/customcrops/timer/CropTimer.java +++ b/src/main/java/net/momirealms/customcrops/integrations/customplugin/oraxen/listeners/OraxenFurnitureListener.java @@ -15,30 +15,27 @@ * along with this program. If not, see . */ -package net.momirealms.customcrops.timer; +package net.momirealms.customcrops.integrations.customplugin.oraxen.listeners; -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.CustomCrops; -import org.bukkit.Bukkit; -import org.bukkit.scheduler.BukkitTask; +import io.th0rgal.oraxen.events.OraxenFurnitureBreakEvent; +import io.th0rgal.oraxen.events.OraxenFurnitureInteractEvent; +import net.momirealms.customcrops.integrations.customplugin.oraxen.OraxenHandler; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; -public class CropTimer { +public class OraxenFurnitureListener implements Listener { - private final int taskID; + private final OraxenHandler handler; - public CropTimer() { - TimeCheck tc = new TimeCheck(); - BukkitTask task; - if (ConfigReader.Config.asyncCheck) task = tc.runTaskTimerAsynchronously(CustomCrops.plugin, 1,1); - else task = tc.runTaskTimer(CustomCrops.plugin, 1,1); - this.taskID = task.getTaskId(); + public OraxenFurnitureListener(OraxenHandler handler) { + this.handler = handler; } - public void stopTimer(int ID) { - Bukkit.getScheduler().cancelTask(ID); + @EventHandler + public void onInteract(OraxenFurnitureInteractEvent event) { } - public int getTaskID() { - return this.taskID; + @EventHandler + public void onBreak(OraxenFurnitureBreakEvent event) { } } diff --git a/src/main/java/net/momirealms/customcrops/integrations/papi/PlaceholderManager.java b/src/main/java/net/momirealms/customcrops/integrations/papi/PlaceholderManager.java new file mode 100644 index 0000000..580e250 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/papi/PlaceholderManager.java @@ -0,0 +1,36 @@ +package net.momirealms.customcrops.integrations.papi; + +import me.clip.placeholderapi.PlaceholderAPI; +import net.momirealms.customcrops.Function; +import net.momirealms.customcrops.config.SeasonConfig; +import org.bukkit.entity.Player; + +public class PlaceholderManager extends Function { + + private SeasonPapi seasonPapi; + + public PlaceholderManager() { + load(); + } + + @Override + public void load() { + super.load(); + if (SeasonConfig.enable) { + this.seasonPapi = new SeasonPapi(); + this.seasonPapi.register(); + } + } + + @Override + public void unload() { + super.unload(); + if (this.seasonPapi != null) { + this.seasonPapi.unregister(); + } + } + + public String parse(Player player, String text) { + return PlaceholderAPI.setPlaceholders(player, text); + } +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/papi/SeasonPapi.java b/src/main/java/net/momirealms/customcrops/integrations/papi/SeasonPapi.java new file mode 100644 index 0000000..c22ffd2 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/papi/SeasonPapi.java @@ -0,0 +1,91 @@ +package net.momirealms.customcrops.integrations.papi; + +import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import net.momirealms.customcrops.api.utils.SeasonUtils; +import net.momirealms.customcrops.config.MainConfig; +import net.momirealms.customcrops.config.MessageConfig; +import net.momirealms.customcrops.config.SeasonConfig; +import net.momirealms.customcrops.integrations.season.CCSeason; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class SeasonPapi extends PlaceholderExpansion { + + @Override + public @NotNull String getIdentifier() { + return "cseason"; + } + + @Override + public @NotNull String getAuthor() { + return "XiaoMoMi"; + } + + @Override + public @NotNull String getVersion() { + return "1.0"; + } + + @Override + public boolean persist() { + return true; + } + + @Override + public @Nullable String onPlaceholderRequest(Player player, @NotNull String params) { + if (!SeasonConfig.enable) return MessageConfig.seasonDisabled; + switch (params) { + case "current" -> { + if (!MainConfig.getWorldsList().contains(player.getWorld())) return MessageConfig.autoSeasonDisabled; + return getSeasonText(player.getWorld()); + } + case "days_left" -> { + if (!SeasonConfig.auto) return MessageConfig.autoSeasonDisabled; + if (!MainConfig.getWorldsList().contains(player.getWorld())) return MessageConfig.noSeason; + return String.valueOf(SeasonConfig.duration - ((int) ((player.getWorld().getFullTime() / 24000L) % (SeasonConfig.duration * 4)) % SeasonConfig.duration)); + } + case "days_gone" -> { + if (!SeasonConfig.auto) return MessageConfig.autoSeasonDisabled; + if (!MainConfig.getWorldsList().contains(player.getWorld())) return MessageConfig.noSeason; + return String.valueOf((int) ((player.getWorld().getFullTime() / 24000L) % (SeasonConfig.duration * 4)) % SeasonConfig.duration + 1); + } + default -> { + if (params.startsWith("current_")) { + World world = Bukkit.getWorld(params.substring(8)); + if (world == null) return MessageConfig.noSeason; + if (!MainConfig.getWorldsList().contains(world)) return MessageConfig.autoSeasonDisabled; + return getSeasonText(world); + } + if (params.startsWith("days_left_")) { + if (!SeasonConfig.auto) return MessageConfig.autoSeasonDisabled; + World world = Bukkit.getWorld(params.substring(10)); + if (world == null) return MessageConfig.noSeason; + if (!MainConfig.getWorldsList().contains(world)) return MessageConfig.noSeason; + return String.valueOf(SeasonConfig.duration - ((int) ((world.getFullTime() / 24000L) % (SeasonConfig.duration * 4)) % SeasonConfig.duration)); + } + if (params.startsWith("days_gone_")) { + if (!SeasonConfig.auto) return MessageConfig.autoSeasonDisabled; + World world = Bukkit.getWorld(params.substring(10)); + if (world == null) return MessageConfig.noSeason; + if (!MainConfig.getWorldsList().contains(world)) return MessageConfig.noSeason; + return String.valueOf((int) ((world.getFullTime() / 24000L) % (SeasonConfig.duration * 4)) % SeasonConfig.duration + 1); + } + } + } + return "null"; + } + + private String getSeasonText(World world) { + CCSeason season = SeasonUtils.getSeason(world); + return switch (season) { + case SPRING -> MessageConfig.spring; + case SUMMER -> MessageConfig.summer; + case AUTUMN -> MessageConfig.autumn; + case WINTER -> MessageConfig.winter; + default -> throw new IllegalStateException("Unexpected value: " + season); + }; + } +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/protection/BentoBoxIntegration.java b/src/main/java/net/momirealms/customcrops/integrations/protection/BentoBoxHook.java similarity index 94% rename from src/main/java/net/momirealms/customcrops/integrations/protection/BentoBoxIntegration.java rename to src/main/java/net/momirealms/customcrops/integrations/protection/BentoBoxHook.java index f529032..48795a2 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/protection/BentoBoxIntegration.java +++ b/src/main/java/net/momirealms/customcrops/integrations/protection/BentoBoxHook.java @@ -17,6 +17,7 @@ package net.momirealms.customcrops.integrations.protection; +import net.momirealms.customcrops.integrations.AntiGrief; import org.bukkit.Location; import org.bukkit.entity.Player; import world.bentobox.bentobox.BentoBox; @@ -26,7 +27,7 @@ import world.bentobox.bentobox.lists.Flags; import java.util.Optional; -public class BentoBoxIntegration implements Integration{ +public class BentoBoxHook implements AntiGrief { @Override public boolean canBreak(Location location, Player player) { diff --git a/src/main/java/net/momirealms/customcrops/integrations/protection/CrashClaimIntegration.java b/src/main/java/net/momirealms/customcrops/integrations/protection/CrashClaimHook.java similarity index 93% rename from src/main/java/net/momirealms/customcrops/integrations/protection/CrashClaimIntegration.java rename to src/main/java/net/momirealms/customcrops/integrations/protection/CrashClaimHook.java index fc9f092..4f5d1ac 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/protection/CrashClaimIntegration.java +++ b/src/main/java/net/momirealms/customcrops/integrations/protection/CrashClaimHook.java @@ -19,10 +19,11 @@ package net.momirealms.customcrops.integrations.protection; import net.crashcraft.crashclaim.api.CrashClaimAPI; import net.crashcraft.crashclaim.permissions.PermissionRoute; +import net.momirealms.customcrops.integrations.AntiGrief; import org.bukkit.Location; import org.bukkit.entity.Player; -public class CrashClaimIntegration implements Integration{ +public class CrashClaimHook implements AntiGrief { @Override public boolean canBreak(Location location, Player player) { diff --git a/src/main/java/net/momirealms/customcrops/integrations/protection/GriefDefenderIntegration.java b/src/main/java/net/momirealms/customcrops/integrations/protection/GriefDefenderHook.java similarity index 91% rename from src/main/java/net/momirealms/customcrops/integrations/protection/GriefDefenderIntegration.java rename to src/main/java/net/momirealms/customcrops/integrations/protection/GriefDefenderHook.java index 83b4d0a..8ea5a5e 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/protection/GriefDefenderIntegration.java +++ b/src/main/java/net/momirealms/customcrops/integrations/protection/GriefDefenderHook.java @@ -17,10 +17,11 @@ package net.momirealms.customcrops.integrations.protection; +import net.momirealms.customcrops.integrations.AntiGrief; import org.bukkit.Location; import org.bukkit.entity.Player; -public class GriefDefenderIntegration implements Integration { +public class GriefDefenderHook implements AntiGrief { @Override public boolean canBreak(Location location, Player player) { diff --git a/src/main/java/net/momirealms/customcrops/integrations/protection/GriefPreventionIntegration.java b/src/main/java/net/momirealms/customcrops/integrations/protection/GriefPreventionHook.java similarity index 91% rename from src/main/java/net/momirealms/customcrops/integrations/protection/GriefPreventionIntegration.java rename to src/main/java/net/momirealms/customcrops/integrations/protection/GriefPreventionHook.java index 9f58c97..3ad8b33 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/protection/GriefPreventionIntegration.java +++ b/src/main/java/net/momirealms/customcrops/integrations/protection/GriefPreventionHook.java @@ -17,10 +17,11 @@ package net.momirealms.customcrops.integrations.protection; +import net.momirealms.customcrops.integrations.AntiGrief; import org.bukkit.Location; import org.bukkit.entity.Player; -public class GriefPreventionIntegration implements Integration{ +public class GriefPreventionHook implements AntiGrief { @Override public boolean canBreak(Location location, Player player) { diff --git a/src/main/java/net/momirealms/customcrops/integrations/protection/KingdomsXIntegration.java b/src/main/java/net/momirealms/customcrops/integrations/protection/KingdomsXHook.java similarity index 94% rename from src/main/java/net/momirealms/customcrops/integrations/protection/KingdomsXIntegration.java rename to src/main/java/net/momirealms/customcrops/integrations/protection/KingdomsXHook.java index c7ee8ea..f4a7d62 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/protection/KingdomsXIntegration.java +++ b/src/main/java/net/momirealms/customcrops/integrations/protection/KingdomsXHook.java @@ -17,13 +17,14 @@ package net.momirealms.customcrops.integrations.protection; +import net.momirealms.customcrops.integrations.AntiGrief; import org.bukkit.Location; import org.bukkit.entity.Player; import org.kingdoms.constants.group.Kingdom; import org.kingdoms.constants.land.Land; import org.kingdoms.constants.player.KingdomPlayer; -public class KingdomsXIntegration implements Integration { +public class KingdomsXHook implements AntiGrief { @Override public boolean canBreak(Location location, Player player) { diff --git a/src/main/java/net/momirealms/customcrops/integrations/protection/LandsIntegration.java b/src/main/java/net/momirealms/customcrops/integrations/protection/LandsHook.java similarity index 93% rename from src/main/java/net/momirealms/customcrops/integrations/protection/LandsIntegration.java rename to src/main/java/net/momirealms/customcrops/integrations/protection/LandsHook.java index 32e6006..9241134 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/protection/LandsIntegration.java +++ b/src/main/java/net/momirealms/customcrops/integrations/protection/LandsHook.java @@ -20,10 +20,11 @@ package net.momirealms.customcrops.integrations.protection; import me.angeschossen.lands.api.flags.Flags; import me.angeschossen.lands.api.land.Area; import net.momirealms.customcrops.CustomCrops; +import net.momirealms.customcrops.integrations.AntiGrief; import org.bukkit.Location; import org.bukkit.entity.Player; -public class LandsIntegration implements Integration{ +public class LandsHook implements AntiGrief { @Override public boolean canBreak(Location location, Player player) { diff --git a/src/main/java/net/momirealms/customcrops/integrations/protection/PlotSquaredIntegration.java b/src/main/java/net/momirealms/customcrops/integrations/protection/PlotSquaredHook.java similarity index 93% rename from src/main/java/net/momirealms/customcrops/integrations/protection/PlotSquaredIntegration.java rename to src/main/java/net/momirealms/customcrops/integrations/protection/PlotSquaredHook.java index 5a6d077..85ed525 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/protection/PlotSquaredIntegration.java +++ b/src/main/java/net/momirealms/customcrops/integrations/protection/PlotSquaredHook.java @@ -18,9 +18,10 @@ package net.momirealms.customcrops.integrations.protection; import com.plotsquared.core.location.Location; +import net.momirealms.customcrops.integrations.AntiGrief; import org.bukkit.entity.Player; -public class PlotSquaredIntegration implements Integration { +public class PlotSquaredHook implements AntiGrief { @Override public boolean canBreak(org.bukkit.Location location, Player player) { diff --git a/src/main/java/net/momirealms/customcrops/integrations/protection/ResidenceIntegration.java b/src/main/java/net/momirealms/customcrops/integrations/protection/ResidenceHook.java similarity index 94% rename from src/main/java/net/momirealms/customcrops/integrations/protection/ResidenceIntegration.java rename to src/main/java/net/momirealms/customcrops/integrations/protection/ResidenceHook.java index 67c396c..50bce03 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/protection/ResidenceIntegration.java +++ b/src/main/java/net/momirealms/customcrops/integrations/protection/ResidenceHook.java @@ -20,10 +20,11 @@ package net.momirealms.customcrops.integrations.protection; import com.bekvon.bukkit.residence.containers.Flags; import com.bekvon.bukkit.residence.protection.ClaimedResidence; import com.bekvon.bukkit.residence.protection.ResidencePermissions; +import net.momirealms.customcrops.integrations.AntiGrief; import org.bukkit.Location; import org.bukkit.entity.Player; -public class ResidenceIntegration implements Integration { +public class ResidenceHook implements AntiGrief { @Override public boolean canBreak(Location location, Player player) { diff --git a/src/main/java/net/momirealms/customcrops/integrations/protection/TownyIntegration.java b/src/main/java/net/momirealms/customcrops/integrations/protection/TownyHook.java similarity index 93% rename from src/main/java/net/momirealms/customcrops/integrations/protection/TownyIntegration.java rename to src/main/java/net/momirealms/customcrops/integrations/protection/TownyHook.java index 8c512de..c82d0b1 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/protection/TownyIntegration.java +++ b/src/main/java/net/momirealms/customcrops/integrations/protection/TownyHook.java @@ -19,10 +19,11 @@ package net.momirealms.customcrops.integrations.protection; import com.palmergames.bukkit.towny.object.TownyPermission; import com.palmergames.bukkit.towny.utils.PlayerCacheUtil; +import net.momirealms.customcrops.integrations.AntiGrief; import org.bukkit.Location; import org.bukkit.entity.Player; -public class TownyIntegration implements Integration{ +public class TownyHook implements AntiGrief { @Override public boolean canBreak(Location location, Player player) { diff --git a/src/main/java/net/momirealms/customcrops/integrations/protection/WorldGuardIntegration.java b/src/main/java/net/momirealms/customcrops/integrations/protection/WorldGuardHook.java similarity index 96% rename from src/main/java/net/momirealms/customcrops/integrations/protection/WorldGuardIntegration.java rename to src/main/java/net/momirealms/customcrops/integrations/protection/WorldGuardHook.java index cc96624..3eadd6d 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/protection/WorldGuardIntegration.java +++ b/src/main/java/net/momirealms/customcrops/integrations/protection/WorldGuardHook.java @@ -27,10 +27,11 @@ import com.sk89q.worldguard.protection.flags.Flags; import com.sk89q.worldguard.protection.managers.RegionManager; import com.sk89q.worldguard.protection.regions.RegionContainer; import com.sk89q.worldguard.protection.regions.RegionQuery; +import net.momirealms.customcrops.integrations.AntiGrief; import org.bukkit.Location; import org.bukkit.entity.Player; -public class WorldGuardIntegration implements Integration { +public class WorldGuardHook implements AntiGrief { @Override public boolean canPlace(Location location, Player player) { diff --git a/src/main/java/net/momirealms/customcrops/integrations/season/CCSeason.java b/src/main/java/net/momirealms/customcrops/integrations/season/CCSeason.java new file mode 100644 index 0000000..c0d6ea6 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/season/CCSeason.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations.season; + +public enum CCSeason { + + SPRING, + SUMMER, + AUTUMN, + WINTER, + UNKNOWN + +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/season/InternalSeason.java b/src/main/java/net/momirealms/customcrops/integrations/season/InternalSeason.java new file mode 100644 index 0000000..99c6c27 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/season/InternalSeason.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations.season; + +import net.momirealms.customcrops.CustomCrops; +import net.momirealms.customcrops.Function; +import net.momirealms.customcrops.config.ConfigUtil; +import net.momirealms.customcrops.config.MainConfig; +import net.momirealms.customcrops.config.SeasonConfig; +import net.momirealms.customcrops.utils.AdventureUtil; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class InternalSeason extends Function implements SeasonInterface { + + private ConcurrentHashMap seasonHashMap; + private BukkitTask task; + private YamlConfiguration data; + + public InternalSeason() { + load(); + } + + @Override + public void load() { + super.load(); + this.seasonHashMap = new ConcurrentHashMap<>(); + this.data = ConfigUtil.readData(new File(CustomCrops.plugin.getDataFolder(), "data" + File.separator + "season.yml")); + for (String worldName : data.getKeys(false)) { + World world = Bukkit.getWorld(worldName); + if (world != null) { + if ((MainConfig.whiteOrBlack && MainConfig.worldList.contains(world)) || (!MainConfig.whiteOrBlack && !MainConfig.worldList.contains(world))) { + seasonHashMap.put(world, CCSeason.valueOf(data.getString(worldName,"SPRING").toUpperCase())); + } + } + } + if (SeasonConfig.auto) { + startTimer(); + } + } + + @Override + public void unload() { + super.unload(); + for (Map.Entry season : seasonHashMap.entrySet()) { + data.set(season.getKey().getName(), season.getValue().name()); + } + try { + data.save(new File(CustomCrops.plugin.getDataFolder(), "data" + File.separator + "season.yml")); + } + catch (IOException e) { + e.printStackTrace(); + AdventureUtil.consoleMessage("[CustomCrops] Error occurs when saving season data"); + } + this.seasonHashMap.clear(); + if (task != null) task.cancel(); + } + + @Override + public boolean isWrongSeason(World world, @Nullable CCSeason[] seasonList) { + if (seasonList == null) return false; + for (CCSeason season : seasonList) { + if (season == seasonHashMap.get(world)) { + return false; + } + } + return true; + } + + @Override + public void unloadWorld(World world) { + CCSeason season = seasonHashMap.remove(world); + if (season == null) return; + data.set(world.getName(), season.name()); + } + + @Override + @NotNull + public CCSeason getSeason(World world) { + CCSeason season = seasonHashMap.get(world); + if (season == null) { + season = countSeason(world); + setSeason(season, world); + } + return season; + } + + @Override + public void setSeason(CCSeason season, World world) { + seasonHashMap.put(world, season); + } + + private void startTimer() { + this.task = new BukkitRunnable() { + @Override + public void run() { + if (MainConfig.whiteOrBlack) { + for (World world : MainConfig.worlds) { + if (world.getTime() < 100) { + setSeason(countSeason(world), world); + } + } + } + else { + List worlds = new ArrayList<>(Bukkit.getWorlds()); + List blackWorlds = List.of(MainConfig.worlds); + worlds.removeAll(blackWorlds); + for (World world : worlds) { + if (world.getTime() < 100) { + setSeason(countSeason(world), world); + } + } + } + } + }.runTaskTimerAsynchronously(CustomCrops.plugin, 0, 100); + } + + private CCSeason countSeason(World world) { + int season = (int) ((world.getFullTime() / 24000L) % (SeasonConfig.duration * 4)) / SeasonConfig.duration; + return switch (season) { + case 0 -> CCSeason.SPRING; + case 1 -> CCSeason.SUMMER; + case 2 -> CCSeason.AUTUMN; + case 3 -> CCSeason.WINTER; + default -> CCSeason.UNKNOWN; + }; + } +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/season/RealisticSeasonsHook.java b/src/main/java/net/momirealms/customcrops/integrations/season/RealisticSeasonsHook.java new file mode 100644 index 0000000..cfb4fef --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/season/RealisticSeasonsHook.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations.season; + +import me.casperge.realisticseasons.api.SeasonsAPI; +import net.momirealms.customcrops.Function; +import org.bukkit.World; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class RealisticSeasonsHook extends Function implements SeasonInterface { + + private SeasonsAPI api; + + @Override + public void load() { + super.load(); + this.api = SeasonsAPI.getInstance(); + } + + @Override + public void unload() { + super.unload(); + } + + @Override + public boolean isWrongSeason(World world, @Nullable CCSeason[] seasonList) { + if (seasonList == null) return false; + for (CCSeason season : seasonList) { + if (season == getSeason(world)) { + return false; + } + } + return false; + } + + @Override + public void unloadWorld(World world) { + } + + /** + * Get the season from RealisticSeasons + * @param world world + * @return CustomCrops Season + */ + @Override + @NotNull + public CCSeason getSeason(World world){ + switch (api.getSeason(world)){ + case SPRING -> {return CCSeason.SPRING;} + case SUMMER -> {return CCSeason.SUMMER;} + case WINTER -> {return CCSeason.WINTER;} + case FALL -> {return CCSeason.AUTUMN;} + } + return CCSeason.UNKNOWN; + } + + /** + * Set season for RealisticSeasons + * @param season season + * @param world world + */ + @Override + public void setSeason(CCSeason season, World world) { + me.casperge.realisticseasons.season.Season rsSeason = switch (season) { + case SPRING -> me.casperge.realisticseasons.season.Season.SPRING; + case SUMMER -> me.casperge.realisticseasons.season.Season.SUMMER; + case AUTUMN -> me.casperge.realisticseasons.season.Season.FALL; + case WINTER -> me.casperge.realisticseasons.season.Season.WINTER; + default -> throw new IllegalStateException("Unexpected value: " + season); + }; + api.setSeason(world, rsSeason); + } +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/integrations/season/SeasonInterface.java b/src/main/java/net/momirealms/customcrops/integrations/season/SeasonInterface.java new file mode 100644 index 0000000..a86b818 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/integrations/season/SeasonInterface.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.integrations.season; + +import org.bukkit.World; + +public interface SeasonInterface { + + CCSeason getSeason(World world); + + void setSeason(CCSeason season, World world); + + void load(); + + void unload(); + + boolean isWrongSeason(World world, CCSeason[] seasonList); + + void unloadWorld(World world); + +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/skill/AureliumIntegration.java b/src/main/java/net/momirealms/customcrops/integrations/skill/AureliumsHook.java similarity index 92% rename from src/main/java/net/momirealms/customcrops/integrations/skill/AureliumIntegration.java rename to src/main/java/net/momirealms/customcrops/integrations/skill/AureliumsHook.java index 061bf49..920a915 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/skill/AureliumIntegration.java +++ b/src/main/java/net/momirealms/customcrops/integrations/skill/AureliumsHook.java @@ -20,9 +20,10 @@ package net.momirealms.customcrops.integrations.skill; import com.archyx.aureliumskills.api.AureliumAPI; import com.archyx.aureliumskills.leveler.Leveler; import com.archyx.aureliumskills.skills.Skill; +import net.momirealms.customcrops.integrations.SkillXP; import org.bukkit.entity.Player; -public class AureliumIntegration implements SkillXP { +public class AureliumsHook implements SkillXP { private static final Leveler leveler = AureliumAPI.getPlugin().getLeveler(); private static final Skill skill = AureliumAPI.getPlugin().getSkillRegistry().getSkill("farming"); diff --git a/src/main/java/net/momirealms/customcrops/integrations/skill/EcoSkillsIntegration.java b/src/main/java/net/momirealms/customcrops/integrations/skill/EcoSkillsHook.java similarity index 90% rename from src/main/java/net/momirealms/customcrops/integrations/skill/EcoSkillsIntegration.java rename to src/main/java/net/momirealms/customcrops/integrations/skill/EcoSkillsHook.java index 3f9c1e6..f8fbfcd 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/skill/EcoSkillsIntegration.java +++ b/src/main/java/net/momirealms/customcrops/integrations/skill/EcoSkillsHook.java @@ -19,9 +19,10 @@ package net.momirealms.customcrops.integrations.skill; import com.willfp.ecoskills.api.EcoSkillsAPI; import com.willfp.ecoskills.skills.Skills; +import net.momirealms.customcrops.integrations.SkillXP; import org.bukkit.entity.Player; -public class EcoSkillsIntegration implements SkillXP{ +public class EcoSkillsHook implements SkillXP { @Override public void addXp(Player player, double amount) { diff --git a/src/main/java/net/momirealms/customcrops/integrations/skill/JobsRebornIntegration.java b/src/main/java/net/momirealms/customcrops/integrations/skill/JobsRebornHook.java similarity index 93% rename from src/main/java/net/momirealms/customcrops/integrations/skill/JobsRebornIntegration.java rename to src/main/java/net/momirealms/customcrops/integrations/skill/JobsRebornHook.java index 8f12059..0492ff9 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/skill/JobsRebornIntegration.java +++ b/src/main/java/net/momirealms/customcrops/integrations/skill/JobsRebornHook.java @@ -21,11 +21,12 @@ import com.gamingmesh.jobs.Jobs; import com.gamingmesh.jobs.container.Job; import com.gamingmesh.jobs.container.JobProgression; import com.gamingmesh.jobs.container.JobsPlayer; +import net.momirealms.customcrops.integrations.SkillXP; import org.bukkit.entity.Player; import java.util.List; -public class JobsRebornIntegration implements SkillXP{ +public class JobsRebornHook implements SkillXP { @Override public void addXp(Player player, double amount) { diff --git a/src/main/java/net/momirealms/customcrops/integrations/skill/MMOCoreIntegration.java b/src/main/java/net/momirealms/customcrops/integrations/skill/MMOCoreHook.java similarity index 92% rename from src/main/java/net/momirealms/customcrops/integrations/skill/MMOCoreIntegration.java rename to src/main/java/net/momirealms/customcrops/integrations/skill/MMOCoreHook.java index 29294d2..d4b6701 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/skill/MMOCoreIntegration.java +++ b/src/main/java/net/momirealms/customcrops/integrations/skill/MMOCoreHook.java @@ -19,9 +19,10 @@ package net.momirealms.customcrops.integrations.skill; import net.Indyuce.mmocore.experience.EXPSource; import net.Indyuce.mmocore.experience.Profession; +import net.momirealms.customcrops.integrations.SkillXP; import org.bukkit.entity.Player; -public class MMOCoreIntegration implements SkillXP{ +public class MMOCoreHook implements SkillXP { @Override public void addXp(Player player, double amount) { Profession profession = net.Indyuce.mmocore.MMOCore.plugin.professionManager.get("farming"); diff --git a/src/main/java/net/momirealms/customcrops/integrations/skill/mcMMOIntegration.java b/src/main/java/net/momirealms/customcrops/integrations/skill/mcMMOHook.java similarity index 90% rename from src/main/java/net/momirealms/customcrops/integrations/skill/mcMMOIntegration.java rename to src/main/java/net/momirealms/customcrops/integrations/skill/mcMMOHook.java index ffbfa59..9036c1b 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/skill/mcMMOIntegration.java +++ b/src/main/java/net/momirealms/customcrops/integrations/skill/mcMMOHook.java @@ -18,9 +18,10 @@ package net.momirealms.customcrops.integrations.skill; import com.gmail.nossr50.api.ExperienceAPI; +import net.momirealms.customcrops.integrations.SkillXP; import org.bukkit.entity.Player; -public class mcMMOIntegration implements SkillXP { +public class mcMMOHook implements SkillXP { @Override public void addXp(Player player, double amount) { diff --git a/src/main/java/net/momirealms/customcrops/limits/CropsPerChunk.java b/src/main/java/net/momirealms/customcrops/limits/CropsPerChunk.java deleted file mode 100644 index 2b03775..0000000 --- a/src/main/java/net/momirealms/customcrops/limits/CropsPerChunk.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.limits; - -import dev.lone.itemsadder.api.CustomBlock; -import net.momirealms.customcrops.ConfigReader; -import org.bukkit.Location; - -public class CropsPerChunk { - - public static boolean isLimited(Location location){ - if (!ConfigReader.Config.enableLimit) return false; - int n = 1; - Location chunkLocation = new Location(location.getWorld(),location.getChunk().getX()*16,ConfigReader.Config.yMin,location.getChunk().getZ()*16); - Label_out: - for (int i = 0; i < 16; ++i) - for (int j = 0; j < 16; ++j) { - Location square = chunkLocation.clone().add(i, 0.0, j); - for (int k = ConfigReader.Config.yMin; k <= ConfigReader.Config.yMax; ++k) { - square.add(0.0, 1.0, 0.0); - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(square.getBlock()); - if(customBlock != null) - if (customBlock.getNamespacedID().contains("_stage_")) - if (n++ > ConfigReader.Config.cropLimit) - break Label_out; - } - } - return n > ConfigReader.Config.cropLimit; - } -} diff --git a/src/main/java/net/momirealms/customcrops/limits/CropsPerChunkEntity.java b/src/main/java/net/momirealms/customcrops/limits/CropsPerChunkEntity.java deleted file mode 100644 index b2e7515..0000000 --- a/src/main/java/net/momirealms/customcrops/limits/CropsPerChunkEntity.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.limits; - -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.utils.FurnitureUtil; -import org.bukkit.Location; - -public class CropsPerChunkEntity { - - public static boolean isLimited(Location location){ - if (!ConfigReader.Config.enableLimit) return false; - int n = 1; - Location chunkLocation = new Location(location.getWorld(),location.getChunk().getX()*16+0.5,ConfigReader.Config.yMin+0.1,location.getChunk().getZ()*16+0.5); - Label_out: - for (int i = 0; i < 16; ++i) - for (int j = 0; j < 16; ++j) { - Location square = chunkLocation.clone().add(i, 0, j); - for (int k = ConfigReader.Config.yMin; k <= ConfigReader.Config.yMax; ++k) { - square.add(0.0, 1.0, 0.0); - String namespacedID = FurnitureUtil.getNamespacedID(square); - if(namespacedID != null && namespacedID.contains("_stage_")){ - if (n++ > ConfigReader.Config.cropLimit) - break Label_out; - } - } - } - return n > ConfigReader.Config.cropLimit; - } -} diff --git a/src/main/java/net/momirealms/customcrops/limits/SprinklersPerChunk.java b/src/main/java/net/momirealms/customcrops/limits/SprinklersPerChunk.java deleted file mode 100644 index cbf6e61..0000000 --- a/src/main/java/net/momirealms/customcrops/limits/SprinklersPerChunk.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.limits; - -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.utils.FurnitureUtil; -import org.bukkit.Location; - -public class SprinklersPerChunk { - - public static boolean isLimited(Location location){ - if (!ConfigReader.Config.enableLimit) return false; - int n = 1; - Location chunkLocation = new Location(location.getWorld(),location.getChunk().getX()*16, ConfigReader.Config.yMin,location.getChunk().getZ()*16); - Label_out: - for (int i = 0; i < 16; ++i) - for (int j = 0; j < 16; ++j) { - Location square = chunkLocation.clone().add(i + 0.5, 0.5, j + 0.5); - for (int k = ConfigReader.Config.yMin; k <= ConfigReader.Config.yMax; ++k) { - square.add(0.0, 1.0, 0.0); - if(FurnitureUtil.isSprinkler(square)) - if (n++ > ConfigReader.Config.sprinklerLimit) - break Label_out; - } - } - return n > ConfigReader.Config.sprinklerLimit; - } -} diff --git a/src/main/java/net/momirealms/customcrops/listener/JoinAndQuit.java b/src/main/java/net/momirealms/customcrops/listener/JoinAndQuit.java deleted file mode 100644 index b886f7b..0000000 --- a/src/main/java/net/momirealms/customcrops/listener/JoinAndQuit.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.listener; - -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.utils.JedisUtil; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; - -import java.util.HashMap; -import java.util.HashSet; - -public class JoinAndQuit implements Listener { - - public static HashSet onlinePlayers = new HashSet<>(); - public static HashMap coolDown = new HashMap<>(); - - @EventHandler - public void onJoin(PlayerJoinEvent event){ - if (ConfigReader.useRedis) JedisUtil.addPlayer(event.getPlayer().getName()); - else onlinePlayers.add(event.getPlayer().getName()); - } - - @EventHandler - public void onQuit(PlayerQuitEvent event){ - if (ConfigReader.useRedis) JedisUtil.remPlayer(event.getPlayer().getName()); - else onlinePlayers.remove(event.getPlayer().getName()); - coolDown.remove(event.getPlayer()); - } -} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/listener/itemframe/BreakBlockI.java b/src/main/java/net/momirealms/customcrops/listener/itemframe/BreakBlockI.java deleted file mode 100644 index d882a65..0000000 --- a/src/main/java/net/momirealms/customcrops/listener/itemframe/BreakBlockI.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.listener.itemframe; - -import dev.lone.itemsadder.api.CustomFurniture; -import dev.lone.itemsadder.api.CustomStack; -import dev.lone.itemsadder.api.Events.CustomBlockBreakEvent; -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.datamanager.CropManager; -import net.momirealms.customcrops.datamanager.PotManager; -import net.momirealms.customcrops.objects.fertilizer.Fertilizer; -import net.momirealms.customcrops.objects.fertilizer.QualityCrop; -import net.momirealms.customcrops.integrations.protection.Integration; -import net.momirealms.customcrops.objects.Crop; -import net.momirealms.customcrops.objects.SimpleLocation; -import net.momirealms.customcrops.utils.DropUtil; -import net.momirealms.customcrops.utils.FurnitureUtil; -import net.momirealms.customcrops.utils.LocUtil; -import org.apache.commons.lang.StringUtils; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; - -import java.util.concurrent.ThreadLocalRandom; - -public class BreakBlockI implements Listener { - - @EventHandler - public void onBreak(CustomBlockBreakEvent event){ - if (event.isCancelled()) return; - String namespacedId = event.getNamespacedID(); - if(namespacedId.equalsIgnoreCase(ConfigReader.Basic.watered_pot) || namespacedId.equalsIgnoreCase(ConfigReader.Basic.pot)){ - Location location = event.getBlock().getLocation(); - PotManager.Cache.remove(LocUtil.fromLocation(location)); - World world = location.getWorld(); - for (Integration integration : ConfigReader.Config.integration) - if(!integration.canBreak(location, event.getPlayer())) return; - CustomFurniture furniture = FurnitureUtil.getFurniture(location.add(0.5,1.1,0.5)); - if(furniture != null){ - String nsID = furniture.getNamespacedID(); - if(nsID.contains("_stage_")){ - SimpleLocation simpleLocation = LocUtil.fromLocation(location); - if (CropManager.Cache.remove(simpleLocation) == null){ - CropManager.RemoveCache.add(simpleLocation); - } - CustomFurniture.remove(furniture.getArmorstand(), false); - if (nsID.equals(ConfigReader.Basic.dead)) return; - if (ConfigReader.Config.quality){ - String[] cropNameList = StringUtils.split(StringUtils.split(nsID, ":")[1], "_"); - int nextStage = Integer.parseInt(cropNameList[2]) + 1; - if (CustomFurniture.getInstance(StringUtils.chop(nsID) + nextStage) == null) { - Crop cropInstance = ConfigReader.CROPS.get(cropNameList[0]); - ThreadLocalRandom current = ThreadLocalRandom.current(); - int random = current.nextInt(cropInstance.getMin(), cropInstance.getMax() + 1); - Location itemLoc = location.clone().add(0.5,0.2,0.5); - Fertilizer fertilizer = PotManager.Cache.get(LocUtil.fromLocation(location.clone().subtract(0,1,0))); - if (fertilizer != null){ - if (fertilizer instanceof QualityCrop qualityCrop){ - int[] weights = qualityCrop.getChance(); - double weightTotal = weights[0] + weights[1] + weights[2]; - for (int i = 0; i < random; i++){ - double ran = Math.random(); - if (ran < weights[0]/(weightTotal)) world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_1()).getItemStack()); - else if(ran > 1 - weights[1]/(weightTotal)) world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_2()).getItemStack()); - else world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_3()).getItemStack()); - } - } - } - else DropUtil.normalDrop(cropInstance, random, itemLoc, world); - } - } - } - } - } - } -} diff --git a/src/main/java/net/momirealms/customcrops/listener/itemframe/BreakFurnitureI.java b/src/main/java/net/momirealms/customcrops/listener/itemframe/BreakFurnitureI.java deleted file mode 100644 index d6271dc..0000000 --- a/src/main/java/net/momirealms/customcrops/listener/itemframe/BreakFurnitureI.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.listener.itemframe; - -import dev.lone.itemsadder.api.CustomFurniture; -import dev.lone.itemsadder.api.CustomStack; -import dev.lone.itemsadder.api.Events.FurnitureBreakEvent; -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.datamanager.CropManager; -import net.momirealms.customcrops.datamanager.PotManager; -import net.momirealms.customcrops.datamanager.SprinklerManager; -import net.momirealms.customcrops.objects.fertilizer.Fertilizer; -import net.momirealms.customcrops.objects.fertilizer.QualityCrop; -import net.momirealms.customcrops.integrations.protection.Integration; -import net.momirealms.customcrops.objects.Crop; -import net.momirealms.customcrops.objects.SimpleLocation; -import net.momirealms.customcrops.objects.Sprinkler; -import net.momirealms.customcrops.objects.fertilizer.YieldIncreasing; -import net.momirealms.customcrops.utils.DropUtil; -import net.momirealms.customcrops.utils.LocUtil; -import org.apache.commons.lang.StringUtils; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; - -import java.util.List; -import java.util.concurrent.ThreadLocalRandom; - -public class BreakFurnitureI implements Listener { - - @EventHandler - public void onBreakFurniture(FurnitureBreakEvent event){ - if (event.isCancelled()) return; - String namespacedID = event.getNamespacedID(); - Sprinkler config = ConfigReader.SPRINKLERS.get(namespacedID); - if (config != null){ - SimpleLocation simpleLocation = LocUtil.fromLocation(event.getBukkitEntity().getLocation()); - if (SprinklerManager.Cache.remove(simpleLocation) == null){ - SprinklerManager.RemoveCache.add(simpleLocation); - } - return; - } - if (namespacedID.contains("_stage_")){ - Player player = event.getPlayer(); - Location location = event.getBukkitEntity().getLocation(); - for (Integration integration : ConfigReader.Config.integration) - if(!integration.canBreak(location, player)) return; - SimpleLocation simpleLocation = LocUtil.fromLocation(location); - if (CropManager.Cache.remove(simpleLocation) == null){ - CropManager.RemoveCache.add(simpleLocation); - } - if (!ConfigReader.Config.quality || namespacedID.equals(ConfigReader.Basic.dead)) return; - String[] cropNameList = StringUtils.split(StringUtils.split(namespacedID, ":")[1], "_"); - int nextStage = Integer.parseInt(cropNameList[2]) + 1; - if (CustomFurniture.getInstance(StringUtils.chop(namespacedID) + nextStage) == null) { - Crop cropInstance = ConfigReader.CROPS.get(cropNameList[0]); - ThreadLocalRandom current = ThreadLocalRandom.current(); - int random = current.nextInt(cropInstance.getMin(), cropInstance.getMax() + 1); - Location itemLoc = location.clone().add(0,0.2,0); - World world = location.getWorld(); - List commands = cropInstance.getCommands(); - Fertilizer fertilizer = PotManager.Cache.get(LocUtil.fromLocation(location.clone().subtract(0,1,0))); - if (commands != null) - for (String command : commands) - Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), command.replace("{player}", player.getName())); - if (ConfigReader.Config.skillXP != null && cropInstance.getSkillXP() != 0) ConfigReader.Config.skillXP.addXp(player, cropInstance.getSkillXP()); - if (fertilizer != null){ - if (fertilizer instanceof QualityCrop qualityCrop){ - int[] weights = qualityCrop.getChance(); - double weightTotal = weights[0] + weights[1] + weights[2]; - for (int i = 0; i < random; i++){ - double ran = Math.random(); - if (ran < weights[0]/(weightTotal)) world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_1()).getItemStack()); - else if(ran > 1 - weights[1]/(weightTotal)) world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_2()).getItemStack()); - else world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_3()).getItemStack()); - } - }else if (fertilizer instanceof YieldIncreasing yieldIncreasing){ - if (Math.random() < yieldIncreasing.getChance()){ - random += yieldIncreasing.getBonus(); - } - DropUtil.normalDrop(cropInstance, random , itemLoc, world); - } - else DropUtil.normalDrop(cropInstance, random, itemLoc, world); - } - else DropUtil.normalDrop(cropInstance, random, itemLoc, world); - } - } - } -} diff --git a/src/main/java/net/momirealms/customcrops/listener/itemframe/InteractFurnitureI.java b/src/main/java/net/momirealms/customcrops/listener/itemframe/InteractFurnitureI.java deleted file mode 100644 index 69f98c0..0000000 --- a/src/main/java/net/momirealms/customcrops/listener/itemframe/InteractFurnitureI.java +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.listener.itemframe; - -import de.tr7zw.changeme.nbtapi.NBTCompound; -import de.tr7zw.changeme.nbtapi.NBTItem; -import dev.lone.itemsadder.api.CustomFurniture; -import dev.lone.itemsadder.api.CustomStack; -import dev.lone.itemsadder.api.Events.FurnitureInteractEvent; -import net.kyori.adventure.key.Key; -import net.kyori.adventure.sound.Sound; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.datamanager.CropManager; -import net.momirealms.customcrops.datamanager.PotManager; -import net.momirealms.customcrops.datamanager.SprinklerManager; -import net.momirealms.customcrops.objects.fertilizer.Fertilizer; -import net.momirealms.customcrops.objects.fertilizer.QualityCrop; -import net.momirealms.customcrops.integrations.protection.Integration; -import net.momirealms.customcrops.listener.JoinAndQuit; -import net.momirealms.customcrops.objects.Crop; -import net.momirealms.customcrops.objects.SimpleLocation; -import net.momirealms.customcrops.objects.Sprinkler; -import net.momirealms.customcrops.objects.WateringCan; -import net.momirealms.customcrops.objects.fertilizer.YieldIncreasing; -import net.momirealms.customcrops.utils.*; -import org.apache.commons.lang.StringUtils; -import org.bukkit.*; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.Damageable; - -import java.util.List; -import java.util.Objects; -import java.util.concurrent.ThreadLocalRandom; - -public class InteractFurnitureI implements Listener { - - @EventHandler - public void onEntityInteract(FurnitureInteractEvent event){ - if (event.isCancelled()) return; - long time = System.currentTimeMillis(); - Player player = event.getPlayer(); - if (time - (JoinAndQuit.coolDown.getOrDefault(player, time - 200)) < 200) return; - JoinAndQuit.coolDown.put(player, time); - String namespacedID = event.getNamespacedID(); - Sprinkler config = ConfigReader.SPRINKLERS.get(namespacedID); - if(config != null){ - ItemStack itemStack = player.getInventory().getItemInMainHand(); - Location location = event.getBukkitEntity().getLocation(); - String world = location.getWorld().getName(); - int x = location.getBlockX(); - int z = location.getBlockZ(); - int maxWater = config.getWater(); - int currentWater = 0; - Location loc = location.clone().subtract(0,1,0).getBlock().getLocation().add(0,1,0); - Sprinkler sprinkler = SprinklerManager.Cache.get(LocUtil.fromLocation(loc)); - if (itemStack.getType() == Material.WATER_BUCKET){ - itemStack.setType(Material.BUCKET); - if (sprinkler != null){ - currentWater = sprinkler.getWater(); - currentWater += ConfigReader.Config.sprinklerRefill; - if (currentWater > maxWater) currentWater = maxWater; - sprinkler.setWater(currentWater); - }else { - String path = world + "." + x / 16 + "," + z / 16 + "." + x + "," + location.getBlockY() + "," + z; - currentWater = SprinklerManager.data.getInt(path+ ".water"); - currentWater += ConfigReader.Config.sprinklerRefill; - if (currentWater > maxWater) currentWater = maxWater; - SprinklerManager.data.set(path + ".water", currentWater); - SprinklerManager.data.set(path + ".range", config.getRange()); - } - AdventureManager.playerSound(player, ConfigReader.Sounds.addWaterToSprinklerSource, ConfigReader.Sounds.addWaterToSprinklerKey); - } - else { - if (ConfigReader.Config.canAddWater && itemStack.getType() != Material.AIR){ - NBTItem nbtItem = new NBTItem(itemStack); - NBTCompound nbtCompound = nbtItem.getCompound("itemsadder"); - if (nbtCompound != null) { - String id = nbtCompound.getString("id"); - String namespace = nbtCompound.getString("namespace"); - WateringCan wateringCan = ConfigReader.CANS.get(namespace + ":" + id); - if (wateringCan != null) { - int water = nbtItem.getInteger("WaterAmount"); - if (water > 0){ - nbtItem.setInteger("WaterAmount", --water); - AdventureManager.playerSound(player, ConfigReader.Sounds.addWaterToSprinklerSource, ConfigReader.Sounds.addWaterToSprinklerKey); - if (nbtCompound.hasKey("custom_durability")){ - int dur = nbtCompound.getInteger("custom_durability"); - int max_dur = nbtCompound.getInteger("max_custom_durability"); - if (dur > 0){ - nbtCompound.setInteger("custom_durability", dur - 1); - nbtCompound.setDouble("fake_durability", (int) itemStack.getType().getMaxDurability() * (double) (dur/max_dur)); - nbtItem.setInteger("Damage", (int) (itemStack.getType().getMaxDurability() * (1 - (double) dur/max_dur))); - } else { - AdventureManager.playerSound(player, net.kyori.adventure.sound.Sound.Source.PLAYER, Key.key("minecraft:item.shield.break")); - itemStack.setAmount(itemStack.getAmount() - 1); - } - } - if (sprinkler != null){ - currentWater = sprinkler.getWater(); - currentWater++; - if (currentWater > maxWater) currentWater = maxWater; - sprinkler.setWater(currentWater); - }else { - String path = world + "." + x / 16 + "," + z / 16 + "." + x + "," + location.getBlockY() + "," + z; - currentWater = SprinklerManager.data.getInt(path + ".water"); - currentWater++; - if (currentWater > maxWater) currentWater = maxWater; - SprinklerManager.data.set(path + ".water", currentWater); - SprinklerManager.data.set(path + ".range", config.getRange()); - } - } - else { - currentWater = SprinklerManager.getCurrentWater(location, world, x, z, sprinkler); - } - if (ConfigReader.Message.hasWaterInfo){ - AdventureManager.playerActionbar(player, - (ConfigReader.Message.waterLeft + - ConfigReader.Message.waterFull.repeat(water) + - ConfigReader.Message.waterEmpty.repeat(wateringCan.getMax() - water) + - ConfigReader.Message.waterRight) - .replace("{max_water}", String.valueOf(wateringCan.getMax())) - .replace("{water}", String.valueOf(water))); - } - if (ConfigReader.Basic.hasWaterLore){ - String string = - (ConfigReader.Basic.waterLeft + - ConfigReader.Basic.waterFull.repeat(water) + - ConfigReader.Basic.waterEmpty.repeat(wateringCan.getMax() - water) + - ConfigReader.Basic.waterRight) - .replace("{max_water}", String.valueOf(wateringCan.getMax())) - .replace("{water}", String.valueOf(water)); - List lores = nbtItem.getCompound("display").getStringList("Lore"); - lores.clear(); - ConfigReader.Basic.waterLore.forEach(lore -> lores.add(GsonComponentSerializer.gson().serialize(MiniMessage.miniMessage().deserialize(lore.replace("{water_info}", string))))); - } - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); - } - } - else currentWater = SprinklerManager.getCurrentWater(location, world, x, z, sprinkler); - } - else currentWater = SprinklerManager.getCurrentWater(location, world, x, z, sprinkler); - } - if (ConfigReader.Message.hasSprinklerInfo) - HoloUtil.showHolo( - (ConfigReader.Message.sprinklerLeft + - ConfigReader.Message.sprinklerFull.repeat(currentWater) + - ConfigReader.Message.sprinklerEmpty.repeat(maxWater - currentWater) + - ConfigReader.Message.sprinklerRight) - .replace("{max_water}", String.valueOf(maxWater)) - .replace("{water}", String.valueOf(currentWater)), - player, - location.add(0, ConfigReader.Message.sprinklerOffset,0), - ConfigReader.Message.sprinklerTime); - } - if (namespacedID.contains("_stage_")){ - ItemStack itemStack = player.getInventory().getItemInMainHand(); - if (itemStack.getType() != Material.AIR){ - NBTItem nbtItem = new NBTItem(itemStack); - NBTCompound nbtCompound = nbtItem.getCompound("itemsadder"); - if (nbtCompound != null){ - Location location = event.getBukkitEntity().getLocation(); - for (Integration integration : ConfigReader.Config.integration) - if(!integration.canPlace(location, player)) return; - String id = nbtCompound.getString("id"); - String namespace = nbtCompound.getString("namespace"); - String nsID = namespace + ":" +id; - WateringCan wateringCan = ConfigReader.CANS.get(nsID); - if (wateringCan != null){ - int water = nbtItem.getInteger("WaterAmount"); - if (water > 0){ - nbtItem.setInteger("WaterAmount", --water); - if (nbtCompound.hasKey("custom_durability")){ - int dur = nbtCompound.getInteger("custom_durability"); - int max_dur = nbtCompound.getInteger("max_custom_durability"); - if (dur > 0){ - nbtCompound.setInteger("custom_durability", dur - 1); - nbtCompound.setDouble("fake_durability", (int) itemStack.getType().getMaxDurability() * (double) (dur/max_dur)); - nbtItem.setInteger("Damage", (int) (itemStack.getType().getMaxDurability() * (1 - (double) dur/max_dur))); - } else { - AdventureManager.playerSound(player, net.kyori.adventure.sound.Sound.Source.PLAYER, Key.key("minecraft:item.shield.break")); - itemStack.setAmount(itemStack.getAmount() - 1); - } - } - AdventureManager.playerSound(player, ConfigReader.Sounds.waterPotSource, ConfigReader.Sounds.waterPotKey); - PotUtil.waterPot(wateringCan.getWidth(), wateringCan.getLength(), location.subtract(0.5,1,0.5), player.getLocation().getYaw()); - } - if (ConfigReader.Message.hasWaterInfo) - AdventureManager.playerActionbar(player, - (ConfigReader.Message.waterLeft + - ConfigReader.Message.waterFull.repeat(water) + - ConfigReader.Message.waterEmpty.repeat(wateringCan.getMax() - water) + - ConfigReader.Message.waterRight) - .replace("{max_water}", String.valueOf(wateringCan.getMax())) - .replace("{water}", String.valueOf(water))); - if (ConfigReader.Basic.hasWaterLore){ - List lores = nbtItem.getCompound("display").getStringList("Lore"); - lores.clear(); - String string = - (ConfigReader.Basic.waterLeft + - ConfigReader.Basic.waterFull.repeat(water) + - ConfigReader.Basic.waterEmpty.repeat(wateringCan.getMax() - water) + - ConfigReader.Basic.waterRight) - .replace("{max_water}", String.valueOf(wateringCan.getMax())) - .replace("{water}", String.valueOf(water)); - ConfigReader.Basic.waterLore.forEach(lore -> lores.add(GsonComponentSerializer.gson().serialize(MiniMessage.miniMessage().deserialize(lore.replace("{water_info}", string))))); - } - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); - return; - } - Fertilizer fertilizerConfig = ConfigReader.FERTILIZERS.get(id); - if (fertilizerConfig != null){ - if (!fertilizerConfig.isBefore()){ - if (player.getGameMode() != GameMode.CREATIVE) itemStack.setAmount(itemStack.getAmount() - 1); - PotUtil.addFertilizer(fertilizerConfig, event.getBukkitEntity().getLocation().subtract(0,1,0)); - AdventureManager.playerSound(player, ConfigReader.Sounds.useFertilizerSource, ConfigReader.Sounds.useFertilizerKey); - }else { - AdventureManager.playerMessage(player, ConfigReader.Message.prefix + ConfigReader.Message.beforePlant); - } - return; - } - if (ConfigReader.Message.hasCropInfo && nsID.equals(ConfigReader.Basic.soilDetector)){ - Fertilizer fertilizer = PotManager.Cache.get(LocUtil.fromLocation(location.subtract(0,1,0))); - if (fertilizer != null){ - Fertilizer fConfig = ConfigReader.FERTILIZERS.get(fertilizer.getKey()); - if (fConfig == null) { - PotManager.Cache.remove(LocUtil.fromLocation(location)); - return; - } - HoloUtil.showHolo( - ConfigReader.Message.cropText - .replace("{fertilizer}", fConfig.getName()) - .replace("{times}", String.valueOf(fertilizer.getTimes())) - .replace("{max_times}", String.valueOf(fConfig.getTimes())), - player, - location.add(0, ConfigReader.Message.cropOffset, 0), - ConfigReader.Message.cropTime); - } - } - } - else if (ConfigReader.Config.boneMeal && itemStack.getType() == Material.BONE_MEAL){ - Entity entity = event.getBukkitEntity(); - Location location = entity.getLocation(); - for (Integration integration : ConfigReader.Config.integration) - if(!integration.canPlace(location, player)) return; - if (!namespacedID.equals(ConfigReader.Basic.dead)){ - int nextStage = Integer.parseInt(namespacedID.substring(namespacedID.length()-1)) + 1; - String next = StringUtils.chop(namespacedID) + nextStage; - if (CustomFurniture.getInstance(next) != null){ - if (player.getGameMode() != GameMode.CREATIVE) itemStack.setAmount(itemStack.getAmount() - 1); - AdventureManager.playerSound(player, ConfigReader.Sounds.boneMealSource, ConfigReader.Sounds.boneMealKey); - if (Math.random() < ConfigReader.Config.boneMealChance){ - CustomFurniture.remove(entity, false); - FurnitureUtil.placeCrop(next, location); - location.getWorld().spawnParticle(ConfigReader.Config.boneMealSuccess, location.add(0,0.3,0),5,0.2,0.2,0.2); - } - } - } - } - else if(ConfigReader.Config.rightClickHarvest && !ConfigReader.Config.needEmptyHand){ - rightClickHarvest(event.getFurniture(), player); - } - } - else if(ConfigReader.Config.rightClickHarvest && !Objects.equals(ConfigReader.Basic.dead, namespacedID)){ - rightClickHarvest(event.getFurniture(), player); - } - } - } - - - - /** - * 右键收获判定 - * @param crop 农作物实体 - * @param player 玩家 - */ - private void rightClickHarvest(CustomFurniture crop, Player player) { - Entity entity = crop.getArmorstand(); - Location location = entity.getLocation(); - for (Integration integration : ConfigReader.Config.integration) - if(!integration.canBreak(location, player)) return; - String namespacedID = crop.getNamespacedID(); - String[] cropNameList = StringUtils.split(namespacedID, "_"); - int nextStage = Integer.parseInt(cropNameList[2]) + 1; - if (CustomFurniture.getInstance(StringUtils.chop(namespacedID) + nextStage) == null) { - CustomFurniture.remove(entity, false); - Crop cropInstance = ConfigReader.CROPS.get(StringUtils.split(cropNameList[0], ":")[1]); - if (ConfigReader.Config.quality){ - ThreadLocalRandom current = ThreadLocalRandom.current(); - int random = current.nextInt(cropInstance.getMin(), cropInstance.getMax() + 1); - World world = location.getWorld(); - Location itemLoc = location.clone().add(0,0.2,0); - Fertilizer fertilizer = PotManager.Cache.get(LocUtil.fromLocation(location.clone().subtract(0,1,0))); - List commands = cropInstance.getCommands(); - if (commands != null) - for (String command : commands) - Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), command.replace("{player}", player.getName())); - if (ConfigReader.Config.skillXP != null && cropInstance.getSkillXP() != 0) ConfigReader.Config.skillXP.addXp(player, cropInstance.getSkillXP()); - if (cropInstance.getOtherLoots() != null) cropInstance.getOtherLoots().forEach(s -> location.getWorld().dropItem(itemLoc, CustomStack.getInstance(s).getItemStack())); - if (fertilizer != null){ - Fertilizer fConfig = ConfigReader.FERTILIZERS.get(fertilizer.getKey()); - if (fConfig == null) return; - if (fConfig instanceof QualityCrop qualityCrop){ - int[] weights = qualityCrop.getChance(); - double weightTotal = weights[0] + weights[1] + weights[2]; - for (int i = 0; i < random; i++){ - double ran = Math.random(); - if (ran < weights[0]/(weightTotal)) world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_1()).getItemStack()); - else if(ran > 1 - weights[1]/(weightTotal)) world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_2()).getItemStack()); - else world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_3()).getItemStack()); - } - }else if (fConfig instanceof YieldIncreasing yieldIncreasing){ - if (Math.random() < yieldIncreasing.getChance()){ - random += yieldIncreasing.getBonus(); - } - DropUtil.normalDrop(cropInstance, random , itemLoc, world); - } - else DropUtil.normalDrop(cropInstance, random, itemLoc, world); - } - else DropUtil.normalDrop(cropInstance, random, itemLoc, world); - } - AdventureManager.playerSound(player, ConfigReader.Sounds.harvestSource, ConfigReader.Sounds.harvestKey); - if(cropInstance.getReturnStage() != null){ - FurnitureUtil.placeCrop(cropInstance.getReturnStage(), location); - SimpleLocation simpleLocation = LocUtil.fromLocation(location); - CropManager.RemoveCache.remove(simpleLocation); - CropManager.Cache.put(simpleLocation, player.getName()); - } - } - } -} diff --git a/src/main/java/net/momirealms/customcrops/listener/itemframe/RightClickI.java b/src/main/java/net/momirealms/customcrops/listener/itemframe/RightClickI.java deleted file mode 100644 index 83d69ce..0000000 --- a/src/main/java/net/momirealms/customcrops/listener/itemframe/RightClickI.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.listener.itemframe; - -import de.tr7zw.changeme.nbtapi.NBTCompound; -import de.tr7zw.changeme.nbtapi.NBTItem; -import dev.lone.itemsadder.api.CustomBlock; -import net.kyori.adventure.key.Key; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.datamanager.CropManager; -import net.momirealms.customcrops.datamanager.PotManager; -import net.momirealms.customcrops.datamanager.SeasonManager; -import net.momirealms.customcrops.datamanager.SprinklerManager; -import net.momirealms.customcrops.objects.fertilizer.Fertilizer; -import net.momirealms.customcrops.integrations.protection.Integration; -import net.momirealms.customcrops.limits.CropsPerChunkEntity; -import net.momirealms.customcrops.limits.SprinklersPerChunk; -import net.momirealms.customcrops.listener.JoinAndQuit; -import net.momirealms.customcrops.objects.Crop; -import net.momirealms.customcrops.objects.SimpleLocation; -import net.momirealms.customcrops.objects.Sprinkler; -import net.momirealms.customcrops.objects.WateringCan; -import net.momirealms.customcrops.requirements.PlantingCondition; -import net.momirealms.customcrops.requirements.Requirement; -import net.momirealms.customcrops.utils.*; -import org.apache.commons.lang.StringUtils; -import org.bukkit.*; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.Damageable; - -import java.util.List; - -public class RightClickI implements Listener { - - @EventHandler - public void onInteract(PlayerInteractEvent event){ - if (event.isCancelled()) return; - long time = System.currentTimeMillis(); - Player player = event.getPlayer(); - if (time - (JoinAndQuit.coolDown.getOrDefault(player, time - 200)) < 200) return; - JoinAndQuit.coolDown.put(player, time); - Action action = event.getAction(); - if (action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK){ - ItemStack itemStack = event.getItem(); - if (itemStack != null && itemStack.getType() != Material.AIR){ - NBTItem nbtItem = new NBTItem(itemStack); - NBTCompound nbtCompound = nbtItem.getCompound("itemsadder"); - if (nbtCompound != null){ - String id = nbtCompound.getString("id"); - String namespace = nbtCompound.getString("namespace"); - String itemNID = namespace + ":" + id; - if (id.endsWith("_seeds") && action == Action.RIGHT_CLICK_BLOCK && event.getBlockFace() == BlockFace.UP){ - String cropName = StringUtils.remove(id, "_seeds"); - Crop cropInstance = ConfigReader.CROPS.get(cropName); - if (cropInstance != null){ - Block block = event.getClickedBlock(); - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(block); - if (customBlock == null) return; - String namespacedID = customBlock.getNamespacedID(); - if (namespacedID.equals(ConfigReader.Basic.pot) || namespacedID.equals(ConfigReader.Basic.watered_pot)){ - Location location = block.getLocation().add(0,1,0); //已+1 - for (Integration integration : ConfigReader.Config.integration) - if(!integration.canPlace(location, player)) return; - if (FurnitureUtil.getNamespacedID(location.clone().add(0.5,0.1,0.5)) != null) return; - PlantingCondition plantingCondition = new PlantingCondition(player, location); - if (cropInstance.getRequirements() != null) - for (Requirement requirement : cropInstance.getRequirements()) - if (!requirement.canPlant(plantingCondition)) return; - Label_out: - if (ConfigReader.Season.enable && cropInstance.getSeasons() != null){ - if (!ConfigReader.Config.allWorld){ - for (String season : cropInstance.getSeasons()) - if (season.equals(SeasonManager.SEASON.get(location.getWorld().getName()))) - break Label_out; - }else { - for(String season : cropInstance.getSeasons()) - if (season.equals(SeasonManager.SEASON.get(ConfigReader.Config.referenceWorld))) - break Label_out; - } - if(ConfigReader.Season.greenhouse){ - for(int i = 1; i <= ConfigReader.Season.range; i++){ - CustomBlock cb = CustomBlock.byAlreadyPlaced(location.clone().add(0,i,0).getBlock()); - if (cb != null) - if(cb.getNamespacedID().equalsIgnoreCase(ConfigReader.Basic.glass)) - break Label_out; - } - } - if (ConfigReader.Config.nwSeason) AdventureManager.playerMessage(player, ConfigReader.Message.prefix + ConfigReader.Message.badSeason); - if (ConfigReader.Config.pwSeason) return; - } - if (location.getBlock().getType() != Material.AIR) return; - if (player.getGameMode() != GameMode.CREATIVE) itemStack.setAmount(itemStack.getAmount() - 1); - if (CropsPerChunkEntity.isLimited(location)){ - AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.crop_limit.replace("{max}", String.valueOf(ConfigReader.Config.cropLimit))); - return; - } - SimpleLocation simpleLocation = LocUtil.fromLocation(location); - CropManager.RemoveCache.remove(simpleLocation); - CropManager.Cache.put(simpleLocation, player.getName()); - FurnitureUtil.placeCrop(namespace + ":" + cropName + "_stage_1", location); - AdventureManager.playerSound(player, ConfigReader.Sounds.plantSeedSource, ConfigReader.Sounds.plantSeedKey); - } - }else AdventureManager.playerMessage(player, ConfigReader.Message.prefix + ConfigReader.Message.not_configed); - return; - } - WateringCan wateringCan = ConfigReader.CANS.get(itemNID); - if (wateringCan != null){ - int water = nbtItem.getInteger("WaterAmount"); - List lineOfSight = player.getLineOfSight(null, 5); - for (Block block : lineOfSight) { - if (block.getType() == Material.WATER) { - if (wateringCan.getMax() > water){ - water += ConfigReader.Config.waterCanRefill; - if (water > wateringCan.getMax()) water = wateringCan.getMax(); - nbtItem.setInteger("WaterAmount", water); - player.getWorld().playSound(player.getLocation(), Sound.ITEM_BUCKET_FILL,1,1); - if (ConfigReader.Message.hasWaterInfo) - AdventureManager.playerActionbar(player, - (ConfigReader.Message.waterLeft + - ConfigReader.Message.waterFull.repeat(water) + - ConfigReader.Message.waterEmpty.repeat(wateringCan.getMax() - water) + - ConfigReader.Message.waterRight) - .replace("{max_water}", String.valueOf(wateringCan.getMax())) - .replace("{water}", String.valueOf(water))); - if (ConfigReader.Basic.hasWaterLore){ - List lores = nbtItem.getCompound("display").getStringList("Lore"); - lores.clear(); - String string = - (ConfigReader.Basic.waterLeft + - ConfigReader.Basic.waterFull.repeat(water) + - ConfigReader.Basic.waterEmpty.repeat(wateringCan.getMax() - water) + - ConfigReader.Basic.waterRight) - .replace("{max_water}", String.valueOf(wateringCan.getMax())) - .replace("{water}", String.valueOf(water)); - ConfigReader.Basic.waterLore.forEach(lore -> lores.add(GsonComponentSerializer.gson().serialize(MiniMessage.miniMessage().deserialize(lore.replace("{water_info}", string))))); - } - if (ConfigReader.Config.hasParticle) player.getWorld().spawnParticle(Particle.WATER_SPLASH, block.getLocation().add(0.5,1, 0.5),15,0.1,0.1,0.1); - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); - } - return; - } - } - if(action == Action.RIGHT_CLICK_BLOCK){ - Block block = event.getClickedBlock(); - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(block); - if (customBlock == null) return; - for (Integration integration : ConfigReader.Config.integration) - if(!integration.canPlace(block.getLocation(), player)) return; - String namespacedID = customBlock.getNamespacedID(); - if ((namespacedID.equals(ConfigReader.Basic.pot) || namespacedID.equals(ConfigReader.Basic.watered_pot)) && event.getBlockFace() == BlockFace.UP){ - if (water > 0){ - nbtItem.setInteger("WaterAmount", --water); - AdventureManager.playerSound(player, ConfigReader.Sounds.waterPotSource, ConfigReader.Sounds.waterPotKey); - PotUtil.waterPot(wateringCan.getWidth(), wateringCan.getLength(), block.getLocation(), player.getLocation().getYaw()); - if (nbtCompound.hasKey("custom_durability")){ - int dur = nbtCompound.getInteger("custom_durability"); - int max_dur = nbtCompound.getInteger("max_custom_durability"); - if (dur > 0){ - nbtCompound.setInteger("custom_durability", dur - 1); - nbtCompound.setDouble("fake_durability", (int) itemStack.getType().getMaxDurability() * (double) (dur/max_dur)); - nbtItem.setInteger("Damage", (int) (itemStack.getType().getMaxDurability() * (1 - (double) dur/max_dur))); - } else { - AdventureManager.playerSound(player, net.kyori.adventure.sound.Sound.Source.PLAYER, Key.key("minecraft:item.shield.break")); - itemStack.setAmount(itemStack.getAmount() - 1); - } - } - } - if (ConfigReader.Message.hasWaterInfo) - AdventureManager.playerActionbar(player, - (ConfigReader.Message.waterLeft + - ConfigReader.Message.waterFull.repeat(water) + - ConfigReader.Message.waterEmpty.repeat(wateringCan.getMax() - water) + - ConfigReader.Message.waterRight) - .replace("{max_water}", String.valueOf(wateringCan.getMax())) - .replace("{water}", String.valueOf(water))); - if (ConfigReader.Basic.hasWaterLore){ - List lores = nbtItem.getCompound("display").getStringList("Lore"); - lores.clear(); - String string = - (ConfigReader.Basic.waterLeft + - ConfigReader.Basic.waterFull.repeat(water) + - ConfigReader.Basic.waterEmpty.repeat(wateringCan.getMax() - water) + - ConfigReader.Basic.waterRight) - .replace("{max_water}", String.valueOf(wateringCan.getMax())) - .replace("{water}", String.valueOf(water)); - ConfigReader.Basic.waterLore.forEach(lore -> lores.add(GsonComponentSerializer.gson().serialize(MiniMessage.miniMessage().deserialize(lore.replace("{water_info}", string))))); - } - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); - } - } - return; - } - Fertilizer fertilizerConfig = ConfigReader.FERTILIZERS.get(id); - if (fertilizerConfig != null && action == Action.RIGHT_CLICK_BLOCK){ - Block block = event.getClickedBlock(); - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(block); - if (customBlock == null) return; - for (Integration integration : ConfigReader.Config.integration) - if(!integration.canPlace(block.getLocation(), player)) return; - String namespacedID = customBlock.getNamespacedID(); - if (namespacedID.equals(ConfigReader.Basic.pot) || namespacedID.equals(ConfigReader.Basic.watered_pot)){ - String furniture = FurnitureUtil.getNamespacedID(block.getLocation().clone().add(0.5,1.1,0.5)); - if (furniture != null){ - if (fertilizerConfig.isBefore() && furniture.contains("_stage_")){ - AdventureManager.playerMessage(player, ConfigReader.Message.prefix + ConfigReader.Message.beforePlant); - return; - }else { - if (player.getGameMode() != GameMode.CREATIVE) itemStack.setAmount(itemStack.getAmount() - 1); - AdventureManager.playerSound(player, ConfigReader.Sounds.useFertilizerSource, ConfigReader.Sounds.useFertilizerKey); - PotUtil.addFertilizer(fertilizerConfig, block.getLocation()); - } - }else { - if (player.getGameMode() != GameMode.CREATIVE) itemStack.setAmount(itemStack.getAmount() - 1); - AdventureManager.playerSound(player, ConfigReader.Sounds.useFertilizerSource, ConfigReader.Sounds.useFertilizerKey); - PotUtil.addFertilizer(fertilizerConfig, block.getLocation()); - } - } - return; - } - Sprinkler sprinkler = ConfigReader.SPRINKLERS.get(itemNID); - if (sprinkler != null && action == Action.RIGHT_CLICK_BLOCK && event.getBlockFace() == BlockFace.UP){ - Location location = event.getClickedBlock().getLocation(); - for (Integration integration : ConfigReader.Config.integration) - if (!integration.canPlace(location, player)) return; - if (FurnitureUtil.isSprinkler(location.clone().add(0.5, 1.5, 0.5))) return; - if (SprinklersPerChunk.isLimited(location)){ - AdventureManager.playerMessage(player, ConfigReader.Message.prefix + ConfigReader.Message.sprinkler_limit.replace("{max}", String.valueOf(ConfigReader.Config.sprinklerLimit))); - return; - } - Sprinkler sprinklerData = new Sprinkler(sprinkler.getRange(), 0); - sprinklerData.setPlayer(player.getName()); - if (player.getGameMode() != GameMode.CREATIVE) itemStack.setAmount(itemStack.getAmount() - 1); - SimpleLocation simpleLocation = LocUtil.fromLocation(location.add(0,1,0)); - SprinklerManager.Cache.put(simpleLocation, sprinklerData); - SprinklerManager.RemoveCache.remove(simpleLocation); - FurnitureUtil.placeFurniture(sprinkler.getNamespacedID_2(),location); - AdventureManager.playerSound(player, ConfigReader.Sounds.placeSprinklerSource, ConfigReader.Sounds.placeSprinklerKey); - return; - } - if (ConfigReader.Message.hasCropInfo && itemNID.equals(ConfigReader.Basic.soilDetector) && action == Action.RIGHT_CLICK_BLOCK){ - Block block = event.getClickedBlock(); - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(block); - if (customBlock == null) return; - for (Integration integration : ConfigReader.Config.integration) if(!integration.canPlace(block.getLocation(), player)) return; - String namespacedID = customBlock.getNamespacedID(); - if(namespacedID.equals(ConfigReader.Basic.pot) || namespacedID.equals(ConfigReader.Basic.watered_pot)){ - Location location = block.getLocation(); - Fertilizer fertilizer = PotManager.Cache.get(LocUtil.fromLocation(location)); - if (fertilizer != null){ - Fertilizer config = ConfigReader.FERTILIZERS.get(fertilizer.getKey()); - if (config == null){ - PotManager.Cache.remove(LocUtil.fromLocation(location)); - return; - } - HoloUtil.showHolo( - ConfigReader.Message.cropText - .replace("{fertilizer}", config.getName()) - .replace("{times}", String.valueOf(fertilizer.getTimes())) - .replace("{max_times}", String.valueOf(config.getTimes())), - player, - location.add(0.5,ConfigReader.Message.cropOffset,0.5), - ConfigReader.Message.cropTime); - } - } - } - } - } - } - } -} diff --git a/src/main/java/net/momirealms/customcrops/listener/tripwire/BreakBlockT.java b/src/main/java/net/momirealms/customcrops/listener/tripwire/BreakBlockT.java deleted file mode 100644 index 9d3d654..0000000 --- a/src/main/java/net/momirealms/customcrops/listener/tripwire/BreakBlockT.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.listener.tripwire; - -import dev.lone.itemsadder.api.CustomBlock; -import dev.lone.itemsadder.api.CustomStack; -import dev.lone.itemsadder.api.Events.CustomBlockBreakEvent; -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.CustomCrops; -import net.momirealms.customcrops.datamanager.CropManager; -import net.momirealms.customcrops.datamanager.PotManager; -import net.momirealms.customcrops.listener.JoinAndQuit; -import net.momirealms.customcrops.objects.fertilizer.Fertilizer; -import net.momirealms.customcrops.objects.fertilizer.QualityCrop; -import net.momirealms.customcrops.integrations.protection.Integration; -import net.momirealms.customcrops.objects.Crop; -import net.momirealms.customcrops.objects.SimpleLocation; -import net.momirealms.customcrops.objects.fertilizer.YieldIncreasing; -import net.momirealms.customcrops.utils.DropUtil; -import net.momirealms.customcrops.utils.LocUtil; -import org.apache.commons.lang.StringUtils; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.inventory.ItemStack; - -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.ThreadLocalRandom; - -public class BreakBlockT implements Listener { - - private HashMap coolDown = new HashMap<>(); - - @EventHandler - public void onBreak(CustomBlockBreakEvent event){ - if (event.isCancelled()) return; - long time = System.currentTimeMillis(); - Player player = event.getPlayer(); - if (time - (coolDown.getOrDefault(player, time - 100)) < 80) return; - coolDown.put(player, time); - String namespacedId = event.getNamespacedID(); - if(namespacedId.contains("_stage_")){ - Location location = event.getBlock().getLocation(); - for (Integration integration : ConfigReader.Config.integration) - if(!integration.canBreak(location, player)) return; - SimpleLocation simpleLocation = LocUtil.fromLocation(location); - if (CropManager.Cache.remove(simpleLocation) == null){ - CropManager.RemoveCache.add(simpleLocation); - } - if (player.getInventory().getItemInMainHand().containsEnchantment(Enchantment.SILK_TOUCH) || player.getInventory().getItemInMainHand().getType() == Material.SHEARS){ - event.setCancelled(true); - CustomBlock.place(namespacedId, location); - CustomBlock.byAlreadyPlaced(location.getBlock()).getLoot().forEach(itemStack -> location.getWorld().dropItem(location.clone().add(0.5,0.2,0.5), itemStack)); - CustomBlock.remove(location); - return; - } - if (!ConfigReader.Config.quality || namespacedId.equals(ConfigReader.Basic.dead)) return; - String[] cropNameList = StringUtils.split(StringUtils.split(namespacedId, ":")[1], "_"); - int nextStage = Integer.parseInt(cropNameList[2]) + 1; - if (CustomBlock.getInstance(StringUtils.chop(namespacedId) + nextStage) == null) { - Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.plugin, ()-> { - if (location.getBlock().getType() != Material.AIR) return; - Crop cropInstance = ConfigReader.CROPS.get(cropNameList[0]); - ThreadLocalRandom current = ThreadLocalRandom.current(); - int random = current.nextInt(cropInstance.getMin(), cropInstance.getMax() + 1); - Location itemLoc = location.clone().add(0.5,0.2,0.5); - World world = location.getWorld(); - List commands = cropInstance.getCommands(); - Fertilizer fertilizer = PotManager.Cache.get(LocUtil.fromLocation(location.clone().subtract(0,1,0))); - if (commands != null) - Bukkit.getScheduler().runTask(CustomCrops.plugin, ()-> { - for (String command : commands) - Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), command.replace("{player}", player.getName())); - }); - if (ConfigReader.Config.skillXP != null && cropInstance.getSkillXP() != 0) - Bukkit.getScheduler().runTask(CustomCrops.plugin, ()-> ConfigReader.Config.skillXP.addXp(player, cropInstance.getSkillXP())); - if (fertilizer != null){ - if (fertilizer instanceof QualityCrop qualityCrop){ - int[] weights = qualityCrop.getChance(); - double weightTotal = weights[0] + weights[1] + weights[2]; - Bukkit.getScheduler().runTask(CustomCrops.plugin, ()-> { - for (int i = 0; i < random; i++){ - double ran = Math.random(); - if (ran < weights[0]/(weightTotal)) world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_1()).getItemStack()); - else if(ran > 1 - weights[1]/(weightTotal)) world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_2()).getItemStack()); - else world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_3()).getItemStack()); - } - }); - } - else Bukkit.getScheduler().runTask(CustomCrops.plugin, ()-> DropUtil.normalDrop(cropInstance, random, itemLoc, world)); - } - else Bukkit.getScheduler().runTask(CustomCrops.plugin, ()-> DropUtil.normalDrop(cropInstance, random, itemLoc, world)); - }); - } - } - else if(namespacedId.equalsIgnoreCase(ConfigReader.Basic.watered_pot) || namespacedId.equalsIgnoreCase(ConfigReader.Basic.pot)){ - Location location = event.getBlock().getLocation(); - PotManager.Cache.remove(LocUtil.fromLocation(location)); - World world = location.getWorld(); - Block blockUp = location.add(0,1,0).getBlock(); - for (Integration integration : ConfigReader.Config.integration) - if(!integration.canBreak(location, event.getPlayer())) return; - if(CustomBlock.byAlreadyPlaced(blockUp) != null){ - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(blockUp); - String cropNamespacedId = customBlock.getNamespacedID(); - if(cropNamespacedId.contains("_stage_")){ - CustomBlock.remove(location); - SimpleLocation simpleLocation = LocUtil.fromLocation(location); - if (CropManager.Cache.remove(simpleLocation) == null){ - CropManager.RemoveCache.add(simpleLocation); - } - if (cropNamespacedId.equals(ConfigReader.Basic.dead)) return; - if (ConfigReader.Config.quality){ - String[] cropNameList = StringUtils.split(StringUtils.split(cropNamespacedId, ":")[1], "_"); - int nextStage = Integer.parseInt(cropNameList[2]) + 1; - if (CustomBlock.getInstance(StringUtils.chop(cropNamespacedId) + nextStage) == null) { - Crop cropInstance = ConfigReader.CROPS.get(cropNameList[0]); - ThreadLocalRandom current = ThreadLocalRandom.current(); - int random = current.nextInt(cropInstance.getMin(), cropInstance.getMax() + 1); - Location itemLoc = location.clone().add(0.5,0.2,0.5); - Fertilizer fertilizer = PotManager.Cache.get(LocUtil.fromLocation(location.clone().subtract(0,1,0))); - if (fertilizer != null){ - if (fertilizer instanceof QualityCrop qualityCrop){ - int[] weights = qualityCrop.getChance(); - double weightTotal = weights[0] + weights[1] + weights[2]; - for (int i = 0; i < random; i++){ - double ran = Math.random(); - if (ran < weights[0]/(weightTotal)) world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_1()).getItemStack()); - else if(ran > 1 - weights[1]/(weightTotal)) world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_2()).getItemStack()); - else world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_3()).getItemStack()); - } - }else if (fertilizer instanceof YieldIncreasing yieldIncreasing){ - if (Math.random() < yieldIncreasing.getChance()){ - random += yieldIncreasing.getBonus(); - } - DropUtil.normalDrop(cropInstance, random , itemLoc, world); - } - } - else DropUtil.normalDrop(cropInstance, random, itemLoc, world); - return; - } - } - for (ItemStack itemStack : customBlock.getLoot()) - world.dropItem(location.clone().add(0.5, 0.2, 0.5), itemStack); - } - } - } - } -} diff --git a/src/main/java/net/momirealms/customcrops/listener/tripwire/BreakFurnitureT.java b/src/main/java/net/momirealms/customcrops/listener/tripwire/BreakFurnitureT.java deleted file mode 100644 index bd0e3c4..0000000 --- a/src/main/java/net/momirealms/customcrops/listener/tripwire/BreakFurnitureT.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.listener.tripwire; - -import dev.lone.itemsadder.api.Events.FurnitureBreakEvent; -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.datamanager.SprinklerManager; -import net.momirealms.customcrops.objects.SimpleLocation; -import net.momirealms.customcrops.objects.Sprinkler; -import net.momirealms.customcrops.utils.LocUtil; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; - -public class BreakFurnitureT implements Listener { - - @EventHandler - public void onBreakFurniture(FurnitureBreakEvent event){ - if (event.isCancelled()) return; - Sprinkler config = ConfigReader.SPRINKLERS.get(event.getNamespacedID()); - if (config != null){ - SimpleLocation simpleLocation = LocUtil.fromLocation(event.getBukkitEntity().getLocation()); - if(SprinklerManager.Cache.remove(simpleLocation) == null){ - SprinklerManager.RemoveCache.add(simpleLocation); - } - } - } -} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/listener/tripwire/InteractFurnitureT.java b/src/main/java/net/momirealms/customcrops/listener/tripwire/InteractFurnitureT.java deleted file mode 100644 index d55f325..0000000 --- a/src/main/java/net/momirealms/customcrops/listener/tripwire/InteractFurnitureT.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.listener.tripwire; - -import de.tr7zw.changeme.nbtapi.NBTCompound; -import de.tr7zw.changeme.nbtapi.NBTItem; -import dev.lone.itemsadder.api.Events.FurnitureInteractEvent; -import net.kyori.adventure.key.Key; -import net.kyori.adventure.sound.Sound; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.CustomCrops; -import net.momirealms.customcrops.datamanager.SprinklerManager; -import net.momirealms.customcrops.listener.JoinAndQuit; -import net.momirealms.customcrops.objects.SimpleLocation; -import net.momirealms.customcrops.objects.Sprinkler; -import net.momirealms.customcrops.objects.WateringCan; -import net.momirealms.customcrops.utils.*; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.inventory.ItemStack; - -import java.util.HashMap; -import java.util.List; - - -public class InteractFurnitureT implements Listener { - - @EventHandler - public void onEntityInteract(FurnitureInteractEvent event){ - if (event.isCancelled()) return; - Sprinkler config = ConfigReader.SPRINKLERS.get(event.getNamespacedID()); - if(config != null){ - long time = System.currentTimeMillis(); - Player player = event.getPlayer(); - if (time - (JoinAndQuit.coolDown.getOrDefault(player, time - 200)) < 200) return; - JoinAndQuit.coolDown.put(player, time); - ItemStack itemStack = player.getInventory().getItemInMainHand(); - Location location = event.getBukkitEntity().getLocation(); - String world = location.getWorld().getName(); - int x = location.getBlockX(); - int z = location.getBlockZ(); - int maxWater = config.getWater(); - int currentWater = 0; - Location loc = location.clone().subtract(0,1,0).getBlock().getLocation().add(0,1,0); - Sprinkler sprinkler = SprinklerManager.Cache.get(LocUtil.fromLocation(loc)); - if (itemStack.getType() == Material.WATER_BUCKET){ - itemStack.setType(Material.BUCKET); - if (sprinkler != null){ - currentWater = sprinkler.getWater(); - currentWater += ConfigReader.Config.sprinklerRefill; - if (currentWater > maxWater) currentWater = maxWater; - sprinkler.setWater(currentWater); - }else { - String path = world + "." + x / 16 + "," + z / 16 + "." + x + "," + location.getBlockY() + "," + z ; - currentWater = SprinklerManager.data.getInt(path+ ".water"); - currentWater += ConfigReader.Config.sprinklerRefill; - if (currentWater > maxWater) currentWater = maxWater; - SprinklerManager.data.set(path + ".water", currentWater); - SprinklerManager.data.set(path + ".range", config.getRange()); - } - AdventureManager.playerSound(player, ConfigReader.Sounds.addWaterToSprinklerSource, ConfigReader.Sounds.addWaterToSprinklerKey); - } - else { - if (ConfigReader.Config.canAddWater && itemStack.getType() != Material.AIR){ - NBTItem nbtItem = new NBTItem(itemStack); - NBTCompound nbtCompound = nbtItem.getCompound("itemsadder"); - if (nbtCompound != null) { - String id = nbtCompound.getString("id"); - String namespace = nbtCompound.getString("namespace"); - WateringCan wateringCan = ConfigReader.CANS.get(namespace + ":" + id); - if (wateringCan != null) { - int water = nbtItem.getInteger("WaterAmount"); - if (water > 0){ - nbtItem.setInteger("WaterAmount", --water); - if (nbtCompound.hasKey("custom_durability")){ - int dur = nbtCompound.getInteger("custom_durability"); - int max_dur = nbtCompound.getInteger("max_custom_durability"); - if (dur > 0){ - nbtCompound.setInteger("custom_durability", dur - 1); - nbtCompound.setDouble("fake_durability", (int) itemStack.getType().getMaxDurability() * (double) (dur/max_dur)); - nbtItem.setInteger("Damage", (int) (itemStack.getType().getMaxDurability() * (1 - (double) dur/max_dur))); - } else { - AdventureManager.playerSound(player, net.kyori.adventure.sound.Sound.Source.PLAYER, Key.key("minecraft:item.shield.break")); - itemStack.setAmount(itemStack.getAmount() - 1); - } - } - AdventureManager.playerSound(player, ConfigReader.Sounds.addWaterToSprinklerSource, ConfigReader.Sounds.addWaterToSprinklerKey); - if (sprinkler != null){ - currentWater = sprinkler.getWater(); - currentWater++; - if (currentWater > maxWater) currentWater = maxWater; - sprinkler.setWater(currentWater); - }else { - String path = world + "." + x / 16 + "," + z / 16 + "." + x + "," + location.getBlockY() + "," + z ; - currentWater = SprinklerManager.data.getInt(path + ".water"); - currentWater++; - if (currentWater > maxWater) currentWater = maxWater; - SprinklerManager.data.set(path + ".water", currentWater); - SprinklerManager.data.set(path + ".range", config.getRange()); - } - } - else { - currentWater = SprinklerManager.getCurrentWater(location, world, x, z, sprinkler); - } - if (ConfigReader.Message.hasWaterInfo){ - AdventureManager.playerActionbar(player, - (ConfigReader.Message.waterLeft + - ConfigReader.Message.waterFull.repeat(water) + - ConfigReader.Message.waterEmpty.repeat(wateringCan.getMax() - water) + - ConfigReader.Message.waterRight) - .replace("{max_water}", String.valueOf(wateringCan.getMax())) - .replace("{water}", String.valueOf(water))); - } - if (ConfigReader.Basic.hasWaterLore){ - String string = - (ConfigReader.Basic.waterLeft + - ConfigReader.Basic.waterFull.repeat(water) + - ConfigReader.Basic.waterEmpty.repeat(wateringCan.getMax() - water) + - ConfigReader.Basic.waterRight) - .replace("{max_water}", String.valueOf(wateringCan.getMax())) - .replace("{water}", String.valueOf(water)); - List lores = nbtItem.getCompound("display").getStringList("Lore"); - lores.clear(); - ConfigReader.Basic.waterLore.forEach(lore -> lores.add(GsonComponentSerializer.gson().serialize(MiniMessage.miniMessage().deserialize(lore.replace("{water_info}", string))))); - } - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); - } - } - else currentWater = SprinklerManager.getCurrentWater(location, world, x, z, sprinkler); - } - else currentWater = SprinklerManager.getCurrentWater(location, world, x, z, sprinkler); - } - if (ConfigReader.Message.hasSprinklerInfo) - HoloUtil.showHolo( - (ConfigReader.Message.sprinklerLeft + - ConfigReader.Message.sprinklerFull.repeat(currentWater) + - ConfigReader.Message.sprinklerEmpty.repeat(maxWater - currentWater) + - ConfigReader.Message.sprinklerRight) - .replace("{max_water}", String.valueOf(maxWater)) - .replace("{water}", String.valueOf(currentWater)), - player, - location.add(0, ConfigReader.Message.sprinklerOffset,0), - ConfigReader.Message.sprinklerTime); - } - } -} diff --git a/src/main/java/net/momirealms/customcrops/listener/tripwire/RightClickT.java b/src/main/java/net/momirealms/customcrops/listener/tripwire/RightClickT.java deleted file mode 100644 index f174347..0000000 --- a/src/main/java/net/momirealms/customcrops/listener/tripwire/RightClickT.java +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.listener.tripwire; - -import de.tr7zw.changeme.nbtapi.NBTCompound; -import de.tr7zw.changeme.nbtapi.NBTItem; -import dev.lone.itemsadder.api.CustomBlock; -import dev.lone.itemsadder.api.CustomStack; -import net.kyori.adventure.key.Key; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.datamanager.CropManager; -import net.momirealms.customcrops.datamanager.PotManager; -import net.momirealms.customcrops.datamanager.SeasonManager; -import net.momirealms.customcrops.datamanager.SprinklerManager; -import net.momirealms.customcrops.listener.itemframe.InteractFurnitureI; -import net.momirealms.customcrops.objects.fertilizer.Fertilizer; -import net.momirealms.customcrops.objects.fertilizer.QualityCrop; -import net.momirealms.customcrops.integrations.protection.Integration; -import net.momirealms.customcrops.limits.CropsPerChunk; -import net.momirealms.customcrops.limits.SprinklersPerChunk; -import net.momirealms.customcrops.listener.JoinAndQuit; -import net.momirealms.customcrops.objects.Crop; -import net.momirealms.customcrops.objects.SimpleLocation; -import net.momirealms.customcrops.objects.Sprinkler; -import net.momirealms.customcrops.objects.WateringCan; -import net.momirealms.customcrops.objects.fertilizer.YieldIncreasing; -import net.momirealms.customcrops.requirements.PlantingCondition; -import net.momirealms.customcrops.requirements.Requirement; -import net.momirealms.customcrops.utils.*; -import org.apache.commons.lang.StringUtils; -import org.bukkit.*; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.Damageable; - -import java.util.List; -import java.util.concurrent.ThreadLocalRandom; - -public class RightClickT implements Listener { - - @EventHandler - public void onInteract(PlayerInteractEvent event){ - if (event.isCancelled()) return; - long time = System.currentTimeMillis(); - Player player = event.getPlayer(); - if (time - (JoinAndQuit.coolDown.getOrDefault(player, time - 200)) < 200) return; - JoinAndQuit.coolDown.put(player, time); - Action action = event.getAction(); - if (action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK){ - ItemStack itemStack = event.getItem(); - if (itemStack != null && itemStack.getType() != Material.AIR){ - NBTItem nbtItem = new NBTItem(itemStack); - NBTCompound nbtCompound = nbtItem.getCompound("itemsadder"); - if (nbtCompound != null){ - String id = nbtCompound.getString("id"); - String namespace = nbtCompound.getString("namespace"); - String itemNID = namespace + ":" + id; - if (id.endsWith("_seeds") && action == Action.RIGHT_CLICK_BLOCK && event.getBlockFace() == BlockFace.UP){ - String cropName = StringUtils.remove(id, "_seeds"); - Crop cropInstance = ConfigReader.CROPS.get(cropName); - if (cropInstance != null){ - Block block = event.getClickedBlock(); - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(block); - if (customBlock == null) return; - String namespacedID = customBlock.getNamespacedID(); - if (namespacedID.equals(ConfigReader.Basic.pot) || namespacedID.equals(ConfigReader.Basic.watered_pot)){ - Location location = block.getLocation().add(0,1,0); //已+1 - for (Integration integration : ConfigReader.Config.integration) - if(!integration.canPlace(location, player)) return; - if(FurnitureUtil.isSprinkler(location.clone().add(0.5, 0.5, 0.5))) return; - PlantingCondition plantingCondition = new PlantingCondition(player, location); - if (cropInstance.getRequirements() != null) - for (Requirement requirement : cropInstance.getRequirements()) - if (!requirement.canPlant(plantingCondition)) return; - Label_out: - if (ConfigReader.Season.enable && cropInstance.getSeasons() != null){ - if (!ConfigReader.Config.allWorld){ - for (String season : cropInstance.getSeasons()) - if (season.equals(SeasonManager.SEASON.get(location.getWorld().getName()))) - break Label_out; - }else { - for(String season : cropInstance.getSeasons()) - if (season.equals(SeasonManager.SEASON.get(ConfigReader.Config.referenceWorld))) - break Label_out; - } - if(ConfigReader.Season.greenhouse){ - for(int i = 1; i <= ConfigReader.Season.range; i++){ - CustomBlock cb = CustomBlock.byAlreadyPlaced(location.clone().add(0,i,0).getBlock()); - if (cb != null) - if(cb.getNamespacedID().equalsIgnoreCase(ConfigReader.Basic.glass)) - break Label_out; - } - } - if (ConfigReader.Config.nwSeason) AdventureManager.playerMessage(player, ConfigReader.Message.prefix + ConfigReader.Message.badSeason); - if (ConfigReader.Config.pwSeason) return; - } - if (location.getBlock().getType() != Material.AIR) return; - if (player.getGameMode() != GameMode.CREATIVE) itemStack.setAmount(itemStack.getAmount() - 1); - if (CropsPerChunk.isLimited(location)){ - AdventureManager.playerMessage(player,ConfigReader.Message.prefix + ConfigReader.Message.crop_limit.replace("{max}", String.valueOf(ConfigReader.Config.cropLimit))); - return; - } - SimpleLocation simpleLocation = LocUtil.fromLocation(location); - CropManager.RemoveCache.remove(simpleLocation); - CropManager.Cache.put(simpleLocation, player.getName()); - CustomBlock.place((namespace + ":" + cropName + "_stage_1"), location); - AdventureManager.playerSound(player, ConfigReader.Sounds.plantSeedSource, ConfigReader.Sounds.plantSeedKey); - } - }else AdventureManager.playerMessage(player, ConfigReader.Message.prefix + ConfigReader.Message.not_configed); - return; - } - WateringCan wateringCan = ConfigReader.CANS.get(itemNID); - if (wateringCan != null){ - int water = nbtItem.getInteger("WaterAmount"); - List lineOfSight = player.getLineOfSight(null, 5); - for (Block block : lineOfSight) { - if (block.getType() == Material.WATER) { - if (wateringCan.getMax() > water){ - water += ConfigReader.Config.waterCanRefill; - if (water > wateringCan.getMax()) water = wateringCan.getMax(); - nbtItem.setInteger("WaterAmount", water); - player.getWorld().playSound(player.getLocation(), Sound.ITEM_BUCKET_FILL,1,1); - if (ConfigReader.Message.hasWaterInfo) - AdventureManager.playerActionbar(player, - (ConfigReader.Message.waterLeft + - ConfigReader.Message.waterFull.repeat(water) + - ConfigReader.Message.waterEmpty.repeat(wateringCan.getMax() - water) + - ConfigReader.Message.waterRight) - .replace("{max_water}", String.valueOf(wateringCan.getMax())) - .replace("{water}", String.valueOf(water))); - if (ConfigReader.Basic.hasWaterLore){ - List lores = nbtItem.getCompound("display").getStringList("Lore"); - lores.clear(); - String string = - (ConfigReader.Basic.waterLeft + - ConfigReader.Basic.waterFull.repeat(water) + - ConfigReader.Basic.waterEmpty.repeat(wateringCan.getMax() - water) + - ConfigReader.Basic.waterRight) - .replace("{max_water}", String.valueOf(wateringCan.getMax())) - .replace("{water}", String.valueOf(water)); - ConfigReader.Basic.waterLore.forEach(lore -> lores.add(GsonComponentSerializer.gson().serialize(MiniMessage.miniMessage().deserialize(lore.replace("{water_info}", string))))); - } - if (ConfigReader.Config.hasParticle) player.getWorld().spawnParticle(Particle.WATER_SPLASH, block.getLocation().add(0.5,1, 0.5),15,0.1,0.1,0.1); - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); - } - return; - } - } - if(action == Action.RIGHT_CLICK_BLOCK){ - Block block = event.getClickedBlock(); - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(block); - if (customBlock == null) return; - for (Integration integration : ConfigReader.Config.integration) - if(!integration.canPlace(block.getLocation(), player)) return; - String namespacedID = customBlock.getNamespacedID(); - if ((namespacedID.equals(ConfigReader.Basic.pot) || namespacedID.equals(ConfigReader.Basic.watered_pot)) && event.getBlockFace() == BlockFace.UP){ - if (water > 0){ - nbtItem.setInteger("WaterAmount", --water); - AdventureManager.playerSound(player, ConfigReader.Sounds.waterPotSource, ConfigReader.Sounds.waterPotKey); - PotUtil.waterPot(wateringCan.getWidth(), wateringCan.getLength(), block.getLocation(), player.getLocation().getYaw()); - if (nbtCompound.hasKey("custom_durability")){ - int dur = nbtCompound.getInteger("custom_durability"); - int max_dur = nbtCompound.getInteger("max_custom_durability"); - if (dur > 0){ - nbtCompound.setInteger("custom_durability", dur - 1); - nbtCompound.setDouble("fake_durability", (int) itemStack.getType().getMaxDurability() * (double) (dur/max_dur)); - nbtItem.setInteger("Damage", (int) (itemStack.getType().getMaxDurability() * (1 - (double) dur/max_dur))); - } else { - AdventureManager.playerSound(player, net.kyori.adventure.sound.Sound.Source.PLAYER, Key.key("minecraft:item.shield.break")); - itemStack.setAmount(itemStack.getAmount() - 1); - } - } - } - if (ConfigReader.Message.hasWaterInfo) - AdventureManager.playerActionbar(player, - (ConfigReader.Message.waterLeft + - ConfigReader.Message.waterFull.repeat(water) + - ConfigReader.Message.waterEmpty.repeat(wateringCan.getMax() - water) + - ConfigReader.Message.waterRight) - .replace("{max_water}", String.valueOf(wateringCan.getMax())) - .replace("{water}", String.valueOf(water))); - if (ConfigReader.Basic.hasWaterLore){ - List lores = nbtItem.getCompound("display").getStringList("Lore"); - lores.clear(); - String string = - (ConfigReader.Basic.waterLeft + - ConfigReader.Basic.waterFull.repeat(water) + - ConfigReader.Basic.waterEmpty.repeat(wateringCan.getMax() - water) + - ConfigReader.Basic.waterRight) - .replace("{max_water}", String.valueOf(wateringCan.getMax())) - .replace("{water}", String.valueOf(water)); - ConfigReader.Basic.waterLore.forEach(lore -> lores.add(GsonComponentSerializer.gson().serialize(MiniMessage.miniMessage().deserialize(lore.replace("{water_info}", string))))); - } - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); - } - else if (namespacedID.contains("_stage_")){ - if (water > 0) { - nbtItem.setInteger("WaterAmount", --water); - AdventureManager.playerSound(player, ConfigReader.Sounds.waterPotSource, ConfigReader.Sounds.waterPotKey); - PotUtil.waterPot(wateringCan.getWidth(), wateringCan.getLength(), block.getLocation().subtract(0, 1, 0), player.getLocation().getYaw()); - if (nbtCompound.hasKey("custom_durability")){ - int dur = nbtCompound.getInteger("custom_durability"); - int max_dur = nbtCompound.getInteger("max_custom_durability"); - if (dur > 0){ - nbtCompound.setInteger("custom_durability", dur - 1); - nbtCompound.setDouble("fake_durability", (int) itemStack.getType().getMaxDurability() * (double) (dur/max_dur)); - nbtItem.setInteger("Damage", (int) (itemStack.getType().getMaxDurability() * (1 - (double) dur/max_dur))); - } else { - AdventureManager.playerSound(player, net.kyori.adventure.sound.Sound.Source.PLAYER, Key.key("minecraft:item.shield.break")); - itemStack.setAmount(itemStack.getAmount() - 1); - } - } - } - if (ConfigReader.Message.hasWaterInfo) - AdventureManager.playerActionbar(player, - (ConfigReader.Message.waterLeft + - ConfigReader.Message.waterFull.repeat(water) + - ConfigReader.Message.waterEmpty.repeat(wateringCan.getMax() - water) + - ConfigReader.Message.waterRight) - .replace("{max_water}", String.valueOf(wateringCan.getMax())) - .replace("{water}", String.valueOf(water))); - if (ConfigReader.Basic.hasWaterLore){ - List lores = nbtItem.getCompound("display").getStringList("Lore"); - lores.clear(); - String string = - (ConfigReader.Basic.waterLeft + - ConfigReader.Basic.waterFull.repeat(water) + - ConfigReader.Basic.waterEmpty.repeat(wateringCan.getMax() - water) + - ConfigReader.Basic.waterRight) - .replace("{max_water}", String.valueOf(wateringCan.getMax())) - .replace("{water}", String.valueOf(water)); - ConfigReader.Basic.waterLore.forEach(lore -> lores.add(GsonComponentSerializer.gson().serialize(MiniMessage.miniMessage().deserialize(lore.replace("{water_info}", string))))); - } - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); - } - } - return; - } - Fertilizer fertilizerConfig = ConfigReader.FERTILIZERS.get(id); - if (fertilizerConfig != null && action == Action.RIGHT_CLICK_BLOCK){ - Block block = event.getClickedBlock(); - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(block); - if (customBlock == null) return; - for (Integration integration : ConfigReader.Config.integration) - if(!integration.canPlace(block.getLocation(), player)) return; - String namespacedID = customBlock.getNamespacedID(); - if (namespacedID.equals(ConfigReader.Basic.pot) || namespacedID.equals(ConfigReader.Basic.watered_pot)){ - CustomBlock customBlockUp = CustomBlock.byAlreadyPlaced(block.getLocation().clone().add(0,1,0).getBlock()); - if (customBlockUp != null){ - if (fertilizerConfig.isBefore() && customBlockUp.getNamespacedID().contains("_stage_")){ - AdventureManager.playerMessage(player, ConfigReader.Message.prefix + ConfigReader.Message.beforePlant); - return; - }else { - if (player.getGameMode() != GameMode.CREATIVE) itemStack.setAmount(itemStack.getAmount() - 1); - AdventureManager.playerSound(player, ConfigReader.Sounds.useFertilizerSource, ConfigReader.Sounds.useFertilizerKey); - PotUtil.addFertilizer(fertilizerConfig, block.getLocation()); - } - }else { - if (player.getGameMode() != GameMode.CREATIVE) itemStack.setAmount(itemStack.getAmount() - 1); - AdventureManager.playerSound(player, ConfigReader.Sounds.useFertilizerSource, ConfigReader.Sounds.useFertilizerKey); - PotUtil.addFertilizer(fertilizerConfig, block.getLocation()); - } - }else if (namespacedID.contains("_stage_")){ - if (!fertilizerConfig.isBefore()){ - if (player.getGameMode() != GameMode.CREATIVE) itemStack.setAmount(itemStack.getAmount() - 1); - PotUtil.addFertilizer(fertilizerConfig, block.getLocation().subtract(0,1,0)); - AdventureManager.playerSound(player, ConfigReader.Sounds.useFertilizerSource, ConfigReader.Sounds.useFertilizerKey); - }else { - AdventureManager.playerMessage(player, ConfigReader.Message.prefix + ConfigReader.Message.beforePlant); - return; - } - } - return; - } - Sprinkler sprinkler = ConfigReader.SPRINKLERS.get(itemNID); - if (sprinkler != null && action == Action.RIGHT_CLICK_BLOCK && event.getBlockFace() == BlockFace.UP){ - Location location = event.getClickedBlock().getLocation(); - for (Integration integration : ConfigReader.Config.integration) - if (!integration.canPlace(location, player)) return; - if (FurnitureUtil.isSprinkler(location.clone().add(0.5, 1.5, 0.5))) return; - if (SprinklersPerChunk.isLimited(location)){ - AdventureManager.playerMessage(player, ConfigReader.Message.prefix + ConfigReader.Message.sprinkler_limit.replace("{max}", String.valueOf(ConfigReader.Config.sprinklerLimit))); - return; - } - Sprinkler sprinklerData = new Sprinkler(sprinkler.getRange(), 0); - sprinklerData.setPlayer(player.getName()); - if (player.getGameMode() != GameMode.CREATIVE) itemStack.setAmount(itemStack.getAmount() - 1); - SimpleLocation simpleLocation = LocUtil.fromLocation(location.add(0,1,0)); - SprinklerManager.Cache.put(simpleLocation, sprinklerData); - SprinklerManager.RemoveCache.remove(simpleLocation); - FurnitureUtil.placeFurniture(sprinkler.getNamespacedID_2(),location); - AdventureManager.playerSound(player, ConfigReader.Sounds.placeSprinklerSource, ConfigReader.Sounds.placeSprinklerKey); - return; - } - if (ConfigReader.Message.hasCropInfo && itemNID.equals(ConfigReader.Basic.soilDetector) && action == Action.RIGHT_CLICK_BLOCK){ - Block block = event.getClickedBlock(); - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(block); - if (customBlock == null) return; - for (Integration integration : ConfigReader.Config.integration) if(!integration.canPlace(block.getLocation(), player)) return; - String namespacedID = customBlock.getNamespacedID(); - if (namespacedID.contains("_stage_")){ - Location location = block.getLocation().subtract(0,1,0); - Fertilizer fertilizer = PotManager.Cache.get(LocUtil.fromLocation(location)); - if (fertilizer != null){ - Fertilizer config = ConfigReader.FERTILIZERS.get(fertilizer.getKey()); - if (config == null){ - PotManager.Cache.remove(LocUtil.fromLocation(location)); - return; - } - HoloUtil.showHolo( - ConfigReader.Message.cropText - .replace("{fertilizer}", config.getName()) - .replace("{times}", String.valueOf(fertilizer.getTimes())) - .replace("{max_times}", String.valueOf(config.getTimes())), - player, - location.add(0.5, ConfigReader.Message.cropOffset, 0.5), - ConfigReader.Message.cropTime); - } - } - else if(namespacedID.equals(ConfigReader.Basic.pot) || namespacedID.equals(ConfigReader.Basic.watered_pot)){ - Location location = block.getLocation(); - Fertilizer fertilizer = PotManager.Cache.get(LocUtil.fromLocation(block.getLocation())); - if (fertilizer != null){ - Fertilizer config = ConfigReader.FERTILIZERS.get(fertilizer.getKey()); - if (config == null){ - PotManager.Cache.remove(LocUtil.fromLocation(location)); - return; - } - HoloUtil.showHolo( - ConfigReader.Message.cropText - .replace("{fertilizer}", config.getName()) - .replace("{times}", String.valueOf(fertilizer.getTimes())) - .replace("{max_times}", String.valueOf(config.getTimes())), - player, - location.add(0.5,ConfigReader.Message.cropOffset,0.5), - ConfigReader.Message.cropTime); - } - } - } - } - else if (ConfigReader.Config.boneMeal && itemStack.getType() == Material.BONE_MEAL && action == Action.RIGHT_CLICK_BLOCK){ - Block block = event.getClickedBlock(); - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(block); - if (customBlock == null) return; - for (Integration integration : ConfigReader.Config.integration) - if(!integration.canPlace(block.getLocation(), player)) return; - String namespacedID = customBlock.getNamespacedID(); - if (namespacedID.contains("_stage_") && !namespacedID.equals(ConfigReader.Basic.dead)){ - int nextStage = Integer.parseInt(namespacedID.substring(namespacedID.length()-1)) + 1; - String next = StringUtils.chop(namespacedID) + nextStage; - if (CustomBlock.getInstance(next) != null){ - Location location = block.getLocation(); - if (player.getGameMode() != GameMode.CREATIVE) itemStack.setAmount(itemStack.getAmount() - 1); - AdventureManager.playerSound(player, ConfigReader.Sounds.boneMealSource, ConfigReader.Sounds.boneMealKey); - if (Math.random() < ConfigReader.Config.boneMealChance){ - CustomBlock.remove(location); - CustomBlock.place(next, location); - block.getWorld().spawnParticle(ConfigReader.Config.boneMealSuccess, location.add(0.5,0.3,0.5),5,0.2,0.2,0.2); - } - } - } - } - else if(ConfigReader.Config.rightClickHarvest && !ConfigReader.Config.needEmptyHand && action == Action.RIGHT_CLICK_BLOCK) - rightClickHarvest(event.getClickedBlock(), player); - } - else if (ConfigReader.Config.rightClickHarvest && action == Action.RIGHT_CLICK_BLOCK) - rightClickHarvest(event.getClickedBlock(), player); - } - } - - /** - * 右键收获判定 - * @param block 农作物方块 - * @param player 玩家 - */ - private void rightClickHarvest(Block block, Player player) { - Location location = block.getLocation(); - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(block); - if (customBlock == null) return; - for (Integration integration : ConfigReader.Config.integration) - if (!integration.canBreak(location, player)) return; - String namespacedID = customBlock.getNamespacedID(); - if (namespacedID.contains("_stage_")){ - if(namespacedID.equals(ConfigReader.Basic.dead)) return; - String[] cropNameList = StringUtils.split(customBlock.getId(), "_"); - int nextStage = Integer.parseInt(cropNameList[2]) + 1; - if (CustomBlock.getInstance(StringUtils.chop(namespacedID) + nextStage) == null) { - Crop cropInstance = ConfigReader.CROPS.get(cropNameList[0]); - if (ConfigReader.Config.quality){ - ThreadLocalRandom current = ThreadLocalRandom.current(); - int random = current.nextInt(cropInstance.getMin(), cropInstance.getMax() + 1); - World world = location.getWorld(); - Location itemLoc = location.clone().add(0.5,0.2,0.5); - Fertilizer fertilizer = PotManager.Cache.get(LocUtil.fromLocation(location.clone().subtract(0,1,0))); - List commands = cropInstance.getCommands(); - if (commands != null) - for (String command : commands) - Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), command.replace("{player}", player.getName())); - if (ConfigReader.Config.skillXP != null && cropInstance.getSkillXP() != 0) ConfigReader.Config.skillXP.addXp(player, cropInstance.getSkillXP()); - if (cropInstance.doesDropIALoot()) customBlock.getLoot().forEach(itemStack -> location.getWorld().dropItem(location.clone().add(0.5,0.2,0.5), itemStack)); - if (cropInstance.getOtherLoots() != null) cropInstance.getOtherLoots().forEach(s -> location.getWorld().dropItem(location.clone().add(0.5,0.2,0.5), CustomStack.getInstance(s).getItemStack())); - if (fertilizer != null){ - Fertilizer fConfig = ConfigReader.FERTILIZERS.get(fertilizer.getKey()); - if (fConfig == null) return; - if (fConfig instanceof QualityCrop qualityCrop){ - int[] weights = qualityCrop.getChance(); - double weightTotal = weights[0] + weights[1] + weights[2]; - for (int i = 0; i < random; i++){ - double ran = Math.random(); - if (ran < weights[0]/(weightTotal)) world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_1()).getItemStack()); - else if(ran > 1 - weights[1]/(weightTotal)) world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_2()).getItemStack()); - else world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_3()).getItemStack()); - } - }else if (fConfig instanceof YieldIncreasing yieldIncreasing){ - if (Math.random() < yieldIncreasing.getChance()){ - random += yieldIncreasing.getBonus(); - } - DropUtil.normalDrop(cropInstance, random, itemLoc, world); - } - else DropUtil.normalDrop(cropInstance, random, itemLoc, world); - } - else DropUtil.normalDrop(cropInstance, random, itemLoc, world); - } - else customBlock.getLoot().forEach(loot-> location.getWorld().dropItem(location.clone().add(0.5,0.2,0.5), loot)); - CustomBlock.remove(location); - AdventureManager.playerSound(player, ConfigReader.Sounds.harvestSource, ConfigReader.Sounds.harvestKey); - if(cropInstance.getReturnStage() != null){ - CustomBlock.place(cropInstance.getReturnStage(), location); - SimpleLocation simpleLocation = LocUtil.fromLocation(location); - CropManager.RemoveCache.remove(simpleLocation); - CropManager.Cache.put(simpleLocation, player.getName()); - } - } - } - } -} diff --git a/src/main/java/net/momirealms/customcrops/managers/CropManager.java b/src/main/java/net/momirealms/customcrops/managers/CropManager.java new file mode 100644 index 0000000..5667411 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/managers/CropManager.java @@ -0,0 +1,300 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.managers; + +import dev.lone.itemsadder.api.CustomStack; +import net.momirealms.customcrops.CustomCrops; +import net.momirealms.customcrops.Function; +import net.momirealms.customcrops.api.crop.Crop; +import net.momirealms.customcrops.api.event.CropHarvestEvent; +import net.momirealms.customcrops.config.BasicItemConfig; +import net.momirealms.customcrops.config.MainConfig; +import net.momirealms.customcrops.config.SeasonConfig; +import net.momirealms.customcrops.integrations.customplugin.CustomInterface; +import net.momirealms.customcrops.integrations.customplugin.HandlerP; +import net.momirealms.customcrops.integrations.customplugin.itemsadder.ItemsAdderFrameHandler; +import net.momirealms.customcrops.integrations.customplugin.itemsadder.ItemsAdderHook; +import net.momirealms.customcrops.integrations.customplugin.itemsadder.ItemsAdderWireHandler; +import net.momirealms.customcrops.integrations.customplugin.oraxen.OraxenFrameHandler; +import net.momirealms.customcrops.integrations.customplugin.oraxen.OraxenHook; +import net.momirealms.customcrops.integrations.customplugin.oraxen.OraxenWireHandler; +import net.momirealms.customcrops.integrations.season.CCSeason; +import net.momirealms.customcrops.integrations.season.InternalSeason; +import net.momirealms.customcrops.integrations.season.RealisticSeasonsHook; +import net.momirealms.customcrops.integrations.season.SeasonInterface; +import net.momirealms.customcrops.managers.listener.ItemSpawnListener; +import net.momirealms.customcrops.managers.listener.WorldListener; +import net.momirealms.customcrops.managers.timer.TimerTask; +import net.momirealms.customcrops.objects.OtherLoot; +import net.momirealms.customcrops.objects.QualityLoot; +import net.momirealms.customcrops.objects.QualityRatio; +import net.momirealms.customcrops.objects.actions.ActionInterface; +import net.momirealms.customcrops.objects.fertilizer.Fertilizer; +import net.momirealms.customcrops.objects.fertilizer.QualityCrop; +import net.momirealms.customcrops.objects.fertilizer.YieldIncreasing; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Nullable; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ThreadLocalRandom; + +public class CropManager extends Function { + + private ItemSpawnListener itemSpawnListener; + private WorldListener worldListener; + private TimerTask timerTask; + private ConcurrentHashMap customWorlds; + private CropModeInterface cropMode; + private SeasonInterface seasonInterface; + private CustomInterface customInterface; + private HandlerP handler; + + public CropManager() { + load(); + } + + @Override + public void load() { + super.load(); + this.customWorlds = new ConcurrentHashMap<>(); + + this.itemSpawnListener = new ItemSpawnListener(this); + this.worldListener = new WorldListener(this); + + //new Time Check task + this.timerTask = new TimerTask(this); + if (MainConfig.asyncTimeCheck) this.timerTask.runTaskTimerAsynchronously(CustomCrops.plugin, 1, 100); + else this.timerTask.runTaskTimer(CustomCrops.plugin, 1,100); + + //Crop mode + if (MainConfig.cropMode.equalsIgnoreCase("tripwire")) this.cropMode = new WireCropImpl(this); + else this.cropMode = new FrameCropImpl(this); + + if (MainConfig.customPlugin.equals("itemsadder")) { + customInterface = new ItemsAdderHook(); + if (MainConfig.cropMode.equalsIgnoreCase("tripwire")) this.handler = new ItemsAdderWireHandler(this); + else this.handler = new ItemsAdderFrameHandler(this); + } + else if (MainConfig.customPlugin.equals("oraxen")){ + customInterface = new OraxenHook(); + if (MainConfig.cropMode.equalsIgnoreCase("tripwire")) this.handler = new OraxenWireHandler(this); + else this.handler = new OraxenFrameHandler(this); + } + + handler.load(); + + if (SeasonConfig.enable) { + if (MainConfig.realisticSeasonHook) seasonInterface = new RealisticSeasonsHook(); + else seasonInterface = new InternalSeason(); + } + + //load Worlds + for (World world : Bukkit.getWorlds()) { + onWorldLoad(world); + } + } + + @Override + public void unload() { + super.unload(); + HandlerList.unregisterAll(this.itemSpawnListener); + HandlerList.unregisterAll(this.worldListener); + if (this.handler != null) handler.unload(); + this.timerTask.cancel(); + for (CustomWorld customWorld : customWorlds.values()) { + customWorld.unload(true); + } + customWorlds.clear(); + } + + public void onItemSpawn(Item item) { + String id = customInterface.getItemID(item.getItemStack()); + if (id == null) return; + if (id.contains("_stage_")) item.remove(); + } + + public void onWorldLoad(World world) { + CustomWorld cw = customWorlds.get(world); + if (cw != null) return; + if (MainConfig.getWorldsList().contains(world)) { + CustomWorld customWorld = new CustomWorld(world, this); + customWorlds.put(world, customWorld); + } + } + + public void onWorldUnload(World world, boolean disable) { + CustomWorld customWorld = customWorlds.get(world); + if (customWorld == null) return; + customWorld.unload(disable); + customWorlds.remove(world); + seasonInterface.unloadWorld(world); + } + + public void grow(World world, int time) { + CustomWorld customWorld = customWorlds.get(world); + if (customWorld == null) return; + if (MainConfig.cropMode.equals("tripwire")) customWorld.growWire(time); + else customWorld.growFrame(time); + } + + public CropModeInterface getCropMode() { + return cropMode; + } + + public SeasonInterface getSeasonAPI() { + return seasonInterface; + } + + public boolean hasGlass(Location location) { + for(int i = 1; i <= SeasonConfig.effectiveRange; i++){ + String blockID = customInterface.getBlockID(location); + if (blockID != null && blockID.equals(BasicItemConfig.greenHouseGlass)) return true; + } + return false; + } + + public CustomInterface getCustomInterface() { + return customInterface; + } + + public boolean isWrongSeason(Location location, CCSeason[] seasonList) { + if (!SeasonConfig.enable) return false; + if (seasonInterface.isWrongSeason(location.getWorld(), seasonList)) { + if (SeasonConfig.greenhouse) return !hasGlass(location); + else return true; + } + return false; + } + + @Nullable + public Fertilizer getFertilizer(Location potLoc) { + World world = potLoc.getWorld(); + CustomWorld customWorld = customWorlds.get(world); + if (customWorld == null) return null; + return customWorld.getFertilizer(potLoc); + } + + public void potDryJudge(Location potLoc) { + World world = potLoc.getWorld(); + CustomWorld customWorld = customWorlds.get(world); + if (customWorld == null) { + makePotDry(potLoc); + } + else if (!customWorld.isPotWet(potLoc)) { + makePotDry(potLoc); + } + } + + private void makePotDry(Location potLoc) { + customInterface.removeBlock(potLoc); + customInterface.placeNoteBlock(potLoc, BasicItemConfig.dryPot); + } + + public void makePotWet(Location potLoc) { + String potID = customInterface.getBlockID(potLoc); + if (potID == null) return; + if (!potID.equals(BasicItemConfig.dryPot)) return; + customInterface.removeBlock(potLoc); + customInterface.placeNoteBlock(potLoc, BasicItemConfig.wetPot); + } + + @Nullable + public CustomWorld getCustomWorld(World world) { + return customWorlds.get(world); + } + + public void proceedHarvest(Crop crop, Player player, Location location, @Nullable Fertilizer fertilizer) { + //Call harvest event + CropHarvestEvent cropHarvestEvent = new CropHarvestEvent(player, crop, location, fertilizer); + Bukkit.getPluginManager().callEvent(cropHarvestEvent); + if (cropHarvestEvent.isCancelled()) return; + + ActionInterface[] actions = crop.getActions(); + if (actions != null) performActions(actions, player); + + if (player.getGameMode() == GameMode.CREATIVE) return; + + Location itemLoc = location.clone().add(0.5,0.2,0.5); + + QualityLoot qualityLoot = crop.getQualityLoot(); + if (qualityLoot != null) { + int amount = ThreadLocalRandom.current().nextInt(qualityLoot.getMin(), qualityLoot.getMax() + 1); + QualityRatio qualityRatio = null; + if (fertilizer instanceof YieldIncreasing yieldIncreasing) { + if (Math.random() < yieldIncreasing.getChance()) { + amount += yieldIncreasing.getBonus(); + } + } + else if (fertilizer instanceof QualityCrop qualityCrop) { + if (Math.random() < qualityCrop.getChance()) { + qualityRatio = qualityCrop.getQualityRatio(); + } + } + dropQualityLoots(qualityLoot, amount, itemLoc, qualityRatio); + } + OtherLoot[] otherLoots = crop.getOtherLoots(); + if (otherLoots != null) dropOtherLoots(otherLoots, itemLoc); + } + + public void performActions(ActionInterface[] actions, Player player) { + for (ActionInterface action : actions) { + action.performOn(player); + } + } + + public void dropOtherLoots(OtherLoot[] otherLoots, Location location) { + for (OtherLoot otherLoot : otherLoots) { + if (Math.random() < otherLoot.getChance()) { + int random = ThreadLocalRandom.current().nextInt(otherLoot.getMin(), otherLoot.getMax() + 1); + ItemStack drop = CustomStack.getInstance(otherLoot.getItemID()).getItemStack(); + drop.setAmount(random); + location.getWorld().dropItem(location, drop); + } + } + } + + public void dropQualityLoots(QualityLoot qualityLoot, int amount, Location location, @Nullable QualityRatio qualityRatio) { + if (qualityRatio == null) qualityRatio = MainConfig.qualityRatio; + for (int i = 0; i < amount; i++) { + double random = Math.random(); + World world = location.getWorld(); + if (random < qualityRatio.getQuality_1()) { + ItemStack drop = customInterface.getItemStack(qualityLoot.getQuality_1()); + if (drop == null) continue; + world.dropItem(location, drop); + } + else if(random > qualityRatio.getQuality_2()){ + ItemStack drop = customInterface.getItemStack(qualityLoot.getQuality_2()); + if (drop == null) continue; + world.dropItem(location, drop); + } + else { + ItemStack drop = customInterface.getItemStack(qualityLoot.getQuality_3()); + if (drop == null) continue; + world.dropItem(location, drop); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/requirements/PlantingCondition.java b/src/main/java/net/momirealms/customcrops/managers/CropModeInterface.java similarity index 72% rename from src/main/java/net/momirealms/customcrops/requirements/PlantingCondition.java rename to src/main/java/net/momirealms/customcrops/managers/CropModeInterface.java index 206ec42..55588ec 100644 --- a/src/main/java/net/momirealms/customcrops/requirements/PlantingCondition.java +++ b/src/main/java/net/momirealms/customcrops/managers/CropModeInterface.java @@ -15,14 +15,13 @@ * along with this program. If not, see . */ -package net.momirealms.customcrops.requirements; +package net.momirealms.customcrops.managers; import org.bukkit.Location; -import org.bukkit.entity.Player; -public record PlantingCondition (Player player, Location location){ - public Location getLocation() { return location; } - public Player getPlayer() { - return player; - } +public interface CropModeInterface { + + boolean growJudge(Location location); + void loadChunk(Location location); + } diff --git a/src/main/java/net/momirealms/customcrops/managers/CustomWorld.java b/src/main/java/net/momirealms/customcrops/managers/CustomWorld.java new file mode 100644 index 0000000..ffb6bed --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/managers/CustomWorld.java @@ -0,0 +1,300 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.managers; + +import net.momirealms.customcrops.CustomCrops; +import net.momirealms.customcrops.api.event.CustomWorldEvent; +import net.momirealms.customcrops.config.ConfigUtil; +import net.momirealms.customcrops.config.CropConfig; +import net.momirealms.customcrops.config.FertilizerConfig; +import net.momirealms.customcrops.config.SprinklerConfig; +import net.momirealms.customcrops.objects.SimpleLocation; +import net.momirealms.customcrops.objects.Sprinkler; +import net.momirealms.customcrops.objects.WorldState; +import net.momirealms.customcrops.objects.fertilizer.Fertilizer; +import net.momirealms.customcrops.utils.AdventureUtil; +import net.momirealms.customcrops.utils.MiscUtils; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.scheduler.BukkitScheduler; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.io.IOException; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +public class CustomWorld { + + private final World world; + private final ConcurrentHashMap cropCache; + private final ConcurrentHashMap sprinklerCache; + private final ConcurrentHashMap fertilizerCache; + private final Set watered; + private final CropManager cropManager; + + public CustomWorld(World world, CropManager cropManager) { + this.world = world; + this.cropCache = new ConcurrentHashMap<>(4096); + this.fertilizerCache = new ConcurrentHashMap<>(2048); + this.sprinklerCache = new ConcurrentHashMap<>(1024); + this.cropManager = cropManager; + this.watered = Collections.synchronizedSet(new HashSet<>()); + Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.plugin, () -> { + loadCropCache(); + loadSprinklerCache(); + loadFertilizerCache(); + Bukkit.getScheduler().runTask(CustomCrops.plugin, () -> { + CustomWorldEvent customWorldEvent = new CustomWorldEvent(world, WorldState.LOAD); + Bukkit.getPluginManager().callEvent(customWorldEvent); + }); + }); + } + + public void unload(boolean disable) { + if (disable) { + unloadCrop(); + unloadSprinkler(); + unloadFertilizer(); + } + else { + Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.plugin, () -> { + unloadCrop(); + unloadSprinkler(); + unloadFertilizer(); + Bukkit.getScheduler().runTask(CustomCrops.plugin, () -> { + CustomWorldEvent customWorldEvent = new CustomWorldEvent(world, WorldState.UNLOAD); + Bukkit.getPluginManager().callEvent(customWorldEvent); + }); + }); + } + } + + private void loadFertilizerCache() { + YamlConfiguration data = loadData("fertilizers", world.getName()); + for (String key : data.getKeys(false)) { + String[] loc = StringUtils.split(key, ","); + SimpleLocation location = new SimpleLocation(world.getName(), Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2])); + String fertilizer = data.getString(key + ".type"); + int times = data.getInt(key + ".times"); + Fertilizer fertilizerConfig = FertilizerConfig.FERTILIZERS.get(fertilizer); + if (fertilizerConfig != null) { + fertilizerCache.put(location, fertilizerConfig.getWithTimes(times)); + } + } + } + + private void unloadFertilizer() { + YamlConfiguration data = new YamlConfiguration(); + for (Map.Entry en : fertilizerCache.entrySet()) { + SimpleLocation location = en.getKey(); + String loc = location.getX() + "," + location.getY() + "," + location.getZ(); + data.set(loc + ".times", en.getValue().getTimes()); + data.set(loc + ".type", en.getValue().getKey()); + } + try { + data.save(new File(CustomCrops.plugin.getDataFolder().getParentFile().getParentFile(), world.getName() + File.separator + "customcrops_data" + File.separator + "fertilizers.yml")); + } + catch (IOException e) { + e.printStackTrace(); + AdventureUtil.consoleMessage("[CustomCrops] Failed to save pot data for world " + world.getName() + ""); + } + } + + private void loadSprinklerCache() { + YamlConfiguration data = loadData("sprinklers", world.getName()); + for (String key : data.getKeys(false)) { + String[] loc = StringUtils.split(key, ","); + SimpleLocation location = new SimpleLocation(world.getName(), Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2])); + String sprinkler = data.getString(key + ".type"); + int water = data.getInt(key + ".water"); + Sprinkler sprinklerConfig = SprinklerConfig.SPRINKLERS_CONFIG.get(sprinkler + "CONFIG"); + if (sprinklerConfig != null) { + if (water > sprinklerConfig.getWater()) water = sprinklerConfig.getWater(); + Sprinkler sprinklerInstance = new Sprinkler(sprinklerConfig.getKey(), sprinklerConfig.getRange(), water); + sprinklerCache.put(location, sprinklerInstance); + } + } + } + + private void unloadSprinkler() { + YamlConfiguration data = new YamlConfiguration(); + for (Map.Entry en : sprinklerCache.entrySet()) { + SimpleLocation location = en.getKey(); + String loc = location.getX() + "," + location.getY() + "," + location.getZ(); + data.set(loc + ".water", en.getValue().getWater()); + data.set(loc + ".type", en.getValue().getKey()); + } + try { + data.save(new File(CustomCrops.plugin.getDataFolder().getParentFile().getParentFile(), world.getName() + File.separator + "customcrops_data" + File.separator + "sprinklers.yml")); + } + catch (IOException e) { + e.printStackTrace(); + AdventureUtil.consoleMessage("[CustomCrops] Failed to save sprinkler data for world " + world.getName() + ""); + } + } + + private void loadCropCache() { + YamlConfiguration data = loadData("crops", world.getName()); + for (String key : data.getKeys(false)) { + String[] loc = StringUtils.split(key, ","); + SimpleLocation location = new SimpleLocation(world.getName(), Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2])); + String crop = data.getString(key); + if (crop == null) return; + if (CropConfig.CROPS.containsKey(crop)) { + cropCache.put(location, crop); + } + } + } + + private void unloadCrop() { + YamlConfiguration data = new YamlConfiguration(); + for (Map.Entry en : cropCache.entrySet()) { + SimpleLocation location = en.getKey(); + String loc = location.getX() + "," + location.getY() + "," + location.getZ(); + data.set(loc, en.getValue()); + } + try { + data.save(new File(CustomCrops.plugin.getDataFolder().getParentFile().getParentFile(), world.getName() + File.separator + "customcrops_data" + File.separator + "crops.yml")); + } + catch (IOException e) { + e.printStackTrace(); + AdventureUtil.consoleMessage("[CustomCrops] Failed to save crop data for world " + world.getName() + ""); + } + } + + public void growWire(int time) { + BukkitScheduler bukkitScheduler = Bukkit.getScheduler(); + CropModeInterface cropMode = cropManager.getCropMode(); + bukkitScheduler.runTaskAsynchronously(CustomCrops.plugin, () -> { + route(); + for (SimpleLocation location : cropCache.keySet()) { + bukkitScheduler.runTaskLaterAsynchronously(CustomCrops.plugin, () -> { + Location seedLoc = MiscUtils.getLocation(location); + if (seedLoc == null) return; + if (cropMode.growJudge(seedLoc)) { + cropCache.remove(location); + } + }, new Random().nextInt(time)); + } + }); + } + + public void growFrame(int time) { + BukkitScheduler bukkitScheduler = Bukkit.getScheduler(); + CropModeInterface cropMode = cropManager.getCropMode(); + bukkitScheduler.runTaskAsynchronously(CustomCrops.plugin, () -> { + route(); + for (SimpleLocation location : cropCache.keySet()) { + long random = new Random().nextInt(time); + bukkitScheduler.runTaskLater(CustomCrops.plugin, () -> { + Location seedLoc = MiscUtils.getLocation(location); + if (seedLoc == null) return; + cropMode.loadChunk(seedLoc); + }, random); + bukkitScheduler.runTaskLater(CustomCrops.plugin, () -> { + Location seedLoc = MiscUtils.getLocation(location); + if (seedLoc == null) return; + if (cropMode.growJudge(seedLoc)) { + cropCache.remove(location); + } + }, random + 5); + } + }); + } + + private void route() { + watered.clear(); + for (Map.Entry sprinklerEntry : sprinklerCache.entrySet()) { + sprinklerWork(sprinklerEntry.getKey(), sprinklerEntry.getValue()); + } + for (Map.Entry fertilizerEntry : fertilizerCache.entrySet()) { + Fertilizer fertilizer = fertilizerEntry.getValue(); + if (fertilizer.getTimes() > 1) { + fertilizer.setTimes(fertilizer.getTimes() - 1); + } + else { + fertilizerCache.remove(fertilizerEntry.getKey()); + } + } + } + + public YamlConfiguration loadData(String data, String worldName) { + return ConfigUtil.readData(new File(CustomCrops.plugin.getDataFolder().getParentFile().getParentFile(), worldName + File.separator + "customcrops_data" + File.separator + data +".yml")); + } + + /** + * Sprinkler Work + * @param location sprinkler location + */ + public void sprinklerWork(SimpleLocation location, Sprinkler sprinkler) { + if (sprinkler.getWater() <= 0) return; + Location sprinklerLoc = MiscUtils.getLocation(location); + if (sprinklerLoc == null) return; + sprinkler.setWater(sprinkler.getWater() - 1); + int range = sprinkler.getRange(); + for(int i = -range; i <= range; i++){ + for (int j = -range; j <= range; j++){ + Location wetLoc = sprinklerLoc.clone().add(i,-1,j); + cropManager.makePotWet(wetLoc); + watered.add(MiscUtils.getSimpleLocation(wetLoc)); + } + } + } + + @Nullable + public Fertilizer getFertilizer(Location potLoc) { + return fertilizerCache.get(MiscUtils.getSimpleLocation(potLoc)); + } + + public boolean isPotWet(Location potLoc) { + return watered.contains(MiscUtils.getSimpleLocation(potLoc)); + } + + public void removeFertilizer(Location potLoc) { + fertilizerCache.remove(MiscUtils.getSimpleLocation(potLoc)); + } + + public void addFertilizer(Location potLoc, Fertilizer fertilizer) { + fertilizerCache.put(MiscUtils.getSimpleLocation(potLoc), fertilizer); + } + + public void removeCrop(Location cropLoc) { + cropCache.remove(MiscUtils.getSimpleLocation(cropLoc)); + } + + @Nullable + public Sprinkler getSprinkler(Location location) { + return sprinklerCache.get(MiscUtils.getSimpleLocation(location)); + } + + public void addCrop(Location cropLoc, String crop) { + cropCache.put(MiscUtils.getSimpleLocation(cropLoc), crop); + } + + public void removeSprinkler(Location location) { + sprinklerCache.remove(MiscUtils.getSimpleLocation(location)); + } + + public void addSprinkler(Location location, Sprinkler sprinkler) { + sprinklerCache.put(MiscUtils.getSimpleLocation(location), sprinkler); + } +} diff --git a/src/main/java/net/momirealms/customcrops/managers/FrameCropImpl.java b/src/main/java/net/momirealms/customcrops/managers/FrameCropImpl.java new file mode 100644 index 0000000..16f0b32 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/managers/FrameCropImpl.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.managers; + +import net.momirealms.customcrops.api.crop.Crop; +import net.momirealms.customcrops.config.BasicItemConfig; +import net.momirealms.customcrops.config.CropConfig; +import net.momirealms.customcrops.config.MainConfig; +import net.momirealms.customcrops.integrations.customplugin.CustomInterface; +import net.momirealms.customcrops.integrations.customplugin.oraxen.OraxenHook; +import net.momirealms.customcrops.objects.GiganticCrop; +import net.momirealms.customcrops.objects.fertilizer.Fertilizer; +import net.momirealms.customcrops.objects.fertilizer.RetainingSoil; +import net.momirealms.customcrops.objects.fertilizer.SpeedGrow; +import net.momirealms.customcrops.utils.FurnitureUtil; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.entity.ItemFrame; +import org.bukkit.persistence.PersistentDataType; + +public class FrameCropImpl implements CropModeInterface { + + private final CropManager cropManager; + private final CustomInterface customInterface; + + public FrameCropImpl(CropManager cropManager) { + this.cropManager = cropManager; + this.customInterface = cropManager.getCustomInterface(); + } + + @Override + public void loadChunk(Location location) { + Chunk chunk = location.getChunk(); + chunk.load(); + } + + @Override + public boolean growJudge(Location location) { + + Chunk chunk = location.getChunk(); + + if (chunk.isEntitiesLoaded()) { + + ItemFrame itemFrame = FurnitureUtil.getItemFrame(location); + if (itemFrame == null) return true; + String id = customInterface.getItemID(itemFrame.getItem()); + if (id == null) return true; + if (id.equals(BasicItemConfig.deadCrop)) return true; + + String[] cropNameList = StringUtils.split(id,"_"); + String cropKey = cropNameList[0]; + if (cropKey.contains(":")) cropKey = StringUtils.split(cropKey, ":")[1]; + Crop crop = CropConfig.CROPS.get(cropKey); + if (crop == null) return true; + if (cropManager.isWrongSeason(location, crop.getSeasons())) { + itemFrame.setItem(customInterface.getItemStack(BasicItemConfig.deadCrop)); + if (MainConfig.OraxenHook) itemFrame.getPersistentDataContainer().set(OraxenHook.FURNITURE, PersistentDataType.STRING, BasicItemConfig.deadCrop); + return true; + } + + Location potLoc = location.clone().subtract(0,1,0); + String potID = customInterface.getBlockID(potLoc); + if (potID == null) return true; + + Fertilizer fertilizer = cropManager.getFertilizer(potLoc); + + boolean certainGrow = false; + if (potID.equals(BasicItemConfig.wetPot)) { + if (!(fertilizer instanceof RetainingSoil retainingSoil && Math.random() < retainingSoil.getChance())) { + cropManager.potDryJudge(potLoc); + } + certainGrow = true; + } + + int nextStage = Integer.parseInt(cropNameList[2]) + 1; + String temp = StringUtils.chop(id); + if (customInterface.doesExist(temp + nextStage)) { + if (fertilizer instanceof SpeedGrow speedGrow && Math.random() < speedGrow.getChance()) { + if (customInterface.doesExist(temp + (nextStage+1))) { + addStage(itemFrame, temp + (nextStage+1)); + } + } + else if (certainGrow || Math.random() < MainConfig.dryGrowChance) { + addStage(itemFrame, temp + nextStage); + } + } + else { + GiganticCrop giganticCrop = crop.getGiganticCrop(); + if (giganticCrop != null && Math.random() < giganticCrop.getChance()) { + customInterface.removeFurniture(itemFrame); + if (giganticCrop.isBlock()) { + customInterface.placeWire(location, giganticCrop.getBlockID()); + } + else { + customInterface.placeFurniture(location, giganticCrop.getBlockID()); + } + } + return true; + } + } + return false; + } + + private void addStage(ItemFrame itemFrame, String stage) { + itemFrame.setItem(customInterface.getItemStack(stage)); + if (!MainConfig.OraxenHook) itemFrame.getPersistentDataContainer().set(OraxenHook.FURNITURE, PersistentDataType.STRING, stage); + } +} diff --git a/src/main/java/net/momirealms/customcrops/managers/WireCropImpl.java b/src/main/java/net/momirealms/customcrops/managers/WireCropImpl.java new file mode 100644 index 0000000..8bcac47 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/managers/WireCropImpl.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.managers; + +import net.momirealms.customcrops.api.crop.Crop; +import net.momirealms.customcrops.config.BasicItemConfig; +import net.momirealms.customcrops.config.CropConfig; +import net.momirealms.customcrops.config.MainConfig; +import net.momirealms.customcrops.integrations.customplugin.CustomInterface; +import net.momirealms.customcrops.objects.GiganticCrop; +import net.momirealms.customcrops.objects.fertilizer.Fertilizer; +import net.momirealms.customcrops.objects.fertilizer.Gigantic; +import net.momirealms.customcrops.objects.fertilizer.RetainingSoil; +import net.momirealms.customcrops.objects.fertilizer.SpeedGrow; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Chunk; +import org.bukkit.Location; + +public class WireCropImpl implements CropModeInterface{ + + private final CropManager cropManager; + private final CustomInterface customInterface; + + public WireCropImpl(CropManager cropManager) { + this.cropManager = cropManager; + this.customInterface = cropManager.getCustomInterface(); + } + + @Override + public void loadChunk(Location location) { + Chunk chunk = location.getChunk(); + chunk.load(); + } + + @Override + public boolean growJudge(Location location) { + String blockID = customInterface.getBlockID(location); + if (blockID == null) return true; + if (!blockID.contains("_stage_")) return true; + String[] cropNameList = StringUtils.split(blockID,"_"); + String cropKey = cropNameList[0]; + if (cropKey.contains(":")) cropKey = StringUtils.split(cropKey, ":")[1]; + Crop crop = CropConfig.CROPS.get(cropKey); + if (crop == null) return true; + if (cropManager.isWrongSeason(location, crop.getSeasons())) { + customInterface.removeBlock(location); + customInterface.placeWire(location, BasicItemConfig.deadCrop); + return true; + } + Location potLoc = location.clone().subtract(0,1,0); + String potID = customInterface.getBlockID(potLoc); + if (potID == null) return true; + + Fertilizer fertilizer = cropManager.getFertilizer(potLoc); + + boolean certainGrow = false; + if (potID.equals(BasicItemConfig.wetPot)) { + if (!(fertilizer instanceof RetainingSoil retainingSoil && Math.random() < retainingSoil.getChance())) { + cropManager.potDryJudge(potLoc); + } + certainGrow = true; + } + + int nextStage = Integer.parseInt(cropNameList[2]) + 1; + String temp = StringUtils.chop(blockID); + if (customInterface.doesExist(temp + nextStage)) { + if (fertilizer instanceof SpeedGrow speedGrow && Math.random() < speedGrow.getChance()) { + if (customInterface.doesExist(temp + (nextStage+1))) { + addStage(location, temp + (nextStage+1)); + } + } + else if (certainGrow || Math.random() < MainConfig.dryGrowChance) { + addStage(location, temp + nextStage); + } + } + else { + GiganticCrop giganticCrop = crop.getGiganticCrop(); + if (giganticCrop != null) { + double chance = giganticCrop.getChance(); + if (fertilizer instanceof Gigantic gigantic) { + chance += gigantic.getChance(); + } + if (Math.random() < chance) { + customInterface.removeBlock(location); + if (giganticCrop.isBlock()) { + customInterface.placeWire(location, giganticCrop.getBlockID()); + } + else { + customInterface.placeFurniture(location, giganticCrop.getBlockID()); + } + } + } + return true; + } + return false; + } + + private void addStage(Location seedLoc, String stage) { + customInterface.removeBlock(seedLoc); + customInterface.placeWire(seedLoc, stage); + } +} diff --git a/src/main/java/net/momirealms/customcrops/managers/listener/InteractListener.java b/src/main/java/net/momirealms/customcrops/managers/listener/InteractListener.java new file mode 100644 index 0000000..c1bc751 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/managers/listener/InteractListener.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.managers.listener; + +import net.momirealms.customcrops.integrations.customplugin.HandlerP; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +public class InteractListener implements Listener { + + private final HandlerP handlerP; + + public InteractListener(HandlerP handlerP) { + this.handlerP = handlerP; + } + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + handlerP.onPlayerInteract(event); + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) { + handlerP.onQuit(event.getPlayer()); + } +} diff --git a/src/main/java/net/momirealms/customcrops/listener/ItemSpawn.java b/src/main/java/net/momirealms/customcrops/managers/listener/ItemSpawnListener.java similarity index 64% rename from src/main/java/net/momirealms/customcrops/listener/ItemSpawn.java rename to src/main/java/net/momirealms/customcrops/managers/listener/ItemSpawnListener.java index ee345f0..3ef0504 100644 --- a/src/main/java/net/momirealms/customcrops/listener/ItemSpawn.java +++ b/src/main/java/net/momirealms/customcrops/managers/listener/ItemSpawnListener.java @@ -15,21 +15,26 @@ * along with this program. If not, see . */ -package net.momirealms.customcrops.listener; +package net.momirealms.customcrops.managers.listener; -import dev.lone.itemsadder.api.CustomStack; +import net.momirealms.customcrops.managers.CropManager; import org.bukkit.entity.Item; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntitySpawnEvent; -public class ItemSpawn implements Listener { +public class ItemSpawnListener implements Listener { + + private final CropManager cropManager; + + public ItemSpawnListener(CropManager cropManager) { + this.cropManager = cropManager; + } @EventHandler - public void entitySpawn(EntitySpawnEvent event){ - if(event.getEntity() instanceof Item item) - if(CustomStack.byItemStack(item.getItemStack()) != null) - if(CustomStack.byItemStack(item.getItemStack()).getId().contains("_stage_")) - item.remove(); + public void onItemSpawn(EntitySpawnEvent event) { + if (event.getEntity() instanceof Item item) { + cropManager.onItemSpawn(item); + } } -} \ No newline at end of file +} diff --git a/src/main/java/net/momirealms/customcrops/managers/listener/WorldListener.java b/src/main/java/net/momirealms/customcrops/managers/listener/WorldListener.java new file mode 100644 index 0000000..ebcd38b --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/managers/listener/WorldListener.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.managers.listener; + +import net.momirealms.customcrops.managers.CropManager; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.world.WorldLoadEvent; +import org.bukkit.event.world.WorldUnloadEvent; + +public class WorldListener implements Listener { + + private final CropManager cropManager; + + public WorldListener(CropManager cropManager) { + this.cropManager = cropManager; + } + + @EventHandler + public void onWorldUnload(WorldLoadEvent event) { + System.out.println("load"); + cropManager.onWorldLoad(event.getWorld()); + } + + @EventHandler + public void onWorldUnload(WorldUnloadEvent event) { + System.out.println("unload"); + cropManager.onWorldUnload(event.getWorld(), false); + } +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/RealisticSeason.java b/src/main/java/net/momirealms/customcrops/managers/timer/TimerTask.java similarity index 54% rename from src/main/java/net/momirealms/customcrops/integrations/RealisticSeason.java rename to src/main/java/net/momirealms/customcrops/managers/timer/TimerTask.java index a4ab22a..79f6c21 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/RealisticSeason.java +++ b/src/main/java/net/momirealms/customcrops/managers/timer/TimerTask.java @@ -15,29 +15,28 @@ * along with this program. If not, see . */ -package net.momirealms.customcrops.integrations; +package net.momirealms.customcrops.managers.timer; -import me.casperge.realisticseasons.api.SeasonsAPI; +import net.momirealms.customcrops.config.MainConfig; +import net.momirealms.customcrops.managers.CropManager; import org.bukkit.World; +import org.bukkit.scheduler.BukkitRunnable; -public class RealisticSeason { +public class TimerTask extends BukkitRunnable { - public static String getSeason(World world){ - SeasonsAPI seasonsapi = SeasonsAPI.getInstance(); - switch (seasonsapi.getSeason(world)){ - case SPRING -> { - return "spring"; - } - case SUMMER -> { - return "summer"; - } - case WINTER -> { - return "winter"; - } - case FALL -> { - return "autumn"; + private final CropManager cropManager; + + public TimerTask(CropManager cropManager) { + this.cropManager = cropManager; + } + + @Override + public void run() { + for (World world : MainConfig.getWorldsList()) { + long time = world.getTime(); + if (time > 950 && time < 1051) { + cropManager.grow(world, MainConfig.timeToGrow); } } - return "null"; } } diff --git a/src/main/java/net/momirealms/customcrops/objects/CCCrop.java b/src/main/java/net/momirealms/customcrops/objects/CCCrop.java new file mode 100644 index 0000000..38a860f --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/CCCrop.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects; + +import net.momirealms.customcrops.api.crop.Crop; +import net.momirealms.customcrops.integrations.season.CCSeason; +import net.momirealms.customcrops.objects.actions.ActionInterface; +import net.momirealms.customcrops.objects.requirements.RequirementInterface; + +public class CCCrop implements Crop { + + private CCSeason[] seasons; + private RequirementInterface[] requirementInterfaces; + private String returnStage; + private QualityLoot qualityLoot; + private GiganticCrop giganticCrop; + private double skillXP; + private OtherLoot[] otherLoots; + private ActionInterface[] actions; + private final String key; + + public CCCrop(String key) { + this.key = key; + } + + public QualityLoot getQualityLoot() { + return qualityLoot; + } + + public void setQualityLoot(QualityLoot qualityLoot) { + this.qualityLoot = qualityLoot; + } + + public String getKey() { + return key; + } + + public CCSeason[] getSeasons() { + return seasons; + } + + public RequirementInterface[] getRequirements() { + return requirementInterfaces; + } + + public String getReturnStage() { + return returnStage; + } + + public GiganticCrop getGiganticCrop() { + return giganticCrop; + } + + public double getSkillXP() { + return skillXP; + } + + public OtherLoot[] getOtherLoots() { + return otherLoots; + } + + public ActionInterface[] getActions() { + return actions; + } + + public void setSeasons(CCSeason[] seasons) { + this.seasons = seasons; + } + + public void setRequirements(RequirementInterface[] requirementInterfaces) { + this.requirementInterfaces = requirementInterfaces; + } + + public void setReturnStage(String returnStage) { + this.returnStage = returnStage; + } + + public void setGiganticCrop(GiganticCrop giganticCrop) { + this.giganticCrop = giganticCrop; + } + + public void setSkillXP(double skillXP) { + this.skillXP = skillXP; + } + + public void setOtherLoots(OtherLoot[] otherLoots) { + this.otherLoots = otherLoots; + } + + public void setActions(ActionInterface[] actions) { + this.actions = actions; + } +} diff --git a/src/main/java/net/momirealms/customcrops/objects/Crop.java b/src/main/java/net/momirealms/customcrops/objects/Crop.java deleted file mode 100644 index 5a5f712..0000000 --- a/src/main/java/net/momirealms/customcrops/objects/Crop.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.objects; - -import net.momirealms.customcrops.requirements.Requirement; - -import java.util.List; - -public class Crop { - - private double giantChance; - private String giant; - private List requirements; - private List seasons; - private List otherLoots; - private String returnStage; - private final int min; - private final int max; - private String quality_1; - private String quality_2; - private String quality_3; - private double skillXP; - private boolean dropIALoot; - private List commands; - private double growChance; - private boolean isBlock; - - public Crop(int min, int max){ - this.min = min; - this.max = max; - } - - public String getReturnStage(){ - return this.returnStage; - } - public String getGiant(){ - return this.giant; - } - public double getGiantChance() { return this.giantChance; } - public List getRequirements() {return requirements;} - public List getSeasons() {return seasons;} - public String getQuality_1() { return quality_1; } - public String getQuality_2() { return quality_2; } - public String getQuality_3() { return quality_3; } - public int getMax() { return max; } - public int getMin() { return min; } - public List getCommands() { return commands; } - public double getSkillXP() {return skillXP;} - public boolean doesDropIALoot() {return dropIALoot;} - public double getGrowChance() {return growChance;} - public boolean isBlock() {return isBlock;} - public List getOtherLoots() {return otherLoots;} - - public void setReturnStage(String stage){ this.returnStage = stage; } - public void setGiant(String giant) { this.giant = giant; } - public void setGiantChance(double giantChance) { this.giantChance = giantChance; } - public void setRequirements(List requirements) { this.requirements = requirements; } - public void setSeasons(List seasons) { this.seasons = seasons; } - public void setQuality_1(String quality_1) { this.quality_1 = quality_1; } - public void setQuality_2(String quality_2) { this.quality_2 = quality_2; } - public void setQuality_3(String quality_3) { this.quality_3 = quality_3; } - public void setCommands(List commands) { this.commands = commands; } - public void setSkillXP(double skillXP) {this.skillXP = skillXP;} - public void setDropIALoot(boolean dropIALoot) {this.dropIALoot = dropIALoot;} - public void setGrowChance(double growChance) {this.growChance = growChance;} - public void setIsBlock(boolean isBlock) {this.isBlock = isBlock;} - public void setOtherLoots(List otherLoots) {this.otherLoots = otherLoots;} -} diff --git a/src/main/java/net/momirealms/customcrops/objects/GiganticCrop.java b/src/main/java/net/momirealms/customcrops/objects/GiganticCrop.java new file mode 100644 index 0000000..aae4cc2 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/GiganticCrop.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects; + +public class GiganticCrop { + + private final double chance; + private final boolean isBlock; + private final String blockID; + + public GiganticCrop(double chance, boolean isBlock, String blockID) { + this.chance = chance; + this.isBlock = isBlock; + this.blockID = blockID; + } + + public double getChance() { + return chance; + } + + public boolean isBlock() { + return isBlock; + } + + public String getBlockID() { + return blockID; + } +} diff --git a/src/main/java/net/momirealms/customcrops/objects/OtherLoot.java b/src/main/java/net/momirealms/customcrops/objects/OtherLoot.java new file mode 100644 index 0000000..9fcfbbb --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/OtherLoot.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects; + +public class OtherLoot { + + private final int min; + private final int max; + private final String itemID; + private final double chance; + + public OtherLoot(int min, int max, String itemID, double chance) { + this.min = min; + this.max = max; + this.itemID = itemID; + this.chance = chance; + } + + public int getMin() { + return min; + } + + public int getMax() { + return max; + } + + public String getItemID() { + return itemID; + } + + public double getChance() { + return chance; + } +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/objects/QualityLoot.java b/src/main/java/net/momirealms/customcrops/objects/QualityLoot.java new file mode 100644 index 0000000..c6dcce1 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/QualityLoot.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects; + +public class QualityLoot { + + private final int min; + private final int max; + + private final String quality_1; + private final String quality_2; + private final String quality_3; + + public QualityLoot(int min, int max, String quality_1, String quality_2, String quality_3) { + this.quality_1 = quality_1; + this.quality_2 = quality_2; + this.quality_3 = quality_3; + this.max = max; + this.min = min; + } + + public String getQuality_1() { + return quality_1; + } + + public String getQuality_2() { + return quality_2; + } + + public String getQuality_3() { + return quality_3; + } + + public int getMin() { + return min; + } + + public int getMax() { + return max; + } +} diff --git a/src/main/java/net/momirealms/customcrops/objects/QualityRatio.java b/src/main/java/net/momirealms/customcrops/objects/QualityRatio.java new file mode 100644 index 0000000..9dc7155 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/QualityRatio.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects; + +public class QualityRatio { + + private final double quality_1; + private final double quality_2; + + public QualityRatio(double quality_1, double quality_2) { + this.quality_1 = quality_1; + this.quality_2 = quality_2; + } + + public double getQuality_1() { + return quality_1; + } + + public double getQuality_2() { + return quality_2; + } +} diff --git a/src/main/java/net/momirealms/customcrops/objects/ScareCow.java b/src/main/java/net/momirealms/customcrops/objects/ScareCow.java new file mode 100644 index 0000000..cbda47a --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/ScareCow.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects; + +public class ScareCow { +} diff --git a/src/main/java/net/momirealms/customcrops/objects/SimpleLocation.java b/src/main/java/net/momirealms/customcrops/objects/SimpleLocation.java index 08ef6c3..e984185 100644 --- a/src/main/java/net/momirealms/customcrops/objects/SimpleLocation.java +++ b/src/main/java/net/momirealms/customcrops/objects/SimpleLocation.java @@ -71,4 +71,4 @@ public class SimpleLocation { hash = 19 * hash + (int) (Double.doubleToLongBits(this.z) ^ (Double.doubleToLongBits(this.z) >>> 32)); return hash; } -} +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/objects/Sprinkler.java b/src/main/java/net/momirealms/customcrops/objects/Sprinkler.java index 7d851f0..72d3f63 100644 --- a/src/main/java/net/momirealms/customcrops/objects/Sprinkler.java +++ b/src/main/java/net/momirealms/customcrops/objects/Sprinkler.java @@ -17,28 +17,65 @@ package net.momirealms.customcrops.objects; +import org.jetbrains.annotations.Nullable; + public class Sprinkler { - private int water; private int range; - private String player; - private String namespacedID_1; - private String namespacedID_2; + private int water; + private final String key; + private String twoD; + private String threeD; - public Sprinkler(int range, int water){ + public Sprinkler(String key, int range, int water) { + this.range = range; this.water = water; + this.key = key; + } + + public int getRange() { + return range; + } + + public void setRange(int range) { this.range = range; } - public int getWater() {return water;} - public String getNamespacedID_1() {return namespacedID_1;} - public String getNamespacedID_2() {return namespacedID_2;} - public int getRange() {return range;} - public String getPlayer() {return player;} + public int getWater() { + return water; + } - public void setRange(int range) {this.range = range;} - public void setNamespacedID_2(String namespacedID_2) {this.namespacedID_2 = namespacedID_2;} - public void setNamespacedID_1(String namespacedID_1) {this.namespacedID_1 = namespacedID_1;} - public void setWater(int water) {this.water = water;} - public void setPlayer(String player) {this.player = player;} + public void setWater(int water) { + this.water = water; + } + + public String getKey() { + return key; + } + + /** + * Only needed in config + * @return twoD + */ + @Nullable + public String getTwoD() { + return twoD; + } + + public void setTwoD(String twoD) { + this.twoD = twoD; + } + + /** + * Only needed in config + * @return threeD + */ + @Nullable + public String getThreeD() { + return threeD; + } + + public void setThreeD(String threeD) { + this.threeD = threeD; + } } diff --git a/src/main/java/net/momirealms/customcrops/objects/WateringCan.java b/src/main/java/net/momirealms/customcrops/objects/WaterCan.java similarity index 93% rename from src/main/java/net/momirealms/customcrops/objects/WateringCan.java rename to src/main/java/net/momirealms/customcrops/objects/WaterCan.java index a014416..f84bd55 100644 --- a/src/main/java/net/momirealms/customcrops/objects/WateringCan.java +++ b/src/main/java/net/momirealms/customcrops/objects/WaterCan.java @@ -17,7 +17,7 @@ package net.momirealms.customcrops.objects; -public record WateringCan(int max, int width, int length) { +public record WaterCan(int max, int width, int length) { public int getMax() { return max; @@ -30,5 +30,4 @@ public record WateringCan(int max, int width, int length) { public int getWidth() { return width; } - -} +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/objects/WorldState.java b/src/main/java/net/momirealms/customcrops/objects/WorldState.java new file mode 100644 index 0000000..171dc0e --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/WorldState.java @@ -0,0 +1,8 @@ +package net.momirealms.customcrops.objects; + +public enum WorldState { + + LOAD, + UNLOAD + +} diff --git a/src/main/java/net/momirealms/customcrops/objects/WrappedSound.java b/src/main/java/net/momirealms/customcrops/objects/WrappedSound.java new file mode 100644 index 0000000..4128560 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/WrappedSound.java @@ -0,0 +1,29 @@ +package net.momirealms.customcrops.objects; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.sound.Sound; + +public class WrappedSound { + + private final Sound.Source source; + private final Key key; + private final boolean enable; + + public WrappedSound(Sound.Source source, Key key, boolean enable) { + this.source = source; + this.key = key; + this.enable = enable; + } + + public Sound.Source getSource() { + return source; + } + + public Key getKey() { + return key; + } + + public boolean isEnable() { + return enable; + } +} diff --git a/src/main/java/net/momirealms/customcrops/objects/actions/ActionCommand.java b/src/main/java/net/momirealms/customcrops/objects/actions/ActionCommand.java new file mode 100644 index 0000000..64b97cc --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/actions/ActionCommand.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.actions; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +public class ActionCommand implements ActionInterface { + + private final String[] commands; + + public ActionCommand(String[] commands) { + this.commands = commands; + } + + @Override + public void performOn(Player player) { + for (String command : commands) { + Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), command.replace("{player}", player.getName())); + } + } +} diff --git a/src/main/java/net/momirealms/customcrops/integrations/protection/Integration.java b/src/main/java/net/momirealms/customcrops/objects/actions/ActionInterface.java similarity index 75% rename from src/main/java/net/momirealms/customcrops/integrations/protection/Integration.java rename to src/main/java/net/momirealms/customcrops/objects/actions/ActionInterface.java index 2a7402d..14176d5 100644 --- a/src/main/java/net/momirealms/customcrops/integrations/protection/Integration.java +++ b/src/main/java/net/momirealms/customcrops/objects/actions/ActionInterface.java @@ -15,12 +15,10 @@ * along with this program. If not, see . */ -package net.momirealms.customcrops.integrations.protection; +package net.momirealms.customcrops.objects.actions; -import org.bukkit.Location; import org.bukkit.entity.Player; -public interface Integration { - boolean canBreak(Location location, Player player); - boolean canPlace(Location location, Player player); -} +public interface ActionInterface { + void performOn(Player player); +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/objects/actions/ActionMessage.java b/src/main/java/net/momirealms/customcrops/objects/actions/ActionMessage.java new file mode 100644 index 0000000..2157479 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/actions/ActionMessage.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.actions; + +import net.momirealms.customcrops.utils.AdventureUtil; +import org.bukkit.entity.Player; + +public class ActionMessage implements ActionInterface{ + + private final String[] messages; + + public ActionMessage(String[] messages) { + this.messages = messages; + } + + @Override + public void performOn(Player player) { + for (String message : messages) { + AdventureUtil.playerMessage(player, message.replace("{player}", player.getName())); + } + } +} diff --git a/src/main/java/net/momirealms/customcrops/objects/actions/ActionSkillXP.java b/src/main/java/net/momirealms/customcrops/objects/actions/ActionSkillXP.java new file mode 100644 index 0000000..3c00d52 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/actions/ActionSkillXP.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.actions; + +import net.momirealms.customcrops.config.MainConfig; +import org.bukkit.entity.Player; + +public class ActionSkillXP implements ActionInterface { + + private final double xp; + + public ActionSkillXP(double xp) { + this.xp = xp; + } + + @Override + public void performOn(Player player) { + if (MainConfig.skillXP != null) { + MainConfig.skillXP.addXp(player, xp); + } + } +} diff --git a/src/main/java/net/momirealms/customcrops/objects/actions/ActionXP.java b/src/main/java/net/momirealms/customcrops/objects/actions/ActionXP.java new file mode 100644 index 0000000..aeb3fc7 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/actions/ActionXP.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.actions; + +import org.bukkit.entity.Player; + +public class ActionXP implements ActionInterface { + + private final int amount; + + public ActionXP(int amount) { + this.amount = amount; + } + + @Override + public void performOn(Player player) { + player.giveExp(amount); + } +} diff --git a/src/main/java/net/momirealms/customcrops/objects/fertilizer/Fertilizer.java b/src/main/java/net/momirealms/customcrops/objects/fertilizer/Fertilizer.java index b54758f..bb4df38 100644 --- a/src/main/java/net/momirealms/customcrops/objects/fertilizer/Fertilizer.java +++ b/src/main/java/net/momirealms/customcrops/objects/fertilizer/Fertilizer.java @@ -19,27 +19,27 @@ package net.momirealms.customcrops.objects.fertilizer; import org.bukkit.Particle; -public class Fertilizer { +public abstract class Fertilizer { String key; int times; boolean before; String name; Particle particle; + double chance; - protected Fertilizer(String key, int times) { + protected Fertilizer(String key, int times, double chance, boolean before, String name) { this.key = key; this.times = times; + this.chance = chance; + this.before = before; + this.name = name; } public String getKey() { return key; } - public void setKey(String key) { - this.key = key; - } - public int getTimes() { return times; } @@ -52,18 +52,10 @@ public class Fertilizer { return before; } - public void setBefore(boolean before) { - this.before = before; - } - public String getName() { return name; } - public void setName(String name) { - this.name = name; - } - public Particle getParticle() { return particle; } @@ -71,4 +63,12 @@ public class Fertilizer { public void setParticle(Particle particle) { this.particle = particle; } + + public Fertilizer getWithTimes(int times) { + return null; + } + + public double getChance() { + return chance; + } } diff --git a/src/main/java/net/momirealms/customcrops/objects/fertilizer/Gigantic.java b/src/main/java/net/momirealms/customcrops/objects/fertilizer/Gigantic.java new file mode 100644 index 0000000..6db0c8b --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/fertilizer/Gigantic.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.fertilizer; + +public class Gigantic extends Fertilizer{ + + public Gigantic(String key, int times, double chance, boolean before, String name) { + super(key, times, chance, before, name); + } + + @Override + public Fertilizer getWithTimes(int times) { + return new Gigantic(this.key, times, this.chance, this.before, this.name); + } +} diff --git a/src/main/java/net/momirealms/customcrops/objects/fertilizer/QualityCrop.java b/src/main/java/net/momirealms/customcrops/objects/fertilizer/QualityCrop.java index 3da7bc2..f6273f4 100644 --- a/src/main/java/net/momirealms/customcrops/objects/fertilizer/QualityCrop.java +++ b/src/main/java/net/momirealms/customcrops/objects/fertilizer/QualityCrop.java @@ -18,19 +18,23 @@ package net.momirealms.customcrops.objects.fertilizer; +import net.momirealms.customcrops.objects.QualityRatio; + public class QualityCrop extends Fertilizer { - private int[] chance; + private final QualityRatio qualityRatio; - public QualityCrop(String key, int times) { - super(key, times); + public QualityCrop(String key, int times, double chance, QualityRatio qualityRatio, boolean before, String name) { + super(key, times, chance, before, name); + this.qualityRatio = qualityRatio; } - public int[] getChance() { - return chance; + public QualityRatio getQualityRatio() { + return qualityRatio; } - public void setChance(int[] chance) { - this.chance = chance; + @Override + public Fertilizer getWithTimes(int times) { + return new QualityCrop(this.key, times, this.chance, this.qualityRatio, this.before, this.name); } } diff --git a/src/main/java/net/momirealms/customcrops/objects/fertilizer/RetainingSoil.java b/src/main/java/net/momirealms/customcrops/objects/fertilizer/RetainingSoil.java index 4e1472b..65bb1e9 100644 --- a/src/main/java/net/momirealms/customcrops/objects/fertilizer/RetainingSoil.java +++ b/src/main/java/net/momirealms/customcrops/objects/fertilizer/RetainingSoil.java @@ -19,18 +19,12 @@ package net.momirealms.customcrops.objects.fertilizer; public class RetainingSoil extends Fertilizer { - double chance; - - public double getChance() { - return chance; + public RetainingSoil(String key, int times, double chance, boolean before, String name){ + super(key, times, chance, before, name); } - public void setChance(double chance) { - this.chance = chance; + @Override + public Fertilizer getWithTimes(int times) { + return new RetainingSoil(this.key, times, this.chance, this.before, this.name); } - - public RetainingSoil(String key, int times){ - super(key, times); - } - } diff --git a/src/main/java/net/momirealms/customcrops/objects/fertilizer/SpeedGrow.java b/src/main/java/net/momirealms/customcrops/objects/fertilizer/SpeedGrow.java index a4dbcff..53736f7 100644 --- a/src/main/java/net/momirealms/customcrops/objects/fertilizer/SpeedGrow.java +++ b/src/main/java/net/momirealms/customcrops/objects/fertilizer/SpeedGrow.java @@ -19,17 +19,12 @@ package net.momirealms.customcrops.objects.fertilizer; public class SpeedGrow extends Fertilizer { - private double chance; - - public SpeedGrow(String key, int times){ - super(key, times); + public SpeedGrow(String key, int times, double chance, boolean before, String name){ + super(key, times, chance, before, name); } - public double getChance() { - return chance; - } - - public void setChance(double chance) { - this.chance = chance; + @Override + public Fertilizer getWithTimes(int times) { + return new SpeedGrow(this.key, times, this.chance, this.before, this.name); } } diff --git a/src/main/java/net/momirealms/customcrops/objects/fertilizer/YieldIncreasing.java b/src/main/java/net/momirealms/customcrops/objects/fertilizer/YieldIncreasing.java index 8a8275e..015c74b 100644 --- a/src/main/java/net/momirealms/customcrops/objects/fertilizer/YieldIncreasing.java +++ b/src/main/java/net/momirealms/customcrops/objects/fertilizer/YieldIncreasing.java @@ -19,26 +19,19 @@ package net.momirealms.customcrops.objects.fertilizer; public class YieldIncreasing extends Fertilizer { - private int bonus; - private double chance; + private final int bonus; - public YieldIncreasing(String key, int times) { - super(key, times); - } - - public double getChance() { - return chance; - } - - public void setChance(double chance) { - this.chance = chance; + public YieldIncreasing(String key, int times, double chance ,int bonus, boolean before, String name) { + super(key, times, chance, before, name); + this.bonus = bonus; } public int getBonus() { return bonus; } - public void setBonus(int bonus) { - this.bonus = bonus; + @Override + public Fertilizer getWithTimes(int times) { + return new YieldIncreasing(this.key, times, this.chance, this.bonus, this.before, this.name); } } diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/CustomPapi.java b/src/main/java/net/momirealms/customcrops/objects/requirements/CustomPapi.java new file mode 100644 index 0000000..afb56cc --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/CustomPapi.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements; + +import net.momirealms.customcrops.objects.requirements.papi.*; +import net.momirealms.customcrops.utils.AdventureUtil; +import org.bukkit.configuration.MemorySection; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +public class CustomPapi implements RequirementInterface { + + public static HashSet allPapi = new HashSet<>(); + + private PapiRequirement papiRequirement; + private final String msg; + + public CustomPapi(Map expressions, String msg){ + this.msg = msg; + expressions.keySet().forEach(key -> { + if (key.startsWith("&&")){ + List papiRequirements = new ArrayList<>(); + if (expressions.get(key) instanceof MemorySection map2){ + addAndRequirements(papiRequirements, map2.getValues(false)); + } + papiRequirement = new ExpressionAnd(papiRequirements); + } + else if (key.startsWith("||")){ + List papiRequirements = new ArrayList<>(); + if (expressions.get(key) instanceof MemorySection map2){ + addOrRequirements(papiRequirements, map2.getValues(false)); + } + papiRequirement = new ExpressionOr(papiRequirements); + } + else { + if (expressions.get(key) instanceof MemorySection map){ + String type = map.getString("type"); + if (type == null) return; + String papi = map.getString("papi"); + if (papi == null) return; + String value = map.getString("value"); + if (value == null) return; + allPapi.add(papi); + switch (type){ + case "==" -> papiRequirement = new PapiEquals(papi, value); + case "!=" -> papiRequirement = new PapiNotEquals(papi, value); + case ">=" -> papiRequirement = new PapiNoLess(papi, Double.parseDouble(value)); + case "<=" -> papiRequirement = new PapiNoLarger(papi, Double.parseDouble(value)); + case "<" -> papiRequirement = new PapiSmaller(papi, Double.parseDouble(value)); + case ">" -> papiRequirement = new PapiGreater(papi, Double.parseDouble(value)); + } + } + } + }); + } + + @Override + public boolean isConditionMet(PlantingCondition plantingCondition) { + if (!papiRequirement.isMet(plantingCondition.getPapiMap())) { + AdventureUtil.playerMessage(plantingCondition.getPlayer(), msg); + return false; + } + return true; + } + + private void addAndRequirements(List requirements, Map map){ + requirements.add(new ExpressionAnd(getRequirements(map))); + } + + private void addOrRequirements(List requirements, Map map){ + requirements.add(new ExpressionOr(getRequirements(map))); + } + + private List getRequirements(Map map) { + List papiRequirements = new ArrayList<>(); + map.keySet().forEach(key -> { + if (key.startsWith("&&")){ + if (map.get(key) instanceof MemorySection map2){ + addAndRequirements(papiRequirements, map2.getValues(false)); + } + }else if (key.startsWith("||")){ + if (map.get(key) instanceof MemorySection map2){ + addOrRequirements(papiRequirements, map2.getValues(false)); + } + }else { + if (map.get(key) instanceof MemorySection map2){ + String type = map2.getString("type"); + if (type == null) return; + String papi = map2.getString("papi"); + if (papi == null) return; + String value = map2.getString("value"); + if (value == null) return; + allPapi.add(papi); + switch (type){ + case "==" -> papiRequirements.add(new PapiEquals(papi, value)); + case "!=" -> papiRequirements.add(new PapiNotEquals(papi, value)); + case ">=" -> papiRequirements.add(new PapiNoLess(papi, Double.parseDouble(value))); + case "<=" -> papiRequirements.add(new PapiNoLarger(papi, Double.parseDouble(value))); + case "<" -> papiRequirements.add(new PapiSmaller(papi, Double.parseDouble(value))); + case ">" -> papiRequirements.add(new PapiGreater(papi, Double.parseDouble(value))); + } + } + } + }); + return papiRequirements; + } +} diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/PlantingCondition.java b/src/main/java/net/momirealms/customcrops/objects/requirements/PlantingCondition.java new file mode 100644 index 0000000..ce0f299 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/PlantingCondition.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements; + +import net.momirealms.customcrops.CustomCrops; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; + +public class PlantingCondition { + + private final Location location; + private final Player player; + private HashMap papiMap; + + public PlantingCondition(Location location, Player player) { + this.location = location; + this.player = player; + if (CustomCrops.plugin.hasPapi()){ + this.papiMap = new HashMap<>(); + CustomPapi.allPapi.forEach(papi -> this.papiMap.put(papi, CustomCrops.plugin.getPlaceholderManager().parse(player, papi))); + } + } + + @Nullable + public HashMap getPapiMap() { + return papiMap; + } + + @NotNull + public Location getLocation() { + return location; + } + + @NotNull + public Player getPlayer() { + return player; + } +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/Requirement.java b/src/main/java/net/momirealms/customcrops/objects/requirements/Requirement.java new file mode 100644 index 0000000..2f68925 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/Requirement.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements; + +import net.momirealms.customcrops.utils.AdventureUtil; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public abstract class Requirement { + + protected String[] values; + protected boolean mode; + protected String msg; + + protected Requirement(@NotNull String[] values, boolean mode, @Nullable String msg) { + this.values = values; + this.mode = mode; + this.msg = msg; + } + + public void notMetMessage(Player player) { + if (msg == null) return; + AdventureUtil.playerMessage(player, this.msg); + } +} diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementBiome.java b/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementBiome.java new file mode 100644 index 0000000..550e480 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementBiome.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements; + +public class RequirementBiome extends Requirement implements RequirementInterface { + + public RequirementBiome(String[] values, boolean mode, String msg) { + super(values, mode, msg); + } + + @Override + public boolean isConditionMet(PlantingCondition plantingCondition) { + String currentBiome = plantingCondition.getLocation().getBlock().getBiome().getKey().toString(); + if (mode) { + for (String value : values) { + if (!(currentBiome.equalsIgnoreCase(value))) { + notMetMessage(plantingCondition.getPlayer()); + return false; + } + } + return true; + } + else { + for (String value : values) { + if (currentBiome.equalsIgnoreCase(value)) { + return true; + } + } + notMetMessage(plantingCondition.getPlayer()); + return false; + } + } +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementInterface.java b/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementInterface.java new file mode 100644 index 0000000..4156d0c --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementInterface.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements; + +public interface RequirementInterface { + boolean isConditionMet(PlantingCondition plantingCondition); +} diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementPermission.java b/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementPermission.java new file mode 100644 index 0000000..51eb1ac --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementPermission.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements; + +public class RequirementPermission extends Requirement implements RequirementInterface { + + public RequirementPermission(String[] values, boolean mode, String msg) { + super(values, mode, msg); + } + + @Override + public boolean isConditionMet(PlantingCondition plantingCondition) { + if (mode) { + for (String value : values) { + if (!(plantingCondition.getPlayer().hasPermission(value))) { + notMetMessage(plantingCondition.getPlayer()); + return false; + } + } + return true; + } + else { + for (String value : values) { + if (plantingCondition.getPlayer().hasPermission(value)) { + return true; + } + } + notMetMessage(plantingCondition.getPlayer()); + return false; + } + } +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementTime.java b/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementTime.java new file mode 100644 index 0000000..84af59b --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementTime.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements; + +import org.apache.commons.lang.StringUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class RequirementTime extends Requirement implements RequirementInterface { + + public RequirementTime(@NotNull String[] values, boolean mode, @Nullable String msg) { + super(values, mode, msg); + } + + @Override + public boolean isConditionMet(PlantingCondition plantingCondition) { + long time = plantingCondition.getLocation().getWorld().getTime(); + if (mode) { + for (String value : values) { + String[] timeMinMax = StringUtils.split(value, "~"); + if (!(time > Long.parseLong(timeMinMax[0]) && time < Long.parseLong(timeMinMax[1]))) { + notMetMessage(plantingCondition.getPlayer()); + return false; + } + } + return true; + } + else { + for (String value : values) { + String[] timeMinMax = StringUtils.split(value, "~"); + if (time > Long.parseLong(timeMinMax[0]) && time < Long.parseLong(timeMinMax[1])) { + return true; + } + } + notMetMessage(plantingCondition.getPlayer()); + return false; + } + } +} diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementWeather.java b/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementWeather.java new file mode 100644 index 0000000..952bf95 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementWeather.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements; + +import org.bukkit.World; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class RequirementWeather extends Requirement implements RequirementInterface { + + public RequirementWeather(@NotNull String[] values, boolean mode, @Nullable String msg) { + super(values, mode, msg); + } + + @Override + public boolean isConditionMet(PlantingCondition plantingCondition) { + World world = plantingCondition.getLocation().getWorld(); + String weather; + if (world.isThundering()) weather = "thunder"; + else if (world.isClearWeather()) weather = "clear"; + else weather = "rain"; + if (mode) { + for (String value : values) { + if (!value.equalsIgnoreCase(weather)) { + notMetMessage(plantingCondition.getPlayer()); + return false; + } + } + return true; + } + else { + for (String value : values) { + if (value.equalsIgnoreCase(weather)) { + return true; + } + } + notMetMessage(plantingCondition.getPlayer()); + return false; + } + } +} diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementWorld.java b/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementWorld.java new file mode 100644 index 0000000..65bac3a --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementWorld.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class RequirementWorld extends Requirement implements RequirementInterface { + + public RequirementWorld(@NotNull String[] values, boolean mode, @Nullable String msg) { + super(values, mode, msg); + } + + @Override + public boolean isConditionMet(PlantingCondition plantingCondition) { + String worldName = plantingCondition.getLocation().getWorld().getName(); + if (mode) { + for (String value : values) { + if (!value.equals(worldName)) { + notMetMessage(plantingCondition.getPlayer()); + return false; + } + } + return true; + } + else { + for (String value : values) { + if (value.equals(worldName)) { + return true; + } + } + notMetMessage(plantingCondition.getPlayer()); + return false; + } + } +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementYPos.java b/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementYPos.java new file mode 100644 index 0000000..78cb3a2 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/RequirementYPos.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements; + +import org.apache.commons.lang.StringUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class RequirementYPos extends Requirement implements RequirementInterface { + + public RequirementYPos(@NotNull String[] values, boolean mode, @Nullable String msg) { + super(values, mode, msg); + } + + @Override + public boolean isConditionMet(PlantingCondition plantingCondition) { + int y = plantingCondition.getLocation().getBlockY(); + if (mode) { + for (String value : values) { + String[] yMinMax = StringUtils.split(value, "~"); + if (!(y > Long.parseLong(yMinMax[0]) && y < Long.parseLong(yMinMax[1]))) { + notMetMessage(plantingCondition.getPlayer()); + return false; + } + } + return true; + } + else { + for (String value : values) { + String[] yMinMax = StringUtils.split(value, "~"); + if (y > Long.parseLong(yMinMax[0]) && y < Long.parseLong(yMinMax[1])) { + return true; + } + } + notMetMessage(plantingCondition.getPlayer()); + return false; + } + } +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/papi/ExpressionAnd.java b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/ExpressionAnd.java new file mode 100644 index 0000000..56c6e19 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/ExpressionAnd.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements.papi; + +import java.util.HashMap; +import java.util.List; + +public record ExpressionAnd(List requirements) implements PapiRequirement{ + + @Override + public boolean isMet(HashMap papiMap) { + for (PapiRequirement requirement : requirements) { + if (!requirement.isMet(papiMap)) return false; + } + return true; + } +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/papi/ExpressionOr.java b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/ExpressionOr.java new file mode 100644 index 0000000..5b5a498 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/ExpressionOr.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements.papi; + +import java.util.HashMap; +import java.util.List; + +public record ExpressionOr(List requirements) implements PapiRequirement{ + + @Override + public boolean isMet(HashMap papiMap) { + for (PapiRequirement requirement : requirements) { + if (requirement.isMet(papiMap)) return true; + } + return false; + } +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiEquals.java b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiEquals.java new file mode 100644 index 0000000..e58db79 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiEquals.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements.papi; + +import java.util.HashMap; +import java.util.Objects; + +public record PapiEquals(String papi, String requirement) implements PapiRequirement{ + + @Override + public boolean isMet(HashMap papiMap) { + String value = papiMap.get(papi); + return Objects.equals(value, requirement); + } +} diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiGreater.java b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiGreater.java new file mode 100644 index 0000000..f386d86 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiGreater.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements.papi; + +import java.util.HashMap; + +public record PapiGreater(String papi, double requirement) implements PapiRequirement{ + + @Override + public boolean isMet(HashMap papiMap) { + double value = Double.parseDouble(papiMap.get(papi)); + return value > requirement; + } +} diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiNoLarger.java b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiNoLarger.java new file mode 100644 index 0000000..075edb1 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiNoLarger.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements.papi; + +import java.util.HashMap; + +public record PapiNoLarger(String papi, double requirement) implements PapiRequirement{ + + @Override + public boolean isMet(HashMap papiMap) { + double value = Double.parseDouble(papiMap.get(papi)); + return value <= requirement; + } +} diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiNoLess.java b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiNoLess.java new file mode 100644 index 0000000..e3f1fd7 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiNoLess.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements.papi; + +import java.util.HashMap; + +public record PapiNoLess(String papi, double requirement) implements PapiRequirement{ + + @Override + public boolean isMet(HashMap papiMap) { + double value = Double.parseDouble(papiMap.get(papi)); + return value >= requirement; + } +} diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiNotEquals.java b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiNotEquals.java new file mode 100644 index 0000000..11a48ae --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiNotEquals.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements.papi; + +import java.util.HashMap; +import java.util.Objects; + +public record PapiNotEquals(String papi, String requirement) implements PapiRequirement{ + + @Override + public boolean isMet(HashMap papiMap) { + String value = papiMap.get(papi); + return !Objects.equals(value, requirement); + } +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiRequirement.java b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiRequirement.java new file mode 100644 index 0000000..cc66df8 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiRequirement.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements.papi; + +import java.util.HashMap; + +public interface PapiRequirement { + boolean isMet(HashMap papiMap); +} diff --git a/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiSmaller.java b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiSmaller.java new file mode 100644 index 0000000..acd1281 --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/objects/requirements/papi/PapiSmaller.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.objects.requirements.papi; + +import java.util.HashMap; + +public record PapiSmaller(String papi, double requirement) implements PapiRequirement{ + + @Override + public boolean isMet(HashMap papiMap) { + double value = Double.parseDouble(papiMap.get(papi)); + return value < requirement; + } +} diff --git a/src/main/java/net/momirealms/customcrops/requirements/Biome.java b/src/main/java/net/momirealms/customcrops/requirements/Biome.java deleted file mode 100644 index eaac8f1..0000000 --- a/src/main/java/net/momirealms/customcrops/requirements/Biome.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.requirements; - -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.utils.AdventureManager; - -import java.util.List; - -public record Biome(List biomes) implements Requirement { - - public List getBiomes() { - return this.biomes; - } - - @Override - public boolean canPlant(PlantingCondition plantingCondition) { - String currentBiome = plantingCondition.getLocation().getBlock().getBiome().getKey().toString(); - for (String biome : biomes) - if (currentBiome.equalsIgnoreCase(biome)) - return true; - AdventureManager.playerMessage(plantingCondition.player(), ConfigReader.Message.prefix +ConfigReader.Message.badBiome); - return false; - } -} diff --git a/src/main/java/net/momirealms/customcrops/requirements/Permission.java b/src/main/java/net/momirealms/customcrops/requirements/Permission.java deleted file mode 100644 index 4c38988..0000000 --- a/src/main/java/net/momirealms/customcrops/requirements/Permission.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.requirements; - -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.utils.AdventureManager; - -public record Permission(String permission) implements Requirement { - - public String getPermission() { - return this.permission; - } - - @Override - public boolean canPlant(PlantingCondition plantingCondition) { - if (plantingCondition.getPlayer().hasPermission(permission)) return true; - AdventureManager.playerMessage(plantingCondition.player(), ConfigReader.Message.prefix +ConfigReader.Message.badPerm); - return false; - } -} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/requirements/World.java b/src/main/java/net/momirealms/customcrops/requirements/World.java deleted file mode 100644 index 4b47411..0000000 --- a/src/main/java/net/momirealms/customcrops/requirements/World.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.requirements; - -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.utils.AdventureManager; - -import java.util.List; - -public record World(List worlds) implements Requirement { - - public List getWorlds() { - return this.worlds; - } - - @Override - public boolean canPlant(PlantingCondition plantingCondition) { - org.bukkit.World world = plantingCondition.getLocation().getWorld(); - if (worlds.contains(world.getName())) return true; - AdventureManager.playerMessage(plantingCondition.player(), ConfigReader.Message.prefix +ConfigReader.Message.badWorld); - return false; - } -} diff --git a/src/main/java/net/momirealms/customcrops/requirements/YPos.java b/src/main/java/net/momirealms/customcrops/requirements/YPos.java deleted file mode 100644 index a317f3b..0000000 --- a/src/main/java/net/momirealms/customcrops/requirements/YPos.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.requirements; - -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.utils.AdventureManager; -import org.apache.commons.lang.StringUtils; - -import java.util.List; - -public record YPos(List yPos) implements Requirement { - - public List getYPos() { - return this.yPos; - } - - @Override - public boolean canPlant(PlantingCondition plantingCondition) { - int y = (int) plantingCondition.getLocation().getY(); - for (String range : yPos) { - String[] yMinMax = StringUtils.split(range, "~"); - if (y > Integer.parseInt(yMinMax[0]) && y < Integer.parseInt(yMinMax[1])) return true; - } - AdventureManager.playerMessage(plantingCondition.player(), ConfigReader.Message.prefix +ConfigReader.Message.badY); - return false; - } -} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/timer/TimeCheck.java b/src/main/java/net/momirealms/customcrops/timer/TimeCheck.java deleted file mode 100644 index 0bb240f..0000000 --- a/src/main/java/net/momirealms/customcrops/timer/TimeCheck.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.timer; - -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.CustomCrops; -import org.bukkit.Bukkit; -import org.bukkit.scheduler.BukkitRunnable; - -public class TimeCheck extends BukkitRunnable { - - @Override - public void run() { - ConfigReader.Config.worlds.forEach(world ->{ - long time = world.getTime(); - ConfigReader.Config.cropGrowTimeList.forEach(cropGrowTime -> { - if(time == 0) - if(ConfigReader.Season.enable && ConfigReader.Season.seasonChange) - CustomCrops.plugin.getSeasonManager().getSeason(world); - if(time == cropGrowTime){ - if (ConfigReader.Config.allWorld){ - Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.plugin, () -> { - CustomCrops.plugin.getCropManager().cropGrowAll(); - }); - Bukkit.getScheduler().runTaskLaterAsynchronously(CustomCrops.plugin, ()->{ - CustomCrops.plugin.getSprinklerManager().sprinklerWorkAll(); - }, ConfigReader.Config.timeToGrow); - }else { - Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.plugin, () -> { - switch (ConfigReader.Config.growMode){ - case 1 -> CustomCrops.plugin.getCropManager().growModeOne(world.getName()); - case 2 -> CustomCrops.plugin.getCropManager().growModeTwo(world.getName()); - case 3 -> CustomCrops.plugin.getCropManager().growModeThree(world.getName()); - case 4 -> CustomCrops.plugin.getCropManager().growModeFour(world.getName()); - } - }); - Bukkit.getScheduler().runTaskLaterAsynchronously(CustomCrops.plugin, ()->{ - switch (ConfigReader.Config.growMode){ - case 1 -> CustomCrops.plugin.getSprinklerManager().workModeOne(world.getName()); - case 2 -> CustomCrops.plugin.getSprinklerManager().workModeTwo(world.getName()); - case 3 -> CustomCrops.plugin.getSprinklerManager().workModeThree(world.getName()); - case 4 -> CustomCrops.plugin.getSprinklerManager().workModeFour(world.getName()); - } - }, ConfigReader.Config.timeToGrow); - } - } - }); - }); - } -} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/utils/AdventureManager.java b/src/main/java/net/momirealms/customcrops/utils/AdventureUtil.java similarity index 78% rename from src/main/java/net/momirealms/customcrops/utils/AdventureManager.java rename to src/main/java/net/momirealms/customcrops/utils/AdventureUtil.java index ad3cd10..5f6b1e4 100644 --- a/src/main/java/net/momirealms/customcrops/utils/AdventureManager.java +++ b/src/main/java/net/momirealms/customcrops/utils/AdventureUtil.java @@ -25,16 +25,18 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.title.Title; import net.momirealms.customcrops.CustomCrops; import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import java.time.Duration; -public class AdventureManager { +public class AdventureUtil { + + public static void sendMessage(CommandSender sender, String s) { + if (sender instanceof Player player) playerMessage(player, s); + else consoleMessage(s); + } - /** - * 发送控制台信息 - * @param s 文本 - */ public static void consoleMessage(String s) { Audience au = CustomCrops.adventure.sender(Bukkit.getConsoleSender()); MiniMessage mm = MiniMessage.miniMessage(); @@ -42,11 +44,6 @@ public class AdventureManager { au.sendMessage(parsed); } - /** - * 发送玩家信息 - * @param player 玩家 - * @param s 文本 - */ public static void playerMessage(Player player, String s) { Audience au = CustomCrops.adventure.player(player); MiniMessage mm = MiniMessage.miniMessage(); @@ -54,15 +51,6 @@ public class AdventureManager { au.sendMessage(parsed); } - /** - * 发送玩家标题 - * @param player 玩家 - * @param s1 主标题 - * @param s2 副标题 - * @param in 淡入时间 - * @param duration 停留时间 - * @param out 淡出时间 - */ public static void playerTitle(Player player, String s1, String s2, int in, int duration, int out) { Audience au = CustomCrops.adventure.player(player); MiniMessage mm = MiniMessage.miniMessage(); @@ -71,25 +59,14 @@ public class AdventureManager { au.showTitle(title); } - /** - * 发送动作消息 - * @param player 玩家 - * @param s 文本 - */ public static void playerActionbar(Player player, String s) { Audience au = CustomCrops.adventure.player(player); MiniMessage mm = MiniMessage.miniMessage(); au.sendActionBar(mm.deserialize(s)); } - /** - * 发送声音 - * @param player 玩家 - * @param source 来源 - * @param key 键 - */ - public static void playerSound(Player player, Sound.Source source, Key key) { - Sound sound = Sound.sound(key, source, 1, 1); + public static void playerSound(Player player, Sound.Source source, Key key, float volume, float pitch) { + Sound sound = Sound.sound(key, source, volume, pitch); Audience au = CustomCrops.adventure.player(player); au.playSound(sound); } diff --git a/src/main/java/net/momirealms/customcrops/utils/ConfigUtil.java b/src/main/java/net/momirealms/customcrops/utils/ConfigUtil.java deleted file mode 100644 index e8bb443..0000000 --- a/src/main/java/net/momirealms/customcrops/utils/ConfigUtil.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.momirealms.customcrops.utils; - -import dev.dejvokep.boostedyaml.YamlDocument; -import dev.dejvokep.boostedyaml.dvs.versioning.BasicVersioning; -import dev.dejvokep.boostedyaml.settings.dumper.DumperSettings; -import dev.dejvokep.boostedyaml.settings.general.GeneralSettings; -import dev.dejvokep.boostedyaml.settings.loader.LoaderSettings; -import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings; -import net.momirealms.customcrops.CustomCrops; -import net.momirealms.customcrops.helper.Log; - -import java.io.File; -import java.io.IOException; - -public class ConfigUtil { - - public static void update(){ - try { - YamlDocument.create(new File(CustomCrops.plugin.getDataFolder(), "config.yml"), CustomCrops.plugin.getResource("config.yml"), GeneralSettings.DEFAULT, LoaderSettings.builder().setAutoUpdate(true).build(), DumperSettings.DEFAULT, UpdaterSettings.builder().setVersioning(new BasicVersioning("config-version")).build()); - }catch (IOException e){ - Log.warn(e.getMessage()); - } - } -} diff --git a/src/main/java/net/momirealms/customcrops/utils/DropUtil.java b/src/main/java/net/momirealms/customcrops/utils/DropUtil.java deleted file mode 100644 index 33bd961..0000000 --- a/src/main/java/net/momirealms/customcrops/utils/DropUtil.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.momirealms.customcrops.utils; - -import dev.lone.itemsadder.api.CustomStack; -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.objects.Crop; -import org.bukkit.Location; -import org.bukkit.World; - -public class DropUtil { - - /** - * 没有品质肥料下的普通掉落 - * @param cropInstance 农作物 - * @param random 随机农作物数量 - * @param itemLoc 掉落物位置 - * @param world 世界 - */ - public static void normalDrop(Crop cropInstance, int random, Location itemLoc, World world) { - for (int i = 0; i < random; i++){ - double ran = Math.random(); - if (ran < ConfigReader.Config.quality_1){ - world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_1()).getItemStack()); - }else if(ran > ConfigReader.Config.quality_2){ - world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_2()).getItemStack()); - }else { - world.dropItem(itemLoc, CustomStack.getInstance(cropInstance.getQuality_3()).getItemStack()); - } - } - } -} diff --git a/src/main/java/net/momirealms/customcrops/utils/FileUtil.java b/src/main/java/net/momirealms/customcrops/utils/FileUtil.java deleted file mode 100644 index b9d3b6f..0000000 --- a/src/main/java/net/momirealms/customcrops/utils/FileUtil.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) <2022> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.momirealms.customcrops.utils; - -import net.momirealms.customcrops.CustomCrops; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.List; - -public class FileUtil { - - /** - * 备份全部文件 - */ - public static void backUpData(){ - - List files = Arrays.asList("crop","sprinkler","pot","season"); - - Date date = new Date(); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); - - files.forEach(fileName -> { - File data = new File(CustomCrops.plugin.getDataFolder(), "data"+ File.separatorChar + fileName + ".yml"); - File backUp = new File(CustomCrops.plugin.getDataFolder(), "backups"+ File.separatorChar + format.format(date) + File.separatorChar + fileName + ".yml"); - try { - FileUtil.backUp(data, backUp); - } catch (IOException e) { - e.printStackTrace(); - CustomCrops.plugin.getLogger().warning(fileName + ".yml备份出错!"); - } - }); - } - - /** - * 复制某个文件 - * @param file_from 源文件 - * @param file_to 目标文件 - * @throws IOException IO异常 - */ - private static void backUp(File file_from, File file_to) throws IOException { - if(!file_to.exists()){ - file_to.getParentFile().mkdirs(); - } - FileInputStream fis = new FileInputStream(file_from); - if(!file_to.exists()){ - file_to.createNewFile(); - } - FileOutputStream fos = new FileOutputStream(file_to); - byte[] b = new byte[1024]; - int len; - while ((len = fis.read(b))!= -1){ - fos.write(b,0,len); - } - fos.close(); - fis.close(); - } -} diff --git a/src/main/java/net/momirealms/customcrops/utils/FurnitureUtil.java b/src/main/java/net/momirealms/customcrops/utils/FurnitureUtil.java index 6641f3b..6678742 100644 --- a/src/main/java/net/momirealms/customcrops/utils/FurnitureUtil.java +++ b/src/main/java/net/momirealms/customcrops/utils/FurnitureUtil.java @@ -17,81 +17,22 @@ package net.momirealms.customcrops.utils; -import dev.lone.itemsadder.api.CustomFurniture; -import net.momirealms.customcrops.ConfigReader; import org.bukkit.Location; -import org.bukkit.Rotation; import org.bukkit.entity.Entity; import org.bukkit.entity.ItemFrame; -import java.util.Random; - public class FurnitureUtil { - static Rotation[] rotations4 = {Rotation.NONE, Rotation.FLIPPED, Rotation.CLOCKWISE, Rotation.COUNTER_CLOCKWISE}; - static Rotation[] rotations8 = {Rotation.NONE, Rotation.FLIPPED, Rotation.CLOCKWISE, Rotation.COUNTER_CLOCKWISE, - Rotation.CLOCKWISE_45, Rotation.CLOCKWISE_135, Rotation.FLIPPED_45, Rotation.COUNTER_CLOCKWISE_45}; - - /** - * 在指定位置放置家具 - * @param name 物品名 - * @param location 位置 - */ - public static void placeFurniture(String name, Location location){ - CustomFurniture.spawn(name, location.getBlock()); - } - - /** - * 在指定位置放置农作物 - * @param name 农作物命名空间id - * @param location 位置 - */ - public static void placeCrop(String name, Location location){ - CustomFurniture customFurniture = CustomFurniture.spawn(name, location.getBlock()); - Entity entity = customFurniture.getArmorstand(); - if (ConfigReader.Config.rotation && entity instanceof ItemFrame itemFrame){ - if (ConfigReader.Config.variant4) itemFrame.setRotation(rotations4[new Random().nextInt(rotations4.length-1)]); - else itemFrame.setRotation(rotations8[new Random().nextInt(rotations8.length-1)]); - } - } - - /** - * 获取指定位置的家具名 - * 仅限加载中的区块 - * @param location 位置 - * @return 是/否 - */ - public static String getNamespacedID(Location location){ - CustomFurniture furniture = getFurniture(location); - if (furniture != null){ - return furniture.getNamespacedID(); - }else { - return null; - } - } - - /** - * 获取指定位置的家具名 - * 仅限加载中的区块 - * @param location 位置 - * @return 是/否 - */ - public static CustomFurniture getFurniture(Location location){ + public static ItemFrame getItemFrame(Location location) { for(Entity entity : location.getWorld().getNearbyEntities(location,0,0,0)){ - CustomFurniture furniture = CustomFurniture.byAlreadySpawned(entity); - if(furniture != null) return furniture; + if (entity instanceof ItemFrame itemFrame) { + return itemFrame; + } } return null; } - /** - * 判断指定位置的家具是不是洒水器 - * @param location 位置 - * @return 是/否 - */ - public static boolean isSprinkler(Location location){ - String furniture = getNamespacedID(location); - if (furniture != null) return ConfigReader.SPRINKLERS.get(furniture) != null; - else return false; + public static boolean hasFurniture(Location location) { + return getItemFrame(location) != null; } -} \ No newline at end of file +} diff --git a/src/main/java/net/momirealms/customcrops/utils/HoloUtil.java b/src/main/java/net/momirealms/customcrops/utils/HologramUtil.java similarity index 71% rename from src/main/java/net/momirealms/customcrops/utils/HoloUtil.java rename to src/main/java/net/momirealms/customcrops/utils/HologramUtil.java index 25fbf7a..9ee74df 100644 --- a/src/main/java/net/momirealms/customcrops/utils/HoloUtil.java +++ b/src/main/java/net/momirealms/customcrops/utils/HologramUtil.java @@ -28,42 +28,31 @@ import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.momirealms.customcrops.CustomCrops; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import java.util.*; -public class HoloUtil { +public class HologramUtil { public static HashMap cache = new HashMap<>(); - /** - * 对指定玩家展示在指定位置的盔甲架 - * @param text 文本 - * @param player 玩家 - * @param location 位置 - * @param duration 持续时间 - */ + public static void showHolo(String text, Player player, Location location, int duration){ - if (cache.get(location) != null){ - removeHolo(player, cache.get(location)); + Integer entityID = cache.remove(location); + if (entityID != null) { + removeHolo(player, entityID); } - - PacketContainer packet1 = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY); - + PacketContainer spawnPacket = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY); int id = new Random().nextInt(1000000000); - packet1.getModifier().write(0, id); - packet1.getModifier().write(1, UUID.randomUUID()); - packet1.getEntityTypeModifier().write(0, EntityType.ARMOR_STAND); - packet1.getDoubles().write(0, location.getX()); - packet1.getDoubles().write(1, location.getY()); - packet1.getDoubles().write(2, location.getZ()); - - PacketContainer packet2 = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); - + cache.put(location, id); + spawnPacket.getModifier().write(0, id); + spawnPacket.getModifier().write(1, UUID.randomUUID()); + spawnPacket.getEntityTypeModifier().write(0, EntityType.ARMOR_STAND); + spawnPacket.getDoubles().write(0, location.getX()); + spawnPacket.getDoubles().write(1, location.getY()); + spawnPacket.getDoubles().write(2, location.getZ()); + PacketContainer metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); Component component = MiniMessage.miniMessage().deserialize(text); WrappedDataWatcher wrappedDataWatcher = new WrappedDataWatcher(); WrappedDataWatcher.Serializer serializer1 = WrappedDataWatcher.Registry.get(Boolean.class); @@ -75,19 +64,16 @@ public class HoloUtil { byte mask2 = 0x01; wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(0, serializer2), mask1); wrappedDataWatcher.setObject(new WrappedDataWatcher.WrappedDataWatcherObject(15, serializer2), mask2); - packet2.getModifier().write(0,id); - packet2.getWatchableCollectionModifier().write(0, wrappedDataWatcher.getWatchableObjects()); - cache.put(location, id); - + metaPacket.getModifier().write(0,id); + metaPacket.getWatchableCollectionModifier().write(0, wrappedDataWatcher.getWatchableObjects()); try { - ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet1); - ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet2); + ProtocolLibrary.getProtocolManager().sendServerPacket(player, spawnPacket); + ProtocolLibrary.getProtocolManager().sendServerPacket(player, metaPacket); } catch (Exception e) { - AdventureManager.consoleMessage("[CustomCrops] 无法为玩家 "+ player.getName()+" 展示悬浮信息!"); + AdventureUtil.consoleMessage("[CustomCrops] Failed to display hologram for " + player.getName() + " !"); e.printStackTrace(); } - Bukkit.getScheduler().runTaskLater(CustomCrops.plugin, ()->{ removeHolo(player, id); cache.remove(location); @@ -101,7 +87,7 @@ public class HoloUtil { ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); } catch (Exception e) { - AdventureManager.consoleMessage("[CustomCrops] 无法为玩家 "+ player.getName()+" 移除悬浮信息!"); + AdventureUtil.consoleMessage("[CustomCrops] Failed to remove hologram for " + player.getName() + " !"); e.printStackTrace(); } } diff --git a/src/main/java/net/momirealms/customcrops/utils/JedisUtil.java b/src/main/java/net/momirealms/customcrops/utils/JedisUtil.java deleted file mode 100644 index 2732e37..0000000 --- a/src/main/java/net/momirealms/customcrops/utils/JedisUtil.java +++ /dev/null @@ -1,84 +0,0 @@ -package net.momirealms.customcrops.utils; - -import net.momirealms.customcrops.CustomCrops; -import net.momirealms.customcrops.helper.Log; -import org.bukkit.Bukkit; -import org.bukkit.configuration.file.YamlConfiguration; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.JedisPoolConfig; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; - -public class JedisUtil { - - private static JedisPool jedisPool; - - public static Jedis getJedis(){ - return jedisPool.getResource(); - } - - public static void initializeRedis(YamlConfiguration configuration){ - - JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); - jedisPoolConfig.setTestWhileIdle(true); - jedisPoolConfig.setTimeBetweenEvictionRunsMillis(30000); - jedisPoolConfig.setNumTestsPerEvictionRun(-1); - jedisPoolConfig.setMinEvictableIdleTimeMillis(configuration.getInt("redis.MinEvictableIdleTimeMillis",1800000)); - jedisPoolConfig.setMaxTotal(configuration.getInt("redis.MaxTotal",8)); - jedisPoolConfig.setMaxIdle(configuration.getInt("redis.MaxIdle",8)); - jedisPoolConfig.setMinIdle(configuration.getInt("redis.MinIdle",1)); - jedisPoolConfig.setMaxWaitMillis(configuration.getInt("redis.MaxWaitMillis",30000)); - - jedisPool = new JedisPool(jedisPoolConfig, configuration.getString("redis.host","localhost"), configuration.getInt("redis.port",6379)); - - AdventureManager.consoleMessage("[CustomCrops] Redis Enabled!"); - - List minIdleJedisList = new ArrayList<>(jedisPoolConfig.getMinIdle()); - for (int i = 0; i < jedisPoolConfig.getMinIdle(); i++) { - Jedis jedis; - try { - jedis = jedisPool.getResource(); - minIdleJedisList.add(jedis); - jedis.ping(); - } catch (Exception e) { - Log.warn(e.getMessage()); - } - } - - for (int i = 0; i < jedisPoolConfig.getMinIdle(); i++) { - Jedis jedis; - try { - jedis = minIdleJedisList.get(i); - jedis.close(); - } catch (Exception e) { - Log.warn(e.getMessage()); - } - } - } - - public static void addPlayer(String player){ - Bukkit.getScheduler().runTaskLaterAsynchronously(CustomCrops.plugin, ()->{ - Jedis jedis = getJedis(); - jedis.sadd("cc_players", player); - jedis.close(); - }, 20); - } - - public static void remPlayer(String player){ - Bukkit.getScheduler().runTaskAsynchronously(CustomCrops.plugin, ()->{ - Jedis jedis = getJedis(); - jedis.srem("cc_players", player); - jedis.close(); - }); - } - - public static HashSet getPlayers(){ - Jedis jedis = getJedis(); - HashSet players = (HashSet) jedis.smembers("cc_players"); - jedis.close(); - return players; - } -} diff --git a/src/main/java/net/momirealms/customcrops/utils/LimitationUtil.java b/src/main/java/net/momirealms/customcrops/utils/LimitationUtil.java new file mode 100644 index 0000000..137138b --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/utils/LimitationUtil.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customcrops.utils; + +import net.momirealms.customcrops.config.MainConfig; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.ItemFrame; + +public class LimitationUtil { + + public static boolean reachWireLimit(Location location) { + int minHeight = location.getWorld().getMinHeight(); + int maxHeight = location.getWorld().getMaxHeight(); + Location chunkLocation = new Location(location.getWorld(), location.getChunk().getX() * 16, minHeight, location.getChunk().getZ() * 16); + int n = 0; + for (int i = 0; i < 16; ++i){ + for (int j = 0; j < 16; ++j) { + Location square = chunkLocation.clone().add(i, 0, j); + for (int k = minHeight; k <= maxHeight; ++k) { + square.add(0.0, 1.0, 0.0); + if (square.getBlock().getType() == Material.TRIPWIRE && ++n > MainConfig.wireAmount) { + return true; + } + } + } + } + return false; + } + + public static boolean reachFrameLimit(Location location) { + int minHeight = location.getWorld().getMinHeight(); + int maxHeight = location.getWorld().getMaxHeight(); + Location chunkLocation = new Location(location.getWorld(), location.getChunk().getX() * 16, minHeight, location.getChunk().getZ() * 16); + int n = 0; + for (int i = 0; i < 16; ++i) { + for (int j = 0; j < 16; ++j) { + Location square = chunkLocation.clone().add(i + 0.5, 0.5, j + 0.5); + for (int k = minHeight; k <= maxHeight; ++k) { + square.add(0.0, 1.0, 0.0); + if (FurnitureUtil.hasFurniture(square) && ++n > MainConfig.frameAmount) { + return true; + } + } + } + } + return false; + } +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customcrops/utils/LocUtil.java b/src/main/java/net/momirealms/customcrops/utils/LocUtil.java deleted file mode 100644 index 0fd609b..0000000 --- a/src/main/java/net/momirealms/customcrops/utils/LocUtil.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.momirealms.customcrops.utils; - -import net.momirealms.customcrops.objects.SimpleLocation; -import org.bukkit.Location; - -public class LocUtil { - /** - * 将Location转换为SimpleLocation - * @param location Location - * @return SimpleLocation - */ - public static SimpleLocation fromLocation(Location location){ - return new SimpleLocation(location.getWorld().getName(), location.getBlockX(), location.getBlockY(), location.getBlockZ()); - } -} diff --git a/src/main/java/net/momirealms/customcrops/utils/MiscUtils.java b/src/main/java/net/momirealms/customcrops/utils/MiscUtils.java new file mode 100644 index 0000000..7bcba7c --- /dev/null +++ b/src/main/java/net/momirealms/customcrops/utils/MiscUtils.java @@ -0,0 +1,21 @@ +package net.momirealms.customcrops.utils; + +import net.momirealms.customcrops.objects.SimpleLocation; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.jetbrains.annotations.Nullable; + +public class MiscUtils { + + public static SimpleLocation getSimpleLocation(Location location) { + return new SimpleLocation(location.getWorld().getName(), location.getBlockX(), location.getBlockY(), location.getBlockZ()); + } + + @Nullable + public static Location getLocation(SimpleLocation location) { + World world = Bukkit.getWorld(location.getWorldName()); + if (world == null) return null; + return new Location(world, location.getX(), location.getY(), location.getZ()); + } +} diff --git a/src/main/java/net/momirealms/customcrops/utils/PotUtil.java b/src/main/java/net/momirealms/customcrops/utils/PotUtil.java deleted file mode 100644 index 30b8081..0000000 --- a/src/main/java/net/momirealms/customcrops/utils/PotUtil.java +++ /dev/null @@ -1,115 +0,0 @@ -package net.momirealms.customcrops.utils; - -import dev.lone.itemsadder.api.CustomBlock; -import net.momirealms.customcrops.ConfigReader; -import net.momirealms.customcrops.datamanager.PotManager; -import net.momirealms.customcrops.objects.fertilizer.*; -import org.bukkit.Location; -import org.bukkit.Particle; - -public class PotUtil { - - /** - * 水壶浇水判定 - * @param width 宽度 - * @param length 长度 - * @param location 位置 - * @param yaw 视角 - */ - public static void waterPot(int width, int length, Location location, float yaw){ - if (ConfigReader.Config.hasParticle) - location.getWorld().spawnParticle(Particle.WATER_SPLASH, location.clone().add(0.5,1.2,0.5),15,0.1,0.1, 0.1); - int extend = width / 2; - if (yaw < 45 && yaw > -135) { - if (yaw > -45) { - for (int i = -extend; i <= extend; i++) { - Location tempLoc = location.clone().add(i, 0, -1); - for (int j = 0; j < length; j++){ - tempLoc.add(0,0,1); - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(tempLoc.getBlock()); - if(customBlock != null){ - if(customBlock.getNamespacedID().equals(ConfigReader.Basic.pot)){ - CustomBlock.remove(tempLoc); - CustomBlock.place(ConfigReader.Basic.watered_pot, tempLoc); - } - } - } - } - } - else { - for (int i = -extend; i <= extend; i++) { - Location tempLoc = location.clone().add(-1, 0, i); - for (int j = 0; j < length; j++){ - tempLoc.add(1,0,0); - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(tempLoc.getBlock()); - if(customBlock != null){ - if(customBlock.getNamespacedID().equals(ConfigReader.Basic.pot)){ - CustomBlock.remove(tempLoc); - CustomBlock.place(ConfigReader.Basic.watered_pot, tempLoc); - } - } - } - } - } - } - else { - if (yaw > 45 && yaw < 135) { - for (int i = -extend; i <= extend; i++) { - Location tempLoc = location.clone().add(1, 0, i); - for (int j = 0; j < length; j++){ - tempLoc.subtract(1,0,0); - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(tempLoc.getBlock()); - if(customBlock != null){ - if(customBlock.getNamespacedID().equals(ConfigReader.Basic.pot)){ - CustomBlock.remove(tempLoc); - CustomBlock.place(ConfigReader.Basic.watered_pot, tempLoc); - } - } - } - } - } - else { - for (int i = -extend; i <= extend; i++) { - Location tempLoc = location.clone().add(i, 0, 1); - for (int j = 0; j < length; j++){ - tempLoc.subtract(0,0,1); - CustomBlock customBlock = CustomBlock.byAlreadyPlaced(tempLoc.getBlock()); - if(customBlock != null){ - if(customBlock.getNamespacedID().equals(ConfigReader.Basic.pot)){ - CustomBlock.remove(tempLoc); - CustomBlock.place(ConfigReader.Basic.watered_pot, tempLoc); - } - } - } - } - } - } - } - - /** - * 添加肥料 - * @param fertilizerConfig 肥料配置 - * @param location 种植盆位置 - */ - public static void addFertilizer(Fertilizer fertilizerConfig, Location location) { - if (fertilizerConfig instanceof QualityCrop config){ - QualityCrop qualityCrop = new QualityCrop(config.getKey(), config.getTimes()); - qualityCrop.setChance(config.getChance()); - PotManager.Cache.put(LocUtil.fromLocation(location), qualityCrop); - }else if (fertilizerConfig instanceof SpeedGrow config){ - SpeedGrow speedGrow = new SpeedGrow(config.getKey(), config.getTimes()); - speedGrow.setChance(config.getChance()); - PotManager.Cache.put(LocUtil.fromLocation(location), speedGrow); - }else if (fertilizerConfig instanceof RetainingSoil config){ - RetainingSoil retainingSoil = new RetainingSoil(config.getKey(), config.getTimes()); - retainingSoil.setChance(config.getChance()); - PotManager.Cache.put(LocUtil.fromLocation(location), retainingSoil); - }else if (fertilizerConfig instanceof YieldIncreasing config){ - YieldIncreasing yieldIncreasing = new YieldIncreasing(config.getKey(), config.getTimes()); - yieldIncreasing.setBonus(config.getBonus()); - yieldIncreasing.setChance(config.getChance()); - PotManager.Cache.put(LocUtil.fromLocation(location), yieldIncreasing); - } - if (fertilizerConfig.getParticle() != null) location.getWorld().spawnParticle(fertilizerConfig.getParticle(), location.add(0.5,1.3,0.5), 5,0.2,0.2,0.2); - } -} diff --git a/src/main/resources/basic.yml b/src/main/resources/basic.yml deleted file mode 100644 index 90b3a6d..0000000 --- a/src/main/resources/basic.yml +++ /dev/null @@ -1,68 +0,0 @@ -#ItemsAdder items namespacedID -basic: - pot: customcrops:pot - watered-pot: customcrops:watered_pot - greenhouse-glass: customcrops:greenhouse_glass - dead-crop: customcrops:crop_stage_death - soil-detector: customcrops:soil_detector - - -# If you want watering-can has custom durability -# Just set material to damageable items like wooden_sword -# custom durability in itemsadder is compatible in CustomCrops -water-can: - watering_can_1: - item: customcrops:watering_can_1 - #Max storage - max: 3 - #Effective Range - width: 1 - length: 1 - watering_can_2: - item: customcrops:watering_can_2 - max: 4 - width: 1 - length: 3 - watering_can_3: - item: customcrops:watering_can_3 - max: 5 - width: 3 - length: 3 - watering_can_4: - item: customcrops:watering_can_4 - max: 6 - width: 3 - length: 5 - - - -lore: - #Should lore be changed when using watering-can - watering-can: - enable: true - #Lore format - #Available variables: {water_info} - #{water}current water {max_water}max storage - lore: - - '{water_info}' - - 'Right click water to add water to the can.' - #{water_info} - left: '뀂' - full: '뀁뀃' - empty: '뀁뀄' - right: '뀁뀅' - - - -sprinkler: - sprinkler_1: - range: 1 - #Max storage - max-water: 5 - 3Ditem: customcrops:sprinkler_1 - 2Ditem: customcrops:sprinkler_1_item - sprinkler_2: - range: 2 - max-water: 7 - 3Ditem: customcrops:sprinkler_2 - 2Ditem: customcrops:sprinkler_2_item \ No newline at end of file diff --git a/src/main/resources/basic_itemsadder.yml b/src/main/resources/basic_itemsadder.yml new file mode 100644 index 0000000..16fbdd9 --- /dev/null +++ b/src/main/resources/basic_itemsadder.yml @@ -0,0 +1,8 @@ +dry-pot: customcrops:pot +wet-pot: customcrops:watered_pot +greenhouse-glass: customcrops:greenhouse_glass +dead-crop: customcrops:crop_stage_death +soil-surveyor: customcrops:soil_surveyor +crow: customcrops:crow +scarecow: customcrops:scarecow +water-effect: customcrops:water_effect \ No newline at end of file diff --git a/src/main/resources/basic_oraxen.yml b/src/main/resources/basic_oraxen.yml new file mode 100644 index 0000000..55bf35b --- /dev/null +++ b/src/main/resources/basic_oraxen.yml @@ -0,0 +1,8 @@ +dry-pot: pot +wet-pot: watered_pot +greenhouse-glass: greenhouse_glass +dead-crop: crop_stage_death +soil-surveyor: soil_surveyor +crow: crow +scarecow: scarecow +water-effect: water_effect \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 360f941..85bcfa0 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,172 +1,168 @@ #Don't change -config-version: '7' - -#Want to sell the crops? -#Try this plugin: https://www.spigotmc.org/resources/shipping-bin.104591/ -#You can use it with a command binding to an ItemsAdder furniture -#Shipping Bin is similar to the way how players sell items in Stardrew Valley - -config: - # lang: english / spanish / chinese - lang: english - - - # mode: tripwire / item_frame - # This option requires a server restart - # ------------ tripwire ------------ - # Advantage: - # ● async check, less lag - # ● Real block hitbox like vanilla - # - # Disadvantage: - # ● limited amount(127) /iainfo to see how many slots available - # ● visual problem when breaking crops - # ● Can't remove tripwire break sound - # - # ------------ item_frame ------------ - # Advantage: - # ● unlimited amount, create as many as crop types as you want - # ● No tripwire break sound - # ● Rotation - # - # Disadvantage: - # ● entities are very laggy(loading every 5~8 item frames need 0.01 mspt) - # ● spigot optimized the view distance of entities - # ● crops would go missing if there's a large amount of furniture replacing in the same tick(128 crops/tick) - # ● And I can't fix this in my plugin because furniture replacing is handled by ItemsAdder. - # ● No real block hitbox - # ● ItemsAdder furniture breaking sound - # ● itemsAdder loot system doesn't apply to furnitures. - # - crop-mode: tripwire +config-version: '9' - # Should crops be planted in random rotation? - # only works in item_frame mode - rotation: - enable: false - # 4 / 8 - variant: 4 +# lang: english / spanish / chinese +lang: chinese - integration: - #integration to prevent other players' grief - Residence: false - WorldGuard: false - Kingdoms: false - GriefDefender: false - PlotSquared: false - Towny: false - Lands: false - GriefPrevention: false - CrashClaim: false - BentoBox: false - #integration to add players' farming skill xp - AureliumSkills: false - mcMMO: false - MMOCore: false - EcoSkills: false - JobsReborn: false - #integration to sync seasons - RealisticSeasons: false +integration: + # AntiGrief + Residence: false + WorldGuard: false + Kingdoms: false + GriefDefender: false + PlotSquared: false + Towny: false + Lands: false + GriefPrevention: false + CrashClaim: false + BentoBox: false + # Skill Xp + AureliumSkills: false + mcMMO: false + MMOCore: false + EcoSkills: false + JobsReborn: false + # Season + RealisticSeasons: false - # Mode 1: - # ● Crops in loaded chunks will grow - # Mode 2: - # ● Online players' crops will grow - # Mode 3: - # ● If you enable season, mode 3 is recommended (Mode 1 + Mode 2) - # Mode 4: - # ● If you disable season, mode 4 is recommended - # ● All the crops will grow, this is good for offline crops - # ● If season not disabled, your server would be lagging when there's a lot of data - # ● Crop data would be removed as soon as they are ripe when season disabled, so it would not cause lag! - grow-mode: 3 - # The time to start growing(ticks) - # 1000ticks is 7am in game. (0-23999) - # Sprinklers will work after all crops finish growing - grow-time: - - 1000 - - # Time in real life - #real-time: - # - 06:30 - - # Time in random a single crop need to grow(seconds) - # This prevents a large amount of crops grow at the same time - # Large amount of block replacement would cause lag. - time-to-grow: 60 - # Similar to "time-to-grow", this prevent all sprinklers work at the same time - time-to-work: 30 - # Async Time Check (requires restart) - # Crops might not grow when using async. - # It is not really necessary to be Async - async-time-check: false - # Worlds where crops would grow - whitelist-worlds: +worlds: + # Mode: whitelist/blacklist + mode: whitelist + list: - world - # Should all the worlds' crops grow? - # This is useful for per player per world server. - # In this mode, whitelist world can only have one for time & season judgment. - all-world-grow: false - # How does gigantic work? - # In stardrew valley, crops will still absorb water every day after it is ripe to be gigantic - # But you can give it only one chance to be gigantic(This is also good for performance) - gigantic-only-one-try: false - quality: - # If disabled, you need to configurate the loots in ItemsAdder config + +crops: + # Mode: tripwire/item_frame + mode: tripwire + + + +optimization: + # Recommend enabling this to prevent large quantities of crops/itemframes lagging the server + limitation: enable: true - # Default ratio - default-ratio: 17/2/1 + tripwire-amount: 64 + itemframe-amount: 64 + + # Async time check + async-time-check: false - # Water Amount to refill when using water bucket - sprinkler-refill: 2 - # Water Amount to refill with a single click to water block - water-can-refill: 1 - # Can watering-can add water to sprinklers? - water-can-add-water-to-sprinkler: true - # Should particles be displayed when using watering can? - water-particles: true - - - # Should the pot be dry even there's no crop on it - # This would cost addition performance - pot-dry-always-dry: false - +mechanics: + # Can player harvest crops with right click? + # if set "false" crops can't be harvested repeatedly + right-click-harvest: + enable: true + require-empty-hand: true + # Should player be prevented from planting if wrong season + prevent-plant-if-wrong-season: true + # Should player be notified of the wrong season? + should-notify-if-wrong-season: true + # + fill: + watering-can-to-sprinkler: 1 + water-bucket-to-sprinkler: 3 + waterblock-to-watering-can: 1 # Will bone meal accelerate the growth of crop bone-meal: enable: true chance: 0.5 success-particle: VILLAGER_HAPPY - - - - # Should we limit the max amount of crops and sprinkler in one chunk - # Recommended to enable because ItemsAdder might throw StackOverFlow - # when there are too many custom blocks in one chunk - limit: + # Season mechanic + # Crops would go to death stage if growing in wrong seasons + # Season would not affect ripe crops(for better performance and friendly player's experience) + season: enable: true - crop: 64 - sprinkler: 8 + auto-season-change: + enable: true + #duration of each season + duration: 28 + greenhouse: + enable: true + #effective range + range: 5 + crow: + enable: true + chance: 0.001 + default-quality-ratio: 17/2/1 - # can player harvest crops with right click? - # if set "false" crops can't be harvested repeatedly - right-click-harvest: true - # If "right-click-harvest" is true - # Should player must harvest with empty hands? - harvest-with-empty-hand: true - # Should player be prevented from planting if wrong season - prevent-plant-if-wrong-season: true - # Should player be notified of the wrong season? - should-notify-if-wrong-season: true \ No newline at end of file +sounds: + water-pot: + enable: true + sound: minecraft:block.water.ambient + type: player + add-water-to-can: + enable: true + sound: minecraft:item.bucket.fill + type: player + add-water-to-sprinkler: + enable: true + sound: minecraft:item.bucket.fill + type: player + place-sprinkler: + enable: true + sound: minecraft:block.bone_block.place + type: player + plant-seed: + enable: true + sound: minecraft:item.hoe.till + type: player + use-fertilizer: + enable: true + sound: minecraft:item.hoe.till + type: player + harvest-crops: + enable: true + sound: minecraft:block.crop.break + type: player + bonemeal: + enable: true + sound: minecraft:item.hoe.till + type: player + surveyor: + enable: true + sound: minecraft:block.note_block.pling + type: player + + +#Hologram information +hologram: + #Pot infomation + fertilizer-info: + enable: true + y-offset: 0.8 + duration: 1 + text: '{fertilizer} {times}/{max_times}' + #Sprinkler infomation + sprinkler-info: + enable: true + y-offset: 0.8 + duration: 1 + #available variables {water} {max_water} + left: '뀂' + full: '뀁뀃' + empty: '뀁뀄' + right: '뀁뀅' + + + +actionbar: + #Should actionbar be sent when using watering-can + enable: true + #available variables {water} {max_water} + left: '뀂' + full: '뀁뀃' + empty: '뀁뀄' + right: '뀁뀅' \ No newline at end of file diff --git a/src/main/resources/crops.yml b/src/main/resources/crops.yml deleted file mode 100644 index f0036e0..0000000 --- a/src/main/resources/crops.yml +++ /dev/null @@ -1,126 +0,0 @@ -#ItemsAdder items' name should end with "_seeds" "_stage_X" -#to be identified by the plugin -#Just read the default config and you will know how this plugin work - -crops: - tomato: - #the total amount of crops to be dropped - amount: 1~4 - - #Quality Items - quality: - 1: customcrops:tomato - 2: customcrops:tomato_silver_star - 3: customcrops:tomato_golden_star - - #When you break the crop, the event will be handled by ItemsAdder & Customcrops so IA loots would be certainly dropped - #When you right click the crop, the event will only be handled by Customcrops so IA loots would be optional - - #**right click** harvest, should the crop drop the loots from ItemsAdder too - #This is useful for dropping seeds and other items(only works in tripwire mode, furnitures don't support loot at the moment) - drop-ia-loots: false - - #**right click** harvest, should the crop drop other loots - #This is useful for dropping seeds and other items(Works in both tripwire/item_frame mode) - drop-other-loots: - - customcrops:tomato_seeds - - #optional - #The chance that a crop grow a stage at grow time - grow-chance: 0.9 - - #optional - #Overweight - gigantic: - block: customcrops:gigantic_tomato - chance: 0.01 - - #If you want to use item_frame/armor_stand for gigantic crops - #You should config like this - #gigantic: - # furniture: customcrops:gigantic_tomato - # chance: 0.01 - - #optional - commands: - - 'say {player} harvested a tomato! lol' - - #optional - #If you are using skill plugin, you can add farming skill xp to players - #skill-xp: 100 - - #optional - season: - - summer - - autumn - - #optional - #Requirements to plant - requirements: - yPos: - - 50~100 - - 150~200 - biome: - - minecraft:plains - world: - - world - permission: 'customcrops.plant.tomato' - - cabbage: - amount: 1~2 - quality: - 1: customcrops:cabbage - 2: customcrops:cabbage_silver_star - 3: customcrops:cabbage_golden_star - gigantic: - block: customcrops:gigantic_cabbage - chance: 0.01 - season: - - spring - - grape: - amount: 2~4 - quality: - 1: customcrops:grape - 2: customcrops:grape_silver_star - 3: customcrops:grape_golden_star - #optional - #The stage to return when harvesting with a single right click - return: customcrops:grape_stage_4 - season: - - autumn - - corn: - amount: 2~3 - quality: - 1: customcrops:corn - 2: customcrops:corn_silver_star - 3: customcrops:corn_golden_star - season: - - autumn - - summer - - pepper: - amount: 3~6 - quality: - 1: customcrops:pepper - 2: customcrops:pepper_silver_star - 3: customcrops:pepper_golden_star - season: - - spring - - summer - return: customcrops:pepper_stage_3 - - garlic: - amount: 3~4 - quality: - 1: customcrops:garlic - 2: customcrops:garlic_silver_star - 3: customcrops:garlic_golden_star - - redpacket: - amount: 3~4 - quality: - 1: customcrops:redpacket - 2: customcrops:redpacket - 3: customcrops:redpacket \ No newline at end of file diff --git a/src/main/resources/crops_itemsadder.yml b/src/main/resources/crops_itemsadder.yml new file mode 100644 index 0000000..d991573 --- /dev/null +++ b/src/main/resources/crops_itemsadder.yml @@ -0,0 +1,52 @@ +tomato: + # If you don't need quality-loots just delete them + quality-loots: + amount: 1~4 + quality: + 1: customcrops:tomato + 2: customcrops:tomato_silver_star + 3: customcrops:tomato_golden_star + + other-loots: + loot_1: + item: customcrops:tomato_seeds + min_amount: 1 + max_amount: 2 + chance: 0.8 + loot_2: + item: customcrops:tomato + min_amount: 1 + max_amount: 2 + chance: 0.8 + + gigantic-crop: + block: customcrops:gigantic_tomato + #furniture: customcrops:gigantic_tomato(If you want gigantic crop to be a furniture) + chance: 0.01 + + harvest-actions: + messages: + - 'Test Message' + commands: + - 'say {player} harvested a tomato! lol' + xp: 10 + #skill-xp: 100 + + return: customcrops:tomato_stage_1 + + #optional + season: + - summer + - autumn + + requirements: + condition_1: + # available types: + # permission/biome/time/weather/world/yPos + type: permission + # Mode: && / || + mode: '&&' + value: + - crops.plant.tomato + # The message to be shown when player doesn't fit the requirement + message: 'You don''t have permission to plant this seed!' \ No newline at end of file diff --git a/src/main/resources/crops_oraxen.yml b/src/main/resources/crops_oraxen.yml new file mode 100644 index 0000000..5a824f2 --- /dev/null +++ b/src/main/resources/crops_oraxen.yml @@ -0,0 +1,33 @@ +crops: + + tomato: + + # If you don't need quality-loots just delete them + quality-loots: + amount: 1~4 + quality: + 1: tomato + 2: tomato_silver_star + 3: tomato_golden_star + + drop-other-loots: + loot_1: + item: tomato_seeds + amount: 1~2 + chance: 0.8 + + gigantic-crop: + block: gigantic_tomato + #furniture: gigantic_tomato(If you want gigantic crop to be a furniture) + chance: 0.01 + + harvest-actions: + commands: + - 'say {player} harvested a tomato! lol' + exp: 10 + #skill-xp: 100 + + #optional + season: + - summer + - autumn \ No newline at end of file diff --git a/src/main/resources/fertilizer.yml b/src/main/resources/fertilizers_itemsadder.yml similarity index 73% rename from src/main/resources/fertilizer.yml rename to src/main/resources/fertilizers_itemsadder.yml index c1c7705..9a6119d 100644 --- a/src/main/resources/fertilizer.yml +++ b/src/main/resources/fertilizers_itemsadder.yml @@ -3,18 +3,17 @@ speed: speed_1: #Fertilizer Hologram display name name: '뀌' + #The chance of this fertilizer taking effect chance: 0.1 - #How many times can this fertilizer stay in pot + #How many days can this fertilizer stay in pot times: 14 #ItemsAdder item namespacedID item: customcrops:speed_1 #Should this fertilizer be used before planting before-plant: true - #Optional - #The particle to display + #The particle to be displayed when using fertilizer #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Particle.html - #particle: VILLAGER_HAPPY - + particle: VILLAGER_HAPPY speed_2: name: '뀍' chance: 0.2 @@ -29,7 +28,6 @@ speed: before-plant: true - #Pot have a small chance to retain its water after crops grow retaining: retaining_1: @@ -38,14 +36,12 @@ retaining: times: 28 item: customcrops:retaining_1 before-plant: false - retaining_2: name: '뀊' chance: 0.2 times: 28 item: customcrops:retaining_2 before-plant: false - retaining_3: name: '뀋' chance: 0.3 @@ -54,32 +50,31 @@ retaining: before-plant: false - #When haveresting, players have a higher chance to get high quality crops. quality: quality_1: name: '뀆' + chance: 1 times: 28 - chance: 7/2/1 + ratio: 7/2/1 item: customcrops:quality_1 before-plant: true - quality_2: name: '뀇' + chance: 1 times: 28 - chance: 11/6/3 + ratio: 11/6/3 item: customcrops:quality_2 before-plant: true - quality_3: name: '뀈' + chance: 1 times: 28 - chance: 2/2/1 + ratio: 2/2/1 item: customcrops:quality_3 before-plant: true - #When haveresting, players have a higher chance to get more crops. quantity: quantity_1: @@ -102,4 +97,26 @@ quantity: chance: 0.8 bonus: 2 item: customcrops:quantity_3 + before-plant: true + + +#Crops have a higher chance to be gigantic +gigantic: + gigantic_1: + name: '뀆' + times: 14 + chance: 0.5 + item: customcrops:gigantic_1 + before-plant: true + gigantic_2: + name: '뀐' + times: 14 + chance: 0.5 + item: customcrops:gigantic_2 + before-plant: true + gigantic_3: + name: '뀑' + times: 14 + chance: 0.8 + item: customcrops:gigantic_3 before-plant: true \ No newline at end of file diff --git a/src/main/resources/fertilizers_oraxen.yml b/src/main/resources/fertilizers_oraxen.yml new file mode 100644 index 0000000..9ef8d17 --- /dev/null +++ b/src/main/resources/fertilizers_oraxen.yml @@ -0,0 +1,123 @@ +#Crops have a small chance to grow two stages at a time +speed: + speed_1: + #Fertilizer Hologram display name + name: '뀌' + #The chance of this fertilizer taking effect + chance: 0.1 + #How many days can this fertilizer stay in pot + times: 14 + #Oraxen Item id + item: speed_1 + #Should this fertilizer be used before planting + before-plant: true + #The particle to be displayed when using fertilizer + #https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Particle.html + particle: VILLAGER_HAPPY + speed_2: + name: '뀍' + chance: 0.2 + times: 14 + item: speed_2 + before-plant: true + speed_3: + name: '뀎' + chance: 0.3 + times: 14 + item: speed_3 + before-plant: true + + +#Pot have a small chance to retain its water after crops grow +retaining: + retaining_1: + name: '뀉' + chance: 0.1 + times: 28 + item: retaining_1 + before-plant: false + retaining_2: + name: '뀊' + chance: 0.2 + times: 28 + item: retaining_2 + before-plant: false + retaining_3: + name: '뀋' + chance: 0.3 + times: 28 + item: retaining_3 + before-plant: false + + +#When haveresting, players have a higher chance to get high quality crops. +quality: + quality_1: + name: '뀆' + times: 28 + chance: 1 + ratio: 7/2/1 + item: quality_1 + before-plant: true + quality_2: + name: '뀇' + times: 28 + chance: 1 + ratio: 11/6/3 + item: quality_2 + before-plant: true + quality_3: + name: '뀈' + times: 28 + chance: 1 + ratio: 2/2/1 + item: quality_3 + before-plant: true + + +#When haveresting, players have a higher chance to get more crops. +quantity: + quantity_1: + name: '뀆' + times: 14 + chance: 0.5 + bonus: 1 + item: quantity_1 + before-plant: true + quantity_2: + name: '뀐' + times: 14 + chance: 0.5 + bonus: 2 + item: quantity_2 + before-plant: true + quantity_3: + name: '뀑' + times: 14 + chance: 0.8 + bonus: 2 + item: quantity_3 + before-plant: true + + +#Crops have a higher chance to be gigantic +gigantic: + gigantic_1: + name: '뀆' + times: 14 + # If a crop's default gigantic chance is 0.01, now it's 0.03 + chance: 0.02 + item: gigantic_1 + before-plant: true + gigantic_2: + name: '뀐' + times: 14 + chance: 0.04 + item: gigantic_2 + before-plant: true + gigantic_3: + name: '뀑' + times: 14 + chance: 0.08 + item: gigantic_3 + before-plant: true \ No newline at end of file diff --git a/src/main/resources/messages/messages_chinese.yml b/src/main/resources/messages/messages_chinese.yml index f6d3200..72ba287 100644 --- a/src/main/resources/messages/messages_chinese.yml +++ b/src/main/resources/messages/messages_chinese.yml @@ -10,52 +10,15 @@ messages: summer: '夏' autumn: '秋' winter: '冬' - sprinkler-limit: '此区块的洒水器已到达上限{max}' - crop-limit: '此区块的农作物数量已到达上限{max}' - not-configed: '此种子未在配置文件中配置!' - bad-Y: '此高度不适合这种农作物生长!' - bad-biome: '此生物群系不适合这种农作物生长!' - bad-perm: '你还没有权限种植这种农作物呢!' - bad-world: '这个农作物无法在这个世界生长!' - bad-season: '当前季节不适合这种农作物生长!' - force-grow: '成功强制 {world} 的农作物生长!' - force-water: '成功强制 {world} 的洒水器洒水!' - force-save: '成功强制保存缓存信息!' - force-all: '成功强制 {world} 的农作物生长和洒水器工作!' + limitation-tripwire: '此区块的拌线数量已到达上限 {max}' + limitation-itemframe: '此区块的展示框数量已到达上限 {max}' + grow-simulation: '已开始模拟生长' back-up: '已完成数据备份!' set-season: '成功切换世界 {world} 的季节为 {season}!' before-plant: '这种肥料必须在种植前使用!' - no-season: '当前世界没有季节' -#全息信息显示 -hologram: - #农作物肥料信息 - grow-info: - enable: true - #悬浮信息高度偏移 - y-offset: 0.8 - #悬浮信息持续时间(秒) - duration: 1 - #悬浮信息内容 - #可用变量 {fertilizer}肥料名 {times}剩余生效次数 {max_times}最大生效次数 - text: '{fertilizer} {times}/{max_times}' - #洒水器信息 - sprinkler-info: - enable: true - y-offset: -0.2 - duration: 1 - #可用变量 {water}当前水量 {max_water}最大蓄水量 - left: '뀂' - full: '뀁뀃' - empty: '뀁뀄' - right: '뀁뀅' - -actionbar: - #使用水壶的时候是否发送actionbar - watering-can: - enable: true - #可用变量 {water}当前水量 {max_water}最大蓄水量 - left: '뀂' - full: '뀁뀃' - empty: '뀁뀄' - right: '뀁뀅' \ No newline at end of file + no-season: '此世界没有季节' + season-disabled: '季节系统已被禁用' + auto-season-disabled: '自动季节切换已被禁用,无法计算此变量' + world-not-exist: '世界 {world} 不存在' + season-not-exist: '季节 {season} 不存在' \ No newline at end of file diff --git a/src/main/resources/messages/messages_english.yml b/src/main/resources/messages/messages_english.yml index 1173695..72ba287 100644 --- a/src/main/resources/messages/messages_english.yml +++ b/src/main/resources/messages/messages_english.yml @@ -2,57 +2,23 @@ #https://docs.adventure.kyori.net/minimessage/format.html messages: prefix: '[CustomCrops] ' - reload: 'Reloaded! Took {time}ms' - no-perm: 'No Permission!' - lack-args: 'Arguments are insufficient!' - wrong-args: 'Wrong Args!' - spring: 'Spring' - summer: 'Summer' - autumn: 'Autumn' - winter: 'Winter' - sprinkler-limit: 'Sprinklers have reached chunk limitation {max}' - crop-limit: 'Crops have reached chunk limitation {max}' - not-configed: 'This seed is not configurated in config!' - bad-Y: 'This height is not suitable for planting!' - bad-biome: 'This biome is not suitable for planting!' - bad-perm: 'You don''t have permission to plant this crop!' - bad-world: 'This world is not suitable for planting' - bad-season: 'Current season is not suitable for planting' - force-grow: 'Forced {world}''s crops to start growing!' - force-water: 'Forced {world}''s sprinklers to start working!' - force-save: 'Successfully saved cache to file!' - force-all: 'Forced {world}''s crops to start growing and sprinklers to start working!' - back-up: 'Backed up!' - set-season: 'Changed {world}''s season to {season}!' - before-plant: 'This fertilizer must be used befored planting!' - no-season: 'Season Disabled' + reload: '重载成功! 耗时 {time}ms' + no-perm: '权限不足!' + lack-args: '参数不足!' + wrong-args: '参数错误!' + spring: '春' + summer: '夏' + autumn: '秋' + winter: '冬' + limitation-tripwire: '此区块的拌线数量已到达上限 {max}' + limitation-itemframe: '此区块的展示框数量已到达上限 {max}' + grow-simulation: '已开始模拟生长' + back-up: '已完成数据备份!' + set-season: '成功切换世界 {world} 的季节为 {season}!' + before-plant: '这种肥料必须在种植前使用!' -#Holograms -hologram: - #Pot infomation - grow-info: - enable: true - y-offset: 0.8 - duration: 1 - #available variables {fertilizer} {times} {max_times} - text: '{fertilizer} {times}/{max_times}' - #Sprinkler infomation - sprinkler-info: - enable: true - y-offset: -0.2 - duration: 1 - #available variables {water} {max_water} - left: '뀂' - full: '뀁뀃' - empty: '뀁뀄' - right: '뀁뀅' - -actionbar: - #Should actionbar be sent when using watering-can - watering-can: - enable: true - #available variables {water} {max_water} - left: '뀂' - full: '뀁뀃' - empty: '뀁뀄' - right: '뀁뀅' \ No newline at end of file + no-season: '此世界没有季节' + season-disabled: '季节系统已被禁用' + auto-season-disabled: '自动季节切换已被禁用,无法计算此变量' + world-not-exist: '世界 {world} 不存在' + season-not-exist: '季节 {season} 不存在' \ No newline at end of file diff --git a/src/main/resources/messages/messages_spanish.yml b/src/main/resources/messages/messages_spanish.yml index e8faa11..f6a8c73 100644 --- a/src/main/resources/messages/messages_spanish.yml +++ b/src/main/resources/messages/messages_spanish.yml @@ -25,34 +25,4 @@ messages: back-up: 'Backed up!' set-season: '¡Cambió la estación de {world} a {season}!' before-plant: 'Este abono debe utilizarse antes de la siembra.' - no-season: 'Temporada Desactivada' - -#Holograms -hologram: - #Pot infomation - grow-info: - enable: true - y-offset: 0.8 - duration: 1 - #available variables {fertilizer} {times} {max_times} - text: '{fertilizer} {times}/{max_times}' - #Sprinkler infomation - sprinkler-info: - enable: true - y-offset: -0.2 - duration: 1 - #available variables {water} {max_water} - left: '뀂' - full: '뀁뀃' - empty: '뀁뀄' - right: '뀁뀅' - -actionbar: - #Should actionbar be sent when using watering-can - watering-can: - enable: true - #available variables {water} {max_water} - left: '뀂' - full: '뀁뀃' - empty: '뀁뀄' - right: '뀁뀅' \ No newline at end of file + no-season: 'Temporada Desactivada' \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 73bf81b..a0ae776 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,12 +1,13 @@ name: CustomCrops version: '${version}' main: net.momirealms.customcrops.CustomCrops -api-version: 1.16 +api-version: 1.17 authors: [ XiaoMoMi ] depend: - - ItemsAdder - ProtocolLib softdepend: + - ItemsAdder + - Oraxen - PlaceholderAPI - Residence - Kingdoms diff --git a/src/main/resources/redis.yml b/src/main/resources/redis.yml deleted file mode 100644 index 1226c80..0000000 --- a/src/main/resources/redis.yml +++ /dev/null @@ -1,11 +0,0 @@ -# Sync online players list between servers -# Designed for grow-mode 2 & 3 -redis: - enable: false - host: localhost - port: 6379 - MaxTotal: 8 - MaxIdle: 8 - MinIdle: 1 - MaxWaitMillis: 30000 - MinEvictableIdleTimeMillis: 1800000 \ No newline at end of file diff --git a/src/main/resources/season.yml b/src/main/resources/season.yml deleted file mode 100644 index a822089..0000000 --- a/src/main/resources/season.yml +++ /dev/null @@ -1,17 +0,0 @@ -season: - - #require a restart to apply - enable: true - - auto-season-change: - #If you enabled RealisticSeasons Integration - #keep this true - enable: true - #duration of each season - #would not take effect if enabled RealisticSeasons Integration - duration: 28 - - greenhouse: - enable: true - #effective range - range: 5 \ No newline at end of file diff --git a/src/main/resources/sounds.yml b/src/main/resources/sounds.yml deleted file mode 100644 index 11dca09..0000000 --- a/src/main/resources/sounds.yml +++ /dev/null @@ -1,31 +0,0 @@ -water-pot: - sound: minecraft:block.water.ambient - type: player - -add-water-to-can: - sound: minecraft:item.bucket.fill - type: player - -add-water-to-sprinkler: - sound: minecraft:item.bucket.fill - type: player - -place-sprinkler: - sound: minecraft:block.bone_block.place - type: player - -plant-seed: - sound: minecraft:item.hoe.till - type: player - -use-fertilizer: - sound: minecraft:item.hoe.till - type: player - -harvest: - sound: minecraft:block.crop.break - type: player - -bonemeal: - sound: minecraft:item.hoe.till - type: player \ No newline at end of file diff --git a/src/main/resources/sprinklers_itemsadder.yml b/src/main/resources/sprinklers_itemsadder.yml new file mode 100644 index 0000000..0d2b552 --- /dev/null +++ b/src/main/resources/sprinklers_itemsadder.yml @@ -0,0 +1,10 @@ +sprinkler_1: + range: 1 + max-water-storage: 5 + 3Ditem: customcrops:sprinkler_1 + 2Ditem: customcrops:sprinkler_1_item +sprinkler_2: + range: 2 + max-water-storage: 7 + 3Ditem: customcrops:sprinkler_2 + 2Ditem: customcrops:sprinkler_2_item \ No newline at end of file diff --git a/src/main/resources/sprinklers_oraxen.yml b/src/main/resources/sprinklers_oraxen.yml new file mode 100644 index 0000000..1242ab0 --- /dev/null +++ b/src/main/resources/sprinklers_oraxen.yml @@ -0,0 +1,10 @@ +sprinkler_1: + range: 1 + max-water-storage: 5 + 3Ditem: sprinkler_1 + 2Ditem: sprinkler_1_item +sprinkler_2: + range: 2 + max-water-storage: 7 + 3Ditem: sprinkler_2 + 2Ditem: sprinkler_2_item \ No newline at end of file diff --git a/src/main/resources/watercans_itemsadder.yml b/src/main/resources/watercans_itemsadder.yml new file mode 100644 index 0000000..8e8cc66 --- /dev/null +++ b/src/main/resources/watercans_itemsadder.yml @@ -0,0 +1,21 @@ +watering_can_1: + item: customcrops:watering_can_1 + max-water-storage: 3 + #Effective Range + width: 1 + length: 1 +watering_can_2: + item: customcrops:watering_can_2 + max-water-storage: 4 + width: 1 + length: 3 +watering_can_3: + item: customcrops:watering_can_3 + max-water-storage: 5 + width: 3 + length: 3 +watering_can_4: + item: customcrops:watering_can_4 + max-water-storage: 6 + width: 3 + length: 5 \ No newline at end of file diff --git a/src/main/resources/watercans_oraxen.yml b/src/main/resources/watercans_oraxen.yml new file mode 100644 index 0000000..d32e095 --- /dev/null +++ b/src/main/resources/watercans_oraxen.yml @@ -0,0 +1,21 @@ +watering_can_1: + item: watering_can_1 + max-water-storage: 3 + #Effective Range + width: 1 + length: 1 +watering_can_2: + item: watering_can_2 + max-water-storage: 4 + width: 1 + length: 3 +watering_can_3: + item: watering_can_3 + max-water-storage: 5 + width: 3 + length: 3 +watering_can_4: + item: watering_can_4 + max-water-storage: 6 + width: 3 + length: 5 \ No newline at end of file