Custom Games

There are two methods to register a custom game type: using an expansion jar or a plugin. Using the expansion jar method requires placing the built jar file into the "expansion" folder, similar to how it works with PlaceholderAPI. If you're using the plugin method to register a custom game type, after adding the custom game factory, you will need to call the CustomFishing's reload function to apply the changes.

Using a plugin

BukkitCustomFishingPlugin.getInstance().getGameManager().registerGameType("accurate_click_v2", ((id, section) -> {
    GameBasics basics = getGameBasics(section);
    return new AbstractGame(id, basics) {

        private final String barWidth = section.getString("title.total-width", "15~20");
        private final String barSuccess = section.getString("title.success-width","3~4");
        private final String barBody = section.getString("title.body","");
        private final String left = section.getString("title.left","");
        private final String right = section.getString("title.right","");
        private final String barPointer = section.getString("title.pointer", "");
        private final String barTarget = section.getString("title.target","");
        private final String subtitle = section.getString("subtitle", "<gray>Reel in at the most critical moment</gray>");

        @Override
        public BiFunction<CustomFishingHook, GameSetting, AbstractGamingPlayer> gamingPlayerProvider() {

            int minWidth = Integer.parseInt(barWidth.split("~")[0]);
            int maxWidth = Integer.parseInt(barWidth.split("~")[1]);
            int minSuccess = Integer.parseInt(barSuccess.split("~")[0]);
            int maxSuccess = Integer.parseInt(barSuccess.split("~")[1]);

            return (customFishingHook, gameSetting) -> new AbstractGamingPlayer(customFishingHook, gameSetting) {

                private final int totalWidth = RandomUtils.generateRandomInt(minWidth, maxWidth);
                private final int successWidth = RandomUtils.generateRandomInt(minSuccess, maxSuccess);
                private final int successPosition = ThreadLocalRandom.current().nextInt((totalWidth - successWidth + 1)) + 1;
                private int currentIndex = 0;
                private int timer = 0;
                private boolean face = true;

                @Override
                protected void tick() {
                    timer++;
                    if (timer % ((106 - (int) settings.difficulty()) / 5) == 0) {
                        movePointer();
                    }
                    showUI();
                }

                private void movePointer() {
                    if (face) {
                        currentIndex++;
                        if (currentIndex >= totalWidth - 1) {
                            face = false;
                        }
                    } else {
                        currentIndex--;
                        if (currentIndex <= 0) {
                            face = true;
                        }
                    }
                }

                private void showUI() {
                    StringBuilder stringBuilder = new StringBuilder();
                    for (int i = 1; i <= totalWidth; i++) {
                        if (i == currentIndex + 1) {
                            stringBuilder.append(barPointer);
                            continue;
                        }
                        if (i >= successPosition && i <= successPosition + successWidth - 1) {
                            stringBuilder.append(barTarget);
                            continue;
                        }
                        stringBuilder.append(barBody);
                    }

                    SparrowHeart.getInstance().sendTitle(getPlayer(), AdventureHelper.miniMessageToJson(left + stringBuilder + right), AdventureHelper.miniMessageToJson(subtitle), 0, 20, 0);
                }

                @Override
                public boolean isSuccessful() {
                    if (isTimeOut) return false;
                    return currentIndex + 1 <= successPosition + successWidth - 1 && currentIndex + 1 >= successPosition;
                }
            };
        }
    };
}));

Using an expansion jar

package net.momirealms.customfishing.api;

import dev.dejvokep.boostedyaml.block.implementation.Section;
import net.momirealms.customfishing.api.mechanic.fishing.CustomFishingHook;
import net.momirealms.customfishing.api.mechanic.game.*;
import net.momirealms.customfishing.api.mechanic.misc.value.MathValue;
import net.momirealms.customfishing.common.helper.AdventureHelper;
import net.momirealms.customfishing.common.util.RandomUtils;
import net.momirealms.sparrow.heart.SparrowHeart;

import java.util.concurrent.ThreadLocalRandom;
import java.util.function.BiFunction;

public class CustomGameFactory extends GameExpansion {
    @Override
    public String getVersion() {
        return "1.0";
    }

    @Override
    public String getAuthor() {
        return "XiaoMoMi";
    }

    @Override
    public String getGameType() {
        return "accurate_click_v2";
    }

    @Override
    public GameFactory getGameFactory() {
        return ((id, section) -> {
            GameBasics basics = getGameBasics(section);
            return new AbstractGame(id, basics) {

                private final String barWidth = section.getString("title.total-width", "15~20");
                private final String barSuccess = section.getString("title.success-width","3~4");
                private final String barBody = section.getString("title.body","");
                private final String left = section.getString("title.left","");
                private final String right = section.getString("title.right","");
                private final String barPointer = section.getString("title.pointer", "");
                private final String barTarget = section.getString("title.target","");
                private final String subtitle = section.getString("subtitle", "<gray>Reel in at the most critical moment</gray>");

                @Override
                public BiFunction<CustomFishingHook, GameSetting, AbstractGamingPlayer> gamingPlayerProvider() {

                    int minWidth = Integer.parseInt(barWidth.split("~")[0]);
                    int maxWidth = Integer.parseInt(barWidth.split("~")[1]);
                    int minSuccess = Integer.parseInt(barSuccess.split("~")[0]);
                    int maxSuccess = Integer.parseInt(barSuccess.split("~")[1]);

                    return (customFishingHook, gameSetting) -> new AbstractGamingPlayer(customFishingHook, gameSetting) {

                        private final int totalWidth = RandomUtils.generateRandomInt(minWidth, maxWidth);
                        private final int successWidth = RandomUtils.generateRandomInt(minSuccess, maxSuccess);
                        private final int successPosition = ThreadLocalRandom.current().nextInt((totalWidth - successWidth + 1)) + 1;
                        private int currentIndex = 0;
                        private int timer = 0;
                        private boolean face = true;

                        @Override
                        protected void tick() {
                            timer++;
                            if (timer % ((106 - (int) settings.difficulty()) / 5) == 0) {
                                movePointer();
                            }
                            showUI();
                        }

                        private void movePointer() {
                            if (face) {
                                currentIndex++;
                                if (currentIndex >= totalWidth - 1) {
                                    face = false;
                                }
                            } else {
                                currentIndex--;
                                if (currentIndex <= 0) {
                                    face = true;
                                }
                            }
                        }

                        private void showUI() {
                            StringBuilder stringBuilder = new StringBuilder();
                            for (int i = 1; i <= totalWidth; i++) {
                                if (i == currentIndex + 1) {
                                    stringBuilder.append(barPointer);
                                    continue;
                                }
                                if (i >= successPosition && i <= successPosition + successWidth - 1) {
                                    stringBuilder.append(barTarget);
                                    continue;
                                }
                                stringBuilder.append(barBody);
                            }

                            SparrowHeart.getInstance().sendTitle(getPlayer(), AdventureHelper.miniMessageToJson(left + stringBuilder + right), AdventureHelper.miniMessageToJson(subtitle), 0, 20, 0);
                        }

                        @Override
                        public boolean isSuccessful() {
                            if (isTimeOut) return false;
                            return currentIndex + 1 <= successPosition + successWidth - 1 && currentIndex + 1 >= successPosition;
                        }
                    };
                }
            };
        });
    }

    private GameBasics getGameBasics(Section section) {
        return GameBasics.builder()
                .difficulty(MathValue.auto(section.get("difficulty", "20~80"), false))
                .time(MathValue.auto(section.get("time", 15), false))
                .build();
    }
}

Last updated