9
0
mirror of https://github.com/Xiao-MoMi/Custom-Fishing.git synced 2025-12-26 10:29:16 +00:00
This commit is contained in:
XiaoMoMi
2023-09-18 02:05:04 +08:00
parent 165ee5565f
commit e19b9f8a16
16 changed files with 334 additions and 12 deletions

View File

@@ -44,12 +44,14 @@ dependencies {
compileOnly("com.github.Zrips:Jobs:4.17.2")
compileOnly("com.github.Archy-X:AureliumSkills:Beta1.3.21")
compileOnly("com.github.MilkBowl:VaultAPI:1.7")
compileOnly("org.betonquest:betonquest:2.0.0-SNAPSHOT")
// local jars
compileOnly(files("libs/AdvancedEnchantments-api.jar"))
compileOnly(files("libs/RealisticSeasons-api.jar"))
compileOnly(files("libs/CustomCrops-api.jar"))
compileOnly(files("libs/mcMMO-api.jar"))
compileOnly(files("libs/ClueScrolls-4.8.7-api.jar"))
// api module
implementation(project(":api"))

Binary file not shown.

View File

@@ -51,6 +51,7 @@ import net.momirealms.customfishing.storage.StorageManagerImpl;
import net.momirealms.customfishing.version.VersionManagerImpl;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
import java.io.File;
@@ -130,6 +131,7 @@ public class CustomFishingPluginImpl extends CustomFishingPlugin {
((TotemManagerImpl) this.totemManager).disable();
this.coolDownManager.disable();
this.commandManager.unload();
HandlerList.unregisterAll(this);
}
@Override

View File

@@ -30,14 +30,18 @@ import net.momirealms.customfishing.compatibility.entity.ItemsAdderEntityImpl;
import net.momirealms.customfishing.compatibility.entity.MythicEntityImpl;
import net.momirealms.customfishing.compatibility.item.*;
import net.momirealms.customfishing.compatibility.level.*;
import net.momirealms.customfishing.compatibility.quest.BetonQuestHook;
import net.momirealms.customfishing.compatibility.quest.ClueScrollsHook;
import net.momirealms.customfishing.compatibility.season.CustomCropsSeasonImpl;
import net.momirealms.customfishing.compatibility.season.RealisticSeasonsImpl;
import org.bukkit.Bukkit;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
public class IntegrationManagerImpl implements IntegrationManager {
@@ -50,7 +54,7 @@ public class IntegrationManagerImpl implements IntegrationManager {
this.plugin = plugin;
this.levelPluginMap = new HashMap<>();
this.enchantments = new HashMap<>();
this.init();
this.load();
}
public void disable() {
@@ -58,7 +62,7 @@ public class IntegrationManagerImpl implements IntegrationManager {
this.levelPluginMap.clear();
}
public void init() {
public void load() {
if (plugin.isHookedPluginEnabled("ItemsAdder")) {
plugin.getItemManager().registerItemLibrary(new ItemsAdderItemImpl());
plugin.getBlockManager().registerBlockLibrary(new ItemsAdderBlockImpl());
@@ -129,6 +133,16 @@ public class IntegrationManagerImpl implements IntegrationManager {
if (plugin.isHookedPluginEnabled("Vault")) {
VaultHook.initialize();
}
if (plugin.isHookedPluginEnabled("ClueScrolls")) {
ClueScrollsHook clueScrollsHook = new ClueScrollsHook();
Bukkit.getPluginManager().registerEvents(clueScrollsHook, plugin);
hookMessage("ClueScrolls");
}
if (plugin.isHookedPluginEnabled("BetonQuest")) {
if (Objects.requireNonNull(Bukkit.getPluginManager().getPlugin("BetonQuest")).getPluginMeta().getVersion().startsWith("2")) {
BetonQuestHook.register();
}
}
}
@Override

View File

@@ -0,0 +1,191 @@
/*
* 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.customfishing.compatibility.quest;
import net.momirealms.customfishing.api.event.FishingResultEvent;
import net.momirealms.customfishing.api.util.LogUtils;
import org.betonquest.betonquest.BetonQuest;
import org.betonquest.betonquest.Instruction;
import org.betonquest.betonquest.VariableNumber;
import org.betonquest.betonquest.api.CountingObjective;
import org.betonquest.betonquest.api.config.quest.QuestPackage;
import org.betonquest.betonquest.api.profiles.OnlineProfile;
import org.betonquest.betonquest.api.profiles.Profile;
import org.betonquest.betonquest.exceptions.InstructionParseException;
import org.betonquest.betonquest.utils.PlayerConverter;
import org.betonquest.betonquest.utils.location.CompoundLocation;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import java.util.Collections;
import java.util.HashSet;
@SuppressWarnings("DuplicatedCode")
public class BetonQuestHook {
public static void register() {
BetonQuest.getInstance().registerObjectives("customfishing_id", IDObjective.class);
BetonQuest.getInstance().registerObjectives("customfishing_group", GroupObjective.class);
}
public static class IDObjective extends CountingObjective implements Listener {
private final CompoundLocation playerLocation;
private final VariableNumber rangeVar;
private final HashSet<String> loot_ids;
public IDObjective(Instruction instruction) throws InstructionParseException {
super(instruction, "loot_to_fish");
loot_ids = new HashSet<>();
Collections.addAll(loot_ids, instruction.getArray());
targetAmount = instruction.getVarNum();
preCheckAmountNotLessThanOne(targetAmount);
final QuestPackage pack = instruction.getPackage();
final String loc = instruction.getOptional("playerLocation");
final String range = instruction.getOptional("range");
if (loc != null && range != null) {
playerLocation = new CompoundLocation(pack, loc);
rangeVar = new VariableNumber(pack, range);
} else {
playerLocation = null;
rangeVar = null;
}
}
@EventHandler
public void onFish(FishingResultEvent event) {
if (event.getResult() != FishingResultEvent.Result.FAILURE) {
OnlineProfile onlineProfile = PlayerConverter.getID(event.getPlayer());
if (!containsPlayer(onlineProfile)) {
return;
}
if (isInvalidLocation(event, onlineProfile)) {
return;
}
if (this.loot_ids.contains(event.getLoot().getID()) && this.checkConditions(onlineProfile)) {
getCountingData(onlineProfile).progress(event.getAmount());
completeIfDoneOrNotify(onlineProfile);
}
}
}
private boolean isInvalidLocation(FishingResultEvent event, final Profile profile) {
if (playerLocation == null || rangeVar == null) {
return false;
}
final Location targetLocation;
try {
targetLocation = playerLocation.getLocation(profile);
} catch (final org.betonquest.betonquest.exceptions.QuestRuntimeException e) {
LogUtils.warn(e.getMessage());
return true;
}
final int range = rangeVar.getInt(profile);
final Location playerLoc = event.getPlayer().getLocation();
return !playerLoc.getWorld().equals(targetLocation.getWorld()) || targetLocation.distanceSquared(playerLoc) > range * range;
}
@Override
public void start() {
Bukkit.getPluginManager().registerEvents(this, BetonQuest.getInstance());
}
@Override
public void stop() {
HandlerList.unregisterAll(this);
}
}
public static class GroupObjective extends CountingObjective implements Listener {
private final CompoundLocation playerLocation;
private final VariableNumber rangeVar;
private final HashSet<String> loot_groups;
public GroupObjective(Instruction instruction) throws InstructionParseException {
super(instruction, "group_to_fish");
loot_groups = new HashSet<>();
Collections.addAll(loot_groups, instruction.getArray());
targetAmount = instruction.getVarNum();
preCheckAmountNotLessThanOne(targetAmount);
final QuestPackage pack = instruction.getPackage();
final String loc = instruction.getOptional("playerLocation");
final String range = instruction.getOptional("range");
if (loc != null && range != null) {
playerLocation = new CompoundLocation(pack, loc);
rangeVar = new VariableNumber(pack, range);
} else {
playerLocation = null;
rangeVar = null;
}
}
@EventHandler
public void onFish(FishingResultEvent event) {
if (event.getResult() != FishingResultEvent.Result.FAILURE) {
OnlineProfile onlineProfile = PlayerConverter.getID(event.getPlayer());
if (!containsPlayer(onlineProfile)) {
return;
}
if (isInvalidLocation(event, onlineProfile)) {
return;
}
String[] groups = event.getLoot().getLootGroup();
if (groups != null)
for (String group : groups) {
if (this.loot_groups.contains(group) && this.checkConditions(onlineProfile)) {
getCountingData(onlineProfile).progress(event.getAmount());
completeIfDoneOrNotify(onlineProfile);
return;
}
}
}
}
private boolean isInvalidLocation(FishingResultEvent event, final Profile profile) {
if (playerLocation == null || rangeVar == null) {
return false;
}
final Location targetLocation;
try {
targetLocation = playerLocation.getLocation(profile);
} catch (final org.betonquest.betonquest.exceptions.QuestRuntimeException e) {
LogUtils.warn(e.getMessage());
return true;
}
final int range = rangeVar.getInt(profile);
final Location playerLoc = event.getPlayer().getLocation();
return !playerLoc.getWorld().equals(targetLocation.getWorld()) || targetLocation.distanceSquared(playerLoc) > range * range;
}
@Override
public void start() {
Bukkit.getPluginManager().registerEvents(this, BetonQuest.getInstance());
}
@Override
public void stop() {
HandlerList.unregisterAll(this);
}
}
}

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.customfishing.compatibility.quest;
import com.electro2560.dev.cluescrolls.api.*;
import net.momirealms.customfishing.api.CustomFishingPlugin;
import net.momirealms.customfishing.api.event.FishingResultEvent;
import net.momirealms.customfishing.api.mechanic.loot.Loot;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public class ClueScrollsHook implements Listener {
private final CustomClue idClue;
private final CustomClue groupClue;
public ClueScrollsHook() {
idClue = ClueScrollsAPI.getInstance().registerCustomClue(CustomFishingPlugin.getInstance(), "loot", new ClueConfigData("id", DataType.STRING));
groupClue = ClueScrollsAPI.getInstance().registerCustomClue(CustomFishingPlugin.getInstance(), "group", new ClueConfigData("group", DataType.STRING));
}
@EventHandler
public void onFish(FishingResultEvent event) {
if (event.isCancelled() || event.getResult() == FishingResultEvent.Result.FAILURE)
return;
final Player player = event.getPlayer();
idClue.handle(
player,
event.getAmount(),
new ClueDataPair("loot_id", "any")
);
Loot loot = event.getLoot();
if (loot != null)
idClue.handle(
player,
event.getAmount(),
new ClueDataPair("loot_id", loot.getID())
);
if (loot != null && loot.getLootGroup() != null)
for (String group : event.getLoot().getLootGroup()) {
groupClue.handle(
player,
event.getAmount(),
new ClueDataPair("loot_group", group)
);
}
}
}

View File

@@ -42,6 +42,7 @@ import net.momirealms.customfishing.api.mechanic.game.GameInstance;
import net.momirealms.customfishing.api.mechanic.game.GameSettings;
import net.momirealms.customfishing.api.mechanic.game.GamingPlayer;
import net.momirealms.customfishing.api.mechanic.loot.Loot;
import net.momirealms.customfishing.api.mechanic.loot.LootType;
import net.momirealms.customfishing.api.mechanic.loot.WeightModifier;
import net.momirealms.customfishing.api.util.LogUtils;
import net.momirealms.customfishing.api.util.WeightUtils;
@@ -525,6 +526,14 @@ public class FishingManagerImpl implements Listener, FishingManager {
var fishingPreparation = state.getPreparation();
var player = fishingPreparation.getPlayer();
fishingPreparation.insertArg("{size-multiplier}", String.format("%.2f", effect.getSizeMultiplier()));
int amount;
if (loot.getType() == LootType.ITEM) {
amount = (int) effect.getMultipleLootChance();
amount += Math.random() < (effect.getMultipleLootChance() - amount) ? 2 : 1;
} else {
amount = 1;
}
fishingPreparation.insertArg("{amount}", String.valueOf(amount));
// call event
FishingResultEvent fishingResultEvent = new FishingResultEvent(
@@ -540,8 +549,7 @@ public class FishingManagerImpl implements Listener, FishingManager {
switch (loot.getType()) {
case ITEM -> {
int amount = (int) effect.getMultipleLootChance();
amount += Math.random() < (effect.getMultipleLootChance() - amount) ? 2 : 1;
// build the items for multiple times instead of using setAmount() to make sure that each item is unique
if (loot.getID().equals("vanilla")) {
ItemStack itemStack = vanillaLootMap.remove(player.getUniqueId());
@@ -560,8 +568,12 @@ public class FishingManagerImpl implements Listener, FishingManager {
}
return;
}
case ENTITY -> plugin.getEntityManager().summonEntity(hook.getLocation(), player.getLocation(), loot);
case BLOCK -> plugin.getBlockManager().summonBlock(player, hook.getLocation(), player.getLocation(), loot);
case ENTITY -> {
plugin.getEntityManager().summonEntity(hook.getLocation(), player.getLocation(), loot);
}
case BLOCK -> {
plugin.getBlockManager().summonBlock(player, hook.getLocation(), player.getLocation(), loot);
}
}
doSuccessActions(loot, effect, fishingPreparation, player);
}

View File

@@ -26,9 +26,9 @@ import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.effect.EffectCarrier;
import net.momirealms.customfishing.api.scheduler.CancellableTask;
import net.momirealms.customfishing.mechanic.totem.block.TotemBlock;
import net.momirealms.customfishing.mechanic.totem.block.property.AxisImpl;
import net.momirealms.customfishing.mechanic.totem.block.property.FaceImpl;
import net.momirealms.customfishing.mechanic.totem.block.TotemBlock;
import net.momirealms.customfishing.mechanic.totem.block.property.HalfImpl;
import net.momirealms.customfishing.mechanic.totem.block.property.TotemBlockProperty;
import net.momirealms.customfishing.mechanic.totem.block.type.TypeCondition;

View File

@@ -23,7 +23,6 @@ import org.bukkit.Axis;
import org.bukkit.Location;
import java.io.Serializable;
import java.util.Arrays;
import java.util.StringJoiner;
public class TotemModel implements Serializable {

View File

@@ -0,0 +1,31 @@
# Don't change this
config-version: '26'
messages:
prefix: '<gradient:#0070B3:#A0EACF>[CustomFishing] </gradient>'
reload: '<white>重载完成. 耗时 <green>{time}ms.'
item-not-exist: '物品不存在.'
give-item: '给予玩家 {player} {amount}x {item}.'
get-item: '获得 {amount}x {item}.'
possible-loots: '可能的战利品: '
split-char: ', '
competition-not-exist: '比赛 {id} 不存在.'
no-competition-ongoing: "没有正在进行的比赛."
stop-competition: '停止了当前的比赛.'
end-competition: '结束了当前的比赛.'
no-score: '无比分'
no-player: '无选手'
no-rank: '无排名'
goal-catch-amount: '捕鱼总数'
goal-max-size: '最大尺寸'
goal-total-size: '捕鱼总尺寸'
goal-total-score: '捕鱼总分'
unsafe-modification: "你不能修改一个正在其他子服游玩的玩家钓鱼背包."
never-played: "此玩家从未玩过服务器."
data-not-loaded: "<red>数据未能正常加载. 请尝试切换子服或重进. 如果问题依然存在请联系服务器管理员."
open-market-gui: "为玩家 {player} 打开了市场"
open-fishing-bag: "为玩家 {player} 打开了钓鱼背包"
format-day: '天'
format-hour: '小时'
format-minute: '分'
format-second: '秒'

View File

@@ -5,7 +5,6 @@ messages:
prefix: '<gradient:#0070B3:#A0EACF>[CustomFishing] </gradient>'
reload: '<white>Reloaded. Took <green>{time}ms.'
item-not-exist: 'Item not found.'
escape: 'The fish slipped off the hook and escaped.'
give-item: 'Successfully given player {player} {amount}x {item}.'
get-item: 'Successfully got {amount}x {item}.'
possible-loots: 'Possible loots here: '

View File

@@ -5,7 +5,6 @@ messages:
prefix: '<gradient:#0070B3:#A0EACF>[CustomFishing] </gradient>'
reload: '<white>Újratöltve. Időtartam: <green>{time}ms.'
item-not-exist: 'Tétel nem található.'
escape: 'A hal lecsúszott a horogról és elmenekült.'
give-item: 'Sikeresen adva {player} játékosnak {amount}x {item}.'
get-item: 'Sikeresen megszerezve {amount}x {item}.'
possible-loots: 'Lehetséges kapások itt: '

View File

@@ -27,6 +27,7 @@ softdepend:
- BattlePass
- ClueScrolls
- BetonQuest
- Quests
- AdvancedEnchantments
- EcoEnchants