<:YukariCope:1215938934815588362> (implementation of 0072-lithium-gen.patch)

This commit is contained in:
DoggySazHi
2024-03-09 10:50:39 -08:00
parent 1a37d828b0
commit c3c31567d0
5 changed files with 243 additions and 2 deletions

View File

@@ -0,0 +1,111 @@
// Nitori Copyright (C) 2024 Gensokyo Reimagined
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package net.gensokyoreimagined.nitori.common.util;
import net.minecraft.core.SectionPos;
import net.minecraft.world.level.LevelHeightAccessor;
/*
* Originally from CaffeineMC, licensed under GNU Lesser General Public License v3.0
* See https://github.com/CaffeineMC/lithium-fabric for more information/sources
*/
public class Pos {
public static class BlockCoord {
public static int getYSize(LevelHeightAccessor view) {
return view.getHeight();
}
public static int getMinY(LevelHeightAccessor view) {
return view.getMinBuildHeight();
}
public static int getMaxYInclusive(LevelHeightAccessor view) {
return view.getMaxBuildHeight() - 1;
}
public static int getMaxYExclusive(LevelHeightAccessor view) {
return view.getMaxBuildHeight();
}
public static int getMaxInSectionCoord(int sectionCoord) {
return 15 + getMinInSectionCoord(sectionCoord);
}
public static int getMaxYInSectionIndex(LevelHeightAccessor view, int sectionIndex){
return getMaxInSectionCoord(SectionYCoord.fromSectionIndex(view, sectionIndex));
}
public static int getMinInSectionCoord(int sectionCoord) {
return SectionPos.sectionToBlockCoord(sectionCoord);
}
public static int getMinYInSectionIndex(LevelHeightAccessor view, int sectionIndex) {
return getMinInSectionCoord(SectionYCoord.fromSectionIndex(view, sectionIndex));
}
}
public static class ChunkCoord {
public static int fromBlockCoord(int blockCoord) {
return SectionPos.blockToSectionCoord(blockCoord);
}
public static int fromBlockSize(int i) {
return i >> 4; //same method as fromBlockCoord, just be clear about coord/size semantic difference
}
}
public static class SectionYCoord {
public static int getNumYSections(LevelHeightAccessor view) {
return view.getSectionsCount();
}
public static int getMinYSection(LevelHeightAccessor view) {
return view.getMinSection();
}
public static int getMaxYSectionInclusive(LevelHeightAccessor view) {
return view.getMaxSection() - 1;
}
public static int getMaxYSectionExclusive(LevelHeightAccessor view) {
return view.getMaxSection();
}
public static int fromSectionIndex(LevelHeightAccessor view, int sectionCoord) {
return sectionCoord + SectionYCoord.getMinYSection(view);
}
public static int fromBlockCoord(int blockCoord) {
return SectionPos.blockToSectionCoord(blockCoord);
}
}
public static class SectionYIndex {
public static int getNumYSections(LevelHeightAccessor view) {
return view.getSectionsCount();
}
public static int getMinYSectionIndex(LevelHeightAccessor view) {
return 0;
}
public static int getMaxYSectionIndexInclusive(LevelHeightAccessor view) {
return view.getSectionsCount() - 1;
}
public static int getMaxYSectionIndexExclusive(LevelHeightAccessor view) {
return view.getSectionsCount();
}
public static int fromSectionCoord(LevelHeightAccessor view, int sectionCoord) {
return sectionCoord - SectionYCoord.getMinYSection(view);
}
public static int fromBlockCoord(LevelHeightAccessor view, int blockCoord) {
return fromSectionCoord(view, SectionPos.blockToSectionCoord(blockCoord));
}
}
}

View File

@@ -15,7 +15,7 @@
package net.gensokyoreimagined.nitori.core;
import com.google.common.collect.Lists;
import net.gensokyoreimagined.nitori.common.util.collections.HashedReferenceList;
import net.gensokyoreimagined.nitori.common.util.collections.wcHashedReferenceList;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.TickingBlockEntity;
import org.spongepowered.asm.mixin.Final;

View File

@@ -0,0 +1,46 @@
// Nitori Copyright (C) 2024 Gensokyo Reimagined
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package net.gensokyoreimagined.nitori.core;
import net.minecraft.core.Holder;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(NoiseBasedChunkGenerator.class)
public class MixinNoiseBasedChunkGenerator {
@Shadow @Final public Holder<NoiseGeneratorSettings> settings;
@Unique
private int gensouHacks$cachedSeaLevel;
@Inject(method = "<init>", at = @At("TAIL"))
public void constructor(BiomeSource biomeSource, Holder settings, CallbackInfo ci) {
this.gensouHacks$cachedSeaLevel = this.settings.value().seaLevel();
}
@Inject(method = "getSeaLevel", at = @At("HEAD"), cancellable = true)
public void getSeaLevel(CallbackInfoReturnable<Integer> cir) {
cir.setReturnValue(this.gensouHacks$cachedSeaLevel);
cir.cancel();
}
}

View File

@@ -0,0 +1,82 @@
// Nitori Copyright (C) 2024 Gensokyo Reimagined
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package net.gensokyoreimagined.nitori.core;
import net.gensokyoreimagined.nitori.common.util.Pos;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
@Mixin(WorldGenRegion.class)
public class MixinWorldGenRegion {
@Shadow @Final private ChunkPos firstPos;
@Shadow @Final private int size;
@Unique
private ChunkAccess[] gensouHacks$chunksArr;
@Unique
private int gensouHacks$minChunkX;
@Unique
private int gensouHacks$minChunkZ;
@Inject(method = "<init>", at = @At("RETURN"))
private void onInit(ServerLevel world, List<ChunkAccess> chunks, ChunkStatus status, int placementRadius, CallbackInfo ci) {
this.gensouHacks$minChunkX = this.firstPos.x;
this.gensouHacks$minChunkZ = this.firstPos.z;
this.gensouHacks$chunksArr = chunks.toArray(new ChunkAccess[0]);
}
@Inject(method = "getChunk(II)Lnet/minecraft/world/level/chunk/ChunkAccess;", at = @At("HEAD"), cancellable = true)
public void getChunk(int chunkX, int chunkZ, CallbackInfoReturnable<ChunkAccess> cir) {
int x = chunkX - this.gensouHacks$minChunkX;
int z = chunkZ - this.gensouHacks$minChunkZ;
int w = this.size;
if (x >= 0 && z >= 0 && x < w && z < w) {
cir.setReturnValue(this.gensouHacks$chunksArr[x + z * w]);
cir.cancel();
} else {
throw new NullPointerException("No chunk exists at " + new ChunkPos(chunkX, chunkZ));
}
}
@Inject(method = "getBlockState", at = @At("HEAD"), cancellable = true)
public void getBlockState(BlockPos pos, CallbackInfoReturnable<BlockState> cir) {
int x = (Pos.ChunkCoord.fromBlockCoord(pos.getX())) - this.gensouHacks$minChunkX;
int z = (Pos.ChunkCoord.fromBlockCoord(pos.getZ())) - this.gensouHacks$minChunkZ;
int w = this.size;
if (x >= 0 && z >= 0 && x < w && z < w) {
cir.setReturnValue(this.gensouHacks$chunksArr[x + z * w].getBlockState(pos));
cir.cancel();
} else {
throw new NullPointerException("No chunk exists at " + new ChunkPos(pos));
}
}
}

View File

@@ -17,6 +17,8 @@
"MixinGameRules",
"MixinPlayer",
"MixinEntity",
"MixinMob"
"MixinMob",
"MixinWorldGenRegion",
"MixinNoiseBasedChunkGenerator"
]
}