Compare commits

...

28 Commits

Author SHA1 Message Date
b40a33f69a feat(swarm): walk farther 2023-08-23 21:35:56 +08:00
22b1450a72 feat: adjust swarm time table 2023-08-23 14:28:06 +08:00
abb5646959 fix: game crash when no container available 2023-08-21 09:10:13 +08:00
1ee1c7215d fix: container focus again 2023-08-18 09:34:07 +08:00
d45f8d2a57 fix: signed 32-bits integer overflowed
Use in the wild: Mojang
2023-08-18 09:28:00 +08:00
cd40ba58da fix: WorkPoiAI not initialized early 2023-08-16 10:22:17 +08:00
d110d688c6 fix: only stroll in near positions 2023-08-11 16:00:14 +08:00
6cc16233fa fix: work poi missing 2023-08-11 15:55:17 +08:00
00ce17cb21 fix: disable despawn for swarm 2023-08-11 15:44:22 +08:00
3a4ad875e2 fix: missing bed memory for swarm 2023-08-11 15:33:25 +08:00
e25f23f40b chore: trigger longjing build 2023-08-11 09:51:19 +08:00
f794f9848b fix: remove debug log 2023-08-10 22:22:40 +08:00
f2b60ca6b0 fix(i18n): json syntax 2023-08-10 22:11:25 +08:00
a68b68a0e3 fix: remove duplicated key 2023-08-10 22:09:21 +08:00
33604db8a0 feat(i18n): add translations 2023-08-10 22:07:56 +08:00
a31321e662 feat: volume scaler 2023-08-10 22:03:32 +08:00
db74d07155 fix: mitigation for container tracker 2023-08-10 11:48:16 +08:00
d578db6fb2 fix: crash 2023-08-10 11:45:21 +08:00
296fe1efc2 fix: crash when trying to interact with destoryed container 2023-08-10 11:41:33 +08:00
2c95dfa660 fix: fix unable to bootstrap registry warning 2023-08-01 17:53:34 +08:00
fa1aefe425 feat: remove 3.0 base factor for music 2023-08-01 17:51:53 +08:00
dca1482526 feat: add quilt support
It is not working at all
2023-08-01 16:56:38 +08:00
9aa248e7f2 build: add fabric support 2023-08-01 15:45:21 +08:00
2b62599485 feat: use sided success for SmartInstrument 2023-08-01 14:57:31 +08:00
f588d3bc72 feat: right-click to cycle projection effect radius 2023-08-01 14:55:35 +08:00
c6edaac2e1 feat: custom projection radius 2023-08-01 14:44:11 +08:00
e18b4d78fb style: format code 2023-07-30 21:19:41 +08:00
68c90c8f8a fix: empty containers are always skipped 2023-07-30 21:15:03 +08:00
34 changed files with 521 additions and 63 deletions

2
.gitignore vendored
View File

@@ -1,4 +1,4 @@
build build
.gradle .gradle
forge/run */run
.idea .idea

View File

@@ -45,6 +45,10 @@ allprojects {
name = "ParchmentMC" name = "ParchmentMC"
setUrl("https://maven.parchmentmc.org") setUrl("https://maven.parchmentmc.org")
} }
maven {
name = "QuiltMC"
setUrl("https://maven.quiltmc.org/repository/release/")
}
} }
dependencies { dependencies {

View File

@@ -1,5 +1,5 @@
architectury { architectury {
common("forge") common("forge", "fabric", "quilt")
} }
loom { loom {

View File

@@ -20,6 +20,7 @@ import quaedam.projection.misc.NoiseProjection
import quaedam.projection.misc.SkylightProjection import quaedam.projection.misc.SkylightProjection
import quaedam.projection.misc.SoundProjection import quaedam.projection.misc.SoundProjection
import quaedam.projection.music.MusicProjection import quaedam.projection.music.MusicProjection
import quaedam.projection.swarm.ProjectedPersonEntity
import quaedam.projection.swarm.SwarmProjection import quaedam.projection.swarm.SwarmProjection
import quaedam.projector.Projector import quaedam.projector.Projector
import quaedam.shell.ProjectionShell import quaedam.shell.ProjectionShell
@@ -48,6 +49,8 @@ object Quaedam {
} }
} }
val lateinit = mutableListOf<() -> Unit>()
fun init() { fun init() {
QuaedamConfig QuaedamConfig
Projector Projector
@@ -75,6 +78,9 @@ object Quaedam {
soundEvents.register() soundEvents.register()
poiTypes.register() poiTypes.register()
projectionEffects.register() projectionEffects.register()
lateinit.forEach { it() }
lateinit.clear()
} }
fun resource(path: String) = ResourceLocation(ID, path) fun resource(path: String) = ResourceLocation(ID, path)

View File

@@ -39,7 +39,7 @@ data class ProjectionEffectType<T : ProjectionEffect>(val constructor: () -> T)
val registryKey: ResourceKey<Registry<ProjectionEffectType<*>>> = val registryKey: ResourceKey<Registry<ProjectionEffectType<*>>> =
ResourceKey.createRegistryKey(Quaedam.resource("projection_effect")) ResourceKey.createRegistryKey(Quaedam.resource("projection_effect"))
val registry: Registry<ProjectionEffectType<*>> = BuiltInRegistries.registerSimple(registryKey) { null } val registry: Registry<ProjectionEffectType<*>> = BuiltInRegistries.registerSimple(registryKey) { nopEffect }
val nopEffect: ProjectionEffectType<NopEffect> = val nopEffect: ProjectionEffectType<NopEffect> =
Registry.register(registry, Quaedam.resource("nop"), ProjectionEffectType { NopEffect }) Registry.register(registry, Quaedam.resource("nop"), ProjectionEffectType { NopEffect })

View File

@@ -59,10 +59,11 @@ object NoiseProjection {
if (projections.isNotEmpty()) { if (projections.isNotEmpty()) {
val rate = projections.maxOf { it.rate } val rate = projections.maxOf { it.rate }
val amount = min(projections.sumOf { it.amount }, 12) val amount = min(projections.sumOf { it.amount }, 12)
val volume = projections.fold(1.0f) { v, p -> v * p.volume }
if (amount != 0 && random.nextInt(1000 / rate) == 1) { if (amount != 0 && random.nextInt(1000 / rate) == 1) {
for (i in 0 until random.nextInt(amount)) { for (i in 0 until random.nextInt(amount)) {
// play random noise // play random noise
playRandomNoise(random, game) playRandomNoise(random, game, volume)
} }
} }
} }
@@ -70,7 +71,7 @@ object NoiseProjection {
} }
} }
private fun playRandomNoise(random: RandomSource, game: Minecraft) { private fun playRandomNoise(random: RandomSource, game: Minecraft, volume: Float) {
val volumeFactor = random.nextInt(100) val volumeFactor = random.nextInt(100)
val sound = SimpleSoundInstance( val sound = SimpleSoundInstance(
soundEvent.get().location, soundEvent.get().location,
@@ -80,7 +81,7 @@ object NoiseProjection {
in 10..15 -> random.nextFloat() * 0.5f + 0.5f in 10..15 -> random.nextFloat() * 0.5f + 0.5f
in 21..50 -> random.nextFloat() * 0.3f in 21..50 -> random.nextFloat() * 0.3f
else -> random.nextFloat() * 0.2f else -> random.nextFloat() * 0.2f
}, } * volume,
random.nextFloat() + 0.4f, random.nextFloat() + 0.4f,
RandomSource.create(random.nextLong()), RandomSource.create(random.nextLong()),
false, false,
@@ -102,12 +103,14 @@ object NoiseProjectionBlock : EntityProjectionBlock<NoiseProjectionEffect>(creat
} }
data class NoiseProjectionEffect(var rate: Int = 250, var amount: Int = 3) : ProjectionEffect(), data class NoiseProjectionEffect(var rate: Int = 250, var amount: Int = 3, var volume: Float = 1.0f) :
ProjectionEffect(),
ProjectionEffectShell.Provider { ProjectionEffectShell.Provider {
companion object { companion object {
const val TAG_RATE = "Rate" const val TAG_RATE = "Rate"
const val TAG_AMOUNT = "Amount" const val TAG_AMOUNT = "Amount"
const val TAG_VOLUME = "Volume"
val maxAmount get() = QuaedamConfig.current.valuesInt["projection.noise.max_amount"] ?: 8 val maxAmount get() = QuaedamConfig.current.valuesInt["projection.noise.max_amount"] ?: 8
val maxRate get() = QuaedamConfig.current.valuesInt["projection.noise.max_rate"] ?: 300 val maxRate get() = QuaedamConfig.current.valuesInt["projection.noise.max_rate"] ?: 300
@@ -119,11 +122,13 @@ data class NoiseProjectionEffect(var rate: Int = 250, var amount: Int = 3) : Pro
override fun toNbt(tag: CompoundTag) { override fun toNbt(tag: CompoundTag) {
tag.putInt(TAG_RATE, rate) tag.putInt(TAG_RATE, rate)
tag.putInt(TAG_AMOUNT, amount) tag.putInt(TAG_AMOUNT, amount)
tag.putFloat(TAG_VOLUME, volume)
} }
override fun fromNbt(tag: CompoundTag, trusted: Boolean) { override fun fromNbt(tag: CompoundTag, trusted: Boolean) {
rate = tag.getInt(TAG_RATE) rate = tag.getInt(TAG_RATE)
amount = tag.getInt(TAG_AMOUNT) amount = tag.getInt(TAG_AMOUNT)
volume = tag.getFloat(TAG_VOLUME)
if (!trusted) { if (!trusted) {
amount = min(amount, maxAmount) amount = min(amount, maxAmount)
rate = min(rate, maxRate) rate = min(rate, maxRate)
@@ -133,6 +138,7 @@ data class NoiseProjectionEffect(var rate: Int = 250, var amount: Int = 3) : Pro
override fun createShell() = buildProjectionEffectShell(this) { override fun createShell() = buildProjectionEffectShell(this) {
intSlider("quaedam.shell.noise.rate", ::rate, 0..maxRate step 5) intSlider("quaedam.shell.noise.rate", ::rate, 0..maxRate step 5)
intSlider("quaedam.shell.noise.amount", ::amount, 0..maxAmount) intSlider("quaedam.shell.noise.amount", ::amount, 0..maxAmount)
floatSlider("quaedam.shell.noise.volume", ::volume, 0.0f..1.0f, 0.1f)
} }
} }

View File

@@ -43,10 +43,12 @@ object SoundProjectionBlock : EntityProjectionBlock<SoundProjectionEffect>(creat
} }
data class SoundProjectionEffect(var rate: Int = 60) : ProjectionEffect(), ProjectionEffectShell.Provider { data class SoundProjectionEffect(var rate: Int = 60, var volume: Float = 1.0f) : ProjectionEffect(),
ProjectionEffectShell.Provider {
companion object { companion object {
const val TAG_RATE = "Rate" const val TAG_RATE = "Rate"
const val TAG_VOLUME = "Volume"
val maxRate get() = QuaedamConfig.current.valuesInt["projection.sound.max_rate"] ?: 210 val maxRate get() = QuaedamConfig.current.valuesInt["projection.sound.max_rate"] ?: 210
} }
@@ -56,10 +58,12 @@ data class SoundProjectionEffect(var rate: Int = 60) : ProjectionEffect(), Proje
override fun toNbt(tag: CompoundTag) { override fun toNbt(tag: CompoundTag) {
tag.putInt(TAG_RATE, rate) tag.putInt(TAG_RATE, rate)
tag.putFloat(TAG_VOLUME, volume)
} }
override fun fromNbt(tag: CompoundTag, trusted: Boolean) { override fun fromNbt(tag: CompoundTag, trusted: Boolean) {
rate = tag.getInt(TAG_RATE) rate = tag.getInt(TAG_RATE)
volume = tag.getFloat(TAG_VOLUME)
if (!trusted) { if (!trusted) {
rate = min(rate, maxRate) rate = min(rate, maxRate)
} }
@@ -67,6 +71,7 @@ data class SoundProjectionEffect(var rate: Int = 60) : ProjectionEffect(), Proje
override fun createShell() = buildProjectionEffectShell(this) { override fun createShell() = buildProjectionEffectShell(this) {
intSlider("quaedam.shell.sound.rate", ::rate, 0..maxRate) intSlider("quaedam.shell.sound.rate", ::rate, 0..maxRate)
floatSlider("quaedam.shell.sound.volume", ::volume, 0.0f..1.0f, 0.1f)
} }
} }

View File

@@ -71,7 +71,7 @@ class MusicPlayer(
// play note // play note
val projections = Projector.findNearbyProjections(level, pos, MusicProjection.effect.get()) val projections = Projector.findNearbyProjections(level, pos, MusicProjection.effect.get())
.takeIf { it.isNotEmpty() } ?: listOf(MusicProjectionEffect()) .takeIf { it.isNotEmpty() } ?: listOf(MusicProjectionEffect())
val volume = 3.0f * projections.maxOf { it.volumeFactor } * note.volume val volume = projections.maxOf { it.volumeFactor } * note.volume
val particle = projections.any { it.particle } val particle = projections.any { it.particle }
val instrument = level.getBlockState(pos).getValue(BlockStateProperties.NOTEBLOCK_INSTRUMENT) val instrument = level.getBlockState(pos).getValue(BlockStateProperties.NOTEBLOCK_INSTRUMENT)
val pitch = if (instrument.isTunable) { val pitch = if (instrument.isTunable) {

View File

@@ -126,10 +126,10 @@ object SmartInstrumentBlock : Block(
|| CausalityAnchor.checkEffect(level, pos) || CausalityAnchor.checkEffect(level, pos)
) { ) {
val entity = level.getBlockEntity(pos) as SmartInstrumentBlockEntity val entity = level.getBlockEntity(pos) as SmartInstrumentBlockEntity
if (entity.player == null) { if (entity.player == null && !level.isClientSide) {
entity.startMusic() entity.startMusic()
} }
return InteractionResult.SUCCESS return InteractionResult.sidedSuccess(level.isClientSide)
} }
return super.use(state, level, pos, player, hand, hit) return super.use(state, level, pos, player, hand, hit)
} }

View File

@@ -60,7 +60,7 @@ class ProjectedPersonEntity(entityType: EntityType<out PathfinderMob>, level: Le
}!! }!!
init { init {
EntityAttributeRegistry.register(entity, ::createAttributes) Quaedam.lateinit += { EntityAttributeRegistry.register(entity, ::createAttributes) }
if (Platform.getEnv() == EnvType.CLIENT) ProjectedPersonRenderer if (Platform.getEnv() == EnvType.CLIENT) ProjectedPersonRenderer
ProjectedPersonShape ProjectedPersonShape
ProjectedPersonAI ProjectedPersonAI
@@ -177,7 +177,8 @@ class ProjectedPersonEntity(entityType: EntityType<out PathfinderMob>, level: Le
Projector.findNearbyProjections(level(), blockPosition(), SwarmProjection.effect.get()).isNotEmpty() Projector.findNearbyProjections(level(), blockPosition(), SwarmProjection.effect.get()).isNotEmpty()
override fun checkDespawn() { override fun checkDespawn() {
super.checkDespawn() // no despawn
// super.checkDespawn()
if (!checkProjectionEffect() && !CausalityAnchor.checkEffect(level(), blockPosition())) { if (!checkProjectionEffect() && !CausalityAnchor.checkEffect(level(), blockPosition())) {
dropEquipment() dropEquipment()
remove(RemovalReason.KILLED) remove(RemovalReason.KILLED)
@@ -237,24 +238,27 @@ class ProjectedPersonEntity(entityType: EntityType<out PathfinderMob>, level: Le
} }
fun findNearbySoundProjection() = fun findNearbySoundProjection() =
Projector.findNearbyProjections(level(), blockPosition(), SoundProjection.effect.get()).firstOrNull() Projector.findNearbyProjections(level(), blockPosition(), SoundProjection.effect.get())
override fun isSilent() = override fun isSilent() =
super.isSilent() && findNearbySoundProjection() != null super.isSilent() && findNearbySoundProjection().isEmpty()
override fun getAmbientSound(): SoundEvent? { override fun getAmbientSound(): SoundEvent? {
if (findNearbySoundProjection() != null) { if (findNearbySoundProjection().isNotEmpty()) {
// sound projection available // sound projection available
return soundNoise.get() return soundNoise.get()
} }
return null return null
} }
override fun getSoundVolume() = super.getSoundVolume() * (random.nextFloat() * 1.1f + 0.4f) override fun getSoundVolume() =
super.getSoundVolume() * (random.nextFloat() * 1.1f + 0.4f) *
findNearbySoundProjection().fold(1.0f) { v, p -> v * p.volume }
override fun getVoicePitch() = super.getVoicePitch() * (random.nextFloat() * 0.55f + 0.7f) override fun getVoicePitch() = super.getVoicePitch() * (random.nextFloat() * 0.55f + 0.7f)
override fun getAmbientSoundInterval() = 80 - random.nextInt((findNearbySoundProjection()?.rate ?: 1) * 5) override fun getAmbientSoundInterval() =
80 - random.nextInt((findNearbySoundProjection().firstOrNull()?.rate ?: 1) * 5)
override fun isEffectiveAi() = super.isEffectiveAi() && checkProjectionEffect() override fun isEffectiveAi() = super.isEffectiveAi() && checkProjectionEffect()

View File

@@ -10,6 +10,7 @@ import net.minecraft.client.renderer.entity.EntityRendererProvider
import net.minecraft.client.renderer.entity.MobRenderer import net.minecraft.client.renderer.entity.MobRenderer
import net.minecraft.client.renderer.entity.layers.CustomHeadLayer import net.minecraft.client.renderer.entity.layers.CustomHeadLayer
import net.minecraft.client.renderer.entity.layers.ItemInHandLayer import net.minecraft.client.renderer.entity.layers.ItemInHandLayer
import quaedam.Quaedam
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
class ProjectedPersonRenderer(context: EntityRendererProvider.Context) : class ProjectedPersonRenderer(context: EntityRendererProvider.Context) :
@@ -21,7 +22,12 @@ class ProjectedPersonRenderer(context: EntityRendererProvider.Context) :
companion object { companion object {
init { init {
EntityRendererRegistry.register(ProjectedPersonEntity.entity, ::ProjectedPersonRenderer) Quaedam.lateinit += {
EntityRendererRegistry.register(
ProjectedPersonEntity.entity,
::ProjectedPersonRenderer
)
}
} }
} }

View File

@@ -32,33 +32,37 @@ class ExchangeItem<E> : Behavior<E>(
entity.brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE) entity.brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE)
} }
override fun canStillUse(level: ServerLevel, entity: E, l: Long) = override fun canStillUse(level: ServerLevel, owner: E, gameTime: Long) =
entity.brain.getMemory(MemoryModuleType.WALK_TARGET).isPresent || entity.brain.getMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE).isEmpty || (closeAt != null && closeAt!! < l) owner.brain.getMemory(MemoryModuleType.WALK_TARGET).isPresent
|| owner.brain.getMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE).isEmpty
|| (closeAt != null && closeAt!! < gameTime)
override fun tick(level: ServerLevel, entity: E, l: Long) { override fun tick(level: ServerLevel, owner: E, gameTime: Long) {
if (closeAt == null) { if (closeAt == null) {
if (entity.brain.getMemory(MemoryModuleType.WALK_TARGET).isEmpty) { if (owner.brain.getMemory(MemoryModuleType.WALK_TARGET).isEmpty) {
// reached // reached
val chest = level.getBlockEntity(target!!) as BaseContainerBlockEntity val chest = level.getBlockEntity(target!!) ?: return
if (chest !is BaseContainerBlockEntity)
return
if (chest is ChestBlockEntity) { if (chest is ChestBlockEntity) {
ChestBlockEntity.playSound(level, target!!, level.getBlockState(target!!), SoundEvents.CHEST_OPEN) ChestBlockEntity.playSound(level, target!!, level.getBlockState(target!!), SoundEvents.CHEST_OPEN)
} }
if (chest.isEmpty) { if (chest.isEmpty && level.random.nextBoolean()) {
closeAt = l + 7 closeAt = gameTime + 7
} else { } else {
closeAt = l + 10 + level.random.nextInt(100) closeAt = gameTime + 10 + level.random.nextInt(100)
exchangeItems(level, entity) exchangeItems(level, owner)
} }
} }
} }
} }
override fun stop(level: ServerLevel, entity: E, l: Long) { override fun stop(level: ServerLevel, owner: E, gameTime: Long) {
entity.brain.eraseMemory(MemoryModuleType.WALK_TARGET) owner.brain.eraseMemory(MemoryModuleType.WALK_TARGET)
entity.brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE) owner.brain.eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE)
if (closeAt != null) { if (closeAt != null) {
// opened // opened
val chest = level.getBlockEntity(target!!)!! val chest = level.getBlockEntity(target!!) ?: return
if (chest is ChestBlockEntity) { if (chest is ChestBlockEntity) {
ChestBlockEntity.playSound(level, target!!, level.getBlockState(target!!), SoundEvents.CHEST_CLOSE) ChestBlockEntity.playSound(level, target!!, level.getBlockState(target!!), SoundEvents.CHEST_CLOSE)
} }
@@ -66,7 +70,9 @@ class ExchangeItem<E> : Behavior<E>(
} }
private fun exchangeItems(level: ServerLevel, entity: E) { private fun exchangeItems(level: ServerLevel, entity: E) {
val container = level.getBlockEntity(target!!) as Container val container = level.getBlockEntity(target!!) ?: return
if (container !is Container)
return
val inventory = entity.inventory val inventory = entity.inventory
for (i in 1..10) { for (i in 1..10) {
val maxCount = 1 + level.random.nextInt(16) val maxCount = 1 + level.random.nextInt(16)

View File

@@ -10,6 +10,7 @@ import net.minecraft.world.level.block.entity.BaseContainerBlockEntity
import quaedam.Quaedam import quaedam.Quaedam
import quaedam.utils.getChunksNearby import quaedam.utils.getChunksNearby
import java.util.* import java.util.*
import kotlin.random.Random
class NearestVisibleContainer : Sensor<LivingEntity>() { class NearestVisibleContainer : Sensor<LivingEntity>() {
@@ -33,7 +34,9 @@ class NearestVisibleContainer : Sensor<LivingEntity>() {
if (entity.tickCount and 0b11111 == 0) { // 32gt if (entity.tickCount and 0b11111 == 0) { // 32gt
val pos = level.getChunksNearby(entity.blockPosition(), 1) val pos = level.getChunksNearby(entity.blockPosition(), 1)
.flatMap { it.blockEntities.filterValues { be -> be is BaseContainerBlockEntity }.keys } .flatMap { it.blockEntities.filterValues { be -> be is BaseContainerBlockEntity }.keys }
.minByOrNull { it.distManhattan(entity.blockPosition()) } .sortedBy { it.distManhattan(entity.blockPosition()) / 5 }
.shuffled(Random(System.currentTimeMillis() / 10000))
.firstOrNull()
entity.brain.setMemory(memory.get(), pos) entity.brain.setMemory(memory.get(), pos)
} }
} }

View File

@@ -1,7 +1,6 @@
package quaedam.projection.swarm.ai package quaedam.projection.swarm.ai
import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableList
import net.minecraft.core.Holder
import net.minecraft.core.registries.Registries import net.minecraft.core.registries.Registries
import net.minecraft.tags.TagKey import net.minecraft.tags.TagKey
import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.LivingEntity
@@ -11,8 +10,6 @@ import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.memory.MemoryStatus import net.minecraft.world.entity.ai.memory.MemoryStatus
import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities
import net.minecraft.world.entity.ai.sensing.SensorType import net.minecraft.world.entity.ai.sensing.SensorType
import net.minecraft.world.entity.ai.village.poi.PoiType
import net.minecraft.world.entity.ai.village.poi.PoiTypes
import net.minecraft.world.entity.monster.Monster import net.minecraft.world.entity.monster.Monster
import net.minecraft.world.entity.schedule.Activity import net.minecraft.world.entity.schedule.Activity
import net.minecraft.world.entity.schedule.Schedule import net.minecraft.world.entity.schedule.Schedule
@@ -32,8 +29,8 @@ object ProjectedPersonAI {
val defaultSchedule = Quaedam.schedules.register("projected_person_default") { val defaultSchedule = Quaedam.schedules.register("projected_person_default") {
ScheduleBuilder(Schedule()).changeActivityAt(10, Activity.IDLE) ScheduleBuilder(Schedule()).changeActivityAt(10, Activity.IDLE)
.changeActivityAt(10, Activity.IDLE) .changeActivityAt(10, Activity.IDLE)
.changeActivityAt(2000, Activity.WORK) .changeActivityAt(900, Activity.WORK)
.changeActivityAt(7300, Activity.IDLE) .changeActivityAt(6300, Activity.IDLE)
.changeActivityAt(9000, Activity.WORK) .changeActivityAt(9000, Activity.WORK)
.changeActivityAt(10700, Activity.IDLE) .changeActivityAt(10700, Activity.IDLE)
.changeActivityAt(11000, Activity.PLAY) .changeActivityAt(11000, Activity.PLAY)
@@ -55,6 +52,7 @@ object ProjectedPersonAI {
init { init {
BedInChunkSensor BedInChunkSensor
AmusementAI AmusementAI
WorkPoiAI
NearestVisibleContainer NearestVisibleContainer
} }
@@ -71,6 +69,7 @@ object ProjectedPersonAI {
MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE,
MemoryModuleType.HOME, MemoryModuleType.HOME,
MemoryModuleType.LAST_WOKEN, MemoryModuleType.LAST_WOKEN,
MemoryModuleType.NEAREST_BED,
NearestVisibleContainer.memory.get(), NearestVisibleContainer.memory.get(),
) )
} }
@@ -158,7 +157,15 @@ object ProjectedPersonAI {
brain.addActivity( brain.addActivity(
Activity.WORK, ImmutableList.of( Activity.WORK, ImmutableList.of(
5 weight ExchangeItem(), 5 weight ExchangeItem(),
10 weight createStrollBehavior(), 7 weight WorkPoiAI.createStrollAroundPoi(),
7 weight WorkPoiAI.createStrollToPoi(),
10 weight RunOne(
mapOf(),
listOf(
1 weightR createStrollBehavior(),
1 weightR WorkPoiAI.createAcquirePoi(),
)
),
) )
) )
} }
@@ -182,7 +189,7 @@ object ProjectedPersonAI {
private fun createStrollBehavior() = RunOne( private fun createStrollBehavior() = RunOne(
listOf( listOf(
2 weightR RandomStroll.stroll(1.0f), 2 weightR RandomStroll.stroll(1.0f, 42, 12),
2 weightR SetWalkTargetFromLookTarget.create(1.0f, 5), 2 weightR SetWalkTargetFromLookTarget.create(1.0f, 5),
1 weightR DoNothing(30, 60) 1 weightR DoNothing(30, 60)
) )

View File

@@ -0,0 +1,49 @@
package quaedam.projection.swarm.ai
import net.minecraft.core.GlobalPos
import net.minecraft.world.entity.ai.behavior.AcquirePoi
import net.minecraft.world.entity.ai.behavior.StrollAroundPoi
import net.minecraft.world.entity.ai.behavior.StrollToPoi
import net.minecraft.world.entity.ai.memory.MemoryModuleType
import net.minecraft.world.entity.ai.village.poi.PoiTypes
import quaedam.Quaedam
import java.util.*
object WorkPoiAI {
const val ID = "work"
val poiTypes by lazy {
setOf(
PoiTypes.ARMORER,
PoiTypes.BUTCHER,
PoiTypes.CARTOGRAPHER,
PoiTypes.CLERIC,
PoiTypes.FARMER,
PoiTypes.FISHERMAN,
PoiTypes.FLETCHER,
PoiTypes.LEATHERWORKER,
PoiTypes.LIBRARIAN,
PoiTypes.MASON,
PoiTypes.SHEPHERD,
PoiTypes.TOOLSMITH,
PoiTypes.WEAPONSMITH,
PoiTypes.LODESTONE,
PoiTypes.LIGHTNING_ROD,
)
}
val memory = Quaedam.memoryTypes.register(ID) {
MemoryModuleType(Optional.of(GlobalPos.CODEC))
}!!
fun createAcquirePoi() =
AcquirePoi.create({ it.`is` { key -> key in poiTypes } }, memory.get(), false, Optional.empty())
fun createStrollToPoi() =
StrollToPoi.create(memory.get(), 0.4f, 7, 4)
fun createStrollAroundPoi() =
StrollAroundPoi.create(memory.get(), 0.4f, 5)
}

View File

@@ -34,7 +34,7 @@ object Projector {
fun findNearbyProjectors(level: Level, pos: BlockPos) = level.getChunksNearby(pos, currentEffectRadius) fun findNearbyProjectors(level: Level, pos: BlockPos) = level.getChunksNearby(pos, currentEffectRadius)
.flatMap { .flatMap {
it.blockEntities.filter { (_, v) -> v is ProjectorBlockEntity } it.blockEntities.filter { (_, v) -> v is ProjectorBlockEntity && pos in v }
.keys .keys
.filterNotNull() .filterNotNull()
} }

View File

@@ -1,6 +1,7 @@
package quaedam.projector package quaedam.projector
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.network.chat.Component
import net.minecraft.server.level.ServerLevel import net.minecraft.server.level.ServerLevel
import net.minecraft.util.RandomSource import net.minecraft.util.RandomSource
import net.minecraft.world.InteractionHand import net.minecraft.world.InteractionHand
@@ -15,6 +16,8 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.material.MapColor import net.minecraft.world.level.material.MapColor
import net.minecraft.world.level.material.PushReaction import net.minecraft.world.level.material.PushReaction
import net.minecraft.world.phys.BlockHitResult import net.minecraft.world.phys.BlockHitResult
import quaedam.shell.ProjectionShellItem
import quaedam.utils.sendBlockUpdated
object ProjectorBlock : Block(Properties.of() object ProjectorBlock : Block(Properties.of()
.jumpFactor(0.8f) .jumpFactor(0.8f)
@@ -41,6 +44,21 @@ object ProjectorBlock : Block(Properties.of()
interactionHand: InteractionHand, interactionHand: InteractionHand,
blockHitResult: BlockHitResult blockHitResult: BlockHitResult
): InteractionResult { ): InteractionResult {
if (player.getItemInHand(interactionHand).item == ProjectionShellItem) {
if (!level.isClientSide) {
val entity = level.getBlockEntity(blockPos) as ProjectorBlockEntity
var newRadius = entity.effectRadius + 1
if (newRadius > Projector.currentEffectRadius) {
newRadius = 0
}
entity.updateEffectArea(newRadius)
entity.setChanged()
entity.sendBlockUpdated()
checkUpdate(level, blockPos)
player.sendSystemMessage(Component.translatable("quaedam.projector.radius_updated", newRadius))
}
return InteractionResult.sidedSuccess(level.isClientSide)
}
checkUpdate(level, blockPos) checkUpdate(level, blockPos)
return InteractionResult.PASS return InteractionResult.PASS
} }

View File

@@ -1,6 +1,7 @@
package quaedam.projector package quaedam.projector
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.SectionPos
import net.minecraft.core.Vec3i import net.minecraft.core.Vec3i
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.network.protocol.Packet import net.minecraft.network.protocol.Packet
@@ -17,32 +18,23 @@ import quaedam.projection.ProjectionEffect
import quaedam.projection.ProjectionEffectType import quaedam.projection.ProjectionEffectType
import quaedam.projection.ProjectionProvider import quaedam.projection.ProjectionProvider
import quaedam.utils.sendBlockUpdated import quaedam.utils.sendBlockUpdated
import kotlin.math.max
import kotlin.math.min
class ProjectorBlockEntity(pos: BlockPos, state: BlockState) : class ProjectorBlockEntity(pos: BlockPos, state: BlockState) :
BlockEntity(Projector.blockEntity.get(), pos, state) { BlockEntity(Projector.blockEntity.get(), pos, state) {
companion object { companion object {
const val TAG_EFFECT_RADIUS = "EffectRadius"
const val TAG_PROJECTION_EFFECTS = "ProjectionEffects" const val TAG_PROJECTION_EFFECTS = "ProjectionEffects"
} }
val effectAreaChunk by lazy { var effectRadius: Int = 0
val chunk = level!!.getChunk(pos).pos lateinit var effectArea: BoundingBox
ChunkPos(chunk.x - Projector.currentEffectRadius, chunk.z - Projector.currentEffectRadius) to lateinit var effectAreaAABB: AABB
ChunkPos(chunk.x + Projector.currentEffectRadius, chunk.z + Projector.currentEffectRadius)
}
val effectArea: BoundingBox by lazy { init {
val (minChunk, maxChunk) = effectAreaChunk updateEffectArea(Projector.currentEffectRadius)
val minBlock = BlockPos(minChunk.minBlockX, level!!.minBuildHeight, minChunk.minBlockZ)
val maxBlock = BlockPos(maxChunk.maxBlockX, level!!.maxBuildHeight, maxChunk.maxBlockZ)
BoundingBox.fromCorners(minBlock, maxBlock)
}
val effectAreaAABB by lazy {
val (minChunk, maxChunk) = effectAreaChunk
val minBlock = BlockPos(minChunk.minBlockX, level!!.minBuildHeight, minChunk.minBlockZ)
val maxBlock = BlockPos(maxChunk.maxBlockX, level!!.maxBuildHeight, maxChunk.maxBlockZ)
AABB(minBlock, maxBlock)
} }
val checkArea: BoundingBox by lazy { val checkArea: BoundingBox by lazy {
@@ -57,11 +49,13 @@ class ProjectorBlockEntity(pos: BlockPos, state: BlockState) :
effects.map { (type, effect) -> effects.map { (type, effect) ->
effectsTag.put(type.id.toString(), effect.toNbt()) effectsTag.put(type.id.toString(), effect.toNbt())
} }
tag.putInt(TAG_EFFECT_RADIUS, effectRadius)
tag.put(TAG_PROJECTION_EFFECTS, effectsTag) tag.put(TAG_PROJECTION_EFFECTS, effectsTag)
} }
override fun load(tag: CompoundTag) { override fun load(tag: CompoundTag) {
super.load(tag) super.load(tag)
updateEffectArea(max(min(tag.getInt(TAG_EFFECT_RADIUS), Projector.currentEffectRadius), 0))
val effectsTag = tag[TAG_PROJECTION_EFFECTS] val effectsTag = tag[TAG_PROJECTION_EFFECTS]
val effects = mutableMapOf<ProjectionEffectType<*>, ProjectionEffect>() val effects = mutableMapOf<ProjectionEffectType<*>, ProjectionEffect>()
if (effectsTag != null && effectsTag is CompoundTag) { if (effectsTag != null && effectsTag is CompoundTag) {
@@ -76,6 +70,20 @@ class ProjectorBlockEntity(pos: BlockPos, state: BlockState) :
updateEffects(effects, notify = false) updateEffects(effects, notify = false)
} }
fun updateEffectArea(radius: Int) {
effectRadius = radius
val chunk = ChunkPos(SectionPos.blockToSectionCoord(blockPos.x), SectionPos.blockToSectionCoord(blockPos.z))
val minChunk = ChunkPos(chunk.x - radius, chunk.z - radius)
val maxChunk = ChunkPos(chunk.x + radius, chunk.z + radius)
// Y is not the limit value of Int because at
// Lnet/minecraft/world/level/entity/EntitySectionStorage;forEachAccessibleNonEmptySection(Lnet/minecraft/world/phys/AABB;Lnet/minecraft/util/AbortableIterationConsumer;)V
// it may get overflow
val minBlock = BlockPos(minChunk.minBlockX, Short.MIN_VALUE.toInt(), minChunk.minBlockZ)
val maxBlock = BlockPos(maxChunk.maxBlockX, Short.MAX_VALUE.toInt(), maxChunk.maxBlockZ)
effectArea = BoundingBox.fromCorners(minBlock, maxBlock)
effectAreaAABB = AABB(minBlock, maxBlock)
}
override fun getUpdateTag(): CompoundTag = saveWithoutMetadata() override fun getUpdateTag(): CompoundTag = saveWithoutMetadata()
override fun getUpdatePacket(): Packet<ClientGamePacketListener> = ClientboundBlockEntityDataPacket.create(this) override fun getUpdatePacket(): Packet<ClientGamePacketListener> = ClientboundBlockEntityDataPacket.create(this)

View File

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@@ -13,6 +13,7 @@
"item.quaedam.projection_shell": "Projection Shell", "item.quaedam.projection_shell": "Projection Shell",
"item.quaedam.iron_copper_metal": "Copper-iron Alloy", "item.quaedam.iron_copper_metal": "Copper-iron Alloy",
"item.quaedam.projection_metal": "Projection Metal", "item.quaedam.projection_metal": "Projection Metal",
"quaedam.projector.radius_updated": "Current effect radius: %s",
"quaedam.screen.projection_shell": "Projection Shell", "quaedam.screen.projection_shell": "Projection Shell",
"quaedam.screen.projection_shell.lock_revoked": "Timeout! Connection Lost", "quaedam.screen.projection_shell.lock_revoked": "Timeout! Connection Lost",
"quaedam.screen.projection_shell.lock_failed": "Permission denied!", "quaedam.screen.projection_shell.lock_failed": "Permission denied!",
@@ -22,8 +23,10 @@
"quaedam.shell.skylight.factor": "Factor", "quaedam.shell.skylight.factor": "Factor",
"quaedam.shell.noise.rate": "Rate", "quaedam.shell.noise.rate": "Rate",
"quaedam.shell.noise.amount": "Amount", "quaedam.shell.noise.amount": "Amount",
"quaedam.shell.noise.volume": "Volume",
"quaedam.shell.swarm.max_count": "Max Count", "quaedam.shell.swarm.max_count": "Max Count",
"quaedam.shell.sound.rate": "Rate", "quaedam.shell.sound.rate": "Rate",
"quaedam.shell.sound.volume": "Volume",
"quaedam.shell.music.volume_factor": "Volume Factor", "quaedam.shell.music.volume_factor": "Volume Factor",
"quaedam.shell.music.particle": "Particle", "quaedam.shell.music.particle": "Particle",
"quaedam.shell.music.particle.true": "Display", "quaedam.shell.music.particle.true": "Display",

View File

@@ -13,6 +13,7 @@
"item.quaedam.projection_shell": "投影操作面板", "item.quaedam.projection_shell": "投影操作面板",
"item.quaedam.iron_copper_metal": "铜铁合金", "item.quaedam.iron_copper_metal": "铜铁合金",
"item.quaedam.projection_metal": "投影金属", "item.quaedam.projection_metal": "投影金属",
"quaedam.projector.radius_updated": "当前效果半径:%s",
"quaedam.screen.projection_shell": "投影操作", "quaedam.screen.projection_shell": "投影操作",
"quaedam.screen.projection_shell.lock_revoked": "超时!连接丢失", "quaedam.screen.projection_shell.lock_revoked": "超时!连接丢失",
"quaedam.screen.projection_shell.lock_failed": "正被使用", "quaedam.screen.projection_shell.lock_failed": "正被使用",
@@ -22,8 +23,10 @@
"quaedam.shell.skylight.factor": "因子", "quaedam.shell.skylight.factor": "因子",
"quaedam.shell.noise.rate": "速率", "quaedam.shell.noise.rate": "速率",
"quaedam.shell.noise.amount": "数量", "quaedam.shell.noise.amount": "数量",
"quaedam.shell.noise.volume": "响度因子",
"quaedam.shell.swarm.max_count": "最大数量", "quaedam.shell.swarm.max_count": "最大数量",
"quaedam.shell.sound.rate": "速率", "quaedam.shell.sound.rate": "速率",
"quaedam.shell.sound.volume": "响度因子",
"quaedam.shell.music.volume_factor": "响度因子", "quaedam.shell.music.volume_factor": "响度因子",
"quaedam.shell.music.particle": "粒子效果", "quaedam.shell.music.particle": "粒子效果",
"quaedam.shell.music.particle.true": "显示", "quaedam.shell.music.particle.true": "显示",

View File

@@ -13,6 +13,7 @@
"item.quaedam.projection_shell": "投射滥权终端", "item.quaedam.projection_shell": "投射滥权终端",
"item.quaedam.iron_copper_metal": "有点生锈的铁锭", "item.quaedam.iron_copper_metal": "有点生锈的铁锭",
"item.quaedam.projection_metal": "投影Metal©", "item.quaedam.projection_metal": "投影Metal©",
"quaedam.projector.radius_updated": "现在乱七八糟的效果能碰到的范围:%s",
"quaedam.screen.projection_shell": "控制面板", "quaedam.screen.projection_shell": "控制面板",
"quaedam.screen.projection_shell.lock_revoked": "土豆熟了", "quaedam.screen.projection_shell.lock_revoked": "土豆熟了",
"quaedam.screen.projection_shell.lock_failed": "宁配吗?", "quaedam.screen.projection_shell.lock_failed": "宁配吗?",
@@ -22,8 +23,10 @@
"quaedam.shell.skylight.factor": "防晒系数", "quaedam.shell.skylight.factor": "防晒系数",
"quaedam.shell.noise.rate": "急急急等级", "quaedam.shell.noise.rate": "急急急等级",
"quaedam.shell.noise.amount": "声卡压榨等级", "quaedam.shell.noise.amount": "声卡压榨等级",
"quaedam.shell.noise.volume": "振幅大小",
"quaedam.shell.swarm.max_count": "显卡和处理器迫害等级", "quaedam.shell.swarm.max_count": "显卡和处理器迫害等级",
"quaedam.shell.sound.rate": "急急急等级", "quaedam.shell.sound.rate": "急急急等级",
"quaedam.shell.sound.volume": "振幅大小",
"quaedam.shell.music.volume_factor": "振幅大小", "quaedam.shell.music.volume_factor": "振幅大小",
"quaedam.shell.music.particle": "会变色的颗粒buff", "quaedam.shell.music.particle": "会变色的颗粒buff",
"quaedam.shell.music.particle.true": "打开", "quaedam.shell.music.particle.true": "打开",

82
fabric/build.gradle.kts Normal file
View File

@@ -0,0 +1,82 @@
plugins {
id("com.github.johnrengelman.shadow")
}
architectury {
platformSetupLoomIde()
fabric()
}
loom {
accessWidenerPath.set(project(":common").loom.accessWidenerPath)
}
val common: Configuration by configurations.creating
val shadowCommon: Configuration by configurations.creating
val developmentFabric: Configuration by configurations.getting
configurations {
compileOnly.configure { extendsFrom(common) }
runtimeOnly.configure { extendsFrom(common) }
developmentFabric.extendsFrom(common)
}
dependencies {
modImplementation("net.fabricmc:fabric-loader:${rootProject.property("fabric_loader_version")}")
modApi("net.fabricmc.fabric-api:fabric-api:${rootProject.property("fabric_version")}")
modApi("dev.architectury:architectury-fabric:${rootProject.property("architectury_version")}")
modImplementation("net.fabricmc:fabric-language-kotlin:${rootProject.property("fabric_kotlin_version")}")
common(project(":common", "namedElements")) {
isTransitive = false
}
shadowCommon(project(":common", "transformProductionFabric")){
isTransitive = false
}
}
tasks.processResources {
inputs.property("version", project.version)
filesMatching("fabric.mod.json") {
expand(
mapOf(
"version" to project.version,
"minecraft_version" to rootProject.property("minecraft_version"),
"architectury_version" to rootProject.property("architectury_version"),
"fabric_kotlin_version" to rootProject.property("fabric_kotlin_version")
)
)
}
}
tasks.shadowJar {
exclude("architectury.common.json")
configurations = listOf(shadowCommon)
archiveClassifier.set("dev-shadow")
}
tasks.remapJar {
injectAccessWidener.set(true)
inputFile.set(tasks.shadowJar.get().archiveFile)
dependsOn(tasks.shadowJar)
archiveClassifier.set(null as String?)
}
tasks.jar {
archiveClassifier.set("dev")
}
tasks.sourcesJar {
val commonSources = project(":common").tasks.getByName<Jar>("sourcesJar")
dependsOn(commonSources)
from(commonSources.archiveFile.map { zipTree(it) })
}
components.getByName("java") {
this as AdhocComponentWithVariants
this.withVariantsFromConfiguration(project.configurations["shadowRuntimeElements"]) {
skip()
}
}

View File

@@ -0,0 +1,12 @@
package quaedam.fabric
import net.fabricmc.api.ModInitializer
import quaedam.Quaedam
object QuaedamFabric: ModInitializer {
override fun onInitialize() {
Quaedam.init()
}
}

View File

@@ -0,0 +1,34 @@
{
"schemaVersion": 1,
"id": "quaedam",
"version": "${version}",
"name": "Quaedam",
"description": "Hot hot hot!",
"authors": [
"xtex"
],
"contact": {
"homepage": "https://codeberg.org/xtex/quaedam",
"sources": "https://codeberg.org/xtex/quaedam"
},
"license": "Apache-2.0",
"icon": "assets/quaedam/icon.png",
"environment": "*",
"entrypoints": {
"main": [
{
"adapter": "kotlin",
"value": "quaedam.fabric.QuaedamFabric"
}
]
},
"mixins": [
"quaedam-common.mixins.json"
],
"depends": {
"fabric": "*",
"minecraft": ">=${minecraft_version}",
"architectury": ">=${architectury_version}",
"fabric-language-kotlin": ">=${fabric_kotlin_version}"
}
}

View File

@@ -0,0 +1,13 @@
{
"required": true,
"package": "quaedam.fabric.mixin",
"compatibilityLevel": "JAVA_17",
"minVersion": "0.8",
"client": [
],
"mixins": [
],
"injectors": {
"defaultRequire": 1
}
}

View File

@@ -11,7 +11,7 @@ authors = "xtex"
description = ''' description = '''
Hot hot hot! Hot hot hot!
''' '''
logoFile = "icon.png" logoFile = "assets/quaedam/icon.png"
[[dependencies.quaedam]] [[dependencies.quaedam]]
modId = "forge" modId = "forge"

View File

@@ -1,13 +1,27 @@
org.gradle.parallel=true org.gradle.parallel=true
org.gradle.caching=true org.gradle.caching=true
org.gradle.jvmargs=-Xmx2048M org.gradle.jvmargs=-Xmx2048M
minecraft_version=1.20.1 minecraft_version=1.20.1
parchment_version=2023.07.16 parchment_version=2023.07.30
# https://www.curseforge.com/minecraft/mc-mods/architectury-api # https://modrinth.com/mod/architectury-api
architectury_version=9.1.12 architectury_version=9.1.12
# https://files.minecraftforge.net/net/minecraftforge/forge/ # https://files.minecraftforge.net/net/minecraftforge/forge/
forge_version=1.20.1-47.1.43 forge_version=1.20.1-47.1.43
# https://www.curseforge.com/minecraft/mc-mods/kotlin-for-forge/files # https://modrinth.com/mod/kotlin-for-forge
kotlin_for_forge_version=4.4.0 kotlin_for_forge_version=4.4.0
# https://fabricmc.net/develop/ # https://fabricmc.net/develop/
fabric_loader_version=0.14.21 fabric_loader_version=0.14.21
fabric_version=0.86.1+1.20.1
# https://modrinth.com/mod/fabric-language-kotlin
fabric_kotlin_version=1.10.8+kotlin.1.9.0
# https://github.com/QuiltMC/quilt-loader/tags
quilt_loader_version=0.20.0-beta.5
# https://modrinth.com/mod/qsl
quilt_fabric_version=7.0.3+0.83.1-1.20.1
quilt_standard_library_version=6.0.4+1.20.1
# https://modrinth.com/mod/qkl
quilt_kotlin_libraries_version=2.1.1+kt.1.9.0+flk.1.9.6

86
quilt/build.gradle.kts Normal file
View File

@@ -0,0 +1,86 @@
plugins {
id("com.github.johnrengelman.shadow")
}
architectury {
platformSetupLoomIde()
loader("quilt")
}
loom {
accessWidenerPath.set(project(":common").loom.accessWidenerPath)
}
val common: Configuration by configurations.creating
val shadowCommon: Configuration by configurations.creating
val developmentQuilt: Configuration by configurations.getting
configurations {
compileOnly.configure { extendsFrom(common) }
runtimeOnly.configure { extendsFrom(common) }
developmentQuilt.extendsFrom(common)
}
dependencies {
modImplementation("org.quiltmc:quilt-loader:${rootProject.property("quilt_loader_version")}")
modApi("org.quiltmc.quilted-fabric-api:quilted-fabric-api:${rootProject.property("quilt_fabric_version")}")
modApi("dev.architectury:architectury-fabric:${rootProject.property("architectury_version")}") {
exclude("net.fabricmc")
exclude("net.fabricmc.fabric-api")
}
modApi("org.quiltmc:qsl:${rootProject.property("quilt_standard_library_version")}")
modApi("org.quiltmc.quilt-kotlin-libraries:quilt-kotlin-libraries:${rootProject.property("quilt_kotlin_libraries_version")}")
common(project(":common", "namedElements")) {
isTransitive = false
}
shadowCommon(project(":common", "transformProductionQuilt")) {
isTransitive = false
}
}
tasks.processResources {
inputs.property("version", project.version)
filesMatching("quilt.mod.json") {
expand(
mapOf(
"version" to project.version,
"minecraft_version" to rootProject.property("minecraft_version"),
"architectury_version" to rootProject.property("architectury_version"),
"quilt_kotlin_libraries_version" to rootProject.property("quilt_kotlin_libraries_version"),
)
)
}
}
tasks.shadowJar {
exclude("architectury.common.json")
configurations = listOf(shadowCommon)
archiveClassifier.set("dev-shadow")
}
tasks.remapJar {
injectAccessWidener.set(true)
inputFile.set(tasks.shadowJar.get().archiveFile)
dependsOn(tasks.shadowJar)
archiveClassifier.set(null as String?)
}
tasks.jar {
archiveClassifier.set("dev")
}
tasks.sourcesJar {
val commonSources = project(":common").tasks.getByName<Jar>("sourcesJar")
dependsOn(commonSources)
from(commonSources.archiveFile.map { zipTree(it) })
}
components.getByName("java") {
this as AdhocComponentWithVariants
this.withVariantsFromConfiguration(project.configurations["shadowRuntimeElements"]) {
skip()
}
}

1
quilt/gradle.properties Normal file
View File

@@ -0,0 +1 @@
loom.platform=quilt

View File

@@ -0,0 +1,12 @@
package quaedam.quilt
import net.fabricmc.api.ModInitializer
import quaedam.Quaedam
object QuaedamQuilt: ModInitializer {
override fun onInitialize() {
Quaedam.init()
}
}

View File

@@ -0,0 +1,13 @@
{
"required": true,
"package": "quaedam.fabric.mixin",
"compatibilityLevel": "JAVA_17",
"minVersion": "0.8",
"client": [
],
"mixins": [
],
"injectors": {
"defaultRequire": 1
}
}

View File

@@ -0,0 +1,59 @@
{
"_comment": "https://github.com/QuiltMC/rfcs/blob/main/specification/0002-quilt.mod.json.md",
"schema_version": 1,
"mixin": [
"quaedam-common.mixins.json"
],
"quilt_loader": {
"metadata": {
"name": "Quaedam",
"description": "Hot hot hot!",
"license": "Apache-2.0",
"authors": [
"xtex"
],
"contact": {
"homepage": "https://codeberg.org/xtex/quaedam",
"sources": "https://codeberg.org/xtex/quaedam"
},
"icon": "assets/quaedam/icon.png"
},
"group": "quaedam",
"id": "quaedam",
"version": "${version}",
"intermediate_mappings": "net.fabricmc:intermediary",
"entrypoints": {
"init": [
{
"adapter": "kotlin",
"value": "quaedam.quilt.QuaedamQuilt"
}
]
},
"depends": [
{
"id": "quilt_loader",
"version": "*"
},
{
"id": "quilt_base",
"version": "*"
},
{
"id": "minecraft",
"version": ">=${minecraft_version}"
},
{
"id": "architectury",
"version": ">=${architectury_version}"
},
{
"id": "qkl",
"version": ">=${quilt_kotlin_libraries_version}"
}
]
},
"minecraft": {
"environment": "*"
}
}

View File

@@ -10,5 +10,6 @@ pluginManagement {
include("common") include("common")
include("forge") include("forge")
include("fabric", "quilt")
rootProject.name = "quaedam" rootProject.name = "quaedam"