diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index e6110c64e..7a6204d89 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -35,7 +35,7 @@ jobs: uses: softprops/action-gh-release@v1 with: name: Latest v1.0.2 dev - tag_name: mc1.20/6-v1.0.2 + tag_name: mc1.21/0-v1.0.4 body: \"changes\"=${{ github.event.head_commit.message }} token: ${{ secrets.GIT_TOKEN }} files: build/libs/*.jar diff --git a/API-DOCS.md b/API-DOCS.md index 74df18ffc..04491c09b 100644 --- a/API-DOCS.md +++ b/API-DOCS.md @@ -1,11 +1,14 @@ # API Documentation ## Introduction -Welcome to the **GenesisMC** API documentation. This document provides instructions on how to interact with GenesisMC's codebase for external plugin use, or contributing. + +Welcome to the **GenesisMC** API documentation. This document provides instructions on how to interact with GenesisMC's +codebase for external plugin use, or contributing. ## Adding the API to Gradle Kotlin Script -Just add the repository where the API is hosted to your `build.gradle.kts` file and the dependency. Ensure you have paperweight installed aswell, because GenesisMC uses NMS and CraftBukkit instances throughout the plugin and API +Just add the repository where the API is hosted to your `build.gradle.kts` file and the dependency. Ensure you have +paperweight installed aswell, because GenesisMC uses NMS and CraftBukkit instances throughout the plugin and API ```kotlin repositories { @@ -16,7 +19,7 @@ repositories { } dependencies { - implementation("io.github.Dueris:GenesisMC:mc1.20/6-v1.0.0") + implementation("io.github.Dueris:GenesisMC:mc1.21/0-v1.0.0") } ``` @@ -24,8 +27,11 @@ dependencies { Setting up GenesisMC to hook into it is quite simple, and doesnt require much work at all. -GenesisMC starts the Calio parser during its init process, meaning you need to add it to your dependencies list inside your `paper-plugin.yml` file. This guide will go over how to create new PowerTypes, Conditions, Actions, and how to even replace/remove instances of them within Genesis. +GenesisMC starts the Calio parser during its init process, meaning you need to add it to your dependencies list inside +your `paper-plugin.yml` file. This guide will go over how to create new PowerTypes, Conditions, Actions, and how to even +replace/remove instances of them within Genesis. What your depend list should look like: + ```yaml dependencies: server: @@ -38,197 +44,259 @@ dependencies: ## Creating a new PowerType -The Power system in Genesis works closely to the Apoli PowerType system, where each PowerType instance is a representation of a Power json inside the datapack. For example: +The Power system in Genesis works closely to the Apoli PowerType system, where each PowerType instance is a +representation of a Power json inside the datapack. For example: -I have a power in ``data/dueris/powers/test.json`` with the `"type"` field as `"apoli:test"`, and a PowerType of the type `"apoli:test"`. Calio will create a new instance of the PowerType and register it using defined AccessorKeys(more details bellow in the `Calio` section). +I have a power in ``data/dueris/powers/test.json`` with the `"type"` field as `"apoli:test"`, and a PowerType of the +type `"apoli:test"`. Calio will create a new instance of the PowerType and register it using defined AccessorKeys(more +details bellow in the `Calio` section). Lets start by creating a new class: + ```java public class ApoliExamplePower extends PowerType { } ``` -In Calio/Apoli, a PowerType is an extension of the FactoryHolder system which contains methods to create a valid instance for Calio to create the object. To create a FactoryHolder inside Calio during parsing, it reads the FactoryData provided by the FactoryHolder, which is defined by the method ``registerComponents(FactoryData data)``. FactoryData is the definition of a Constructor for the FactoryHolder. The first instance added is the first arg, the second being the second arg, etc. It also provides the key for the `"type"` field. +In Calio/Apoli, a PowerType is an extension of the FactoryHolder system which contains methods to create a valid +instance for Calio to create the object. To create a FactoryHolder inside Calio during parsing, it reads the FactoryData +provided by the FactoryHolder, which is defined by the method ``registerComponents(FactoryData data)``. FactoryData is +the definition of a Constructor for the FactoryHolder. The first instance added is the first arg, the second being the +second arg, etc. It also provides the key for the `"type"` field. With adding the constructor, it becomes: + ```java public class ApoliExamplePower extends PowerType { - public ApoliExamplePower(String name, String description, boolean hidden, FactoryJsonObject condition, int loading_priority) { - super(name, description, hidden, condition, loading_priority); - } + public ApoliExamplePower(String name, String description, boolean hidden, FactoryJsonObject condition, int loading_priority) { + super(name, description, hidden, condition, loading_priority); + } } ``` + Adding the method to create the FactoryData: + ```java public class ApoliExamplePower extends PowerType { - public ApoliExamplePower(String name, String description, boolean hidden, FactoryJsonObject condition, int loading_priority) { - super(name, description, hidden, condition, loading_priority); - } + public ApoliExamplePower(String name, String description, boolean hidden, FactoryJsonObject condition, int loading_priority) { + super(name, description, hidden, condition, loading_priority); + } - // registerComponents method. We call the PowerType.registerComponents method first to define those args - // from the base instead of Copy/Pasting its registerComponents method and adding to it. - // By default, the PowerType class does not contain a Namespace, which is why ofNamespace needs to be added. - // The way this is made allows for creating easy extensions of any power without too much struggle. - public static FactoryData registerComponents(FactoryData data) { - return PowerType.registerComponents(data).ofNamespace(new NamespacedKey("example", "apoli")); - } + // registerComponents method. We call the PowerType.registerComponents method first to define those args + // from the base instead of Copy/Pasting its registerComponents method and adding to it. + // By default, the PowerType class does not contain a Namespace, which is why ofNamespace needs to be added. + // The way this is made allows for creating easy extensions of any power without too much struggle. + public static FactoryData registerComponents(FactoryData data) { + return PowerType.registerComponents(data).ofNamespace(new NamespacedKey("example", "apoli")); + } } ``` -To Add your own fields to the power json, its as simple as adding the ``add`` method to the FactoryData building. The ``add`` method takes a FactoryDataDefiner, which is an Object that defines the 3 args needed for FactoryData building, or you can provide the 3 args and the FactoryData will create the instance for you. The method takes 3 params, a `String` key, a `Class` class type, which defines the type of class the arg will be, and a `T` default value. Gradle should throw a compile error if your class type provided and the default value do not match. The default value can be null. To add a required param, you can replace the default value with a `new RequiredInstance()`, and Calio will throw a ParseException if the value isnt provided. To add an optional param, its the same thing but with a `new OptionalInstance()`. Calio will provide null if not found. +To Add your own fields to the power json, its as simple as adding the ``add`` method to the FactoryData building. +The ``add`` method takes a FactoryDataDefiner, which is an Object that defines the 3 args needed for FactoryData +building, or you can provide the 3 args and the FactoryData will create the instance for you. The method takes 3 params, +a `String` key, a `Class` class type, which defines the type of class the arg will be, and a `T` default value. +Gradle should throw a compile error if your class type provided and the default value do not match. The default value +can be null. To add a required param, you can replace the default value with a `new RequiredInstance()`, and Calio will +throw a ParseException if the value isnt provided. To add an optional param, its the same thing but with +a `new OptionalInstance()`. Calio will provide null if not found. + ```java public class ApoliExamplePower extends PowerType { - private String welcomeMessage; - - public ApoliExamplePower(String name, String description, boolean hidden, FactoryJsonObject condition, int loading_priority, String welcomeMessage) { - super(name, description, hidden, condition, loading_priority); - } + private String welcomeMessage; - public static FactoryData registerComponents(FactoryData data) { - return PowerType.registerComponents(data).ofNamespace(new NamespacedKey("example", "apoli")) - /* | Field name | Class type | Default value | */ - .add("welcome_message", String.class, "Hello World!"); - } + public ApoliExamplePower(String name, String description, boolean hidden, FactoryJsonObject condition, int loading_priority, String welcomeMessage) { + super(name, description, hidden, condition, loading_priority); + } - public String welcomeMessage() { - return this.welcomeMessage; - } + public static FactoryData registerComponents(FactoryData data) { + return PowerType.registerComponents(data).ofNamespace(new NamespacedKey("example", "apoli")) + /* | Field name | Class type | Default value | */ + .add("welcome_message", String.class, "Hello World!"); + } + + public String welcomeMessage() { + return this.welcomeMessage; + } } ``` -By default, a PowerType is an implementation of a Listener instance, so there is no need to add `implements org.bukkit.Listener` to your class. However, if you are creating an external plugin, you will need to register your Class as a Listener with Bukkit, as Calio doesnt do this automagically. If you are contributing, then there is no need because during registration of the Power, GenesisMC takes care of this. +By default, a PowerType is an implementation of a Listener instance, so there is no need to +add `implements org.bukkit.Listener` to your class. However, if you are creating an external plugin, you will need to +register your Class as a Listener with Bukkit, as Calio doesnt do this automagically. If you are contributing, then +there is no need because during registration of the Power, GenesisMC takes care of this. Now that we have created our PowerType, lets register it. Its as simple as adding calling this method: + ```java // Registers the PowerType in the Calio "type" registry -CraftCalio.INSTANCE.register(ApoliExamplePower.class/*replace with your class*/); +CraftCalio.INSTANCE.register(ApoliExamplePower .class/*replace with your class*/); ``` ### Adding functionality to your PowerType + By default, PowerType provides Overridable methods that can be used to create your Power. The methods are as such: -| Method Name | Description | -|-------------|--------------------------------------------------------------------------------------------| +| Method Name | Description | +|-------------------|--------------------------------------------------------------------------------------| | tick | Acts as the run() method in BukkitRunnables | | tick(Player) | Ticks the PowerType on the Player that currently has the Power | | tickAsync(Player) | Ticks the PowerType on the Player that currently has the Power on the AsyncScheduler | For this example, we are going to use `tick(Player)`: + ```java public class ApoliExamplePower extends PowerType { - private String welcomeMessage; - - public ApoliExamplePower(String name, String description, boolean hidden, FactoryJsonObject condition, int loading_priority, String welcomeMessage) { - super(name, description, hidden, condition, loading_priority); - } + private String welcomeMessage; - public static FactoryData registerComponents(FactoryData data) { - return PowerType.registerComponents(data).ofNamespace(new NamespacedKey("example", "apoli")) - .add("welcome_message", String.class, "Hello World!"); - } + public ApoliExamplePower(String name, String description, boolean hidden, FactoryJsonObject condition, int loading_priority, String welcomeMessage) { + super(name, description, hidden, condition, loading_priority); + } - public String welcomeMessage() { - return this.welcomeMessage; - } + public static FactoryData registerComponents(FactoryData data) { + return PowerType.registerComponents(data).ofNamespace(new NamespacedKey("example", "apoli")) + .add("welcome_message", String.class, "Hello World!"); + } - @Override - public void tick(Player player) { - if (player.getGameMode().equals(GameMode.CREATIVE)) { - player.sendMessage(Component.text("Your in creative mode!")); - } - } + public String welcomeMessage() { + return this.welcomeMessage; + } + + @Override + public void tick(Player player) { + if (player.getGameMode().equals(GameMode.CREATIVE)) { + player.sendMessage(Component.text("Your in creative mode!")); + } + } } ``` -Now lets add functionality for our `welcome_message` field. If our instance was created successfully, then the provided `welcomeMessage` value should be the one that was provided in the json, or our default value: + +Now lets add functionality for our `welcome_message` field. If our instance was created successfully, then the +provided `welcomeMessage` value should be the one that was provided in the json, or our default value: + ```java public class ApoliExamplePower extends PowerType { - private String welcomeMessage; - - public ApoliExamplePower(String name, String description, boolean hidden, FactoryJsonObject condition, int loading_priority, String welcomeMessage) { - super(name, description, hidden, condition, loading_priority); - } + private String welcomeMessage; - public static FactoryData registerComponents(FactoryData data) { - return PowerType.registerComponents(data).ofNamespace(new NamespacedKey("example", "apoli")) - .add("welcome_message", String.class, "Hello World!"); - } + public ApoliExamplePower(String name, String description, boolean hidden, FactoryJsonObject condition, int loading_priority, String welcomeMessage) { + super(name, description, hidden, condition, loading_priority); + } - public String welcomeMessage() { - return this.welcomeMessage; - } + public static FactoryData registerComponents(FactoryData data) { + return PowerType.registerComponents(data).ofNamespace(new NamespacedKey("example", "apoli")) + .add("welcome_message", String.class, "Hello World!"); + } - @Override - public void tick(Player player) { - if (player.getGameMode().equals(GameMode.CREATIVE)) { - player.sendMessage(Component.text("Your in creative mode!")); - } - } + public String welcomeMessage() { + return this.welcomeMessage; + } - @EventHandler - public void onJoin(PlayerJoinEvent e) { - e.getPlayer().sendMessage(Component.text(welcomeMessage())); - } + @Override + public void tick(Player player) { + if (player.getGameMode().equals(GameMode.CREATIVE)) { + player.sendMessage(Component.text("Your in creative mode!")); + } + } + + @EventHandler + public void onJoin(PlayerJoinEvent e) { + e.getPlayer().sendMessage(Component.text(welcomeMessage())); + } } ``` -And thats about it! In this section of the tutorial we have learned how to create and register a new PowerType, and add functionality to our new power. + +And thats about it! In this section of the tutorial we have learned how to create and register a new PowerType, and add +functionality to our new power. ## Conditions -To create a new Condition, is a little bit weirder. The current Condition system wasnt really built with external plugins in mind, but its possible to hook into the Condition system with ease. +To create a new Condition, is a little bit weirder. The current Condition system wasnt really built with external +plugins in mind, but its possible to hook into the Condition system with ease. In this tutorial, we are going to add a new entity condition that checks if the entity is currently in spectator mode. -To register a Condition, you must first go through the ConditionExecutor to access the conditions `register` method. Each Condition class has its respective ConditionFactory class. A ConditionFactory is a builder for creating, registering, and calling Conditions. Conditions in GenesisMC are defined by a NamepacedKey as the associated type, and a Predicate to define if the condition is true or not. Each Condition type category has its own ConditionFactory. +To register a Condition, you must first go through the ConditionExecutor to access the conditions `register` method. +Each Condition class has its respective ConditionFactory class. A ConditionFactory is a builder for creating, +registering, and calling Conditions. Conditions in GenesisMC are defined by a NamepacedKey as the associated type, and a +Predicate to define if the condition is true or not. Each Condition type category has its own ConditionFactory. + ```java ConditionExecutor.entityConditions.register(new EntityConditions.ConditionFactory()); ``` Now, we are going to add our `"type"` param, which defines the type associated in the json, like "origins:sprinting": + ```java ConditionExecutor.entityConditions.register(new EntityConditions.ConditionFactory(new NamespacedKey("dueris", "in_spectator"))); ``` -The 2nd and last arg is the Predicate. In the EntityConditon ConditionFactory, it is a BiPredicate, condition object and the entity. Each ConditionFactory has a FactoryJsonObject as its condition provider, which is a set of methods for reading and parsing data within the JsonObject provided. For more info on FactoryJsonObjects, please see the Calio docs. +The 2nd and last arg is the Predicate. In the EntityConditon ConditionFactory, it is a BiPredicate, condition object and the entity. Each ConditionFactory has a FactoryJsonObject as its condition provider, +which is a set of methods for reading and parsing data within the JsonObject provided. For more info on +FactoryJsonObjects, please see the Calio docs. + ```java -ConditionExecutor.entityConditions.register(new EntityConditions.ConditionFactory(new NamespacedKey("dueris", "in_spectator"), (condition, entity) -> { - if (entity instanceof Player player) { - return player.getGameMode().equals(GameMode.SPECTATOR); +ConditionExecutor.entityConditions.register(new EntityConditions.ConditionFactory(new NamespacedKey("dueris", "in_spectator"), (condition,entity)->{ + if(entity instanceof +Player player){ + return player. + +getGameMode(). + +equals(GameMode.SPECTATOR); } - return false; -})); + return false; + })); ``` -Now we have a fully functioning condition added to the plugin! GenesisMC should automagically setup the rest of the registration to allow any origin to test the condition. + +Now we have a fully functioning condition added to the plugin! GenesisMC should automagically setup the rest of the +registration to allow any origin to test the condition. ## Actions -Creating a new Action is quite similar to creating a new Condition, but with ActionFactories instead. In this tutorial, we are going to create a new Action called "dueris:welcome", which will send a welcome message to a Player. The ActionFactory system is quite literally the same thing as the Condition system, but with different registry points and we use BiFunctions instead of BiPredicates, since we dont need a return value for the action. +Creating a new Action is quite similar to creating a new Condition, but with ActionFactories instead. In this tutorial, +we are going to create a new Action called "dueris:welcome", which will send a welcome message to a Player. The +ActionFactory system is quite literally the same thing as the Condition system, but with different registry points and +we use BiFunctions instead of BiPredicates, since we dont need a return value for the action. + ```java Actions.entityActions.register(new EntityActions.ActionFactory()); ``` Now we define our `"type"` param, like before: + ```java Actions.entityActions.register(new EntityActions.ActionFactory(new NamespacedKey("dueris", "welcome"))); ``` And lets add our functionality to our Action: + ```java -Actions.entityActions.register(new EntityActions.ActionFactory(new NamespacedKey("dueris", "welcome"), (action, entity) -> { - if (entity instanceof Player player) { - // We send the welcome message with a provided "message" param inside the Action. - player.sendMessage(Component.text(action.getString("message"))); - } -})); +Actions.entityActions.register(new EntityActions.ActionFactory(new NamespacedKey("dueris", "welcome"), (action,entity)->{ + if(entity instanceof +Player player){ + // We send the welcome message with a provided "message" param inside the Action. + player. + +sendMessage(Component.text(action.getString("message"))); + } + })); ``` And thats it! Almost the exact same thing as Condition registration, and the same process in the end aswell. ## PowerHolderComponent -The PowerHolderComponent class is the main utility class for accessing information about Powers. It holds and manages the switching of origins, adding and removal of powers, and a few misc things related to the PersistentDataContainer. Realistically, you only need to know a few things, how to get the powers of an entity, how to apply and remove powers, and setting the origin of the entity. +The PowerHolderComponent class is the main utility class for accessing information about Powers. It holds and manages +the switching of origins, adding and removal of powers, and a few misc things related to the PersistentDataContainer. +Realistically, you only need to know a few things, how to get the powers of an entity, how to apply and remove powers, +and setting the origin of the entity. ### Retrieving the Powers of the Entity -Lets start with getting any and all Powers of the entity. The method PowerHolderComponent.getPowers(Entity) returns all the Powers on all layers of the Entity, however if it is not a Player instance, it will return an empty list due to Entities not being able to hold Powers(yet): +Lets start with getting any and all Powers of the entity. The method PowerHolderComponent.getPowers(Entity) returns all +the Powers on all layers of the Entity, however if it is not a Player instance, it will return an empty list due to +Entities not being able to hold Powers(yet): + ```java Entity entity = /*your entity instance*/; List powers = PowerHolderComponent.getPowers(entity); @@ -236,17 +304,24 @@ List powers = PowerHolderComponent.getPowers(entity); Now lets get all the Powers of a specific type. There are 2 ways of retrieving this information. 1, is by providing the String of the type key, like "apoli:multiple" or "apoli:phasing": + ```java Entity entity = /*your entity instance*/; List phasingPowers = PowerHolderComponent.getPowers(entity, "apoli:phasing"); // Returns all the powers of the phasing powertype ``` -2, is by providing the PowerType *class* inside the source. This way allows GenesisMC to return that PowerType instance instead of the raw PowerType aswell, and is a lot faster than the 1st way. Lets do the same example as before, but with the other method. + +2, is by providing the PowerType *class* inside the source. This way allows GenesisMC to return that PowerType instance +instead of the raw PowerType aswell, and is a lot faster than the 1st way. Lets do the same example as before, but with +the other method. + ```java Entity entity = /*your entity instance*/; List phasingPowers = PowerHolderComponent.getPowers(entity, Phasing.class); ``` -Now we are going to get a *specific* Power from its *tag* instance now. A PowerType tag is the NamespacedKey assigned to the Power upon registration, and works the same way as the normal Minecraft registration. +Now we are going to get a *specific* Power from its *tag* instance now. A PowerType tag is the NamespacedKey assigned to +the Power upon registration, and works the same way as the normal Minecraft registration. + ```java Entity entity = /*your entity instance*/; PowerType phasingPower = PowerHolderComponent.getPower(entity, "origins:phasing"); @@ -254,7 +329,9 @@ PowerType phasingPower = PowerHolderComponent.getPower(entity, "origins:phasing" ### Applying and Removing Powers -Now lets apply a Power. To simplify the process, there is a different class that does this for you called the `PowerUtils` class. This class contains 2 methods, `grantPower` and `removePower`. Each method has the same args: +Now lets apply a Power. To simplify the process, there is a different class that does this for you called +the `PowerUtils` class. This class contains 2 methods, `grantPower` and `removePower`. Each method has the same args: + ``` (Nullable) CommandSender - allows for sending the return message from the `/power` command. If null, it wont send. PowerType - the Power to grant or remove @@ -264,43 +341,72 @@ boolean - suppresses the return message from the CommandSender and the debug sta ### Checking if a Player has a Power -Checking if an Entity has a Power is similar to retrieving them. We have 2 methods for this, using the PowerType class, and the String tag. +Checking if an Entity has a Power is similar to retrieving them. We have 2 methods for this, using the PowerType class, +and the String tag. Lets do it with a provided PowerType arg: + ```java Entity entity = /*your entity instance*/; -if (PowerHolderComponent.hasPowerType(entity, Phasing.class)) { - entity.sendMessage(Component.text("You have a phasing power!")); -} +if(PowerHolderComponent. + +hasPowerType(entity, Phasing .class)){ + entity. + +sendMessage(Component.text("You have a phasing power!")); + } ``` + When using the one with a provided String, it takes a Power *tag*, not a Power *type*: + ```java Entity entity = /*your entity instance*/; -if (PowerHolderComponent.hasPower(entity, "origins:phasing")) { - entity.sendMessage(Component.text("You have the phantom phasing power!")); -} +if(PowerHolderComponent. + +hasPower(entity, "origins:phasing")){ + entity. + +sendMessage(Component.text("You have the phantom phasing power!")); + } ``` ### Setting and Getting the Origin of a Player -To set the Origin of a Player, you need to get the Origin object, and Layer object. There are a few ways of getting a Layer or Origin, the easiest being in the `CraftApoli` class, which serves as a core utility class for the CraftApoli system. In this example, we will use the methods `getOriginFromTag` - returns the origin matching the tag, null if not found and `getLayersFromRegistry` - returns all the layers in the registrar. +To set the Origin of a Player, you need to get the Origin object, and Layer object. There are a few ways of getting a +Layer or Origin, the easiest being in the `CraftApoli` class, which serves as a core utility class for the CraftApoli +system. In this example, we will use the methods `getOriginFromTag` - returns the origin matching the tag, null if not +found and `getLayersFromRegistry` - returns all the layers in the registrar. Setting an origin is quite simple, and requires an Origin and Layer to set it: + ```java Player player = /*your player instance*/; /** * Sets the origin on the default layer provided by Origins/GenesisMC */ -PowerHolderComponent.setOrigin(player, CraftApoli.getOriginFromTag("origins:elytrian"), CraftApoli.getLayerFromTag("origins:origin")); +PowerHolderComponent. + +setOrigin(player, CraftApoli.getOriginFromTag("origins:elytrian"),CraftApoli. + +getLayerFromTag("origins:origin")); /** * Sets the origin on ALL layers in the GenesisMC registrar */ -for (Layer layer : CraftApoli.getLayersFromRegistry()) { - PowerHolderComponent.setOrigin(player, CraftApoli.getOriginFromTag("origins:elytrian"), layer); -} + for( +Layer layer :CraftApoli. + +getLayersFromRegistry()){ + PowerHolderComponent. + +setOrigin(player, CraftApoli.getOriginFromTag("origins:elytrian"),layer); + } ``` -To get the Origin on a Player, there are a few ways. In GenesisMC, each Layer for the player has an assigned Origin to it in a Map inside the PowerHolderComponent. To get a specific layer, you can provide a Layer argument to the `getOrigin` method and return that specific origin. If the Layer isnt specified, it will return the full Layer -> Origin Map. +To get the Origin on a Player, there are a few ways. In GenesisMC, each Layer for the player has an assigned Origin to +it in a Map inside the PowerHolderComponent. To get a specific layer, you can provide a Layer argument to +the `getOrigin` method and return that specific origin. If the Layer isnt specified, it will return the full Layer -> +Origin Map. + ```java Player player = /*your player instance*/; /** @@ -314,4 +420,5 @@ Map layerToOriginMap = PowerHolderComponent.getOrigin(player); Origin originsOrigin = PowerHolderComponent.getOrigin(player, CraftApoli.getLayerFromTag("origins:origin")); ``` -And thats it! That should cover everything important that you need to know for the GenesisMC CraftApoli system. Ping @dueris in the discord server if you have any questions regarding the API or specific functionalities of the plugin. +And thats it! That should cover everything important that you need to know for the GenesisMC CraftApoli system. Ping +@dueris in the discord server if you have any questions regarding the API or specific functionalities of the plugin. diff --git a/build.gradle.kts b/build.gradle.kts index 3ea23b756..75ecae42f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,7 +11,7 @@ plugins { id("io.github.goooler.shadow") version "8.1.7" apply true } -val paperweightVersion: String = "1.20.6-R0.1-SNAPSHOT" +val paperweightVersion: String = "1.21-R0.1-SNAPSHOT" allprojects { apply(plugin = "java") @@ -70,13 +70,13 @@ tasks { } } runServer { - minecraftVersion("1.20.6") + minecraftVersion("1.21") } } tasks.register("makePublisher") { dependsOn(tasks.shadowJar) - archiveFileName.set("genesis-v1.0.2-SNAPSHOT.jar") + archiveFileName.set("genesis-v1.0.4-SNAPSHOT.jar") from(sourceSets.main.get().output) } @@ -105,7 +105,7 @@ publishing { artifact(tasks.getByName("makePublisher")) { groupId = "io.github.dueris" artifactId = "genesis" - version = "v1.0.2-SNAPSHOT" + version = "v1.0.4-SNAPSHOT" } } repositories { diff --git a/calio/src/main/java/me/dueris/calio/CraftCalio.java b/calio/src/main/java/me/dueris/calio/CraftCalio.java index c6cb58a98..3d6ad30b8 100644 --- a/calio/src/main/java/me/dueris/calio/CraftCalio.java +++ b/calio/src/main/java/me/dueris/calio/CraftCalio.java @@ -1,7 +1,9 @@ package me.dueris.calio; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; import com.mojang.datafixers.util.Pair; import me.dueris.calio.data.*; import me.dueris.calio.data.AssetIdentifier.AssetType; @@ -38,14 +40,13 @@ public static NamespacedKey bukkitIdentifier(String namespace, String path) { } public static ResourceLocation nmsIdentifier(String namespace, String path) { - return new ResourceLocation(namespace, path); + return ResourceLocation.fromNamespaceAndPath(namespace, path); } /** * Add a datapack path to the list of directories to parse. * * @param path the path to be added - * @return void */ public void addDatapackPath(Path path) { datapackDirectoriesToParse.add(path.toFile()); @@ -54,8 +55,7 @@ public void addDatapackPath(Path path) { /** * A method to start parsing with a provided debug mode and ExecutorService. * - * @param debug a boolean indicating whether debugging is enabled - * @param threadPool an ExecutorService for managing threads + * @param debug a boolean indicating whether debugging is enabled */ public void start(boolean debug) { this.isDebugging = debug; @@ -116,13 +116,13 @@ public void start(boolean debug) { }); }); this.keys.stream().sorted(Comparator.comparingInt(AccessorKey::getPriority)).forEach(accessorKey -> datapackDirectoriesToParse.forEach(root -> { - packLoop: for (File datapack : root.listFiles()) { try { FileReader fileReader = FileReaderFactory.createFileReader(datapack.toPath()); if (fileReader == null) continue; List files = fileReader.listFiles(); HashMap, Integer> newLoadingPrioritySortedMap = new HashMap<>(); + fileLoop: for (String file : files) { file = file.replace("/", "\\"); if ((file.startsWith("data\\")) && file.endsWith(".json")) { @@ -140,12 +140,16 @@ public void start(boolean debug) { line.append(newLine); } String finishedLine = line.toString().replace("\n", ""); + if (isCorrupted(finishedLine)) { + getLogger().severe("The json file with ResourceLocation of \"{}\" is corrupted! Please contact the pack author.".replace("{}", namespace + ":" + key)); + continue fileLoop; + } JsonObject powerParser; try { powerParser = JsonParser.parseReader(new StringReader(finishedLine)).getAsJsonObject(); } catch (Throwable throwable) { - getLogger().severe("An unhandled exception occurred when parsing a json file! Invalid syntax? The datapack will not be loaded."); - continue packLoop; + getLogger().severe("An unhandled exception occurred when parsing a json file \"{}\"! Invalid syntax? The datapack will not be loaded.".replace("{}", namespace + ":" + key)); + continue fileLoop; } NamespacedKey namespacedKey = new NamespacedKey(namespace, key); JsonObject remappedJsonObject = JsonObjectRemapper.remapJsonObject(powerParser, namespacedKey); @@ -170,6 +174,18 @@ public void start(boolean debug) { })); } + private boolean isCorrupted(String finishedLine) { + try { + JsonElement jsonElement = JsonParser.parseString(finishedLine); + if (!jsonElement.isJsonObject()) { + return true; + } + } catch (JsonSyntaxException e) { + return true; + } + return false; + } + /** * Logs a debug message if debugging is enabled. * @@ -230,10 +246,6 @@ public void registerAccessor(String directory, int prior keys.add(new AccessorKey(directory, priority, useTypeDefiner, registryKey, typeOf, null)); } - public void registerAccessor(String directory, int priority, boolean useTypeDefiner, RegistryKey registryKey) { - keys.add(new AccessorKey(directory, priority, useTypeDefiner, registryKey, null, null)); - } - public void registerAsset(String directory, int priority, String fileType, AssetType assetType, RegistryKey registryKey) { assetKeys.add(new AssetIdentifier<>(directory, priority, fileType, assetType, registryKey)); } diff --git a/calio/src/main/java/me/dueris/calio/data/AssetIdentifier.java b/calio/src/main/java/me/dueris/calio/data/AssetIdentifier.java index 2981e8e80..1190344f9 100644 --- a/calio/src/main/java/me/dueris/calio/data/AssetIdentifier.java +++ b/calio/src/main/java/me/dueris/calio/data/AssetIdentifier.java @@ -3,9 +3,10 @@ import me.dueris.calio.registry.Registrable; import me.dueris.calio.registry.RegistryKey; -public record AssetIdentifier(String directory, int priority, String fileType, AssetType assetType, RegistryKey registryKey) { +public record AssetIdentifier(String directory, int priority, String fileType, + AssetType assetType, RegistryKey registryKey) { - public static enum AssetType { - IMAGE, JSON; - } + public enum AssetType { + IMAGE, JSON + } } diff --git a/calio/src/main/java/me/dueris/calio/data/FactoryDataDefiner.java b/calio/src/main/java/me/dueris/calio/data/FactoryDataDefiner.java index 30cf4417c..f57c50aaf 100644 --- a/calio/src/main/java/me/dueris/calio/data/FactoryDataDefiner.java +++ b/calio/src/main/java/me/dueris/calio/data/FactoryDataDefiner.java @@ -7,8 +7,8 @@ * Implementation of a TriPair object */ public class FactoryDataDefiner { - private String key; - private Class type; + private final String key; + private final Class type; private Object defaultVal; public FactoryDataDefiner(String objName, Class type, T defaultVal) { @@ -28,7 +28,7 @@ public FactoryDataDefiner(String objName, Class type, OptionalInstance defaul } public Class getType() { - return (Class) this.type; + return this.type; } public String getObjName() { diff --git a/calio/src/main/java/me/dueris/calio/util/holders/QuadPair.java b/calio/src/main/java/me/dueris/calio/util/holders/QuadPair.java index 34e1e9e70..15532c1ab 100644 --- a/calio/src/main/java/me/dueris/calio/util/holders/QuadPair.java +++ b/calio/src/main/java/me/dueris/calio/util/holders/QuadPair.java @@ -1,3 +1,4 @@ package me.dueris.calio.util.holders; -public record QuadPair(A a, B b, C c, D d) { } +public record QuadPair(A a, B b, C c, D d) { +} diff --git a/origins/build.gradle.kts b/origins/build.gradle.kts index 86866df3a..75a2955bd 100644 --- a/origins/build.gradle.kts +++ b/origins/build.gradle.kts @@ -3,7 +3,7 @@ plugins { } group = "me.dueris" -version = "mc1.20-v1.0.2" +version = "mc1.21-v1.0.4" description = "Bringing the Origins Mod to PaperMC" dependencies { @@ -45,7 +45,7 @@ tasks { "name" to project.name, "version" to project.version, "description" to project.description, - "apiVersion" to "1.20" + "apiVersion" to "1.21" ) inputs.properties(props) filesMatching("paper-plugin.yml") { @@ -56,7 +56,7 @@ tasks { tasks.register("makePublisher") { dependsOn(tasks.shadowJar) - archiveFileName.set("genesis-v1.0.2-SNAPSHOT.jar") + archiveFileName.set("genesis-v1.0.4-SNAPSHOT.jar") from(sourceSets.main.get().output) } @@ -65,7 +65,7 @@ publishing { artifact(tasks.getByName("makePublisher")) { groupId = "io.github.dueris" artifactId = "genesis" - version = "v1.0.2-SNAPSHOT" + version = "v1.0.4-SNAPSHOT" } } repositories { diff --git a/origins/src/main/java/me/dueris/genesismc/Bootstrap.java b/origins/src/main/java/me/dueris/genesismc/Bootstrap.java index 853918336..b520e5516 100644 --- a/origins/src/main/java/me/dueris/genesismc/Bootstrap.java +++ b/origins/src/main/java/me/dueris/genesismc/Bootstrap.java @@ -4,27 +4,10 @@ import io.papermc.paper.plugin.bootstrap.PluginBootstrap; import it.unimi.dsi.fastutil.Pair; import me.dueris.calio.data.JsonObjectRemapper; -import me.dueris.calio.registry.Registrar; -import me.dueris.calio.registry.impl.CalioRegistry; -import me.dueris.genesismc.factory.actions.types.BiEntityActions; -import me.dueris.genesismc.factory.actions.types.BlockActions; -import me.dueris.genesismc.factory.actions.types.EntityActions; -import me.dueris.genesismc.factory.actions.types.ItemActions; -import me.dueris.genesismc.factory.conditions.types.*; -import me.dueris.genesismc.factory.powers.holder.PowerType; +import me.dueris.genesismc.content.NMSBootstrap; import me.dueris.genesismc.registry.Registries; -import me.dueris.genesismc.registry.nms.OriginLootCondition; -import me.dueris.genesismc.registry.nms.PowerLootCondition; -import me.dueris.genesismc.registry.registries.DatapackRepository; -import me.dueris.genesismc.registry.registries.Layer; -import me.dueris.genesismc.registry.registries.Origin; -import me.dueris.genesismc.screen.ChoosingPage; -import me.dueris.genesismc.util.LangFile; -import me.dueris.genesismc.util.TextureLocation; import me.dueris.genesismc.util.Util; -import net.minecraft.core.Registry; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.resources.ResourceLocation; +import me.dueris.genesismc.util.WrappedBootstrapContext; import org.apache.commons.io.FilenameUtils; import org.bukkit.configuration.file.YamlConfiguration; import org.jetbrains.annotations.NotNull; @@ -39,13 +22,14 @@ import java.util.Comparator; import java.util.Optional; import java.util.Properties; +import java.util.function.Consumer; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; // TODO: MachineMaker PluginDatapacks -// TODO: WaterProtection Enchantment - 1.21 public class Bootstrap implements PluginBootstrap { public static ArrayList oldDV = new ArrayList<>(); + public static ArrayList> apiCalls = new ArrayList<>(); static { oldDV.add("OriginsGenesis"); @@ -56,8 +40,6 @@ public class Bootstrap implements PluginBootstrap { oldDV.add("Origins-GenesisMC[0_2_6]"); } - private CalioRegistry registry; - public static void deleteDirectory(Path directory, boolean ignoreErrors) throws IOException { if (Files.exists(directory)) { Files.walk(directory) @@ -75,7 +57,7 @@ public static void deleteDirectory(Path directory, boolean ignoreErrors) throws } } - public static void copyOriginDatapack(Path datapackPath) { + public static void copyOriginDatapack(Path datapackPath, WrappedBootstrapContext context) { for (String string : oldDV) { if (Files.exists(datapackPath)) { String path = Path.of(datapackPath + File.separator + string).toAbsolutePath().toString(); @@ -87,7 +69,7 @@ public static void copyOriginDatapack(Path datapackPath) { } else { File file = new File(datapackPath.toAbsolutePath().toString()); file.mkdirs(); - copyOriginDatapack(datapackPath); + copyOriginDatapack(datapackPath, context); } } try { @@ -154,15 +136,20 @@ public static String levelNameProp() { } @Override - public void bootstrap(@NotNull BootstrapContext context) { + public void bootstrap(@NotNull BootstrapContext bootContext) { + WrappedBootstrapContext context = new WrappedBootstrapContext(bootContext); + NMSBootstrap.bootstrap(context); + for (Consumer apiCall : apiCalls) { + apiCall.accept(context); + } + File packDir = new File(this.parseDatapackPath()); try { - File packDir = new File(this.parseDatapackPath()); - copyOriginDatapack(packDir.toPath()); + copyOriginDatapack(packDir.toPath(), context); } catch (Exception e) { // ignore + } finally { + context.initRegistries(packDir.toPath()); } - Registry.register(BuiltInRegistries.LOOT_CONDITION_TYPE, new ResourceLocation("apoli", "power"), PowerLootCondition.TYPE); - Registry.register(BuiltInRegistries.LOOT_CONDITION_TYPE, new ResourceLocation("origins", "origin"), OriginLootCondition.TYPE); JsonObjectRemapper.typeMappings.add(new Pair() { @Override @@ -185,26 +172,27 @@ public String right() { JsonObjectRemapper.typeAlias.put("apoli:in_set", "apoli:in_entity_set"); JsonObjectRemapper.typeAlias.put("apoli:set_size", "apoli:entity_set_size"); - this.registry = CalioRegistry.INSTANCE; // Create new registry instances - this.registry.create(Registries.ORIGIN, new Registrar(Origin.class)); - this.registry.create(Registries.LAYER, new Registrar(Layer.class)); - this.registry.create(Registries.CRAFT_POWER, new Registrar(PowerType.class)); - this.registry.create(Registries.FLUID_CONDITION, new Registrar(FluidConditions.ConditionFactory.class)); - this.registry.create(Registries.ENTITY_CONDITION, new Registrar(EntityConditions.ConditionFactory.class)); - this.registry.create(Registries.BIOME_CONDITION, new Registrar(BiomeConditions.ConditionFactory.class)); - this.registry.create(Registries.BIENTITY_CONDITION, new Registrar(BiEntityConditions.ConditionFactory.class)); - this.registry.create(Registries.BLOCK_CONDITION, new Registrar(BlockConditions.ConditionFactory.class)); - this.registry.create(Registries.ITEM_CONDITION, new Registrar(ItemConditions.ConditionFactory.class)); - this.registry.create(Registries.DAMAGE_CONDITION, new Registrar(DamageConditions.ConditionFactory.class)); - this.registry.create(Registries.ENTITY_ACTION, new Registrar(EntityActions.ActionFactory.class)); - this.registry.create(Registries.ITEM_ACTION, new Registrar(ItemActions.ActionFactory.class)); - this.registry.create(Registries.BLOCK_ACTION, new Registrar(BlockActions.ActionFactory.class)); - this.registry.create(Registries.BIENTITY_ACTION, new Registrar(BiEntityActions.ActionFactory.class)); - this.registry.create(Registries.TEXTURE_LOCATION, new Registrar(TextureLocation.class)); - this.registry.create(Registries.LANG, new Registrar(LangFile.class)); - this.registry.create(Registries.PACK_SOURCE, new Registrar(DatapackRepository.class)); - this.registry.create(Registries.CHOOSING_PAGE, new Registrar(ChoosingPage.class)); + context.createRegistries( + Registries.ORIGIN, + Registries.LAYER, + Registries.CRAFT_POWER, + Registries.FLUID_CONDITION, + Registries.ENTITY_CONDITION, + Registries.BIOME_CONDITION, + Registries.BIENTITY_CONDITION, + Registries.BLOCK_CONDITION, + Registries.ITEM_CONDITION, + Registries.DAMAGE_CONDITION, + Registries.ENTITY_ACTION, + Registries.ITEM_ACTION, + Registries.BLOCK_ACTION, + Registries.BIENTITY_ACTION, + Registries.TEXTURE_LOCATION, + Registries.LANG, + Registries.PACK_SOURCE, + Registries.CHOOSING_PAGE + ); } public String parseDatapackPath() { diff --git a/origins/src/main/java/me/dueris/genesismc/GenesisMC.java b/origins/src/main/java/me/dueris/genesismc/GenesisMC.java index bf3af2480..c116cd98e 100644 --- a/origins/src/main/java/me/dueris/genesismc/GenesisMC.java +++ b/origins/src/main/java/me/dueris/genesismc/GenesisMC.java @@ -78,7 +78,7 @@ public final class GenesisMC extends JavaPlugin implements Listener { public static OriginScheduler.MainTickerThread scheduler = null; public static String version = Bukkit.getVersion().split("\\(MC: ")[1].replace(")", ""); public static boolean isCompatible = false; - public static String pluginVersion = "v1.0.2"; + public static String pluginVersion = "v1.0.4"; public static String world_container; public static ExecutorService loaderThreadPool; public static ArrayList versions = new ArrayList<>(); @@ -86,8 +86,7 @@ public final class GenesisMC extends JavaPlugin implements Listener { private static GenesisMC plugin; static { - versions.add("1.20.5"); - versions.add("1.20.6"); + versions.add("1.21"); } public IRegistry registry; diff --git a/origins/src/main/java/me/dueris/genesismc/content/NMSBootstrap.java b/origins/src/main/java/me/dueris/genesismc/content/NMSBootstrap.java new file mode 100644 index 000000000..be51389b3 --- /dev/null +++ b/origins/src/main/java/me/dueris/genesismc/content/NMSBootstrap.java @@ -0,0 +1,75 @@ +package me.dueris.genesismc.content; + +import me.dueris.genesismc.registry.nms.OriginLootCondition; +import me.dueris.genesismc.registry.nms.PowerLootCondition; +import me.dueris.genesismc.util.JsonObjectBuilder; +import me.dueris.genesismc.util.WrappedBootstrapContext; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceLocation; + +public class NMSBootstrap { + + public static void bootstrap(WrappedBootstrapContext context) { + context.registerBuiltin(BuiltInRegistries.LOOT_CONDITION_TYPE, ResourceLocation.fromNamespaceAndPath("apoli", "power"), PowerLootCondition.TYPE); + context.registerBuiltin(BuiltInRegistries.LOOT_CONDITION_TYPE, ResourceLocation.fromNamespaceAndPath("origins", "origin"), OriginLootCondition.TYPE); + + context.addDataDrivenPointer(Registries.ENCHANTMENT); + + context.registerData( + Registries.ENCHANTMENT, + new JsonObjectBuilder() + .number("anvil_cost", 2) + .jsonObject("description", new JsonObjectBuilder() + .string("type", "text") + .string("text", "Water Protection") + .build()) + .jsonObject("effects", new JsonObjectBuilder() + .jsonArray("minecraft:damage_protection", new JsonObjectBuilder.JsonArrayBuilder() + .jsonObject(new JsonObjectBuilder() + .jsonObject("effect", new JsonObjectBuilder() + .string("type", "minecraft:add") + .jsonObject("value", new JsonObjectBuilder() + .string("type", "minecraft:linear") + .number("base", 2.0) + .number("per_level_above_first", 2.0) + .build()) + .build()) + .jsonObject("requirements", new JsonObjectBuilder() + .string("condition", "minecraft:all_of") + .jsonArray("terms", new JsonObjectBuilder.JsonArrayBuilder() + .jsonObject(new JsonObjectBuilder() + .string("condition", "minecraft:damage_source_properties") + .jsonObject("predicate", new JsonObjectBuilder() + .jsonArray("tags", new JsonObjectBuilder.JsonArrayBuilder() + .jsonObject(new JsonObjectBuilder() + .bool("expected", true) + .string("id", "origins:water_protection_effects") + .build()) + .build()) + .build()) + .build()) + .build()) + .build()) + .build()) + .build()) + .build()) + .string("exclusive_set", "#minecraft:exclusive_set/armor") + .jsonObject("max_cost", new JsonObjectBuilder() + .number("base", 18) + .number("per_level_above_first", 8) + .build()) + .number("max_level", 4) + .jsonObject("min_cost", new JsonObjectBuilder() + .number("base", 10) + .number("per_level_above_first", 8) + .build()) + .stringArray("slots", "armor") + .string("supported_items", "#minecraft:enchantable/armor") + .number("weight", 5) + .build(), + ResourceLocation.fromNamespaceAndPath("origins", "water_protection") + ); + + } +} diff --git a/origins/src/main/java/me/dueris/genesismc/factory/actions/types/EntityActions.java b/origins/src/main/java/me/dueris/genesismc/factory/actions/types/EntityActions.java index 58e1a1e2d..2565432df 100644 --- a/origins/src/main/java/me/dueris/genesismc/factory/actions/types/EntityActions.java +++ b/origins/src/main/java/me/dueris/genesismc/factory/actions/types/EntityActions.java @@ -88,6 +88,13 @@ public void register() { bar.change(change, operation); }); })); + register(new ActionFactory(GenesisMC.apoliIdentifier("set_resource"), (action, entity) -> { + Optional resourceBar = Resource.getDisplayedBar(entity, action.getString("resource")); + resourceBar.ifPresent((bar) -> { + int val = action.getNumber("value").getInt(); + bar.change(val, "set"); + }); + })); register(new ActionFactory(GenesisMC.apoliIdentifier("modify_resource"), (action, entity) -> { Optional resourceBar = Resource.getDisplayedBar(entity, action.getString("resource")); resourceBar.ifPresent((bar) -> { diff --git a/origins/src/main/java/me/dueris/genesismc/factory/conditions/ConditionExecutor.java b/origins/src/main/java/me/dueris/genesismc/factory/conditions/ConditionExecutor.java index 54cd1544b..7624f87b3 100644 --- a/origins/src/main/java/me/dueris/genesismc/factory/conditions/ConditionExecutor.java +++ b/origins/src/main/java/me/dueris/genesismc/factory/conditions/ConditionExecutor.java @@ -136,7 +136,7 @@ public CraftEntity right() { if (con != null) { return getPossibleInvert(invert, con.test(condition, entityPair)); } else { - return getPossibleInvert(invert, true); // Condition null or not found. + return getPossibleInvert(invert, false); // Condition null or not found. } } return false; @@ -210,7 +210,7 @@ public static boolean testBiome(FactoryJsonObject condition, org.bukkit.block.Bi if (con != null) { return getPossibleInvert(invert, con.test(condition, new oshi.util.tuples.Pair(nmsBiome, CraftLocation.toBlockPosition(blockPos)))); } else { - return getPossibleInvert(invert, true); // Condition null or not found. + return getPossibleInvert(invert, false); // Condition null or not found. } } return false; @@ -281,7 +281,7 @@ public static boolean testBlock(FactoryJsonObject condition, CraftBlock block) { if (con != null) { return getPossibleInvert(invert, con.test(condition, block)); } else { - return getPossibleInvert(invert, true); // Condition null or not found. + return getPossibleInvert(invert, false); // Condition null or not found. } } return false; @@ -347,7 +347,7 @@ public static boolean testDamage(FactoryJsonObject condition, EntityDamageEvent if (con != null) { return getPossibleInvert(invert, con.test(condition, event)); } else { - return getPossibleInvert(invert, true); // Condition null or not found. + return getPossibleInvert(invert, false); // Condition null or not found. } } return false; @@ -417,7 +417,7 @@ public static boolean testEntity(FactoryJsonObject condition, CraftEntity entity if (con != null) { return getPossibleInvert(invert, con.test(condition, entity)); } else { - return getPossibleInvert(invert, true); // Condition null or not found. + return getPossibleInvert(invert, false); // Condition null or not found. } } return false; @@ -483,7 +483,7 @@ public static boolean testItem(FactoryJsonObject condition, ItemStack itemStack) if (con != null) { return getPossibleInvert(invert, con.test(condition, itemStack)); } else { - return getPossibleInvert(invert, true); // Condition null or not found. + return getPossibleInvert(invert, false); // Condition null or not found. } } return false; @@ -549,7 +549,7 @@ public static boolean testFluid(FactoryJsonObject condition, net.minecraft.world if (con != null) { return getPossibleInvert(invert, con.test(condition, fluid)); } else { - return getPossibleInvert(invert, true); // Condition null or not found. + return getPossibleInvert(invert, false); // Condition null or not found. } } return false; diff --git a/origins/src/main/java/me/dueris/genesismc/factory/conditions/types/EntityConditions.java b/origins/src/main/java/me/dueris/genesismc/factory/conditions/types/EntityConditions.java index 02a79381a..99d9314a1 100644 --- a/origins/src/main/java/me/dueris/genesismc/factory/conditions/types/EntityConditions.java +++ b/origins/src/main/java/me/dueris/genesismc/factory/conditions/types/EntityConditions.java @@ -346,14 +346,14 @@ public void registerConditions() { switch (condition.getStringOrDefault("calculation", "sum")) { case "sum": for (net.minecraft.world.item.ItemStack stack : CraftEnchantment.bukkitToMinecraft(enchantment).getSlotItems(((CraftPlayer) player).getHandle()).values()) { - value += EnchantmentHelper.getItemEnchantmentLevel(CraftEnchantment.bukkitToMinecraft(enchantment), stack); + value += EnchantmentHelper.getItemEnchantmentLevel(CraftEnchantment.bukkitToMinecraftHolder(enchantment), stack); } break; case "max": int equippedEnchantmentLevel = 0; for (net.minecraft.world.item.ItemStack stack : CraftEnchantment.bukkitToMinecraft(enchantment).getSlotItems(((CraftPlayer) player).getHandle()).values()) { - int enchantmentLevel = EnchantmentHelper.getItemEnchantmentLevel(CraftEnchantment.bukkitToMinecraft(enchantment), stack); + int enchantmentLevel = EnchantmentHelper.getItemEnchantmentLevel(CraftEnchantment.bukkitToMinecraftHolder(enchantment), stack); if (enchantmentLevel > equippedEnchantmentLevel) { equippedEnchantmentLevel = enchantmentLevel; @@ -614,7 +614,7 @@ public void registerConditions() { } } String comparison = condition.getStringOrDefault("comparison", ">="); - int compare_to = condition.getNumber("compare_to").getInt(); + int compare_to = condition.getNumberOrDefault("compare_to", 1).getInt(); return Comparison.fromString(comparison).compare(count, compare_to); })); register(new ConditionFactory(GenesisMC.apoliIdentifier("saturation_level"), (condition, entity) -> { @@ -698,12 +698,17 @@ public void registerConditions() { condition.getNamespacedKey("predicate") ); ReloadableServerRegistries.Holder holder = entity.getHandle().getServer().reloadableRegistries(); - - LootItemCondition predicate = holder.get().registry(net.minecraft.core.registries.Registries.PREDICATE).stream() - .flatMap(Registry::holders) - .filter(regHolder -> regHolder.key().location().equals(location)) - .map(Holder.Reference::value) - .findFirst().orElseThrow(); + LootItemCondition predicate; + + try { + predicate = holder.get().registry(net.minecraft.core.registries.Registries.PREDICATE).stream() + .flatMap(Registry::holders) + .filter(regHolder -> regHolder.key().location().equals(location)) + .map(Holder.Reference::value) + .findFirst().orElseThrow(); + } catch (Throwable throwable) { + return false; + } LootParams params = new LootParams.Builder(level) .withParameter(LootContextParams.ORIGIN, entity.getHandle().position()) diff --git a/origins/src/main/java/me/dueris/genesismc/factory/conditions/types/ItemConditions.java b/origins/src/main/java/me/dueris/genesismc/factory/conditions/types/ItemConditions.java index 11c3ed3a6..381be4797 100644 --- a/origins/src/main/java/me/dueris/genesismc/factory/conditions/types/ItemConditions.java +++ b/origins/src/main/java/me/dueris/genesismc/factory/conditions/types/ItemConditions.java @@ -10,6 +10,7 @@ import me.dueris.genesismc.util.EntityLinkedItemStack; import me.dueris.genesismc.util.Reflector; import me.dueris.genesismc.util.Util; +import net.minecraft.core.Holder; import net.minecraft.core.component.DataComponents; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; @@ -17,7 +18,6 @@ import net.minecraft.tags.TagKey; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Equipable; import net.minecraft.world.item.Item; @@ -55,14 +55,14 @@ public void registerConditions() { if (slot == null) { return Equipable.get(nms) != null; } - return LivingEntity.getEquipmentSlotForItem(nms) == slot; + return Util.getEquipmentSlotForItem(nms) == slot; })); register(new ConditionFactory(GenesisMC.apoliIdentifier("is_damageable"), (condition, itemStack) -> CraftItemStack.asCraftCopy(itemStack).handle.isDamageableItem())); register(new ConditionFactory(GenesisMC.apoliIdentifier("fireproof"), (condition, itemStack) -> CraftItemStack.asCraftCopy(itemStack).handle.has(DataComponents.FIRE_RESISTANT))); register(new ConditionFactory(GenesisMC.apoliIdentifier("enchantment"), (condition, itemStack) -> { Enchantment enchantment = CraftRegistry.ENCHANTMENT.get(NamespacedKey.fromString(condition.getString("enchantment"))); if (enchantment != null) { - net.minecraft.world.item.enchantment.Enchantment nmsEnchantment = CraftEnchantment.bukkitToMinecraft(enchantment); + Holder nmsEnchantment = CraftEnchantment.bukkitToMinecraftHolder(enchantment); Comparison comparison = Comparison.fromString(condition.getString("comparison")); int compare_to = condition.getNumber("compare_to").getInt(); diff --git a/origins/src/main/java/me/dueris/genesismc/factory/data/types/ExplosionMask.java b/origins/src/main/java/me/dueris/genesismc/factory/data/types/ExplosionMask.java index 52412f4cd..33d23228e 100644 --- a/origins/src/main/java/me/dueris/genesismc/factory/data/types/ExplosionMask.java +++ b/origins/src/main/java/me/dueris/genesismc/factory/data/types/ExplosionMask.java @@ -1,26 +1,39 @@ package me.dueris.genesismc.factory.data.types; +import com.mojang.datafixers.util.Pair; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; import me.dueris.calio.data.factory.FactoryJsonObject; import me.dueris.genesismc.factory.conditions.ConditionExecutor; import me.dueris.genesismc.util.Util; import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleOptions; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Explosion; +import net.minecraft.world.level.block.BaseFireBlock; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; import org.bukkit.Location; import org.bukkit.Sound; import org.bukkit.block.Block; import org.bukkit.craftbukkit.CraftParticle; import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.craftbukkit.util.CraftLocation; +import org.bukkit.event.block.BlockExplodeEvent; +import org.bukkit.event.entity.EntityExplodeEvent; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; public class ExplosionMask { List blocks; Explosion explosion; ServerLevel level; + boolean fire; public ExplosionMask(Explosion explosion, ServerLevel level) { this.blocks = new ArrayList<>(); @@ -32,8 +45,26 @@ public static ExplosionMask getExplosionMask(Explosion explosion, ServerLevel le return new ExplosionMask(explosion, level); } + private static void addOrAppendStack(List> stacks, ItemStack stack, BlockPos pos) { + if (stack.isEmpty()) return; + for (int i = 0; i < stacks.size(); ++i) { + Pair pair = stacks.get(i); + ItemStack itemstack1 = pair.getFirst(); + + if (ItemEntity.areMergable(itemstack1, stack)) { + stacks.set(i, Pair.of(ItemEntity.merge(itemstack1, stack, 16), pair.getSecond())); + if (stack.isEmpty()) { + return; + } + } + } + + stacks.add(Pair.of(stack, pos)); + } + public ExplosionMask apply(FactoryJsonObject getter, boolean destroyAfterMask) { this.explosion.explode(); // Setup explosion stuff -- includes iterator for explosions + this.fire = getter.getBooleanOrDefault("create_fire", false); this.blocks = createBlockList(this.explosion.getToBlow(), this.level); List finalBlocks = new ArrayList<>(this.blocks); boolean testFilters = getter.isPresent("indestructible") || getter.isPresent("destructible"); @@ -80,6 +111,98 @@ public void destroyBlocks() { this.level.getWorld().playSound(new Location(this.level.getWorld(), x, y, z), Sound.ENTITY_GENERIC_EXPLODE, 1, 1); this.level.getWorld().spawnParticle(CraftParticle.minecraftToBukkit(particleparam.getType()), new Location(this.level.getWorld(), x, y, z), 4); + + boolean flag1 = this.explosion.interactsWithBlocks(); + + if (flag1) { + System.out.println("sdkhf"); + this.level.getProfiler().push("explosion_blocks"); + List> list = new ArrayList(); + + net.minecraft.Util.shuffle(this.explosion.getToBlow(), this.level.random); + Iterator objectlistiterator = this.explosion.getToBlow().iterator(); + org.bukkit.World bworld = this.level.getWorld(); + org.bukkit.entity.Entity explode = this.explosion.source == null ? null : this.explosion.source.getBukkitEntity(); + Location location = new Location(bworld, this.explosion.center().x, this.explosion.center().y, this.explosion.center().z); + + List blockList = new ObjectArrayList<>(); + for (int i1 = this.explosion.getToBlow().size() - 1; i1 >= 0; i1--) { + BlockPos cpos = this.explosion.getToBlow().get(i1); + org.bukkit.block.Block bblock = bworld.getBlockAt(cpos.getX(), cpos.getY(), cpos.getZ()); + if (!bblock.getType().isAir()) { + blockList.add(bblock); + } + } + + List bukkitBlocks; + + if (explode != null) { + EntityExplodeEvent event = new EntityExplodeEvent(explode, location, blockList, this.explosion.yield); + this.level.getCraftServer().getPluginManager().callEvent(event); + this.explosion.wasCanceled = event.isCancelled(); + bukkitBlocks = event.blockList(); + this.explosion.yield = event.getYield(); + } else { + org.bukkit.block.Block block = location.getBlock(); + org.bukkit.block.BlockState blockState = (level.damageSources().generic().getDirectBlockState() != null) ? level.damageSources().generic().getDirectBlockState() : block.getState(); + BlockExplodeEvent event = new BlockExplodeEvent(block, blockState, blockList, this.explosion.yield); + this.level.getCraftServer().getPluginManager().callEvent(event); + this.explosion.wasCanceled = event.isCancelled(); + bukkitBlocks = event.blockList(); + this.explosion.yield = event.getYield(); + } + + this.explosion.getToBlow().clear(); + + for (org.bukkit.block.Block bblock : bukkitBlocks) { + BlockPos coords = new BlockPos(bblock.getX(), bblock.getY(), bblock.getZ()); + this.explosion.getToBlow().add(coords); + } + + if (this.explosion.wasCanceled) { + return; + } + objectlistiterator = this.explosion.getToBlow().iterator(); + + while (objectlistiterator.hasNext()) { + BlockPos blockposition = objectlistiterator.next(); + BlockState iblockdata = this.level.getBlockState(blockposition); + net.minecraft.world.level.block.Block block = iblockdata.getBlock(); + if (block instanceof net.minecraft.world.level.block.TntBlock) { + Entity sourceEntity = this.explosion.source == null ? null : this.explosion.source; + BlockPos sourceBlock = sourceEntity == null ? BlockPos.containing(this.explosion.center().x, this.explosion.center().y, this.explosion.center().z) : null; + if (!CraftEventFactory.callTNTPrimeEvent(this.level, blockposition, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.EXPLOSION, sourceEntity, sourceBlock)) { + this.level.sendBlockUpdated(blockposition, Blocks.AIR.defaultBlockState(), iblockdata, 3); // Update the block on the client + continue; + } + } + + this.level.getBlockState(blockposition).onExplosionHit(this.level, blockposition, this.explosion, (itemstack, blockposition1) -> { + addOrAppendStack(list, itemstack, blockposition1); + }); + } + + Iterator> iterator = list.iterator(); + + while (iterator.hasNext()) { + Pair pair = iterator.next(); + + net.minecraft.world.level.block.Block.popResource(this.level, pair.getSecond(), pair.getFirst()); + } + + this.level.getProfiler().pop(); + } + + if (this.fire) { + + for (BlockPos blockposition1 : this.explosion.getToBlow()) { + if (this.level.random.nextInt(3) == 0 && this.level.getBlockState(blockposition1).isAir() && this.level.getBlockState(blockposition1.below()).isSolidRender(this.level, blockposition1.below())) { + if (!CraftEventFactory.callBlockIgniteEvent(this.level, blockposition1, this.explosion).isCancelled()) { + this.level.setBlockAndUpdate(blockposition1, BaseFireBlock.getState(this.level, blockposition1)); + } + } + } + } } private List createBlockList(List blockPos, ServerLevel level) { diff --git a/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/AttributeHandler.java b/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/AttributeHandler.java index 299b71608..6c8fd7db6 100644 --- a/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/AttributeHandler.java +++ b/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/AttributeHandler.java @@ -1,5 +1,6 @@ package me.dueris.genesismc.factory.powers.apoli; +import com.mojang.datafixers.util.Pair; import me.dueris.calio.data.FactoryData; import me.dueris.calio.data.factory.FactoryJsonArray; import me.dueris.calio.data.factory.FactoryJsonObject; @@ -19,11 +20,15 @@ import org.bukkit.event.player.PlayerEvent; import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; public class AttributeHandler extends PowerType { private final Modifier[] modifiers; private final boolean updateHealth; private final @Nullable String attribute; + public static ConcurrentHashMap>> playerModifiers = new ConcurrentHashMap<>(); public AttributeHandler(String name, String description, boolean hidden, FactoryJsonObject condition, int loading_priority, boolean updateHealth, FactoryJsonObject modifier, FactoryJsonArray modifiers, String attribute) { super(name, description, hidden, condition, loading_priority); @@ -50,9 +55,20 @@ public void powerUpdate(PowerUpdateEvent e) { } } + @Override + public void bootstrapUnapply(Player player) { + if (playerModifiers.containsKey(player)) { + playerModifiers.get(player).forEach(pair -> { + if (player.getAttribute(pair.getFirst()) == null) return; + player.getAttribute(pair.getFirst()).removeModifier(pair.getSecond()); + }); + } + } + protected void runAttributeModifyPower(PlayerEvent e) { Player p = e.getPlayer(); if (!getPlayers().contains(p)) return; + playerModifiers.putIfAbsent(p, new ArrayList<>()); for (Modifier modifier : modifiers) { try { String attrName = modifier.handle.getString("attribute"); @@ -79,6 +95,7 @@ protected void runAttributeModifyPower(PlayerEvent e) { if (p.getAttribute(attributeModifier) != null) { p.getAttribute(attributeModifier).addTransientModifier(attrModifier); + playerModifiers.get(p).add(new Pair<>(attributeModifier, attrModifier)); } AttributeExecuteEvent attributeExecuteEvent = new AttributeExecuteEvent(p, attributeModifier, this, e.isAsynchronous()); diff --git a/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/Cooldown.java b/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/Cooldown.java index eb71ee57b..fa9998766 100644 --- a/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/Cooldown.java +++ b/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/Cooldown.java @@ -1,5 +1,6 @@ package me.dueris.genesismc.factory.powers.apoli; +import com.destroystokyo.paper.event.server.ServerTickEndEvent; import com.google.gson.JsonObject; import it.unimi.dsi.fastutil.Pair; import me.dueris.calio.data.FactoryData; @@ -18,15 +19,18 @@ import org.bukkit.event.server.ServerLoadEvent; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import static me.dueris.genesismc.factory.powers.apoli.Resource.currentlyDisplayed; import static me.dueris.genesismc.factory.powers.apoli.Resource.serverLoadedBars; public class Cooldown extends PowerType implements CooldownPower { - public static ConcurrentHashMap>> cooldowns = new ConcurrentHashMap<>(); private static final ConcurrentHashMap timingsTracker = new ConcurrentHashMap<>(); + private static final Set ticked = new HashSet<>(); + public static ConcurrentHashMap>> cooldowns = new ConcurrentHashMap<>(); private final HudRender hudRender; private final int cooldown; @@ -88,13 +92,23 @@ public void preLoad(ServerLoadEvent e) { }); } + @EventHandler + public void serverTickEnd(ServerTickEndEvent e) { + ticked.clear(); + } + @Override public void tick() { Util.collectValues(new ArrayList<>(cooldowns.values())).forEach((pair) -> { KeyedBossBar bar = pair.left(); + String keyString = bar.getKey().asString(); + if (ticked.contains(keyString)) { + return; + } + ticked.add(keyString); ModifiableFloatPair floatPair = timingsTracker.get(bar); float max = floatPair.a(); - float cur = floatPair.setB(floatPair.b() - 1); // Decrease the tracker + float cur = floatPair.setB(floatPair.b() - 1); if (cur <= 0) { for (Player player : bar.getPlayers()) { Resource.currentlyDisplayed.putIfAbsent(player, new ArrayList<>()); @@ -127,6 +141,8 @@ private void scheduleRemoval(Pair pair) { break; } } + + timingsTracker.remove(pair.key()); } @Override diff --git a/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/FireProjectile.java b/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/FireProjectile.java index 19e1792ea..423ad6a67 100644 --- a/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/FireProjectile.java +++ b/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/FireProjectile.java @@ -187,9 +187,10 @@ public void run() { if (entityToSpawn instanceof Projectile projectileToSpawn) { if (projectileToSpawn instanceof AbstractHurtingProjectile explosiveProjectileToSpawn) { - explosiveProjectileToSpawn.xPower = rotationVector.x * speed; - explosiveProjectileToSpawn.yPower = rotationVector.y * speed; - explosiveProjectileToSpawn.zPower = rotationVector.z * speed; + Vec3 vector = new Vec3(rotationVector.x * speed, rotationVector.y * speed, rotationVector.z * speed); + explosiveProjectileToSpawn.assignDirectionalMovement( + vector, vector.length() + ); } projectileToSpawn.setOwner(player); diff --git a/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/PreventSleep.java b/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/PreventSleep.java index da791dfd8..d1989b186 100644 --- a/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/PreventSleep.java +++ b/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/PreventSleep.java @@ -60,8 +60,8 @@ public void runD(PlayerInteractEvent e) { player.setBedSpawnLocation(blockLocation); } - player.sendMessage(message.equalsIgnoreCase("origins.avian_sleep_fail") ? "You need fresh air to sleep" : - message.equalsIgnoreCase("text.apoli.cannot_sleep") ? "You cannot sleep" : "text.apoli.cannot_sleep"); + player.sendMessage(message.replace("origins.avian_sleep_fail", "You need fresh air to sleep") + .replace("text.apoli.cannot_sleep", "You cannot sleep")); e.setCancelled(true); } } diff --git a/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/provider/origins/WaterBreathe.java b/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/provider/origins/WaterBreathe.java index bbc0bb18d..8bc5a02a3 100644 --- a/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/provider/origins/WaterBreathe.java +++ b/origins/src/main/java/me/dueris/genesismc/factory/powers/apoli/provider/origins/WaterBreathe.java @@ -125,7 +125,7 @@ public void tick() { finalDmg = 0.5f; } } - DamageType dmgType = Util.DAMAGE_REGISTRY.get(new ResourceLocation("origins", "no_water_for_gills")); + DamageType dmgType = Util.DAMAGE_REGISTRY.get(ResourceLocation.fromNamespaceAndPath("origins", "no_water_for_gills")); ((CraftPlayer) p).getHandle().hurt(Util.getDamageSource(dmgType), finalDmg); } } diff --git a/origins/src/main/java/me/dueris/genesismc/factory/powers/holder/PowerType.java b/origins/src/main/java/me/dueris/genesismc/factory/powers/holder/PowerType.java index 749ee6e5e..824080001 100644 --- a/origins/src/main/java/me/dueris/genesismc/factory/powers/holder/PowerType.java +++ b/origins/src/main/java/me/dueris/genesismc/factory/powers/holder/PowerType.java @@ -109,6 +109,12 @@ public void tickAsync(Player player) { public void tick() { } + public void bootstrapUnapply(Player player) { + } + + public void bootstrapApply(Player player) { + } + public String getType() { try { return ((FactoryData) getClass().getDeclaredMethod("registerComponents", FactoryData.class).invoke(null, new FactoryData())).getIdentifier().asString(); diff --git a/origins/src/main/java/me/dueris/genesismc/util/JsonObjectBuilder.java b/origins/src/main/java/me/dueris/genesismc/util/JsonObjectBuilder.java new file mode 100644 index 000000000..a95fc9ff9 --- /dev/null +++ b/origins/src/main/java/me/dueris/genesismc/util/JsonObjectBuilder.java @@ -0,0 +1,183 @@ +package me.dueris.genesismc.util; + +import com.google.gson.JsonArray; +import com.google.gson.JsonNull; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; + +import java.util.List; + +public class JsonObjectBuilder { + private final JsonObject jsonObject; + + public JsonObjectBuilder() { + this.jsonObject = new JsonObject(); + } + + public JsonObjectBuilder string(String key, String value) { + jsonObject.addProperty(key, value); + return this; + } + + public JsonObjectBuilder number(String key, Number value) { + jsonObject.addProperty(key, value); + return this; + } + + public JsonObjectBuilder bool(String key, Boolean value) { + jsonObject.addProperty(key, value); + return this; + } + + public JsonObjectBuilder nullValue(String key) { + jsonObject.add(key, JsonNull.INSTANCE); + return this; + } + + public JsonObjectBuilder stringArray(String key, String... values) { + JsonArray jsonArray = new JsonArray(); + for (String value : values) { + jsonArray.add(value); + } + jsonObject.add(key, jsonArray); + return this; + } + + public JsonObjectBuilder numberArray(String key, Number... values) { + JsonArray jsonArray = new JsonArray(); + for (Number value : values) { + jsonArray.add(new JsonPrimitive(value)); + } + jsonObject.add(key, jsonArray); + return this; + } + + public JsonObjectBuilder boolArray(String key, Boolean... values) { + JsonArray jsonArray = new JsonArray(); + for (Boolean value : values) { + jsonArray.add(value); + } + jsonObject.add(key, jsonArray); + return this; + } + + public JsonObjectBuilder jsonObject(String key, JsonObject value) { + jsonObject.add(key, value); + return this; + } + + public JsonObjectBuilder jsonObject(String key, JsonObjectBuilder builder) { + jsonObject.add(key, builder.build()); + return this; + } + + public JsonObjectBuilder jsonArray(String key, JsonArray value) { + jsonObject.add(key, value); + return this; + } + + public JsonObjectBuilder objectArray(String key, JsonObject... values) { + JsonArray jsonArray = new JsonArray(); + for (JsonObject value : values) { + jsonArray.add(value); + } + jsonObject.add(key, jsonArray); + return this; + } + + public JsonObjectBuilder stringList(String key, List values) { + JsonArray jsonArray = new JsonArray(); + for (String value : values) { + jsonArray.add(value); + } + jsonObject.add(key, jsonArray); + return this; + } + + public JsonObjectBuilder numberList(String key, List values) { + JsonArray jsonArray = new JsonArray(); + for (Number value : values) { + jsonArray.add(new JsonPrimitive(value)); + } + jsonObject.add(key, jsonArray); + return this; + } + + public JsonObjectBuilder boolList(String key, List values) { + JsonArray jsonArray = new JsonArray(); + for (Boolean value : values) { + jsonArray.add(value); + } + jsonObject.add(key, jsonArray); + return this; + } + + public JsonObjectBuilder objectList(String key, List values) { + JsonArray jsonArray = new JsonArray(); + for (JsonObject value : values) { + jsonArray.add(value); + } + jsonObject.add(key, jsonArray); + return this; + } + + public JsonObjectBuilder builderList(String key, List builders) { + JsonArray jsonArray = new JsonArray(); + for (JsonObjectBuilder builder : builders) { + jsonArray.add(builder.build()); + } + jsonObject.add(key, jsonArray); + return this; + } + + public JsonObjectBuilder raw(String key, com.google.gson.JsonElement value) { + jsonObject.add(key, value); + return this; + } + + public JsonObject build() { + return jsonObject; + } + + public static class JsonArrayBuilder { + private final JsonArray jsonArray; + + public JsonArrayBuilder() { + this.jsonArray = new JsonArray(); + } + + public JsonArrayBuilder string(String value) { + jsonArray.add(value); + return this; + } + + public JsonArrayBuilder number(Number value) { + jsonArray.add(new com.google.gson.JsonPrimitive(value)); + return this; + } + + public JsonArrayBuilder bool(Boolean value) { + jsonArray.add(value); + return this; + } + + public JsonArrayBuilder jsonObject(JsonObjectBuilder builder) { + jsonArray.add(builder.build()); + return this; + } + + public JsonArrayBuilder jsonObject(JsonObject value) { + jsonArray.add(value); + return this; + } + + public JsonArrayBuilder jsonArray(JsonArray value) { + jsonArray.add(value); + return this; + } + + public JsonArray build() { + return jsonArray; + } + } +} \ No newline at end of file diff --git a/origins/src/main/java/me/dueris/genesismc/util/LogoutBugWorkaround.java b/origins/src/main/java/me/dueris/genesismc/util/LogoutBugWorkaround.java index 7beb23bfe..1fdb5124b 100644 --- a/origins/src/main/java/me/dueris/genesismc/util/LogoutBugWorkaround.java +++ b/origins/src/main/java/me/dueris/genesismc/util/LogoutBugWorkaround.java @@ -1,6 +1,7 @@ package me.dueris.genesismc.util; import me.dueris.genesismc.GenesisMC; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.NamespacedKey; import org.bukkit.entity.Player; @@ -13,10 +14,22 @@ import org.bukkit.scheduler.BukkitRunnable; public class LogoutBugWorkaround implements Listener { + static { + GenesisMC.preShutdownTasks.add(() -> { + for (Player p : Bukkit.getOnlinePlayers()) { + p.getPersistentDataContainer().set(new NamespacedKey(GenesisMC.getPlugin(), "logoutWorkaroundLocation"), PersistentDataType.STRING, formatLocation(p.getLocation())); + } + }); + } + + public static String formatLocation(Location location) { + return location.x() + "//" + location.getY() + "//" + location.getZ() + "//" + location.getYaw() + "//" + location.getPitch(); + } + @EventHandler public void logout(PlayerQuitEvent e) { Player p = e.getPlayer(); - p.getPersistentDataContainer().set(new NamespacedKey(GenesisMC.getPlugin(), "logoutWorkaroundLocation"), PersistentDataType.STRING, this.formatLocation(p.getLocation())); + p.getPersistentDataContainer().set(new NamespacedKey(GenesisMC.getPlugin(), "logoutWorkaroundLocation"), PersistentDataType.STRING, formatLocation(p.getLocation())); } @EventHandler @@ -64,8 +77,4 @@ public void endPlatformFix(PlayerTeleportEvent e) { // Fixes spawning inside the e.setTo(new Location(e.getTo().getWorld(), e.getTo().getX(), 51, e.getTo().getZ(), e.getTo().getYaw(), e.getTo().getPitch())); } } - - public String formatLocation(Location location) { - return location.x() + "//" + location.getY() + "//" + location.getZ() + "//" + location.getYaw() + "//" + location.getPitch(); - } } diff --git a/origins/src/main/java/me/dueris/genesismc/util/Util.java b/origins/src/main/java/me/dueris/genesismc/util/Util.java index 5edf6bc45..defd3b983 100644 --- a/origins/src/main/java/me/dueris/genesismc/util/Util.java +++ b/origins/src/main/java/me/dueris/genesismc/util/Util.java @@ -34,6 +34,7 @@ import net.minecraft.world.entity.*; import net.minecraft.world.food.FoodProperties; import net.minecraft.world.item.ArmorItem; +import net.minecraft.world.item.Equipable; import net.minecraft.world.level.Level; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.levelgen.Heightmap; @@ -288,6 +289,12 @@ private static boolean isRainingAndExposed(Level world, BlockPos blockPos) { && world.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, blockPos).getY() < blockPos.getY(); } + public static EquipmentSlot getEquipmentSlotForItem(net.minecraft.world.item.ItemStack stack) { + Equipable equipable = Equipable.get(stack); + + return equipable != null ? equipable.getEquipmentSlot() : EquipmentSlot.MAINHAND; + } + public static boolean hasChangedBlockCoordinates(final Location fromLoc, final Location toLoc) { return !(fromLoc.getWorld().equals(toLoc.getWorld()) && fromLoc.getBlockX() == toLoc.getBlockX() @@ -295,6 +302,12 @@ public static boolean hasChangedBlockCoordinates(final Location fromLoc, final L && fromLoc.getBlockZ() == toLoc.getBlockZ()); } + public static String compileStrings(List strings) { + StringBuilder builder = new StringBuilder(); + strings.forEach(builder::append); + return builder.toString(); + } + public static void downloadFileFromURL(String fileUrl) throws IOException { URL url = new URL(fileUrl); try (BufferedInputStream in = new BufferedInputStream(url.openStream())) { diff --git a/origins/src/main/java/me/dueris/genesismc/util/WrappedBootstrapContext.java b/origins/src/main/java/me/dueris/genesismc/util/WrappedBootstrapContext.java new file mode 100644 index 000000000..9764ff560 --- /dev/null +++ b/origins/src/main/java/me/dueris/genesismc/util/WrappedBootstrapContext.java @@ -0,0 +1,133 @@ +package me.dueris.genesismc.util; + +import com.google.common.io.Files; +import com.google.gson.JsonObject; +import com.mojang.datafixers.util.Pair; +import io.papermc.paper.plugin.bootstrap.BootstrapContext; +import me.dueris.calio.registry.IRegistry; +import me.dueris.calio.registry.Registrar; +import me.dueris.calio.registry.RegistryKey; +import me.dueris.calio.registry.impl.CalioRegistry; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; + +public class WrappedBootstrapContext { + private final BootstrapContext context; + private final IRegistry registry; + private final List registryPointers = new CopyOnWriteArrayList<>(); + private final ConcurrentHashMap, JsonObject> registered = new ConcurrentHashMap<>(); + private final Logger LOGGER = LogManager.getLogger("ApoliBootstrapContext"); + + public WrappedBootstrapContext(BootstrapContext context) { + this.context = context; + this.registry = CalioRegistry.INSTANCE; + } + + public void createRegistry(RegistryKey key) { + registry.create(key, new Registrar<>(key.type())); + } + + public void createRegistries(RegistryKey... keys) { + for (RegistryKey key : keys) { + createRegistry(key); + } + } + + public void addDataDrivenPointer(ResourceKey key) { + registryPointers.add(key.location().getPath()); + } + + public void registerData(ResourceKey key, JsonObject data, ResourceLocation location) { + if (!registryPointers.contains(key.location().getPath())) { + registryPointers.add(key.location().getPath()); + } + + LOGGER.log(Level.INFO, "Registered new data for location: {}", location.getPath()); + registered.put( + new Pair<>(key, location), + data + ); + } + + public void initRegistries(Path datapackPath) { + LOGGER.log(Level.INFO, "Creating data-driven registries..."); + File data = Arrays.stream(Arrays.stream(datapackPath.toFile().listFiles()) + .filter(Objects::nonNull) + .filter(f -> { + return f.getName().equalsIgnoreCase("datapack"); + }).filter(File::isDirectory) + .findFirst().orElseThrow().listFiles()).filter(f -> { + return f.getName().equalsIgnoreCase("data"); + }).filter(File::isDirectory) + .findFirst().orElseThrow(); + + for (Pair key : registered.keySet()) { + String namespace = key.getSecond().getNamespace(); + String registryLocation = key.getFirst().location().getPath(); + File namespaceFile = new File(data, namespace); + if (!namespaceFile.exists()) { + namespaceFile.mkdirs(); + } + + File registryLocationFile = new File(namespaceFile, registryLocation); + if (!registryLocationFile.exists()) { + registryLocationFile.mkdirs(); + } + + File registryFile = new File(registryLocationFile, key.getSecond().getPath() + ".json"); + if (registryFile.exists()) { + try { + List lines = Files.readLines(registryFile, StandardCharsets.UTF_8); + String finishedLines = compileStrings(lines); + if (registered.get(key).toString().equalsIgnoreCase(finishedLines)) { + continue; + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + try { + Files.write(registered.get(key).toString(), registryFile, StandardCharsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + LOGGER.log(Level.INFO, "Created registry entry ({}) for registry \"{}\"", key.getSecond().toString(), registryLocation); + } + } + + registered.clear(); + + } + + public void registerBuiltin(Registry registry, ResourceLocation location, T type) { + Registry.register(registry, location, type); + } + + public IRegistry registry() { + return registry; + } + + public BootstrapContext context() { + return context; + } + + private String compileStrings(List strings) { + StringBuilder builder = new StringBuilder(); + strings.forEach(builder::append); + return builder.toString(); + } +} diff --git a/origins/src/main/java/me/dueris/genesismc/util/entity/GlowingEntitiesUtils.java b/origins/src/main/java/me/dueris/genesismc/util/entity/GlowingEntitiesUtils.java index d6900f30a..25a6d15d1 100644 --- a/origins/src/main/java/me/dueris/genesismc/util/entity/GlowingEntitiesUtils.java +++ b/origins/src/main/java/me/dueris/genesismc/util/entity/GlowingEntitiesUtils.java @@ -26,7 +26,7 @@ /** * A Spigot util to easily make entities glow. *

- * 1.17 -> 1.20.6 + * 1.17 -> 1.21 * * @author SkytAsul * @version 1.3.4 @@ -737,8 +737,8 @@ private enum ProtocolMappings { "a", "b"), V1_20_5_REMAPPED( - 20, - 5, + 21, + 0, true, "DATA_SHARED_FLAGS_ID", "MARKER", diff --git a/origins/src/main/java/me/dueris/genesismc/util/entity/PowerHolderComponent.java b/origins/src/main/java/me/dueris/genesismc/util/entity/PowerHolderComponent.java index a654dfe31..5e30e2b07 100644 --- a/origins/src/main/java/me/dueris/genesismc/util/entity/PowerHolderComponent.java +++ b/origins/src/main/java/me/dueris/genesismc/util/entity/PowerHolderComponent.java @@ -276,6 +276,7 @@ public static void applyPower(Player player, PowerType power, boolean suppress, if (!powersAppliedList.containsKey(player)) powersAppliedList.put(player, new ConcurrentLinkedQueue<>(List.of(c))); else powersAppliedList.get(player).add(c); + c.bootstrapApply(player); if (!suppress) { if (OriginConfiguration.getConfiguration().getBoolean("debug")) Bukkit.getConsoleSender().sendMessage(ChatColor.GREEN + "Assigned power[" + power.getTag() + "] to player " + player.getName()); @@ -295,6 +296,7 @@ public static void removePower(Player player, PowerType power, boolean suppress, NamespacedKey registryKey = power.key(); PowerType c = GenesisMC.getPlugin().registry.retrieve(Registries.CRAFT_POWER).get(registryKey); if (c != null) { + c.bootstrapUnapply(player); powersAppliedList.get(player).remove(c); c.removePlayer(player); if (!suppress) { diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/loot_tables/replaced_loot_table.json b/origins/src/main/resources/minecraft/datapack/data/apoli/loot_table/replaced_loot_table.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/loot_tables/replaced_loot_table.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/loot_table/replaced_loot_table.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/aggregate.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/aggregate.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/aggregate.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/aggregate.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/air.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/air.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/air.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/air.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/amethyst.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/amethyst.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/amethyst.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/amethyst.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/bamboo.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/bamboo.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/bamboo.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/bamboo.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/bamboo_sapling.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/bamboo_sapling.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/bamboo_sapling.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/bamboo_sapling.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/barrier.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/barrier.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/barrier.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/barrier.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/bubble_column.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/bubble_column.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/bubble_column.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/bubble_column.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/cactus.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/cactus.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/cactus.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/cactus.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/cake.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/cake.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/cake.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/cake.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/carpet.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/carpet.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/carpet.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/carpet.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/cobweb.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/cobweb.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/cobweb.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/cobweb.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/decoration.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/decoration.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/decoration.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/decoration.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/dense_ice.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/dense_ice.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/dense_ice.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/dense_ice.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/egg.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/egg.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/egg.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/egg.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/fire.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/fire.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/fire.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/fire.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/glass.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/glass.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/glass.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/glass.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/gourd.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/gourd.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/gourd.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/gourd.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/ice.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/ice.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/ice.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/ice.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/lava.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/lava.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/lava.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/lava.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/leaves.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/leaves.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/leaves.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/leaves.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/metal.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/metal.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/metal.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/metal.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/moss_block.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/moss_block.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/moss_block.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/moss_block.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/nether_shoots.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/nether_shoots.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/nether_shoots.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/nether_shoots.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/nether_wood.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/nether_wood.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/nether_wood.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/nether_wood.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/organic_product.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/organic_product.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/organic_product.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/organic_product.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/piston.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/piston.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/piston.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/piston.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/plant.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/plant.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/plant.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/plant.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/portal.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/portal.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/portal.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/portal.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/powder_snow.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/powder_snow.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/powder_snow.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/powder_snow.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/redstone_lamp.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/redstone_lamp.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/redstone_lamp.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/redstone_lamp.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/repair_station.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/repair_station.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/repair_station.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/repair_station.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/replaceable_plant.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/replaceable_plant.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/replaceable_plant.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/replaceable_plant.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/replaceable_underwater_plant.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/replaceable_underwater_plant.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/replaceable_underwater_plant.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/replaceable_underwater_plant.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/sculk.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/sculk.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/sculk.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/sculk.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/shulker_box.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/shulker_box.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/shulker_box.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/shulker_box.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/snow_block.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/snow_block.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/snow_block.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/snow_block.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/snow_layer.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/snow_layer.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/snow_layer.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/snow_layer.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/soil.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/soil.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/soil.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/soil.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/solid_organic.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/solid_organic.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/solid_organic.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/solid_organic.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/sponge.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/sponge.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/sponge.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/sponge.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/stone.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/stone.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/stone.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/stone.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/structure_void.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/structure_void.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/structure_void.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/structure_void.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/tnt.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/tnt.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/tnt.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/tnt.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/underwater_plant.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/underwater_plant.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/underwater_plant.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/underwater_plant.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/water.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/water.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/water.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/water.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/wood.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/wood.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/wood.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/wood.json diff --git a/origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/wool.json b/origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/wool.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/apoli/tags/blocks/material/wool.json rename to origins/src/main/resources/minecraft/datapack/data/apoli/tags/block/material/wool.json diff --git a/origins/src/main/resources/minecraft/datapack/data/genesis/functions/boom_command_step.mcfunction b/origins/src/main/resources/minecraft/datapack/data/genesis/function/boom_command_step.mcfunction similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/genesis/functions/boom_command_step.mcfunction rename to origins/src/main/resources/minecraft/datapack/data/genesis/function/boom_command_step.mcfunction diff --git a/origins/src/main/resources/minecraft/datapack/data/origins/tags/blocks/cobwebs.json b/origins/src/main/resources/minecraft/datapack/data/origins/tags/block/cobwebs.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/origins/tags/blocks/cobwebs.json rename to origins/src/main/resources/minecraft/datapack/data/origins/tags/block/cobwebs.json diff --git a/origins/src/main/resources/minecraft/datapack/data/origins/tags/blocks/flower.json b/origins/src/main/resources/minecraft/datapack/data/origins/tags/block/flower.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/origins/tags/blocks/flower.json rename to origins/src/main/resources/minecraft/datapack/data/origins/tags/block/flower.json diff --git a/origins/src/main/resources/minecraft/datapack/data/origins/tags/blocks/natural_stone.json b/origins/src/main/resources/minecraft/datapack/data/origins/tags/block/natural_stone.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/origins/tags/blocks/natural_stone.json rename to origins/src/main/resources/minecraft/datapack/data/origins/tags/block/natural_stone.json diff --git a/origins/src/main/resources/minecraft/datapack/data/origins/tags/blocks/sculk.json b/origins/src/main/resources/minecraft/datapack/data/origins/tags/block/sculk.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/origins/tags/blocks/sculk.json rename to origins/src/main/resources/minecraft/datapack/data/origins/tags/block/sculk.json diff --git a/origins/src/main/resources/minecraft/datapack/data/origins/tags/blocks/unphasable.json b/origins/src/main/resources/minecraft/datapack/data/origins/tags/block/unphasable.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/origins/tags/blocks/unphasable.json rename to origins/src/main/resources/minecraft/datapack/data/origins/tags/block/unphasable.json diff --git a/origins/src/main/resources/minecraft/datapack/data/origins/tags/damage_type/water_protection_effects.json b/origins/src/main/resources/minecraft/datapack/data/origins/tags/damage_type/water_protection_effects.json new file mode 100644 index 000000000..7eeb07785 --- /dev/null +++ b/origins/src/main/resources/minecraft/datapack/data/origins/tags/damage_type/water_protection_effects.json @@ -0,0 +1,5 @@ +{ + "values": [ + "origins:hurt_by_water" + ] +} \ No newline at end of file diff --git a/origins/src/main/resources/minecraft/datapack/data/origins/tags/items/allow_bee_eat.json b/origins/src/main/resources/minecraft/datapack/data/origins/tags/item/allow_bee_eat.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/origins/tags/items/allow_bee_eat.json rename to origins/src/main/resources/minecraft/datapack/data/origins/tags/item/allow_bee_eat.json diff --git a/origins/src/main/resources/minecraft/datapack/data/origins/tags/items/ignore_diet.json b/origins/src/main/resources/minecraft/datapack/data/origins/tags/item/ignore_diet.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/origins/tags/items/ignore_diet.json rename to origins/src/main/resources/minecraft/datapack/data/origins/tags/item/ignore_diet.json diff --git a/origins/src/main/resources/minecraft/datapack/data/origins/tags/items/meat.json b/origins/src/main/resources/minecraft/datapack/data/origins/tags/item/meat.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/origins/tags/items/meat.json rename to origins/src/main/resources/minecraft/datapack/data/origins/tags/item/meat.json diff --git a/origins/src/main/resources/minecraft/datapack/data/origins/tags/items/pumpkin_like/equipment.json b/origins/src/main/resources/minecraft/datapack/data/origins/tags/item/pumpkin_like/equipment.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/origins/tags/items/pumpkin_like/equipment.json rename to origins/src/main/resources/minecraft/datapack/data/origins/tags/item/pumpkin_like/equipment.json diff --git a/origins/src/main/resources/minecraft/datapack/data/origins/tags/items/pumpkin_like/food.json b/origins/src/main/resources/minecraft/datapack/data/origins/tags/item/pumpkin_like/food.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/origins/tags/items/pumpkin_like/food.json rename to origins/src/main/resources/minecraft/datapack/data/origins/tags/item/pumpkin_like/food.json diff --git a/origins/src/main/resources/minecraft/datapack/data/origins/tags/items/ranged_weapons.json b/origins/src/main/resources/minecraft/datapack/data/origins/tags/item/ranged_weapons.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/origins/tags/items/ranged_weapons.json rename to origins/src/main/resources/minecraft/datapack/data/origins/tags/item/ranged_weapons.json diff --git a/origins/src/main/resources/minecraft/datapack/data/origins/tags/items/shields.json b/origins/src/main/resources/minecraft/datapack/data/origins/tags/item/shields.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/origins/tags/items/shields.json rename to origins/src/main/resources/minecraft/datapack/data/origins/tags/item/shields.json diff --git a/origins/src/main/resources/minecraft/datapack/data/origins/tags/items/swords.json b/origins/src/main/resources/minecraft/datapack/data/origins/tags/item/swords.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/origins/tags/items/swords.json rename to origins/src/main/resources/minecraft/datapack/data/origins/tags/item/swords.json diff --git a/origins/src/main/resources/minecraft/datapack/data/shoot/functions/hit_block.mcfunction b/origins/src/main/resources/minecraft/datapack/data/shoot/function/hit_block.mcfunction similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/shoot/functions/hit_block.mcfunction rename to origins/src/main/resources/minecraft/datapack/data/shoot/function/hit_block.mcfunction diff --git a/origins/src/main/resources/minecraft/datapack/data/shoot/functions/hit_entity.mcfunction b/origins/src/main/resources/minecraft/datapack/data/shoot/function/hit_entity.mcfunction similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/shoot/functions/hit_entity.mcfunction rename to origins/src/main/resources/minecraft/datapack/data/shoot/function/hit_entity.mcfunction diff --git a/origins/src/main/resources/minecraft/datapack/data/shoot/functions/load.mcfunction b/origins/src/main/resources/minecraft/datapack/data/shoot/function/load.mcfunction similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/shoot/functions/load.mcfunction rename to origins/src/main/resources/minecraft/datapack/data/shoot/function/load.mcfunction diff --git a/origins/src/main/resources/minecraft/datapack/data/shoot/functions/ray.mcfunction b/origins/src/main/resources/minecraft/datapack/data/shoot/function/ray.mcfunction similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/shoot/functions/ray.mcfunction rename to origins/src/main/resources/minecraft/datapack/data/shoot/function/ray.mcfunction diff --git a/origins/src/main/resources/minecraft/datapack/data/shoot/functions/start_ray.mcfunction b/origins/src/main/resources/minecraft/datapack/data/shoot/function/start_ray.mcfunction similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/shoot/functions/start_ray.mcfunction rename to origins/src/main/resources/minecraft/datapack/data/shoot/function/start_ray.mcfunction diff --git a/origins/src/main/resources/minecraft/datapack/data/shoot/tags/blocks/non_solid.json b/origins/src/main/resources/minecraft/datapack/data/shoot/tags/block/non_solid.json similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/shoot/tags/blocks/non_solid.json rename to origins/src/main/resources/minecraft/datapack/data/shoot/tags/block/non_solid.json diff --git a/origins/src/main/resources/minecraft/datapack/data/star/functions/starcircle.mcfunction b/origins/src/main/resources/minecraft/datapack/data/star/function/starcircle.mcfunction similarity index 100% rename from origins/src/main/resources/minecraft/datapack/data/star/functions/starcircle.mcfunction rename to origins/src/main/resources/minecraft/datapack/data/star/function/starcircle.mcfunction diff --git a/origins/src/main/resources/paper-plugin.yml b/origins/src/main/resources/paper-plugin.yml index 248df8e2b..4c1207e26 100644 --- a/origins/src/main/resources/paper-plugin.yml +++ b/origins/src/main/resources/paper-plugin.yml @@ -2,9 +2,9 @@ bootstrapper: "me.dueris.genesismc.Bootstrap" loader: "me.dueris.genesismc.DependencyLoader" load: POSTWORLD name: "GenesisMC" -version: 'mc1.20-1.0.2' +version: 'mc1.21-1.0.4' main: "me.dueris.genesismc.GenesisMC" -api-version: "1.20" +api-version: "1.21" authors: [ Dueris ] folia-supported: false description: "A port of the Origins mod to PaperMC servers with Custom Origins support" diff --git a/version.txt b/version.txt index 0de61d2af..4f8c9939d 100644 --- a/version.txt +++ b/version.txt @@ -12,5 +12,7 @@ 1.0.0 : 10 | 1.0.1 : 11 | 1.0.2 : 12 | +1.0.3 : 13 | +1.0.4 : 14 | -latest : 12 | +latest : 14 |