9
0
mirror of https://github.com/Xiao-MoMi/Custom-Crops.git synced 2025-12-22 00:19:24 +00:00

1.7 Partially Prepared Products

This commit is contained in:
Xiao-MoMi
2022-10-03 02:20:09 +08:00
parent ed80c56d9b
commit 20d921d3e4
183 changed files with 7453 additions and 6896 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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'

View File

@@ -1,616 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<String, Crop> CROPS = new HashMap<>();
public static HashMap<String, Fertilizer> FERTILIZERS = new HashMap<>();
public static HashMap<String, WateringCan> CANS = new HashMap<>();
public static HashMap<String, Sprinkler> SPRINKLERS = new HashMap<>();
public static HashSet<String> 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<World> worlds;
public static List<String> worldNames;
public static List<Long> cropGrowTimeList;
public static List<Integration> 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("<red>[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("<red>[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("<red>[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<String> 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("<red>[CustomCrops] Watering Can " + key + "'s width should be odd!</red>");
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 <green>" + CANS.size() + " <gray>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 <green>" + SPRINKLERS.size()/2 + "<gray> 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("<red>[CustomCrops] Warining: It's not advised to enable season in mode 4</red>");
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: <gold>Auto");
else AdventureManager.consoleMessage("[CustomCrops] Season Change mode: <gold>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<String> 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("<red>[CustomCrops] You forget to set " + key +"'s amount!</red>");
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<Requirement> 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<String>) value));
case "yPos" -> requirements.add(new YPos((List<String>) value));
case "biome" -> requirements.add(new Biome((List<String>) 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<green> " + CROPS.size() + " <gray>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 <green>" + FERTILIZERS.size() + " <gray>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] <gold>" + plugin + " <color:#FFEBCD>Hooked!");
}
}

View File

@@ -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 <white>" + Bukkit.getVersion());
AdventureUtil.consoleMessage("[CustomCrops] Running on <white>" + 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><u>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><u>Oraxen");
}
else {
AdventureUtil.consoleMessage("<red>[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: <color:#F5DEB3>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: <color:#F5DEB3>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("<gradient:#ff206c:#fdee55>[CustomCrops] </gradient><color:#F5DEB3>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("<gradient:#ff206c:#fdee55>[CustomCrops] </gradient><red>Detected that you might have not set \"disable-REAL_WIRE\" false in ItemsAdder's config!");
AdventureManager.consoleMessage("<gradient:#ff206c:#fdee55>[CustomCrops] </gradient><red>You need a restart to apply that config :)");
}
public PlaceholderManager getPlaceholderManager() {
return placeholderManager;
}
public boolean hasPapi() {
return placeholderManager != null;
}
public CropManager getCropManager() {
return cropManager;
}
}

View File

@@ -15,8 +15,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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() {
}
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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();
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@@ -15,18 +15,21 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@@ -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<String, SubCommand> subCommandMap;
public AbstractSubCommand(String command, Map<String, SubCommand> subCommandMap) {
this.command = command;
this.subCommandMap = subCommandMap;
}
@Override
public boolean onCommand(CommandSender sender, List<String> 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<String> onTabComplete(CommandSender sender, List<String> args) {
if (subCommandMap == null)
return Collections.singletonList("");
if (args.size() <= 1) {
List<String> 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<String, SubCommand> 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<String, SubCommand> subCommandMap) {
this.subCommandMap = subCommandMap;
}
}

View File

@@ -1,94 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<String> 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<String> 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<String> 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<String> 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<String> 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<String> arrayList = new ArrayList<>();
for (String cmd : ConfigReader.Config.worldNames) {
if (cmd.startsWith(args[1]))
arrayList.add(cmd);
}
return arrayList;
}
return null;
}
}

View File

@@ -1,248 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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,"<color:#F5DEB3>/customcrops reload 重载插件");
AdventureManager.playerMessage(player,"<color:#F5DEB3>/customcrops setseason <world> <season> 设置某个世界的季节");
AdventureManager.playerMessage(player,"<color:#F5DEB3>/customcrops backup 备份数据");
AdventureManager.playerMessage(player,"<color:#F5DEB3>/customcrops forcegrow <world> 强制某个世界的农作物进行生长判定");
AdventureManager.playerMessage(player,"<color:#F5DEB3>/customcrops forcewater <world> 强制某个世界的洒水器进行工作判定");
AdventureManager.playerMessage(player,"<color:#F5DEB3>/customcrops forcesave <file> 强制更新缓存并保存");
}else {
AdventureManager.consoleMessage("<color:#F5DEB3>/customcrops reload 重载插件");
AdventureManager.consoleMessage("<color:#F5DEB3>/customcrops setseason <world> <season> 设置某个世界的季节");
AdventureManager.consoleMessage("<color:#F5DEB3>/customcrops backup 备份数据");
AdventureManager.consoleMessage("<color:#F5DEB3>/customcrops forcegrow <world> 强制某个世界的农作物进行生长判定");
AdventureManager.consoleMessage("<color:#F5DEB3>/customcrops forcewater <world> 强制某个世界的洒水器进行工作判定");
AdventureManager.consoleMessage("<color:#F5DEB3>/customcrops forcesave <file> 强制更新缓存并保存");
}
}
}
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);
}
}
}

View File

@@ -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<String, SubCommand> subCommandMap;
public PluginCommand() {
subCommandMap = new ConcurrentHashMap<>();
regDefaultSubCommands();
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
List<String> 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<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
List<String> argList = Arrays.asList(args);
if (argList.size() <= 1) {
List<String> 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<String, SubCommand> getSubCommandMap() {
return subCommandMap;
}
}

View File

@@ -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<String> args);
List<String> onTabComplete(CommandSender sender, List<String> args);
String getSubCommand();
Map<String, SubCommand> getSubCommands();
void regSubCommand(SubCommand subCommand);
}

View File

@@ -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<String> args) {
ConfigUtil.reloadConfigs();
AdventureUtil.sendMessage(sender, MessageConfig.prefix + MessageConfig.reload);
return true;
}
});
}
@Override
public boolean onCommand(CommandSender sender, List<String> 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);
}
}

View File

@@ -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<String> args) {
AdventureUtil.sendMessage(sender, MessageConfig.prefix + MessageConfig.setSeason);
return true;
}
});
}
@Override
public boolean onCommand(CommandSender sender, List<String> 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();
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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");
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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("<red>[CustomCrops] Failed to generate data files!</red>");
}
}
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();
}
}
}

View File

@@ -0,0 +1,157 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<String, Crop> 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<OtherLoot> 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<ActionInterface> 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<String> 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<RequirementInterface> 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 <green>" + CROPS.size() + "<gray> crops");
}
}

View File

@@ -0,0 +1,132 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<String, Fertilizer> 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 <green>" + FERTILIZERS.size() / 2 + "<gray> fertilizers");
}
}

View File

@@ -0,0 +1,222 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<World> 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<AntiGrief> 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<String> 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("<red>[CustomCrops] Illegal Particle Argument for Bone Meal</red>");
}
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", "<font:customcrops:default>뀂");
actionBarFull = config.getString("actionbar.full", "뀁뀃");
actionBarEmpty = config.getString("actionbar.empty", "뀁뀄");
actionBarRight = config.getString("actionbar.right", "뀁뀅</font>");
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", "<font:customcrops:default>뀂");
sprinklerFull = config.getString("hologram.sprinkler-info.full", "뀁뀃");
sprinklerEmpty = config.getString("hologram.sprinkler-info.empty", "뀁뀄");
sprinklerRight = config.getString("hologram.sprinkler-info.right", "뀁뀅</font>");
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", "<font:customcrops:default>{fertilizer}</font> <white>{times}<gray>/<white>{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<World> worldList = new ArrayList<>(Bukkit.getWorlds());
worldList.removeAll(MainConfig.worldList);
return worldList.toArray(new World[0]);
}
}
public static List<World> getWorldsList() {
if (MainConfig.whiteOrBlack) {
return worldList;
}
else {
List<World> worldList = new ArrayList<>(Bukkit.getWorlds());
worldList.removeAll(MainConfig.worldList);
return worldList;
}
}
private static void hookMessage(String plugin){
AdventureUtil.consoleMessage("[CustomCrops] <gold>" + plugin + " <color:#FFEBCD>Hooked!");
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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");
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@@ -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)
);
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<String, Sprinkler> SPRINKLERS_CONFIG;
public static HashMap<String, Sprinkler> SPRINKLERS_2D;
public static HashMap<String, Sprinkler> 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 <green>" + amount + "<gray> sprinklers");
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<String, WaterCan> 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 <green>" + CANS.size() + "<gray> watering cans");
}
}

View File

@@ -1,825 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<SimpleLocation, String> Cache = new ConcurrentHashMap<>();
public static HashSet<SimpleLocation> 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("<red>[CustomCrops] 农作物数据文件生成失败!</red>");
}
}
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("<red>[CustomCrops] crop.yml保存出错!</red>");
}
}
/**
* 将数据保存到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<SimpleLocation> 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<String> 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<String> 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<World> 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("<red>[CustomCrops] Unknown fertilizer, Auto removed!</red>");
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<String> 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<String> 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("<red>[CustomCrops] Unknown fertilizer, Auto removed!</red>");
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<String> 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<String> getPlayers(){
if (ConfigReader.useRedis){
return JedisUtil.getPlayers();
}else {
return new HashSet<>(JoinAndQuit.onlinePlayers);
}
}
}

View File

@@ -1,104 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<SimpleLocation, Fertilizer> 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("<red>[CustomCrops] 种植盆数据文件生成失败!</red>");
}
}
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("<red>[CustomCrops] 未知肥料类型错误!</red>");
}
}
});
});
}
/**
* 保存数据
*/
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();
}
}
}

View File

@@ -1,133 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<String, String> 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("<red>[CustomCrops] 季节数据文件生成失败!</red>");
}
}
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<String> 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("<red>[CustomCrops] 自动季节计算错误!</red>");
}
}
}
/**
* 保存数据
*/
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("<red>[CustomCrops] season.yml保存出错!</red>");
}
});
}
/**
* 设置季节
* @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;
}
}

View File

@@ -1,367 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<SimpleLocation, Sprinkler> Cache = new ConcurrentHashMap<>();
public static HashSet<SimpleLocation> 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("<red>[CustomCrops] 洒水器数据文件生成失败!</red>");
}
}
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("<red>[CustomCrops] sprinkler.yml保存出错!</red>");
}
}
/**
* 清理无用数据
*/
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<SimpleLocation> 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<String> 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<String> 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<World> 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<String> 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;
}
}

View File

@@ -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;

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -0,0 +1,47 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -1,84 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -15,10 +15,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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);
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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);
}

View File

@@ -0,0 +1,464 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<Player, Long> 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<Block> 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);
}
}
}
}
}
}
}
}

View File

@@ -0,0 +1,161 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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());
}
}

View File

@@ -0,0 +1,182 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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());
}
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -0,0 +1,354 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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);
}
}
}
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@@ -0,0 +1,149 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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());
}
}

View File

@@ -0,0 +1,128 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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) {
}
}

View File

@@ -0,0 +1,126 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -0,0 +1,222 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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());
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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) {
}
}

View File

@@ -15,30 +15,27 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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) {
}
}

View File

@@ -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);
}
}

View File

@@ -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);
};
}
}

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customcrops.integrations.season;
public enum CCSeason {
SPRING,
SUMMER,
AUTUMN,
WINTER,
UNKNOWN
}

View File

@@ -0,0 +1,155 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<World, CCSeason> 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<World, CCSeason> 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("<red>[CustomCrops] Error occurs when saving season data</red>");
}
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<World> worlds = new ArrayList<>(Bukkit.getWorlds());
List<World> 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;
};
}
}

View File

@@ -0,0 +1,89 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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);
}

View File

@@ -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");

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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");

View File

@@ -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) {

View File

@@ -1,45 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -1,45 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -1,43 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@@ -1,48 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<String> onlinePlayers = new HashSet<>();
public static HashMap<Player, Long> 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());
}
}

View File

@@ -1,92 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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);
}
}
}
}
}
}
}

View File

@@ -1,107 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<String> 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);
}
}
}
}

View File

@@ -1,352 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<String> 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<String> 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<String> 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());
}
}
}
}

View File

@@ -1,295 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<Block> 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<String> 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<String> 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);
}
}
}
}
}
}
}
}

View File

@@ -1,171 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<Player, Long> 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<String> 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);
}
}
}
}
}

View File

@@ -1,42 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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);
}
}
}
}

View File

@@ -1,166 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<String> 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);
}
}
}

View File

@@ -1,460 +0,0 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<Block> 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<String> 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<String> 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<String> 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<String> 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());
}
}
}
}
}

View File

@@ -0,0 +1,300 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<World, CustomWorld> 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);
}
}
}
}

View File

@@ -15,14 +15,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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);
}

View File

@@ -0,0 +1,300 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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<SimpleLocation, String> cropCache;
private final ConcurrentHashMap<SimpleLocation, Sprinkler> sprinklerCache;
private final ConcurrentHashMap<SimpleLocation, Fertilizer> fertilizerCache;
private final Set<SimpleLocation> 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<SimpleLocation, Fertilizer> 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("<red>[CustomCrops] Failed to save pot data for world " + world.getName() + "</red>");
}
}
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<SimpleLocation, Sprinkler> 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("<red>[CustomCrops] Failed to save sprinkler data for world " + world.getName() + "</red>");
}
}
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<SimpleLocation, String> 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("<red>[CustomCrops] Failed to save crop data for world " + world.getName() + "</red>");
}
}
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<SimpleLocation, Sprinkler> sprinklerEntry : sprinklerCache.entrySet()) {
sprinklerWork(sprinklerEntry.getKey(), sprinklerEntry.getValue());
}
for (Map.Entry<SimpleLocation, Fertilizer> 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);
}
}

View File

@@ -0,0 +1,124 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
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);
}
}

Some files were not shown because too many files have changed in this diff Show More