├── .gitattributes ├── .gitignore ├── CREDITS.txt ├── LICENSE ├── LICENSE.txt ├── Readme.md ├── build.gradle ├── changelog.txt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src └── main ├── java └── dev │ └── zanckor │ ├── api │ ├── database │ │ └── LocateHash.java │ ├── enuminterface │ │ ├── enumdialog │ │ │ ├── IEnumDialogOption.java │ │ │ └── IEnumDialogReq.java │ │ └── enumquest │ │ │ ├── IEnumQuestGoal.java │ │ │ ├── IEnumQuestRequirement.java │ │ │ ├── IEnumQuestReward.java │ │ │ └── IEnumTargetType.java │ ├── filemanager │ │ ├── FileAbstract.java │ │ ├── FolderManager.java │ │ ├── dialog │ │ │ ├── abstractdialog │ │ │ │ ├── AbstractDialogOption.java │ │ │ │ └── AbstractDialogRequirement.java │ │ │ ├── codec │ │ │ │ ├── NPCConversation.java │ │ │ │ ├── NPCDialog.java │ │ │ │ └── ReadDialog.java │ │ │ └── register │ │ │ │ └── LoadDialog.java │ │ ├── npc │ │ │ ├── entity_type │ │ │ │ ├── codec │ │ │ │ │ └── EntityTypeDialog.java │ │ │ │ └── register │ │ │ │ │ └── LoadDialogList.java │ │ │ └── entity_type_tag │ │ │ │ ├── codec │ │ │ │ └── EntityTypeTagDialog.java │ │ │ │ ├── gateenum │ │ │ │ └── LogicGate.java │ │ │ │ └── register │ │ │ │ └── LoadTagDialogList.java │ │ └── quest │ │ │ ├── abstracquest │ │ │ ├── AbstractGoal.java │ │ │ ├── AbstractQuestRequirement.java │ │ │ ├── AbstractReward.java │ │ │ └── AbstractTargetType.java │ │ │ ├── codec │ │ │ ├── server │ │ │ │ ├── ServerGoal.java │ │ │ │ ├── ServerQuest.java │ │ │ │ ├── ServerRequirement.java │ │ │ │ └── ServerReward.java │ │ │ └── user │ │ │ │ ├── UserGoal.java │ │ │ │ └── UserQuest.java │ │ │ └── register │ │ │ ├── LoadQuest.java │ │ │ └── QuestTemplateRegistry.java │ └── screen │ │ └── ScreenRegistry.java │ ├── example │ ├── ClientModSetup.java │ ├── ModExample.java │ ├── client │ │ └── screen │ │ │ ├── button │ │ │ └── TextButton.java │ │ │ ├── dialog │ │ │ ├── DialogScreen.java │ │ │ └── MinimalistDialogScreen.java │ │ │ ├── hud │ │ │ ├── QuestTrackedTimer.java │ │ │ └── RenderQuestTracker.java │ │ │ └── questlog │ │ │ └── QuestLog.java │ ├── common │ │ ├── entity │ │ │ ├── NpcTypes.java │ │ │ ├── client │ │ │ │ └── NPCRenderer.java │ │ │ └── server │ │ │ │ └── NPCEntity.java │ │ ├── enumregistry │ │ │ ├── EnumRegistry.java │ │ │ ├── enumdialog │ │ │ │ ├── EnumDialogOption.java │ │ │ │ ├── EnumDialogReq.java │ │ │ │ └── EnumDialogReqStatus.java │ │ │ └── enumquest │ │ │ │ ├── EnumGoalType.java │ │ │ │ ├── EnumQuestRequirement.java │ │ │ │ └── EnumQuestReward.java │ │ └── handler │ │ │ ├── dialogoption │ │ │ ├── DialogAddQuest.java │ │ │ ├── DialogCloseDialog.java │ │ │ └── DialogOpenDialog.java │ │ │ ├── dialogrequirement │ │ │ ├── DialogRequirement.java │ │ │ └── QuestRequirement.java │ │ │ ├── questgoal │ │ │ ├── CollectGoal.java │ │ │ ├── CollectNBTGoal.java │ │ │ ├── InteractEntityGoal.java │ │ │ ├── KillGoal.java │ │ │ ├── MoveToGoal.java │ │ │ └── XpGoal.java │ │ │ ├── questrequirement │ │ │ └── XpRequirement.java │ │ │ ├── questreward │ │ │ ├── CommandReward.java │ │ │ ├── ItemReward.java │ │ │ ├── LootTableReward.java │ │ │ ├── QuestReward.java │ │ │ └── XpReward.java │ │ │ └── targettype │ │ │ ├── DefaultTargetType.java │ │ │ ├── EntityTargetType.java │ │ │ ├── EntityUUIDTargetType.java │ │ │ ├── ItemTargetType.java │ │ │ ├── MoveToTargetType.java │ │ │ └── XPTargetType.java │ └── server │ │ └── event │ │ ├── AssignEntityStats.java │ │ └── questevent │ │ ├── CollectEvent.java │ │ ├── InteractWEntityEvent.java │ │ ├── KillEvent.java │ │ ├── MoveToEvent.java │ │ └── XPEvent.java │ └── mod │ ├── EventHandlerRegister.java │ ├── QuestApiMain.java │ ├── client │ ├── event │ │ └── ClientEvent.java │ └── screen │ │ ├── abstractscreen │ │ ├── AbstractDialog.java │ │ ├── AbstractQuestLog.java │ │ └── AbstractQuestTracked.java │ │ └── questmaker │ │ ├── QuestDefaultScreen.java │ │ ├── QuestGoalSelectorScreen.java │ │ └── QuestMakerManager.java │ ├── common │ ├── config │ │ ├── client │ │ │ ├── RendererConfig.java │ │ │ └── ScreenConfig.java │ │ └── server │ │ │ └── GoalConfig.java │ ├── datapack │ │ ├── CompoundTagDialogJSONListener.java │ │ ├── DialogJSONListener.java │ │ ├── EntityTypeDialogJSONListener.java │ │ └── QuestJSONListener.java │ ├── menu │ │ └── MenuHandler.java │ ├── network │ │ ├── NetworkHandler.java │ │ ├── SendQuestPacket.java │ │ ├── handler │ │ │ ├── ClientHandler.java │ │ │ └── ServerHandler.java │ │ └── message │ │ │ ├── dialogoption │ │ │ ├── AddQuest.java │ │ │ ├── CloseDialog.java │ │ │ ├── DialogRequestPacket.java │ │ │ └── DisplayDialog.java │ │ │ ├── npcmarker │ │ │ └── ValidNPCMarker.java │ │ │ ├── quest │ │ │ ├── ActiveQuestList.java │ │ │ ├── QuestDataPacket.java │ │ │ ├── ServerQuestList.java │ │ │ ├── TimerPacket.java │ │ │ └── ToastPacket.java │ │ │ └── screen │ │ │ ├── ModifyTrackedQuests.java │ │ │ ├── OpenVanillaEntityScreen.java │ │ │ ├── RemovedQuest.java │ │ │ ├── RequestActiveQuests.java │ │ │ └── UpdateQuestTracked.java │ └── util │ │ ├── GsonManager.java │ │ ├── MCUtil.java │ │ ├── MCUtilClient.java │ │ ├── Mathematic.java │ │ └── Timer.java │ └── server │ ├── command │ └── QuestCommand.java │ ├── event │ ├── ServerEvent.java │ └── StartDialog.java │ ├── menu │ └── questmaker │ │ └── QuestMakerMenu.java │ └── startdialog │ └── StartDialog.java └── resources ├── META-INF └── mods.toml ├── assets └── questapi │ ├── lang │ ├── en_us.json │ └── es_ES.json │ └── textures │ └── gui │ ├── dialog_background.png │ ├── minimalist_dialog_background.png │ ├── quest_maker_bg.png │ └── questlog_api.png ├── data └── questapi │ ├── dialog │ ├── collect_items_dialog.json │ └── secondary_collect_items_dialog.json │ └── quest │ ├── collect_items.json │ ├── collect_items_tag.json │ ├── interact_entity.json │ ├── kill_entities.json │ ├── move_to_coords.json │ └── multiple_quests.json ├── pack.mcmeta └── questapi.png /.gitattributes: -------------------------------------------------------------------------------- 1 | # Disable autocrlf on generated files, they always generate with LF 2 | # Add any extra files or paths here to make git stop saying they 3 | # are changed when only line endings change. 4 | src/generated/**/.cache/cache text eol=lf 5 | src/generated/**/*.json text eol=lf 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # eclipse 2 | bin 3 | *.launch 4 | .settings 5 | .metadata 6 | .classpath 7 | .project 8 | 9 | # idea 10 | out 11 | *.ipr 12 | *.iws 13 | *.iml 14 | .idea 15 | 16 | # gradle 17 | build 18 | .gradle 19 | 20 | # other 21 | eclipse 22 | run 23 | 24 | # Files from Forge MDK 25 | forge*changelog.txt 26 | -------------------------------------------------------------------------------- /CREDITS.txt: -------------------------------------------------------------------------------- 1 | Minecraft Forge: Credits/Thank You 2 | 3 | Forge is a set of tools and modifications to the Minecraft base game code to assist 4 | mod developers in creating new and exciting content. It has been in development for 5 | several years now, but I would like to take this time thank a few people who have 6 | helped it along it's way. 7 | 8 | First, the people who originally created the Forge projects way back in Minecraft 9 | alpha. Eloraam of RedPower, and SpaceToad of Buildcraft, without their acceptiance 10 | of me taking over the project, who knows what Minecraft modding would be today. 11 | 12 | Secondly, someone who has worked with me, and developed some of the core features 13 | that allow modding to be as functional, and as simple as it is, cpw. For developing 14 | FML, which stabelized the client and server modding ecosystem. As well as the base 15 | loading system that allows us to modify Minecraft's code as elegently as possible. 16 | 17 | Mezz, who has stepped up as the issue and pull request manager. Helping to keep me 18 | sane as well as guiding the community into creating better additions to Forge. 19 | 20 | Searge, Bspks, Fesh0r, ProfMobious, and all the rest over on the MCP team {of which 21 | I am a part}. For creating some of the core tools needed to make Minecraft modding 22 | both possible, and as stable as can be. 23 | On that note, here is some specific information of the MCP data we use: 24 | * Minecraft Coder Pack (MCP) * 25 | Forge Mod Loader and Minecraft Forge have permission to distribute and automatically 26 | download components of MCP and distribute MCP data files. This permission is not 27 | transitive and others wishing to redistribute the Minecraft Forge source independently 28 | should seek permission of MCP or remove the MCP data files and request their users 29 | to download MCP separately. 30 | 31 | And lastly, the countless community members who have spent time submitting bug reports, 32 | pull requests, and just helping out the community in general. Thank you. 33 | 34 | --LexManos 35 | 36 | ========================================================================= 37 | 38 | This is Forge Mod Loader. 39 | 40 | You can find the source code at all times at https://github.com/MinecraftForge/MinecraftForge/tree/1.12.x/src/main/java/net/minecraftforge/fml 41 | 42 | This minecraft mod is a clean open source implementation of a mod loader for minecraft servers 43 | and minecraft clients. 44 | 45 | The code is authored by cpw. 46 | 47 | It began by partially implementing an API defined by the client side ModLoader, authored by Risugami. 48 | http://www.minecraftforum.net/topic/75440- 49 | This support has been dropped as of Minecraft release 1.7, as Risugami no longer maintains ModLoader. 50 | 51 | It also contains suggestions and hints and generous helpings of code from LexManos, author of MinecraftForge. 52 | http://www.minecraftforge.net/ 53 | 54 | Additionally, it contains an implementation of topological sort based on that 55 | published at http://keithschwarz.com/interesting/code/?dir=topological-sort 56 | 57 | It also contains code from the Maven project for performing versioned dependency 58 | resolution. http://maven.apache.org/ 59 | 60 | It also contains a partial repackaging of the javaxdelta library from http://sourceforge.net/projects/javaxdelta/ 61 | with credit to it's authors. 62 | 63 | Forge Mod Loader downloads components from the Minecraft Coder Pack 64 | (http://mcp.ocean-labs.de/index.php/Main_Page) with kind permission from the MCP team. 65 | 66 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Zanckor 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # QuestApi 2 | 3 | QuestApi is a Forge library that allows modders and modpack makers to easily add quests and dialogs to their Minecraft modifications. By simply adding a few .json files, users can create quests and dialogs that are portable between worlds, servers, and different Minecraft versions. 4 | 5 | ## Features 6 | 7 | - Massive quest and dialog creation with pre-made and custom templates. 8 | - Easy creation of custom quests, dialogs, requirements, and rewards. 9 | - Automatic loading of files on login. 10 | - NPC dialogs with customizable screens per mod/dialog. 11 | - In-game quest log screen and quest tracked HUD progress. 12 | 13 | ## Wiki 14 | 15 | Take a look at our [wiki](https://github.com/zanckor/QuestApi/wiki) to learn how to add your own quests, dialogs, and screens. 16 | 17 | ## Contact 18 | 19 | If you have any suggestions for improvements, find any bugs, or would like to point out anything that is not very intuitive, feel free to contact me via Discord (Zanckor#6989). 20 | 21 | ## Downloads 22 | 23 | [CurseForge](https://www.curseforge.com/minecraft/mc-mods/questapi) 24 | [Modrinth](https://modrinth.com/mod/questapi) 25 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Sets default memory used for gradle commands. Can be overridden by user or command line properties. 2 | # This is required to provide enough memory for the Minecraft decompilation process. 3 | org.gradle.jvmargs=-Xmx3G 4 | org.gradle.daemon=false -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zanckor/QuestAPI/531a3a540ea6eb606027ead3090fd6b1b8bf8c17/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if %ERRORLEVEL% equ 0 goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if %ERRORLEVEL% equ 0 goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | set EXIT_CODE=%ERRORLEVEL% 84 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 85 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 86 | exit /b %EXIT_CODE% 87 | 88 | :mainEnd 89 | if "%OS%"=="Windows_NT" endlocal 90 | 91 | :omega 92 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven { url = 'https://maven.minecraftforge.net/' } 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/enuminterface/enumdialog/IEnumDialogOption.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.enuminterface.enumdialog; 2 | 3 | import dev.zanckor.api.filemanager.dialog.abstractdialog.AbstractDialogOption; 4 | import dev.zanckor.example.common.enumregistry.EnumRegistry; 5 | 6 | public interface IEnumDialogOption { 7 | AbstractDialogOption getDialogOption(); 8 | 9 | default void registerEnumDialogOption(Class enumClass) { 10 | EnumRegistry.registerDialogOption(enumClass); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/enuminterface/enumdialog/IEnumDialogReq.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.enuminterface.enumdialog; 2 | 3 | import dev.zanckor.api.filemanager.dialog.abstractdialog.AbstractDialogRequirement; 4 | import dev.zanckor.example.common.enumregistry.EnumRegistry; 5 | 6 | public interface IEnumDialogReq { 7 | AbstractDialogRequirement getDialogRequirement(); 8 | 9 | default void registerEnumDialogReq(Class enumClass) { 10 | EnumRegistry.registerDialogRequirement(enumClass); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/enuminterface/enumquest/IEnumQuestGoal.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.enuminterface.enumquest; 2 | 3 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractGoal; 4 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractTargetType; 5 | import dev.zanckor.example.common.enumregistry.EnumRegistry; 6 | 7 | public interface IEnumQuestGoal { 8 | AbstractGoal getQuest(); 9 | 10 | default void registerEnumGoal(Class enumClass) { 11 | EnumRegistry.registerQuestGoal(enumClass); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/enuminterface/enumquest/IEnumQuestRequirement.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.enuminterface.enumquest; 2 | 3 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractQuestRequirement; 4 | import dev.zanckor.example.common.enumregistry.EnumRegistry; 5 | 6 | public interface IEnumQuestRequirement { 7 | AbstractQuestRequirement getRequirement(); 8 | 9 | default void registerEnumQuestReq(Class enumClass) { 10 | EnumRegistry.registerQuestRequirement(enumClass); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/enuminterface/enumquest/IEnumQuestReward.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.enuminterface.enumquest; 2 | 3 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractReward; 4 | import dev.zanckor.example.common.enumregistry.EnumRegistry; 5 | 6 | public interface IEnumQuestReward { 7 | AbstractReward getReward(); 8 | 9 | default void registerEnumReward(Class enumClass) { 10 | EnumRegistry.registerQuestReward(enumClass); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/enuminterface/enumquest/IEnumTargetType.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.enuminterface.enumquest; 2 | 3 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractTargetType; 4 | import dev.zanckor.example.common.enumregistry.EnumRegistry; 5 | 6 | public interface IEnumTargetType { 7 | AbstractTargetType getTargetType(); 8 | 9 | default void registerTargetType(Class enumClass) { 10 | EnumRegistry.registerTargetType(enumClass); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/FileAbstract.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager; 2 | 3 | public abstract class FileAbstract { 4 | //The only purpose of this class is to be similar to a "var" or "Object" but limited to File classes 5 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/FolderManager.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager; 2 | 3 | import dev.zanckor.mod.QuestApiMain; 4 | import net.minecraft.world.entity.player.Player; 5 | import net.minecraft.world.level.storage.LevelResource; 6 | import net.minecraftforge.event.entity.player.PlayerEvent; 7 | import net.minecraftforge.event.server.ServerAboutToStartEvent; 8 | import net.minecraftforge.eventbus.api.SubscribeEvent; 9 | import net.minecraftforge.fml.common.Mod; 10 | 11 | import java.io.File; 12 | import java.nio.file.Path; 13 | import java.nio.file.Paths; 14 | 15 | import static dev.zanckor.mod.QuestApiMain.*; 16 | 17 | @Mod.EventBusSubscriber(modid = QuestApiMain.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE) 18 | public class FolderManager { 19 | 20 | /** 21 | * Each time that server starts serverFolderManager is called to create base folders 22 | * Each time a player joins the server, playerFolderManager is called to create his data folders 23 | */ 24 | 25 | @SubscribeEvent 26 | public static void serverFolderManager(ServerAboutToStartEvent e) { 27 | Path serverDirectory = e.getServer().getWorldPath(LevelResource.ROOT).toAbsolutePath(); 28 | 29 | createAPIFolder(serverDirectory); 30 | } 31 | 32 | public static void createAPIFolder(Path serverDirectory) { 33 | File questApi = new File(serverDirectory.toString(), "quest-api"); 34 | File playerData = new File(questApi.toString(), "player-data"); 35 | File serverQuests = new File(questApi.toString(), "server-quests"); 36 | File serverDialogs = new File(questApi.toString(), "server-dialogs"); 37 | File serverNPC = new File(questApi.toString(), "server-npc"); 38 | File entity_type_list = new File(serverNPC.toString(), "entity_type_list"); 39 | File compoundTag_list = new File(serverNPC.toString(), "compound_tag_list"); 40 | 41 | File[] paths = {questApi, playerData, serverQuests, serverDialogs, serverNPC, entity_type_list, compoundTag_list}; 42 | 43 | for (File file : paths) { 44 | if (!file.exists()) { 45 | file.mkdirs(); 46 | } 47 | } 48 | 49 | QuestApiMain.serverDirectory = serverDirectory; 50 | QuestApiMain.questApi = questApi.toPath(); 51 | QuestApiMain.playerData = playerData.toPath(); 52 | QuestApiMain.serverQuests = serverQuests.toPath(); 53 | QuestApiMain.serverDialogs = serverDialogs.toPath(); 54 | QuestApiMain.serverNPC = serverNPC.toPath(); 55 | QuestApiMain.entity_type_list = entity_type_list.toPath(); 56 | QuestApiMain.compoundTag_List = compoundTag_list.toPath(); 57 | } 58 | 59 | 60 | @SubscribeEvent 61 | public static void playerFolderManager(PlayerEvent.PlayerLoggedInEvent e) { 62 | if (e.getEntity().level().isClientSide || !(e.getEntity() instanceof Player)) return; 63 | 64 | Path userFolder = Paths.get(playerData.toString(), e.getEntity().getUUID().toString()); 65 | 66 | if (!userFolder.toFile().exists()) { 67 | getActiveQuest(userFolder).toFile().mkdirs(); 68 | getCompletedQuest(userFolder).toFile().mkdirs(); 69 | getFailedQuest(userFolder).toFile().mkdirs(); 70 | getReadDialogs(userFolder).toFile().mkdirs(); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/dialog/abstractdialog/AbstractDialogOption.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.dialog.abstractdialog; 2 | 3 | import dev.zanckor.api.filemanager.dialog.codec.NPCConversation; 4 | import net.minecraft.resources.ResourceLocation; 5 | import net.minecraft.world.entity.Entity; 6 | import net.minecraft.world.entity.player.Player; 7 | import net.minecraft.world.item.Item; 8 | 9 | import java.io.IOException; 10 | 11 | public abstract class AbstractDialogOption { 12 | 13 | /** 14 | * Abstract class to call a registered dialog option 15 | * @param player The player 16 | * @param dialog DialogTemplate class with all dialog data 17 | * @param option_id DialogOption ID, Returns the object inside the List DialogOption. This is not a parameter inside the .json file 18 | * @throws IOException Exception fired when server cannot read json file 19 | */ 20 | 21 | public abstract void handler(Player player, NPCConversation dialog, int option_id, Entity entity) throws IOException; 22 | public abstract void handler(Player player, NPCConversation dialog, int option_id, String resourceLocation) throws IOException; 23 | public abstract void handler(Player player, NPCConversation dialog, int option_id, Item item) throws IOException; 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/dialog/abstractdialog/AbstractDialogRequirement.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.dialog.abstractdialog; 2 | 3 | import dev.zanckor.api.filemanager.dialog.codec.NPCConversation; 4 | import net.minecraft.resources.ResourceLocation; 5 | import net.minecraft.world.entity.Entity; 6 | import net.minecraft.world.entity.player.Player; 7 | import net.minecraft.world.item.Item; 8 | 9 | import java.io.IOException; 10 | 11 | public abstract class AbstractDialogRequirement { 12 | /** 13 | * Abstract class to call a registered dialog requirement so on try to display a dialog first check the requirement for determinate option_id 14 | * @param player The player 15 | * @param player The player 16 | * @param dialog DialogTemplate class with all dialog data 17 | * @param option_id DialogOption ID, Returns the object inside the List DialogOption. This is not a parameter inside the .json file 18 | * @throws IOException Exception fired when server cannot read json file 19 | */ 20 | 21 | public abstract boolean handler(Player player, NPCConversation dialog, int option_id, Entity entity) throws IOException; 22 | public abstract boolean handler(Player player, NPCConversation dialog, int option_id, String resourceLocation) throws IOException; 23 | public abstract boolean handler(Player player, NPCConversation dialog, int option_id, Item item) throws IOException; 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/dialog/codec/NPCConversation.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.dialog.codec; 2 | 3 | import dev.zanckor.api.database.LocateHash; 4 | import dev.zanckor.api.filemanager.FileAbstract; 5 | 6 | import java.io.IOException; 7 | import java.nio.file.Path; 8 | import java.util.List; 9 | 10 | public class NPCConversation extends FileAbstract { 11 | private static String global_id; 12 | 13 | List dialog; 14 | String identifier; 15 | 16 | public String getIdentifier() { 17 | return identifier; 18 | } 19 | 20 | public void setIdentifier(String identifier) { 21 | this.identifier = identifier; 22 | } 23 | 24 | public String getGlobal_id() { 25 | return global_id; 26 | } 27 | 28 | public List getDialog() { 29 | return dialog; 30 | } 31 | 32 | public static NPCConversation createDialog(Path path) throws IOException { 33 | NPCConversation dialogQuest = new NPCConversation(); 34 | 35 | dialogQuest.setGlobal_id(global_id); 36 | 37 | LocateHash.registerDialogLocation(global_id, path); 38 | 39 | return dialogQuest; 40 | } 41 | 42 | public void setGlobal_id(String global_id) { 43 | this.global_id = global_id; 44 | } 45 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/dialog/codec/ReadDialog.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.dialog.codec; 2 | 3 | import dev.zanckor.api.filemanager.FileAbstract; 4 | 5 | import java.util.List; 6 | 7 | public class ReadDialog extends FileAbstract { 8 | 9 | /** 10 | * This class allows dev to add dialog to dialog-read.json or get which ones are already read 11 | * 12 | * Returns a list of dialogs already read by a certain player 13 | */ 14 | 15 | 16 | public static class GlobalID extends FileAbstract { 17 | String global_id; 18 | List dialog_id; 19 | 20 | public GlobalID(String id, List dialog_id) { 21 | this.global_id = id; 22 | this.dialog_id = dialog_id; 23 | } 24 | 25 | public String getGlobal_id() { 26 | return global_id; 27 | } 28 | 29 | public List getDialog_id() { 30 | return dialog_id; 31 | } 32 | } 33 | 34 | public static class DialogID extends FileAbstract { 35 | int dialog_id; 36 | 37 | public DialogID(int id) { 38 | this.dialog_id = id; 39 | } 40 | 41 | public int getDialog_id() { 42 | return dialog_id; 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/dialog/register/LoadDialog.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.dialog.register; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonObject; 5 | import dev.zanckor.api.filemanager.FolderManager; 6 | import dev.zanckor.api.filemanager.dialog.codec.NPCConversation; 7 | import dev.zanckor.mod.common.datapack.DialogJSONListener; 8 | import dev.zanckor.mod.common.util.GsonManager; 9 | import net.minecraft.resources.ResourceLocation; 10 | import net.minecraft.server.MinecraftServer; 11 | import net.minecraft.server.packs.resources.ResourceManager; 12 | import net.minecraft.world.level.storage.LevelResource; 13 | 14 | import java.io.*; 15 | import java.nio.file.Path; 16 | import java.util.Map; 17 | 18 | import static dev.zanckor.mod.QuestApiMain.serverDialogs; 19 | 20 | public class LoadDialog { 21 | 22 | /** 23 | * Each time that server starts running, registerDialog is called to copy resource's dialog files to minecraft folder. 24 | */ 25 | 26 | static NPCConversation dialogTemplate; 27 | 28 | public static void registerDialog(MinecraftServer server, String modid) { 29 | ResourceManager resourceManager = server.getResourceManager(); 30 | 31 | if (serverDialogs == null) { 32 | FolderManager.createAPIFolder(server.getWorldPath(LevelResource.ROOT).toAbsolutePath()); 33 | } 34 | 35 | resourceManager.listResources("dialog", (file) -> { 36 | if (file.getPath().length() > 7) { 37 | String fileName = file.getPath().substring(7); 38 | ResourceLocation resourceLocation = new ResourceLocation(modid, file.getPath()); 39 | if(!modid.equals(file.getNamespace())) return false; 40 | 41 | if (file.getPath().endsWith(".json")) { 42 | read(resourceLocation, server); 43 | write(dialogTemplate, modid, fileName); 44 | } else { 45 | throw new RuntimeException("File " + fileName + " in " + file.getPath() + " is not .json"); 46 | } 47 | } 48 | 49 | return false; 50 | }); 51 | } 52 | 53 | 54 | public static void registerDatapackDialog(MinecraftServer server) throws IOException { 55 | if (serverDialogs == null) { 56 | FolderManager.createAPIFolder(server.getWorldPath(LevelResource.ROOT).toAbsolutePath()); 57 | } 58 | 59 | for(Map.Entry entry : DialogJSONListener.datapackDialogList.entrySet()){ 60 | FileWriter writer = new FileWriter(String.valueOf(Path.of(serverDialogs + "/" + entry.getKey()))); 61 | writer.write(entry.getValue().toString()); 62 | writer.close(); 63 | } 64 | } 65 | 66 | private static void read(ResourceLocation resourceLocation, MinecraftServer server) { 67 | try { 68 | if(!server.getResourceManager().getResource(resourceLocation).isPresent()) return; 69 | 70 | InputStream inputStream = server.getResourceManager().getResource(resourceLocation).get().open(); 71 | dialogTemplate = GsonManager.gson.fromJson(new InputStreamReader(inputStream), NPCConversation.class); 72 | 73 | } catch (IOException e) { 74 | throw new RuntimeException(e); 75 | } 76 | } 77 | 78 | private static void write(NPCConversation dialogTemplate, String identifier, String fileName) { 79 | try { 80 | if(dialogTemplate == null) return; 81 | 82 | File file = new File(serverDialogs.toFile(), identifier + "." + fileName); 83 | 84 | if (dialogTemplate.getIdentifier() == null || dialogTemplate.getIdentifier().isEmpty()) { 85 | dialogTemplate.setIdentifier(identifier); 86 | } 87 | 88 | GsonManager.writeJson(file, dialogTemplate); 89 | } catch (IOException e) { 90 | throw new RuntimeException(e); 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/npc/entity_type/codec/EntityTypeDialog.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.npc.entity_type.codec; 2 | 3 | import com.mojang.serialization.Codec; 4 | import com.mojang.serialization.codecs.RecordCodecBuilder; 5 | import dev.zanckor.api.filemanager.FileAbstract; 6 | 7 | import java.util.List; 8 | 9 | public class EntityTypeDialog extends FileAbstract { 10 | public static final Codec CODEC = RecordCodecBuilder.create(instance -> 11 | instance.group( 12 | Codec.STRING.fieldOf("id").forGetter(EntityTypeDialog::getId), 13 | Codec.STRING.listOf().fieldOf("entity_type").forGetter(EntityTypeDialog::getEntity_type), 14 | Codec.STRING.listOf().fieldOf("dialog_list").forGetter(EntityTypeDialog::getDialog_list) 15 | ).apply(instance, (id, entityType, dialogList) -> new EntityTypeDialog())); 16 | 17 | 18 | private String id; 19 | private List entity_type; 20 | private List dialog_list; 21 | 22 | public List getEntity_type() { 23 | return entity_type; 24 | } 25 | 26 | public List getDialog_list() { 27 | return dialog_list; 28 | } 29 | 30 | public String getId() { 31 | return id; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/npc/entity_type/register/LoadDialogList.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.npc.entity_type.register; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonObject; 5 | import dev.zanckor.api.database.LocateHash; 6 | import dev.zanckor.api.filemanager.FolderManager; 7 | import dev.zanckor.api.filemanager.npc.entity_type.codec.EntityTypeDialog; 8 | import dev.zanckor.mod.common.datapack.DialogJSONListener; 9 | import dev.zanckor.mod.common.util.GsonManager; 10 | import net.minecraft.resources.ResourceLocation; 11 | import net.minecraft.server.MinecraftServer; 12 | import net.minecraft.server.packs.resources.ResourceManager; 13 | import net.minecraft.world.level.storage.LevelResource; 14 | 15 | import java.io.*; 16 | import java.nio.file.Path; 17 | import java.util.Map; 18 | 19 | import static dev.zanckor.mod.QuestApiMain.entity_type_list; 20 | import static dev.zanckor.mod.QuestApiMain.serverDialogs; 21 | import static dev.zanckor.mod.common.datapack.EntityTypeDialogJSONListener.datapackDialogPerEntityTypeList; 22 | 23 | public class LoadDialogList { 24 | 25 | /** 26 | * Each time that server starts running, registerNPCDialogList is called to copy resource's files to minecraft folder. 27 | */ 28 | 29 | static EntityTypeDialog entityTypeDialog; 30 | 31 | public static void registerNPCDialogList(MinecraftServer server, String modid) throws IOException { 32 | ResourceManager resourceManager = server.getResourceManager(); 33 | 34 | if (entity_type_list == null) { 35 | FolderManager.createAPIFolder(server.getWorldPath(LevelResource.ROOT).toAbsolutePath()); 36 | } 37 | 38 | resourceManager.listResources("npc/entity_type_list", (file) -> { 39 | if (file.getPath().length() > 22) { 40 | String fileName = file.getPath().substring(21); 41 | ResourceLocation resourceLocation = new ResourceLocation(modid, file.getPath()); 42 | if(!modid.equals(file.getNamespace())) return false; 43 | 44 | if (file.getPath().endsWith(".json")) { 45 | read(resourceLocation, server); 46 | write(entityTypeDialog, modid, fileName); 47 | } else { 48 | throw new RuntimeException("File " + fileName + " in " + file.getPath() + " is not .json"); 49 | } 50 | } 51 | 52 | return false; 53 | }); 54 | 55 | LocateHash.registerDialogPerEntityType(); 56 | } 57 | 58 | 59 | public static void registerDatapackDialogList(MinecraftServer server) throws IOException { 60 | if (entity_type_list == null) { 61 | FolderManager.createAPIFolder(server.getWorldPath(LevelResource.ROOT).toAbsolutePath()); 62 | } 63 | 64 | for (Map.Entry entry : datapackDialogPerEntityTypeList.entrySet()) { 65 | FileWriter writer = new FileWriter(String.valueOf(Path.of(entity_type_list + "/" + entry.getKey()))); 66 | writer.write(entry.getValue().toString()); 67 | writer.close(); 68 | } 69 | } 70 | 71 | 72 | private static void read(ResourceLocation resourceLocation, MinecraftServer server) { 73 | try { 74 | if(!server.getResourceManager().getResource(resourceLocation).isPresent()) return; 75 | 76 | InputStream inputStream = server.getResourceManager().getResource(resourceLocation).get().open(); 77 | entityTypeDialog = GsonManager.gson.fromJson(new InputStreamReader(inputStream), EntityTypeDialog.class); 78 | 79 | } catch (IOException e) { 80 | throw new RuntimeException(e); 81 | } 82 | } 83 | 84 | private static void write(EntityTypeDialog entityTypeDialog, String modid, String fileName) { 85 | try { 86 | if(entityTypeDialog == null) return; 87 | 88 | File file = new File(entity_type_list.toFile(), modid + "." + fileName); 89 | GsonManager.writeJson(file, entityTypeDialog); 90 | } catch (IOException e) { 91 | throw new RuntimeException(e); 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/npc/entity_type_tag/codec/EntityTypeTagDialog.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.npc.entity_type_tag.codec; 2 | 3 | import dev.zanckor.api.filemanager.FileAbstract; 4 | import dev.zanckor.api.filemanager.npc.entity_type_tag.gateenum.LogicGate; 5 | 6 | import java.util.List; 7 | 8 | public class EntityTypeTagDialog extends FileAbstract { 9 | private String id; 10 | private List entity_type; 11 | private List conditions; 12 | 13 | public List getEntity_type() { 14 | return entity_type; 15 | } 16 | 17 | public List getConditions() { 18 | return conditions; 19 | } 20 | public class EntityTypeTagDialogCondition{ 21 | private List nbt; 22 | private String logic_gate; 23 | private List dialog_list; 24 | 25 | public LogicGate getLogic_gate() { 26 | return LogicGate.valueOf(logic_gate); 27 | } 28 | 29 | public List getNbt() { 30 | return nbt; 31 | } 32 | 33 | public List getEntity_type() { 34 | return entity_type; 35 | } 36 | 37 | public List getDialog_list() { 38 | return dialog_list; 39 | } 40 | 41 | public class EntityTypeTagDialogNBT { 42 | private String tag; 43 | private String value; 44 | 45 | public String getTag() { 46 | return tag; 47 | } 48 | 49 | public String getValue() { 50 | return value; 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/npc/entity_type_tag/gateenum/LogicGate.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.npc.entity_type_tag.gateenum; 2 | 3 | public enum LogicGate { 4 | OR, 5 | AND 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/npc/entity_type_tag/register/LoadTagDialogList.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.npc.entity_type_tag.register; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonObject; 5 | import dev.zanckor.api.database.LocateHash; 6 | import dev.zanckor.api.filemanager.FolderManager; 7 | import dev.zanckor.api.filemanager.npc.entity_type_tag.codec.EntityTypeTagDialog; 8 | import dev.zanckor.mod.common.datapack.DialogJSONListener; 9 | import dev.zanckor.mod.common.util.GsonManager; 10 | import net.minecraft.resources.ResourceLocation; 11 | import net.minecraft.server.MinecraftServer; 12 | import net.minecraft.server.packs.resources.ResourceManager; 13 | import net.minecraft.world.level.storage.LevelResource; 14 | 15 | import java.io.*; 16 | import java.nio.file.Path; 17 | import java.util.Map; 18 | 19 | import static dev.zanckor.mod.QuestApiMain.*; 20 | import static dev.zanckor.mod.common.datapack.CompoundTagDialogJSONListener.datapackDialogPerCompoundTagList; 21 | import static dev.zanckor.mod.common.datapack.EntityTypeDialogJSONListener.datapackDialogPerEntityTypeList; 22 | 23 | public class LoadTagDialogList { 24 | 25 | /** 26 | * Each time that server starts running, registerNPCTagDialogList is called to copy resource's files to minecraft folder. 27 | */ 28 | 29 | static EntityTypeTagDialog entityTypeTagDialog; 30 | 31 | public static void registerNPCTagDialogList(MinecraftServer server, String modid) throws IOException { 32 | ResourceManager resourceManager = server.getResourceManager(); 33 | 34 | if (compoundTag_List == null) { 35 | FolderManager.createAPIFolder(server.getWorldPath(LevelResource.ROOT).toAbsolutePath()); 36 | } 37 | 38 | resourceManager.listResources("npc/compound_tag_list", (file) -> { 39 | if (file.getPath().length() > 22) { 40 | String fileName = file.getPath().substring(22); 41 | ResourceLocation resourceLocation = new ResourceLocation(modid, file.getPath()); 42 | if(!modid.equals(file.getNamespace())) return false; 43 | 44 | if (file.getPath().endsWith(".json")) { 45 | read(resourceLocation, server); 46 | write(entityTypeTagDialog, modid, fileName); 47 | } else { 48 | throw new RuntimeException("File " + fileName + " in " + file.getPath() + " is not .json"); 49 | } 50 | } 51 | 52 | return false; 53 | }); 54 | 55 | LocateHash.registerDialogPerCompoundTag(); 56 | } 57 | 58 | 59 | public static void registerDatapackTagDialogList(MinecraftServer server) throws IOException { 60 | if (compoundTag_List == null) { 61 | FolderManager.createAPIFolder(server.getWorldPath(LevelResource.ROOT).toAbsolutePath()); 62 | } 63 | 64 | for(Map.Entry entry : datapackDialogPerCompoundTagList.entrySet()){ 65 | FileWriter writer = new FileWriter(String.valueOf(Path.of(compoundTag_List + "/" + entry.getKey()))); 66 | writer.write(entry.getValue().toString()); 67 | writer.close(); 68 | } 69 | } 70 | 71 | 72 | private static void read(ResourceLocation resourceLocation, MinecraftServer server) { 73 | try { 74 | if(!server.getResourceManager().getResource(resourceLocation).isPresent()) return; 75 | 76 | InputStream inputStream = server.getResourceManager().getResource(resourceLocation).get().open(); 77 | entityTypeTagDialog = GsonManager.gson.fromJson(new InputStreamReader(inputStream), EntityTypeTagDialog.class); 78 | } catch (IOException e) { 79 | throw new RuntimeException(e); 80 | } 81 | } 82 | 83 | private static void write(EntityTypeTagDialog entityTypeDialog, String modid, String fileName) { 84 | try { 85 | if(entityTypeDialog == null) return; 86 | 87 | File file = new File(compoundTag_List.toFile(), modid + "." + fileName); 88 | GsonManager.writeJson(file, entityTypeDialog); 89 | } catch (IOException e) { 90 | throw new RuntimeException(e); 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/quest/abstracquest/AbstractQuestRequirement.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.quest.abstracquest; 2 | 3 | import dev.zanckor.api.filemanager.quest.codec.server.ServerQuest; 4 | import dev.zanckor.example.ModExample; 5 | import dev.zanckor.example.common.enumregistry.enumquest.EnumQuestRequirement; 6 | import net.minecraft.world.entity.player.Player; 7 | 8 | import java.io.IOException; 9 | 10 | public abstract class AbstractQuestRequirement { 11 | 12 | /** 13 | * Abstract class to call a registered quest type handler 14 | * 15 | * @param player The player 16 | * @param questTemplate ServerQuestBase with global quest data 17 | * @param requirementIndex 18 | * @throws IOException Exception fired when server cannot read json file 19 | * @see EnumQuestRequirement Types of requirements to access a quest 20 | * @see ModExample Main class where you should register requirement's types 21 | */ 22 | 23 | public abstract boolean handler(Player player, ServerQuest questTemplate, int requirementIndex) throws IOException; 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/quest/abstracquest/AbstractReward.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.quest.abstracquest; 2 | 3 | import dev.zanckor.api.filemanager.quest.codec.server.ServerQuest; 4 | import dev.zanckor.example.ModExample; 5 | import dev.zanckor.example.common.enumregistry.enumquest.EnumQuestRequirement; 6 | import net.minecraft.server.level.ServerPlayer; 7 | 8 | import java.io.IOException; 9 | 10 | public abstract class AbstractReward { 11 | 12 | /** 13 | * Abstract class to call a registered quest type handler 14 | * 15 | * @param player The player 16 | * @param questTemplate ServerQuestBase with global quest data 17 | * @param rewardIndex 18 | * @throws IOException 19 | * @see EnumQuestRequirement Types of rewards gave on complete a quest 20 | * @see ModExample Main class where you should register reward's types 21 | */ 22 | 23 | public abstract void handler(ServerPlayer player, ServerQuest questTemplate, int rewardIndex) throws IOException; 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/quest/abstracquest/AbstractTargetType.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.quest.abstracquest; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import dev.zanckor.api.filemanager.quest.codec.user.UserGoal; 5 | import net.minecraft.ChatFormatting; 6 | import net.minecraft.network.chat.MutableComponent; 7 | import net.minecraft.world.entity.player.Player; 8 | 9 | public abstract class AbstractTargetType { 10 | 11 | /** 12 | * Class that returns as a human-readable text the quest target 13 | * 14 | * @param resourceLocationString Resource location of the target wanted to translate. Example: entity.minecraft.cow 15 | * @param player 16 | * @param chatFormatting 17 | * @param chatFormatting1 18 | */ 19 | 20 | public abstract MutableComponent handler(String resourceLocationString, UserGoal goal, Player player, ChatFormatting chatFormatting, ChatFormatting chatFormatting1); 21 | public abstract String target(String resourceLocationString); 22 | public abstract void renderTarget(PoseStack poseStack, int xPosition, int yPosition, double size, double rotation, UserGoal goal, String resourceLocationString); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/quest/codec/server/ServerGoal.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.quest.codec.server; 2 | 3 | import java.util.List; 4 | 5 | public class ServerGoal { 6 | private String type; 7 | private String target; 8 | private Integer amount; 9 | 10 | private Integer additionalIntegerData; 11 | private Double additionalDoubleData; 12 | private String additionalStringData; 13 | private List additionalListData; 14 | private Object additionalClassData; 15 | 16 | public String getType() { 17 | return type; 18 | } 19 | 20 | public void setType(String type) { 21 | this.type = type; 22 | } 23 | 24 | public String getTarget() { 25 | return target; 26 | } 27 | 28 | public void setTarget(String target) { 29 | this.target = target; 30 | } 31 | 32 | public Integer getAmount() { 33 | return amount; 34 | } 35 | 36 | public void setAmount(Integer amount) { 37 | this.amount = amount; 38 | } 39 | 40 | public Integer getAdditionalIntegerData() { 41 | return additionalIntegerData; 42 | } 43 | 44 | public void setAdditionalIntegerData(Integer additionalIntegerData) { 45 | this.additionalIntegerData = additionalIntegerData; 46 | } 47 | 48 | public Double getAdditionalDoubleData() { 49 | return additionalDoubleData; 50 | } 51 | 52 | public void setAdditionalDoubleData(Double additionalDoubleData) { 53 | this.additionalDoubleData = additionalDoubleData; 54 | } 55 | 56 | public String getAdditionalStringData() { 57 | return additionalStringData; 58 | } 59 | 60 | public void setAdditionalStringData(String additionalStringData) { 61 | this.additionalStringData = additionalStringData; 62 | } 63 | 64 | public List getAdditionalListData() { 65 | return additionalListData; 66 | } 67 | 68 | public void setAdditionalListData(List additionalListData) { 69 | this.additionalListData = additionalListData; 70 | } 71 | 72 | public Object getAdditionalClassData() { 73 | return additionalClassData; 74 | } 75 | 76 | public void setAdditionalClassData(Object additionalClassData) { 77 | this.additionalClassData = additionalClassData; 78 | } 79 | } 80 | 81 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/quest/codec/server/ServerQuest.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.quest.codec.server; 2 | 3 | import dev.zanckor.api.filemanager.FileAbstract; 4 | 5 | import java.util.List; 6 | 7 | public class ServerQuest extends FileAbstract { 8 | private String id; 9 | private String title; 10 | private boolean hasTimeLimit; 11 | private int timeLimitInSeconds; 12 | private List goals; 13 | private List rewards; 14 | private List requirements; 15 | 16 | 17 | public String getId() { 18 | return id; 19 | } 20 | 21 | public void setId(String id) { 22 | this.id = id; 23 | } 24 | 25 | public String getTitle() { 26 | return title; 27 | } 28 | 29 | public void setTitle(String title) { 30 | this.title = title; 31 | } 32 | 33 | public boolean hasTimeLimit() { 34 | return hasTimeLimit; 35 | } 36 | 37 | public void setHasTimeLimit(boolean hasTimeLimit) { 38 | this.hasTimeLimit = hasTimeLimit; 39 | } 40 | 41 | public int getTimeLimitInSeconds() { 42 | return timeLimitInSeconds; 43 | } 44 | 45 | public void setTimeLimitInSeconds(int timeLimitInSeconds) { 46 | this.timeLimitInSeconds = timeLimitInSeconds; 47 | } 48 | 49 | public List getGoalList() { 50 | return goals; 51 | } 52 | 53 | public void setGoalList(List goals) { 54 | this.goals = goals; 55 | } 56 | 57 | public List getRewards() { 58 | return rewards; 59 | } 60 | 61 | public void setRewards(List ServerRewards) { 62 | this.rewards = ServerRewards; 63 | } 64 | 65 | public List getRequirements() { 66 | return requirements; 67 | } 68 | 69 | public void setRequirements(List ServerRequirements) { 70 | this.requirements = ServerRequirements; 71 | } 72 | } 73 | 74 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/quest/codec/server/ServerRequirement.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.quest.codec.server; 2 | 3 | 4 | import java.util.List; 5 | 6 | public class ServerRequirement { 7 | private String type; 8 | private int requirements_min; 9 | private int requirements_max; 10 | private Integer additionalIntegerData; 11 | private Double additionalDoubleData; 12 | private String additionalStringData; 13 | private List additionalListData; 14 | private Object additionalClassData; 15 | 16 | public Integer getAdditionalIntegerData() { 17 | return additionalIntegerData; 18 | } 19 | 20 | public void setAdditionalIntegerData(Integer additionalIntegerData) { 21 | this.additionalIntegerData = additionalIntegerData; 22 | } 23 | 24 | public Double getAdditionalDoubleData() { 25 | return additionalDoubleData; 26 | } 27 | 28 | public void setAdditionalDoubleData(Double additionalDoubleData) { 29 | this.additionalDoubleData = additionalDoubleData; 30 | } 31 | 32 | public String getAdditionalStringData() { 33 | return additionalStringData; 34 | } 35 | 36 | public void setAdditionalStringData(String additionalStringData) { 37 | this.additionalStringData = additionalStringData; 38 | } 39 | 40 | public List getAdditionalListData() { 41 | return additionalListData; 42 | } 43 | 44 | public void setAdditionalListData(List additionalListData) { 45 | this.additionalListData = additionalListData; 46 | } 47 | 48 | public Object getAdditionalClassData() { 49 | return additionalClassData; 50 | } 51 | 52 | public void setAdditionalClassData(Object additionalClassData) { 53 | this.additionalClassData = additionalClassData; 54 | } 55 | 56 | public String getType() { 57 | return type; 58 | } 59 | 60 | public void setType(String type) { 61 | this.type = type; 62 | } 63 | 64 | public int getRequirements_min() { 65 | return requirements_min; 66 | } 67 | 68 | public void setRequirements_min(int requirements_min) { 69 | this.requirements_min = requirements_min; 70 | } 71 | 72 | public int getRequirements_max() { 73 | return requirements_max; 74 | } 75 | 76 | public void setRequirements_max(int requirements_max) { 77 | this.requirements_max = requirements_max; 78 | } 79 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/quest/codec/server/ServerReward.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.quest.codec.server; 2 | 3 | import java.util.List; 4 | 5 | public class ServerReward { 6 | private String type; 7 | private String tag; 8 | private Integer amount; 9 | private Integer additionalIntegerData; 10 | private Double additionalDoubleData; 11 | private String additionalStringData; 12 | private List additionalListData; 13 | private Object additionalClassData; 14 | 15 | public Double getAdditionalDoubleData() { 16 | return additionalDoubleData; 17 | } 18 | 19 | public void setAdditionalDoubleData(Double additionalDoubleData) { 20 | this.additionalDoubleData = additionalDoubleData; 21 | } 22 | 23 | public String getAdditionalStringData() { 24 | return additionalStringData; 25 | } 26 | 27 | public void setAdditionalStringData(String additionalStringData) { 28 | this.additionalStringData = additionalStringData; 29 | } 30 | 31 | public List getAdditionalListData() { 32 | return additionalListData; 33 | } 34 | 35 | public void setAdditionalListData(List additionalListData) { 36 | this.additionalListData = additionalListData; 37 | } 38 | 39 | public Object getAdditionalClassData() { 40 | return additionalClassData; 41 | } 42 | 43 | public void setAdditionalClassData(Object additionalClassData) { 44 | this.additionalClassData = additionalClassData; 45 | } 46 | 47 | public Integer getAdditionalIntegerData() { 48 | return additionalIntegerData; 49 | } 50 | 51 | public void setAdditionalIntegerData(Integer additionalIntegerData) { 52 | this.additionalIntegerData = additionalIntegerData; 53 | } 54 | 55 | public String getType() { 56 | return type; 57 | } 58 | 59 | public void setType(String type) { 60 | this.type = type; 61 | } 62 | 63 | public String getTag() { 64 | return tag; 65 | } 66 | 67 | public void setTag(String tag) { 68 | this.tag = tag; 69 | } 70 | 71 | public Integer getAmount() { 72 | return amount; 73 | } 74 | 75 | public void setAmount(Integer amount) { 76 | this.amount = amount; 77 | } 78 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/quest/codec/user/UserGoal.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.quest.codec.user; 2 | 3 | import dev.zanckor.api.filemanager.quest.codec.server.ServerGoal; 4 | 5 | import java.util.List; 6 | 7 | public class UserGoal { 8 | private String type; 9 | private String translatableType; 10 | private String target; 11 | private Integer current_amount; 12 | private Integer amount; 13 | 14 | private Integer additionalIntegerData; 15 | private Double additionalDoubleData; 16 | private String additionalStringData; 17 | private List additionalListData; 18 | private Object additionalClassData; 19 | 20 | 21 | public static UserGoal createQuestGoal(ServerGoal serverGoal, String modid) { 22 | UserGoal userGoal = new UserGoal(); 23 | 24 | userGoal.setType(serverGoal.getType()); 25 | userGoal.setTranslatableType(modid + "." + serverGoal.getType()); 26 | userGoal.setTarget(serverGoal.getTarget()); 27 | userGoal.setCurrentAmount(0); 28 | userGoal.setAmount(serverGoal.getAmount()); 29 | 30 | userGoal.setAdditionalStringData(serverGoal.getAdditionalStringData()); 31 | userGoal.setAdditionalIntegerData(serverGoal.getAdditionalIntegerData()); 32 | userGoal.setAdditionalDoubleData(serverGoal.getAdditionalDoubleData()); 33 | userGoal.setAdditionalListData(serverGoal.getAdditionalListData()); 34 | userGoal.setAdditionalClassData(serverGoal.getAdditionalClassData()); 35 | 36 | return userGoal; 37 | } 38 | 39 | public String getType() { 40 | return type; 41 | } 42 | 43 | public void setType(String type) { 44 | this.type = type; 45 | } 46 | 47 | public String getTranslatableType() { 48 | return translatableType; 49 | } 50 | 51 | public void setTranslatableType(String translatableType) { 52 | this.translatableType = translatableType; 53 | } 54 | 55 | public String getTarget() { 56 | return target; 57 | } 58 | 59 | public void setTarget(String target) { 60 | this.target = target; 61 | } 62 | 63 | public Integer getCurrent_amount() { 64 | return current_amount; 65 | } 66 | 67 | public void setCurrent_amount(Integer current_amount) { 68 | this.current_amount = current_amount; 69 | } 70 | 71 | public Integer getAdditionalIntegerData() { 72 | return additionalIntegerData; 73 | } 74 | 75 | public void setAdditionalIntegerData(Integer additionalIntegerData) { 76 | this.additionalIntegerData = additionalIntegerData; 77 | } 78 | 79 | public Double getAdditionalDoubleData() { 80 | return additionalDoubleData; 81 | } 82 | 83 | public void setAdditionalDoubleData(Double additionalDoubleData) { 84 | this.additionalDoubleData = additionalDoubleData; 85 | } 86 | 87 | public String getAdditionalStringData() { 88 | return additionalStringData; 89 | } 90 | 91 | public void setAdditionalStringData(String additionalStringData) { 92 | this.additionalStringData = additionalStringData; 93 | } 94 | 95 | public List getAdditionalListData() { 96 | return additionalListData; 97 | } 98 | 99 | public Object getAdditionalClassData() { 100 | return additionalClassData; 101 | } 102 | 103 | public void setAdditionalClassData(Object additionalClassData) { 104 | this.additionalClassData = additionalClassData; 105 | } 106 | 107 | public void setAdditionalListData(List additionalListData) { 108 | this.additionalListData = additionalListData; 109 | } 110 | 111 | public Integer getAmount() { 112 | return amount; 113 | } 114 | 115 | public void setAmount(Integer amount) { 116 | this.amount = amount; 117 | } 118 | 119 | public Integer getCurrentAmount() { 120 | return current_amount; 121 | } 122 | 123 | public void setCurrentAmount(Integer amount) { 124 | this.current_amount = amount; 125 | } 126 | 127 | public void incrementCurrentAmount(Integer amount) { 128 | this.current_amount += amount; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/quest/codec/user/UserQuest.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.quest.codec.user; 2 | 3 | import dev.zanckor.api.database.LocateHash; 4 | import dev.zanckor.api.filemanager.FileAbstract; 5 | import dev.zanckor.api.filemanager.quest.codec.server.ServerQuest; 6 | import dev.zanckor.example.common.enumregistry.EnumRegistry; 7 | 8 | import java.io.File; 9 | import java.nio.file.Path; 10 | import java.util.ArrayList; 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | public class UserQuest extends FileAbstract { 15 | private String id; 16 | private String title; 17 | private List questGoals; 18 | private boolean timeLimit; 19 | private int timeLimitInSeconds; 20 | private boolean completed; 21 | 22 | 23 | public static UserQuest createQuest(ServerQuest serverQuest, Path path) { 24 | UserQuest userQuest = new UserQuest(); 25 | List questGoalList = new ArrayList<>(); 26 | String questModid = path.getFileName().toString().split(File.separator + ".")[0]; 27 | 28 | userQuest.setId(serverQuest.getId()); 29 | userQuest.setTitle(serverQuest.getTitle()); 30 | userQuest.setTimeLimit(serverQuest.hasTimeLimit()); 31 | userQuest.setTimeLimitInSeconds(serverQuest.getTimeLimitInSeconds()); 32 | userQuest.setCompleted(false); 33 | 34 | for (int goalsIndex = 0; goalsIndex < serverQuest.getGoalList().size(); goalsIndex++) { 35 | UserGoal questGoal = UserGoal.createQuestGoal(serverQuest.getGoalList().get(goalsIndex), questModid); 36 | Enum goalEnum = EnumRegistry.getEnum(questGoal.getType(), EnumRegistry.getQuestGoal()); 37 | 38 | questGoalList.add(questGoal); 39 | LocateHash.registerQuestTypeLocation(goalEnum, path); 40 | } 41 | 42 | userQuest.setQuestGoals(questGoalList); 43 | LocateHash.registerQuestByID(userQuest.getId(), path); 44 | 45 | return userQuest; 46 | } 47 | 48 | public String getId() { 49 | return id; 50 | } 51 | 52 | public void setId(String id) { 53 | this.id = id; 54 | } 55 | 56 | public String getTitle() { 57 | return title; 58 | } 59 | 60 | public void setTitle(String title) { 61 | this.title = title; 62 | } 63 | 64 | public boolean isCompleted() { 65 | return completed; 66 | } 67 | 68 | public void setCompleted(boolean completed) { 69 | this.completed = completed; 70 | } 71 | 72 | public List getQuestGoals() { 73 | return questGoals; 74 | } 75 | 76 | public void setQuestGoals(List questGoals) { 77 | this.questGoals = questGoals; 78 | } 79 | 80 | public boolean hasTimeLimit() { 81 | return timeLimit; 82 | } 83 | 84 | public void setTimeLimit(boolean timeLimit) { 85 | this.timeLimit = timeLimit; 86 | } 87 | 88 | public int getTimeLimitInSeconds() { 89 | return timeLimitInSeconds; 90 | } 91 | 92 | public void setTimeLimitInSeconds(int timeLimitInSeconds) { 93 | this.timeLimitInSeconds = timeLimitInSeconds; 94 | } 95 | } 96 | 97 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/quest/register/LoadQuest.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.quest.register; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonObject; 5 | import dev.zanckor.api.filemanager.FolderManager; 6 | import dev.zanckor.api.filemanager.quest.codec.server.ServerQuest; 7 | import dev.zanckor.mod.common.datapack.QuestJSONListener; 8 | import dev.zanckor.mod.common.util.GsonManager; 9 | import net.minecraft.resources.ResourceLocation; 10 | import net.minecraft.server.MinecraftServer; 11 | import net.minecraft.server.packs.resources.ResourceManager; 12 | import net.minecraft.world.level.storage.LevelResource; 13 | 14 | import java.io.*; 15 | import java.nio.file.Path; 16 | import java.util.Map; 17 | 18 | import static dev.zanckor.mod.QuestApiMain.serverQuests; 19 | 20 | public class LoadQuest { 21 | 22 | /** 23 | * Each time that server starts running, registerquest is called to copy resource's quest files to minecraft folder. 24 | */ 25 | 26 | 27 | static ServerQuest playerQuest; 28 | 29 | public static void registerQuest(MinecraftServer server, String modid) { 30 | ResourceManager resourceManager = server.getResourceManager(); 31 | 32 | if (serverQuests == null) { 33 | FolderManager.createAPIFolder(server.getWorldPath(LevelResource.ROOT).toAbsolutePath()); 34 | } 35 | 36 | resourceManager.listResources("quest", (file) -> { 37 | if (file.getPath().length() > 7) { 38 | String fileName = file.getPath().substring(6); 39 | ResourceLocation resourceLocation = new ResourceLocation(modid, file.getPath()); 40 | if(!modid.equals(file.getNamespace())) return false; 41 | 42 | if (file.getPath().endsWith(".json")) { 43 | read(resourceLocation, resourceManager); 44 | write(playerQuest, fileName, modid); 45 | } else { 46 | throw new RuntimeException("File " + fileName + " in " + file.getPath() + " is not .json"); 47 | } 48 | } 49 | 50 | return false; 51 | }); 52 | } 53 | 54 | public static void registerDatapackQuest(MinecraftServer server) throws IOException { 55 | if (serverQuests == null) { 56 | FolderManager.createAPIFolder(server.getWorldPath(LevelResource.ROOT).toAbsolutePath()); 57 | } 58 | 59 | for (Map.Entry entry : QuestJSONListener.datapackQuestList.entrySet()) { 60 | FileWriter writer = new FileWriter(String.valueOf(Path.of(serverQuests + "/" + entry.getKey()))); 61 | writer.write(entry.getValue().toString()); 62 | writer.close(); 63 | } 64 | } 65 | 66 | private static void read(ResourceLocation resourceLocation, ResourceManager resourceManager) { 67 | try { 68 | if(!resourceManager.getResource(resourceLocation).isPresent()) return; 69 | 70 | InputStream inputStream = resourceManager.getResource(resourceLocation).get().open(); 71 | playerQuest = GsonManager.gson.fromJson(new InputStreamReader(inputStream), ServerQuest.class); 72 | 73 | } catch (IOException e) { 74 | throw new RuntimeException(e); 75 | } 76 | } 77 | 78 | private static void write(ServerQuest serverQuest, String fileName, String identifier) { 79 | try { 80 | if(serverQuest == null) return; 81 | 82 | File file = new File(serverQuests.toFile(), identifier + "." + fileName); 83 | serverQuest.setId(identifier + "." + fileName.substring(0, fileName.length() - 5)); 84 | GsonManager.writeJson(file, serverQuest); 85 | } catch (IOException e) { 86 | throw new RuntimeException(e); 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/filemanager/quest/register/QuestTemplateRegistry.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.filemanager.quest.register; 2 | 3 | import dev.zanckor.api.enuminterface.enumdialog.IEnumDialogOption; 4 | import dev.zanckor.api.enuminterface.enumdialog.IEnumDialogReq; 5 | import dev.zanckor.api.enuminterface.enumquest.IEnumQuestGoal; 6 | import dev.zanckor.api.enuminterface.enumquest.IEnumQuestRequirement; 7 | import dev.zanckor.api.enuminterface.enumquest.IEnumQuestReward; 8 | import dev.zanckor.api.enuminterface.enumquest.IEnumTargetType; 9 | import dev.zanckor.api.filemanager.dialog.abstractdialog.AbstractDialogOption; 10 | import dev.zanckor.api.filemanager.dialog.abstractdialog.AbstractDialogRequirement; 11 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractGoal; 12 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractQuestRequirement; 13 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractReward; 14 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractTargetType; 15 | import dev.zanckor.example.common.handler.targettype.DefaultTargetType; 16 | 17 | import java.util.HashMap; 18 | 19 | public class QuestTemplateRegistry { 20 | 21 | /** 22 | * This class stores quest types, reward types, requirement types... as temporary data to improve access time. 23 | * You should use these methods to add your own quests. 24 | */ 25 | 26 | 27 | private static HashMap quest_goal = new HashMap<>(); 28 | private static HashMap quest_reward = new HashMap<>(); 29 | private static HashMap quest_requirement = new HashMap<>(); 30 | private static HashMap dialog_requirement = new HashMap<>(); 31 | private static HashMap dialog_template = new HashMap<>(); 32 | 33 | private static HashMap target_type = new HashMap<>(); 34 | 35 | public static void registerQuest(IEnumQuestGoal key) { 36 | quest_goal.put((Enum) key, key.getQuest()); 37 | } 38 | public static void registerDialogOption(IEnumDialogOption key) { 39 | dialog_template.put((Enum) key, key.getDialogOption()); 40 | } 41 | public static void registerReward(IEnumQuestReward key) { 42 | quest_reward.put((Enum) key, key.getReward()); 43 | } 44 | public static void registerQuestRequirement(IEnumQuestRequirement key) { 45 | quest_requirement.put((Enum) key, key.getRequirement()); 46 | } 47 | public static void registerDialogRequirement(IEnumDialogReq key) { 48 | dialog_requirement.put((Enum) key, key.getDialogRequirement()); 49 | } 50 | public static void registerTargetType(IEnumTargetType key) { 51 | target_type.put((Enum) key, key.getTargetType()); 52 | } 53 | 54 | 55 | 56 | 57 | public static AbstractGoal getQuestTemplate(Enum key) { 58 | try { 59 | return quest_goal.get(key); 60 | } catch (NullPointerException e) { 61 | throw new RuntimeException("Incorrect quest key: " + key); 62 | } 63 | } 64 | public static HashMap getAllGoals() { 65 | return quest_goal; 66 | } 67 | public static AbstractDialogOption getDialogTemplate(Enum key) { 68 | try { 69 | return dialog_template.get(key); 70 | } catch (NullPointerException e) { 71 | throw new RuntimeException("Incorrect quest key: " + key); 72 | } 73 | } 74 | public static AbstractReward getQuestReward(Enum key) { 75 | try { 76 | return quest_reward.get(key); 77 | } catch (NullPointerException e) { 78 | throw new RuntimeException("Incorrect reward key: " + key); 79 | } 80 | } 81 | public static AbstractQuestRequirement getQuestRequirement(Enum key) { 82 | try { 83 | return quest_requirement.get(key); 84 | } catch (NullPointerException e) { 85 | throw new RuntimeException("Incorrect requirement key: " + key); 86 | } 87 | } 88 | public static AbstractDialogRequirement getDialogRequirement(Enum key) { 89 | try { 90 | return dialog_requirement.get(key); 91 | } catch (NullPointerException e) { 92 | throw new RuntimeException("Incorrect requirement key: " + key); 93 | } 94 | } 95 | public static AbstractTargetType getTranslatableTargetType(Enum key) { 96 | return target_type.getOrDefault(key, new DefaultTargetType()); 97 | } 98 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/api/screen/ScreenRegistry.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.api.screen; 2 | 3 | import dev.zanckor.mod.QuestApiMain; 4 | import dev.zanckor.mod.client.screen.abstractscreen.AbstractDialog; 5 | import dev.zanckor.mod.client.screen.abstractscreen.AbstractQuestLog; 6 | import dev.zanckor.mod.client.screen.abstractscreen.AbstractQuestTracked; 7 | 8 | import java.util.HashMap; 9 | 10 | public class ScreenRegistry { 11 | /** 12 | * This class has registries whichever screen you want to display to screens 13 | */ 14 | 15 | private static HashMap dialog = new HashMap<>(); 16 | private static HashMap tracked_screen = new HashMap<>(); 17 | private static HashMap quest_log_screen = new HashMap<>(); 18 | 19 | 20 | /** 21 | * Registry dialog - Display dialog screen 22 | */ 23 | public static void registerDialogScreen(String identifier, AbstractDialog screen) { 24 | dialog.put(identifier, screen); 25 | } 26 | 27 | public static AbstractDialog getDialogScreen(String identifier) { 28 | AbstractDialog abstractDialog = dialog.get(identifier); 29 | 30 | if (abstractDialog != null) { 31 | return abstractDialog; 32 | } 33 | 34 | errorMessage(identifier); 35 | return dialog.get(QuestApiMain.MOD_ID); 36 | } 37 | 38 | /** 39 | * Registry quest tracked screen - Display tracked quest data on HUD 40 | */ 41 | 42 | public static void registerQuestTrackedScreen(String identifier, AbstractQuestTracked screen) { 43 | tracked_screen.put(identifier, screen); 44 | } 45 | 46 | public static AbstractQuestTracked getQuestTrackedScreen(String identifier) { 47 | AbstractQuestTracked trackedScreen = tracked_screen.get(identifier); 48 | 49 | if (trackedScreen != null) { 50 | return trackedScreen; 51 | } 52 | 53 | errorMessage(identifier); 54 | return tracked_screen.get(QuestApiMain.MOD_ID); 55 | } 56 | 57 | 58 | /** 59 | * Registry quest log screen - Shows active quest and quest data 60 | */ 61 | public static void registerQuestLogScreen(String identifier, AbstractQuestLog screen) { 62 | quest_log_screen.put(identifier, screen); 63 | } 64 | 65 | public static AbstractQuestLog getQuestLogScreen(String identifier) { 66 | AbstractQuestLog questLogScreen = quest_log_screen.get(identifier); 67 | 68 | if (questLogScreen != null) { 69 | return questLogScreen; 70 | } 71 | 72 | errorMessage(identifier); 73 | return quest_log_screen.get(QuestApiMain.MOD_ID); 74 | } 75 | 76 | 77 | private static void errorMessage(String identifier) { 78 | QuestApiMain.LOGGER.error("Your identifier " + identifier + " is incorrect or you have no screen registered"); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/ClientModSetup.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example; 2 | 3 | import dev.zanckor.example.common.entity.NpcTypes; 4 | import dev.zanckor.example.common.entity.client.NPCRenderer; 5 | import dev.zanckor.mod.QuestApiMain; 6 | import net.minecraft.client.renderer.entity.EntityRenderers; 7 | import net.minecraftforge.api.distmarker.Dist; 8 | import net.minecraftforge.eventbus.api.SubscribeEvent; 9 | import net.minecraftforge.fml.common.Mod; 10 | import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; 11 | 12 | 13 | @Mod.EventBusSubscriber(modid = QuestApiMain.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) 14 | public class ClientModSetup { 15 | 16 | @SubscribeEvent 17 | public static void registerOverlays(FMLClientSetupEvent e) { 18 | EntityRenderers.register(NpcTypes.NPC_ENTITY.get(), NPCRenderer::new); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/client/screen/button/TextButton.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.client.screen.button; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import dev.zanckor.mod.common.util.MCUtilClient; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.client.gui.GuiGraphics; 7 | import net.minecraft.client.gui.components.Button; 8 | import net.minecraft.network.chat.Component; 9 | import net.minecraft.network.chat.MutableComponent; 10 | import net.minecraft.network.chat.Style; 11 | 12 | public class TextButton extends Button { 13 | float scale; 14 | int maxLength; 15 | 16 | public TextButton(int xPosition, int yPosition, int width, int height, float scale, Component component, int maxLength, OnPress onPress) { 17 | super(xPosition, yPosition, width, height, component, onPress, DEFAULT_NARRATION); 18 | this.scale = scale; 19 | this.maxLength = maxLength; 20 | } 21 | 22 | 23 | @Override 24 | public void render(GuiGraphics graphics, int xPos, int yPos, float v) { 25 | PoseStack poseStack = graphics.pose(); 26 | Style style = !isMouseOver(xPos, yPos) ? getMessage().getStyle() : getMessage().getStyle().withUnderlined(true); 27 | 28 | poseStack.pushPose(); 29 | poseStack.translate(this.getX(), this.getY(), 0); 30 | poseStack.scale(scale, scale, 1); 31 | 32 | MCUtilClient.renderLine(graphics, poseStack, 16, 0, maxLength, Component.literal(getMessage().getString()).withStyle(style), Minecraft.getInstance().font); 33 | poseStack.popPose(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/client/screen/hud/QuestTrackedTimer.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.client.screen.hud; 2 | 3 | import dev.zanckor.mod.QuestApiMain; 4 | import dev.zanckor.mod.common.network.handler.ClientHandler; 5 | import dev.zanckor.mod.common.util.Timer; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraftforge.api.distmarker.Dist; 8 | import net.minecraftforge.event.TickEvent; 9 | import net.minecraftforge.eventbus.api.SubscribeEvent; 10 | import net.minecraftforge.fml.common.Mod; 11 | 12 | import java.io.IOException; 13 | 14 | import static dev.zanckor.mod.common.network.handler.ClientHandler.trackedQuestList; 15 | 16 | @Mod.EventBusSubscriber(modid = QuestApiMain.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT) 17 | public class QuestTrackedTimer { 18 | @SubscribeEvent 19 | public static void tickEvent(TickEvent e) throws IOException { 20 | Minecraft mc = Minecraft.getInstance(); 21 | if (mc.player == null || trackedQuestList.isEmpty() || !(e.phase.equals(TickEvent.Phase.START))) { 22 | return; 23 | } 24 | 25 | ClientHandler.trackedQuestList.forEach(quest -> { 26 | if (mc.player.tickCount % 20 == 0 && quest.hasTimeLimit() && Timer.existsTimer(mc.player.getUUID(), "TIMER_QUEST" + quest.getId()) && quest.getTimeLimitInSeconds() > 0) { 27 | quest.setTimeLimitInSeconds((int) Timer.remainingTime(mc.player.getUUID(), "TIMER_QUEST" + quest.getId()) / 1000); 28 | } 29 | }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/entity/NpcTypes.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.entity; 2 | 3 | import dev.zanckor.example.common.entity.server.NPCEntity; 4 | import dev.zanckor.mod.QuestApiMain; 5 | import net.minecraft.resources.ResourceLocation; 6 | import net.minecraft.world.entity.EntityType; 7 | import net.minecraft.world.entity.MobCategory; 8 | import net.minecraftforge.eventbus.api.IEventBus; 9 | import net.minecraftforge.registries.DeferredRegister; 10 | import net.minecraftforge.registries.ForgeRegistries; 11 | import net.minecraftforge.registries.RegistryObject; 12 | 13 | public class NpcTypes { 14 | public static final DeferredRegister> 15 | ENTITY_TYPES = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, QuestApiMain.MOD_ID); 16 | 17 | 18 | public static final RegistryObject> NPC_ENTITY = ENTITY_TYPES.register("quest_npc", 19 | () -> EntityType.Builder.of(NPCEntity::new, MobCategory.AMBIENT) 20 | .build(new ResourceLocation(QuestApiMain.MOD_ID, "quest_npc").toString())); 21 | 22 | 23 | public static void register(IEventBus eventBus) { 24 | ENTITY_TYPES.register(eventBus); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/entity/client/NPCRenderer.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.entity.client; 2 | 3 | import net.minecraft.client.renderer.entity.*; 4 | import net.minecraft.client.renderer.entity.player.PlayerRenderer; 5 | 6 | public class NPCRenderer extends VillagerRenderer { 7 | public NPCRenderer(EntityRendererProvider.Context ctx) { 8 | super(ctx); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/entity/server/NPCEntity.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.entity.server; 2 | 3 | import dev.zanckor.mod.server.startdialog.StartDialog; 4 | import net.minecraft.world.InteractionHand; 5 | import net.minecraft.world.InteractionResult; 6 | import net.minecraft.world.entity.EntityType; 7 | import net.minecraft.world.entity.Mob; 8 | import net.minecraft.world.entity.ai.attributes.AttributeSupplier; 9 | import net.minecraft.world.entity.ai.attributes.Attributes; 10 | import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal; 11 | import net.minecraft.world.entity.npc.Villager; 12 | import net.minecraft.world.entity.player.Player; 13 | import net.minecraft.world.level.Level; 14 | 15 | import java.io.IOException; 16 | 17 | public class NPCEntity extends Villager { 18 | private String dialogID = "questapi.secondary_collect_items_dialog"; 19 | 20 | public NPCEntity(EntityType entityType, Level level) { 21 | super(entityType, level); 22 | this.setInvulnerable(true); 23 | } 24 | 25 | 26 | @Override 27 | public InteractionResult mobInteract(Player player, InteractionHand interactionHand) { 28 | if (!player.level().isClientSide && interactionHand.equals(InteractionHand.MAIN_HAND)) { 29 | try { 30 | StartDialog.loadDialog(player, dialogID, "minecraft:cow"); 31 | } catch (IOException e) { 32 | throw new RuntimeException(e); 33 | } 34 | } 35 | 36 | return super.mobInteract(player, interactionHand); 37 | } 38 | 39 | 40 | protected void registerGoals() { 41 | this.goalSelector.addGoal(0, new LookAtPlayerGoal(this, Player.class, 8.0F)); 42 | } 43 | 44 | public static AttributeSupplier setAttributes() { 45 | return Mob.createMobAttributes() 46 | .add(Attributes.MAX_HEALTH, Integer.MAX_VALUE) 47 | .add(Attributes.MOVEMENT_SPEED, 0) 48 | .build(); 49 | } 50 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/enumregistry/EnumRegistry.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.enumregistry; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | public class EnumRegistry { 9 | static List enumDialogOption = new ArrayList<>(); 10 | static List enumDialogRequirement = new ArrayList<>(); 11 | 12 | static List enumQuestRequirement = new ArrayList<>(); 13 | static List enumQuestReward = new ArrayList<>(); 14 | static List enumQuestGoal = new ArrayList<>(); 15 | static List enumTargetType = new ArrayList<>(); 16 | 17 | 18 | public static void registerDialogOption(Class enumClass) { 19 | enumDialogOption.add(enumClass); 20 | } 21 | 22 | public static void registerDialogRequirement(Class enumClass) { 23 | enumDialogRequirement.add(enumClass); 24 | } 25 | 26 | public static void registerQuestRequirement(Class enumClass) { 27 | enumQuestRequirement.add(enumClass); 28 | } 29 | 30 | public static void registerQuestReward(Class enumClass) { 31 | enumQuestReward.add(enumClass); 32 | } 33 | 34 | public static void registerQuestGoal(Class enumClass) { 35 | enumQuestGoal.add(enumClass); 36 | } 37 | 38 | public static void registerTargetType(Class enumClass) { 39 | enumTargetType.add(enumClass); 40 | } 41 | 42 | 43 | public static List getDialogOption() { 44 | return enumDialogOption; 45 | } 46 | public static List getDialogRequirement() { 47 | return enumDialogRequirement; 48 | } 49 | 50 | public static List getQuestRequirement() { 51 | return enumQuestRequirement; 52 | } 53 | 54 | public static List getQuestReward() { 55 | return enumQuestReward; 56 | } 57 | 58 | public static List getQuestGoal() { 59 | return enumQuestGoal; 60 | } 61 | 62 | public static List getTargetType() { 63 | return enumTargetType; 64 | } 65 | 66 | 67 | public static Enum getEnum(String enumString, List enumRegistry) { 68 | Enum anEnum; 69 | 70 | for (Class enumClass : enumRegistry){ 71 | Object[] enumValues = enumClass.getEnumConstants(); 72 | 73 | for(Object enumValue : enumValues){ 74 | if(enumValue.toString().equalsIgnoreCase(enumString)){ 75 | anEnum = Enum.valueOf(enumClass, enumString); 76 | 77 | return anEnum; 78 | } 79 | } 80 | } 81 | 82 | return null; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/enumregistry/enumdialog/EnumDialogOption.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.enumregistry.enumdialog; 2 | 3 | import dev.zanckor.api.enuminterface.enumdialog.IEnumDialogOption; 4 | import dev.zanckor.api.filemanager.dialog.abstractdialog.AbstractDialogOption; 5 | import dev.zanckor.example.common.handler.dialogoption.DialogAddQuest; 6 | import dev.zanckor.example.common.handler.dialogoption.DialogCloseDialog; 7 | import dev.zanckor.example.common.handler.dialogoption.DialogOpenDialog; 8 | 9 | public enum EnumDialogOption implements IEnumDialogOption { 10 | OPEN_DIALOG(new DialogOpenDialog()), 11 | CLOSE_DIALOG(new DialogCloseDialog()), 12 | ADD_QUEST(new DialogAddQuest()); 13 | 14 | AbstractDialogOption dialogOption; 15 | 16 | EnumDialogOption(AbstractDialogOption abstractDialogOption) { 17 | dialogOption = abstractDialogOption; 18 | registerEnumDialogOption(this.getClass()); 19 | } 20 | 21 | @Override 22 | public AbstractDialogOption getDialogOption() { 23 | return dialogOption; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/enumregistry/enumdialog/EnumDialogReq.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.enumregistry.enumdialog; 2 | 3 | import dev.zanckor.api.enuminterface.enumdialog.IEnumDialogReq; 4 | import dev.zanckor.api.filemanager.dialog.abstractdialog.AbstractDialogRequirement; 5 | import dev.zanckor.example.common.handler.dialogrequirement.DialogRequirement; 6 | import dev.zanckor.example.common.handler.dialogrequirement.QuestRequirement; 7 | 8 | public enum EnumDialogReq implements IEnumDialogReq { 9 | QUEST(new QuestRequirement()), 10 | DIALOG(new DialogRequirement()); 11 | 12 | 13 | AbstractDialogRequirement dialogRequirement; 14 | EnumDialogReq(AbstractDialogRequirement abstractDialogRequirement) { 15 | dialogRequirement = abstractDialogRequirement; 16 | registerEnumDialogReq(this.getClass()); 17 | } 18 | 19 | @Override 20 | public AbstractDialogRequirement getDialogRequirement() { 21 | return dialogRequirement; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/enumregistry/enumdialog/EnumDialogReqStatus.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.enumregistry.enumdialog; 2 | 3 | public enum EnumDialogReqStatus { 4 | NOT_OBTAINED, 5 | IN_PROGRESS, 6 | COMPLETED, 7 | 8 | READ, 9 | NOT_READ 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/enumregistry/enumquest/EnumGoalType.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.enumregistry.enumquest; 2 | 3 | 4 | import dev.zanckor.api.enuminterface.enumquest.IEnumQuestGoal; 5 | import dev.zanckor.api.enuminterface.enumquest.IEnumTargetType; 6 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractGoal; 7 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractTargetType; 8 | import dev.zanckor.example.common.handler.questgoal.*; 9 | import dev.zanckor.example.common.handler.targettype.EntityTargetType; 10 | import dev.zanckor.example.common.handler.targettype.ItemTargetType; 11 | import dev.zanckor.example.common.handler.targettype.MoveToTargetType; 12 | import dev.zanckor.example.common.handler.targettype.XPTargetType; 13 | 14 | public enum EnumGoalType implements IEnumQuestGoal { 15 | INTERACT_ENTITY(new InteractEntityGoal()), 16 | KILL(new KillGoal()), 17 | MOVE_TO(new MoveToGoal()), 18 | COLLECT(new CollectGoal()), 19 | COLLECT_WITH_NBT(new CollectNBTGoal()), 20 | XP(new XpGoal()); 21 | 22 | 23 | AbstractGoal goal; 24 | 25 | EnumGoalType(AbstractGoal abstractGoal) { 26 | this.goal = abstractGoal; 27 | registerEnumGoal(this.getClass()); 28 | } 29 | 30 | @Override 31 | public AbstractGoal getQuest() { 32 | return goal; 33 | } 34 | 35 | 36 | public enum EnumTargetType implements IEnumTargetType { 37 | TARGET_TYPE_INTERACT_ENTITY(new EntityTargetType()), 38 | TARGET_TYPE_KILL(new EntityTargetType()), 39 | TARGET_TYPE_MOVE_TO(new MoveToTargetType()), 40 | TARGET_TYPE_COLLECT(new ItemTargetType()), 41 | TARGET_TYPE_COLLECT_WITH_NBT(new ItemTargetType()), 42 | TARGET_TYPE_XP(new XPTargetType()); 43 | 44 | AbstractTargetType targetType; 45 | 46 | EnumTargetType(AbstractTargetType targetType) { 47 | this.targetType = targetType; 48 | registerTargetType(this.getClass()); 49 | } 50 | 51 | @Override 52 | public AbstractTargetType getTargetType() { 53 | return targetType; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/enumregistry/enumquest/EnumQuestRequirement.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.enumregistry.enumquest; 2 | 3 | import dev.zanckor.api.enuminterface.enumquest.IEnumQuestRequirement; 4 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractQuestRequirement; 5 | import dev.zanckor.example.common.handler.questrequirement.XpRequirement; 6 | 7 | public enum EnumQuestRequirement implements IEnumQuestRequirement { 8 | XP(new XpRequirement()); 9 | 10 | AbstractQuestRequirement questRequirement; 11 | 12 | EnumQuestRequirement(AbstractQuestRequirement abstractQuestRequirement) { 13 | questRequirement = abstractQuestRequirement; 14 | registerEnumQuestReq(this.getClass()); 15 | } 16 | 17 | @Override 18 | public AbstractQuestRequirement getRequirement() { 19 | return questRequirement; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/enumregistry/enumquest/EnumQuestReward.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.enumregistry.enumquest; 2 | 3 | import dev.zanckor.api.enuminterface.enumquest.IEnumQuestReward; 4 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractReward; 5 | import dev.zanckor.example.common.handler.questreward.*; 6 | 7 | public enum EnumQuestReward implements IEnumQuestReward { 8 | ITEM(new ItemReward()), 9 | COMMAND(new CommandReward()), 10 | QUEST(new QuestReward()), 11 | XP(new XpReward()), LEVEL(new XpReward()), POINTS(new XpReward()), 12 | LOOT_TABLE(new LootTableReward()); 13 | 14 | AbstractReward reward; 15 | 16 | EnumQuestReward(AbstractReward reward) { 17 | this.reward = reward; 18 | registerEnumReward(this.getClass()); 19 | } 20 | 21 | @Override 22 | public AbstractReward getReward() { 23 | return reward; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/dialogoption/DialogCloseDialog.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.dialogoption; 2 | 3 | import dev.zanckor.api.database.LocateHash; 4 | import dev.zanckor.api.filemanager.dialog.abstractdialog.AbstractDialogOption; 5 | import dev.zanckor.api.filemanager.dialog.codec.NPCConversation; 6 | import dev.zanckor.api.filemanager.dialog.codec.NPCDialog; 7 | import dev.zanckor.example.common.enumregistry.enumdialog.EnumDialogOption; 8 | import dev.zanckor.mod.common.network.SendQuestPacket; 9 | import dev.zanckor.mod.common.network.message.dialogoption.CloseDialog; 10 | import net.minecraft.resources.ResourceLocation; 11 | import net.minecraft.world.entity.Entity; 12 | import net.minecraft.world.entity.player.Player; 13 | import net.minecraft.world.item.Item; 14 | 15 | import java.io.IOException; 16 | 17 | public class DialogCloseDialog extends AbstractDialogOption { 18 | 19 | /** 20 | * When player clicks on an option which type is "CLOSE_DIALOG" will close the screen. 21 | * 22 | * @param player The player 23 | * @param dialog DialogTemplate class with all dialog data 24 | * @param option_id DialogOption ID, Returns the object inside the List DialogOption. This is not a parameter inside the .json file 25 | * @throws IOException Exception fired when server cannot read json file 26 | */ 27 | 28 | @Override 29 | public void handler(Player player, NPCConversation dialog, int option_id, Entity entity) throws IOException { 30 | int currentDialog = LocateHash.currentDialog.get(player); 31 | NPCDialog.DialogOption option = dialog.getDialog().get(currentDialog).getOptions().get(option_id); 32 | 33 | if (option.getType().equals(EnumDialogOption.CLOSE_DIALOG.toString())) { 34 | SendQuestPacket.TO_CLIENT(player, new CloseDialog()); 35 | } 36 | } 37 | 38 | @Override 39 | public void handler(Player player, NPCConversation dialog, int option_id, String resourceLocation) throws IOException { 40 | handler(player, dialog, option_id, (Entity) null); 41 | } 42 | 43 | @Override 44 | public void handler(Player player, NPCConversation dialog, int option_id, Item item) throws IOException { 45 | handler(player, dialog, option_id, (Entity) null); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/dialogoption/DialogOpenDialog.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.dialogoption; 2 | 3 | import dev.zanckor.api.database.LocateHash; 4 | import dev.zanckor.api.filemanager.dialog.abstractdialog.AbstractDialogOption; 5 | import dev.zanckor.api.filemanager.dialog.codec.NPCConversation; 6 | import dev.zanckor.api.filemanager.dialog.codec.NPCDialog; 7 | import dev.zanckor.example.common.enumregistry.enumdialog.EnumDialogOption; 8 | import dev.zanckor.mod.common.network.SendQuestPacket; 9 | import dev.zanckor.mod.common.network.message.dialogoption.DisplayDialog; 10 | import net.minecraft.resources.ResourceLocation; 11 | import net.minecraft.world.entity.Entity; 12 | import net.minecraft.world.entity.player.Player; 13 | import net.minecraft.world.item.Item; 14 | 15 | import java.io.IOException; 16 | 17 | public class DialogOpenDialog extends AbstractDialogOption { 18 | 19 | /** 20 | * When player clicks on an option which type is "OPEN_DIALOG" will try to change current screen to the dialog specified on that option. 21 | * 22 | * @param player The player 23 | * @param dialog DialogTemplate class with all dialog data 24 | * @param option_id DialogOption ID, Returns the object inside the List DialogOption. This is not a parameter inside the .json file 25 | * @throws IOException Exception fired when server cannot read json file 26 | */ 27 | 28 | @Override 29 | public void handler(Player player, NPCConversation dialog, int option_id, Entity entity) throws IOException { 30 | int currentDialog = LocateHash.currentDialog.get(player); 31 | NPCDialog.DialogOption option = dialog.getDialog().get(currentDialog).getOptions().get(option_id); 32 | 33 | if (option.getType().equals(EnumDialogOption.OPEN_DIALOG.toString())) { 34 | SendQuestPacket.TO_CLIENT(player, new DisplayDialog(dialog, dialog.getIdentifier(), option.getDialog(), player, entity)); 35 | } 36 | } 37 | 38 | @Override 39 | public void handler(Player player, NPCConversation dialog, int option_id, String resourceLocation) throws IOException { 40 | int currentDialog = LocateHash.currentDialog.get(player); 41 | NPCDialog.DialogOption option = dialog.getDialog().get(currentDialog).getOptions().get(option_id); 42 | 43 | if (option.getType().equals(EnumDialogOption.OPEN_DIALOG.toString())) { 44 | SendQuestPacket.TO_CLIENT(player, new DisplayDialog(dialog, dialog.getIdentifier(), option.getDialog(), player, resourceLocation)); 45 | } 46 | } 47 | 48 | @Override 49 | public void handler(Player player, NPCConversation dialog, int option_id, Item item) throws IOException { 50 | int currentDialog = LocateHash.currentDialog.get(player); 51 | NPCDialog.DialogOption option = dialog.getDialog().get(currentDialog).getOptions().get(option_id); 52 | 53 | if (option.getType().equals(EnumDialogOption.OPEN_DIALOG.toString())) { 54 | SendQuestPacket.TO_CLIENT(player, new DisplayDialog(dialog, dialog.getIdentifier(), option.getDialog(), player, item)); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/questgoal/CollectGoal.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.questgoal; 2 | 3 | import com.google.gson.Gson; 4 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractGoal; 5 | import dev.zanckor.api.filemanager.quest.codec.user.UserGoal; 6 | import dev.zanckor.api.filemanager.quest.codec.user.UserQuest; 7 | import dev.zanckor.mod.common.network.SendQuestPacket; 8 | import dev.zanckor.mod.common.network.message.screen.UpdateQuestTracked; 9 | import dev.zanckor.mod.common.util.GsonManager; 10 | import dev.zanckor.mod.common.util.MCUtil; 11 | import net.minecraft.resources.ResourceLocation; 12 | import net.minecraft.server.level.ServerPlayer; 13 | import net.minecraft.world.entity.Entity; 14 | import net.minecraft.world.item.Item; 15 | import net.minecraft.world.item.ItemStack; 16 | import net.minecraftforge.registries.ForgeRegistries; 17 | 18 | import java.io.File; 19 | import java.io.FileWriter; 20 | import java.io.IOException; 21 | 22 | import static dev.zanckor.example.common.enumregistry.enumquest.EnumGoalType.COLLECT; 23 | 24 | public class CollectGoal extends AbstractGoal { 25 | 26 | public void handler(ServerPlayer player, Entity entity, Gson gson, File file, UserQuest userQuest, int indexGoal, Enum questType) throws IOException { 27 | String questID = userQuest.getId(); 28 | userQuest = (UserQuest) GsonManager.getJsonClass(file, UserQuest.class); 29 | if (userQuest == null || (!(questID.equals(userQuest.getId())))) return; 30 | 31 | updateData(player, file); 32 | super.handler(player, entity, gson, file, userQuest, indexGoal, questType); 33 | } 34 | 35 | @Override 36 | public void enhancedCompleteQuest(ServerPlayer player, File file, UserGoal userGoal) throws IOException { 37 | UserQuest userQuest = (UserQuest) GsonManager.getJsonClass(file, UserQuest.class); 38 | if (userQuest == null) return; 39 | 40 | if (MCUtil.isQuestCompleted(userQuest)) { 41 | removeItems(player, userGoal); 42 | } 43 | } 44 | 45 | public static void removeItems(ServerPlayer player, UserGoal goalEnhanced) { 46 | if (!(goalEnhanced.getType().equals(COLLECT.name()))) return; 47 | 48 | 49 | String valueItem = goalEnhanced.getTarget(); 50 | Item itemTarget = ForgeRegistries.ITEMS.getValue(new ResourceLocation(valueItem)); 51 | 52 | int itemSlot = player.getInventory().findSlotMatchingItem(itemTarget.getDefaultInstance()); 53 | 54 | if (itemSlot < 0) return; 55 | player.getInventory().removeItem(itemSlot, goalEnhanced.getAmount()); 56 | } 57 | 58 | public void updateData(ServerPlayer player, File file) throws IOException { 59 | UserQuest userQuest = (UserQuest) GsonManager.getJsonClass(file, UserQuest.class); 60 | if (userQuest == null) return; 61 | 62 | for (UserGoal questGoal : userQuest.getQuestGoals()) { 63 | if (!(questGoal.getType().equals(COLLECT.name()))) continue; 64 | 65 | int itemCount; 66 | String valueItem = questGoal.getTarget(); 67 | Item itemTarget = ForgeRegistries.ITEMS.getValue(new ResourceLocation(valueItem)); 68 | 69 | 70 | //Checks inventory's items 71 | if (!player.getInventory().contains(itemTarget.getDefaultInstance())) { 72 | questGoal.setCurrentAmount(0); 73 | } else { 74 | int itemSlot = player.getInventory().findSlotMatchingItem(itemTarget.getDefaultInstance()); 75 | ItemStack item = player.getInventory().getItem(itemSlot); 76 | itemCount = item.getCount() > questGoal.getAmount() ? questGoal.getAmount() : item.getCount(); 77 | 78 | questGoal.setCurrentAmount(itemCount); 79 | } 80 | 81 | GsonManager.writeJson(file, userQuest); 82 | } 83 | } 84 | 85 | @Override 86 | public Enum getGoalType() { 87 | return COLLECT; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/questgoal/InteractEntityGoal.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.questgoal; 2 | 3 | import com.google.gson.Gson; 4 | import dev.zanckor.api.filemanager.quest.codec.user.UserGoal; 5 | import dev.zanckor.api.filemanager.quest.codec.user.UserQuest; 6 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractGoal; 7 | import dev.zanckor.mod.common.network.SendQuestPacket; 8 | import dev.zanckor.mod.common.network.message.screen.UpdateQuestTracked; 9 | import dev.zanckor.mod.common.util.GsonManager; 10 | import dev.zanckor.mod.common.util.MCUtil; 11 | import net.minecraft.server.level.ServerPlayer; 12 | import net.minecraft.world.entity.Entity; 13 | import net.minecraft.world.entity.EntityType; 14 | 15 | import java.io.File; 16 | import java.io.FileWriter; 17 | import java.io.IOException; 18 | 19 | import static dev.zanckor.example.common.enumregistry.enumquest.EnumGoalType.INTERACT_ENTITY; 20 | 21 | public class InteractEntityGoal extends AbstractGoal { 22 | 23 | public void handler(ServerPlayer player, Entity entity, Gson gson, File file, UserQuest userQuest, int indexGoal, Enum questType) throws IOException { 24 | userQuest = (UserQuest) GsonManager.getJsonClass(file, UserQuest.class); 25 | UserGoal questGoal = userQuest.getQuestGoals().get(indexGoal); 26 | 27 | //Checks if interacted entity equals to target and if it is, checks if current progress is more than target amount 28 | if (questGoal.getCurrentAmount() >= questGoal.getAmount() || !(questGoal.getTarget().equals(EntityType.getKey(entity.getType()).toString()))) 29 | return; 30 | 31 | questGoal.incrementCurrentAmount(1); 32 | GsonManager.writeJson(file, userQuest); 33 | 34 | userQuest = (UserQuest) GsonManager.getJsonClass(file, UserQuest.class); 35 | super.handler(player, entity, gson, file, userQuest, indexGoal, questType); 36 | } 37 | 38 | @Override 39 | public void enhancedCompleteQuest(ServerPlayer player, File file, UserGoal userGoal) { 40 | 41 | } 42 | 43 | @Override 44 | public void updateData(ServerPlayer player, File file) throws IOException { 45 | } 46 | 47 | @Override 48 | public Enum getGoalType() { 49 | return INTERACT_ENTITY; 50 | } 51 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/questgoal/KillGoal.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.questgoal; 2 | 3 | import com.google.gson.Gson; 4 | import dev.zanckor.api.filemanager.quest.codec.user.UserGoal; 5 | import dev.zanckor.api.filemanager.quest.codec.user.UserQuest; 6 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractGoal; 7 | import dev.zanckor.mod.common.network.SendQuestPacket; 8 | import dev.zanckor.mod.common.network.message.screen.UpdateQuestTracked; 9 | import dev.zanckor.mod.common.util.GsonManager; 10 | import dev.zanckor.mod.common.util.MCUtil; 11 | import net.minecraft.server.level.ServerPlayer; 12 | import net.minecraft.world.entity.Entity; 13 | import net.minecraft.world.entity.EntityType; 14 | 15 | import java.io.File; 16 | import java.io.FileWriter; 17 | import java.io.IOException; 18 | 19 | import static dev.zanckor.example.common.enumregistry.enumquest.EnumGoalType.KILL; 20 | 21 | public class KillGoal extends AbstractGoal { 22 | public void handler(ServerPlayer player, Entity entity, Gson gson, File file, UserQuest userQuest, int indexGoal, Enum questType) throws IOException { 23 | userQuest = (UserQuest) GsonManager.getJsonClass(file, UserQuest.class); 24 | UserGoal questGoal = userQuest.getQuestGoals().get(indexGoal); 25 | 26 | //Checks if killed entity equals to target and if it is, checks if current progress is more than target amount 27 | if (questGoal.getCurrentAmount() >= questGoal.getAmount() || !(questGoal.getTarget().equals(EntityType.getKey(entity.getType()).toString()))) 28 | return; 29 | 30 | questGoal.incrementCurrentAmount(1); 31 | GsonManager.writeJson(file, userQuest); 32 | 33 | userQuest = (UserQuest) GsonManager.getJsonClass(file, UserQuest.class); 34 | super.handler(player, entity, gson, file, userQuest, indexGoal, questType); 35 | } 36 | 37 | @Override 38 | public void enhancedCompleteQuest(ServerPlayer player, File file, UserGoal userGoal) { 39 | 40 | } 41 | 42 | @Override 43 | public void updateData(ServerPlayer player, File file) throws IOException { 44 | } 45 | 46 | @Override 47 | public Enum getGoalType() { 48 | return KILL; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/questgoal/MoveToGoal.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.questgoal; 2 | 3 | import com.google.gson.Gson; 4 | import dev.zanckor.api.filemanager.quest.codec.user.UserGoal; 5 | import dev.zanckor.api.filemanager.quest.codec.user.UserQuest; 6 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractGoal; 7 | import dev.zanckor.mod.common.network.SendQuestPacket; 8 | import dev.zanckor.mod.common.network.message.screen.UpdateQuestTracked; 9 | import dev.zanckor.mod.common.util.GsonManager; 10 | import dev.zanckor.mod.common.util.MCUtil; 11 | import net.minecraft.server.level.ServerPlayer; 12 | import net.minecraft.world.entity.Entity; 13 | 14 | import java.io.File; 15 | import java.io.FileWriter; 16 | import java.io.IOException; 17 | 18 | import static dev.zanckor.example.common.enumregistry.enumquest.EnumGoalType.MOVE_TO; 19 | 20 | public class MoveToGoal extends AbstractGoal { 21 | 22 | public void handler(ServerPlayer player, Entity entity, Gson gson, File file, UserQuest userQuest, int indexGoal, Enum questType) throws IOException { 23 | 24 | UserGoal questGoal = userQuest.getQuestGoals().get(indexGoal); 25 | 26 | if (!(questGoal.getType().equals(MOVE_TO.toString()))) return; 27 | questGoal.setCurrentAmount(1); 28 | GsonManager.writeJson(file, userQuest); 29 | 30 | userQuest = (UserQuest) GsonManager.getJsonClass(file, UserQuest.class); 31 | super.handler(player, entity, gson, file, userQuest, indexGoal, questType); 32 | } 33 | 34 | @Override 35 | public void enhancedCompleteQuest(ServerPlayer player, File file, UserGoal userGoal) { 36 | 37 | } 38 | 39 | @Override 40 | public void updateData(ServerPlayer player, File file) throws IOException { 41 | } 42 | 43 | @Override 44 | public Enum getGoalType() { 45 | return MOVE_TO; 46 | } 47 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/questgoal/XpGoal.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.questgoal; 2 | 3 | import com.google.gson.Gson; 4 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractGoal; 5 | import dev.zanckor.api.filemanager.quest.codec.user.UserGoal; 6 | import dev.zanckor.api.filemanager.quest.codec.user.UserQuest; 7 | import dev.zanckor.mod.common.network.SendQuestPacket; 8 | import dev.zanckor.mod.common.network.message.screen.UpdateQuestTracked; 9 | import dev.zanckor.mod.common.util.GsonManager; 10 | import dev.zanckor.mod.common.util.MCUtil; 11 | import net.minecraft.server.level.ServerPlayer; 12 | import net.minecraft.world.entity.Entity; 13 | 14 | import java.io.File; 15 | import java.io.FileWriter; 16 | import java.io.IOException; 17 | 18 | import static dev.zanckor.example.common.enumregistry.enumquest.EnumGoalType.XP; 19 | 20 | public class XpGoal extends AbstractGoal { 21 | 22 | public void handler(ServerPlayer player, Entity entity, Gson gson, File file, UserQuest userQuest, int indexGoal, Enum questType) throws IOException { 23 | userQuest = (UserQuest) GsonManager.getJsonClass(file, UserQuest.class); 24 | UserGoal questGoal = userQuest.getQuestGoals().get(indexGoal); 25 | 26 | if (questGoal.getCurrentAmount() == null) return; 27 | 28 | int currentAmount = player.experienceLevel >= questGoal.getAmount() ? questGoal.getAmount() : player.experienceLevel; 29 | questGoal.setCurrentAmount(currentAmount); 30 | GsonManager.writeJson(file, userQuest); 31 | 32 | userQuest = (UserQuest) GsonManager.getJsonClass(file, UserQuest.class); 33 | super.handler(player, entity, gson, file, userQuest, indexGoal, questType); 34 | } 35 | 36 | @Override 37 | public void enhancedCompleteQuest(ServerPlayer player, File file, UserGoal userGoal) { 38 | player.setExperienceLevels(player.experienceLevel - userGoal.getAmount()); 39 | } 40 | 41 | @Override 42 | public void updateData(ServerPlayer player, File file) throws IOException { 43 | } 44 | 45 | @Override 46 | public Enum getGoalType() { 47 | return XP; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/questrequirement/XpRequirement.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.questrequirement; 2 | 3 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractQuestRequirement; 4 | import dev.zanckor.api.filemanager.quest.codec.server.ServerQuest; 5 | import dev.zanckor.api.filemanager.quest.codec.server.ServerRequirement; 6 | import dev.zanckor.example.common.enumregistry.enumdialog.EnumDialogReq; 7 | import net.minecraft.network.chat.Component; 8 | import net.minecraft.world.entity.player.Player; 9 | 10 | import java.io.IOException; 11 | 12 | public class XpRequirement extends AbstractQuestRequirement { 13 | 14 | /** 15 | * Type of requirement that checks if player is between two values of XP 16 | * 17 | * @param player The player 18 | * @param serverQuest ServerQuestBase with global quest data 19 | * @param requirementIndex 20 | * @throws IOException Exception fired when server cannot read json file 21 | * @see EnumDialogReq Requirement types 22 | */ 23 | 24 | @Override 25 | public boolean handler(Player player, ServerQuest serverQuest, int requirementIndex) throws IOException { 26 | ServerRequirement requirement = serverQuest.getRequirements().get(requirementIndex); 27 | if (player.experienceLevel < 0) player.experienceLevel = 0; 28 | 29 | boolean hasReqs = player.experienceLevel >= requirement.getRequirements_min() && player.experienceLevel <= requirement.getRequirements_max(); 30 | 31 | if (!hasReqs) { 32 | player.sendSystemMessage(Component.literal("Player " + player.getScoreboardName() + " doesn't have the requirements to access to this quest")); 33 | player.sendSystemMessage(Component.literal("Minimum: " + requirement.getRequirements_min())); 34 | player.sendSystemMessage(Component.literal("Maximum: " + requirement.getRequirements_max())); 35 | } 36 | 37 | return hasReqs; 38 | } 39 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/questreward/CommandReward.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.questreward; 2 | 3 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractReward; 4 | import dev.zanckor.api.filemanager.quest.codec.server.ServerQuest; 5 | import dev.zanckor.example.common.enumregistry.enumquest.EnumQuestReward; 6 | import net.minecraft.commands.CommandSourceStack; 7 | import net.minecraft.server.level.ServerPlayer; 8 | 9 | import java.io.IOException; 10 | 11 | public class CommandReward extends AbstractReward { 12 | 13 | /** 14 | * Type of reward, executes command set on quest.json as reward 15 | * 16 | * @param player The player 17 | * @param serverQuest ServerQuestBase with global quest data 18 | * @param rewardIndex 19 | * @throws IOException Exception fired when server cannot read json file 20 | * @see EnumQuestReward Reward types 21 | */ 22 | 23 | @Override 24 | public void handler(ServerPlayer player, ServerQuest serverQuest, int rewardIndex) throws IOException { 25 | String command = serverQuest.getRewards().get(rewardIndex).getTag(); 26 | if(command.contains("@p")) command.replace("@p", player.getScoreboardName()); 27 | 28 | int quantity = serverQuest.getRewards().get(rewardIndex).getAmount(); 29 | 30 | CommandSourceStack sourceStack = player.getServer().createCommandSourceStack(); 31 | 32 | for (int timesExecuted = 0; timesExecuted < quantity; timesExecuted++) { 33 | sourceStack.getServer().getCommands().performPrefixedCommand(sourceStack, command); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/questreward/ItemReward.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.questreward; 2 | 3 | import dev.zanckor.api.filemanager.quest.codec.server.ServerQuest; 4 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractReward; 5 | import dev.zanckor.example.common.enumregistry.enumquest.EnumQuestReward; 6 | import net.minecraft.resources.ResourceLocation; 7 | import net.minecraft.server.level.ServerPlayer; 8 | import net.minecraft.world.item.Item; 9 | import net.minecraft.world.item.ItemStack; 10 | import net.minecraftforge.registries.ForgeRegistries; 11 | 12 | import java.io.IOException; 13 | 14 | public class ItemReward extends AbstractReward { 15 | 16 | /** 17 | * Type of reward, gives player whatever item is set on quest.json as reward 18 | * 19 | * @param player The player 20 | * @param serverQuest ServerQuestBase with global quest data 21 | * @param rewardIndex 22 | * @throws IOException Exception fired when server cannot read json file 23 | * @see EnumQuestReward Reward types 24 | */ 25 | 26 | @Override 27 | public void handler(ServerPlayer player, ServerQuest serverQuest, int rewardIndex) throws IOException { 28 | String valueItem = serverQuest.getRewards().get(rewardIndex).getTag(); 29 | int quantity = serverQuest.getRewards().get(rewardIndex).getAmount(); 30 | 31 | Item item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(valueItem)); 32 | ItemStack stack = new ItemStack(item, quantity); 33 | 34 | player.addItem(stack); 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/questreward/LootTableReward.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.questreward; 2 | 3 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractReward; 4 | import dev.zanckor.api.filemanager.quest.codec.server.ServerQuest; 5 | import dev.zanckor.example.common.enumregistry.enumquest.EnumQuestReward; 6 | import net.minecraft.resources.ResourceLocation; 7 | import net.minecraft.server.MinecraftServer; 8 | import net.minecraft.server.level.ServerLevel; 9 | import net.minecraft.server.level.ServerPlayer; 10 | import net.minecraft.world.item.ItemStack; 11 | import net.minecraft.world.level.storage.loot.LootContext; 12 | import net.minecraft.world.level.storage.loot.LootParams; 13 | import net.minecraft.world.level.storage.loot.LootTable; 14 | import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; 15 | import net.minecraft.world.level.storage.loot.parameters.LootContextParams; 16 | 17 | import java.io.IOException; 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | 21 | public class LootTableReward extends AbstractReward { 22 | 23 | /** 24 | * Type of reward, gives player whatever item is set on quest.json as reward 25 | * 26 | * @param player The player 27 | * @param serverQuest ServerQuestBase with global quest data 28 | * @param rewardIndex 29 | * @throws IOException Exception fired when server cannot read json file 30 | * @see EnumQuestReward Reward types 31 | */ 32 | 33 | @Override 34 | public void handler(ServerPlayer player, ServerQuest serverQuest, int rewardIndex) throws IOException { 35 | String lootTableRL = serverQuest.getRewards().get(rewardIndex).getTag(); 36 | int rolls = serverQuest.getRewards().get(rewardIndex).getAmount(); 37 | MinecraftServer server = player.server; 38 | List itemStackList = new ArrayList<>(); 39 | 40 | ResourceLocation rl = new ResourceLocation(lootTableRL); 41 | LootTable lootTable = server.getLootData().getLootTable(rl); 42 | 43 | for(int actualRoll = 0; actualRoll < rolls; actualRoll++) { 44 | LootParams lootparams = (new LootParams.Builder((ServerLevel) player.level())).create(LootContextParamSets.EMPTY); 45 | itemStackList = lootTable.getRandomItems(lootparams); 46 | } 47 | 48 | for(ItemStack itemStack : itemStackList){ 49 | player.getInventory().add(itemStack); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/questreward/QuestReward.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.questreward; 2 | 3 | import dev.zanckor.api.database.LocateHash; 4 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractQuestRequirement; 5 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractReward; 6 | import dev.zanckor.api.filemanager.quest.codec.server.ServerQuest; 7 | import dev.zanckor.api.filemanager.quest.codec.user.UserQuest; 8 | import dev.zanckor.api.filemanager.quest.register.QuestTemplateRegistry; 9 | import dev.zanckor.example.common.enumregistry.EnumRegistry; 10 | import dev.zanckor.example.common.enumregistry.enumquest.EnumQuestRequirement; 11 | import dev.zanckor.example.common.enumregistry.enumquest.EnumQuestReward; 12 | import dev.zanckor.mod.common.util.GsonManager; 13 | import dev.zanckor.mod.common.util.Timer; 14 | import net.minecraft.server.level.ServerPlayer; 15 | 16 | import java.io.File; 17 | import java.io.FileWriter; 18 | import java.io.IOException; 19 | import java.nio.file.Path; 20 | import java.nio.file.Paths; 21 | 22 | import static dev.zanckor.mod.QuestApiMain.*; 23 | 24 | public class QuestReward extends AbstractReward { 25 | 26 | /** 27 | * Type of reward, gives player another quest (multistage) set on quest.json as reward 28 | * 29 | * @param player The player 30 | * @param serverQuest ServerQuestBase with global quest data 31 | * @param rewardIndex 32 | * @throws IOException Exception fired when server cannot read json file 33 | * @see EnumQuestReward Reward types 34 | */ 35 | 36 | @Override 37 | public void handler(ServerPlayer player, ServerQuest serverQuest, int rewardIndex) throws IOException { 38 | String quest = serverQuest.getRewards().get(rewardIndex).getTag() + ".json"; 39 | Path userFolder = Paths.get(playerData.toString(), player.getUUID().toString()); 40 | 41 | for (File file : serverQuests.toFile().listFiles()) { 42 | if (!(file.getName().equals(quest))) continue; 43 | 44 | Path path = Paths.get(getActiveQuest(userFolder).toString(), File.separator, file.getName()); 45 | ServerQuest rewardServerQuest = (ServerQuest) GsonManager.getJsonClass(file, ServerQuest.class); 46 | 47 | //Checks all quest requirements and return if player hasn't any requirement 48 | for (int requirementIndex = 0; requirementIndex < rewardServerQuest.getRequirements().size(); requirementIndex++) { 49 | Enum questRequirementEnum = EnumRegistry.getEnum(rewardServerQuest.getRequirements().get(requirementIndex).getType(), EnumRegistry.getQuestRequirement()); 50 | AbstractQuestRequirement requirement = QuestTemplateRegistry.getQuestRequirement(questRequirementEnum); 51 | 52 | if (!requirement.handler(player, rewardServerQuest, requirementIndex)) return; 53 | } 54 | 55 | UserQuest userQuest = UserQuest.createQuest(rewardServerQuest, path); 56 | GsonManager.writeJson(path.toFile(), userQuest); 57 | 58 | if (userQuest.hasTimeLimit()) { 59 | Timer.updateCooldown(player.getUUID(), userQuest.getId(), userQuest.getTimeLimitInSeconds()); 60 | } 61 | 62 | LocateHash.registerQuestByID(serverQuest.getRewards().get(rewardIndex).getTag(), path); 63 | 64 | break; 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/questreward/XpReward.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.questreward; 2 | 3 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractReward; 4 | import dev.zanckor.api.filemanager.quest.codec.server.ServerQuest; 5 | import dev.zanckor.example.common.enumregistry.enumquest.EnumQuestReward; 6 | import net.minecraft.server.level.ServerPlayer; 7 | 8 | import java.io.IOException; 9 | 10 | public class XpReward extends AbstractReward { 11 | 12 | /** 13 | * Type of reward, gives player X quantity of xp set on quest.json as reward 14 | * 15 | * @param player The player 16 | * @param serverQuest ServerQuestBase with global quest data 17 | * @param rewardIndex 18 | * @throws IOException Exception fired when server cannot read json file 19 | * @see EnumQuestReward Reward types 20 | */ 21 | 22 | @Override 23 | public void handler(ServerPlayer player, ServerQuest serverQuest, int rewardIndex) throws IOException { 24 | EnumQuestReward type = EnumQuestReward.valueOf(serverQuest.getRewards().get(rewardIndex).getTag()); 25 | int quantity = serverQuest.getRewards().get(rewardIndex).getAmount(); 26 | 27 | switch (type){ 28 | case LEVEL -> player.giveExperienceLevels(quantity); 29 | case POINTS -> player.giveExperiencePoints(quantity); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/targettype/DefaultTargetType.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.targettype; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractTargetType; 5 | import dev.zanckor.api.filemanager.quest.codec.user.UserGoal; 6 | import dev.zanckor.mod.common.util.MCUtilClient; 7 | import net.minecraft.ChatFormatting; 8 | import net.minecraft.client.resources.language.I18n; 9 | import net.minecraft.network.chat.MutableComponent; 10 | import net.minecraft.resources.ResourceLocation; 11 | import net.minecraft.world.entity.player.Player; 12 | 13 | import static dev.zanckor.mod.common.util.MCUtilClient.properNoun; 14 | 15 | public class DefaultTargetType extends AbstractTargetType { 16 | 17 | @Override 18 | public MutableComponent handler(String resourceLocationString, UserGoal goal, Player player, ChatFormatting chatFormatting, ChatFormatting chatFormatting1) { 19 | String translationKey = new ResourceLocation(resourceLocationString).getPath(); 20 | 21 | return MCUtilClient.formatString(properNoun(I18n.get(translationKey)), " " + goal.getCurrentAmount() + "/" + goal.getAmount(), 22 | chatFormatting, chatFormatting1); 23 | } 24 | 25 | @Override 26 | public String target(String resourceLocationString) { 27 | String translationKey = new ResourceLocation(resourceLocationString).getPath(); 28 | 29 | return properNoun(I18n.get(translationKey)); 30 | } 31 | 32 | @Override 33 | public void renderTarget(PoseStack poseStack, int xPosition, int yPosition, double size, double rotation, UserGoal goal, String resourceLocationString) { 34 | //Renders nothing 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/targettype/EntityTargetType.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.targettype; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractTargetType; 5 | import dev.zanckor.api.filemanager.quest.codec.user.UserGoal; 6 | import dev.zanckor.mod.common.util.MCUtilClient; 7 | import net.minecraft.ChatFormatting; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.resources.language.I18n; 10 | import net.minecraft.network.chat.MutableComponent; 11 | import net.minecraft.resources.ResourceLocation; 12 | import net.minecraft.world.entity.EntityType; 13 | import net.minecraft.world.entity.LivingEntity; 14 | import net.minecraft.world.entity.player.Player; 15 | import net.minecraftforge.api.distmarker.Dist; 16 | import net.minecraftforge.fml.common.Mod; 17 | import net.minecraftforge.registries.ForgeRegistries; 18 | 19 | import static dev.zanckor.mod.QuestApiMain.MOD_ID; 20 | import static dev.zanckor.mod.common.util.MCUtilClient.properNoun; 21 | 22 | public class EntityTargetType extends AbstractTargetType { 23 | 24 | @Override 25 | public MutableComponent handler(String resourceLocationString, UserGoal goal, Player player, ChatFormatting chatFormatting, ChatFormatting chatFormatting1) { 26 | EntityType translationKey = ForgeRegistries.ENTITY_TYPES.getValue(new ResourceLocation(resourceLocationString)); 27 | 28 | return MCUtilClient.formatString(properNoun(I18n.get(translationKey.getDescriptionId())), " " + goal.getCurrentAmount() + "/" + goal.getAmount(), 29 | chatFormatting, chatFormatting1); 30 | } 31 | 32 | @Override 33 | public String target(String resourceLocationString) { 34 | EntityType translationKey = ForgeRegistries.ENTITY_TYPES.getValue(new ResourceLocation(resourceLocationString)); 35 | 36 | return properNoun(I18n.get(translationKey.getDescriptionId())); 37 | } 38 | 39 | 40 | @Override 41 | public void renderTarget(PoseStack poseStack, int xPosition, int yPosition, double size, double rotation, UserGoal goal, String resourceLocationString) { 42 | EntityType entityType = ForgeRegistries.ENTITY_TYPES.getValue(new ResourceLocation(resourceLocationString)); 43 | rotation = goal.getCurrentAmount() >= goal.getAmount() ? rotation : 0; 44 | 45 | MCUtilClient.renderEntity( 46 | xPosition + 5, yPosition + 4, 5, 47 | rotation * 5, (LivingEntity) entityType.create(Minecraft.getInstance().level), poseStack); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/targettype/EntityUUIDTargetType.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.targettype; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractTargetType; 5 | import dev.zanckor.api.filemanager.quest.codec.user.UserGoal; 6 | import dev.zanckor.mod.common.util.MCUtilClient; 7 | import net.minecraft.ChatFormatting; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.resources.language.I18n; 10 | import net.minecraft.network.chat.MutableComponent; 11 | import net.minecraft.resources.ResourceLocation; 12 | import net.minecraft.world.entity.EntityType; 13 | import net.minecraft.world.entity.LivingEntity; 14 | import net.minecraft.world.entity.player.Player; 15 | import net.minecraftforge.registries.ForgeRegistries; 16 | 17 | import java.util.UUID; 18 | 19 | import static dev.zanckor.mod.common.util.MCUtilClient.properNoun; 20 | 21 | public class EntityUUIDTargetType extends AbstractTargetType { 22 | 23 | @Override 24 | public MutableComponent handler(String resourceLocationString, UserGoal goal, Player player, ChatFormatting chatFormatting, ChatFormatting chatFormatting1) { 25 | LivingEntity entity = (LivingEntity) MCUtilClient.getEntityByUUID(UUID.fromString(new ResourceLocation(resourceLocationString).getPath())); 26 | String translationKey = entity != null ? entity.getType().getDescriptionId() : ""; 27 | 28 | return MCUtilClient.formatString(properNoun(I18n.get(translationKey)), " " + goal.getCurrentAmount() + "/" + goal.getAmount(), 29 | chatFormatting, chatFormatting1); 30 | } 31 | 32 | @Override 33 | public String target(String resourceLocationString) { 34 | LivingEntity entity = (LivingEntity) MCUtilClient.getEntityByUUID(UUID.fromString(new ResourceLocation(resourceLocationString).getPath())); 35 | String translationKey = entity != null ? entity.getType().getDescriptionId() : ""; 36 | 37 | return properNoun(I18n.get(translationKey)); 38 | } 39 | 40 | @Override 41 | public void renderTarget(PoseStack poseStack, int xPosition, int yPosition, double size, double rotation, UserGoal goal, String resourceLocationString) { 42 | EntityType entityType = ForgeRegistries.ENTITY_TYPES.getValue(new ResourceLocation(resourceLocationString)); 43 | rotation = goal.getCurrentAmount() >= goal.getAmount() ? rotation : 0; 44 | 45 | MCUtilClient.renderEntity( 46 | xPosition + 10, yPosition + 4, 5, 47 | rotation, (LivingEntity) entityType.create(Minecraft.getInstance().level), poseStack); 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/targettype/ItemTargetType.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.targettype; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractTargetType; 5 | import dev.zanckor.api.filemanager.quest.codec.user.UserGoal; 6 | import dev.zanckor.mod.common.util.MCUtilClient; 7 | import dev.zanckor.mod.common.util.Mathematic; 8 | import net.minecraft.ChatFormatting; 9 | import net.minecraft.client.Minecraft; 10 | import net.minecraft.client.resources.language.I18n; 11 | import net.minecraft.network.chat.MutableComponent; 12 | import net.minecraft.resources.ResourceLocation; 13 | import net.minecraft.world.entity.player.Player; 14 | import net.minecraft.world.item.Item; 15 | import net.minecraft.world.item.ItemStack; 16 | import net.minecraft.world.item.MapItem; 17 | import net.minecraftforge.api.distmarker.Dist; 18 | import net.minecraftforge.fml.common.Mod; 19 | import net.minecraftforge.registries.ForgeRegistries; 20 | 21 | import java.time.chrono.MinguoEra; 22 | 23 | import static dev.zanckor.mod.QuestApiMain.MOD_ID; 24 | import static dev.zanckor.mod.common.util.MCUtilClient.properNoun; 25 | 26 | 27 | public class ItemTargetType extends AbstractTargetType { 28 | 29 | @Override 30 | public MutableComponent handler(String resourceLocationString, UserGoal goal, Player player, ChatFormatting chatFormatting, ChatFormatting chatFormatting1) { 31 | Item itemTarget = ForgeRegistries.ITEMS.getValue(new ResourceLocation(resourceLocationString)); 32 | String translationKey = itemTarget.getDescriptionId(itemTarget.getDefaultInstance()); 33 | 34 | return MCUtilClient.formatString(properNoun(I18n.get(translationKey)), " " + goal.getCurrentAmount() + "/" + goal.getAmount(), 35 | chatFormatting, chatFormatting1); 36 | } 37 | 38 | @Override 39 | public String target(String resourceLocationString) { 40 | Item itemTarget = ForgeRegistries.ITEMS.getValue(new ResourceLocation(resourceLocationString)); 41 | String translationKey = itemTarget.getDescriptionId(itemTarget.getDefaultInstance()); 42 | 43 | return properNoun(I18n.get(translationKey)); 44 | } 45 | 46 | @Override 47 | public void renderTarget(PoseStack poseStack, int xPosition, int yPosition, double size, double rotation, UserGoal goal, String resourceLocationString) { 48 | ItemStack itemStack = ForgeRegistries.ITEMS.getValue(new ResourceLocation(resourceLocationString)).getDefaultInstance(); 49 | rotation = goal.getCurrentAmount() >= goal.getAmount() ? rotation : 0; 50 | 51 | poseStack.pushPose(); 52 | MCUtilClient.renderItem(itemStack, xPosition, yPosition, size, rotation, poseStack); 53 | poseStack.popPose(); 54 | } 55 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/targettype/MoveToTargetType.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.targettype; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractTargetType; 5 | import dev.zanckor.api.filemanager.quest.codec.user.UserGoal; 6 | import dev.zanckor.mod.common.util.MCUtilClient; 7 | import net.minecraft.ChatFormatting; 8 | import net.minecraft.network.chat.MutableComponent; 9 | import net.minecraft.world.entity.player.Player; 10 | import net.minecraftforge.api.distmarker.Dist; 11 | import net.minecraftforge.fml.common.Mod; 12 | 13 | import static dev.zanckor.mod.QuestApiMain.MOD_ID; 14 | 15 | public class MoveToTargetType extends AbstractTargetType { 16 | 17 | @Override 18 | public MutableComponent handler(String resourceLocationString, UserGoal goal, Player player, ChatFormatting chatFormatting, ChatFormatting chatFormatting1) { 19 | return MCUtilClient.formatString("Location", " " + goal.getAdditionalListData().toString().substring(1, goal.getAdditionalListData().toString().length() - 1) 20 | + " / " + (int) player.getX() + ", " + (int) player.getY() + ", " + (int) player.getZ(), 21 | chatFormatting, chatFormatting1); 22 | } 23 | 24 | @Override 25 | public String target(String resourceLocationString) { 26 | return "Location"; 27 | } 28 | 29 | @Override 30 | public void renderTarget(PoseStack poseStack, int xPosition, int yPosition, double size, double rotation, UserGoal goal, String resourceLocationString) { 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/common/handler/targettype/XPTargetType.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.common.handler.targettype; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractTargetType; 5 | import dev.zanckor.api.filemanager.quest.codec.user.UserGoal; 6 | import dev.zanckor.mod.common.util.MCUtilClient; 7 | import dev.zanckor.mod.common.util.Timer; 8 | import net.minecraft.ChatFormatting; 9 | import net.minecraft.client.Minecraft; 10 | import net.minecraft.network.chat.MutableComponent; 11 | import net.minecraft.world.entity.LivingEntity; 12 | import net.minecraft.world.entity.player.Player; 13 | import net.minecraft.world.item.Items; 14 | import net.minecraftforge.api.distmarker.Dist; 15 | import net.minecraftforge.fml.common.Mod; 16 | 17 | import static dev.zanckor.mod.QuestApiMain.MOD_ID; 18 | 19 | 20 | public class XPTargetType extends AbstractTargetType { 21 | 22 | @Override 23 | public MutableComponent handler(String resourceLocationString, UserGoal goal, Player player, ChatFormatting chatFormatting, ChatFormatting chatFormatting1) { 24 | if(goal.getCurrentAmount() == null) goal.setCurrentAmount(0); 25 | 26 | return MCUtilClient.formatString("XP", " " + goal.getCurrentAmount() + "/" + goal.getAmount(), 27 | chatFormatting, chatFormatting1); 28 | } 29 | 30 | @Override 31 | public String target(String resourceLocationString) { 32 | return "XP"; 33 | } 34 | 35 | @Override 36 | public void renderTarget(PoseStack poseStack, int xPosition, int yPosition, double size, double rotation, UserGoal goal, String resourceLocationString) { 37 | rotation = goal.getCurrentAmount() >= goal.getAmount() ? rotation : 0; 38 | 39 | MCUtilClient.renderItem(Items.EXPERIENCE_BOTTLE.getDefaultInstance(), xPosition + 10, yPosition, size, rotation, poseStack); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/server/event/AssignEntityStats.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.server.event; 2 | 3 | import dev.zanckor.example.common.entity.NpcTypes; 4 | import dev.zanckor.example.common.entity.server.NPCEntity; 5 | import dev.zanckor.mod.QuestApiMain; 6 | import net.minecraftforge.event.entity.EntityAttributeCreationEvent; 7 | import net.minecraftforge.eventbus.api.SubscribeEvent; 8 | import net.minecraftforge.fml.common.Mod; 9 | 10 | @Mod.EventBusSubscriber(modid = QuestApiMain.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) 11 | public class AssignEntityStats { 12 | @SubscribeEvent 13 | public static void assignEntityAtts(EntityAttributeCreationEvent e) { 14 | e.put(NpcTypes.NPC_ENTITY.get(), NPCEntity.setAttributes()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/server/event/questevent/CollectEvent.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.server.event.questevent; 2 | 3 | import dev.zanckor.mod.QuestApiMain; 4 | import dev.zanckor.mod.common.network.handler.ServerHandler; 5 | import net.minecraft.server.level.ServerPlayer; 6 | import net.minecraftforge.event.entity.player.PlayerEvent; 7 | import net.minecraftforge.eventbus.api.SubscribeEvent; 8 | import net.minecraftforge.fml.common.Mod; 9 | 10 | import java.io.IOException; 11 | 12 | import static dev.zanckor.example.common.enumregistry.enumquest.EnumGoalType.COLLECT; 13 | import static dev.zanckor.example.common.enumregistry.enumquest.EnumGoalType.COLLECT_WITH_NBT; 14 | 15 | @Mod.EventBusSubscriber(modid = QuestApiMain.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE) 16 | public class CollectEvent { 17 | 18 | @SubscribeEvent 19 | public static void CollectPickUpQuest(PlayerEvent.ItemPickupEvent e) throws IOException { 20 | if(!(e.getEntity() instanceof ServerPlayer) || e.getEntity().level().isClientSide) return; 21 | 22 | runGoalHandler((ServerPlayer) e.getEntity()); 23 | } 24 | 25 | @SubscribeEvent 26 | public static void CollectCraftQuest(PlayerEvent.ItemCraftedEvent e) throws IOException { 27 | if(!(e.getEntity() instanceof ServerPlayer) || e.getEntity().level().isClientSide) return; 28 | 29 | runGoalHandler((ServerPlayer) e.getEntity()); 30 | } 31 | 32 | @SubscribeEvent 33 | public static void CollectCraftQuest(PlayerEvent.ItemSmeltedEvent e) throws IOException { 34 | if(!(e.getEntity() instanceof ServerPlayer) || e.getEntity().level().isClientSide) return; 35 | 36 | runGoalHandler((ServerPlayer) e.getEntity()); 37 | } 38 | 39 | public static void runGoalHandler(ServerPlayer player) throws IOException { 40 | ServerHandler.questHandler(COLLECT, player, null); 41 | ServerHandler.questHandler(COLLECT_WITH_NBT, player, null); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/server/event/questevent/InteractWEntityEvent.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.server.event.questevent; 2 | 3 | import dev.zanckor.mod.QuestApiMain; 4 | import dev.zanckor.mod.common.network.handler.ServerHandler; 5 | import dev.zanckor.mod.common.util.Timer; 6 | import net.minecraft.server.level.ServerPlayer; 7 | import net.minecraft.world.InteractionHand; 8 | import net.minecraft.world.entity.LivingEntity; 9 | import net.minecraftforge.event.entity.player.PlayerInteractEvent; 10 | import net.minecraftforge.eventbus.api.SubscribeEvent; 11 | import net.minecraftforge.fml.common.Mod; 12 | 13 | import java.io.IOException; 14 | 15 | import static dev.zanckor.example.common.enumregistry.enumquest.EnumGoalType.INTERACT_ENTITY; 16 | 17 | @Mod.EventBusSubscriber(modid = QuestApiMain.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE) 18 | public class InteractWEntityEvent { 19 | 20 | @SubscribeEvent 21 | public static void interactWithNPC(PlayerInteractEvent.EntityInteract e) throws IOException { 22 | if (e.getHand() == InteractionHand.OFF_HAND || e.getSide().isClient() || !(e.getTarget() instanceof LivingEntity)) 23 | return; 24 | 25 | 26 | if (Timer.canUseWithCooldown(e.getEntity().getUUID(), "INTERACT_EVENT_COOLDOWN", 1)) { 27 | ServerHandler.questHandler(INTERACT_ENTITY, (ServerPlayer) e.getEntity(), (LivingEntity) e.getTarget()); 28 | Timer.updateCooldown(e.getEntity().getUUID(), "INTERACT_EVENT_COOLDOWN", 1); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/server/event/questevent/KillEvent.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.server.event.questevent; 2 | 3 | import dev.zanckor.mod.QuestApiMain; 4 | import dev.zanckor.mod.common.network.handler.ServerHandler; 5 | import net.minecraft.server.level.ServerPlayer; 6 | import net.minecraftforge.event.entity.living.LivingDeathEvent; 7 | import net.minecraftforge.eventbus.api.SubscribeEvent; 8 | import net.minecraftforge.fml.common.Mod; 9 | 10 | import java.io.IOException; 11 | 12 | import static dev.zanckor.example.common.enumregistry.enumquest.EnumGoalType.KILL; 13 | 14 | @Mod.EventBusSubscriber(modid = QuestApiMain.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE) 15 | public class KillEvent { 16 | @SubscribeEvent 17 | public static void killQuest(LivingDeathEvent e) throws IOException { 18 | if (!(e.getSource().getEntity() instanceof ServerPlayer player) || player.level().isClientSide) return; 19 | 20 | ServerHandler.questHandler(KILL, player, e.getEntity()); 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/server/event/questevent/MoveToEvent.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.server.event.questevent; 2 | 3 | import dev.zanckor.api.database.LocateHash; 4 | import dev.zanckor.api.filemanager.quest.codec.user.UserGoal; 5 | import dev.zanckor.api.filemanager.quest.codec.user.UserQuest; 6 | import dev.zanckor.mod.QuestApiMain; 7 | import dev.zanckor.mod.common.network.handler.ServerHandler; 8 | import dev.zanckor.mod.common.util.GsonManager; 9 | import dev.zanckor.mod.common.util.Mathematic; 10 | import net.minecraft.core.BlockPos; 11 | import net.minecraft.core.Vec3i; 12 | import net.minecraft.server.level.ServerPlayer; 13 | import net.minecraft.world.phys.Vec3; 14 | import net.minecraftforge.event.TickEvent; 15 | import net.minecraftforge.eventbus.api.SubscribeEvent; 16 | import net.minecraftforge.fml.common.Mod; 17 | 18 | import java.io.IOException; 19 | import java.nio.file.Path; 20 | import java.util.List; 21 | 22 | import static dev.zanckor.example.common.enumregistry.enumquest.EnumGoalType.MOVE_TO; 23 | import static net.minecraft.core.Direction.Axis.*; 24 | 25 | @Mod.EventBusSubscriber(modid = QuestApiMain.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE) 26 | public class MoveToEvent { 27 | 28 | @SubscribeEvent 29 | public static void moveToQuest(TickEvent.PlayerTickEvent e) throws IOException { 30 | if (e.player == null || e.side.isClient() || e.player.getServer().getTickCount() % 20 != 0) return; 31 | 32 | List moveToQuests = LocateHash.getQuestTypeLocation(MOVE_TO); 33 | 34 | if (moveToQuests != null) { 35 | for (Path path : moveToQuests) { 36 | UserQuest playerQuest = (UserQuest) GsonManager.getJsonClass(path.toFile(), UserQuest.class); 37 | if (playerQuest == null || playerQuest.isCompleted()) continue; 38 | 39 | moveTo(playerQuest, (ServerPlayer) e.player); 40 | } 41 | } 42 | } 43 | 44 | public static void moveTo(UserQuest userQuest, ServerPlayer player) throws IOException { 45 | BlockPos targetPos = null; 46 | 47 | //Checks per each goal if there's any MOVE_TO goal, 48 | //Then, add a new position to targetPos via additionalListData field from json 49 | for (int indexGoals = 0; indexGoals < userQuest.getQuestGoals().size(); indexGoals++) { 50 | UserGoal questGoal = userQuest.getQuestGoals().get(indexGoals); 51 | List additionalListData = (List) questGoal.getAdditionalListData(); 52 | 53 | if (!(questGoal.getType().equals(MOVE_TO.toString())) || additionalListData == null) continue; 54 | 55 | Vec3i vec3Coord = new Vec3i(additionalListData.get(0).intValue(), additionalListData.get(1).intValue(), additionalListData.get(2).intValue()); 56 | 57 | targetPos = new BlockPos(vec3Coord); 58 | } 59 | 60 | //If player coords are in a range of 10 blocks to target coord, executes questHandler 61 | Vec3 playerCoord = new Vec3(player.getBlockX(), player.getBlockY(), player.getBlockZ()); 62 | 63 | if (targetPos != null && Mathematic.numberBetween( 64 | playerCoord.x, targetPos.get(X) - 10, targetPos.get(X) + 10) && 65 | Mathematic.numberBetween(playerCoord.y, targetPos.get(Y) - 10, targetPos.get(Y) + 10) && 66 | Mathematic.numberBetween(playerCoord.z, targetPos.get(Z) - 10, targetPos.get(Z) + 10)) { 67 | 68 | ServerHandler.questHandler(MOVE_TO, player, null); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/example/server/event/questevent/XPEvent.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.example.server.event.questevent; 2 | 3 | import dev.zanckor.mod.QuestApiMain; 4 | import dev.zanckor.mod.common.network.handler.ServerHandler; 5 | import net.minecraft.server.level.ServerPlayer; 6 | import net.minecraftforge.event.entity.player.PlayerXpEvent; 7 | import net.minecraftforge.eventbus.api.SubscribeEvent; 8 | import net.minecraftforge.fml.common.Mod; 9 | 10 | import java.io.IOException; 11 | 12 | import static dev.zanckor.example.common.enumregistry.enumquest.EnumGoalType.XP; 13 | 14 | @Mod.EventBusSubscriber(modid = QuestApiMain.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE) 15 | public class XPEvent { 16 | @SubscribeEvent 17 | public static void xpQuest(PlayerXpEvent e) throws IOException { 18 | if (!(e.getEntity() instanceof ServerPlayer player) || player.level().isClientSide) return; 19 | 20 | ServerHandler.questHandler(XP, player, e.getEntity()); 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/client/screen/abstractscreen/AbstractDialog.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.client.screen.abstractscreen; 2 | 3 | import dev.zanckor.mod.common.network.message.dialogoption.DisplayDialog; 4 | import net.minecraft.client.gui.screens.Screen; 5 | import net.minecraft.network.chat.Component; 6 | import net.minecraft.resources.ResourceLocation; 7 | import net.minecraft.world.item.Item; 8 | 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.UUID; 12 | 13 | public abstract class AbstractDialog extends Screen { 14 | protected AbstractDialog(Component component) { 15 | super(component); 16 | } 17 | 18 | public abstract Screen modifyScreen(int dialogID, String text, int optionSize, HashMap> optionIntegers, HashMap> optionStrings, UUID npcUUID, String resourceLocation, Item item, DisplayDialog.NpcType npcType); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/client/screen/abstractscreen/AbstractQuestLog.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.client.screen.abstractscreen; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.gui.screens.Screen; 5 | import net.minecraft.client.renderer.MultiBufferSource; 6 | import net.minecraft.network.chat.Component; 7 | 8 | import java.io.IOException; 9 | import java.util.List; 10 | 11 | public abstract class AbstractQuestLog extends Screen { 12 | 13 | protected AbstractQuestLog(Component component) { 14 | super(component); 15 | } 16 | 17 | public abstract Screen modifyScreen() throws IOException; 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/client/screen/abstractscreen/AbstractQuestTracked.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.client.screen.abstractscreen; 2 | 3 | import net.minecraft.client.gui.GuiGraphics; 4 | 5 | public abstract class AbstractQuestTracked { 6 | public abstract void renderQuestTracked(GuiGraphics graphics, int width, int height); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/client/screen/questmaker/QuestGoalSelectorScreen.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.client.screen.questmaker; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import dev.zanckor.api.filemanager.quest.abstracquest.AbstractTargetType; 5 | import dev.zanckor.api.filemanager.quest.codec.server.ServerGoal; 6 | import dev.zanckor.api.filemanager.quest.codec.server.ServerQuest; 7 | import dev.zanckor.api.filemanager.quest.register.QuestTemplateRegistry; 8 | import dev.zanckor.example.client.screen.button.TextButton; 9 | import dev.zanckor.example.common.enumregistry.EnumRegistry; 10 | import dev.zanckor.mod.QuestApiMain; 11 | import dev.zanckor.mod.common.util.MCUtilClient; 12 | import dev.zanckor.mod.server.menu.questmaker.QuestMakerMenu; 13 | import net.minecraft.client.gui.GuiGraphics; 14 | import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; 15 | import net.minecraft.client.resources.language.I18n; 16 | import net.minecraft.network.chat.Component; 17 | import net.minecraft.resources.ResourceLocation; 18 | import net.minecraft.world.entity.player.Inventory; 19 | 20 | import java.util.concurrent.atomic.AtomicInteger; 21 | 22 | public class QuestGoalSelectorScreen extends AbstractContainerScreen { 23 | private final static ResourceLocation BG = new ResourceLocation(QuestApiMain.MOD_ID, "textures/gui/quest_maker_bg.png"); 24 | private int xPosition, yPosition; 25 | private float scale; 26 | ServerQuest editingQuest; 27 | 28 | public QuestGoalSelectorScreen(QuestMakerMenu questDefaultMenu, Inventory inventory, ServerQuest editingQuest, Component component) { 29 | super(questDefaultMenu, inventory, component); 30 | 31 | this.editingQuest = editingQuest; 32 | } 33 | 34 | @Override 35 | protected void init() { 36 | super.init(); 37 | 38 | xPosition = width / 2; 39 | yPosition = height / 2; 40 | imageWidth = width / 2; 41 | imageHeight = width / 4; 42 | scale = ((float) width) / 750; 43 | 44 | //For each available goal to edit in quest, create a MCUtilClient.createButton 45 | AtomicInteger buttonYOffSet = new AtomicInteger(); 46 | for (int goalIndex = 0; goalIndex < editingQuest.getGoalList().size(); goalIndex++) { 47 | ServerGoal goal = editingQuest.getGoalList().get(goalIndex); 48 | Enum goalEnum = EnumRegistry.getEnum(goal.getType(), EnumRegistry.getQuestGoal()); 49 | AbstractTargetType translatableTargetType = QuestTemplateRegistry.getTranslatableTargetType(goalEnum); 50 | 51 | String buttonText = goal.getType() + ": " + translatableTargetType.target(goal.getTarget()); 52 | 53 | int lines = (int) Math.ceil(buttonText.length() / 14) + 1; 54 | int linesOffSet = lines * 10; 55 | 56 | TextButton textButton = new TextButton((int) (xPosition / 1.9), (int) (yPosition / 1.3) + buttonYOffSet.get(), 80, lines * 20, scale, 57 | Component.literal(buttonText), 14, 58 | onPress -> { 59 | }); 60 | 61 | buttonYOffSet.addAndGet((int) (Math.max(linesOffSet, 10) * scale)); 62 | addRenderableWidget(textButton); 63 | } 64 | } 65 | 66 | @Override 67 | protected void renderBg(GuiGraphics p_283065_, float p_97788_, int p_97789_, int p_97790_) { 68 | 69 | } 70 | 71 | @Override 72 | public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { 73 | PoseStack poseStack = graphics.pose(); 74 | graphics.blit(BG, xPosition - (imageWidth / 2), yPosition - (imageHeight / 2), 0, 0, imageWidth, imageHeight, imageWidth, imageHeight); 75 | 76 | poseStack.pushPose(); 77 | renderTitles(graphics, poseStack, scale, xPosition, yPosition); 78 | poseStack.popPose(); 79 | 80 | super.render(graphics, mouseX, mouseY, partialTicks); 81 | } 82 | 83 | public void renderTitles(GuiGraphics graphics, PoseStack poseStack, float scale, int xPosition, int yPosition) { 84 | String questTitle = I18n.get(editingQuest.getTitle()); 85 | 86 | MCUtilClient.renderText(graphics, poseStack, xPosition, yPosition / 1.5, 0, scale, 40, questTitle, font); 87 | MCUtilClient.renderText(graphics, poseStack, xPosition / 1.725, yPosition / 1.5, 0, scale, 40, "Goals", font); 88 | } 89 | 90 | @Override 91 | protected void renderLabels(GuiGraphics p_281635_, int p_282681_, int p_283686_) { 92 | super.renderLabels(p_281635_, p_282681_, p_283686_); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/client/screen/questmaker/QuestMakerManager.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.client.screen.questmaker; 2 | 3 | import dev.zanckor.api.filemanager.quest.codec.server.ServerQuest; 4 | 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | 9 | public class QuestMakerManager { 10 | public static List availableQuests = new ArrayList<>(); 11 | public static HashMap editingServerQuests = new HashMap<>(); 12 | 13 | public static ServerQuest getUnsavedQuest(String id) { 14 | return editingServerQuests.get(id); 15 | } 16 | 17 | public static void addQuest(ServerQuest quest){ 18 | editingServerQuests.put(quest.getId(), quest); 19 | } 20 | 21 | public static void removeChanges(String id){ 22 | editingServerQuests.remove(id); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/config/client/RendererConfig.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.config.client; 2 | 3 | import dev.zanckor.mod.QuestApiMain; 4 | import net.minecraftforge.common.ForgeConfigSpec; 5 | 6 | public class RendererConfig { 7 | public static final ForgeConfigSpec.Builder BUILDER = new ForgeConfigSpec.Builder(); 8 | 9 | public static ForgeConfigSpec SPEC; 10 | 11 | public static ForgeConfigSpec.ConfigValue QUEST_MARK_UPDATE_COOLDOWN; 12 | 13 | static { 14 | BUILDER.push("Renderer configuration"); 15 | 16 | QUEST_MARK_UPDATE_COOLDOWN = BUILDER.comment("How long ! mark takes to update on change entity data.") 17 | .comment("Lower value = Smoothness + Lager") 18 | .define("Quest Mark ! Update Cooldown", 5); 19 | 20 | BUILDER.pop(); 21 | SPEC = BUILDER.build(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/config/client/ScreenConfig.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.config.client; 2 | 3 | import dev.zanckor.mod.QuestApiMain; 4 | import net.minecraftforge.common.ForgeConfigSpec; 5 | 6 | public class ScreenConfig { 7 | public static final ForgeConfigSpec.Builder BUILDER = new ForgeConfigSpec.Builder(); 8 | public static ForgeConfigSpec SPEC; 9 | 10 | public static ForgeConfigSpec.ConfigValue QUEST_TRACKED_SCREEN; 11 | public static ForgeConfigSpec.ConfigValue QUEST_LOG_SCREEN; 12 | 13 | static { 14 | BUILDER.push("Screen configuration"); 15 | 16 | QUEST_TRACKED_SCREEN = BUILDER.comment("Which quest tracked design you want to see") 17 | .define("Quest Tracked Screen", "minimalist_" + QuestApiMain.MOD_ID); 18 | 19 | QUEST_LOG_SCREEN = BUILDER.comment("Which design you want to see on quest log") 20 | .define("Quest Log Screen", QuestApiMain.MOD_ID); 21 | 22 | BUILDER.pop(); 23 | SPEC = BUILDER.build(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/config/server/GoalConfig.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.config.server; 2 | 3 | import net.minecraftforge.common.ForgeConfigSpec; 4 | 5 | public class GoalConfig { 6 | public static final ForgeConfigSpec.Builder BUILDER = new ForgeConfigSpec.Builder(); 7 | public static ForgeConfigSpec SPEC; 8 | 9 | public static ForgeConfigSpec.ConfigValue LOCATE_STRUCTURE_COOLDOWN; 10 | 11 | static { 12 | BUILDER.push("Goals configuration"); 13 | 14 | LOCATE_STRUCTURE_COOLDOWN = BUILDER.comment("What time should take to check again if player is close enough to an structure.") 15 | .comment("*Don't recommended set less than 10s.") 16 | .comment("*Time is counted with Ticks. 1s = 20 ticks") 17 | .define("Locate Structure Cooldown", 200); 18 | 19 | BUILDER.pop(); 20 | SPEC = BUILDER.build(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/datapack/CompoundTagDialogJSONListener.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.datapack; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonElement; 5 | import com.google.gson.JsonObject; 6 | import dev.zanckor.mod.QuestApiMain; 7 | import dev.zanckor.mod.common.util.GsonManager; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.server.packs.resources.ResourceManager; 10 | import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener; 11 | import net.minecraft.util.profiling.ProfilerFiller; 12 | import net.minecraftforge.event.AddReloadListenerEvent; 13 | 14 | import java.nio.file.Path; 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | 18 | public class CompoundTagDialogJSONListener extends SimpleJsonResourceReloadListener { 19 | public static HashMap datapackDialogPerCompoundTagList = new HashMap<>(); 20 | 21 | public CompoundTagDialogJSONListener(Gson gson, String name) { 22 | super(gson, name); 23 | } 24 | 25 | public static void register(AddReloadListenerEvent e) { 26 | e.addListener(new CompoundTagDialogJSONListener(GsonManager.gson, "questapi/npc/compound_tag_list")); 27 | } 28 | 29 | @Override 30 | protected void apply(Map jsonElementMap, ResourceManager resourceManager, ProfilerFiller profilerFiller) { 31 | QuestApiMain.LOGGER.debug("Loaded list of dialogs loaded via entity type datapack"); 32 | 33 | jsonElementMap.forEach((rl, jsonElement) -> { 34 | JsonObject obj = jsonElement.getAsJsonObject(); 35 | if (obj.get("id") == null) return; 36 | 37 | //Load quest 38 | if(obj.get("entity_type") != null) { 39 | String questId = "." + obj.get("id").toString().substring(1, obj.get("id").toString().length() - 1); 40 | Path path = Path.of(rl.getNamespace() + questId + ".json"); 41 | 42 | datapackDialogPerCompoundTagList.put(path.toString(), obj); 43 | } 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/datapack/DialogJSONListener.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.datapack; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonElement; 5 | import com.google.gson.JsonObject; 6 | import dev.zanckor.mod.QuestApiMain; 7 | import dev.zanckor.mod.common.util.GsonManager; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.server.packs.resources.ResourceManager; 10 | import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener; 11 | import net.minecraft.util.profiling.ProfilerFiller; 12 | import net.minecraftforge.event.AddReloadListenerEvent; 13 | 14 | import java.nio.file.Path; 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | 18 | public class DialogJSONListener extends SimpleJsonResourceReloadListener { 19 | public static HashMap datapackDialogList = new HashMap<>(); 20 | 21 | public DialogJSONListener(Gson gson, String name) { 22 | super(gson, name); 23 | } 24 | 25 | public static void register(AddReloadListenerEvent e) { 26 | e.addListener(new DialogJSONListener(GsonManager.gson, "questapi/dialog")); 27 | } 28 | 29 | @Override 30 | protected void apply(Map jsonElementMap, ResourceManager resourceManager, ProfilerFiller profilerFiller) { 31 | QuestApiMain.LOGGER.debug("Loaded dialog datapack"); 32 | 33 | jsonElementMap.forEach((rl, jsonElement) -> { 34 | JsonObject obj = jsonElement.getAsJsonObject(); 35 | 36 | //Load dialog 37 | if(obj.get("dialog") != null){ 38 | String dialogID = "." + rl.getPath(); 39 | Path path = Path.of(rl.getNamespace() + dialogID + ".json"); 40 | 41 | datapackDialogList.put(path.toString(), obj); 42 | } 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/datapack/EntityTypeDialogJSONListener.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.datapack; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonElement; 5 | import com.google.gson.JsonObject; 6 | import dev.zanckor.mod.QuestApiMain; 7 | import dev.zanckor.mod.common.util.GsonManager; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.server.packs.resources.ResourceManager; 10 | import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener; 11 | import net.minecraft.util.profiling.ProfilerFiller; 12 | import net.minecraftforge.event.AddReloadListenerEvent; 13 | 14 | import java.nio.file.Path; 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | 18 | public class EntityTypeDialogJSONListener extends SimpleJsonResourceReloadListener { 19 | public static HashMap datapackDialogPerEntityTypeList = new HashMap<>(); 20 | 21 | public EntityTypeDialogJSONListener(Gson gson, String name) { 22 | super(gson, name); 23 | } 24 | 25 | public static void register(AddReloadListenerEvent e) { 26 | e.addListener(new EntityTypeDialogJSONListener(GsonManager.gson, "questapi/npc/entity_type_list")); 27 | } 28 | 29 | @Override 30 | protected void apply(Map jsonElementMap, ResourceManager resourceManager, ProfilerFiller profilerFiller) { 31 | QuestApiMain.LOGGER.debug("Loaded list of dialogs loaded via entity type datapack"); 32 | 33 | jsonElementMap.forEach((rl, jsonElement) -> { 34 | JsonObject obj = jsonElement.getAsJsonObject(); 35 | if (obj.get("id") == null) return; 36 | 37 | //Load quest 38 | if(obj.get("entity_type") != null) { 39 | String questId = "." + obj.get("id").toString().substring(1, obj.get("id").toString().length() - 1); 40 | Path path = Path.of(rl.getNamespace() + questId + ".json"); 41 | 42 | datapackDialogPerEntityTypeList.put(path.toString(), obj); 43 | } 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/datapack/QuestJSONListener.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.datapack; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonElement; 5 | import com.google.gson.JsonObject; 6 | import dev.zanckor.mod.QuestApiMain; 7 | import dev.zanckor.mod.common.util.GsonManager; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.server.packs.resources.ResourceManager; 10 | import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener; 11 | import net.minecraft.util.profiling.ProfilerFiller; 12 | import net.minecraftforge.event.AddReloadListenerEvent; 13 | 14 | import java.nio.file.Path; 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | 18 | public class QuestJSONListener extends SimpleJsonResourceReloadListener { 19 | public static HashMap datapackQuestList = new HashMap<>(); 20 | 21 | public QuestJSONListener(Gson gson, String name) { 22 | super(gson, name); 23 | } 24 | 25 | public static void register(AddReloadListenerEvent e) { 26 | e.addListener(new QuestJSONListener(GsonManager.gson, "questapi/quest")); 27 | } 28 | 29 | @Override 30 | protected void apply(Map jsonElementMap, ResourceManager resourceManager, ProfilerFiller profilerFiller) { 31 | QuestApiMain.LOGGER.debug("Loaded quest datapack"); 32 | 33 | jsonElementMap.forEach((rl, jsonElement) -> { 34 | JsonObject obj = jsonElement.getAsJsonObject(); 35 | if (obj.get("id") == null) return; 36 | 37 | //Load quest 38 | if(obj.get("goals") != null) { 39 | String questId = "." + obj.get("id").toString().substring(1, obj.get("id").toString().length() - 1); 40 | Path path = Path.of(rl.getNamespace() + questId + ".json"); 41 | 42 | datapackQuestList.put(path.toString(), obj); 43 | } 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/menu/MenuHandler.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.menu; 2 | 3 | import dev.zanckor.mod.QuestApiMain; 4 | import dev.zanckor.mod.server.menu.questmaker.QuestMakerMenu; 5 | import net.minecraft.world.inventory.MenuType; 6 | import net.minecraftforge.common.extensions.IForgeMenuType; 7 | import net.minecraftforge.registries.DeferredRegister; 8 | import net.minecraftforge.registries.ForgeRegistries; 9 | import net.minecraftforge.registries.RegistryObject; 10 | 11 | public class MenuHandler { 12 | public static final DeferredRegister> REGISTER = DeferredRegister.create(ForgeRegistries.MENU_TYPES, QuestApiMain.MOD_ID); 13 | 14 | public static final RegistryObject> QUEST_DEFAULT_MENU = REGISTER.register("quest_default_menu", 15 | () -> IForgeMenuType.create(((windowId, inv, data) -> new QuestMakerMenu(windowId)))); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/network/SendQuestPacket.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.network; 2 | 3 | import net.minecraft.server.level.ServerPlayer; 4 | import net.minecraft.world.entity.player.Player; 5 | import net.minecraftforge.network.NetworkDirection; 6 | import net.minecraftforge.network.PacketDistributor; 7 | 8 | public class SendQuestPacket { 9 | 10 | public static void NEAR(Player player, Object packet, double radius) { 11 | NetworkHandler.CHANNEL.send( 12 | PacketDistributor.NEAR.with(() -> 13 | new PacketDistributor.TargetPoint(player.getX(), player.getY(), player.getZ(), radius, player.level().dimension())), 14 | packet); 15 | } 16 | 17 | public static void ALL(Object packet) { 18 | NetworkHandler.CHANNEL.send(PacketDistributor.ALL.noArg(), packet); 19 | } 20 | 21 | 22 | public static void TO_CLIENT(Player player, Object packet) { 23 | NetworkHandler.CHANNEL.sendTo(packet, ((ServerPlayer) player).connection.connection, NetworkDirection.PLAY_TO_CLIENT); 24 | } 25 | 26 | public static void TO_SERVER(Object packet) { 27 | NetworkHandler.CHANNEL.sendToServer(packet); 28 | } 29 | 30 | 31 | public static void DIMENSION(Player player, Object packet) { 32 | NetworkHandler.CHANNEL.send( 33 | PacketDistributor.DIMENSION.with(() -> 34 | player.level().dimension()), 35 | packet); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/network/message/dialogoption/AddQuest.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.network.message.dialogoption; 2 | 3 | import dev.zanckor.example.common.enumregistry.enumdialog.EnumDialogOption; 4 | import dev.zanckor.mod.common.network.handler.ServerHandler; 5 | import net.minecraft.network.FriendlyByteBuf; 6 | import net.minecraft.world.entity.player.Player; 7 | import net.minecraftforge.network.NetworkEvent; 8 | 9 | import java.util.function.Supplier; 10 | 11 | public class AddQuest { 12 | 13 | /** 14 | * Add question 15 | */ 16 | 17 | EnumDialogOption optionType; 18 | int optionID; 19 | 20 | public AddQuest(EnumDialogOption optionType, int optionID) { 21 | this.optionType = optionType; 22 | this.optionID = optionID; 23 | } 24 | 25 | public AddQuest(FriendlyByteBuf buffer) { 26 | optionType = buffer.readEnum(EnumDialogOption.class); 27 | optionID = buffer.readInt(); 28 | } 29 | 30 | public void encodeBuffer(FriendlyByteBuf buffer) { 31 | buffer.writeEnum(optionType); 32 | buffer.writeInt(optionID); 33 | } 34 | 35 | 36 | public static void handler(AddQuest msg, Supplier ctx) { 37 | ctx.get().enqueueWork(() -> { 38 | Player player = ctx.get().getSender(); 39 | 40 | ServerHandler.addQuest(player, msg.optionType, msg.optionID); 41 | }); 42 | 43 | ctx.get().setPacketHandled(true); 44 | } 45 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/network/message/dialogoption/CloseDialog.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.network.message.dialogoption; 2 | 3 | import dev.zanckor.mod.common.network.handler.ClientHandler; 4 | import net.minecraft.network.FriendlyByteBuf; 5 | import net.minecraftforge.api.distmarker.Dist; 6 | import net.minecraftforge.fml.DistExecutor; 7 | import net.minecraftforge.network.NetworkEvent; 8 | 9 | import java.util.function.Supplier; 10 | 11 | public class CloseDialog { 12 | 13 | public CloseDialog() { 14 | } 15 | 16 | public CloseDialog(FriendlyByteBuf buffer) { 17 | } 18 | 19 | public void encodeBuffer(FriendlyByteBuf buffer) { 20 | } 21 | 22 | 23 | public static void handler(CloseDialog msg, Supplier ctx) { 24 | ctx.get().enqueueWork(() -> { 25 | DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ClientHandler.closeDialog()); 26 | }); 27 | 28 | ctx.get().setPacketHandled(true); 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/network/message/dialogoption/DialogRequestPacket.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.network.message.dialogoption; 2 | 3 | import dev.zanckor.example.common.enumregistry.enumdialog.EnumDialogOption; 4 | import dev.zanckor.mod.common.network.handler.ServerHandler; 5 | import net.minecraft.network.FriendlyByteBuf; 6 | import net.minecraft.server.level.ServerPlayer; 7 | import net.minecraft.world.entity.Entity; 8 | import net.minecraft.world.item.Item; 9 | import net.minecraftforge.network.NetworkEvent; 10 | 11 | import java.util.UUID; 12 | import java.util.function.Supplier; 13 | 14 | public class DialogRequestPacket { 15 | EnumDialogOption optionType; 16 | int optionID; 17 | UUID entityUUID; 18 | String resourceLocation; 19 | Item item; 20 | DisplayDialog.NpcType npcType; 21 | 22 | public DialogRequestPacket(EnumDialogOption optionType, int optionID, Entity npc, String resourceLocation, Item item, DisplayDialog.NpcType npcType) { 23 | this.optionType = optionType; 24 | this.optionID = optionID; 25 | this.entityUUID = npc.getUUID(); 26 | this.resourceLocation = resourceLocation; 27 | this.item = item; 28 | this.npcType = npcType; 29 | } 30 | 31 | public void encodeBuffer(FriendlyByteBuf buffer) { 32 | buffer.writeEnum(optionType); 33 | buffer.writeInt(optionID); 34 | 35 | encodeNpcType(buffer); 36 | } 37 | 38 | private void encodeNpcType(FriendlyByteBuf buf) { 39 | buf.writeEnum(npcType); 40 | 41 | switch (npcType) { 42 | case ITEM -> buf.writeItem(item.getDefaultInstance()); 43 | case UUID -> buf.writeUUID(entityUUID); 44 | case RESOURCE_LOCATION -> buf.writeUtf(resourceLocation); 45 | } 46 | } 47 | 48 | 49 | public DialogRequestPacket(FriendlyByteBuf buffer) { 50 | optionType = buffer.readEnum(EnumDialogOption.class); 51 | optionID = buffer.readInt(); 52 | decodeNpcType(buffer); 53 | } 54 | 55 | public void decodeNpcType(FriendlyByteBuf buf) { 56 | npcType = buf.readEnum(DisplayDialog.NpcType.class); 57 | 58 | switch (npcType) { 59 | case ITEM -> item = buf.readItem().getItem(); 60 | case UUID -> entityUUID = buf.readUUID(); 61 | case RESOURCE_LOCATION -> resourceLocation = buf.readUtf(); 62 | } 63 | } 64 | 65 | public static void handler(DialogRequestPacket msg, Supplier ctx) { 66 | ctx.get().enqueueWork(() -> { 67 | ServerPlayer player = ctx.get().getSender(); 68 | 69 | ServerHandler.requestDialog(player, msg.optionID, msg.optionType, msg.entityUUID, msg.resourceLocation, msg.item, msg.npcType); 70 | }); 71 | 72 | ctx.get().setPacketHandled(true); 73 | } 74 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/network/message/npcmarker/ValidNPCMarker.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.network.message.npcmarker; 2 | 3 | import dev.zanckor.mod.common.network.handler.ClientHandler; 4 | import dev.zanckor.mod.common.util.GsonManager; 5 | import net.minecraft.network.FriendlyByteBuf; 6 | import net.minecraftforge.api.distmarker.Dist; 7 | import net.minecraftforge.fml.DistExecutor; 8 | import net.minecraftforge.network.NetworkEvent; 9 | 10 | import java.io.File; 11 | import java.io.FileNotFoundException; 12 | import java.io.FileReader; 13 | import java.io.IOException; 14 | import java.nio.file.Files; 15 | import java.util.*; 16 | import java.util.function.Supplier; 17 | 18 | import static dev.zanckor.api.database.LocateHash.dialogPerCompoundTag; 19 | import static dev.zanckor.api.database.LocateHash.dialogPerEntityType; 20 | 21 | public class ValidNPCMarker { 22 | List entityTypeList; 23 | Map entityTagMap; 24 | 25 | public ValidNPCMarker() { 26 | } 27 | 28 | public ValidNPCMarker(FriendlyByteBuf buffer) { 29 | String entityStringList = buffer.readUtf(); 30 | ArrayList entityTypeList = new ArrayList<>(Arrays.asList(entityStringList.substring(1, entityStringList.length() - 1).split(","))); 31 | 32 | this.entityTypeList = entityTypeList; 33 | entityTagMap = buffer.readMap(FriendlyByteBuf::readUtf, FriendlyByteBuf::readUtf); 34 | } 35 | 36 | public void encodeBuffer(FriendlyByteBuf buffer) { 37 | try { 38 | buffer.writeUtf(dialogPerEntityType.keySet().toString()); 39 | 40 | //Convert String - File to String - String 41 | HashMap entityTagMap = new HashMap<>(); 42 | 43 | for (String key : dialogPerCompoundTag.keySet()) { 44 | String fileContent = Files.readString(dialogPerCompoundTag.get(key).toPath()); 45 | 46 | entityTagMap.put(key, fileContent); 47 | } 48 | 49 | buffer.writeMap(entityTagMap, FriendlyByteBuf::writeUtf, FriendlyByteBuf::writeUtf); 50 | 51 | 52 | } catch (IOException e) { 53 | throw new RuntimeException(e); 54 | } 55 | } 56 | 57 | 58 | public static void handler(ValidNPCMarker msg, Supplier ctx) { 59 | ctx.get().enqueueWork(() -> { 60 | DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ClientHandler.setAvailableEntityTypeForQuest(msg.entityTypeList, msg.entityTagMap)); 61 | }); 62 | 63 | ctx.get().setPacketHandled(true); 64 | } 65 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/network/message/quest/ActiveQuestList.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.network.message.quest; 2 | 3 | import dev.zanckor.api.filemanager.quest.codec.user.UserQuest; 4 | import dev.zanckor.mod.QuestApiMain; 5 | import dev.zanckor.mod.common.network.handler.ClientHandler; 6 | import dev.zanckor.mod.common.util.GsonManager; 7 | import net.minecraft.network.FriendlyByteBuf; 8 | import net.minecraftforge.api.distmarker.Dist; 9 | import net.minecraftforge.fml.DistExecutor; 10 | import net.minecraftforge.network.NetworkEvent; 11 | 12 | import java.io.File; 13 | import java.io.IOException; 14 | import java.nio.file.Files; 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | import java.util.UUID; 18 | import java.util.function.Supplier; 19 | 20 | public class ActiveQuestList { 21 | List questFileList = new ArrayList<>(); 22 | int listSize; 23 | 24 | 25 | public ActiveQuestList(UUID playerUUID) { 26 | try { 27 | File[] activeQuests = QuestApiMain.getActiveQuest(QuestApiMain.getUserFolder(playerUUID)).toFile().listFiles(); 28 | 29 | if(activeQuests == null) return; 30 | 31 | for (File file : activeQuests) { 32 | questFileList.add(Files.readString(file.toPath())); 33 | } 34 | 35 | } catch (IOException e) { 36 | throw new RuntimeException(e); 37 | } 38 | } 39 | 40 | public ActiveQuestList(FriendlyByteBuf buffer) { 41 | listSize = buffer.readInt(); 42 | 43 | for (int i = 0; i < listSize; i++) { 44 | questFileList.add(buffer.readUtf()); 45 | } 46 | } 47 | 48 | public void encodeBuffer(FriendlyByteBuf buffer) { 49 | buffer.writeInt(questFileList.size()); 50 | 51 | for (int i = 0; i < questFileList.size(); i++) { 52 | buffer.writeUtf(questFileList.get(i)); 53 | } 54 | } 55 | 56 | 57 | public static void handler(ActiveQuestList msg, Supplier ctx) { 58 | ctx.get().enqueueWork(() -> { 59 | List userQuestList = new ArrayList<>(); 60 | msg.questFileList.forEach(questFile -> { 61 | try { 62 | userQuestList.add((UserQuest) GsonManager.getJsonClass(questFile, UserQuest.class)); 63 | } catch (IOException e) { 64 | throw new RuntimeException(e); 65 | } 66 | }); 67 | 68 | DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ClientHandler.setActiveQuestList(userQuestList)); 69 | }); 70 | 71 | ctx.get().setPacketHandled(true); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/network/message/quest/QuestDataPacket.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.network.message.quest; 2 | 3 | import dev.zanckor.mod.common.network.handler.ServerHandler; 4 | import dev.zanckor.mod.common.util.MCUtil; 5 | import net.minecraft.network.FriendlyByteBuf; 6 | import net.minecraft.server.level.ServerLevel; 7 | import net.minecraft.server.level.ServerPlayer; 8 | import net.minecraft.world.entity.Entity; 9 | import net.minecraft.world.entity.LivingEntity; 10 | import net.minecraftforge.network.NetworkEvent; 11 | 12 | import java.io.IOException; 13 | import java.util.UUID; 14 | import java.util.function.Supplier; 15 | 16 | public class QuestDataPacket { 17 | 18 | /** 19 | * Packet to execute a quest handler from client to server 20 | *

21 | * Be careful using this from client side, may cause exploits 22 | */ 23 | 24 | Enum quest; 25 | UUID entity; 26 | 27 | public QuestDataPacket(Enum quest, Entity entity) { 28 | this.quest = quest; 29 | this.entity = entity.getUUID(); 30 | } 31 | 32 | public QuestDataPacket(FriendlyByteBuf buffer) { 33 | this.quest = buffer.readEnum(Enum.class); 34 | this.entity = buffer.readUUID(); 35 | } 36 | 37 | public void encodeBuffer(FriendlyByteBuf buffer) { 38 | buffer.writeEnum(quest); 39 | buffer.writeUUID(entity); 40 | } 41 | 42 | 43 | public static void handler(QuestDataPacket msg, Supplier ctx) { 44 | ctx.get().enqueueWork(() -> { 45 | try { 46 | ServerPlayer player = ctx.get().getSender(); 47 | LivingEntity entity = (LivingEntity) MCUtil.getEntityByUUID((ServerLevel) player.level(), msg.entity); 48 | 49 | ServerHandler.questHandler(msg.quest, player, entity); 50 | } catch (IOException e) { 51 | throw new RuntimeException(e); 52 | } 53 | }); 54 | 55 | ctx.get().setPacketHandled(true); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/network/message/quest/ServerQuestList.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.network.message.quest; 2 | 3 | import dev.zanckor.mod.QuestApiMain; 4 | import dev.zanckor.mod.common.network.handler.ClientHandler; 5 | import net.minecraft.network.FriendlyByteBuf; 6 | import net.minecraftforge.api.distmarker.Dist; 7 | import net.minecraftforge.fml.DistExecutor; 8 | import net.minecraftforge.network.NetworkEvent; 9 | 10 | import java.io.File; 11 | import java.io.IOException; 12 | import java.nio.file.Files; 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | import java.util.function.Supplier; 16 | 17 | public class ServerQuestList { 18 | List questFileList = new ArrayList<>(); 19 | int listSize; 20 | 21 | 22 | public ServerQuestList() { 23 | try { 24 | File[] serverQuests = QuestApiMain.serverQuests.toFile().listFiles(); 25 | 26 | for (File file : serverQuests) { 27 | questFileList.add(Files.readString(file.toPath())); 28 | } 29 | 30 | } catch (IOException e) { 31 | throw new RuntimeException(e); 32 | } 33 | } 34 | 35 | public ServerQuestList(FriendlyByteBuf buffer) { 36 | listSize = buffer.readInt(); 37 | 38 | for (int i = 0; i < listSize; i++) { 39 | questFileList.add(buffer.readUtf()); 40 | } 41 | } 42 | 43 | public void encodeBuffer(FriendlyByteBuf buffer) { 44 | buffer.writeInt(questFileList.size()); 45 | 46 | for (int i = 0; i < questFileList.size(); i++) { 47 | buffer.writeUtf(questFileList.get(i)); 48 | } 49 | 50 | } 51 | 52 | 53 | public static void handler(ServerQuestList msg, Supplier ctx) { 54 | ctx.get().enqueueWork(() -> { 55 | DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ClientHandler.setAvailableServerQuestList(msg.questFileList)); 56 | }); 57 | 58 | ctx.get().setPacketHandled(true); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/network/message/quest/TimerPacket.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.network.message.quest; 2 | 3 | import dev.zanckor.mod.common.network.handler.ServerHandler; 4 | import net.minecraft.network.FriendlyByteBuf; 5 | import net.minecraftforge.network.NetworkEvent; 6 | 7 | import java.util.function.Supplier; 8 | 9 | public class TimerPacket { 10 | 11 | public TimerPacket() { 12 | } 13 | 14 | public TimerPacket(FriendlyByteBuf buffer) { 15 | } 16 | 17 | public void encodeBuffer(FriendlyByteBuf buffer) { 18 | } 19 | 20 | 21 | public static void handler(TimerPacket msg, Supplier ctx) { 22 | ctx.get().enqueueWork(() -> { 23 | ServerHandler.questTimer(ctx.get().getSender().serverLevel()); 24 | }); 25 | 26 | ctx.get().setPacketHandled(true); 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/network/message/quest/ToastPacket.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.network.message.quest; 2 | 3 | import dev.zanckor.mod.common.network.handler.ClientHandler; 4 | import net.minecraft.network.FriendlyByteBuf; 5 | import net.minecraftforge.api.distmarker.Dist; 6 | import net.minecraftforge.fml.DistExecutor; 7 | import net.minecraftforge.network.NetworkEvent; 8 | 9 | import java.util.function.Supplier; 10 | 11 | public class ToastPacket { 12 | 13 | String questName; 14 | 15 | public ToastPacket(String questName) { 16 | this.questName = questName; 17 | } 18 | 19 | public ToastPacket(FriendlyByteBuf buffer) { 20 | this.questName = buffer.readUtf(); 21 | } 22 | 23 | public void encodeBuffer(FriendlyByteBuf buffer) { 24 | buffer.writeUtf(questName); 25 | } 26 | 27 | 28 | public static void handler(ToastPacket msg, Supplier ctx) { 29 | ctx.get().enqueueWork(() -> { 30 | DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ClientHandler.toastQuestCompleted(msg.questName)); 31 | }); 32 | 33 | ctx.get().setPacketHandled(true); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/network/message/screen/ModifyTrackedQuests.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.network.message.screen; 2 | 3 | import dev.zanckor.api.filemanager.quest.codec.user.UserQuest; 4 | import dev.zanckor.mod.common.network.handler.ClientHandler; 5 | import dev.zanckor.mod.common.util.GsonManager; 6 | import net.minecraft.network.FriendlyByteBuf; 7 | import net.minecraftforge.api.distmarker.Dist; 8 | import net.minecraftforge.fml.DistExecutor; 9 | import net.minecraftforge.network.NetworkEvent; 10 | 11 | import java.io.IOException; 12 | import java.util.function.Supplier; 13 | 14 | public class ModifyTrackedQuests { 15 | private UserQuest userQuest; 16 | private Boolean addQuest; 17 | 18 | 19 | public ModifyTrackedQuests(boolean addQuest, UserQuest userQuest) { 20 | this.userQuest = userQuest; 21 | this.addQuest = addQuest; 22 | } 23 | 24 | public ModifyTrackedQuests(FriendlyByteBuf buffer) { 25 | try { 26 | addQuest = buffer.readBoolean(); 27 | userQuest = (UserQuest) GsonManager.getJsonClass(buffer.readUtf(), UserQuest.class); 28 | } catch (IOException e) { 29 | throw new RuntimeException(e); 30 | } 31 | } 32 | 33 | public void encodeBuffer(FriendlyByteBuf buffer) { 34 | buffer.writeBoolean(addQuest); 35 | buffer.writeUtf(GsonManager.gson.toJson(userQuest)); 36 | } 37 | 38 | 39 | public static void handler(ModifyTrackedQuests msg, Supplier ctx) { 40 | ctx.get().enqueueWork(() -> { 41 | DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ClientHandler.modifyTrackedQuests(msg.addQuest, msg.userQuest)); 42 | }); 43 | 44 | ctx.get().setPacketHandled(true); 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/network/message/screen/OpenVanillaEntityScreen.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.network.message.screen; 2 | 3 | import dev.zanckor.mod.common.util.MCUtil; 4 | import net.minecraft.network.FriendlyByteBuf; 5 | import net.minecraft.server.level.ServerLevel; 6 | import net.minecraft.world.InteractionHand; 7 | import net.minecraft.world.entity.Entity; 8 | import net.minecraft.world.entity.player.Player; 9 | import net.minecraftforge.network.NetworkEvent; 10 | 11 | import java.util.UUID; 12 | import java.util.function.Supplier; 13 | 14 | public class OpenVanillaEntityScreen { 15 | 16 | UUID entityUUID; 17 | 18 | 19 | public OpenVanillaEntityScreen(UUID entityUUID) { 20 | this.entityUUID = entityUUID; 21 | } 22 | 23 | public OpenVanillaEntityScreen(FriendlyByteBuf buffer) { 24 | entityUUID = buffer.readUUID(); 25 | } 26 | 27 | public void encodeBuffer(FriendlyByteBuf buffer) { 28 | buffer.writeUUID(entityUUID); 29 | } 30 | 31 | 32 | public static void handler(OpenVanillaEntityScreen msg, Supplier ctx) { 33 | ctx.get().enqueueWork(() -> { 34 | Player player = ctx.get().getSender(); 35 | Entity entity = MCUtil.getEntityByUUID((ServerLevel) ctx.get().getSender().level(), msg.entityUUID); 36 | 37 | player.setShiftKeyDown(true); 38 | player.interactOn(entity, InteractionHand.MAIN_HAND); 39 | }); 40 | 41 | ctx.get().setPacketHandled(true); 42 | } 43 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/network/message/screen/RemovedQuest.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.network.message.screen; 2 | 3 | import dev.zanckor.mod.common.network.handler.ClientHandler; 4 | import net.minecraft.network.FriendlyByteBuf; 5 | import net.minecraftforge.api.distmarker.Dist; 6 | import net.minecraftforge.fml.DistExecutor; 7 | import net.minecraftforge.network.NetworkEvent; 8 | 9 | import java.util.function.Supplier; 10 | 11 | public class RemovedQuest { 12 | private String id; 13 | 14 | 15 | public RemovedQuest(String questID) { 16 | this.id = questID; 17 | } 18 | 19 | public RemovedQuest(FriendlyByteBuf buffer) { 20 | id = buffer.readUtf(); 21 | } 22 | 23 | public void encodeBuffer(FriendlyByteBuf buffer) { 24 | buffer.writeUtf(id); 25 | } 26 | 27 | 28 | public static void handler(RemovedQuest msg, Supplier ctx) { 29 | ctx.get().enqueueWork(() -> { 30 | DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ClientHandler.removeQuest(msg.id)); 31 | }); 32 | 33 | ctx.get().setPacketHandled(true); 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/network/message/screen/RequestActiveQuests.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.network.message.screen; 2 | 3 | import dev.zanckor.mod.common.network.SendQuestPacket; 4 | import dev.zanckor.mod.common.network.message.quest.ActiveQuestList; 5 | import net.minecraft.network.FriendlyByteBuf; 6 | import net.minecraft.world.entity.player.Player; 7 | import net.minecraftforge.network.NetworkEvent; 8 | 9 | import java.util.function.Supplier; 10 | 11 | public class RequestActiveQuests { 12 | 13 | public RequestActiveQuests() { 14 | } 15 | 16 | public RequestActiveQuests(FriendlyByteBuf buffer) { 17 | 18 | } 19 | 20 | public void encodeBuffer(FriendlyByteBuf buffer) { 21 | 22 | } 23 | 24 | 25 | public static void handler(RequestActiveQuests msg, Supplier ctx) { 26 | ctx.get().enqueueWork(() -> { 27 | Player player = ctx.get().getSender(); 28 | SendQuestPacket.TO_CLIENT(player, new ActiveQuestList(player.getUUID())); 29 | }); 30 | 31 | ctx.get().setPacketHandled(true); 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/network/message/screen/UpdateQuestTracked.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.network.message.screen; 2 | 3 | import dev.zanckor.api.filemanager.quest.codec.user.UserQuest; 4 | import dev.zanckor.mod.common.network.handler.ClientHandler; 5 | import dev.zanckor.mod.common.util.GsonManager; 6 | import net.minecraft.network.FriendlyByteBuf; 7 | import net.minecraftforge.api.distmarker.Dist; 8 | import net.minecraftforge.fml.DistExecutor; 9 | import net.minecraftforge.network.NetworkEvent; 10 | 11 | import java.io.File; 12 | import java.io.IOException; 13 | import java.nio.file.Files; 14 | import java.util.function.Supplier; 15 | 16 | public class UpdateQuestTracked { 17 | private String userQuest; 18 | 19 | 20 | public UpdateQuestTracked(UserQuest userQuest) { 21 | this.userQuest = GsonManager.gson.toJson(userQuest); 22 | } 23 | 24 | public UpdateQuestTracked(FriendlyByteBuf buffer) { 25 | userQuest = buffer.readUtf(); 26 | } 27 | 28 | public void encodeBuffer(FriendlyByteBuf buffer) { 29 | buffer.writeUtf(userQuest); 30 | } 31 | 32 | 33 | public static void handler(UpdateQuestTracked msg, Supplier ctx) { 34 | ctx.get().enqueueWork(() -> { 35 | try { 36 | File file = File.createTempFile("userQuest", "json"); 37 | Files.writeString(file.toPath(), msg.userQuest); 38 | UserQuest userQuest = (UserQuest) GsonManager.getJsonClass(file, UserQuest.class); 39 | 40 | if(userQuest != null) DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ClientHandler.updateQuestTracked(userQuest)); 41 | } catch (IOException e) { 42 | throw new RuntimeException(e); 43 | } 44 | }); 45 | 46 | ctx.get().setPacketHandled(true); 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/util/GsonManager.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.util; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.GsonBuilder; 5 | import dev.zanckor.api.filemanager.FileAbstract; 6 | import net.minecraft.resources.ResourceLocation; 7 | 8 | import java.io.File; 9 | import java.io.FileReader; 10 | import java.io.FileWriter; 11 | import java.io.IOException; 12 | 13 | public class GsonManager { 14 | public static Gson gson = new Gson(); 15 | 16 | public static FileAbstract getJsonClass(File file, Class fileClass) throws IOException { 17 | if (!file.exists()) return null; 18 | 19 | FileReader reader = new FileReader(file); 20 | FileAbstract dialog = GsonManager.gson.fromJson(reader, fileClass); 21 | reader.close(); 22 | 23 | return dialog; 24 | } 25 | 26 | public static FileAbstract getJsonClass(String file, Class fileClass) throws IOException { 27 | return GsonManager.gson.fromJson(file, fileClass); 28 | } 29 | 30 | public static void writeJson(File file, T fileClass) throws IOException { 31 | FileWriter writer = new FileWriter(file); 32 | writer.write(GsonManager.gson.toJson(fileClass)); 33 | writer.flush(); 34 | writer.close(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/util/Mathematic.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.util; 2 | 3 | import net.minecraft.util.Mth; 4 | import net.minecraft.util.RandomSource; 5 | import net.minecraft.world.phys.Vec3; 6 | import org.apache.commons.lang3.Range; 7 | import org.joml.Matrix4f; 8 | import org.lwjgl.BufferUtils; 9 | 10 | import java.nio.FloatBuffer; 11 | 12 | public class Mathematic { 13 | public static boolean numberBetween(double number, double min, double max) { 14 | Range range = Range.between(min, max); 15 | 16 | return range.contains(number); 17 | } 18 | 19 | public static boolean vec3NumberBetween(Vec3 vec3, Vec3 vec32, double min, double max) { 20 | Range rangeX = Range.between(vec32.x + min, vec32.x + max); 21 | Range rangeY = Range.between(vec32.y + min, vec32.y + max); 22 | Range rangeZ = Range.between(vec32.z + min, vec32.z + max); 23 | 24 | return rangeX.contains(vec3.x) && rangeY.contains(vec3.y) && rangeZ.contains(vec3.z); 25 | } 26 | 27 | public static int numberRandomizerBetween(int min, int max) { 28 | int randomizer = (int) Mth.randomBetween(RandomSource.createNewThreadLocalInstance(), min, max); 29 | return randomizer; 30 | } 31 | 32 | public static Vec3 simpleMatrixToVec3(Matrix4f matrix4f) { 33 | FloatBuffer buffer = BufferUtils.createFloatBuffer(16); 34 | matrix4f.get(buffer); 35 | 36 | Vec3 vec3 = new Vec3(buffer.get(3), buffer.get(7), buffer.get(11)); 37 | 38 | return vec3; 39 | } 40 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/common/util/Timer.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.common.util; 2 | 3 | import com.google.common.collect.HashBasedTable; 4 | import com.google.common.collect.Table; 5 | 6 | import java.util.UUID; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | public class Timer { 10 | 11 | private static final Table ACTIVE_COOLDOWNS_TABLE = HashBasedTable.create(); 12 | private static final Table ACTIVE_TICKERS_TABLE = HashBasedTable.create(); 13 | 14 | public static boolean canUseWithCooldown(UUID playerUUID, String cooldownKey, float delayInSeconds) { 15 | Long timeInMillis = ACTIVE_COOLDOWNS_TABLE.get(playerUUID, cooldownKey); 16 | 17 | if (timeInMillis != null) { 18 | return calculateCooldownRemainder(timeInMillis) <= 0L; 19 | } 20 | 21 | updateCooldown(playerUUID, cooldownKey, delayInSeconds); 22 | return true; 23 | } 24 | 25 | public static void updateCooldown(UUID playerUUID, String cooldownKey, float delayInSeconds) { 26 | ACTIVE_COOLDOWNS_TABLE.put(playerUUID, cooldownKey, System.currentTimeMillis() + TimeUnit.SECONDS.toMillis((long) delayInSeconds)); 27 | } 28 | 29 | public static long remainingTime(UUID playerUUID, String cooldownKey) { 30 | Long timeInMillis = ACTIVE_COOLDOWNS_TABLE.get(playerUUID, cooldownKey); 31 | 32 | if (timeInMillis == null) return -1; 33 | 34 | return calculateCooldownRemainder(timeInMillis); 35 | } 36 | 37 | public static boolean existsTimer(UUID playerUUID, String cooldownKey) { 38 | Long timeInMillis = ACTIVE_COOLDOWNS_TABLE.get(playerUUID, cooldownKey); 39 | 40 | return (timeInMillis != null); 41 | } 42 | 43 | public static long calculateCooldownRemainder(long timeInMillis) { 44 | return timeInMillis - System.currentTimeMillis(); 45 | } 46 | 47 | public static boolean canUseWithTicker(UUID playerUUID, String tickerKey, boolean isFirstTickValid, int maxTicks) { 48 | Integer timeInTicks = ACTIVE_TICKERS_TABLE.get(playerUUID, tickerKey); 49 | 50 | if (timeInTicks != null) { 51 | if (calculateTickRemainder(maxTicks, timeInTicks) <= 0) { 52 | updateTicker(playerUUID, tickerKey, 0); 53 | return true; 54 | } 55 | 56 | updateTicker(playerUUID, tickerKey, timeInTicks + 1); 57 | return false; 58 | } 59 | 60 | updateTicker(playerUUID, tickerKey, 0); 61 | return isFirstTickValid; 62 | } 63 | 64 | private static int calculateTickRemainder(int maxTicks, int timeInTicks) { 65 | return maxTicks - timeInTicks; 66 | } 67 | 68 | public static void updateTicker(UUID playerUUID, String tickerKey, int newValue) { 69 | ACTIVE_TICKERS_TABLE.put(playerUUID, tickerKey, newValue); 70 | } 71 | 72 | public static void clearTimers(UUID playerUUID) { 73 | ACTIVE_COOLDOWNS_TABLE.row(playerUUID).clear(); 74 | ACTIVE_TICKERS_TABLE.row(playerUUID).clear(); 75 | } 76 | 77 | public static void clearTimer(UUID playerUUID, String tickerKey) { 78 | ACTIVE_COOLDOWNS_TABLE.remove(playerUUID, tickerKey); 79 | ACTIVE_TICKERS_TABLE.remove(playerUUID, tickerKey); 80 | } 81 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/server/event/StartDialog.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.server.event; 2 | 3 | import dev.zanckor.api.database.LocateHash; 4 | import dev.zanckor.api.filemanager.dialog.abstractdialog.AbstractDialogRequirement; 5 | import dev.zanckor.api.filemanager.dialog.codec.NPCConversation; 6 | import dev.zanckor.api.filemanager.quest.register.QuestTemplateRegistry; 7 | import dev.zanckor.example.common.enumregistry.EnumRegistry; 8 | import dev.zanckor.mod.common.util.GsonManager; 9 | import net.minecraft.resources.ResourceLocation; 10 | import net.minecraft.world.entity.Entity; 11 | import net.minecraft.world.entity.player.Player; 12 | import net.minecraft.world.item.Item; 13 | 14 | import java.io.File; 15 | import java.io.IOException; 16 | import java.nio.file.Path; 17 | 18 | public class StartDialog { 19 | 20 | /** 21 | * @param player The player 22 | * @param globalDialogID Dialog ID of dialog file player will see. Example: collect_items_dialog.json 23 | * @throws IOException Exception fired when server cannot read json file 24 | */ 25 | 26 | public static void loadDialog(Player player, String globalDialogID, Entity entity) throws IOException { 27 | Path path = LocateHash.getDialogLocation(globalDialogID); 28 | 29 | File dialogFile = path.toFile(); 30 | LocateHash.currentGlobalDialog.put(player, dialogFile.getName().substring(0, dialogFile.getName().length() - 5)); 31 | 32 | NPCConversation dialog = (NPCConversation) GsonManager.getJsonClass(dialogFile, NPCConversation.class); 33 | 34 | 35 | for (int dialog_id = dialog.getDialog().size() - 1; dialog_id >= 0; dialog_id--) { 36 | if (dialog.getDialog().get(dialog_id).getServerRequirements().getType() == null) continue; 37 | Enum requirementEnum = EnumRegistry.getEnum(dialog.getDialog().get(dialog_id).getServerRequirements().getType(), EnumRegistry.getDialogRequirement()); 38 | 39 | AbstractDialogRequirement dialogRequirement = QuestTemplateRegistry.getDialogRequirement(requirementEnum); 40 | 41 | if (dialogRequirement != null && dialogRequirement.handler(player, dialog, dialog_id, entity)) return; 42 | } 43 | } 44 | public static void loadDialog(Player player, String globalDialogID, String resourceLocation) throws IOException { 45 | Path path = LocateHash.getDialogLocation(globalDialogID); 46 | 47 | File dialogFile = path.toFile(); 48 | LocateHash.currentGlobalDialog.put(player, dialogFile.getName().substring(0, dialogFile.getName().length() - 5)); 49 | 50 | NPCConversation dialog = (NPCConversation) GsonManager.getJsonClass(dialogFile, NPCConversation.class); 51 | 52 | 53 | for (int dialog_id = dialog.getDialog().size() - 1; dialog_id >= 0; dialog_id--) { 54 | if (dialog.getDialog().get(dialog_id).getServerRequirements().getType() == null) continue; 55 | Enum requirementEnum = EnumRegistry.getEnum(dialog.getDialog().get(dialog_id).getServerRequirements().getType(), EnumRegistry.getDialogRequirement()); 56 | 57 | AbstractDialogRequirement dialogRequirement = QuestTemplateRegistry.getDialogRequirement(requirementEnum); 58 | 59 | if (dialogRequirement != null && dialogRequirement.handler(player, dialog, dialog_id, resourceLocation)) return; 60 | } 61 | } 62 | 63 | public static void loadDialog(Player player, String globalDialogID, Item item) throws IOException { 64 | Path path = LocateHash.getDialogLocation(globalDialogID); 65 | 66 | File dialogFile = path.toFile(); 67 | LocateHash.currentGlobalDialog.put(player, dialogFile.getName().substring(0, dialogFile.getName().length() - 5)); 68 | 69 | NPCConversation dialog = (NPCConversation) GsonManager.getJsonClass(dialogFile, NPCConversation.class); 70 | 71 | 72 | for (int dialog_id = dialog.getDialog().size() - 1; dialog_id >= 0; dialog_id--) { 73 | if (dialog.getDialog().get(dialog_id).getServerRequirements().getType() == null) continue; 74 | Enum requirementEnum = EnumRegistry.getEnum(dialog.getDialog().get(dialog_id).getServerRequirements().getType(), EnumRegistry.getDialogRequirement()); 75 | 76 | AbstractDialogRequirement dialogRequirement = QuestTemplateRegistry.getDialogRequirement(requirementEnum); 77 | 78 | if (dialogRequirement != null && dialogRequirement.handler(player, dialog, dialog_id, item)) return; 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/server/menu/questmaker/QuestMakerMenu.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.server.menu.questmaker; 2 | 3 | import dev.zanckor.mod.common.menu.MenuHandler; 4 | import net.minecraft.world.entity.player.Player; 5 | import net.minecraft.world.inventory.AbstractContainerMenu; 6 | import net.minecraft.world.item.ItemStack; 7 | 8 | public class QuestMakerMenu extends AbstractContainerMenu { 9 | public QuestMakerMenu(int id) { 10 | super(MenuHandler.QUEST_DEFAULT_MENU.get(), id); 11 | } 12 | 13 | 14 | 15 | @Override 16 | public ItemStack quickMoveStack(Player player, int stack) { 17 | return null; 18 | } 19 | 20 | @Override 21 | public boolean stillValid(Player player) { 22 | return true; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/dev/zanckor/mod/server/startdialog/StartDialog.java: -------------------------------------------------------------------------------- 1 | package dev.zanckor.mod.server.startdialog; 2 | 3 | import dev.zanckor.api.database.LocateHash; 4 | import dev.zanckor.api.filemanager.dialog.abstractdialog.AbstractDialogRequirement; 5 | import dev.zanckor.api.filemanager.dialog.codec.NPCConversation; 6 | import dev.zanckor.api.filemanager.quest.register.QuestTemplateRegistry; 7 | import dev.zanckor.example.common.enumregistry.EnumRegistry; 8 | import dev.zanckor.mod.common.util.GsonManager; 9 | import net.minecraft.resources.ResourceLocation; 10 | import net.minecraft.world.entity.Entity; 11 | import net.minecraft.world.entity.player.Player; 12 | import net.minecraft.world.item.Item; 13 | 14 | import java.io.File; 15 | import java.io.IOException; 16 | import java.nio.file.Path; 17 | 18 | public class StartDialog { 19 | 20 | /** 21 | * @param player The player 22 | * @param globalDialogID Dialog ID of dialog file player will see. Example: collect_items_dialog.json 23 | * @throws IOException Exception fired when server cannot read json file 24 | */ 25 | 26 | public static void loadDialog(Player player, String globalDialogID, Entity entity) throws IOException { 27 | Path path = LocateHash.getDialogLocation(globalDialogID); 28 | 29 | File dialogFile = path.toFile(); 30 | LocateHash.currentGlobalDialog.put(player, dialogFile.getName().substring(0, dialogFile.getName().length() - 5)); 31 | 32 | NPCConversation dialog = (NPCConversation) GsonManager.getJsonClass(dialogFile, NPCConversation.class); 33 | 34 | 35 | for (int dialog_id = dialog.getDialog().size() - 1; dialog_id >= 0; dialog_id--) { 36 | if (dialog.getDialog().get(dialog_id).getServerRequirements().getType() == null) continue; 37 | Enum requirementEnum = EnumRegistry.getEnum(dialog.getDialog().get(dialog_id).getServerRequirements().getType(), EnumRegistry.getDialogRequirement()); 38 | 39 | AbstractDialogRequirement dialogRequirement = QuestTemplateRegistry.getDialogRequirement(requirementEnum); 40 | 41 | if (dialogRequirement != null && dialogRequirement.handler(player, dialog, dialog_id, entity)) return; 42 | } 43 | } 44 | public static void loadDialog(Player player, String globalDialogID, String resourceLocation) throws IOException { 45 | Path path = LocateHash.getDialogLocation(globalDialogID); 46 | 47 | File dialogFile = path.toFile(); 48 | LocateHash.currentGlobalDialog.put(player, dialogFile.getName().substring(0, dialogFile.getName().length() - 5)); 49 | 50 | NPCConversation dialog = (NPCConversation) GsonManager.getJsonClass(dialogFile, NPCConversation.class); 51 | 52 | 53 | for (int dialog_id = dialog.getDialog().size() - 1; dialog_id >= 0; dialog_id--) { 54 | if (dialog.getDialog().get(dialog_id).getServerRequirements().getType() == null) continue; 55 | Enum requirementEnum = EnumRegistry.getEnum(dialog.getDialog().get(dialog_id).getServerRequirements().getType(), EnumRegistry.getDialogRequirement()); 56 | 57 | AbstractDialogRequirement dialogRequirement = QuestTemplateRegistry.getDialogRequirement(requirementEnum); 58 | 59 | if (dialogRequirement != null && dialogRequirement.handler(player, dialog, dialog_id, resourceLocation)) return; 60 | } 61 | } 62 | 63 | public static void loadDialog(Player player, String globalDialogID, Item item) throws IOException { 64 | Path path = LocateHash.getDialogLocation(globalDialogID); 65 | 66 | File dialogFile = path.toFile(); 67 | LocateHash.currentGlobalDialog.put(player, dialogFile.getName().substring(0, dialogFile.getName().length() - 5)); 68 | 69 | NPCConversation dialog = (NPCConversation) GsonManager.getJsonClass(dialogFile, NPCConversation.class); 70 | 71 | 72 | for (int dialog_id = dialog.getDialog().size() - 1; dialog_id >= 0; dialog_id--) { 73 | if (dialog.getDialog().get(dialog_id).getServerRequirements().getType() == null) continue; 74 | Enum requirementEnum = EnumRegistry.getEnum(dialog.getDialog().get(dialog_id).getServerRequirements().getType(), EnumRegistry.getDialogRequirement()); 75 | 76 | AbstractDialogRequirement dialogRequirement = QuestTemplateRegistry.getDialogRequirement(requirementEnum); 77 | 78 | if (dialogRequirement != null && dialogRequirement.handler(player, dialog, dialog_id, item)) return; 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /src/main/resources/META-INF/mods.toml: -------------------------------------------------------------------------------- 1 | modLoader="javafml" 2 | loaderVersion="[45,)" 3 | license="MIT License" 4 | [[mods]] 5 | modId="questapi" 6 | version="1.3.8" 7 | displayName="Quest API" 8 | logoFile="questapi.png" 9 | authors="Zanckor" 10 | description=''' 11 | QuestApi is a forge library that allows modders and modpack makers to add easily quests & dialogs by npc, command... 12 | just adding a few .json with easy portability between words, servers and versions. 13 | ''' -------------------------------------------------------------------------------- /src/main/resources/assets/questapi/lang/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "key.categories.QuestApi": "Quest API", 3 | "key.questapi.quest_menu": "Open Quest Menu", 4 | "entity.questapi.quest_npc": "Quest NPC Test", 5 | 6 | "tracker.questapi.quest_type": "Quest Type: ", 7 | "tracker.questapi.quest": "Quest: ", 8 | "tracker.questapi.time_limit": "Time limit: ", 9 | 10 | "quest_type.questapi.interact_entity": "Interact with entity", 11 | "quest_type.questapi.kill": "Kill", 12 | "quest_type.questapi.move_to": "Move to coords", 13 | "quest_type.questapi.collect": "Collect", 14 | "quest_type.questapi.collect_with_nbt": "Collect item with NBT", 15 | "quest_type.questapi.xp": "Obtain XP", 16 | "quest_type.questapi.locate_structure": "Locate structure", 17 | 18 | "quest_name.questapi.collect_items": "Collect Items", 19 | "quest_name.questapi.collect_items_tag": "Collect items with tag", 20 | "quest_name.questapi.interact_with_cow_and_pig": "Interact with cows and pigs", 21 | "quest_name.questapi.kill_entities": "Kill entities", 22 | "quest_name.questapi.locate_structure": "Locate structure", 23 | "quest_name.questapi.locate_coords": "Move to coordinates", 24 | "quest_name.questapi.multiple_quests": "Multiple quests", 25 | 26 | "dialog_text.questapi.collect_items_dialog.salute": "Hello adventurer, I need help with a task, would you help me?", 27 | "dialog_text.questapi.collect_items_dialog.quest_accepted": "Thanks, I need 2 gold and 1 iron ingots.", 28 | "dialog_text.questapi.collect_items_dialog.quest_declined": "I see, it doesn\u0027t matter, if you change your mind I\u0027ll stay here.", 29 | "dialog_text.questapi.collect_items_dialog.repeat_salute": "Ey, I see you\u0027re back, have you changed your mind?", 30 | "dialog_text.questapi.collect_items_dialog.work_in_progress": "Hello traveler, how are you doing on the quest?", 31 | "dialog_text.questapi.collect_items_dialog.greetings": "Thank you very much for helping me traveler.", 32 | 33 | "dialog_text.questapi.collect_items_dialog.salute.accept": "Sure, tell me what you need.", 34 | "dialog_text.questapi.collect_items_dialog.salute.deny": "No, sorry, I don\u0027t have time.", 35 | "dialog_text.questapi.collect_items_dialog.quest_accepted.add_quest": "I\u0027ll start right now.", 36 | "dialog_text.questapi.collect_items_dialog.quest_declined.close_dialog": "Okay...", 37 | "dialog_text.questapi.collect_items_dialog.repeat_salute.accept": "Sure, tell me what you need.", 38 | "dialog_text.questapi.collect_items_dialog.repeat_salute.deny": "No, sorry, I don\u0027t have time.", 39 | "dialog_text.questapi.collect_items_dialog.work_in_progress.close_dialog": "Okay, almost there.", 40 | "dialog_text.questapi.collect_items_dialog.greetings.response": "No problem." 41 | } -------------------------------------------------------------------------------- /src/main/resources/assets/questapi/lang/es_ES.json: -------------------------------------------------------------------------------- 1 | { 2 | "key.categories.QuestApi": "Quest API", 3 | "key.questapi.quest_menu": "Abrir menu de misiones", 4 | "entity.questapi.quest_npc": "Quest NPC Test", 5 | 6 | "tracker.questapi.quest_type": "Tipo de mision: ", 7 | "tracker.questapi.quest": "Mision: ", 8 | "tracker.questapi.time_limit": "Tiempo limite: ", 9 | 10 | 11 | "quest_type.questapi.interact_entity": "Interactuar con entidad", 12 | "quest_type.questapi.kill": "Matar", 13 | "quest_type.questapi.move_to": "Moverte a las coordenadas", 14 | "quest_type.questapi.collect": "Recollectar items", 15 | "quest_type.questapi.collect_with_nbt": "Recolectar item con NBT", 16 | "quest_type.questapi.xp": "Obtener XP", 17 | "quest_type.questapi.locate_structure": "Encontrar estructura", 18 | 19 | "quest_name.questapi.collect_items": "Recolectar items", 20 | "quest_name.questapi.collect_items_tag": "Recolectar items con tag", 21 | "quest_name.questapi.interact_with_cow_and_pig": "Interactuar con vacas y cerdos", 22 | "quest_name.questapi.kill_entities": "Matar entidades", 23 | "quest_name.questapi.locate_structure": "Encontrar estructura", 24 | "quest_name.questapi.locate_coords": "Moverte a coordenadas", 25 | "quest_name.questapi.multiple_quests": "Multiples misiones", 26 | 27 | "dialog_text.questapi.collect_items_dialog.salute": "Hola aventurero, necesito ayuda con una tarea, ¿me ayudarías?", 28 | "dialog_text.questapi.collect_items_dialog.quest_accepted": "Gracias, necesito 2 lingotes de oro y 1 de hierro.", 29 | "dialog_text.questapi.collect_items_dialog.quest_declined": "Ya veo, no importa, si cambias de opinión me quedo aquí.", 30 | "dialog_text.questapi.collect_items_dialog.repeat_salute": "Ey, veo que has vuelto, ¿has cambiado de opinión?", 31 | "dialog_text.questapi.collect_items_dialog.work_in_progress": "Hola viajero, ¿cómo te va en la búsqueda?", 32 | "dialog_text.questapi.collect_items_dialog.greetings": "Muchas gracias por ayudarme viajero.", 33 | 34 | "dialog_text.questapi.collect_items_dialog.salute.accept": "Claro, dime lo que necesitas.", 35 | "dialog_text.questapi.collect_items_dialog.salute.deny": "No, lo siento, no tengo tiempo.", 36 | "dialog_text.questapi.collect_items_dialog.quest_accepted.add_quest": "Empezaré ahora mismo.", 37 | "dialog_text.questapi.collect_items_dialog.quest_declined.close_dialog": "Vale...", 38 | "dialog_text.questapi.collect_items_dialog.repeat_salute.accept": "Claro, dime que necesitas.", 39 | "dialog_text.questapi.collect_items_dialog.repeat_salute.deny": "No, lo siento, no tengo tiempo.", 40 | "dialog_text.questapi.collect_items_dialog.work_in_progress.close_dialog": "Si, me queda poco.", 41 | "dialog_text.questapi.collect_items_dialog.greetings.response": "De nada." 42 | } -------------------------------------------------------------------------------- /src/main/resources/assets/questapi/textures/gui/dialog_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zanckor/QuestAPI/531a3a540ea6eb606027ead3090fd6b1b8bf8c17/src/main/resources/assets/questapi/textures/gui/dialog_background.png -------------------------------------------------------------------------------- /src/main/resources/assets/questapi/textures/gui/minimalist_dialog_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zanckor/QuestAPI/531a3a540ea6eb606027ead3090fd6b1b8bf8c17/src/main/resources/assets/questapi/textures/gui/minimalist_dialog_background.png -------------------------------------------------------------------------------- /src/main/resources/assets/questapi/textures/gui/quest_maker_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zanckor/QuestAPI/531a3a540ea6eb606027ead3090fd6b1b8bf8c17/src/main/resources/assets/questapi/textures/gui/quest_maker_bg.png -------------------------------------------------------------------------------- /src/main/resources/assets/questapi/textures/gui/questlog_api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zanckor/QuestAPI/531a3a540ea6eb606027ead3090fd6b1b8bf8c17/src/main/resources/assets/questapi/textures/gui/questlog_api.png -------------------------------------------------------------------------------- /src/main/resources/data/questapi/dialog/collect_items_dialog.json: -------------------------------------------------------------------------------- 1 | { 2 | "dialog": [ 3 | { 4 | "id": 0, 5 | "dialogText": "dialog_text.questapi.collect_items_dialog.salute", 6 | "requirements": { 7 | "type": "QUEST", 8 | "quest_id": "questapi.collect_items", 9 | "requirement_status": "NOT_OBTAINED" 10 | }, 11 | "options": [ 12 | { 13 | "text": "dialog_text.questapi.collect_items_dialog.salute.accept", 14 | "type": "OPEN_DIALOG", 15 | "global_id": "questapi.collect_items_dialog", 16 | "dialog": 1 17 | }, 18 | { 19 | "text": "dialog_text.questapi.collect_items_dialog.salute.deny", 20 | "type": "OPEN_DIALOG", 21 | "global_id": "questapi.collect_items_dialog", 22 | "dialog": 2 23 | } 24 | ] 25 | }, 26 | { 27 | "id": 1, 28 | "dialogText": "dialog_text.questapi.collect_items_dialog.quest_accepted", 29 | "requirements": { 30 | }, 31 | "options": [ 32 | { 33 | "text": "dialog_text.questapi.collect_items_dialog.quest_accepted.add_quest", 34 | "type": "ADD_QUEST", 35 | "quest_id": "questapi.collect_items" 36 | } 37 | ] 38 | }, 39 | { 40 | "id": 2, 41 | "dialogText": "dialog_text.questapi.collect_items_dialog.quest_declined", 42 | "requirements": { 43 | }, 44 | "options": [ 45 | { 46 | "text": "dialog_text.questapi.collect_items_dialog.quest_declined.close_dialog", 47 | "type": "CLOSE_DIALOG" 48 | } 49 | ] 50 | }, 51 | { 52 | "id": 3, 53 | "dialogText": "dialog_text.questapi.collect_items_dialog.repeat_salute", 54 | "requirements": { 55 | "type": "DIALOG", 56 | "dialog_id": 2, 57 | "requirement_status": "READ" 58 | }, 59 | "options": [ 60 | { 61 | "text": "dialog_text.questapi.collect_items_dialog.repeat_salute.accept", 62 | "type": "OPEN_DIALOG", 63 | "global_id": "questapi.collect_items_dialog", 64 | "dialog": 1 65 | }, 66 | { 67 | "text": "dialog_text.questapi.collect_items_dialog.repeat_salute.deny", 68 | "type": "OPEN_DIALOG", 69 | "global_id": "questapi.collect_items_dialog", 70 | "dialog": 2 71 | } 72 | ] 73 | }, 74 | { 75 | "id": 4, 76 | "dialogText": "dialog_text.questapi.collect_items_dialog.work_in_progress", 77 | "requirements": { 78 | "type": "QUEST", 79 | "quest_id": "questapi.collect_items", 80 | "requirement_status": "IN_PROGRESS" 81 | }, 82 | "options": [ 83 | { 84 | "text": "dialog_text.questapi.collect_items_dialog.work_in_progress.close_dialog", 85 | "type": "CLOSE_DIALOG" 86 | } 87 | ] 88 | }, 89 | { 90 | "id": 5, 91 | "dialogText": "dialog_text.questapi.collect_items_dialog.greetings", 92 | "requirements": { 93 | "type": "QUEST", 94 | "quest_id": "questapi.collect_items", 95 | "requirement_status": "COMPLETED" 96 | }, 97 | "options": [ 98 | { 99 | "text": "dialog_text.questapi.collect_items_dialog.greetings.response", 100 | "type": "CLOSE_DIALOG" 101 | } 102 | ] 103 | } 104 | ] 105 | } -------------------------------------------------------------------------------- /src/main/resources/data/questapi/dialog/secondary_collect_items_dialog.json: -------------------------------------------------------------------------------- 1 | { 2 | "dialog": [ 3 | { 4 | "id": 0, 5 | "dialogText": "dialog_text.questapi.collect_items_dialog.salute", 6 | "requirements": { 7 | "type": "QUEST", 8 | "quest_id": "questapi.collect_items", 9 | "requirement_status": "NOT_OBTAINED" 10 | }, 11 | "options": [ 12 | { 13 | "text": "dialog_text.questapi.collect_items_dialog.salute.accept", 14 | "type": "OPEN_DIALOG", 15 | "global_id": "questapi.collect_items_dialog", 16 | "dialog": 1 17 | }, 18 | { 19 | "text": "dialog_text.questapi.collect_items_dialog.salute.deny", 20 | "type": "OPEN_DIALOG", 21 | "global_id": "questapi.collect_items_dialog", 22 | "dialog": 2 23 | } 24 | ] 25 | }, 26 | { 27 | "id": 1, 28 | "dialogText": "dialog_text.questapi.collect_items_dialog.quest_accepted", 29 | "requirements": { 30 | }, 31 | "options": [ 32 | { 33 | "text": "dialog_text.questapi.collect_items_dialog.quest_accepted.add_quest", 34 | "type": "ADD_QUEST", 35 | "quest_id": "questapi.collect_items" 36 | } 37 | ] 38 | }, 39 | { 40 | "id": 2, 41 | "dialogText": "dialog_text.questapi.collect_items_dialog.quest_declined", 42 | "requirements": { 43 | }, 44 | "options": [ 45 | { 46 | "text": "dialog_text.questapi.collect_items_dialog.quest_declined.close_dialog", 47 | "type": "CLOSE_DIALOG" 48 | } 49 | ] 50 | }, 51 | { 52 | "id": 3, 53 | "dialogText": "dialog_text.questapi.collect_items_dialog.repeat_salute", 54 | "requirements": { 55 | "type": "DIALOG", 56 | "dialog_id": 2, 57 | "requirement_status": "READ" 58 | }, 59 | "options": [ 60 | { 61 | "text": "dialog_text.questapi.collect_items_dialog.repeat_salute.accept", 62 | "type": "OPEN_DIALOG", 63 | "global_id": "questapi.collect_items_dialog", 64 | "dialog": 1 65 | }, 66 | { 67 | "text": "dialog_text.questapi.collect_items_dialog.repeat_salute.deny", 68 | "type": "OPEN_DIALOG", 69 | "global_id": "questapi.collect_items_dialog", 70 | "dialog": 2 71 | } 72 | ] 73 | }, 74 | { 75 | "id": 4, 76 | "dialogText": "dialog_text.questapi.collect_items_dialog.work_in_progress", 77 | "requirements": { 78 | "type": "QUEST", 79 | "quest_id": "questapi.collect_items", 80 | "requirement_status": "IN_PROGRESS" 81 | }, 82 | "options": [ 83 | { 84 | "text": "dialog_text.questapi.collect_items_dialog.work_in_progress.close_dialog", 85 | "type": "CLOSE_DIALOG" 86 | } 87 | ] 88 | }, 89 | { 90 | "id": 5, 91 | "dialogText": "dialog_text.questapi.collect_items_dialog.greetings", 92 | "requirements": { 93 | "type": "QUEST", 94 | "quest_id": "questapi.collect_items", 95 | "requirement_status": "COMPLETED" 96 | }, 97 | "options": [ 98 | { 99 | "text": "dialog_text.questapi.collect_items_dialog.greetings.response", 100 | "type": "CLOSE_DIALOG" 101 | } 102 | ] 103 | } 104 | ], 105 | "identifier": "minimalist_questapi" 106 | } -------------------------------------------------------------------------------- /src/main/resources/data/questapi/quest/collect_items.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "collect_items", 3 | "title": "quest_name.questapi.collect_items", 4 | "hasTimeLimit": false, 5 | "timeLimitInSeconds": 0, 6 | "goals": [ 7 | { 8 | "type": "COLLECT", 9 | "target": "minecraft:iron_ingot", 10 | "amount": 1 11 | }, 12 | { 13 | "type": "COLLECT", 14 | "target": "minecraft:gold_ingot", 15 | "amount": 1 16 | }, 17 | { 18 | "type": "KILL", 19 | "target": "minecraft:pig", 20 | "amount": 1 21 | }, 22 | { 23 | "type": "XP", 24 | "target": "", 25 | "amount": 3 26 | } 27 | ], 28 | "rewards": [ 29 | { 30 | "type": "XP", 31 | "tag": "LEVEL", 32 | "amount": 10 33 | } 34 | ], 35 | "requirements": [ 36 | { 37 | "type": "XP", 38 | "requirements_min": 0, 39 | "requirements_max": 10 40 | } 41 | ] 42 | } -------------------------------------------------------------------------------- /src/main/resources/data/questapi/quest/collect_items_tag.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "collect_items_tag", 3 | "title": "quest_name.questapi.collect_items_tag", 4 | "hasTimeLimit": false, 5 | "timeLimitInSeconds": 0, 6 | "goals": [ 7 | { 8 | "type": "COLLECT_WITH_NBT", 9 | "target": "minecraft:iron_ingot", 10 | "amount": 1, 11 | "additionalClassData": { 12 | "display": "Iron" 13 | } 14 | } 15 | ], 16 | "rewards": [ 17 | { 18 | "type": "XP", 19 | "tag": "LEVEL", 20 | "amount": 10 21 | } 22 | ], 23 | "requirements": [ 24 | { 25 | "type": "XP", 26 | "requirements_min": 0, 27 | "requirements_max": 10 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /src/main/resources/data/questapi/quest/interact_entity.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "interact_entity", 3 | "title": "quest_name.questapi.interact_with_cow_and_pig", 4 | "hasTimeLimit": false, 5 | "timeLimitInSeconds": 0, 6 | "goals": [ 7 | { 8 | "type": "INTERACT_ENTITY", 9 | "target": "minecraft:pig", 10 | "amount": 1 11 | } 12 | ], 13 | "rewards": [ 14 | { 15 | "type": "QUEST", 16 | "tag": "questapi.kill_entities", 17 | "amount": 1 18 | } 19 | ], 20 | "requirements": [ 21 | { 22 | "type": "XP", 23 | "requirements_min": 0, 24 | "requirements_max": 10 25 | } 26 | ] 27 | } -------------------------------------------------------------------------------- /src/main/resources/data/questapi/quest/kill_entities.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "kill_entities", 3 | "title": "quest_name.questapi.kill_entities", 4 | 5 | "hasTimeLimit": true, 6 | "timeLimitInSeconds": 10, 7 | "goals": [ 8 | { 9 | "type": "KILL", 10 | "target": "minecraft:pig", 11 | "amount": 1 12 | }, 13 | { 14 | "type": "KILL", 15 | "target": "minecraft:cow", 16 | "amount": 1 17 | } 18 | ], 19 | "rewards": [ 20 | { 21 | "type": "LOOT_TABLE", 22 | "tag": "minecraft:chests/bastion_treasure", 23 | "amount": 1 24 | } 25 | ], 26 | "requirements": [ 27 | { 28 | "type": "XP", 29 | "requirements_min": 0, 30 | "requirements_max": 10 31 | } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /src/main/resources/data/questapi/quest/move_to_coords.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "move_to_coords", 3 | "title": "quest_name.questapi.locate_coords", 4 | "goals": [ 5 | { 6 | "type": "MOVE_TO", 7 | "target": "0 / 0 / 0", 8 | "amount": 1, 9 | "additionalListData": [0, 0, 0] 10 | } 11 | ], 12 | "hasTimeLimit": false, 13 | "timeLimitInSeconds": 0, 14 | "requirements": [ 15 | { 16 | "type": "XP", 17 | "requirements_min": 40, 18 | "requirements_max": 50 19 | } 20 | ], 21 | "rewards": [ 22 | { 23 | "type": "ITEM", 24 | "tag": "minecraft:coal", 25 | "amount": 64 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /src/main/resources/data/questapi/quest/multiple_quests.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "multiple_quests", 3 | "title": "quest_name.questapi.multiple_quests", 4 | "goals": [ 5 | { 6 | "type": "MOVE_TO", 7 | "target": "0 / 0 / 0", 8 | "amount": 1, 9 | "additionalListData": [0, 0, 0] 10 | }, 11 | { 12 | "type": "COLLECT", 13 | "target": "minecraft:gold_ingot", 14 | "amount": 1 15 | }, 16 | { 17 | "type": "XP", 18 | "target": "", 19 | "amount": 1 20 | } 21 | ], 22 | "hasTimeLimit": false, 23 | "timeLimitInSeconds": 0, 24 | "requirements": [ 25 | { 26 | "type": "XP", 27 | "requirements_min": 0, 28 | "requirements_max": 50 29 | } 30 | ], 31 | "rewards": [ 32 | { 33 | "type": "ITEM", 34 | "tag": "minecraft:coal", 35 | "amount": 64 36 | } 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "description": "examplemod resources", 4 | "pack_format": 9, 5 | "forge:resource_pack_format": 9, 6 | "forge:data_pack_format": 10 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/resources/questapi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zanckor/QuestAPI/531a3a540ea6eb606027ead3090fd6b1b8bf8c17/src/main/resources/questapi.png --------------------------------------------------------------------------------