小默米的插件
原版WIKI
CustomFishing
CustomFishing
  • 插件WIKI
    • 🎣 CustomFishing
      • 🧭 如何配置每个文件
      • ❓️ 常见问题
      • ⚖️ 权重系统 [必读]
      • 📄 格式
        • 🛒 市场
        • ✨ 效果
        • 🎉 事件
        • ✏️ 文本
        • 🎁 物品
        • 🦖 实体
        • 🧊 方块
        • 🏆 战利品
        • 🗿 图腾
        • 🕹️ 迷你游戏
          • 精准点击
          • 精准点击 v2
          • 精准点击 v3
          • 抓住
          • 抓住 v2
          • 拉紧
          • 点击
          • 舞蹈
        • 🏅 比赛
      • ✅ 条件
      • 💪 动作
      • 🅿️ 占位符和表达式
      • 🤝 兼容性
        • ItemsAdder
        • MythicMobs
        • Oraxen
        • EcoItems
        • MMOItems
        • NeigeItems
        • ExecutableItems
        • mcMMO 宝藏
        • 支持的等级系统
        • AdvancedEnchantments
        • EcoEnchants
        • BattlePass
        • BetonQuest 2.0
        • ClueScrolls
        • RealisticSeasons
        • Quests
        • TypeWriter
        • Zaphkiel
        • AuraSkills
      • 🐚 命令和权限
      • 📊 导入和导出数据
      • ⌨️ 应用程序编程接口
        • 事件
        • 基础操作
        • 集成提供器
        • 自定义鱼钩逻辑
        • 自定义游戏
由 GitBook 提供支持
在本页

这有帮助吗?

  1. 插件WIKI
  2. 🎣 CustomFishing
  3. ⌨️ 应用程序编程接口

自定义鱼钩逻辑

要覆盖插件原生的系统,只需按照以下步骤操作:只要实现(HookMechanic)接口并添加到可用机制列表中,自定义逻辑即可生效(注意:添加顺序会影响机制判断的优先级)

CustomFishingHook.mechanicProviders((h, c, e) -> {
    ArrayList<HookMechanic> mechanics = new ArrayList<>();
    mechanics.add(new VanillaMechanic(h, c));
    mechanics.add(new LavaFishingMechanic(h, e, c));
    return mechanics;
});
package net.momirealms.customfishing.api.mechanic.fishing.hook;

import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import net.momirealms.customfishing.api.event.FishingHookStateEvent;
import net.momirealms.customfishing.api.mechanic.config.ConfigManager;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.context.ContextKeys;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.effect.EffectProperties;
import net.momirealms.customfishing.api.util.EventUtils;
import net.momirealms.customfishing.common.plugin.scheduler.SchedulerTask;
import net.momirealms.customfishing.common.util.RandomUtils;
import net.momirealms.sparrow.heart.SparrowHeart;
import net.momirealms.sparrow.heart.feature.fluid.FluidData;
import org.bukkit.*;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.FishHook;
import org.bukkit.entity.Player;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.util.Vector;

import java.util.Objects;
import java.util.concurrent.ThreadLocalRandom;

public class LavaFishingMechanic implements HookMechanic {

    private final FishHook hook;
    private final Effect gearsEffect;
    private final Context<Player> context;
    private ArmorStand tempEntity;
    private SchedulerTask task;
    private int timeUntilLured;
    private int timeUntilHooked;
    private int nibble;
    private boolean hooked;
    private float fishAngle;
    private int currentState;
    private int jumpTimer;
    private boolean firstTime = true;
    private boolean freeze = false;

    public LavaFishingMechanic(FishHook hook, Effect gearsEffect, Context<Player> context) {
        this.hook = hook;
        this.gearsEffect = gearsEffect;
        this.context = context;
    }

    @Override
    public boolean canStart() {
        if (!(boolean) gearsEffect.properties().getOrDefault(EffectProperties.LAVA_FISHING, false)) {
            return false;
        }
        if (hook.isInLava()) {
            return true;
        }
        float lavaHeight = 0F;
        Location location = this.hook.getLocation();
        FluidData fluidData = SparrowHeart.getInstance().getFluidData(location);
        if (fluidData.getFluidType() == Fluid.LAVA || fluidData.getFluidType() == Fluid.FLOWING_LAVA) {
            lavaHeight = (float) (fluidData.getLevel() * 0.125);
        }
        return lavaHeight > 0 && location.getY() % 1 <= lavaHeight;
    }

    @Override
    public boolean shouldStop() {
        if (hook.isInLava()) {
            return false;
        }
        return hook.isOnGround() || (hook.getLocation().getBlock().getType() != Material.LAVA && hook.getLocation().getBlock().getRelative(BlockFace.DOWN).getType() != Material.LAVA);
    }

    @Override
    public void preStart() {
        this.context.arg(ContextKeys.SURROUNDING, EffectProperties.LAVA_FISHING.key());
    }

    @Override
    public void start(Effect finalEffect) {
        EventUtils.fireAndForget(new FishingHookStateEvent(context.holder(), hook, FishingHookStateEvent.State.LAND));
        this.setWaitTime(finalEffect);
        this.task = BukkitCustomFishingPlugin.getInstance().getScheduler().sync().runRepeating(() -> {
            Location location = this.hook.getLocation();
            float lavaHeight = 0F;
            FluidData fluidData = SparrowHeart.getInstance().getFluidData(location);
            if (fluidData.getFluidType() == Fluid.LAVA || fluidData.getFluidType() == Fluid.FLOWING_LAVA) {
                lavaHeight = (float) (fluidData.getLevel() * 0.125);
            }
            if (this.nibble > 0) {
                --this.nibble;
                if (location.getY() % 1 <= lavaHeight) {
                    this.jumpTimer++;
                    if (this.jumpTimer >= 4) {
                        this.jumpTimer = 0;
                        this.hook.setVelocity(new Vector(0,0.24,0));
                    }
                }
                if (this.nibble <= 0) {
                    this.timeUntilLured = 0;
                    this.timeUntilHooked = 0;
                    this.hooked = false;
                    this.jumpTimer = 0;
                    this.currentState = 0;
                }
            } else {
                double hookY = location.getY();
                if (hookY < 0) {
                    hookY += Math.abs(Math.floor(hookY));
                }
                if (hookY % 1 <= lavaHeight || this.hook.isInLava()) {
                    Vector previousVector = this.hook.getVelocity();
                    this.hook.setVelocity(new Vector(previousVector.getX() * 0.6, Math.min(0.1, Math.max(-0.1, previousVector.getY() + 0.07)), previousVector.getZ() * 0.6));
                    this.currentState = 1;
                } else {
                    if (currentState == 1) {
                        this.currentState = 0;
                        // set temp entity
                        this.tempEntity = this.hook.getWorld().spawn(location.clone().subtract(0,1,0), ArmorStand.class);
                        this.setTempEntityProperties(this.tempEntity);
                        this.hook.setHookedEntity(this.tempEntity);
                        if (!firstTime) {
                            EventUtils.fireAndForget(new FishingHookStateEvent(context.holder(), hook, FishingHookStateEvent.State.ESCAPE));
                        }
                        firstTime = false;
                    }
                }
                float f;
                float f1;
                float f2;
                double d0;
                double d1;
                double d2;
                if (this.timeUntilHooked > 0) {
                    this.timeUntilHooked -= 1;
                    if (this.timeUntilHooked > 0) {
                        this.fishAngle += (float) RandomUtils.triangle(0.0D, 9.188D);
                        f = this.fishAngle * 0.017453292F;
                        f1 = (float) Math.sin(f);
                        f2 = (float) Math.cos(f);
                        d0 = location.getX() + (double) (f1 * (float) this.timeUntilHooked * 0.1F);
                        d1 = location.getY();
                        d2 = location.getZ() + (double) (f2 * (float) this.timeUntilHooked * 0.1F);
                        if (RandomUtils.generateRandomFloat(0,1) < 0.15F) {
                            hook.getWorld().spawnParticle(Particle.FLAME, d0, d1 - 0.10000000149011612D, d2, 1, f1, 0.1D, f2, 0.0D);
                        }
                        float f3 = f1 * 0.04F;
                        float f4 = f2 * 0.04F;
                        hook.getWorld().spawnParticle(Particle.FLAME, d0, d1, d2, 0, f4, 0.01D, -f3, 1.0D);
                    } else {
                        double d3 = location.getY() + 0.5D;
                        hook.getWorld().spawnParticle(Particle.FLAME, location.getX(), d3, location.getZ(), (int) (1.0F + 0.3 * 20.0F), 0.3, 0.0D, 0.3, 0.20000000298023224D);
                        this.nibble = RandomUtils.generateRandomInt(20, 40);
                        this.hooked = true;
                        hook.getWorld().playSound(location, Sound.ENTITY_GENERIC_EXTINGUISH_FIRE, 0.25F, 1.0F + (RandomUtils.generateRandomFloat(0,1)-RandomUtils.generateRandomFloat(0,1)) * 0.4F);
                        EventUtils.fireAndForget(new FishingHookStateEvent(context.holder(), hook, FishingHookStateEvent.State.BITE));
                        if (this.tempEntity != null && this.tempEntity.isValid()) {
                            this.tempEntity.remove();
                        }
                    }
                } else if (timeUntilLured > 0) {
                    if (!freeze) {
                        timeUntilLured--;
                    }
                    if (this.timeUntilLured <= 0) {
                        this.fishAngle = RandomUtils.generateRandomFloat(0F, 360F);
                        this.timeUntilHooked = RandomUtils.generateRandomInt(20, 80);
                        EventUtils.fireAndForget(new FishingHookStateEvent(context.holder(), hook, FishingHookStateEvent.State.LURE));
                    }
                } else {
                    setWaitTime(finalEffect);
                }
            }
        }, 1, 1, hook.getLocation());
    }

    @Override
    public boolean isHooked() {
        return hooked;
    }

    @Override
    public void destroy() {
        if (this.tempEntity != null && this.tempEntity.isValid()) {
            this.tempEntity.remove();
        }
        if (this.task != null) {
            this.task.cancel();
        }
        freeze = false;
    }

    @Override
    public void freeze() {
        freeze = true;
    }

    @Override
    public void unfreeze(Effect effect) {
        freeze = false;
    }

    private void setWaitTime(Effect effect) {
        int before = ThreadLocalRandom.current().nextInt(ConfigManager.lavaMaxTime() - ConfigManager.lavaMinTime() + 1) + ConfigManager.lavaMinTime();
        int after = Math.max(ConfigManager.lavaMinTime(), (int) (before * effect.waitTimeMultiplier() + effect.waitTimeAdder()));
        BukkitCustomFishingPlugin.getInstance().debug("Wait time: " + before + " -> " + after + " ticks");
        this.timeUntilLured = after;
    }

    private void setTempEntityProperties(ArmorStand entity) {
        entity.setInvisible(true);
        entity.setCollidable(false);
        entity.setInvulnerable(true);
        entity.setVisible(false);
        entity.setCustomNameVisible(false);
        entity.setSmall(true);
        entity.setGravity(false);
        entity.getPersistentDataContainer().set(
                Objects.requireNonNull(NamespacedKey.fromString("temp-entity", BukkitCustomFishingPlugin.getInstance().getBootstrap())),
                PersistentDataType.STRING,
                "lava"
        );
    }
}
上一页集成提供器下一页自定义游戏

最后更新于2个月前

这有帮助吗?