add IDhApiLevelWrapper.getBlockColorPreApi()

This commit is contained in:
James Seibel
2026-05-18 19:59:06 -05:00
parent 9465512491
commit 492afa7328
5 changed files with 101 additions and 7 deletions
@@ -21,8 +21,14 @@ package com.seibel.distanthorizons.api.interfaces.world;
import com.seibel.distanthorizons.api.interfaces.IDhApiUnsafeWrapper; import com.seibel.distanthorizons.api.interfaces.IDhApiUnsafeWrapper;
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType; import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBiomeWrapper;
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBlockStateWrapper;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister; import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBlockColorOverrideEvent;
import com.seibel.distanthorizons.api.objects.DhApiResult;
import com.seibel.distanthorizons.api.objects.data.IDhApiFullDataSource;
import java.awt.*;
import java.io.File; import java.io.File;
/** /**
@@ -90,6 +96,26 @@ public interface IDhApiLevelWrapper extends IDhApiUnsafeWrapper
*/ */
File getDhSaveFolder(); File getDhSaveFolder();
/**
* Returns the color DH would use for the given block/biome
* pair at the given world position before any API color overrides
* are considered. <br>
* API color overrides are ignored to prevent infinite
* loops if this event is triggered inside said API override.
* <br><br>
*
* Returns {@link DhApiResult#success} = false if {@link IDhApiLevelWrapper#getLevelType()} returns a {@link EDhApiLevelType#SERVER_LEVEL}
* (server levels have no concept of textures or colors).
*
* @see DhApiBlockColorOverrideEvent
* @since API 7.0.0
*/
DhApiResult<Color> getBlockColorPreApi(
IDhApiBlockStateWrapper blockStateWrapper,
IDhApiBiomeWrapper biomeWrapper,
int blockWorldPosX, int blockWorldPosY, int blockWorldPosZ,
IDhApiFullDataSource dataSource);
} }
@@ -19,16 +19,21 @@
package com.seibel.distanthorizons.api.methods.events.abstractEvents; package com.seibel.distanthorizons.api.methods.events.abstractEvents;
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBiomeWrapper;
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBlockStateWrapper; import com.seibel.distanthorizons.api.interfaces.block.IDhApiBlockStateWrapper;
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper; import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent; import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam; import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam; import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
import com.seibel.distanthorizons.api.objects.data.IDhApiFullDataSource;
import com.seibel.distanthorizons.coreapi.util.ColorUtil; import com.seibel.distanthorizons.coreapi.util.ColorUtil;
/** /**
* Performance note: this event will be fired thousands of times on concurrent threads, * Performance note: this event will be fired millions of times on concurrent threads,
* make it thread safe and as fast as possible. <Br><Br> * make it thread safe and as fast as possible. <br>
* (If every LOD block goes through this event, On a 512 render distance world,
* at the medium quality preset, it will be triggered around 40,000,000 times.)
* <Br><Br>
* *
* This event is fired when DH needs to convert a {@link IDhApiBlockStateWrapper} * This event is fired when DH needs to convert a {@link IDhApiBlockStateWrapper}
* into a color for rendering. This event is fired after DH attempts to determine * into a color for rendering. This event is fired after DH attempts to determine
@@ -41,7 +46,7 @@ import com.seibel.distanthorizons.coreapi.util.ColorUtil;
* via {@link DhApiBlockStateWrapperCreatedEvent.EventParam#setAllowApiColorOverride(boolean)}. * via {@link DhApiBlockStateWrapperCreatedEvent.EventParam#setAllowApiColorOverride(boolean)}.
* *
* @author James Seibel * @author James Seibel
* @version 2026-04-14 * @version 2026-05-18
* @since API 6.0.0 * @since API 6.0.0
* @see IDhApiBlockStateWrapper * @see IDhApiBlockStateWrapper
*/ */
@@ -50,6 +55,7 @@ public abstract class DhApiBlockColorOverrideEvent implements IDhApiEvent<DhApiB
public abstract void onBlockColorOverridden(DhApiEventParam<EventParam> event); public abstract void onBlockColorOverridden(DhApiEventParam<EventParam> event);
//=========================// //=========================//
// internal DH API methods // // internal DH API methods //
//=========================// //=========================//
@@ -58,6 +64,7 @@ public abstract class DhApiBlockColorOverrideEvent implements IDhApiEvent<DhApiB
public final void fireEvent(DhApiEventParam<EventParam> event) { this.onBlockColorOverridden(event); } public final void fireEvent(DhApiEventParam<EventParam> event) { this.onBlockColorOverridden(event); }
//==================// //==================//
// parameter object // // parameter object //
//==================// //==================//
@@ -65,7 +72,9 @@ public abstract class DhApiBlockColorOverrideEvent implements IDhApiEvent<DhApiB
public static class EventParam implements IDhApiEventParam public static class EventParam implements IDhApiEventParam
{ {
private IDhApiLevelWrapper levelWrapper; private IDhApiLevelWrapper levelWrapper;
private IDhApiFullDataSource dataSource;
private IDhApiBlockStateWrapper blockStateWrapper = null; private IDhApiBlockStateWrapper blockStateWrapper = null;
private IDhApiBiomeWrapper biomeWrapper = null;
private int colorAsInt = -1; private int colorAsInt = -1;
private int blockPosX = 0, blockPosY = 0, blockPosZ = 0; private int blockPosX = 0, blockPosY = 0, blockPosZ = 0;
@@ -74,17 +83,22 @@ public abstract class DhApiBlockColorOverrideEvent implements IDhApiEvent<DhApiB
//=============// //=============//
// constructor // // constructor //
//=============// //=============//
//region
public EventParam() {} public EventParam() {}
public void update( public void update(
IDhApiLevelWrapper levelWrapper, IDhApiLevelWrapper levelWrapper,
IDhApiFullDataSource dataSource,
IDhApiBlockStateWrapper blockStateWrapper, IDhApiBlockStateWrapper blockStateWrapper,
IDhApiBiomeWrapper biomeWrapper,
int colorAsInt, int colorAsInt,
int blockPosX, int blockPosY, int blockPosZ) int blockPosX, int blockPosY, int blockPosZ)
{ {
this.levelWrapper = levelWrapper; this.levelWrapper = levelWrapper;
this.dataSource = dataSource;
this.blockStateWrapper = blockStateWrapper; this.blockStateWrapper = blockStateWrapper;
this.biomeWrapper = biomeWrapper;
this.colorAsInt = colorAsInt; this.colorAsInt = colorAsInt;
this.blockPosX = blockPosX; this.blockPosX = blockPosX;
@@ -92,15 +106,27 @@ public abstract class DhApiBlockColorOverrideEvent implements IDhApiEvent<DhApiB
this.blockPosZ = blockPosZ; this.blockPosZ = blockPosZ;
} }
//endregion
//=================// //=================//
// getters/setters // // getters/setters //
//=================// //=================//
//region
public IDhApiBlockStateWrapper getBlockStateWrapper() { return this.blockStateWrapper; } public IDhApiBlockStateWrapper getBlockStateWrapper() { return this.blockStateWrapper; }
/** @since API 7.0.0 */
public IDhApiBiomeWrapper getBiomeWrapper() { return this.biomeWrapper; }
public IDhApiLevelWrapper getLevelWrapper() { return levelWrapper; } /** the level DH is resolving this block's color in. */
public IDhApiLevelWrapper getLevelWrapper() { return this.levelWrapper; }
/**
* The DH datasource that contains this block's position. Can be used to access adjacent
* {@link IDhApiBlockStateWrapper}'s and {@link IDhApiBiomeWrapper}'s for adjacent aware tinting.
* @since API 7.0.0
*/
public IDhApiFullDataSource getDataSource() { return this.dataSource; }
public int getColorAsInt() { return this.colorAsInt; } public int getColorAsInt() { return this.colorAsInt; }
public int getAlpha() { return ColorUtil.getAlpha(this.colorAsInt); } public int getAlpha() { return ColorUtil.getAlpha(this.colorAsInt); }
@@ -130,8 +156,15 @@ public abstract class DhApiBlockColorOverrideEvent implements IDhApiEvent<DhApiB
/** @return the block's Z value in the world */ /** @return the block's Z value in the world */
public int getBlockPosZ() { return blockPosZ; } public int getBlockPosZ() { return blockPosZ; }
//endregion
//==========================//
// base api event overrides //
//==========================//
//region
/** /**
* Returns the same instance of this event. * Returns the same instance of this event.
* Copying this event isn't supported * Copying this event isn't supported
@@ -145,6 +178,8 @@ public abstract class DhApiBlockColorOverrideEvent implements IDhApiEvent<DhApiB
@Override @Override
public boolean getCopyBeforeFire() { return false; } public boolean getCopyBeforeFire() { return false; }
//endregion
} }
@@ -46,7 +46,7 @@ public class DhApiResult<T>
// these constructors are private because the create... methods below are easier to understand // 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) { this(success, message, null); }
private DhApiResult(boolean success, String message, T payload) private DhApiResult(boolean success, String message, T payload)
{ {
@@ -19,12 +19,15 @@
package com.seibel.distanthorizons.core.api.external.methods.data; package com.seibel.distanthorizons.core.api.external.methods.data;
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBiomeWrapper;
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBlockStateWrapper;
import com.seibel.distanthorizons.api.interfaces.data.IDhApiTerrainDataCache; import com.seibel.distanthorizons.api.interfaces.data.IDhApiTerrainDataCache;
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper; import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
import com.seibel.distanthorizons.api.objects.DhApiResult; import com.seibel.distanthorizons.api.objects.DhApiResult;
import com.seibel.distanthorizons.api.objects.data.DhApiRaycastResult; import com.seibel.distanthorizons.api.objects.data.DhApiRaycastResult;
import com.seibel.distanthorizons.api.objects.data.DhApiTerrainDataPoint; import com.seibel.distanthorizons.api.objects.data.DhApiTerrainDataPoint;
import com.seibel.distanthorizons.api.interfaces.data.IDhApiTerrainDataRepo; import com.seibel.distanthorizons.api.interfaces.data.IDhApiTerrainDataRepo;
import com.seibel.distanthorizons.api.objects.data.IDhApiFullDataSource;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3i; import com.seibel.distanthorizons.api.objects.math.DhApiVec3i;
import com.seibel.distanthorizons.core.api.internal.SharedApi; import com.seibel.distanthorizons.core.api.internal.SharedApi;
import com.seibel.distanthorizons.core.dataObjects.fullData.FullDataPointIdMap; import com.seibel.distanthorizons.core.dataObjects.fullData.FullDataPointIdMap;
@@ -34,6 +37,8 @@ import com.seibel.distanthorizons.core.level.IDhLevel;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable;
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer; import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.util.DhApiTerrainDataPointUtil; import com.seibel.distanthorizons.core.util.DhApiTerrainDataPointUtil;
import com.seibel.distanthorizons.core.util.FullDataPointUtil; import com.seibel.distanthorizons.core.util.FullDataPointUtil;
@@ -42,12 +47,16 @@ import com.seibel.distanthorizons.core.util.RayCastUtil;
import com.seibel.distanthorizons.core.util.math.Vec3f; import com.seibel.distanthorizons.core.util.math.Vec3f;
import com.seibel.distanthorizons.core.world.AbstractDhWorld; import com.seibel.distanthorizons.core.world.AbstractDhWorld;
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory; import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.coreapi.util.BitShiftUtil; import com.seibel.distanthorizons.coreapi.util.BitShiftUtil;
import com.seibel.distanthorizons.core.util.math.Vec3d; import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.util.math.Vec3i; import com.seibel.distanthorizons.core.util.math.Vec3i;
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
import it.unimi.dsi.fastutil.longs.LongArrayList; import it.unimi.dsi.fastutil.longs.LongArrayList;
import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLogger;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -78,17 +87,21 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
//=============// //=============//
// constructor // // constructor //
//=============// //=============//
//region
private DhApiTerrainDataRepo() private DhApiTerrainDataRepo()
{ {
} }
//endregion
//================// //================//
// Getter Methods // // Getter Methods //
//================// //================//
//region
@Override @Override
public DhApiResult<DhApiTerrainDataPoint> getSingleDataPointAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosY, int blockPosZ, IDhApiTerrainDataCache dataCache) public DhApiResult<DhApiTerrainDataPoint> getSingleDataPointAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosY, int blockPosZ, IDhApiTerrainDataCache dataCache)
@@ -109,9 +122,12 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
public DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtDetailLevelAndPos(IDhApiLevelWrapper levelWrapper, byte detailLevel, int posX, int posZ, IDhApiTerrainDataCache dataCache) public DhApiResult<DhApiTerrainDataPoint[][][]> getAllTerrainDataAtDetailLevelAndPos(IDhApiLevelWrapper levelWrapper, byte detailLevel, int posX, int posZ, IDhApiTerrainDataCache dataCache)
{ return getTerrainDataOverAreaForPositionDetailLevel(levelWrapper, DhSectionPos.encode(detailLevel, posX, posZ), dataCache); } { return getTerrainDataOverAreaForPositionDetailLevel(levelWrapper, DhSectionPos.encode(detailLevel, posX, posZ), dataCache); }
//endregion
// private getters // // private getters //
//region
/** Returns a single API terrain datapoint that contains the given Y block position */ /** Returns a single API terrain datapoint that contains the given Y block position */
private static DhApiResult<DhApiTerrainDataPoint> getTerrainDataAtBlockYPos(IDhApiLevelWrapper levelWrapper, long requestedColumnPos, Integer blockYPos, IDhApiTerrainDataCache dataCache) private static DhApiResult<DhApiTerrainDataPoint> getTerrainDataAtBlockYPos(IDhApiLevelWrapper levelWrapper, long requestedColumnPos, Integer blockYPos, IDhApiTerrainDataCache dataCache)
@@ -340,11 +356,14 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
} }
} }
//endregion
//====================// //====================//
// raycasting methods // // raycasting methods //
//====================// //====================//
//region
@Override @Override
public DhApiResult<DhApiRaycastResult> raycast( public DhApiResult<DhApiRaycastResult> raycast(
@@ -490,11 +509,14 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
return returnList; return returnList;
} }
//endregion
//================// //================//
// setter methods // // setter methods //
//================// //================//
//region
@Override @Override
public DhApiResult<Void> overwriteChunkDataAsync(IDhApiLevelWrapper levelWrapper, Object[] chunkObjectArray) throws ClassCastException public DhApiResult<Void> overwriteChunkDataAsync(IDhApiLevelWrapper levelWrapper, Object[] chunkObjectArray) throws ClassCastException
@@ -524,20 +546,26 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
return DhApiResult.createSuccess(); return DhApiResult.createSuccess();
} }
//endregion
//=============// //=============//
// API helpers // // API helpers //
//=============// //=============//
//region
@Override @Override
public IDhApiTerrainDataCache createSoftCache() { return new DhApiTerrainDataCache(); } public IDhApiTerrainDataCache createSoftCache() { return new DhApiTerrainDataCache(); }
//endregion
//===============// //===============//
// debug methods // // debug methods //
//===============// //===============//
//region
/** /**
* This method is here for debugging the repo and isn't intended for normal use. * This method is here for debugging the repo and isn't intended for normal use.
@@ -618,5 +646,8 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
} }
} }
//endregion
} }
@@ -32,7 +32,9 @@ public interface IClientLevelWrapper extends ILevelWrapper
@Nullable @Nullable
IServerLevelWrapper tryGetServerSideWrapper(); IServerLevelWrapper tryGetServerSideWrapper();
int getBlockColor(DhBlockPos pos, IBiomeWrapper biome, FullDataSourceV2 fullDataSource, IBlockStateWrapper blockState); default int getBlockColor(DhBlockPos pos, IBiomeWrapper biome, FullDataSourceV2 fullDataSource, IBlockStateWrapper blockState)
{ return this.getBlockColor(pos, biome, fullDataSource, blockState, true); }
int getBlockColor(DhBlockPos pos, IBiomeWrapper biome, FullDataSourceV2 fullDataSource, IBlockStateWrapper blockState, boolean allowApiOverride);
/** @return -1 if there was a problem getting the color */ /** @return -1 if there was a problem getting the color */
int getDirtBlockColor(); int getDirtBlockColor();
void clearBlockColorCache(); void clearBlockColorCache();