Compare commits

..

16 Commits

Author SHA1 Message Date
coolGi b1cbc99a40 Removed ununsed injector 2023-06-17 13:00:39 +09:30
coolGi 8e4240ef9a Updated mod version 2023-06-08 17:27:49 +09:30
coolGi 131ba164cf Upped version number 2023-03-15 11:41:26 +00:00
coolGi acc681c535 Fixed up the build, buildsystem and the transparent lod button. 2023-03-15 21:45:57 +10:30
coolGi 1a3f9b82c6 Hack to make core shadow and relocate stuff 2022-12-20 18:52:38 +10:30
coolGi ddd6b3b817 Updated version number 2022-12-20 17:09:15 +10:30
James Seibel 5f116f0ea7 update the version number 1.6.8a -> 1.6.9a 2022-08-07 14:25:41 -05:00
James Seibel f00a1db9c2 update the version number 1.6.7a -> 1.6.8a 2022-07-31 12:06:54 -05:00
coolGi 9557912101 Changed version numbers to 1.6.7 2022-07-12 23:41:52 +09:30
James Seibel ca2b09c2c8 Update the version number to 1.6.6a-dev 2022-07-09 19:48:50 -05:00
cola98765 e1b2c62854 fixed int overflow with pow2 2022-06-23 14:33:06 +02:00
coolGi c3bb079b42 Added version to f3 screen and fixed some stuff in readme 2022-06-13 14:22:11 +09:30
coolGi 9670cbbb74 Updated version number, licence & readme 2022-06-13 13:14:25 +09:30
TomTheFurry 3ca0757358 Fixs: DimFinder nullPtr error on saving PlayerData before player loads in 2022-06-13 00:14:24 +08:00
TomTheFurry 4f2076b48e Fixs: Config Enum Error not caught, GLLogger not disabled, DimFinder Move crash on colliding with existing files, slience the rendering concurrency error 2022-06-13 00:02:42 +08:00
TomTheFurry e91bcb7964 Dummy commit to get git reconise a new core branch. 2022-06-12 23:37:26 +08:00
462 changed files with 16653 additions and 34553 deletions
+1 -7
View File
@@ -17,11 +17,5 @@ It should be automatically included when pulling the full mod.
XZ for Java (data compression)\
https://tukaani.org/xz/java.html
Json & Toml for Java (config handling)\
Toml for Java (config handeling)\
https://github.com/TheElectronWill/night-config
SVG Salamander for SVG's\
https://github.com/blackears/svgSalamander
FlatLaf for theming (for development testing, may remove later)\
https://www.formdev.com/flatlaf/
@@ -1,46 +0,0 @@
The following is short tutorial to setup and register a gitlab runner in a docker container on windows.
Docker can be installed via a installer from their website and these instructions assume that has already been done.
longer tutorials can be found at the following links:
https://faun.pub/gitlab-runner-setup-run-in-docker-container-on-windows-44fee102d02e
https://datawookie.dev/blog/2021/03/install-gitlab-runner-with-docker/
1. install the gitlab runner
run the following command in powershell, changing the config file location if need be
Note: This will NOT work in git bash, only powershell
docker run -d --name gitlab-runner --restart always -v C:\DistantHorizonsWorkspace\Docker\config:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:latest
2. to make sure the docker container was set up correctly run:
docker container list
it will display the docker containers that have been created
3. start and register the runner
run the following command in powershell. change the <ITEM>'s to whatever they should be for the runner you are creating.
docker run --rm -t -i -v C:\gitlab-runner\config:/etc/gitlab-runner gitlab/gitlab-runner register --non-interactive --executor "docker" --docker-image alpine:latest --url "https://gitlab.com/" --registration-token "<TOKEN>" --description "<DESCRIPTION THAT SHOWS UP ON GITLAB>" --run-untagged="true" --locked="false"
4. done
at this point the runner should be up and running, to confirm this go to your:
gitlab project -> settings (on the left menu bar) -> CI/CD -> Runners
and you should see the newly registered runner (the description should show up under the runner's auto generated ID)
Additional commands:
manual registering (shouldn't be needed)
docker exec -it gitlab-runner gitlab-runner register
list gitlab runner info
docker exec -it gitlab-runner gitlab-runner list
list all commands the runner can use
(replace "help" with whatever command you want to use)
docker exec -it gitlab-runner gitlab-runner help
-64
View File
@@ -1,64 +0,0 @@
<?xml version="1.0" standalone="yes"?>
<svg xmlns="http://www.w3.org/2000/svg" width="2040" height="2040">
<!-- Distant Horizons logo in svg format -->
<!-- Converted svg made by coolGi -->
<!-- Made by hand so there may be inaccuracies -->
<!--
Colors used
Blue: "fill:#465AA8"
Green: "fill:#5C7E3C"
Wierd green: "fill:#DCD7AA"
-->
<!-- Big Blue -->
<polygon points="1018.5,15 1434,255 1018.5,486 603,255" style="fill:#465AA8" />
<polygon points="1460,270 1875.5,509.5 1460,750 1045,509" style="fill:#465AA8" />
<polygon points="1889,531.5 1889,1012 1473,1252 1473,772" style="fill:#465AA8" />
<!-- Big Green -->
<polygon points="577,269 992,510 577,750 162,509.5" style="fill:#5C7E3C" />
<polygon points="149,532 564,772 564,1252 149,1012" style="fill:#5C7E3C" />
<polygon points="1889,1041 1889,1522 1474,1762 1473,1281" style="fill:#5C7E3C" />
<!-- Big Wierd Green -->
<polygon points="149,1042 564,1282 564,1762 149,1522" style="fill:#DCD7AA" />
<polygon points="590,1297 1006,1537 1006,2017 590,1777" style="fill:#DCD7AA" />
<polygon points="1031,1537 1447,1297 1447,1777 1031,2017" style="fill:#DCD7AA" />
<!-- Mid Blue -->
<polygon points="1239.5,652 1434,764.5 1239.5,877 1045,764.5" style="fill:#465AA8" />
<polygon points="1447,787 1447,1012 1252,1125 1252,899" style="fill:#465AA8" />
<!-- Mid Green -->
<polygon points="1018.5,525 1214,637 1018.5,749 824,637" style="fill:#5C7E3C" />
<polygon points="798,652 992,764.5 798,877 603,764.5" style="fill:#5C7E3C" />
<polygon points="590,787 785,899 785,1125 590,1012" style="fill:#5C7E3C" />
<polygon points="1447,1042 1447,1267 1252,1380 1252,1154" style="fill:#5C7E3C" />
<polygon points="1226,1170 1226,1395 1031,1507 1031,1282" style="fill:#5C7E3C" />
<!-- Mid Wierd Green -->
<polygon points="590,1042 785,1154 785,1379 590,1267" style="fill:#DCD7AA" />
<polygon points="811,1169 1006,1282 1006,1507 811,1395" style="fill:#DCD7AA" />
<!-- Out Small Blue -->
<polygon points="1018.5,779.5 1103,828 1018.5,877 934,828" style="fill:#465AA8" />
<polygon points="1129,843 1214,892 1129,941 1044,892" style="fill:#465AA8" />
<polygon points="1226,914 1226,1012 1142,1061 1142,963" style="fill:#465AA8" />
<polygon points="1226,1042 1226,1140 1142,1188 1142,1090" style="fill:#465AA8" />
<polygon points="1116,1105 1116,1203 1031,1252 1031,1154" style="fill:#465AA8" />
<!-- Out Small Green -->
<polygon points="908,843 993,892 908,941 823,892" style="fill:#5C7E3C" />
<polygon points="811,914 895,963 895,1061 811,1012" style="fill:#5C7E3C" />
<polygon points="921,1105 1006,1154 1006,1252 921,1203" style="fill:#5C7E3C" />
<!-- Out Small Wierd Green -->
<polygon points="811,1042 895,1090 895,1188 811,1140" style="fill:#DCD7AA" />
<!-- In Small Blue -->
<polygon points="1116,978 1116,1076 1031,1125 1031,1027" style="fill:#465AA8" />
<!-- In Small Green -->
<polygon points="1018.5,907 1103,956 1018.5,1004 934,956" style="fill:#5C7E3C" />
<polygon points="921,978 1006,1027 1006,1125 921,1076" style="fill:#5C7E3C" />
</svg>

Before

Width:  |  Height:  |  Size: 3.2 KiB

@@ -1,4 +0,0 @@
FROM anapsix/alpine-java
MAINTAINER Ran
COPY anotherquestion-1.0-SNAPSHOT.jar /home/anotherquestion-1.0-SNAPSHOT.jar
CMD ["java","-jar","/home/anotherquestion-1.0-SNAPSHOT.jar"]

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 101 KiB

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 113 KiB

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Before

Width:  |  Height:  |  Size: 191 KiB

After

Width:  |  Height:  |  Size: 191 KiB

Before

Width:  |  Height:  |  Size: 172 KiB

After

Width:  |  Height:  |  Size: 172 KiB

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 194 KiB

Before

Width:  |  Height:  |  Size: 174 KiB

After

Width:  |  Height:  |  Size: 174 KiB

@@ -1,93 +0,0 @@
package com.seibel.lod.api;
import com.seibel.lod.api.interfaces.config.IDhApiConfig;
import com.seibel.lod.api.interfaces.override.IDhApiOverrideable;
import com.seibel.lod.api.interfaces.override.worldGenerator.IDhApiWorldGeneratorOverrideRegister;
import com.seibel.lod.api.interfaces.render.IDhApiRenderProxy;
import com.seibel.lod.api.interfaces.world.IDhApiWorldProxy;
import com.seibel.lod.api.methods.override.DhApiWorldGeneratorOverrideRegister;
import com.seibel.lod.coreapi.DependencyInjection.ApiEventInjector;
import com.seibel.lod.coreapi.DependencyInjection.OverrideInjector;
import com.seibel.lod.coreapi.ModInfo;
import com.seibel.lod.api.interfaces.data.IDhApiTerrainDataRepo;
import com.seibel.lod.api.interfaces.events.IDhApiEventInjector;
import com.seibel.lod.coreapi.interfaces.dependencyInjection.IOverrideInjector;
/**
* This is the masthead of the API, almost everything you could want to do
* can be achieved from here. <br>
* For example: you can access singletons which handle the config or event binding. <br><br>
*
* <strong>Q:</strong> Why should I use this class instead of just getting the API singleton I need? <br>
*
* <strong>A:</strong> This way there is a lower chance of your code breaking if we change something on our end.
* For example, if we realized there is a much better way of handling dependency injection we would keep the
* interface the same so your code doesn't have to change. Whereas if you were directly referencing
* the concrete object we replaced, there would be issues.
*
* @author James Seibel
* @version 2023-2-9
*/
public class DhApiMain
{
/**
* <strong>WARNING:</strong>
* All objects in this class will be null until after DH initializes for the first time. <br><br>
*
* Bind a custom {@link com.seibel.lod.api.methods.events.abstractEvents.DhApiAfterDhInitEvent DhApiAfterDhInitEvent}
* to {@link DhApiMain#events ApiCoreInjectors.events} in order to be notified when this class can
* be safely used.
*/
public static class Delayed
{
/** Used to interact with Distant Horizons' Configs. */
public static IDhApiConfig configs = null;
/**
* Used to interact with Distant Horizons' terrain data.
* Designed to be used in conjunction with {@link DhApiMain.Delayed#worldProxy}.
*/
public static IDhApiTerrainDataRepo terrainRepo = null;
/**
* Used to interact with Distant Horizons' currently loaded world.
* Designed to be used in conjunction with {@link DhApiMain.Delayed#terrainRepo}.
*/
public static IDhApiWorldProxy worldProxy = null;
/** Used to interact with Distant Horizons' rendering system. */
public static IDhApiRenderProxy renderProxy = null;
}
// always available //
/** Used to bind/unbind Distant Horizons Api events. */
public static final IDhApiEventInjector events = ApiEventInjector.INSTANCE;
/** Used to bind/unbind Distant Horizons Api events. */
public static final IDhApiWorldGeneratorOverrideRegister worldGenOverrides = DhApiWorldGeneratorOverrideRegister.INSTANCE;
/** Used to bind overrides to change Distant Horizons' core behavior. */
public static final IOverrideInjector<IDhApiOverrideable> overrides = OverrideInjector.INSTANCE;
/** This version should only be updated when breaking changes are introduced to the Distant Horizons API. */
public static int getApiMajorVersion() { return ModInfo.API_MAJOR_VERSION; }
/** This version should be updated whenever new methods are added to the Distant Horizons API. */
public static int getApiMinorVersion() { return ModInfo.API_MINOR_VERSION; }
/**
* Returns the mod's semantic version number in the format: Major.Minor.Patch
* with optional extensions "-a" for alpha, "-b" for beta, and -dev for unstable development builds. <br>
* Examples: "1.6.9-a", "1.7.0-a-dev", "2.1.0-b", "3.0.0", "3.1.4-dev"
*/
public static String getModVersion() { return ModInfo.VERSION; }
/** Returns true if the mod is a development version, false if it is a release version. */
public static boolean getIsDevVersion() { return ModInfo.IS_DEV_BUILD; }
/** Returns the network protocol version. */
public static int getNetworkProtocolVersion() { return ModInfo.PROTOCOL_VERSION; }
}
@@ -1 +0,0 @@
The external api package holds any code that interfaces between Distant Horizons and other mods or projects.
@@ -1,52 +0,0 @@
package com.seibel.lod.api.enums;
/**
* BLOCK - Detail Level: 0, width 1 block, <br>
* CHUNK - Detail Level: 4, width 16 block, <br>
* REGION - Detail Level: 9, width 512 block <br> <br>
*
* Detail levels in Distant Horizons represent how large a section (of either LODs or MC chunks)
* is, with the smallest being 0 (1 block wide). <br>
* The width of a detail level can be calculated by putting the detail level to the power of 2. <br>
* Example for the chunk detail level (4): 2^4 = 16 blocks wide <Br><br>
*
* This enum doesn't contain all valid detail levels, only those most likely to be needed.
* Detail levels 1,2,3, ... 255 are all technically valid detail levels
* (although anything beyond {@link EDhApiDetailLevel#REGION} may be difficult deal with).
*
* @author James Seibel
* @version 2022-12-5
*/
public enum EDhApiDetailLevel
{
// Reminder:
// when adding items up the API minor version
// when removing items up the API major version
/**
* detail level: 0 <Br>
* width in Blocks: 1
*/
BLOCK(0, 1),
/**
* detail level: 4 <Br>
* width in Blocks: 16
*/
CHUNK(4, 16),
/**
* detail level: 9 <Br>
* width in Blocks: 512
*/
REGION(9, 512);
public final byte detailLevel;
public final byte widthInBlocks;
EDhApiDetailLevel(int detailLevel, int widthInBlocks)
{
this.detailLevel = (byte) detailLevel;
this.widthInBlocks = (byte) widthInBlocks;
}
}
@@ -1,40 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.enums.config;
/**
* FAST, <br>
* FANCY,
*
* @author Leetom
* @version 2022-7-1
*/
public enum ELightGenerationMode
{
// Reminder:
// when adding items up the API minor version
// when removing items up the API major version
/** Fake light values using a height map */
FAST,
/** Run the lighting engine though the chunk to generate proper light values */
FANCY
}
@@ -1,88 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.enums.config;
/**
* heightmap <br>
* multi_lod <br>
*
* @author Leonardo Amato
* @version 2023-2-5
*/
public enum EVerticalQuality
{
// HEIGHT_MAP(new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }), // commented out for now since it causes issues with transparency, may be re-added if the transparency issue is fixed
LOW(new int[] { 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1 }),
MEDIUM(new int[] { 6, 4, 3, 2, 2, 1, 1, 1, 1, 1, 1 }),
HIGH(new int[] { 8, 6, 4, 2, 2, 2, 2, 1, 1, 1, 1 }),
ULTRA(new int[] { 16, 8, 4, 2, 2, 2, 2, 1, 1, 1, 1 });
public final int[] maxVerticalData;
EVerticalQuality(int[] maxVerticalData) { this.maxVerticalData = maxVerticalData; }
/** returns null if out of range */
public static EVerticalQuality previous(EVerticalQuality mode)
{
switch (mode)
{
case ULTRA:
return EVerticalQuality.HIGH;
case HIGH:
return EVerticalQuality.MEDIUM;
case MEDIUM:
return EVerticalQuality.LOW;
case LOW:
default:
return null;
}
}
/** returns null if out of range */
public static EVerticalQuality next(EVerticalQuality mode)
{
switch (mode)
{
case MEDIUM:
return EVerticalQuality.HIGH;
case LOW:
return EVerticalQuality.MEDIUM;
case HIGH:
return EVerticalQuality.ULTRA;
case ULTRA:
default:
return null;
}
}
public int calculateMaxVerticalData(byte dataDetail)
{
if (dataDetail >= this.maxVerticalData.length)
{
dataDetail = (byte) (this.maxVerticalData.length - 1);
}
return this.maxVerticalData[dataDetail];
}
}
@@ -1,112 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.enums.rendering;
/**
* OFF, <br>
* SHOW_WIREFRAME, <br>
* SHOW_DETAIL, <br>
* SHOW_DETAIL_WIREFRAME, <br>
* SHOW_GENMODE, <br>
* SHOW_GENMODE_WIREFRAME, <br>
* SHOW_OVERLAPPING_QUADS, <br>
* SHOW_OVERLAPPING_QUADS_WIREFRAME, <br>
* SHOW_RENDER_SOURCE_FLAG, <br>
* SHOW_RENDER_SOURCE_FLAG_WIREFRAME, <br>
*
* @author Leetom
* @author James Seibel
* @version 2022-7-2
*/
public enum EDebugMode
{
// Reminder:
// when adding items up the API minor version
// when removing items up the API major version
/** LODs are rendered normally */
OFF,
/** LOD draws in wireframe. */
SHOW_WIREFRAME,
/** LOD colors are based on their detail */
SHOW_DETAIL,
/** LOD colors are based on their detail, and draws in wireframe. */
SHOW_DETAIL_WIREFRAME,
/** LOD colors are based on their gen mode. */
SHOW_GENMODE,
/** LOD colors are based on their gen mode, and draws in wireframe. */
SHOW_GENMODE_WIREFRAME,
/** Only draw overlapping LOD quads. */
SHOW_OVERLAPPING_QUADS,
/** Only draw overlapping LOD quads, and draws in wireframe. */
SHOW_OVERLAPPING_QUADS_WIREFRAME,
/** LOD colors are based on renderSource flags. */
SHOW_RENDER_SOURCE_FLAG,
/** LOD colors are based on renderSource flags, and draws in wireframe. */
SHOW_RENDER_SOURCE_FLAG_WIREFRAME;
/** returns the next debug mode */
// Deprecated: use DebugMode.next() instead
@Deprecated
public EDebugMode getNext()
{
return next(this);
}
public static EDebugMode next(EDebugMode type) {
switch (type) {
case OFF: return SHOW_WIREFRAME;
case SHOW_WIREFRAME: return SHOW_DETAIL;
case SHOW_DETAIL: return SHOW_DETAIL_WIREFRAME;
case SHOW_DETAIL_WIREFRAME: return SHOW_GENMODE;
case SHOW_GENMODE: return SHOW_GENMODE_WIREFRAME;
case SHOW_GENMODE_WIREFRAME: return SHOW_OVERLAPPING_QUADS;
case SHOW_OVERLAPPING_QUADS: return SHOW_OVERLAPPING_QUADS_WIREFRAME;
case SHOW_OVERLAPPING_QUADS_WIREFRAME: return SHOW_RENDER_SOURCE_FLAG;
case SHOW_RENDER_SOURCE_FLAG: return SHOW_RENDER_SOURCE_FLAG_WIREFRAME;
default: return OFF;
}
}
public static EDebugMode previous(EDebugMode type) {
switch (type) {
case OFF: return SHOW_RENDER_SOURCE_FLAG_WIREFRAME;
case SHOW_RENDER_SOURCE_FLAG_WIREFRAME: return SHOW_RENDER_SOURCE_FLAG;
case SHOW_RENDER_SOURCE_FLAG: return SHOW_OVERLAPPING_QUADS_WIREFRAME;
case SHOW_OVERLAPPING_QUADS_WIREFRAME: return SHOW_OVERLAPPING_QUADS;
case SHOW_OVERLAPPING_QUADS: return SHOW_GENMODE_WIREFRAME;
case SHOW_GENMODE_WIREFRAME: return SHOW_GENMODE;
case SHOW_GENMODE: return SHOW_DETAIL_WIREFRAME;
case SHOW_DETAIL_WIREFRAME: return SHOW_DETAIL;
case SHOW_DETAIL: return SHOW_WIREFRAME;
default: return OFF;
}
}
}
@@ -1,22 +0,0 @@
package com.seibel.lod.api.enums.rendering;
/**
* LINEAR, <br>
* EXPONENTIAL, <br>
* EXPONENTIAL_SQUARED <br>
*
* @author Leetom
* @version 2022-6-30
*/
public enum EFogFalloff
{
// Reminder:
// when adding items up the API minor version
// when removing items up the API major version
LINEAR,
EXPONENTIAL,
EXPONENTIAL_SQUARED,
// TEXTURE_BASED, // TODO: Impl this
}
@@ -1,63 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.enums.rendering;
/**
* Default
* Debug
* Disabled
*
* @version 2022-6-2
*/
public enum ERendererMode
{
// Reminder:
// when adding items up the API minor version
// when removing items up the API major version
DEFAULT,
DEBUG,
DISABLED;
/** Used by the config GUI to cycle through the available rendering options */
public static ERendererMode next(ERendererMode type)
{
switch (type)
{
case DEFAULT: return DEBUG;
case DEBUG: return DISABLED;
default: return DEFAULT;
}
}
/** Used by the config GUI to cycle through the available rendering options */
public static ERendererMode previous(ERendererMode type)
{
switch (type)
{
case DEFAULT: return DISABLED;
case DEBUG: return DEFAULT;
default: return DEBUG;
}
}
}
@@ -1,55 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.enums.rendering;
/**
* OFF, <br>
* SHOW_WIREFRAME, <br>
* SHOW_DETAIL, <br>
* SHOW_DETAIL_WIREFRAME, <br>
* SHOW_GENMODE, <br>
* SHOW_GENMODE_WIREFRAME, <br>
* SHOW_OVERLAPPING_QUADS, <br>
* SHOW_OVERLAPPING_QUADS_WIREFRAME, <br>
*
* @author Leetom
* @author James Seibel
* @version 2022-7-2
*/
public enum ETransparency
{
// Reminder:
// when adding items up the API minor version
// when removing items up the API major version
DISABLED(false, false),
FAKE(true, true),
COMPLETE(true, false);
public final boolean tranparencyEnabled;
public final boolean fakeTransparencyEnabled;
ETransparency(boolean tranparencyEnabled, boolean fakeTransparencyEnabled)
{
this.tranparencyEnabled = tranparencyEnabled;
this.fakeTransparencyEnabled = fakeTransparencyEnabled;
}
}
@@ -1,142 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.enums.worldGeneration;
/**
* PRE_EXISTING_ONLY <br>
* BIOME_ONLY <br>
* BIOME_ONLY_SIMULATE_HEIGHT <br>
* SURFACE <br>
* FEATURES <br>
* FULL <br><br>
*
* In order of fastest to slowest.
*
* @author James Seibel
* @author Leonardo Amato
* @version 2022-12-10
*/
public enum EDhApiDistantGeneratorMode
{
// Reminder:
// when adding items up the API minor version
// when removing items up the API major version
/** Don't generate any new terrain, just generate LODs for already generated chunks. */
PRE_EXISTING_ONLY((byte) 1),
/**
* Only generate the biomes and use biome
* grass/foliage color, water color, or ice color
* to generate the color. <br>
* Doesn't generate height, everything is shown at sea level. <br>
* Multithreaded - Fastest (2-5 ms)
*/
BIOME_ONLY((byte) 2),
/**
* Same as BIOME_ONLY, except instead
* of always using sea level as the LOD height
* different biome types (mountain, ocean, forest, etc.)
* use predetermined heights to simulate having height data.
*/
BIOME_ONLY_SIMULATE_HEIGHT((byte) 3),
/**
* Generate the world surface,
* this does NOT include caves, trees,
* or structures. <br>
* Multithreaded - Faster (10-20 ms)
*/
SURFACE((byte) 4),
/**
* Generate including structures.
* NOTE: This may cause world generation bugs or instability,
* since some features can cause concurrentModification exceptions. <br>
* Multithreaded - Fast (15-20 ms)
*/
FEATURES((byte) 5),
/**
* Ask the server to generate/load each chunk.
* This is the most compatible, but causes server/simulation lag.
* This will also show player made structures if you
* are adding the mod on a pre-existing world. <br>
* Single-threaded - Slow (15-50 ms, with spikes up to 200 ms)
*/
FULL((byte) 6);
public static final EDhApiDistantGeneratorMode RENDERABLE = EDhApiDistantGeneratorMode.BIOME_ONLY;
/** The higher the number the more complete the generation is. */
public final byte complexity;
EDhApiDistantGeneratorMode(byte complexity) { this.complexity = complexity; }
/** returns null if out of range */
public static EDhApiDistantGeneratorMode previous(EDhApiDistantGeneratorMode mode)
{
switch (mode)
{
case FULL:
return EDhApiDistantGeneratorMode.FEATURES;
case FEATURES:
return EDhApiDistantGeneratorMode.SURFACE;
case SURFACE:
return EDhApiDistantGeneratorMode.BIOME_ONLY_SIMULATE_HEIGHT;
case BIOME_ONLY_SIMULATE_HEIGHT:
return EDhApiDistantGeneratorMode.BIOME_ONLY;
case BIOME_ONLY:
return EDhApiDistantGeneratorMode.PRE_EXISTING_ONLY;
case PRE_EXISTING_ONLY:
default:
return null;
}
}
/** returns null if out of range */
public static EDhApiDistantGeneratorMode next(EDhApiDistantGeneratorMode mode)
{
switch (mode)
{
case FEATURES:
return EDhApiDistantGeneratorMode.FULL;
case SURFACE:
return EDhApiDistantGeneratorMode.FEATURES;
case BIOME_ONLY_SIMULATE_HEIGHT:
return EDhApiDistantGeneratorMode.SURFACE;
case BIOME_ONLY:
return EDhApiDistantGeneratorMode.BIOME_ONLY_SIMULATE_HEIGHT;
case PRE_EXISTING_ONLY:
return EDhApiDistantGeneratorMode.BIOME_ONLY;
case FULL:
default:
return null;
}
}
}
@@ -1,16 +0,0 @@
package com.seibel.lod.api.enums.worldGeneration;
/**
* SERVER_LEVEL, <br>
* CLIENT_LEVEL, <br>
* UNKNOWN <br>
*
* @author James Seibel
* @version 2022-7-13
*/
public enum EDhApiLevelType
{
SERVER_LEVEL,
CLIENT_LEVEL,
UNKNOWN
}
@@ -1,31 +0,0 @@
package com.seibel.lod.api.enums.worldGeneration;
/**
* MULTI_THREADED, <br>
* SINGLE_THREADED, <br>
* SERVER_THREAD, <br>
*
* @author James Seibel
* @version 7-14-2022
*/
public enum EDhApiWorldGenThreadMode
{
/**
* This world generator can be run on an unlimited number
* of concurrent threads.
*/
MULTI_THREADED,
/**
* This world generator can only be run on one thread at
* a time, however that thread can run concurrently
* to Minecraft's server thread.
*/
SINGLE_THREADED,
/**
* This world generator can only be run on Minecraft's
* server thread.
*/
SERVER_THREAD,
}
@@ -1,52 +0,0 @@
package com.seibel.lod.api.enums.worldGeneration;
/**
* EMPTY, <br>
* STRUCTURE_START, <br>
* STRUCTURE_REFERENCE, <br>
* BIOMES, <br>
* NOISE, <br>
* SURFACE, <br>
* CARVERS, <br>
* LIQUID_CARVERS, <br>
* FEATURES, <br>
* LIGHT, <br>
*
* @author James Seibel
* @version 2023-4-20
*/
public enum EDhApiWorldGenerationStep
{
EMPTY(0),
STRUCTURE_START(1),
STRUCTURE_REFERENCE(2),
BIOMES(3),
NOISE(4),
SURFACE(5),
CARVERS(6),
LIQUID_CARVERS(7),
FEATURES(8),
LIGHT(9);
/** used when serializing this enum. */
public final byte value;
EDhApiWorldGenerationStep(int value) { this.value = (byte) value; }
/** @return null if the value doesn't correspond to a {@link EDhApiWorldGenerationStep}. */
public static EDhApiWorldGenerationStep fromValue(int value)
{
for (EDhApiWorldGenerationStep genStep : EDhApiWorldGenerationStep.values())
{
if (genStep.value == value)
{
return genStep;
}
}
return null;
}
}
@@ -1,26 +0,0 @@
package com.seibel.lod.api.interfaces;
/**
* The Distant Horizons' API objects can't cover
* every potential use case. Sometimes developers just need
* the base Minecraft Objects.
*
* @author James Seibel
* @version 2022-9-16
*/
public interface IDhApiUnsafeWrapper
{
/**
* Returns the Minecraft object this wrapper contains. <br>
* <strong>Warning</strong>: This object will be Minecraft
* version dependent and may change without notice. <br> <br>
*
* In order to cast this object to something usable, you may want
* to use <code>obj.getClass()</code> when in your IDE
* in order to determine what object this method returns for
* the specific version of Minecraft you are developing for.
*/
Object getWrappedMcObject_UNSAFE();
}
@@ -1,31 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.interfaces.block;
import com.seibel.lod.api.interfaces.IDhApiUnsafeWrapper;
/**
* @author James Seibel
* @version 3-5-2022
*/
public interface IDhApiBiomeWrapper extends IDhApiUnsafeWrapper
{
String getName();
}
@@ -1,15 +0,0 @@
package com.seibel.lod.api.interfaces.block;
import com.seibel.lod.api.interfaces.IDhApiUnsafeWrapper;
/**
* A Minecraft version independent way of handling Blocks.
*
* @author James Seibel
* @version 2022-11-12
*/
public interface IDhApiBlockStateWrapper extends IDhApiUnsafeWrapper
{
boolean isAir();
}
@@ -1,25 +0,0 @@
package com.seibel.lod.api.interfaces.config;
import com.seibel.lod.api.interfaces.config.both.IDhApiWorldGenerationConfig;
import com.seibel.lod.api.interfaces.config.client.IDhApiBuffersConfig;
import com.seibel.lod.api.interfaces.config.client.IDhApiGraphicsConfig;
import com.seibel.lod.api.interfaces.config.client.IDhApiMultiplayerConfig;
import com.seibel.lod.api.interfaces.config.client.IDhApiThreadingConfig;
/**
* This interfaces holds all of the config groups
* the API has access to for easy access to all config values.
*
* @author James Seibel
* @version 9-15-2022
*/
public interface IDhApiConfig
{
IDhApiWorldGenerationConfig getWorldGeneratorConfig();
IDhApiBuffersConfig getBufferConfig();
IDhApiGraphicsConfig getGraphicsConfig();
IDhApiMultiplayerConfig getMultiplayerConfig();
IDhApiThreadingConfig getThreadingConfig();
}
@@ -1,15 +0,0 @@
package com.seibel.lod.api.interfaces.config;
import com.seibel.lod.coreapi.interfaces.dependencyInjection.IBindable;
/**
* This interface is just used to organize API config groups so
* they can be more easily handled together.
*
* @author James Seibel
* @version 9-15-2022
*/
public interface IDhApiConfigGroup extends IBindable
{
}
@@ -1,51 +0,0 @@
package com.seibel.lod.api.interfaces.config;
/**
* An interface for Distant Horizon's Config.
*
* @param <T> The data type of this config.
*
* @author James Seibel
* @version 2022-9-15
*/
public interface IDhApiConfigValue<T>
{
/**
* Returns the active value for this config. <br>
* Returns the True value if either the config cannot be overridden by
* the API or if it hasn't been set by the API.
*/
public T getValue();
/**
* Returns the value held by this config. <br>
* This is the value stored in the config file.
*/
public T getTrueValue();
/**
* Returns the value of the config if it was set by the API.
* Returns null if the config wasn't set by the API.
*/
public T getApiValue();
/**
* Sets the config's value. <br>
* If the newValue is set to null then the config
* will revert to using the True Value.<br>
* If the config cannot be set via the API this method will return false.
*
* @return true if the value was set, false otherwise.
*/
public boolean setValue(T newValue);
/** Returns true if this config can be set via the API, false otherwise. */
public boolean getCanBeOverrodeByApi();
/** Returns the default value for this config. */
public T getDefaultValue();
/** Returns the max value for this config, null if there is no max. */
public T getMaxValue();
/** Returns the min value for this config, null if there is no min. */
public T getMinValue();
}
@@ -1,77 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.interfaces.config.both;
import com.seibel.lod.api.enums.config.EBlocksToAvoid;
import com.seibel.lod.api.enums.worldGeneration.EDhApiDistantGeneratorMode;
import com.seibel.lod.api.enums.config.EGenerationPriority;
import com.seibel.lod.api.interfaces.config.IDhApiConfigValue;
import com.seibel.lod.api.enums.config.ELightGenerationMode;
import com.seibel.lod.api.interfaces.config.IDhApiConfigGroup;
/**
* Distant Horizons' world generation configuration. <br><br>
*
* Note: Fake chunks are NOT saved in Minecraft's vanilla save system.
*
* @author James Seibel
* @version 2022-9-15
*/
public interface IDhApiWorldGenerationConfig extends IDhApiConfigGroup
{
/**
* Defines whether fake chunks will be generated
* outside Minecraft's vanilla render distance.
*/
IDhApiConfigValue<Boolean> getEnableDistantWorldGeneration();
/** Defines to what level fake chunks will be generated. */
IDhApiConfigValue<EDhApiDistantGeneratorMode> getDistantGeneratorMode();
/** Defines how generated fake chunks will be lit. */
IDhApiConfigValue<ELightGenerationMode> getLightingMode();
/** Defines the order in which fake chunks will be generated. */
IDhApiConfigValue<EGenerationPriority> getGenerationPriority();
/**
* Defines what blocks will be ignored when generating LODs. <br><br>
*
* TODO if this isn't deprecated before 1.7 it should probably be moved to the graphics tab
* @deprecated this method won't be needed once we transition to an ID based save system <br>
* (vs the color based system we have currently)
*/
@Deprecated
IDhApiConfigValue<EBlocksToAvoid> getBlocksToAvoid();
/**
* Defines if the color of avoided blocks will color the block below them. <Br>
* (IE: if flowers are avoided should they color the grass below them?)
*
* TODO if this isn't deprecated before 1.7 it should probably be moved to the graphics tab
* @deprecated this method won't be needed once we transition to an ID based save system <br>
* (vs the color based system we have currently)
*/
@Deprecated
IDhApiConfigValue<Boolean> getTintWithAvoidedBlocks();
}
@@ -1,47 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.interfaces.config.client;
import com.seibel.lod.api.enums.config.EGpuUploadMethod;
import com.seibel.lod.api.interfaces.config.IDhApiConfigGroup;
import com.seibel.lod.api.interfaces.config.IDhApiConfigValue;
/**
* Distant Horizons' OpenGL buffer configuration.
*
* @author James Seibel
* @version 2022-9-15
*/
public interface IDhApiBuffersConfig extends IDhApiConfigGroup
{
/** Defines how geometry data is uploaded to the GPU. */
IDhApiConfigValue<EGpuUploadMethod> getGpuUploadMethod();
/**
* Defines how long we should wait after uploading one
* Megabyte of geometry data to the GPU before uploading
* the next Megabyte of data. <br>
* This can be set to a non-zero number to reduce stuttering caused by
* uploading buffers to the GPU.
*/
IDhApiConfigValue<Integer> getBufferUploadTimeoutPerMegabyteInMilliseconds();
}
@@ -1,41 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.interfaces.config.client;
import com.seibel.lod.api.enums.rendering.EDebugMode;
import com.seibel.lod.api.interfaces.config.IDhApiConfigValue;
import com.seibel.lod.api.interfaces.config.IDhApiConfigGroup;
/**
* Distant Horizons' debug configuration.
*
* @author James Seibel
* @version 2022-9-15
*/
public interface IDhApiDebuggingConfig extends IDhApiConfigGroup
{
/** Can be used to debug the standard fake chunk rendering. */
IDhApiConfigValue<EDebugMode> getDebugRenderMode();
/** If enabled debug keybindings can be used. */
IDhApiConfigValue<Boolean> getEnableDebugKeybindings();
}
@@ -1,138 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.interfaces.config.client;
import com.seibel.lod.api.enums.config.*;
import com.seibel.lod.api.enums.rendering.ERendererMode;
import com.seibel.lod.api.interfaces.config.IDhApiConfigValue;
import com.seibel.lod.api.interfaces.config.IDhApiConfigGroup;
/**
* Distant Horizons' graphics/rendering configuration.
*
* @author James Seibel
* @version 2022-9-15
*/
public interface IDhApiGraphicsConfig extends IDhApiConfigGroup
{
//========================//
// basic graphic settings //
//========================//
/** The distance is the radius measured in chunks. */
IDhApiConfigValue<Integer> getChunkRenderDistance();
/**
* Simplified version of {@link IDhApiGraphicsConfig#getRenderingMode()}
* that only enables/disables the fake chunk rendering. <br><br>
*
* Changing this config also changes {@link IDhApiGraphicsConfig#getRenderingMode()}'s value.
*/
IDhApiConfigValue<Boolean> getRenderingEnabled();
/**
* Can be used to enable/disable fake chunk rendering or enable the debug renderer. <br><br>
*
* The debug renderer is used to confirm rendering is working at and will draw
* a single multicolor rhombus on the screen in skybox space (AKA behind MC's rendering). <br><br>
*
* Changing this config also changes {@link IDhApiGraphicsConfig#getRenderingEnabled()}'s value.
*/
IDhApiConfigValue<ERendererMode> getRenderingMode();
//==================//
// graphic settings //
//==================//
/** Defines how detailed fake chunks are in the horizontal direction */
IDhApiConfigValue<EHorizontalResolution> getMaxDetailLevel();
/** Defines how detailed fake chunks are in the vertical direction */
IDhApiConfigValue<EVerticalQuality> getVerticalQuality();
/** Modifies the quadratic function fake chunks use for horizontal quality drop-off. */
IDhApiConfigValue<EHorizontalQuality> getHorizontalQualityDropoff();
/**
* The same as vanilla Minecraft's biome blending. <br><br>
*
* 0 = blending of 1x1 aka off <br>
* 1 = blending of 3x3 <br>
* 2 = blending of 5x5 <br>
* ... <br>
*/
IDhApiConfigValue<Integer> getBiomeBlending();
//===========================//
// advanced graphic settings //
//===========================//
/** If directional culling is disabled fake chunks will be rendered behind the camera. */
IDhApiConfigValue<Boolean> getDisableDirectionalCulling();
/** Determines how fake chunks are rendered in comparison to vanilla MC's chunks. */
IDhApiConfigValue<EVanillaOverdraw> getVanillaOverdraw();
/** Modifies how far the vanilla overdraw is rendered in chunks. */
IDhApiConfigValue<Integer> getVanillaOverdrawOffset();
/**
* If enabled the near clip plane is extended to reduce
* overdraw and improve Z-fighting at extreme render distances. <br>
* Disabling this reduces holes in the world due to the near clip plane
* being too close to the camera and the terrain not being covered by vanilla terrain.
*/
IDhApiConfigValue<Boolean> getUseExtendedNearClipPlane();
/**
* Modifies how bright fake chunks are. <br>
* This is done when generating the vertex data and is applied before any shaders.
*/
IDhApiConfigValue<Double> getBrightnessMultiplier();
/**
* Modifies how saturated fake chunks are. <br>
* This is done when generating the vertex data and is applied before any shaders.
*/
IDhApiConfigValue<Double> getSaturationMultiplier();
/** Defines if Distant Horizons should attempt to cull fake chunk cave geometry. */
IDhApiConfigValue<Boolean> getCaveCullingEnabled();
/** Defines what height cave culling should be used below if enabled. */
IDhApiConfigValue<Integer> getCaveCullingHeight();
/** This ratio is relative to Earth's real world curvature. */
IDhApiConfigValue<Integer> getEarthCurvatureRatio();
/** If enabled vanilla chunk rendering is disabled and only fake chunks are rendered. */
IDhApiConfigValue<Boolean> getEnableLodOnlyMode();
/** Defines how often the geometry should be rebuilt when the player moves. */
IDhApiConfigValue<EBufferRebuildTimes> getGeometryRebuildFrequency();
}
@@ -1,130 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.interfaces.config.client;
import com.seibel.lod.api.enums.rendering.*;
import com.seibel.lod.api.interfaces.config.IDhApiConfigGroup;
import com.seibel.lod.api.interfaces.config.IDhApiConfigValue;
/**
* Distant Horizons' fog configuration. <br><br>
*
* Note: unless an option explicitly states that it modifies
* Minecraft's vanilla rendering (like DisableVanillaFog)
* these settings will only affect Distant horizons' fog.
*
* @author James Seibel
* @version 2022-9-15
*/
public interface IDhApiGraphicsFogConfig extends IDhApiConfigGroup
{
//====================//
// basic fog settings //
//====================//
/** Defines at what distance fog is rendered on fake chunks. */
IDhApiConfigValue<EFogDistance> getFogDistance();
/** Should be used to enable/disable fog rendering. */
IDhApiConfigValue<EFogDrawMode> getFogRender();
/** Can be used to enable support with mods that change vanilla MC's fog color. */
IDhApiConfigValue<EFogColorMode> getFogColor();
/**
* If enabled attempts to disable vanilla MC's fog on real chunks. <br>
* May not play nice with other fog editing mods.
*/
IDhApiConfigValue<Boolean> getDisableVanillaFog();
//=======================//
// advanced fog settings //
//=======================//
/**
* Defines where the fog starts as a percent of the
* fake chunks render distance radius. <br>
* Can be greater than the fog end distance to invert the fog direction. <br> <br>
*
* 0.0 = fog starts at the camera <br>
* 1.0 = fog starts at the edge of the fake chunk render distance <br>
*/
IDhApiConfigValue<Double> getFogStartDistance();
/**
* Defines where the fog ends as a percent of the radius
* of the fake chunks render distance. <br>
* Can be less than the fog start distance to invert the fog direction. <br> <br>
*
* 0.0 = fog ends at the camera <br>
* 1.0 = fog ends at the edge of the fake chunk render distance <br>
*/
IDhApiConfigValue<Double> getFogEndDistance();
/** Defines how opaque the fog is at its thinnest point. */
IDhApiConfigValue<Double> getFogMinThickness();
/** Defines how opaque the fog is at its thickest point. */
IDhApiConfigValue<Double> getFogMaxThickness();
/** Defines how the fog changes in thickness. */
IDhApiConfigValue<EFogFalloff> getFogFalloff();
/** Defines the fog density. */
IDhApiConfigValue<Double> getFogDensity();
//=====================//
// height fog settings //
//=====================//
/** Defines how the height fog mixes. */
IDhApiConfigValue<EHeightFogMixMode> getHeightFogMixMode();
/** Defines how the height fog is drawn relative to the camera or world. */
IDhApiConfigValue<EHeightFogMode> getHeightFogMode();
/**
* Defines the height fog's base height if {@link IDhApiGraphicsFogConfig#getHeightFogMode()}
* is set to use a specific height.
*/
IDhApiConfigValue<Double> getHeightFogBaseHeight();
/** Defines the height fog's starting height as a percent of the world height. */
IDhApiConfigValue<Double> getHeightFogStartingHeightPercent();
/** Defines the height fog's ending height as a percent of the world height. */
IDhApiConfigValue<Double> getHeightFogEndingHeightPercent();
/** Defines how opaque the height fog is at its thinnest point. */
IDhApiConfigValue<Double> getHeightFogMinThickness();
/** Defines how opaque the height fog is at its thickest point. */
IDhApiConfigValue<Double> getHeightFogMaxThickness();
/** Defines how the height fog changes in thickness. */
IDhApiConfigValue<EFogFalloff> getHeightFogFalloff();
/** Defines the height fog's density. */
IDhApiConfigValue<Double> getHeightFogDensity();
}
@@ -1,53 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.interfaces.config.client;
import com.seibel.lod.api.interfaces.config.IDhApiConfigValue;
import com.seibel.lod.api.enums.config.EServerFolderNameMode;
import com.seibel.lod.api.interfaces.config.IDhApiConfigGroup;
/**
* Distant Horizons' client-side multiplayer configuration.
*
* @author James Seibel
* @version 2022-9-15
*/
public interface IDhApiMultiplayerConfig extends IDhApiConfigGroup
{
/**
* Defines how multiplayer server folders are named. <br>
* Note: Changing this while connected to a multiplayer world will cause undefined behavior!
*/
IDhApiConfigValue<EServerFolderNameMode> getFolderSavingMode();
/**
* Defines the necessary similarity (as a percent) that two potential levels
* need in order to be considered the same. <br> <br>
*
* Setting this to zero causes every level of a specific dimension type to be consider
* the same level. <br>
* Setting this to a non-zero value allows for usage in servers that user Multiverse
* or similar mods.
*/
IDhApiConfigValue<Double> getMultiverseSimilarityRequirement();
}
@@ -1,64 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.interfaces.config.client;
import com.seibel.lod.api.interfaces.config.IDhApiConfigValue;
import com.seibel.lod.api.interfaces.config.IDhApiConfigGroup;
/**
* Distant Horizons' threading configuration.
*
* @author James Seibel
* @version 2022-9-15
*/
public interface IDhApiThreadingConfig extends IDhApiConfigGroup
{
/**
* Defines how many world generator threads are used to generate
* terrain outside Minecraf's vanilla render distance. <br>
* <br>
* If the number of threads is less than 1 it will be treated as a percentage
* representing how often the single thread will actively generate terrain. <br> <br>
*
* 0.1 = 1 thread active 10% of the time <br>
* 0.5 = 1 thread active 50% of the time <br>
* 1.0 = 1 thread active 100% of the time <br>
* 1.5 = 2 threads active 100% of the time (partial values are rounded up) <br>
* 2.0 = 2 threads active 100% of the time <br>
*
* @deprecated this (and the related config) should be replaced with an int
* count of threads and then a double percent active config.
*/
@Deprecated
IDhApiConfigValue<Double> getWorldGeneratorThread();
// TODO the above should be replaced with these
// IDhApiConfig<Integer> getWorldGeneratorThreadConfig()
// { return new DhApiConfig<>(Threading.numberOfWorldGenerationThreads); }
// IDhApiConfig<Double> getWorldGeneratorThreadActivePercentConfig()
// { return new DhApiConfig<>(Threading.ToBeDetermined); }
/** Defines how many buffer (GPU Terrain data) builder threads are used. */
IDhApiConfigValue<Integer> getBufferBuilderThread();
}
@@ -1,64 +0,0 @@
package com.seibel.lod.api.interfaces.data;
import com.seibel.lod.api.interfaces.world.IDhApiLevelWrapper;
import com.seibel.lod.api.objects.DhApiResult;
import com.seibel.lod.api.objects.data.DhApiRaycastResult;
import com.seibel.lod.api.objects.data.DhApiTerrainDataPoint;
/**
* Used to interface with Distant Horizons' terrain data.
*
* @author James Seibel
* @version 2022-11-19
*/
public interface IDhApiTerrainDataRepo
{
/** Returns the terrain datapoint at the given block position, at or containing the given Y position. */
DhApiResult<DhApiTerrainDataPoint> getSingleDataPointAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosY, int blockPosZ);
/** Returns every datapoint in the column located at the given block X and Z position top to bottom. */
DhApiResult<DhApiTerrainDataPoint[]> getColumnDataAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosZ);
/**
* Returns every datapoint in the given chunk's X and Z position. <br><br>
*
* The returned array is ordered: [relativeBlockX][relativeBlockZ][columnIndex] <br>
* RelativeBlockX/Z are relative to the block position closest to negative infinity in the chunk's position. <br>
* The column data is ordered from top to bottom. Note: each column may have a different number of values. <br>
*/
DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtChunkPos(IDhApiLevelWrapper levelWrapper, int chunkPosX, int chunkPosZ);
/**
* Returns every datapoint in the given region's X and Z position. <br><br>
*
* The returned array is ordered: [relativeBlockX][relativeBlockZ][columnIndex] <br>
* RelativeBlockX/Z are relative to the block position closest to negative infinity in the region's position. <br>
* The column data is ordered from top to bottom. Note: each column may have a different number of values. <br>
*/
DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtRegionPos(IDhApiLevelWrapper levelWrapper, int regionPosX, int regionPosZ);
/**
* Returns every datapoint in the column located at the given detail level and X/Z position. <br>
* This can be used to return terrain data for non-standard sizes (IE 2x2 blocks or 2x2 chunks).
*
* @param detailLevel a positive byte defining the detail level of the returned data. <br>
* Every increase doubles the width of the returned area. <br>
* Example values: 0 = block, 1 = 2x2 blocks, 2 = 4x4 blocks, ... 4 = chunk (16x16 blocks), ... 9 = region (512x512 blocks)
*/
DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtDetailLevelAndPos(IDhApiLevelWrapper levelWrapper, byte detailLevel, int posX, int posZ);
/**
* Returns the datapoint and position of the LOD
* at the end of the given ray. <br><br>
*
* Will return "success" with a null datapoint if the ray reaches the max length without finding any data.
*/
DhApiResult<DhApiRaycastResult> raycast(IDhApiLevelWrapper levelWrapper,
double rayOriginX, double rayOriginY, double rayOriginZ,
float rayDirectionX, float rayDirectionY, float rayDirectionZ,
int maxRayBlockLength);
}
@@ -1,54 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.interfaces.events;
import com.seibel.lod.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.lod.coreapi.interfaces.dependencyInjection.IDependencyInjector;
/**
* This class takes care of dependency injection for API events.
*
* @author James Seibel
* @version 2022-9-13
*/
public interface IDhApiEventInjector extends IDependencyInjector<IDhApiEvent>
{
/**
* Unlinks the given event handler, preventing the handler from being called in the future.
*
* @throws IllegalArgumentException if the implementation object doesn't implement the interface
* @return true if the handler was unbound, false if the handler wasn't bound.
*/
// Note to self: Don't try adding a generic type to IDhApiEvent, the constructor won't accept it
boolean unbind(Class<? extends IDhApiEvent> dependencyInterface, Class<? extends IDhApiEvent> dependencyClassToRemove) throws IllegalArgumentException;
/**
* Fires all bound events of the given type (does nothing if no events are bound).
*
* @param abstractEvent event type
* @param eventParameterObject event parameter
* @return if any of bound event handlers returned that this event should be canceled.
* @param <T> the parameter type taken by the event handlers.
*/
<T, U extends IDhApiEvent<T>> boolean fireAllEvents(Class<U> abstractEvent, T eventParameterObject);
}
@@ -1,31 +0,0 @@
package com.seibel.lod.api.interfaces.override;
import com.seibel.lod.api.enums.worldGeneration.EDhApiDistantGeneratorMode;
import com.seibel.lod.api.interfaces.world.IDhApiLevelWrapper;
import com.seibel.lod.api.enums.worldGeneration.EDhApiWorldGenThreadMode;
import com.seibel.lod.api.interfaces.world.IDhApiChunkWrapper;
/**
* @author James Seibel
* @version 2022-9-8
*/
public abstract class AbstractDhApiWorldGenerator implements IDhApiOverrideable
{
/** Returns which thread chunk generation requests can be created on. */
public abstract EDhApiWorldGenThreadMode getThreadingMode();
public EDhApiWorldGenThreadMode getCoreThreadingMode()
{
return this.getThreadingMode();
}
public abstract IDhApiChunkWrapper generateChunk(int chunkPosX, int chunkPosZ, IDhApiLevelWrapper serverLevelWrapper, EDhApiDistantGeneratorMode maxStepToGenerate);
public final IDhApiChunkWrapper generateCoreChunk(int chunkPosX, int chunkPosZ, IDhApiLevelWrapper serverLevelWrapper, EDhApiDistantGeneratorMode maxStepToGenerate)
{
// TODO probably need to change the return type
return null; //generateChunk(chunkPosX, chunkPosZ, null, generationStepEnumConverter.convertToApiType(maxStepToGenerate));
}
}
@@ -1,20 +0,0 @@
package com.seibel.lod.api.interfaces.override;
import com.seibel.lod.coreapi.interfaces.dependencyInjection.IBindable;
import com.seibel.lod.coreapi.interfaces.dependencyInjection.IOverrideInjector;
/**
* Implemented by all DhApi objects that can be overridden.
*
* @author James Seibel
* @version 2022-9-5
*/
public interface IDhApiOverrideable extends IBindable
{
/**
* Higher (larger numerical) priorities override lower (smaller numerical) priorities . <br>
* For most developers this can be left at the default.
*/
default int getPriority() { return IOverrideInjector.DEFAULT_NON_CORE_OVERRIDE_PRIORITY; }
}
@@ -1,126 +0,0 @@
package com.seibel.lod.api.interfaces.override.worldGenerator;
import com.seibel.lod.api.enums.EDhApiDetailLevel;
import com.seibel.lod.api.enums.worldGeneration.EDhApiDistantGeneratorMode;
import com.seibel.lod.api.enums.worldGeneration.EDhApiWorldGenThreadMode;
import com.seibel.lod.api.interfaces.override.IDhApiOverrideable;
import java.io.Closeable;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
/**
* @author James Seibel
* @version 2022-12-10
*/
public interface IDhApiWorldGenerator extends Closeable, IDhApiOverrideable
{
//============//
// parameters //
//============//
/**
* Returns which thread chunk generation requests will be run on. <br>
* TODO: only {@link EDhApiWorldGenThreadMode#SINGLE_THREADED} is currently supported
*/
EDhApiWorldGenThreadMode getThreadingMode();
/**
* Defines the smallest datapoint size that can be generated at a time. <br>
* Minimum detail level is 0 (1 block) <br>
* Default detail level is 0 <br>
* For more information on what detail levels represent see: {@link EDhApiDetailLevel}. <br><br>
*
* TODO: System currently only supports 1x1 block per data.
*
* @see EDhApiDetailLevel
*/
default byte getMinDataDetailLevel() { return EDhApiDetailLevel.BLOCK.detailLevel; }
/**
* Defines the largest datapoint size that can be generated at a time. <br>
* Minimum detail level is 0 (1 block) <br>
* Default detail level is 0 <br>
* For more information on what detail levels represent see: {@link EDhApiDetailLevel}.
*
* @see EDhApiDetailLevel
*/
default byte getMaxDataDetailLevel() { return EDhApiDetailLevel.BLOCK.detailLevel; }
/**
* When creating generation requests the system will attempt to group nearby tasks together. <br><br>
* What is the minimum size a single generation call can batch together? <br>
*
* Minimum detail level is 4 (the size of a MC chunk) <br>
* Default detail level is 4 <br>
* For more information on what detail levels represent see: {@link EDhApiDetailLevel}.
*
* @see EDhApiDetailLevel
*/
default byte getMinGenerationGranularity() { return EDhApiDetailLevel.CHUNK.detailLevel; }
/**
* When creating generation requests the system will attempt to group nearby tasks together. <br><br>
* What is the maximum size a single generation call can batch together? <br>
*
* Minimum detail level is 4 (the size of a MC chunk) <br>
* Default detail level is 6 (4x4 chunks) <br>
* For more information on what detail levels represent see: {@link EDhApiDetailLevel}.
*
* @see EDhApiDetailLevel
*/
default byte getMaxGenerationGranularity() { return (byte) (EDhApiDetailLevel.CHUNK.detailLevel + 2); }
/** Returns true if the generator is unable to accept new generation requests. */
boolean isBusy();
//=================//
// world generator //
//=================//
/**
* This method is called by Distant Horizons to generate terrain over a given area
* from a thread defined by {@link IDhApiWorldGenerator#getThreadingMode}. <br><br>
*
* After a chunk has been generated it (and any necessary supporting objects as listed below) should be passed into the
* resultConsumer's {@link Consumer#accept} method. If the Consumer is given the wrong data
* type(s) it will throw a {@link ClassCastException} with a list of what objects it was expecting. <br>
* <strong>Note:</strong> these objects are minecraft version dependent and will change without notice!
* Please run your generator in game at least once to confirm the objects you are returning are correct. <br><br>
*
* Consumer expected inputs for each minecraft version (in order): <br>
* <strong>1.18:</strong> {@link net.minecraft.world.level.chunk.ChunkAccess} and {@link net.minecraft.world.level.LevelReader} <br>
*
* @throws ClassCastException if incompatible objects are passed into the resultConsumer.
*/
CompletableFuture<Void> generateChunks(int chunkPosMinX, int chunkPosMinZ,
byte granularity, byte targetDataDetail, EDhApiDistantGeneratorMode generatorMode,
Consumer<Object[]> resultConsumer) throws ClassCastException;
//===============//
// event methods //
//===============//
/**
* Called before a new generator task is started. <br>
* This can be used to run cleanup on existing tasks before new tasks are started.
*/
void preGeneratorTaskStart();
//===========//
// overrides //
//===========//
// This is overridden to remove the "throws IOException"
// that is present in the default Closeable.close() method
@Override
void close();
}
@@ -1,23 +0,0 @@
package com.seibel.lod.api.interfaces.override.worldGenerator;
import com.seibel.lod.api.interfaces.world.IDhApiLevelWrapper;
import com.seibel.lod.api.objects.DhApiResult;
/**
* Handles adding world generator overrides.
*
* @author James Seibel
* @version 2022-12-10
*/
public interface IDhApiWorldGeneratorOverrideRegister
{
/**
* Registers the given world generator for the given level. <Br> <Br>
*
* Only one world generator can be registered for a specific level at a given time. <Br>
* If another world generator has already been registered, DhApiResult will return
* the name of the previously registered generator and success = false.
*/
DhApiResult<Void> registerWorldGeneratorOverride(IDhApiLevelWrapper levelWrapper, IDhApiWorldGenerator worldGenerator);
}
@@ -1,47 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.interfaces.render;
import com.seibel.lod.api.objects.DhApiResult;
/**
* Used to interact with Distant Horizons rendering systems.
*
* @author James Seibel
* @version 2023-2-8
*/
public interface IDhApiRenderProxy
{
/**
* Forces any cached render data to be deleted and regenerated.
* This is generally called whenever resource packs are changed or specific
* rendering settings are changed in Distant Horizon's config. <Br><Br>
*
* If this is called on a dedicated server it won't do anything and will return {@link DhApiResult#success} = false <Br><Br>
*
* Background: <Br>
* Distant Horizons has two different file formats: Full data and Render data. <Br>
* - Full data files store the block, biome, etc. information and is the result of loading or generating new chunks. <Br>
* - Render data files store LOD colors and are created using the Full data and currently loaded resource packs. <Br>
* This is the data cleared by this method.
*/
DhApiResult<Boolean> clearRenderDataCache();
}
@@ -1,68 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.interfaces.world;
import com.seibel.lod.api.interfaces.IDhApiUnsafeWrapper;
/**
* @author James Seibel
* @version 2022-7-14
*/
public interface IDhApiChunkWrapper extends IDhApiUnsafeWrapper
{
/** Returns the absolute Y coordinate of the highest block for the given relative X and Z coordinates. */
int getMaxY(int relativeX, int relativeZ);
/** Returns the maximum absolute block position in the X direction. */
int getMaxX();
/** Returns the maximum absolute block position in the Z direction. */
int getMaxZ();
/** Returns the absolute Y coordinate of the lowest block for the given relative X and Z coordinates. */
int getMinY(int relativeX, int relativeZ);
/** Returns the minimum absolute block position in the X direction. */
int getMinX();
/** Returns the minimum absolute block position in the Z direction. */
int getMinZ();
/**
* Returns true if this chunk's lighting has been built. <br>
* Note: for some versions of Minecraft this value may be unreliable.
*/
boolean isLightCorrect();
/** TODO what side of the block should this return the light for? */
default int getBlockLight(int x, int y, int z) {return -1;}
/** TODO what side of the block should this return the light for? */
default int getSkyLight(int x, int y, int z) {return -1;}
/**
* Returns true if chunks exist in all 4 cardinal and 4 ordinal directions
* relative to this chunk. <br>
* IE: returns true if there are chunks to the North, South, East, West, NE, SE, SW, and NW
* of this chunk.
*/
boolean doNearbyChunksExist();
// TODO these will probably need replacing once 1.7's ID system is done
//IBlockStateWrapper getBlockState(int x, int y, int z);
//IBiomeWrapper getBiome(int x, int y, int z);
}
@@ -1,50 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.interfaces.world;
import com.seibel.lod.api.interfaces.IDhApiUnsafeWrapper;
import com.seibel.lod.api.enums.worldGeneration.EDhApiLevelType;
/**
* Can be either a Server or Client level.
*
* @author James Seibel
* @version 2022-7-14
*/
public interface IDhApiLevelWrapper extends IDhApiUnsafeWrapper
{
IDhApiDimensionTypeWrapper getDimensionType();
EDhApiLevelType getLevelType();
boolean hasCeiling();
boolean hasSkyLight();
/** Returns the max block height of the level(?) */
int getHeight();
/**
* Returns the lowest possible block position for the level. <br>
* For MC versions before 1.18 this will return 0.
*/
default int getMinHeight() { return 0; }
}
@@ -1,62 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.interfaces.world;
import com.seibel.lod.api.interfaces.IDhApiUnsafeWrapper;
/**
* Used to interact with Distant Horizons current world.
*
* @author James Seibel
* @version 2022-11-20
*/
public interface IDhApiWorldProxy
{
/** Returns true if a world is loaded. */
boolean worldLoaded();
/**
* In singleplayer this will return the level the player is currently in. <br>
* In multiplayer this will return null.
*
* @throws IllegalStateException if no world is loaded
*/
IDhApiLevelWrapper getSinglePlayerLevel() throws IllegalStateException;
/** @throws IllegalStateException if no world is loaded */
Iterable<IDhApiLevelWrapper> getAllLoadedLevelWrappers() throws IllegalStateException;
/**
* In the case of servers running multiverse there may be multiple levels for the same dimensionType.
*
* @throws IllegalStateException if no world is loaded
*/
Iterable<IDhApiLevelWrapper> getAllLoadedLevelsForDimensionType(IDhApiDimensionTypeWrapper dimensionTypeWrapper) throws IllegalStateException;
/**
* Returns any dimensions that have names containing the given string (case-insensitive). <br>
* In the case of servers running multiverse there may be multiple levels for the same dimensionType.
*
* @throws IllegalStateException if no world is loaded
*/
Iterable<IDhApiLevelWrapper> getAllLoadedLevelsWithDimensionNameLike(String dimensionName) throws IllegalStateException;
}
@@ -1,51 +0,0 @@
package com.seibel.lod.api.methods.events;
import com.seibel.lod.api.objects.DhApiResult;
import com.seibel.lod.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.lod.coreapi.DependencyInjection.ApiEventInjector;
/**
* Handles adding/removing event handlers.
*
* @author James Seibel
* @version 2022-9-16
*/
public class DhApiEventRegister
{
/**
* Registers the given event handler. <Br>
* Only one eventHandler of a specific class can be registered at a time.
* If multiple of the same eventHandler are added DhApiResult will return
* the name of the already added handler and success = false.
*/
public static DhApiResult<Void> on(Class<? extends IDhApiEvent> eventInterface, IDhApiEvent eventHandlerImplementation)
{
try
{
ApiEventInjector.INSTANCE.bind(eventInterface, eventHandlerImplementation);
return DhApiResult.createSuccess();
}
catch (IllegalStateException e)
{
return DhApiResult.createFail(e.getMessage());
}
}
/**
* Unregisters the given event handler for this event if one has been registered. <br>
* If no eventHandler of the given class has been registered the result will return
* success = false.
*/
public static DhApiResult<Void> off(Class<? extends IDhApiEvent> eventInterface, Class<IDhApiEvent> eventHandlerClass)
{
if (ApiEventInjector.INSTANCE.unbind(eventInterface, eventHandlerClass))
{
return DhApiResult.createSuccess();
}
else
{
return DhApiResult.createFail("No event handler [" + eventHandlerClass.getSimpleName() + "] was bound for the event [" + eventInterface.getSimpleName() + "].");
}
}
}
@@ -1,3 +0,0 @@
The events api package holds objects and methods for listening to events fired by Distant Horizons'.
Each interface should only contain one method and that method should match the name of the file. This is done so Developers can mix and match what events they want their classes to handle.
@@ -1,31 +0,0 @@
package com.seibel.lod.api.methods.events.abstractEvents;
import com.seibel.lod.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.lod.api.objects.events.DhApiEventDefinition;
/**
* @author James Seibel
* @version 2022-11-21
*/
public abstract class DhApiAfterDhInitEvent implements IDhApiEvent<Void>
{
/** Fired after Distant Horizons finishes its initial setup on Minecraft startup. */
public abstract void afterDistantHorizonsInit();
//=========================//
// internal DH API methods //
//=========================//
@Override
public final boolean fireEvent(Void ignoredParam)
{
this.afterDistantHorizonsInit();
return false;
}
public final static DhApiEventDefinition EVENT_DEFINITION = new DhApiEventDefinition(false, true);
@Override
public final DhApiEventDefinition getEventDefinition() { return EVENT_DEFINITION; }
}
@@ -1,45 +0,0 @@
package com.seibel.lod.api.methods.events.abstractEvents;
import com.seibel.lod.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.lod.api.methods.events.sharedParameterObjects.DhApiRenderParam;
import com.seibel.lod.api.objects.events.DhApiEventDefinition;
/**
* @author James Seibel
* @version 2022-11-21
*/
public abstract class DhApiAfterRenderEvent implements IDhApiEvent<DhApiAfterRenderEvent.EventParam>
{
/** Fired after Distant Horizons finishes rendering fake chunks. */
public abstract void afterRender(EventParam input);
//=========================//
// internal DH API methods //
//=========================//
@Override
public final boolean fireEvent(EventParam input)
{
this.afterRender(input);
return false;
}
public final static DhApiEventDefinition EVENT_DEFINITION = new DhApiEventDefinition(false, false);
@Override
public final DhApiEventDefinition getEventDefinition() { return EVENT_DEFINITION; }
//==================//
// parameter object //
//==================//
public static class EventParam extends DhApiRenderParam
{
public EventParam(DhApiRenderParam parent)
{
super(parent.mcProjectionMatrix, parent.mcModelViewMatrix, parent.dhProjectionMatrix, parent.dhModelViewMatrix, parent.partialTicks);
}
}
}
@@ -1,33 +0,0 @@
package com.seibel.lod.api.methods.events.abstractEvents;
import com.seibel.lod.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.lod.api.objects.events.DhApiEventDefinition;
/**
* @author James Seibel
* @version 2022-11-21
*/
public abstract class DhApiBeforeDhInitEvent implements IDhApiEvent<Void>
{
/** Fired before Distant Horizons starts its initial setup on Minecraft startup. */
public abstract void beforeDistantHorizonsInit();
//=========================//
// internal DH API methods //
//=========================//
@Override
public final boolean fireEvent(Void ignoredParam)
{
this.beforeDistantHorizonsInit();
return false;
}
public final static DhApiEventDefinition EVENT_DEFINITION = new DhApiEventDefinition(false, true);
@Override
public final DhApiEventDefinition getEventDefinition() { return EVENT_DEFINITION; }
}
@@ -1,45 +0,0 @@
package com.seibel.lod.api.methods.events.abstractEvents;
import com.seibel.lod.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.lod.api.methods.events.sharedParameterObjects.DhApiRenderParam;
import com.seibel.lod.api.objects.events.DhApiEventDefinition;
/**
* @author James Seibel
* @version 2022-11-21
*/
public abstract class DhApiBeforeRenderEvent implements IDhApiEvent<DhApiBeforeRenderEvent.EventParam>
{
/**
* Fired before Distant Horizons renders fake chunks.
*
* @return whether the event should be canceled or not.
*/
public abstract boolean beforeRender(EventParam input);
//=========================//
// internal DH API methods //
//=========================//
@Override
public final boolean fireEvent(EventParam input) { return this.beforeRender(input); }
public final static DhApiEventDefinition EVENT_DEFINITION = new DhApiEventDefinition(true, false);
@Override
public final DhApiEventDefinition getEventDefinition() { return EVENT_DEFINITION; }
//==================//
// parameter object //
//==================//
public static class EventParam extends DhApiRenderParam
{
public EventParam(DhApiRenderParam parent)
{
super(parent.mcProjectionMatrix, parent.mcModelViewMatrix, parent.dhProjectionMatrix, parent.dhModelViewMatrix, parent.partialTicks);
}
}
}
@@ -1,46 +0,0 @@
package com.seibel.lod.api.methods.events.abstractEvents;
import com.seibel.lod.api.interfaces.world.IDhApiLevelWrapper;
import com.seibel.lod.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.lod.api.objects.events.DhApiEventDefinition;
/**
* @author James Seibel
* @version 2022-11-21
*/
public abstract class DhApiLevelLoadEvent implements IDhApiEvent<DhApiLevelLoadEvent.EventParam>
{
/** Fired after Distant Horizons loads a new level. */
public abstract void onLevelLoad(EventParam input);
//=========================//
// internal DH API methods //
//=========================//
@Override
public final boolean fireEvent(EventParam input)
{
this.onLevelLoad(input);
return false;
}
public final static DhApiEventDefinition EVENT_DEFINITION = new DhApiEventDefinition(false, false);
@Override
public final DhApiEventDefinition getEventDefinition() { return EVENT_DEFINITION; }
//==================//
// parameter object //
//==================//
public static class EventParam
{
/** The newly loaded level. */
public final IDhApiLevelWrapper levelWrapper;
public EventParam(IDhApiLevelWrapper newLevelWrapper) { this.levelWrapper = newLevelWrapper; }
}
}
@@ -1,46 +0,0 @@
package com.seibel.lod.api.methods.events.abstractEvents;
import com.seibel.lod.api.interfaces.world.IDhApiLevelWrapper;
import com.seibel.lod.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.lod.api.objects.events.DhApiEventDefinition;
/**
* @author James Seibel
* @version 2022-11-21
*/
public abstract class DhApiLevelSaveEvent implements IDhApiEvent<DhApiLevelSaveEvent.EventParam>
{
/** Fired after Distant Horizons saves LOD data for the server. */
public abstract void onLevelSave(EventParam input);
//=========================//
// internal DH API methods //
//=========================//
@Override
public final boolean fireEvent(EventParam input)
{
this.onLevelSave(input);
return false;
}
public final static DhApiEventDefinition EVENT_DEFINITION = new DhApiEventDefinition(false, false);
@Override
public final DhApiEventDefinition getEventDefinition() { return EVENT_DEFINITION; }
//==================//
// parameter object //
//==================//
public static class EventParam
{
/** The saved level. */
public final IDhApiLevelWrapper levelWrapper;
public EventParam(IDhApiLevelWrapper newLevelWrapper) { this.levelWrapper = newLevelWrapper; }
}
}
@@ -1,45 +0,0 @@
package com.seibel.lod.api.methods.events.abstractEvents;
import com.seibel.lod.api.interfaces.world.IDhApiLevelWrapper;
import com.seibel.lod.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.lod.api.objects.events.DhApiEventDefinition;
/**
* @author James Seibel
* @version 2022-11-21
*/
public abstract class DhApiLevelUnloadEvent implements IDhApiEvent<DhApiLevelUnloadEvent.EventParam>
{
/** Fired before Distant Horizons unloads a level. */
public abstract void onLevelUnload(EventParam input);
//=========================//
// internal DH API methods //
//=========================//
@Override
public final boolean fireEvent(EventParam input)
{
this.onLevelUnload(input);
return false;
}
public final static DhApiEventDefinition EVENT_DEFINITION = new DhApiEventDefinition(false, false);
@Override
public final DhApiEventDefinition getEventDefinition() { return EVENT_DEFINITION; }
//==================//
// parameter object //
//==================//
public static class EventParam
{
/** The recently unloaded level. */
public final IDhApiLevelWrapper levelWrapper;
public EventParam(IDhApiLevelWrapper newLevelWrapper) { this.levelWrapper = newLevelWrapper; }
}
}
@@ -1,52 +0,0 @@
package com.seibel.lod.api.methods.events.interfaces;
import com.seibel.lod.api.objects.events.DhApiEventDefinition;
import com.seibel.lod.coreapi.interfaces.dependencyInjection.IBindable;
/**
* The interface used by all DH Api events.
*
* @param <T> This is the datatype that will be passed into the event handler's method.
*
* @author James Seibel
* @version 2022-11-20
*/
public interface IDhApiEvent<T> extends IBindable
{
//==========//
// external //
//==========//
/**
* Returns true if the event should be automatically unbound
* after firing. <br>
* Can be useful for one time setup events or waiting for a specific game state. <br> <Br>
*
* Defaults to False
* IE: The event will not be removed after firing and will continue firing until removed.
*/
default boolean removeAfterFiring() { return false; };
//==========//
// internal //
//==========//
/**
* The event definition includes meta information about how the event will behave. <br>
* For example: if the event is cancelable or not.
*/
DhApiEventDefinition getEventDefinition();
/**
* Called internally by Distant Horizons when the event happens.
* This method shouldn't directly be overridden and
* should call a more specific method instead.
*
* @param input the parameter object passed in from the event source. Can be null.
* @return whether the event should be canceled or not.
* A canceled event will still fire the other event handlers that are queued.
*/
boolean fireEvent(T input);
}
@@ -1,42 +0,0 @@
package com.seibel.lod.api.methods.events.sharedParameterObjects;
import com.seibel.lod.coreapi.util.math.Mat4f;
/**
* Parameter passed into Render events.
*
* @author James Seibel
* @version 2022-9-5
*/
public class DhApiRenderParam
{
/** The projection matrix Minecraft is using to render this frame. */
public final Mat4f mcProjectionMatrix;
/** The model view matrix Minecraft is using to render this frame. */
public final Mat4f mcModelViewMatrix;
/** The projection matrix Distant Horizons is using to render this frame. */
public final Mat4f dhProjectionMatrix;
/** The model view matrix Distant Horizons is using to render this frame. */
public final Mat4f dhModelViewMatrix;
/** Indicates how far into this tick the frame is. */
public final float partialTicks;
public DhApiRenderParam(
Mat4f newMcProjectionMatrix, Mat4f newMcModelViewMatrix,
Mat4f newDhProjectionMatrix, Mat4f newDhModelViewMatrix,
float newPartialTicks)
{
this.mcProjectionMatrix = newMcProjectionMatrix;
this.mcModelViewMatrix = newMcModelViewMatrix;
this.dhProjectionMatrix = newDhProjectionMatrix;
this.dhModelViewMatrix = newDhModelViewMatrix;
this.partialTicks = newPartialTicks;
}
}
@@ -1,37 +0,0 @@
package com.seibel.lod.api.methods.override;
import com.seibel.lod.api.interfaces.override.worldGenerator.IDhApiWorldGenerator;
import com.seibel.lod.api.interfaces.override.worldGenerator.IDhApiWorldGeneratorOverrideRegister;
import com.seibel.lod.api.interfaces.world.IDhApiLevelWrapper;
import com.seibel.lod.api.objects.DhApiResult;
import com.seibel.lod.coreapi.DependencyInjection.WorldGeneratorInjector;
/**
* Handles adding world generator overrides.
*
* @author James Seibel
* @version 2022-12-10
*/
public class DhApiWorldGeneratorOverrideRegister implements IDhApiWorldGeneratorOverrideRegister
{
public static DhApiWorldGeneratorOverrideRegister INSTANCE = new DhApiWorldGeneratorOverrideRegister();
private DhApiWorldGeneratorOverrideRegister() { }
@Override
public DhApiResult<Void> registerWorldGeneratorOverride(IDhApiLevelWrapper levelWrapper, IDhApiWorldGenerator worldGenerator)
{
try
{
WorldGeneratorInjector.INSTANCE.bind(levelWrapper, worldGenerator);
return DhApiResult.createSuccess();
}
catch (Exception e)
{
return DhApiResult.createFail(e.getMessage());
}
}
}
@@ -1 +0,0 @@
The overide api package holds objects and methods for overriding Distant Horizons' backend systems, so they can be replaced and improved.
@@ -1,51 +0,0 @@
package com.seibel.lod.api.objects;
/**
* Allows for more descriptive non-critical failure states.
*
* @param <T> The payload type this result contains, can be Void if the result is just used to notify success/failure.
*
* @author James Seibel
* @version 2022-11-24
*/
public class DhApiResult<T>
{
/** True if the action succeeded, false otherwise. */
public final boolean success;
/**
* If the action failed this will contain the reason as to why. <br>
* If the action was successful this will generally be the empty string.
*/
public final String message;
/**
* Whatever object the API Method generated/returned. <br>
* Will be null/Void if this result is just used to notify success/failure.
*/
public final T payload;
// these constructors are private because the create... methods below are easier to understand
private DhApiResult(boolean success, String message) { this(success, message, null); }
private DhApiResult(boolean success, String message, T payload)
{
this.success = success;
// don't allow null messages, in the case of a null message return the empty string to prevent potential null pointers
this.message = (message == null) ? "" : message;
this.payload = payload;
}
public static <Pt> DhApiResult<Pt> createSuccess() { return new DhApiResult<>(true, ""); }
public static <Pt> DhApiResult<Pt> createSuccess(Pt payload) { return new DhApiResult<Pt>(true, "", payload); }
// There is no createSuccess(String message) method because it would be too easy to confuse with createSuccess(Pt payload) when returning null
public static <Pt> DhApiResult<Pt> createSuccess(String message, Pt payload) { return new DhApiResult<Pt>(true, message, payload); }
public static <Pt> DhApiResult<Pt> createFail() { return new DhApiResult<>(false, ""); }
public static <Pt> DhApiResult<Pt> createFail(String message) { return new DhApiResult<>(false, message); }
public static <Pt> DhApiResult<Pt> createFail(String message, Pt payload) { return new DhApiResult<Pt>(false, message, payload); }
}
@@ -1,75 +0,0 @@
package com.seibel.lod.api.objects.config;
import com.seibel.lod.api.interfaces.config.IDhApiConfigValue;
import com.seibel.lod.coreapi.interfaces.config.IConfigEntry;
import com.seibel.lod.coreapi.interfaces.config.IConverter;
import com.seibel.lod.coreapi.util.converters.DefaultConverter;
/**
* A wrapper used to interface with Distant Horizon's Config. <br> <br>
*
* When using this object you need to explicitly define the generic types,
* otherwise Intellij won't do any type checking and the wrong types can be used. <br>
* For example a method returning IDhApiConfig<Integer> when the config should be a Boolean.
*
* @param <apiType> The datatype you, an API dev will use.
* @param <coreType> The datatype Distant Horizons uses in the background; implementing developers can ignore this.
*
* @author James Seibel
* @version 2022-6-30
*/
public class DhApiConfigValue<coreType, apiType> implements IDhApiConfigValue<apiType>
{
private final IConfigEntry<coreType> configEntry;
private final IConverter<coreType, apiType> configConverter;
/**
* This constructor should only be called internally. <br>
* There is no reason for API users to create this object. <br><br>
*
* Uses the default object converter, this requires coreType and apiType to be the same.
*/
@SuppressWarnings("unchecked") // DefaultConverter's cast is safe
public DhApiConfigValue(IConfigEntry<coreType> newConfigEntry)
{
this.configEntry = newConfigEntry;
this.configConverter = (IConverter<coreType, apiType>) new DefaultConverter<coreType>();
}
/**
* This constructor should only be called internally. <br>
* There is no reason for API users to create this object. <br><br>
*/
public DhApiConfigValue(IConfigEntry<coreType> newConfigEntry, IConverter<coreType, apiType> newConverter)
{
this.configEntry = newConfigEntry;
this.configConverter = newConverter;
}
public apiType getValue() { return this.configConverter.convertToApiType(this.configEntry.get()); }
public apiType getTrueValue() { return this.configConverter.convertToApiType(this.configEntry.getTrueValue()); }
public apiType getApiValue() { return this.configConverter.convertToApiType(this.configEntry.getApiValue()); }
public boolean setValue(apiType newValue)
{
if (this.configEntry.getAllowApiOverride())
{
this.configEntry.setApiValue(this.configConverter.convertToCoreType(newValue));
return true;
}
else
{
return false;
}
}
public boolean getCanBeOverrodeByApi() { return this.configEntry.getAllowApiOverride(); }
public apiType getDefaultValue() { return this.configConverter.convertToApiType(configEntry.getDefaultValue()); }
public apiType getMaxValue() { return this.configConverter.convertToApiType(this.configEntry.getMax()); }
public apiType getMinValue() { return this.configConverter.convertToApiType(this.configEntry.getMin()); }
}
@@ -1,36 +0,0 @@
package com.seibel.lod.api.objects.data;
import com.seibel.lod.api.objects.math.DhApiVec3i;
import com.seibel.lod.coreapi.util.math.Vec3i;
/**
* Holds a single datapoint of terrain data
* and the block position from the raycast.
*
* @author James Seibel
* @version 2022-11-19
*/
public class DhApiRaycastResult
{
/**
* LOD position of this raycast. <br><br>
*
* <strong>Note: </strong>
* This will NOT be the exact block position if the LOD the ray
* hits is more than one block tall. In that case this will
* be the bottom block position for that LOD.
*/
public final DhApiVec3i pos;
/** The LOD data at this position. */
public final DhApiTerrainDataPoint dataPoint;
public DhApiRaycastResult(DhApiTerrainDataPoint dataPoint, Vec3i blockPos)
{
this.dataPoint = dataPoint;
this.pos = blockPos;
}
}
@@ -1,44 +0,0 @@
package com.seibel.lod.api.objects.data;
import com.seibel.lod.api.interfaces.block.IDhApiBiomeWrapper;
import com.seibel.lod.api.interfaces.block.IDhApiBlockStateWrapper;
/**
* Holds a single datapoint of terrain data.
*
* @author James Seibel
* @version 2022-11-13
*/
public class DhApiTerrainDataPoint
{
/**
* 0 = block <br>
* 1 = 2x2 blocks <br>
* 2 = 4x4 blocks <br>
* 4 = chunk (16x16 blocks) <br>
* 9 = region (512x512 blocks) <br>
*/
public final byte detailLevel;
public final int lightLevel;
public final int topYBlockPos;
public final int bottomYBlockPos;
public final IDhApiBlockStateWrapper blockStateWrapper;
public final IDhApiBiomeWrapper biomeWrapper;
public DhApiTerrainDataPoint(byte detailLevel, int lightLevel, int topYBlockPos, int bottomYBlockPos, IDhApiBlockStateWrapper blockStateWrapper, IDhApiBiomeWrapper biomeWrapper)
{
this.detailLevel = detailLevel;
this.lightLevel = lightLevel;
this.topYBlockPos = topYBlockPos;
this.bottomYBlockPos = bottomYBlockPos;
this.blockStateWrapper = blockStateWrapper;
this.biomeWrapper = biomeWrapper;
}
}
@@ -1,55 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.objects.events;
import com.seibel.lod.api.methods.events.interfaces.IDhApiEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.HashMap;
/**
* The event definition includes meta information about how the event will behave.
*
* @author James Seibel
* @version 2022-11-20
*/
public class DhApiEventDefinition
{
/** True if the event can be canceled. */
public final boolean isCancelable;
/**
* True if the event will only ever be fired once. <Br>
* An example of this would be initial setup methods, DH won't run its initial setup more than once. <br><br>
*
* If a handler is bound for a one time event after the event has been fired, the handler will be immediately fired.
*/
public final boolean isOneTimeEvent;
public DhApiEventDefinition(boolean isCancelable, boolean isOneTimeEvent)
{
this.isCancelable = isCancelable;
this.isOneTimeEvent = isOneTimeEvent;
}
}
@@ -1,92 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.api.objects.math;
/**
* Often used to store block positions or any other
* position in 3D space.
*
* @author James Seibel
* @version 2022-11-19
*/
public class DhApiVec3i
{
public int x;
public int y;
public int z;
/** creates a Vec3 at (0,0,0) */
public DhApiVec3i()
{
this.x = 0;
this.y = 0;
this.z = 0;
}
public DhApiVec3i(int x, int y, int z)
{
this.x = x;
this.y = y;
this.z = z;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
else if (obj != null && this.getClass() == obj.getClass())
{
DhApiVec3i Vec3f = (DhApiVec3i) obj;
if (Float.compare(Vec3f.x, this.x) != 0)
{
return false;
}
else if (Float.compare(Vec3f.y, this.y) != 0)
{
return false;
}
else
{
return Float.compare(Vec3f.z, this.z) == 0;
}
}
else
{
return false;
}
}
@Override
public int hashCode()
{
int i = Float.floatToIntBits(this.x);
i = 31 * i + Float.floatToIntBits(this.y);
return 31 * i + Float.floatToIntBits(this.z);
}
@Override
public String toString() { return "[" + this.x + ", " + this.y + ", " + this.z + "]"; }
}
@@ -1,155 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.coreapi.DependencyInjection;
import com.seibel.lod.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.lod.coreapi.events.ApiEventDefinitionHandler;
import com.seibel.lod.coreapi.interfaces.dependencyInjection.IBindable;
import com.seibel.lod.api.interfaces.events.IDhApiEventInjector;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.ArrayList;
import java.util.HashMap;
/**
* This class takes care of dependency injection for API events.
*
* @author James Seibel
* @version 2022-11-24
*/
public class ApiEventInjector extends DependencyInjector<IDhApiEvent> implements IDhApiEventInjector // Note to self: Don't try adding a generic type to IDhApiEvent, the constructor won't accept it
{
public static final ApiEventInjector INSTANCE = new ApiEventInjector();
private static final Logger LOGGER = LogManager.getLogger(ApiEventInjector.class.getSimpleName());
private final HashMap<Class<? extends IDhApiEvent>, Object> firedOneTimeEventParamsByEventInterface = new HashMap<>();
private ApiEventInjector() { super(IDhApiEvent.class, true); }
@SuppressWarnings("unchecked")
@Override
public void bind(Class<? extends IDhApiEvent> abstractEvent, IDhApiEvent eventImplementation) throws IllegalStateException, IllegalArgumentException
{
// is this a one time event?
if (ApiEventDefinitionHandler.INSTANCE.getEventDefinition(abstractEvent).isOneTimeEvent)
{
// has this one time event been fired yet?
if (this.firedOneTimeEventParamsByEventInterface.containsKey(abstractEvent))
{
// the one time event has happened, fire the handler
// this has to be an unsafe cast since the hash map can't hold the generic objects
Object parameter = this.firedOneTimeEventParamsByEventInterface.get(abstractEvent);
eventImplementation.fireEvent(parameter);
}
}
// bind the event handler
super.bind(abstractEvent, eventImplementation);
}
@Override
public boolean unbind(Class<? extends IDhApiEvent> abstractEvent, Class<? extends IDhApiEvent> eventClassToRemove) throws IllegalArgumentException
{
// make sure the given dependency implements the necessary interfaces
boolean implementsInterface = this.checkIfClassImplements(eventClassToRemove, abstractEvent) ||
this.checkIfClassExtends(eventClassToRemove, abstractEvent);
boolean implementsBindable = this.checkIfClassImplements(eventClassToRemove, this.bindableInterface);
// display any errors
if (!implementsInterface)
{
throw new IllegalArgumentException("The event handler [" + eventClassToRemove.getSimpleName() + "] doesn't implement or extend: [" + abstractEvent.getSimpleName() + "].");
}
if (!implementsBindable)
{
throw new IllegalArgumentException("The event handler [" + eventClassToRemove.getSimpleName() + "] doesn't implement the interface: [" + IBindable.class.getSimpleName() + "].");
}
// actually remove the dependency
if (this.dependencies.containsKey(abstractEvent))
{
ArrayList<IDhApiEvent> dependencyList = this.dependencies.get(abstractEvent);
int indexToRemove = -1;
for(int i = 0; i < dependencyList.size(); i++)
{
IBindable dependency = dependencyList.get(i);
if (dependency.getClass().equals(eventClassToRemove))
{
indexToRemove = i;
break;
}
}
if (indexToRemove != -1)
{
return dependencyList.remove(indexToRemove) != null;
}
}
// no item was removed
return false;
}
@Override
public <T, U extends IDhApiEvent<T>> boolean fireAllEvents(Class<U> abstractEvent, T eventParameterObject)
{
boolean cancelEvent = false;
// if this is a one time event, record that it was called
if (ApiEventDefinitionHandler.INSTANCE.getEventDefinition(abstractEvent).isOneTimeEvent &&
!this.firedOneTimeEventParamsByEventInterface.containsKey(abstractEvent))
{
this.firedOneTimeEventParamsByEventInterface.put(abstractEvent, eventParameterObject);
}
// fire each bound event
ArrayList<U> eventList = this.getAll(abstractEvent);
for (IDhApiEvent<T> event : eventList)
{
if (event != null)
{
try
{
// fire each event and record if any of them
// request to cancel the event.
cancelEvent |= event.fireEvent(eventParameterObject);
}
catch (Exception e)
{
LOGGER.error("Exception thrown by event handler [" + event.getClass().getSimpleName() + "] for event type [" + abstractEvent.getSimpleName() + "], error:" + e.getMessage(), e);
}
}
}
return cancelEvent;
}
}
@@ -1,205 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.coreapi.DependencyInjection;
import com.seibel.lod.coreapi.interfaces.dependencyInjection.IBindable;
import com.seibel.lod.coreapi.interfaces.dependencyInjection.IDependencyInjector;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
* This class takes care of tracking objects used in dependency injection.
*
* @param <BindableType> extends IBindable and defines what interfaces this dependency handler can deal with.
* @author James Seibel
* @version 2022-11-24
*/
public class DependencyInjector<BindableType extends IBindable> implements IDependencyInjector<BindableType> // Note to self: Don't try adding a generic type to IDhApiEvent, the constructor won't accept it
{
protected final Map<Class<? extends BindableType>, ArrayList<BindableType>> dependencies = new HashMap<>();
/** Internal class reference to BindableType since we can't get it any other way. */
protected final Class<? extends BindableType> bindableInterface;
protected final boolean allowDuplicateBindings;
public DependencyInjector(Class<BindableType> newBindableInterface)
{
this.bindableInterface = newBindableInterface;
this.allowDuplicateBindings = false;
}
public DependencyInjector(Class<BindableType> newBindableInterface, boolean newAllowDuplicateBindings)
{
this.bindableInterface = newBindableInterface;
this.allowDuplicateBindings = newAllowDuplicateBindings;
}
@Override
public void bind(Class<? extends BindableType> dependencyInterface, BindableType dependencyImplementation) throws IllegalStateException, IllegalArgumentException
{
// duplicate check if requested
if (this.dependencies.containsKey(dependencyInterface) && !this.allowDuplicateBindings)
{
throw new IllegalStateException("The dependency [" + dependencyInterface.getSimpleName() + "] has already been bound.");
}
// make sure the given dependency implements the necessary interfaces
boolean implementsInterface = this.checkIfClassImplements(dependencyImplementation.getClass(), dependencyInterface) ||
this.checkIfClassExtends(dependencyImplementation.getClass(), dependencyInterface);
boolean implementsBindable = this.checkIfClassImplements(dependencyImplementation.getClass(), this.bindableInterface);
// display any errors
if (!implementsInterface)
{
throw new IllegalArgumentException("The dependency [" + dependencyImplementation.getClass().getSimpleName() + "] doesn't implement or extend: [" + dependencyInterface.getSimpleName() + "].");
}
if (!implementsBindable)
{
throw new IllegalArgumentException("The dependency [" + dependencyImplementation.getClass().getSimpleName() + "] doesn't implement the interface: [" + IBindable.class.getSimpleName() + "].");
}
// make sure the hashSet has an array to hold the dependency
if (!this.dependencies.containsKey(dependencyInterface))
{
this.dependencies.put(dependencyInterface, new ArrayList<BindableType>());
}
// add the dependency
this.dependencies.get(dependencyInterface).add(dependencyImplementation);
}
@Override
public boolean checkIfClassImplements(Class<?> classToTest, Class<?> interfaceToLookFor)
{
// check the parent class (if applicable)
if (classToTest.getSuperclass() != Object.class && classToTest.getSuperclass() != null)
{
if (this.checkIfClassImplements(classToTest.getSuperclass(), interfaceToLookFor))
{
return true;
}
}
// check interfaces
for (Class<?> implementationInterface : classToTest.getInterfaces())
{
// recurse to check interface parents if necessary
if (implementationInterface.getInterfaces().length != 0)
{
if (this.checkIfClassImplements(implementationInterface, interfaceToLookFor))
{
return true;
}
}
if (implementationInterface.equals(interfaceToLookFor))
{
return true;
}
}
return false;
}
@Override
public boolean checkIfClassExtends(Class<?> classToTest, Class<?> extensionToLookFor) { return extensionToLookFor.isAssignableFrom(classToTest); }
@SuppressWarnings("unchecked")
@Override
public <T extends BindableType> T get(Class<T> interfaceClass) throws ClassCastException
{
return (T) this.getInternalLogic(interfaceClass, false).get(0);
}
@Override
public <T extends BindableType> ArrayList<T> getAll(Class<T> interfaceClass) throws ClassCastException
{
return this.getInternalLogic(interfaceClass, false);
}
@Override
public <T extends BindableType> T get(Class<T> interfaceClass, boolean allowIncompleteDependencies) throws ClassCastException
{
return (T) this.getInternalLogic(interfaceClass, allowIncompleteDependencies).get(0);
}
/**
* Always returns a list of size 1 or greater,
* if no dependencies have been bound the list will contain null.
*/
@SuppressWarnings("unchecked")
private <T extends BindableType> ArrayList<T> getInternalLogic(Class<T> interfaceClass, boolean allowIncompleteDependencies) throws ClassCastException
{
ArrayList<BindableType> dependencyList = this.dependencies.get(interfaceClass);
if (dependencyList != null && dependencyList.size() != 0)
{
// check if each dependencies' delayed setup has been completed
for (IBindable dependency : dependencyList)
{
if (!dependency.getDelayedSetupComplete() && !allowIncompleteDependencies)
{
// a warning can be used here instead if desired
//this.logger.warn("Got dependency of type [" + interfaceClass.getSimpleName() + "], but the dependency's delayed setup hasn't been run!");
throw new IllegalStateException("Got dependency of type [" + interfaceClass.getSimpleName() + "], but the dependency's delayed setup hasn't been run!");
}
}
return (ArrayList<T>) dependencyList;
}
// return an empty list to prevent null pointers
ArrayList<T> emptyList = new ArrayList<T>();
emptyList.add(null);
return emptyList;
}
/** Removes all bound dependencies. */
@Override
public void clear() { this.dependencies.clear(); }
/** Runs delayed setup for any dependencies that require it. */
@Override
public void runDelayedSetup()
{
for (Class<? extends BindableType> interfaceKey : this.dependencies.keySet())
{
IBindable concreteObject = this.get(interfaceKey, true);
if (!concreteObject.getDelayedSetupComplete())
{
concreteObject.finishDelayedSetup();
}
}
}
}
@@ -1,132 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.coreapi.DependencyInjection;
import com.seibel.lod.api.interfaces.override.IDhApiOverrideable;
import com.seibel.lod.coreapi.interfaces.dependencyInjection.IOverrideInjector;
import com.seibel.lod.coreapi.util.StringUtil;
import java.util.HashMap;
/**
* This class takes care of dependency injection for overridable objects. <Br>
* This is done so other mods can override our methods to improve features down the line.
*
* @author James Seibel
* @version 2022-9-8
*/
public class OverrideInjector implements IOverrideInjector<IDhApiOverrideable>
{
public static final OverrideInjector INSTANCE = new OverrideInjector();
private final HashMap<Class<? extends IDhApiOverrideable>, OverridePriorityListContainer> overrideContainerByInterface = new HashMap<>();
/**
* This is used to determine if an override is part of Distant Horizons'
* Core or not.
* This probably isn't the best way of going about this, but it works for now.
*/
private final String corePackagePath;
public OverrideInjector()
{
String thisPackageName = this.getClass().getPackage().getName();
int secondPackageEndingIndex = StringUtil.nthIndexOf(thisPackageName, ".", 3);
this.corePackagePath = thisPackageName.substring(0, secondPackageEndingIndex); // this should be "com.seibel.lod"
}
public OverrideInjector(String newCorePackagePath) { this.corePackagePath = newCorePackagePath; }
@Override
public void bind(Class<? extends IDhApiOverrideable> dependencyInterface, IDhApiOverrideable dependencyImplementation) throws IllegalStateException, IllegalArgumentException
{
// make sure a override container exists
OverridePriorityListContainer overrideContainer = this.overrideContainerByInterface.get(dependencyInterface);
if (overrideContainer == null)
{
overrideContainer = new OverridePriorityListContainer();
this.overrideContainerByInterface.put(dependencyInterface, overrideContainer);
}
// validate the new override //
// check if this override is a core override
if (dependencyImplementation.getPriority() == CORE_PRIORITY)
{
// this claims to be a core override, is that true?
String packageName = dependencyImplementation.getClass().getPackage().getName();
if (!packageName.startsWith(this.corePackagePath))
{
throw new IllegalArgumentException("Only Distant Horizons internal objects can use the Override Priority [" + CORE_PRIORITY + "]. Please use a higher number.");
}
}
// make sure the override has a valid priority
else if (dependencyImplementation.getPriority() < MIN_NON_CORE_OVERRIDE_PRIORITY)
{
throw new IllegalArgumentException("Invalid priority value [" + dependencyImplementation.getPriority() + "], override priorities must be [" + MIN_NON_CORE_OVERRIDE_PRIORITY + "] or greater.");
}
// check if an override already exists with this priority
IDhApiOverrideable existingOverride = overrideContainer.getOverrideWithPriority(dependencyImplementation.getPriority());
if (existingOverride != null)
{
throw new IllegalStateException("An override already exists with the priority [" + dependencyImplementation.getPriority() + "].");
}
// bind the override
overrideContainer.addOverride(dependencyImplementation);
}
@Override
@SuppressWarnings("unchecked")
public <T extends IDhApiOverrideable> T get(Class<T> interfaceClass) throws ClassCastException
{
OverridePriorityListContainer overrideContainer = this.overrideContainerByInterface.get(interfaceClass);
return overrideContainer != null ? (T) overrideContainer.getOverrideWithHighestPriority() : null;
}
@Override
@SuppressWarnings("unchecked")
public <T extends IDhApiOverrideable> T get(Class<T> interfaceClass, int priority) throws ClassCastException
{
OverridePriorityListContainer overrideContainer = this.overrideContainerByInterface.get(interfaceClass);
return overrideContainer != null ? (T) overrideContainer.getOverrideWithPriority(priority) : null;
}
@Override
public void clear() { this.overrideContainerByInterface.clear(); }
}
@@ -1,116 +0,0 @@
package com.seibel.lod.coreapi.DependencyInjection;
import com.seibel.lod.api.interfaces.override.IDhApiOverrideable;
import com.seibel.lod.coreapi.interfaces.dependencyInjection.IBindable;
import java.util.ArrayList;
/**
* Contains a list of overrides and their priorities.
*
* @author James Seibel
* @version 2022-9-5
*/
public class OverridePriorityListContainer implements IBindable
{
/** Sorted highest priority to lowest */
private final ArrayList<OverridePriorityPair> overridePairList = new ArrayList<>();
/** Doesn't do any validation */
public void addOverride(IDhApiOverrideable override)
{
OverridePriorityPair priorityPair = new OverridePriorityPair(override, override.getPriority());
this.overridePairList.add(priorityPair);
sortList();
}
/** @return true if the override was removed from the list, false otherwise. */
public boolean removeOverride(IDhApiOverrideable override)
{
if (this.overridePairList.contains(override))
{
this.overridePairList.remove(override);
sortList();
return true;
}
else
{
return false;
}
}
// getters //
public IDhApiOverrideable getOverrideWithLowestPriority()
{
if (this.overridePairList.size() == 0)
{
return null;
}
else
{
// last item should have the highest priority
return this.overridePairList.get(this.overridePairList.size() - 1).override;
}
}
public IDhApiOverrideable getOverrideWithHighestPriority()
{
if (this.overridePairList.size() != 0)
{
return this.overridePairList.get(0).override;
}
else
{
return null;
}
}
public IDhApiOverrideable getCoreOverride()
{
int lastIndex = this.overridePairList.size() - 1;
if (this.overridePairList.get(lastIndex) != null && this.overridePairList.get(lastIndex).priority == OverrideInjector.CORE_PRIORITY)
{
return this.overridePairList.get(lastIndex).override;
}
else
{
return null;
}
}
/** Returns null if no override with the given priority is found */
public IDhApiOverrideable getOverrideWithPriority(int priority)
{
for (OverridePriorityPair pair : this.overridePairList)
{
if (pair.priority == priority)
{
return pair.override;
}
}
return null;
}
// utils //
/** sort the list so the highest priority item is first in the list */
private void sortList() { this.overridePairList.sort((x,y) -> Integer.compare(y.priority, x.priority)); }
private class OverridePriorityPair
{
public final IDhApiOverrideable override;
public int priority;
public OverridePriorityPair(IDhApiOverrideable newOverride, int newPriority)
{
this.override = newOverride;
this.priority = newPriority;
}
}
}
@@ -1,124 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.coreapi.DependencyInjection;
import com.seibel.lod.api.interfaces.override.worldGenerator.IDhApiWorldGenerator;
import com.seibel.lod.api.interfaces.world.IDhApiLevelWrapper;
import com.seibel.lod.coreapi.interfaces.dependencyInjection.IBindable;
import com.seibel.lod.coreapi.util.StringUtil;
import java.util.HashMap;
/**
* This class takes care of dependency injection for world generators. <Br>
* This is done so other mods can override our world generator(s) to improve or replace them.
* @author James Seibel
* @version 2022-12-10
*/
public class WorldGeneratorInjector
{
public static final WorldGeneratorInjector INSTANCE = new WorldGeneratorInjector();
private final HashMap<IDhApiLevelWrapper, OverrideInjector> worldGeneratorByLevelWrapper = new HashMap<>();
/**
* This is used to determine if an override is part of Distant Horizons'
* Core or not.
* This probably isn't the best way of going about this, but it works for now.
*/
private final String corePackagePath;
public WorldGeneratorInjector()
{
String thisPackageName = this.getClass().getPackage().getName();
int secondPackageEndingIndex = StringUtil.nthIndexOf(thisPackageName, ".", 3);
this.corePackagePath = thisPackageName.substring(0, secondPackageEndingIndex); // this should be "com.seibel.lod"
}
/** This constructor should only be used for testing different corePackagePaths. */
public WorldGeneratorInjector(String newCorePackagePath)
{
this.corePackagePath = newCorePackagePath;
}
/**
* Binds a world generator to the given level. <Br>
* See {@link DependencyInjector#bind(Class, IBindable) bind(Class, IBindable)} for full documentation.
*
* @throws NullPointerException if any parameter is null
* @throws IllegalArgumentException if a non-Distant Horizons world generator with the priority CORE is passed in
*
* @see DependencyInjector#bind(Class, IBindable)
*/
public void bind(IDhApiLevelWrapper levelForWorldGenerator, IDhApiWorldGenerator worldGeneratorImplementation) throws NullPointerException, IllegalArgumentException
{
// validate inputs
if (levelForWorldGenerator == null)
{
throw new NullPointerException("A [" + IDhApiLevelWrapper.class.getSimpleName() + "] is required when binding a world generator.");
}
if (worldGeneratorImplementation == null)
{
throw new NullPointerException("No [" + IDhApiWorldGenerator.class.getSimpleName() + "] given.");
}
// bind this generator to the given level
if (!this.worldGeneratorByLevelWrapper.containsKey(levelForWorldGenerator))
{
this.worldGeneratorByLevelWrapper.put(levelForWorldGenerator, new OverrideInjector(this.corePackagePath));
}
this.worldGeneratorByLevelWrapper.get(levelForWorldGenerator).bind(IDhApiWorldGenerator.class, worldGeneratorImplementation);
}
/**
* Returns the bound world generator with the highest priority. <br>
* Returns null if no world generators have been bound for this specific level. <br><br>
*
* See {@link OverrideInjector#get(Class) get(Class)} for full documentation.
* @see OverrideInjector#get(Class)
*/
public IDhApiWorldGenerator get(IDhApiLevelWrapper levelForWorldGenerator) throws ClassCastException
{
if (!this.worldGeneratorByLevelWrapper.containsKey(levelForWorldGenerator))
{
// no generator exists for this specific level.
return null;
}
// use the existing world generator
return this.worldGeneratorByLevelWrapper.get(levelForWorldGenerator).get(IDhApiWorldGenerator.class);
}
/** Removes all bound world generators. */
public void clear() { this.worldGeneratorByLevelWrapper.clear(); }
}
@@ -1,92 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.coreapi.events;
import com.seibel.lod.api.methods.events.abstractEvents.*;
import com.seibel.lod.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.lod.api.objects.events.DhApiEventDefinition;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.HashMap;
/**
* Holds the API event definitions
* so, they can be accessed without an
* event instance.
*
* @author James Seibel
* @version 2022-11-24
*/
public class ApiEventDefinitionHandler
{
private static final Logger LOGGER = LogManager.getLogger(ApiEventDefinitionHandler.class.getSimpleName());
// note to self: don't try adding a generic interface type here, the event dependency handler's constructor method won't accept it
private final HashMap<Class<? extends IDhApiEvent>, DhApiEventDefinition> DEFINITIONS_BY_EVENT_INTERFACE = new HashMap<>();
public static final ApiEventDefinitionHandler INSTANCE = new ApiEventDefinitionHandler();
private ApiEventDefinitionHandler() { this.addInitialBindings(); }
/** This must include all available events */
public void addInitialBindings()
{
this.setEventDefinition(DhApiAfterDhInitEvent.class, DhApiAfterDhInitEvent.EVENT_DEFINITION);
this.setEventDefinition(DhApiAfterRenderEvent.class, DhApiAfterRenderEvent.EVENT_DEFINITION);
this.setEventDefinition(DhApiBeforeDhInitEvent.class, DhApiBeforeDhInitEvent.EVENT_DEFINITION);
this.setEventDefinition(DhApiBeforeRenderEvent.class, DhApiBeforeRenderEvent.EVENT_DEFINITION);
this.setEventDefinition(DhApiLevelLoadEvent.class, DhApiLevelLoadEvent.EVENT_DEFINITION);
this.setEventDefinition(DhApiLevelSaveEvent.class, DhApiLevelSaveEvent.EVENT_DEFINITION);
this.setEventDefinition(DhApiLevelUnloadEvent.class, DhApiLevelUnloadEvent.EVENT_DEFINITION);
}
/**
* This should only be used for unit testing.
* Under normal circumstances there isn't any reason to clear the event definitions.
*/
public void clear() { this.DEFINITIONS_BY_EVENT_INTERFACE.clear(); }
public void setEventDefinition(Class<? extends IDhApiEvent> eventInterface, DhApiEventDefinition definition)
{
if (this.DEFINITIONS_BY_EVENT_INTERFACE.containsKey(eventInterface))
{
LOGGER.warn("duplicate key added [" + eventInterface.getSimpleName() + "]");
}
this.DEFINITIONS_BY_EVENT_INTERFACE.put(eventInterface, definition);
}
public DhApiEventDefinition getEventDefinition(Class<? extends IDhApiEvent> eventInterface)
{
if (!this.DEFINITIONS_BY_EVENT_INTERFACE.containsKey(eventInterface))
{
throw new NullPointerException("event definition missing for: [" + eventInterface.getSimpleName() + "]");
}
return this.DEFINITIONS_BY_EVENT_INTERFACE.get(eventInterface);
}
}
@@ -1,59 +0,0 @@
package com.seibel.lod.coreapi.interfaces.config;
/**
* Use for making the config variables
*
* @author coolGi
* @version 2022-5-26
*/
public interface IConfigEntry<T>
{
/** Gets the default value of the option */
T getDefaultValue();
void setApiValue(T newApiValue);
T getApiValue();
/** Returns true if this config can be set via the API. */
boolean getAllowApiOverride();
void set(T newValue);
T get();
T getTrueValue();
/** Sets the value without saving */
void setWithoutSaving(T newValue);
/** Gets the min value */
T getMin();
/** Sets the min value */
void setMin(T newMin);
/** Gets the max value */
T getMax();
/** Sets the max value */
void setMax(T newMax);
/** Sets the min and max in 1 setter */
void setMinMax(T newMin, T newMax);
/** Gets the comment */
String getComment();
/** Sets the comment */
void setComment(String newComment);
/**
* Checks if the option is valid
*
* 0 == valid
* 1 == number too high
* -1 == number too low
*/
byte isValid();
/** Checks if a value is valid */
byte isValid(T value);
/** Is the value of this equal to another */
boolean equals(IConfigEntry<?> obj);
}
@@ -1,20 +0,0 @@
package com.seibel.lod.coreapi.interfaces.config;
/**
* Interface used for converting Core and API objects.
*
* @param <CoreType> The type used by DH Core (not visible to the API user)
* @param <ApiType> The type used by DH API (not used by Core)
* @author James Seibel
* @version 2022-7-16
*/
public interface IConverter<CoreType, ApiType>
{
CoreType convertToCoreType(ApiType apiObject);
ApiType convertToApiType(CoreType coreObject);
}
@@ -1,75 +0,0 @@
package com.seibel.lod.coreapi.interfaces.dependencyInjection;
import java.util.ArrayList;
public interface IDependencyInjector<BindableType extends IBindable>
{
/**
* Links the given implementation object to an interface, so it can be referenced later.
*
* @param dependencyInterface The interface (or parent class) the implementation object should implement.
* @param dependencyImplementation An object that implements the dependencyInterface interface.
* @throws IllegalStateException if the interface has already been bound and duplicates aren't allowed
* @throws IllegalArgumentException if the implementation object doesn't implement the interface
*/
void bind(Class<? extends BindableType> dependencyInterface, BindableType dependencyImplementation) throws IllegalStateException, IllegalArgumentException;
/**
* Checks if classToTest (or one of its ancestors)
* implements the given interface.
*/
boolean checkIfClassImplements(Class<?> classToTest, Class<?> interfaceToLookFor);
/** Checks if classToTest extends the given class. */
boolean checkIfClassExtends(Class<?> classToTest, Class<?> extensionToLookFor);
/**
* This does not return incomplete dependencies. <Br>
* See {@link #get(Class, boolean) get(Class, boolean)} for full documentation.
*
* @see #get(Class, boolean)
*/
@SuppressWarnings("unchecked")
<T extends BindableType> T get(Class<T> interfaceClass) throws ClassCastException;
/**
* Returns all dependencies of type T that have been bound. <br>
* Returns an empty list if no dependencies have been bound.
*
* @param <T> class of the dependency
* (inferred from the objectClass parameter)
* @param interfaceClass Interface of the dependency
* @return the dependency of type T
* @throws ClassCastException If the dependency isn't able to be cast to type T.
* (this shouldn't normally happen, unless the bound object changed somehow)
*/
<T extends BindableType> ArrayList<T> getAll(Class<T> interfaceClass) throws ClassCastException;
/**
* Returns a dependency of type T if one has been bound. <br>
* Returns null if a dependency hasn't been bound. <br> <br>
*
* If the handler's {@link #allowDuplicateBindings} is true this returns the first bound dependency.
*
* @param <T> class of the dependency
* (inferred from the interfaceClass parameter)
* @param interfaceClass Interface of the dependency
* @param allowIncompleteDependencies If true this method will also return dependencies that haven't completed their delayed setup.
* @return the dependency of type T
* @throws ClassCastException If the dependency isn't able to be cast to type T.
* (this shouldn't normally happen, unless the bound object changed somehow)
*/
@SuppressWarnings("unchecked")
<T extends BindableType> T get(Class<T> interfaceClass, boolean allowIncompleteDependencies) throws ClassCastException;
/** Removes all bound dependencies. */
public void clear();
/** Runs delayed setup for any dependencies that require it. */
void runDelayedSetup();
}
@@ -1,56 +0,0 @@
package com.seibel.lod.coreapi.interfaces.dependencyInjection;
import com.seibel.lod.api.interfaces.override.IDhApiOverrideable;
public interface IOverrideInjector<BindableType extends IBindable>
{
/**
* All core overrides should have this priority. <Br>
* Should be lower than MIN_OVERRIDE_PRIORITY.
*/
public static final int CORE_PRIORITY = -1;
/**
* The lowest priority non-core overrides can have.
* Should be higher than CORE_PRIORITY.
*/
public static final int MIN_NON_CORE_OVERRIDE_PRIORITY = 0;
/** The priority given to overrides that don't explicitly define a priority. */
public static final int DEFAULT_NON_CORE_OVERRIDE_PRIORITY = 10;
/**
* See {@link IDependencyInjector#bind(Class, IBindable) bind(Class, IBindable)} for full documentation.
*
* @throws IllegalArgumentException if a non-Distant Horizons Override with the priority CORE is passed in or a invalid priority value.
* @throws IllegalStateException if another override with the given priority already has been bound.
* @see IDependencyInjector#bind(Class, IBindable)
*/
void bind(Class<? extends IDhApiOverrideable> dependencyInterface, IDhApiOverrideable dependencyImplementation) throws IllegalStateException, IllegalArgumentException;
/**
* Returns the bound dependency with the highest priority. <br>
* See {@link IDependencyInjector#get(Class, boolean) get(Class, boolean)} for full documentation.
*
* @see IDependencyInjector#get(Class, boolean)
*/
<T extends IDhApiOverrideable> T get(Class<T> interfaceClass) throws ClassCastException;
/**
* Returns a dependency of type T with the specified priority if one has been bound. <br>
* If there is a dependency, but it was bound with a different priority this will return null. <br> <br>
*
* See {@link IDependencyInjector#get(Class, boolean) get(Class, boolean)} for more documentation.
*
* @see IDependencyInjector#get(Class, boolean)
*/
<T extends IDhApiOverrideable> T get(Class<T> interfaceClass, int priority) throws ClassCastException;
/** Removes all bound overrides. */
void clear();
}
@@ -1,78 +0,0 @@
package com.seibel.lod.coreapi.util;
/**
* A list of helper methods to make code easier to read. <br>
* Specifically written because bit shifts short circuit James' brain.
*
* @author James Seibel
* @version 2022-11-6
*/
public class BitShiftUtil
{
/**
* Equivalent to: <br>
* 1 << value, <br>
* 2^value, <br>
* Math.pow(2, value) <br><br>
*
* Note: Math.pow() isn't identical for large values where bits would be lost in the shift, however for medium to small values they function the same. <br><br>
*
* Can also be used to replace bit shifts in the format: <br>
* multiplier << value; <br>
* multiplier * powerOfTwo(value);
*/
public static int powerOfTwo(int value) { return 1 << value; }
/** see {@link BitShiftUtil#powerOfTwo(int)} for documentation */
public static long powerOfTwo(long value) { return 1 << value; }
/**
* Equivalent to: <br>
* value >> 1, <br>
* value / 2 <br><br>
*
* Note: value / 2 isn't identical for negative values
*/
public static int half(int value) { return value >> 1; }
/** see {@link BitShiftUtil#half(int)} for documentation */
public static long half(long value) { return value >> 1; }
/**
* Equivalent to: <br>
* value >> power, <br>
* value / 2^power <br><br>
*
* Note: value / 2^power isn't identical for negative values
*/
public static int divideByPowerOfTwo(int value, int power) { return value >> power; }
/** see {@link BitShiftUtil#divideByPowerOfTwo(int, int)} for documentation */
public static long divideByPowerOfTwo(long value, long power) { return value >> power; }
/**
* Equivalent to: <br>
* value << 1, <br>
* value^2, <br>
* Math.pow(value, 2) <br><br>
*
* Note: Math.pow() isn't identical for large values where bits would be lost in the shift, however for medium to small values they function the same.
*/
public static int square(int value) { return value << 1; }
/** see {@link BitShiftUtil#square(int)} for documentation */
public static long square(long value) { return value << 1; }
/**
* Equivalent to: <br>
* value << power, <br>
* value^power, <br>
* Math.pow(value, power) <br><br>
*
* Note: Math.pow() isn't identical for large values where bits would be lost in the shift, however for medium to small values they function the same.
*/
public static int pow(int value, int power) { return value << power; }
/** see {@link BitShiftUtil#pow(int, int)} for documentation */
public static long pow(long value, long power) { return value << power; }
}
@@ -1,55 +0,0 @@
package com.seibel.lod.coreapi.util;
public class MathUtil
{
/**
* Clamps the given value between the min and max values.
* May behave strangely if min > max.
*/
public static int clamp(int min, int value, int max) { return Math.min(max, Math.max(value, min)); }
/**
* Clamps the given value between the min and max values.
* May behave strangely if min > max.
*/
public static float clamp(float min, float value, float max) { return Math.min(max, Math.max(value, min)); }
/**
* Clamps the given value between the min and max values.
* May behave strangely if min > max.
*/
public static double clamp(double min, double value, double max) { return Math.min(max, Math.max(value, min)); }
/**
* Like Math.floorDiv, but reverse in that it is a ceilDiv
*/
public static int ceilDiv(int value, int divider) { return -Math.floorDiv(-value, divider); }
// Why is this not in the standard library?! Come on Java!
public static byte min(byte a, byte b) { return a < b ? a : b; }
public static byte max(byte a, byte b) { return a > b ? a : b; }
/** This is copied from Minecraft's MathHelper class */
public static float fastInvSqrt(float numb)
{
float half = 0.5F * numb;
int i = Float.floatToIntBits(numb);
i = 1597463007 - (i >> 1);
numb = Float.intBitsToFloat(i);
return numb * (1.5F - half * numb * numb);
}
public static float pow2(float x) { return x * x; }
public static double pow2(double x) { return x * x; }
public static int pow2(int x) { return x * x; }
public static long pow2(long x) { return x * x; }
/** Equivalent to Log_2(numb) */
public static int log2(int numb)
{
// properties of logs allow us to use the base Log_e() method
return (int)(Math.log(numb) / Math.log(2));
}
}
@@ -1,42 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.coreapi.util;
/**
* Miscellaneous string helper functions.
*
* @author James Seibel
* @version 2022-7-19
*/
public class StringUtil
{
/**
* Returns the n-th index of the given string. <br> <br>
*
* Original source: https://stackoverflow.com/questions/3976616/how-to-find-nth-occurrence-of-character-in-a-string
*/
public static int nthIndexOf(String str, String substr, int n)
{
int pos = str.indexOf(substr);
while (--n > 0 && pos != -1)
pos = str.indexOf(substr, pos + 1);
return pos;
}
}
@@ -1,26 +0,0 @@
package com.seibel.lod.coreapi.util.converters;
import com.seibel.lod.coreapi.interfaces.config.IConverter;
/**
* Returns the object passed in, doesn't do any conversion. <br>
* Helpful as the default converter in some cases.
*
* @author James Seibel
* @version 2022-6-30
*/
public class DefaultConverter<T> implements IConverter<T, T>
{
@Override
public T convertToCoreType(T apiObject)
{
return apiObject;
}
@Override
public T convertToApiType(T coreObject)
{
return coreObject;
}
}
@@ -1,25 +0,0 @@
package com.seibel.lod.coreapi.util.converters;
import com.seibel.lod.api.enums.rendering.ERendererMode;
import com.seibel.lod.coreapi.interfaces.config.IConverter;
/**
* Used for simplifying the fake chunk rendering on/off setting.
*
* @author James Seibel
* @version 2022-6-30
*/
public class RenderModeEnabledConverter implements IConverter<ERendererMode, Boolean>
{
@Override public ERendererMode convertToCoreType(Boolean renderingEnabled)
{
return renderingEnabled ? ERendererMode.DEFAULT : ERendererMode.DISABLED;
}
@Override public Boolean convertToApiType(ERendererMode renderingMode)
{
return renderingMode == ERendererMode.DEFAULT;
}
}
@@ -1,36 +0,0 @@
package testItems.events.abstractObjects;
import com.seibel.lod.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.lod.api.objects.events.DhApiEventDefinition;
/**
* A dummy event implementation used for unit testing.
*
* @author James Seibel
* @version 2022-11-20
*/
public abstract class DhApiOneTimeTestEvent implements IDhApiEvent<Boolean>
{
public abstract void onTestEvent(Boolean input);
/** just used for testing */
public abstract Boolean getTestValue();
//=========================//
// internal DH API methods //
//=========================//
@Override
public final boolean fireEvent(Boolean input)
{
this.onTestEvent(input);
return input;
}
public final static DhApiEventDefinition EVENT_DEFINITION = new DhApiEventDefinition(false, true);
@Override
public final DhApiEventDefinition getEventDefinition() { return EVENT_DEFINITION; }
}
@@ -1,37 +0,0 @@
package testItems.events.abstractObjects;
import com.seibel.lod.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.lod.api.objects.events.DhApiEventDefinition;
/**
* A dummy event implementation used for unit testing.
*
* @author James Seibel
* @version 2022-11-20
*/
public abstract class DhApiTestEvent implements IDhApiEvent<Boolean>
{
public abstract void onTestEvent(Boolean input);
/** just used for testing */
public abstract Boolean getTestValue();
//=========================//
// internal DH API methods //
//=========================//
@Override
public final boolean fireEvent(Boolean input)
{
this.onTestEvent(input);
return input;
}
public final static DhApiEventDefinition EVENT_DEFINITION = new DhApiEventDefinition(false, false);
@Override
public final DhApiEventDefinition getEventDefinition() { return EVENT_DEFINITION; }
}
@@ -1,26 +0,0 @@
package testItems.events.objects;
import testItems.events.abstractObjects.DhApiOneTimeTestEvent;
/**
* Dummy test event for unit tests.
*
* @author James Seibel
* @version 2022-11-20
*/
public class DhOneTimeTestEventHandler extends DhApiOneTimeTestEvent
{
public Boolean eventFiredValue = null;
@Override
public void onTestEvent(Boolean input) { this.eventFiredValue = input; }
@Override
public boolean removeAfterFiring() { return false; }
// test (non standard) methods //
@Override
public Boolean getTestValue() { return this.eventFiredValue; }
}
@@ -1,12 +0,0 @@
package testItems.events.objects;
/**
* Dummy test event for unit tests.
*
* @author James Seibel
* @version 2022-11-20
*/
public class DhOneTimeTestEventHandlerAlt extends DhOneTimeTestEventHandler
{
// all other code should be a duplicate of the parent
}
@@ -1,30 +0,0 @@
package testItems.events.objects;
import testItems.events.abstractObjects.DhApiTestEvent;
/**
* Dummy test event for unit tests.
*
* @author James Seibel
* @version 2022-9-11
*/
public class DhTestEventHandler extends DhApiTestEvent
{
public Boolean eventFiredValue = null;
@Override
public void onTestEvent(Boolean input)
{
this.eventFiredValue = input;
}
@Override
public boolean removeAfterFiring() { return false; }
// test (non standard) methods //
@Override
public Boolean getTestValue() { return eventFiredValue; }
}
@@ -1,30 +0,0 @@
package testItems.events.objects;
import testItems.events.abstractObjects.DhApiTestEvent;
/**
* Dummy test event for unit tests.
*
* @author James Seibel
* @version 2022-9-11
*/
public class DhTestEventHandlerAlt extends DhApiTestEvent
{
public Boolean eventFiredValue = null;
@Override
public void onTestEvent(Boolean input)
{
this.eventFiredValue = input;
}
@Override
public boolean removeAfterFiring() { return false; }
// test (non standard) methods //
@Override
public Boolean getTestValue() { return eventFiredValue; }
}
@@ -1,181 +0,0 @@
package tests;
import com.seibel.lod.api.methods.events.abstractEvents.DhApiAfterDhInitEvent;
import com.seibel.lod.api.objects.events.DhApiEventDefinition;
import com.seibel.lod.coreapi.DependencyInjection.ApiEventInjector;
import com.seibel.lod.coreapi.events.ApiEventDefinitionHandler;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import testItems.events.abstractObjects.DhApiOneTimeTestEvent;
import testItems.events.objects.DhOneTimeTestEventHandler;
import testItems.events.objects.DhOneTimeTestEventHandlerAlt;
import testItems.events.abstractObjects.DhApiTestEvent;
import testItems.events.objects.DhTestEventHandler;
import testItems.events.objects.DhTestEventHandlerAlt;
import java.util.ArrayList;
/**
* @author James Seibel
* @version 2022-11-25
*/
public class EventInjectorTest
{
@Before
public void testSetup()
{
ApiEventDefinitionHandler definitionHandler = ApiEventDefinitionHandler.INSTANCE;
// reset the injectors and event definitions
ApiEventInjector.INSTANCE.clear();
definitionHandler.clear();
// register test events
definitionHandler.setEventDefinition(DhApiTestEvent.class, DhApiTestEvent.EVENT_DEFINITION);
definitionHandler.setEventDefinition(DhApiOneTimeTestEvent.class, DhApiOneTimeTestEvent.EVENT_DEFINITION);
definitionHandler.addInitialBindings();
}
@Test
public void testGeneralAndRecurringEvents() // this also tests list dependencies since there can be more than one event handler bound per event
{
// Injector setup
ApiEventInjector TEST_EVENT_HANDLER = ApiEventInjector.INSTANCE;
// pre-dependency setup
Assert.assertNull("Nothing should have been bound.", TEST_EVENT_HANDLER.get(DhApiTestEvent.class));
// dependency setup
TEST_EVENT_HANDLER.bind(DhApiTestEvent.class, new DhTestEventHandler());
TEST_EVENT_HANDLER.bind(DhApiTestEvent.class, new DhTestEventHandlerAlt());
TEST_EVENT_HANDLER.runDelayedSetup();
// get first
DhApiTestEvent afterRenderEvent = TEST_EVENT_HANDLER.get(DhApiTestEvent.class);
Assert.assertNotNull("Event not bound.", afterRenderEvent);
// get list
ArrayList<DhApiTestEvent> afterRenderEventList = TEST_EVENT_HANDLER.getAll(DhApiTestEvent.class);
Assert.assertEquals("Bound list doesn't contain the correct number of items.", 2, afterRenderEventList.size());
// object one
Assert.assertNotNull("Event not bound.", afterRenderEventList.get(0));
Assert.assertEquals("First event object setup incorrectly.", null, afterRenderEventList.get(0).getTestValue());
// object two
Assert.assertNotNull("Event not bound.", afterRenderEventList.get(1));
Assert.assertEquals("First event object setup incorrectly.", null, afterRenderEventList.get(1).getTestValue());
// event firing
Assert.assertEquals("fireAllEvents canceled returned canceled incorrectly.", true, TEST_EVENT_HANDLER.fireAllEvents(DhApiTestEvent.class, true));
// object one
Assert.assertEquals("Event not fired for first object.", true, afterRenderEventList.get(0).getTestValue());
// object two
Assert.assertEquals("Event not fired for second object.", true, afterRenderEventList.get(1).getTestValue());
// unbind
DhApiTestEvent unboundEvent = afterRenderEventList.get(0);
Assert.assertTrue("Unbind should've removed item.", TEST_EVENT_HANDLER.unbind(DhApiTestEvent.class, DhTestEventHandler.class));
Assert.assertFalse("Unbind should've already removed item.", TEST_EVENT_HANDLER.unbind(DhApiTestEvent.class, DhTestEventHandler.class));
// check unbinding
afterRenderEventList = TEST_EVENT_HANDLER.getAll(DhApiTestEvent.class);
Assert.assertEquals("Unbound list doesn't contain the correct number of items.", 1, afterRenderEventList.size());
Assert.assertNotNull("Unbinding removed all items.", afterRenderEventList.get(0));
// check unbound event firing
Assert.assertEquals("fireAllEvents canceled returned canceled incorrectly.", false, TEST_EVENT_HANDLER.fireAllEvents(DhApiTestEvent.class, false));
// remaining event
Assert.assertEquals("Event not fired for remaining object.", false, ((DhTestEventHandlerAlt) afterRenderEventList.get(0)).eventFiredValue);
// unbound event
Assert.assertEquals("Event fired for unbound object.", true, unboundEvent.getTestValue());
// prevent event handlers from being bound to the wrong event interface
Assert.assertThrows("Event bound to a non-implementing interface.", IllegalArgumentException.class, () -> { TEST_EVENT_HANDLER.bind(DhApiOneTimeTestEvent.class, new DhTestEventHandler()); });
Assert.assertThrows("Event bound to a non-implementing interface.", IllegalArgumentException.class, () -> { TEST_EVENT_HANDLER.bind(DhApiTestEvent.class, new DhOneTimeTestEventHandler()); });
}
@Test
public void testEventDefinition()
{
ApiEventDefinitionHandler definitionHandler = ApiEventDefinitionHandler.INSTANCE;
String errorMessagePrefix = "Missing " + DhApiEventDefinition.class.getSimpleName() + " for event class [";
Assert.assertNotNull(errorMessagePrefix + DhApiTestEvent.class.getSimpleName() + "]", definitionHandler.getEventDefinition(DhApiTestEvent.class));
Assert.assertNotNull(errorMessagePrefix + DhApiOneTimeTestEvent.class.getSimpleName() + "]", definitionHandler.getEventDefinition(DhApiOneTimeTestEvent.class));
Assert.assertNotNull(errorMessagePrefix + DhApiAfterDhInitEvent.class.getSimpleName() + "]", definitionHandler.getEventDefinition(DhApiAfterDhInitEvent.class));
}
@Test
public void oneTimeEventTestPreFireBinding() { this.oneTimeEventTest(false); }
@Test
public void oneTimeEventTestPostFireBinding() { this.oneTimeEventTest(true); }
public void oneTimeEventTest(boolean bindEventBeforeOneTimeFiring)
{
// Injector setup
ApiEventInjector TEST_EVENT_HANDLER = ApiEventInjector.INSTANCE;
// pre-dependency setup
Assert.assertNull("Nothing should have been bound.", TEST_EVENT_HANDLER.get(DhApiOneTimeTestEvent.class));
if (bindEventBeforeOneTimeFiring)
{
TEST_EVENT_HANDLER.bind(DhApiOneTimeTestEvent.class, new DhOneTimeTestEventHandler());
}
TEST_EVENT_HANDLER.runDelayedSetup();
// pre-bound event firing
Assert.assertEquals("fireAllEvents canceled returned canceled incorrectly.", bindEventBeforeOneTimeFiring, TEST_EVENT_HANDLER.fireAllEvents(DhApiOneTimeTestEvent.class, true));
// validate pre-bound events fired correctly
ArrayList<DhApiOneTimeTestEvent> oneTimeEventList;
if (bindEventBeforeOneTimeFiring)
{
oneTimeEventList = TEST_EVENT_HANDLER.getAll(DhApiOneTimeTestEvent.class);
Assert.assertEquals("Event not fired for pre-fire object.", true, oneTimeEventList.get(0).getTestValue());
}
// post-event fire binding
// the event should fire instantly
TEST_EVENT_HANDLER.bind(DhApiOneTimeTestEvent.class, new DhOneTimeTestEventHandlerAlt());
// validate both events have fired
oneTimeEventList = TEST_EVENT_HANDLER.getAll(DhApiOneTimeTestEvent.class);
for (int i = 0; i < oneTimeEventList.size(); i++)
{
Assert.assertEquals("Event not fired for object ["+i+"].", true, oneTimeEventList.get(i).getTestValue());
}
// recurring event test
TEST_EVENT_HANDLER.bind(DhApiTestEvent.class, new DhTestEventHandler());
ArrayList<DhApiTestEvent> recurringEventList = TEST_EVENT_HANDLER.getAll(DhApiTestEvent.class);
Assert.assertNull("This unrelated recurring event shouldn't have been fired.", recurringEventList.get(0).getTestValue());
}
}
-41
View File
@@ -1,41 +0,0 @@
/*
* This file is part of the Distant Horizons mod (formerly the LOD Mod),
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2022 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package tests;
import org.junit.Assert;
import org.junit.Test;
/**
* This is just a quick demo to confirm the testing system is set up correctly.
*
* @author James Seibel
* @version 2022-9-5
*/
public class ExampleTest
{
@Test
public void DemoTest()
{
Assert.assertTrue("Example test 1", true);
Assert.assertFalse("Example test 2", false);
}
}
+37
View File
@@ -0,0 +1,37 @@
plugins {
id "com.github.johnrengelman.shadow" version "7.1.0"
}
configurations {
common
shadowMe
implementation.extendsFrom shadowMe
}
dependencies {
// Toml
shadowMe("com.electronwill.night-config:toml:${rootProject.toml_version}") {}
// Compression
common('org.tukaani:xz:1.9')
common('org.apache.commons:commons-compress:1.21')
shadowMe 'org.tukaani:xz:1.9'
shadowMe 'org.apache.commons:commons-compress:1.21'
}
shadowJar {
configurations = [project.configurations.shadowMe]
relocate 'org.tukaani', 'shaded.tukaani'
relocate 'org.apache.commons.compress', 'shaded.apache.commons.compress'
relocate 'com.electronwill.nightconfig', 'shaded.electronwill.nightconfig'
relocate 'com.seibel.lod.common', 'fabric.com.seibel.lod.common'
classifier "dev-shadow"
}
//remapJar {
// input.set shadowJar.archiveFile
// dependsOn shadowJar
// classifier null
//}

Some files were not shown because too many files have changed in this diff Show More