9
0
mirror of https://github.com/Xiao-MoMi/Custom-Crops.git synced 2025-12-21 16:09:21 +00:00
Files
Custom-Crops/src/main/java/net/momirealms/customcrops/managers/CropManager.java
Xiao-MoMi cce61c98a5 2.0.2
2022-10-20 14:46:20 +08:00

471 lines
19 KiB
Java

/*
* 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.crop.Crop;
import net.momirealms.customcrops.api.event.CropHarvestEvent;
import net.momirealms.customcrops.api.event.CrowAttackEvent;
import net.momirealms.customcrops.config.BasicItemConfig;
import net.momirealms.customcrops.config.MainConfig;
import net.momirealms.customcrops.config.SeasonConfig;
import net.momirealms.customcrops.config.SoundConfig;
import net.momirealms.customcrops.integrations.customplugin.CustomInterface;
import net.momirealms.customcrops.integrations.customplugin.HandlerP;
import net.momirealms.customcrops.integrations.customplugin.itemsadder.*;
import net.momirealms.customcrops.integrations.customplugin.oraxen.*;
import net.momirealms.customcrops.api.utils.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.*;
import net.momirealms.customcrops.managers.timer.CrowTask;
import net.momirealms.customcrops.managers.timer.TimerTask;
import net.momirealms.customcrops.objects.Function;
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.RetainingSoil;
import net.momirealms.customcrops.objects.fertilizer.YieldIncreasing;
import net.momirealms.customcrops.utils.AdventureUtil;
import net.momirealms.customcrops.utils.ArmorStandUtil;
import net.momirealms.customcrops.utils.MiscUtils;
import org.bukkit.*;
import org.bukkit.entity.Item;
import org.bukkit.entity.ItemFrame;
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 ArmorStandUtil armorStandUtil;
private ContainerListener containerListener;
private PlayerModeListener playerModeListener;
private PlayerContainerListener playerContainerListener;
private VanillaCropPlaceListener vanillaCropPlaceListener;
private VanillaCropHarvestListener vanillaCropHarvestListener;
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);
this.armorStandUtil = new ArmorStandUtil(this);
Bukkit.getPluginManager().registerEvents(itemSpawnListener, CustomCrops.plugin);
Bukkit.getPluginManager().registerEvents(worldListener, CustomCrops.plugin);
loadMode();
loadSeason();
loadPacket();
loadVanillaMechanic();
//load Worlds
for (World world : Bukkit.getWorlds()) {
onWorldLoad(world);
}
//new Time Check task
this.timerTask = new TimerTask(this);
this.timerTask.runTaskTimerAsynchronously(CustomCrops.plugin, 1,100);
}
public void loadVanillaMechanic() {
if (this.vanillaCropHarvestListener != null) {
HandlerList.unregisterAll(vanillaCropHarvestListener);
}
if (this.vanillaCropPlaceListener != null) {
HandlerList.unregisterAll(vanillaCropPlaceListener);
}
if (MainConfig.preventPlantVanilla) {
this.vanillaCropPlaceListener = new VanillaCropPlaceListener();
Bukkit.getPluginManager().registerEvents(vanillaCropPlaceListener, CustomCrops.plugin);
}
if (MainConfig.rightHarvestVanilla) {
this.vanillaCropHarvestListener = new VanillaCropHarvestListener();
Bukkit.getPluginManager().registerEvents(vanillaCropHarvestListener, CustomCrops.plugin);
}
}
public void loadMode() {
if (this.handler != null) {
handler.unload();
handler = null;
}
//Custom Plugin
if (MainConfig.customPlugin.equals("itemsadder")) {
customInterface = new ItemsAdderHook();
if (MainConfig.cropMode) {
this.handler = new ItemsAdderWireHandler(this);
this.cropMode = new ItemsAdderWireCropImpl(this);
this.handler.load();
}
else {
this.handler = new ItemsAdderFrameHandler(this);
this.cropMode = new ItemsAdderFrameCropImpl(this);
this.handler.load();
}
}
else if (MainConfig.customPlugin.equals("oraxen")){
customInterface = new OraxenHook();
if (MainConfig.cropMode) {
this.handler = new OraxenWireHandler(this);
this.cropMode = new OraxenWireCropImpl(this);
this.handler.load();
}
else {
this.handler = new OraxenFrameHandler(this);
this.cropMode = new OraxenFrameCropImpl(this);
this.handler.load();
}
}
}
public void loadSeason() {
if (SeasonConfig.enable) {
for (CustomWorld customWorld : customWorlds.values()) {
customWorld.unloadSeason();
}
if (seasonInterface != null) {
seasonInterface.unload();
this.seasonInterface = null;
}
if (MainConfig.realisticSeasonHook) seasonInterface = new RealisticSeasonsHook();
else seasonInterface = new InternalSeason();
//empty when enabling
for (CustomWorld customWorld : customWorlds.values()) {
customWorld.loadSeason();
}
return;
}
if (seasonInterface != null) {
seasonInterface.unload();
this.seasonInterface = null;
}
}
public void loadPacket() {
if (this.containerListener != null) {
CustomCrops.protocolManager.removePacketListener(containerListener);
this.containerListener = null;
}
if (this.playerModeListener != null) {
HandlerList.unregisterAll(playerModeListener);
this.playerModeListener = null;
}
if (this.playerContainerListener != null) {
CustomCrops.protocolManager.removePacketListener(playerContainerListener);
this.playerContainerListener = null;
}
if (!MainConfig.enableWaterCanLore || !MainConfig.enablePacketLore) return;
containerListener = new ContainerListener(this);
CustomCrops.protocolManager.addPacketListener(containerListener);
playerContainerListener = new PlayerContainerListener(handler);
CustomCrops.protocolManager.addPacketListener(playerContainerListener);
playerModeListener = new PlayerModeListener();
Bukkit.getPluginManager().registerEvents(playerModeListener, CustomCrops.plugin);
}
@Override
public void unload() {
super.unload();
HandlerList.unregisterAll(this.itemSpawnListener);
HandlerList.unregisterAll(this.worldListener);
if (this.handler != null) handler.unload();
if (this.timerTask != null) this.timerTask.cancel();
for (CustomWorld customWorld : customWorlds.values()) {
customWorld.unload(true);
}
customWorlds.clear();
if (this.seasonInterface != null) seasonInterface.unload();
if (this.containerListener != null) CustomCrops.protocolManager.removePacketListener(containerListener);
}
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.getWorldNameList().contains(world.getName())) {
CustomWorld customWorld = new CustomWorld(world, this);
customWorlds.put(world, customWorld);
if (MainConfig.autoGrow && MainConfig.enableCompensation) {
if (world.getTime() > 1200) {
Bukkit.getScheduler().runTaskLaterAsynchronously(CustomCrops.plugin, () -> grow(world, MainConfig.timeToGrow, 0, 0, true, false), 100);
}
}
}
}
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 cropTime, int sprinklerTime, int dryTime, boolean compensation, boolean force) {
CustomWorld customWorld = customWorlds.get(world);
if (customWorld == null) return;
if (MainConfig.cropMode) customWorld.growWire(cropTime, sprinklerTime, dryTime, compensation, force);
else customWorld.growFrame(cropTime, sprinklerTime, dryTime, compensation, force);
}
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.clone().add(0,i,0));
if (blockID != null && blockID.equals(BasicItemConfig.greenHouseGlass)) return true;
}
return false;
}
public boolean hasScarecrow(Location location) {
CustomWorld customWorld = customWorlds.get(location.getWorld());
if (customWorld == null) return true;
return customWorld.hasScarecrow(location);
}
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) return;
if (!customWorld.isPotWet(potLoc)) {
makePotDry(potLoc);
return;
}
Fertilizer fertilizer = customWorld.getFertilizer(potLoc);
if (!(fertilizer instanceof RetainingSoil retainingSoil && Math.random() < retainingSoil.getChance())) {
makePotDry(potLoc);
}
}
public void makePotDry(Location potLoc) {
String potID = customInterface.getBlockID(potLoc);
if (potID == null) return;
if (!potID.equals(BasicItemConfig.wetPot)) return;
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;
Bukkit.getScheduler().runTask(CustomCrops.plugin, () -> {
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, boolean isRightClick) {
//Call harvest event
CropHarvestEvent cropHarvestEvent = new CropHarvestEvent(player, crop, location, fertilizer);
Bukkit.getPluginManager().callEvent(cropHarvestEvent);
if (cropHarvestEvent.isCancelled()) return;
if (!isRightClick && player.getGameMode() == GameMode.CREATIVE) return;
ActionInterface[] actions = crop.getActions();
if (actions != null) performActions(actions, player);
if (SoundConfig.harvestCrop.isEnable()) {
AdventureUtil.playerSound(
player,
SoundConfig.harvestCrop.getSource(),
SoundConfig.harvestCrop.getKey(),
1,1
);
}
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();
}
}
if (MainConfig.enableSkillBonus) {
double bonus_chance = MainConfig.skillXP.getLevel(player) * MainConfig.bonusPerLevel;
amount *= (bonus_chance + 1);
}
dropQualityLoots(qualityLoot, amount, location.getBlock().getLocation(), qualityRatio);
}
OtherLoot[] otherLoots = crop.getOtherLoots();
if (otherLoots != null) dropOtherLoots(otherLoots, location.getBlock().getLocation(), player);
}
public void performActions(ActionInterface[] actions, Player player) {
for (ActionInterface action : actions) {
action.performOn(player);
}
}
public void dropOtherLoots(OtherLoot[] otherLoots, Location location, Player player) {
for (OtherLoot otherLoot : otherLoots) {
if (Math.random() < otherLoot.getChance()) {
int random = ThreadLocalRandom.current().nextInt(otherLoot.getMin(), otherLoot.getMax() + 1);
if (MainConfig.enableSkillBonus) {
double bonus_chance = MainConfig.skillXP.getLevel(player) * MainConfig.bonusPerLevel;
random *= (bonus_chance + 1);
}
ItemStack drop = getLoot(otherLoot.getItemID());
if (drop == null) continue;
drop.setAmount(random);
location.getWorld().dropItemNaturally(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 = getLoot(qualityLoot.getQuality_1());
if (drop == null) continue;
world.dropItemNaturally(location, drop);
}
else if(random > qualityRatio.getQuality_2()){
ItemStack drop = getLoot(qualityLoot.getQuality_2());
if (drop == null) continue;
world.dropItemNaturally(location, drop);
}
else {
ItemStack drop = getLoot(qualityLoot.getQuality_3());
if (drop == null) continue;
world.dropItemNaturally(location, drop);
}
}
}
@Nullable
private ItemStack getLoot(String id) {
if (id == null) return null;
if (MiscUtils.isVanillaItem(id)) return new ItemStack(Material.valueOf(id));
else return customInterface.getItemStack(id);
}
public boolean crowJudge(Location location, ItemFrame itemFrame) {
if (Math.random() < MainConfig.crowChance && !hasScarecrow(location)) {
for (Player player : location.getNearbyPlayers(48)) {
CrowTask crowTask = new CrowTask(player, location.clone().add(0.4,0,0.4), getArmorStandUtil());
crowTask.runTaskTimerAsynchronously(CustomCrops.plugin, 1, 1);
}
Bukkit.getScheduler().runTaskLater(CustomCrops.plugin, () -> {
customInterface.removeFurniture(itemFrame);
}, 125);
return true;
}
return false;
}
public boolean crowJudge(Location location) {
if (Math.random() < MainConfig.crowChance && !hasScarecrow(location)) {
Bukkit.getScheduler().runTask(CustomCrops.plugin, () -> {
CrowAttackEvent crowAttackEvent = new CrowAttackEvent(location);
Bukkit.getPluginManager().callEvent(crowAttackEvent);
for (Player player : location.getNearbyPlayers(48)) {
CrowTask crowTask = new CrowTask(player, location.clone().add(0.4,0,0.4), getArmorStandUtil());
crowTask.runTaskTimerAsynchronously(CustomCrops.plugin, 1, 1);
}
});
Bukkit.getScheduler().runTaskLater(CustomCrops.plugin, () -> {
customInterface.removeBlock(location);
}, 125);
return true;
}
return false;
}
public ArmorStandUtil getArmorStandUtil() {
return armorStandUtil;
}
public HandlerP getHandler() {
return handler;
}
}