Skip to content

Commit

Permalink
Added DisruptionFeature (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
Luligabi1 committed Oct 31, 2023
1 parent 61bf780 commit 6b15552
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 0 deletions.
57 changes: 57 additions & 0 deletions base/src/main/kotlin/dev/nathanpb/dml/worldgen/Features.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
*
* Copyright (C) 2021 Nathan P. Bombana, IterationFunk
*
* This file is part of Deep Mob Learning: Refabricated.
*
* Deep Mob Learning: Refabricated 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, either version 3 of the License, or
* (at your option) any later version.
*
* Deep Mob Learning: Refabricated 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 Deep Mob Learning: Refabricated. If not, see <https://www.gnu.org/licenses/>.
*/

package dev.nathanpb.dml.worldgen

import dev.nathanpb.dml.identifier
import dev.nathanpb.dml.worldgen.disruption.DisruptionFeature
import dev.nathanpb.dml.worldgen.disruption.DisruptionFeatureConfig
import net.fabricmc.fabric.api.biome.v1.BiomeModifications
import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext
import net.minecraft.registry.Registries
import net.minecraft.registry.Registry
import net.minecraft.registry.RegistryKey
import net.minecraft.registry.RegistryKeys
import net.minecraft.world.gen.GenerationStep
import net.minecraft.world.gen.feature.Feature
import net.minecraft.world.gen.feature.PlacedFeature
import java.util.function.Predicate


fun registerFeatures() {
Registry.register(Registries.FEATURE, DISRUPTION_KEY.value, DISRUPTION_FEATURE)

/*addFeature(
DISRUPTION_KEY,
BiomeSelectors.foundInOverworld().and(
Predicate.not(BiomeSelectors.tag(ConventionalBiomeTags.AQUATIC))
),
true
) // TODO add config to disable*/
}


private fun addFeature(registryKey: RegistryKey<PlacedFeature>, biomeSelector: Predicate<BiomeSelectionContext>, enabled: Boolean) {
if (!enabled) return
BiomeModifications.addFeature(biomeSelector, GenerationStep.Feature.VEGETAL_DECORATION, registryKey)
}

val DISRUPTION_FEATURE: Feature<DisruptionFeatureConfig> = DisruptionFeature(DisruptionFeatureConfig.CODEC)
val DISRUPTION_KEY = RegistryKey.of(RegistryKeys.PLACED_FEATURE, identifier("disruption"))
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package dev.nathanpb.dml.worldgen.disruption

import com.mojang.serialization.Codec
import dev.nathanpb.dml.block.BLOCK_DISRUPTIONS_CORE
import dev.nathanpb.dml.block.BLOCK_FADING_GLITCHED_TILE
import dev.nathanpb.dml.blockEntity.BlockEntityFadingGlitchedTile
import net.minecraft.block.Block
import net.minecraft.block.entity.LootableContainerBlockEntity
import net.minecraft.loot.LootTables
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.BlockPos.Mutable
import net.minecraft.util.math.Direction
import net.minecraft.world.StructureWorldAccess
import net.minecraft.world.gen.feature.Feature
import net.minecraft.world.gen.feature.util.FeatureContext


class DisruptionFeature(
codec: Codec<DisruptionFeatureConfig>
): Feature<DisruptionFeatureConfig>(codec) {


override fun generate(context: FeatureContext<DisruptionFeatureConfig>): Boolean {
val config = context.config
val random = context.random
val origin = context.origin
val world = context.world


var i = 0
val radius = config.radius.get(random)

val cx: Int = origin.x
val cy: Int = origin.y - 1
val cz: Int = origin.z

for(blockPos in BlockPos.iterate(
BlockPos(cx - radius, cy, cz - radius),
BlockPos(cx + radius, cy, cz + radius)
)) {
if(blockPos.getSquaredDistance(cx.toDouble(), blockPos.y.toDouble(), cz.toDouble()) <= (radius * radius + 1).toDouble()) {
var pos = Mutable(blockPos.x, cy, blockPos.z)
var offset: Direction? = null
var canGenerate = true

if(world.getBlockEntity(pos) != null) { // Abort if block entity
canGenerate = false
} else if(world.getBlockState(pos).isReplaceable) { // Offset downward
if(testPos(pos, Direction.DOWN, world)) {
offset = Direction.DOWN
} else if(!testPos(pos, Direction.UP, world)) { // Abort if block would be floating
canGenerate = false
}
} else if(!world.getBlockState(pos.up()).isReplaceable) { // Offset upward
if(testPos(pos, Direction.UP, world)) {
offset = Direction.UP
} else {
canGenerate = false
}
}

if(canGenerate) {
pos = verticalOffset(pos, offset)

val blockState = world.getBlockState(pos)
world.setBlockState(pos, BLOCK_FADING_GLITCHED_TILE.defaultState, Block.NOTIFY_LISTENERS)
(world.getBlockEntity(pos) as? BlockEntityFadingGlitchedTile)?.blockState = blockState
i++
}
}
}

val hasGenerated = i > 0
if(hasGenerated) {
world.setBlockState(origin, BLOCK_DISRUPTIONS_CORE.defaultState, Block.NOTIFY_LISTENERS)
LootableContainerBlockEntity.setLootTable(world, random, origin, LootTables.WOODLAND_MANSION_CHEST)
}

return hasGenerated
}

private fun testPos(pos: BlockPos, direction: Direction, world: StructureWorldAccess): Boolean {
val offsetPos = pos.offset(direction)
val isReplaceable = world.getBlockState(offsetPos).isReplaceable
val isAboveReplaceable = world.getBlockState(offsetPos.up()).isReplaceable

return !isReplaceable && isAboveReplaceable
}

private fun verticalOffset(pos: Mutable, direction: Direction?): Mutable {
return when(direction) {
Direction.DOWN -> pos.move(Direction.DOWN)
Direction.UP -> pos.move(Direction.UP)
else -> pos
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package dev.nathanpb.dml.worldgen.disruption

import com.mojang.serialization.Codec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.util.math.intprovider.IntProvider
import net.minecraft.world.gen.feature.FeatureConfig


class DisruptionFeatureConfig(val radius: IntProvider) : FeatureConfig {

companion object {
val CODEC: Codec<DisruptionFeatureConfig> =
RecordCodecBuilder.create { instance: RecordCodecBuilder.Instance<DisruptionFeatureConfig> ->
instance.group(
IntProvider.createValidatingCodec(0, 8).fieldOf("radius").forGetter(DisruptionFeatureConfig::radius),
).apply(instance, ::DisruptionFeatureConfig)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"type": "dml-refabricated:disruption",
"config": {
"radius": {
"type": "minecraft:uniform",
"value": {
"max_inclusive": 5,
"min_inclusive": 3
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"feature": "dml-refabricated:disruption",
"placement": []
}

0 comments on commit 6b15552

Please sign in to comment.