Mod now compiles on 1.20.2
This commit is contained in:
parent
1f4292012b
commit
c32a5bf71b
@ -142,7 +142,6 @@ dependencies {
|
||||
|
||||
if (handleDeps) {
|
||||
val jei_version: String by project
|
||||
val mekanism_version: String by project
|
||||
val cosmetic_armor_reworked_id: String by project
|
||||
val jade_id: String by project
|
||||
val configured_id: String by project
|
||||
@ -174,7 +173,7 @@ dependencies {
|
||||
// runtimeOnly(fg.deobf("curse.maven:worldedit-225608:${worldedit_fileid}"))
|
||||
// runtimeOnly(fg.deobf("at.ridgo8.moreoverlays:MoreOverlays-updated:${more_overlays_version}"))
|
||||
|
||||
compileOnly(fg.deobf("mekanism:Mekanism:${mekanism_version}:all"))
|
||||
compileOnly(fg.deobf("mekanism:Mekanism:1.20.1-10.3.9.homebaked:all"))
|
||||
|
||||
// runtimeOnly(fg.deobf("curse.maven:cyclops-core-232758:4392602"))
|
||||
// runtimeOnly(fg.deobf("curse.maven:integrated-dynamics-236307:4391535"))
|
||||
@ -395,21 +394,3 @@ if (project.hasProperty("mavenUser") && project.hasProperty("mavenPassword") &&
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing
|
||||
// publish.dependsOn("reobfJar")
|
||||
|
||||
/*
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
artifact jar
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
maven {
|
||||
url "file://${project.projectDir}/mcmodsrepo"
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -6,12 +6,11 @@ kotlin.stdlib.default.dependency=false
|
||||
org.gradle.vfs.watch=true
|
||||
|
||||
mod_id=overdrive_that_matters
|
||||
mod_version=1.3
|
||||
mod_version=1.4
|
||||
|
||||
use_commit_hash_in_version=true
|
||||
|
||||
mc_version=1.20.2
|
||||
use_parchment=false
|
||||
jei_mc_version=1.20.2
|
||||
curios_mc_version=1.20
|
||||
|
||||
@ -22,7 +21,6 @@ mixin_version=0.8.5
|
||||
|
||||
jei_version=16.0.0.28
|
||||
jupiter_version=5.9.2
|
||||
mekanism_version=1.20.1-10.3.9.homebaked
|
||||
curios_version=5.2.0-beta.2
|
||||
cosmetic_armor_reworked_id=4575609
|
||||
ad_astra_id=4594155
|
||||
|
@ -508,8 +508,8 @@ object DataGen {
|
||||
val tagsProvider = TagsProvider(event)
|
||||
val advancementProvider = object : ForgeAdvancementProvider(event.generator.packOutput, event.lookupProvider, event.existingFileHelper, listOf(
|
||||
AdvancementGenerator { registries, saver, existingFileHelper ->
|
||||
addAdvancements(saver, existingFileHelper, languageProvider)
|
||||
addAndroidAdvancements(saver, existingFileHelper, languageProvider)
|
||||
addAdvancements(saver, languageProvider)
|
||||
addAndroidAdvancements(saver, languageProvider)
|
||||
}
|
||||
)) {}
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
package ru.dbotthepony.mc.otm.datagen.advancements
|
||||
|
||||
import net.minecraft.advancements.Advancement
|
||||
import net.minecraft.advancements.AdvancementHolder
|
||||
import net.minecraft.advancements.AdvancementRequirements
|
||||
import net.minecraft.advancements.AdvancementRewards
|
||||
import net.minecraft.advancements.FrameType
|
||||
import net.minecraft.advancements.RequirementsStrategy
|
||||
import net.minecraft.advancements.AdvancementRequirements.Strategy
|
||||
import net.minecraft.advancements.critereon.InventoryChangeTrigger
|
||||
import net.minecraft.world.item.DyeColor
|
||||
import net.minecraft.world.item.ItemStack
|
||||
@ -18,11 +20,11 @@ import ru.dbotthepony.mc.otm.triggers.BlackHoleTrigger
|
||||
import ru.dbotthepony.mc.otm.triggers.NailedEntityTrigger
|
||||
import java.util.function.Consumer
|
||||
|
||||
fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: ExistingFileHelper, lang: MatteryLanguageProvider) {
|
||||
fun addAdvancements(serializer: Consumer<AdvancementHolder>, lang: MatteryLanguageProvider) {
|
||||
val translation = lang.MultiBuilder("otm.advancements.regular")
|
||||
|
||||
val root = AdvancementBuilder()
|
||||
.requirements(RequirementsStrategy.OR)
|
||||
.requirements(Strategy.OR)
|
||||
.display(
|
||||
itemStack = ItemStack(MItems.TRITANIUM_INGOT),
|
||||
title = translation.add("root", "Overdrive That Matters"),
|
||||
@ -36,9 +38,9 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
.addCriterion("has_tritanium_ore", criterion(MItemTags.TRITANIUM_ORES))
|
||||
.addCriterion("has_tritanium_ore_clump", criterion(MItemTags.TRITANIUM_ORE_CLUMPS))
|
||||
.addCriterion("has_tritanium_ingot", InventoryChangeTrigger.TriggerInstance.hasItems(MItems.TRITANIUM_INGOT))
|
||||
.save(serializer, modLocation("regular/root"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/root"))
|
||||
|
||||
addMachineAdvancements(serializer, existingFileHelper, lang, root)
|
||||
addMachineAdvancements(serializer, lang, root)
|
||||
|
||||
val crude = AdvancementBuilder()
|
||||
.parent(root)
|
||||
@ -52,7 +54,7 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
},
|
||||
)
|
||||
.addCriterion("has_item", criterion(MItems.BATTERY_CRUDE))
|
||||
.save(serializer, modLocation("regular/crude_battery"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/crude_battery"))
|
||||
|
||||
val normal = AdvancementBuilder()
|
||||
.parent(crude)
|
||||
@ -66,7 +68,7 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
},
|
||||
)
|
||||
.addCriterion("has_item", criterion(MItems.BATTERY_NORMAL))
|
||||
.save(serializer, modLocation("regular/normal_battery"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/normal_battery"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(normal)
|
||||
@ -80,7 +82,7 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
},
|
||||
)
|
||||
.addCriterion("has_item", criterion(MItems.BATTERY_DENSE))
|
||||
.save(serializer, modLocation("regular/dense_battery"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/dense_battery"))
|
||||
|
||||
val capacitor = AdvancementBuilder()
|
||||
.parent(normal)
|
||||
@ -94,7 +96,7 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
},
|
||||
)
|
||||
.addCriterion("has_item", criterion(MItems.BATTERY_CAPACITOR))
|
||||
.save(serializer, modLocation("regular/capacitor_battery"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/capacitor_battery"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(capacitor)
|
||||
@ -109,7 +111,7 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
frameType = FrameType.GOAL
|
||||
)
|
||||
.addCriterion("has_item", criterion(MItems.ENERGY_SWORD))
|
||||
.save(serializer, modLocation("regular/energy_sword"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/energy_sword"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(normal)
|
||||
@ -124,10 +126,10 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
frameType = FrameType.GOAL
|
||||
)
|
||||
.rewards(AdvancementRewards.Builder.experience(50))
|
||||
.requirements(RequirementsStrategy.OR)
|
||||
.requirements(Strategy.OR)
|
||||
.addCriterion("has_item0", criterion(MItems.QUANTUM_BATTERY))
|
||||
.addCriterion("has_item1", criterion(MItems.QUANTUM_CAPACITOR))
|
||||
.save(serializer, modLocation("regular/quantum_battery"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/quantum_battery"))
|
||||
|
||||
val zpm = AdvancementBuilder()
|
||||
.parent(root)
|
||||
@ -144,9 +146,9 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
)
|
||||
.rewards(AdvancementRewards.Builder.experience(800))
|
||||
.addCriterion("has_item", criterion(MItems.ZPM_BATTERY))
|
||||
.save(serializer, modLocation("regular/zpm_battery"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/zpm_battery"))
|
||||
|
||||
addExopackAdvancements(serializer, existingFileHelper, lang, root, zpm)
|
||||
addExopackAdvancements(serializer, lang, root, zpm)
|
||||
|
||||
val blackhole = AdvancementBuilder()
|
||||
.parent(root)
|
||||
@ -160,8 +162,8 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
},
|
||||
hidden = true
|
||||
)
|
||||
.addCriterion("pulled_by_black_hole", BlackHoleTrigger.instance)
|
||||
.save(serializer, modLocation("regular/black_hole"), existingFileHelper)
|
||||
.addCriterion("pulled_by_black_hole", BlackHoleTrigger.criterion)
|
||||
.save(serializer, modLocation("regular/black_hole"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(blackhole)
|
||||
@ -175,7 +177,7 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
},
|
||||
)
|
||||
.addCriterion("has_item", criterion(MItems.BLACK_HOLE_SCANNER))
|
||||
.save(serializer, modLocation("regular/black_hole_scanner"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/black_hole_scanner"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(blackhole)
|
||||
@ -189,7 +191,7 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
},
|
||||
)
|
||||
.addCriterion("has_item", criterion(MItems.GRAVITATION_STABILIZER))
|
||||
.save(serializer, modLocation("regular/stabilizer"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/stabilizer"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(blackhole)
|
||||
@ -203,11 +205,11 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
},
|
||||
)
|
||||
.addCriterion("has_item", criterion(MItems.PORTABLE_GRAVITATION_STABILIZER))
|
||||
.save(serializer, modLocation("regular/portable_stabilizer"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/portable_stabilizer"))
|
||||
|
||||
val ore = AdvancementBuilder()
|
||||
.parent(root)
|
||||
.requirements(RequirementsStrategy.OR)
|
||||
.requirements(Strategy.OR)
|
||||
.display(
|
||||
itemStack = ItemStack(MItems.TRITANIUM_ORE_CLUMP),
|
||||
title = translation.add("ore", "Blue Metal Discovery") {
|
||||
@ -219,7 +221,7 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
)
|
||||
.addCriterion("has_tritanium_ore", criterion(MItemTags.TRITANIUM_ORES))
|
||||
.addCriterion("has_tritanium_ore_clump", criterion(MItemTags.TRITANIUM_ORE_CLUMPS))
|
||||
.save(serializer, modLocation("regular/ore"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/ore"))
|
||||
|
||||
val ingot = AdvancementBuilder()
|
||||
.parent(ore)
|
||||
@ -233,7 +235,7 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
},
|
||||
)
|
||||
.addCriterion("has_tritanium_ingot", criterion(MItemTags.TRITANIUM_INGOTS))
|
||||
.save(serializer, modLocation("regular/ingot"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/ingot"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(ingot)
|
||||
@ -247,7 +249,7 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
},
|
||||
)
|
||||
.addCriterion("has_tritanium_pickaxe", criterion(MItems.TRITANIUM_PICKAXE))
|
||||
.save(serializer, modLocation("regular/pickaxe"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/pickaxe"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(ingot)
|
||||
@ -262,7 +264,7 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
hidden = true
|
||||
)
|
||||
.addCriterion("hoe", criterion(MItems.TRITANIUM_HOE))
|
||||
.save(serializer, modLocation("regular/hoe"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/hoe"))
|
||||
|
||||
val plate = AdvancementBuilder()
|
||||
.parent(ingot)
|
||||
@ -276,7 +278,7 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
}
|
||||
)
|
||||
.addCriterion("has_item", criterion(MItemTags.TRITANIUM_PLATES))
|
||||
.save(serializer, modLocation("regular/plate"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/plate"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(plate)
|
||||
@ -289,12 +291,12 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
russian("Согните немного тритановых пластин вместе с углеродной сеткой в невероятно прочную броню")
|
||||
}
|
||||
)
|
||||
.requirements(RequirementsStrategy.OR)
|
||||
.requirements(Strategy.OR)
|
||||
.addCriterion("has_item0", criterion(MItems.TRITANIUM_HELMET))
|
||||
.addCriterion("has_item1", criterion(MItems.TRITANIUM_CHESTPLATE))
|
||||
.addCriterion("has_item2", criterion(MItems.TRITANIUM_PANTS))
|
||||
.addCriterion("has_item3", criterion(MItems.TRITANIUM_BOOTS))
|
||||
.save(serializer, modLocation("regular/armor"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/armor"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(ingot)
|
||||
@ -307,12 +309,12 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
russian("Создайте простую тритановую броню из слитков, просто и эффективно")
|
||||
}
|
||||
)
|
||||
.requirements(RequirementsStrategy.OR)
|
||||
.requirements(Strategy.OR)
|
||||
.addCriterion("has_item0", criterion(MItems.SIMPLE_TRITANIUM_HELMET))
|
||||
.addCriterion("has_item1", criterion(MItems.SIMPLE_TRITANIUM_CHESTPLATE))
|
||||
.addCriterion("has_item2", criterion(MItems.SIMPLE_TRITANIUM_PANTS))
|
||||
.addCriterion("has_item3", criterion(MItems.SIMPLE_TRITANIUM_BOOTS))
|
||||
.save(serializer, modLocation("regular/simple_armor"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/simple_armor"))
|
||||
|
||||
val glass = AdvancementBuilder()
|
||||
.parent(plate)
|
||||
@ -325,11 +327,11 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
russian("В инструкции указано что оно должно быть пуленепробиваемо.")
|
||||
}
|
||||
)
|
||||
.requirements(RequirementsStrategy.OR)
|
||||
.requirements(Strategy.OR)
|
||||
.also { advancement ->
|
||||
MRegistry.INDUSTRIAL_GLASS.allItems.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
}
|
||||
.save(serializer, modLocation("regular/industrial_glass"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/industrial_glass"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(glass)
|
||||
@ -343,11 +345,11 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
},
|
||||
frameType = FrameType.GOAL
|
||||
)
|
||||
.requirements(RequirementsStrategy.AND)
|
||||
.requirements(Strategy.AND)
|
||||
.also { advancement ->
|
||||
MRegistry.INDUSTRIAL_GLASS.allItems.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
}
|
||||
.save(serializer, modLocation("regular/industrial_glass2"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/industrial_glass2"))
|
||||
|
||||
val cargoCrate = AdvancementBuilder()
|
||||
.parent(plate)
|
||||
@ -360,11 +362,11 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
russian("Грузовые ящики, будто двойные сундуки, но одинарные.")
|
||||
}
|
||||
)
|
||||
.requirements(RequirementsStrategy.OR)
|
||||
.requirements(Strategy.OR)
|
||||
.also { advancement ->
|
||||
MRegistry.CARGO_CRATES.allItems.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
}
|
||||
.save(serializer, modLocation("regular/cargo_crate"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/cargo_crate"))
|
||||
|
||||
val cargoCrateInMinecart = AdvancementBuilder()
|
||||
.parent(cargoCrate)
|
||||
@ -377,11 +379,11 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
russian("Сбросьте грузовой ящик в вагонетку и посмотрите, что получится")
|
||||
}
|
||||
)
|
||||
.requirements(RequirementsStrategy.OR)
|
||||
.requirements(Strategy.OR)
|
||||
.also { advancement ->
|
||||
MItems.CARGO_CRATE_MINECARTS.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
}
|
||||
.save(serializer, modLocation("regular/cargo_crate_minecart"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/cargo_crate_minecart"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(cargoCrateInMinecart)
|
||||
@ -395,11 +397,11 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
},
|
||||
frameType = FrameType.GOAL
|
||||
)
|
||||
.requirements(RequirementsStrategy.AND)
|
||||
.requirements(Strategy.AND)
|
||||
.also { advancement ->
|
||||
MItems.CARGO_CRATE_MINECARTS.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
}
|
||||
.save(serializer, modLocation("regular/cargo_crate_minecart2"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/cargo_crate_minecart2"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(cargoCrate)
|
||||
@ -413,11 +415,11 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
},
|
||||
frameType = FrameType.GOAL
|
||||
)
|
||||
.requirements(RequirementsStrategy.AND)
|
||||
.requirements(Strategy.AND)
|
||||
.also { advancement ->
|
||||
MRegistry.CARGO_CRATES.allItems.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
}
|
||||
.save(serializer, modLocation("regular/cargo_crate2"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/cargo_crate2"))
|
||||
|
||||
val tritaniumBlock = AdvancementBuilder()
|
||||
.parent(ingot)
|
||||
@ -430,7 +432,7 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
russian("Покройте булыжник в тритане, дешёвый, но невероятно прочный материал")
|
||||
}
|
||||
)
|
||||
.requirements(RequirementsStrategy.OR)
|
||||
.requirements(Strategy.OR)
|
||||
.also { advancement ->
|
||||
MRegistry.TRITANIUM_BLOCK.allItems.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
MRegistry.TRITANIUM_STRIPED_BLOCK.flatItems.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
@ -439,7 +441,7 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
MItems.TRITANIUM_STRIPED_BLOCK.also { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
MItems.TRITANIUM_STRIPED_STAIRS.also { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
}
|
||||
.save(serializer, modLocation("regular/tritanium_block"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/tritanium_block"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(tritaniumBlock)
|
||||
@ -452,12 +454,12 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
russian("Бледно синяя покраска с жёлтой полоской, я готов поспорить вы знаете чей это дизайн")
|
||||
}
|
||||
)
|
||||
.requirements(RequirementsStrategy.OR)
|
||||
.requirements(Strategy.OR)
|
||||
.addCriterion("has_item", criterion(MItems.TRITANIUM_STRIPED_BLOCK))
|
||||
.addCriterion("has_item1", criterion(MItems.TRITANIUM_STRIPED_STAIRS))
|
||||
.addCriterion("has_item2", criterion(MItems.TRITANIUM_STRIPED_SLAB))
|
||||
.addCriterion("has_item3", criterion(MItems.TRITANIUM_STRIPED_WALL))
|
||||
.save(serializer, modLocation("regular/striped_tritanium_block"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/striped_tritanium_block"))
|
||||
|
||||
val colorTritaniumBlock = AdvancementBuilder()
|
||||
.parent(tritaniumBlock)
|
||||
@ -470,7 +472,7 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
russian("Покрасьте тритановый блок для придания ему сказочных оттенков")
|
||||
}
|
||||
)
|
||||
.requirements(RequirementsStrategy.OR)
|
||||
.requirements(Strategy.OR)
|
||||
.also { advancement ->
|
||||
MRegistry.TRITANIUM_BLOCK.items.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
MRegistry.TRITANIUM_STAIRS.items.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
@ -479,7 +481,7 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
MItems.TRITANIUM_STRIPED_BLOCK.also { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
MItems.TRITANIUM_STRIPED_STAIRS.also { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
}
|
||||
.save(serializer, modLocation("regular/tritanium_block2"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/tritanium_block2"))
|
||||
|
||||
val colorfulTritaniumBlock = AdvancementBuilder()
|
||||
.parent(colorTritaniumBlock)
|
||||
@ -494,11 +496,11 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
frameType = FrameType.GOAL
|
||||
)
|
||||
.rewards(AdvancementRewards.Builder.loot(modLocation("tritanium_block3")).addExperience(100))
|
||||
.requirements(RequirementsStrategy.AND)
|
||||
.requirements(Strategy.AND)
|
||||
.also { advancement ->
|
||||
MRegistry.TRITANIUM_BLOCK.items.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
}
|
||||
.save(serializer, modLocation("regular/tritanium_block3"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/tritanium_block3"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(colorfulTritaniumBlock)
|
||||
@ -513,13 +515,13 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
frameType = FrameType.CHALLENGE
|
||||
)
|
||||
.rewards(AdvancementRewards.Builder.loot(modLocation("tritanium_block4")).addExperience(400))
|
||||
.requirements(RequirementsStrategy.AND)
|
||||
.requirements(Strategy.AND)
|
||||
.also { advancement ->
|
||||
MRegistry.TRITANIUM_BLOCK.items.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
MRegistry.TRITANIUM_STRIPED_BLOCK.flatItems.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
MItems.TRITANIUM_STRIPED_BLOCK.also { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
|
||||
}
|
||||
.save(serializer, modLocation("regular/tritanium_block4"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/tritanium_block4"))
|
||||
|
||||
val pill = AdvancementBuilder()
|
||||
.parent(root)
|
||||
@ -532,12 +534,12 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
russian("Найдите одну из этих ваших мистических пилюль")
|
||||
},
|
||||
)
|
||||
.requirements(RequirementsStrategy.OR)
|
||||
.requirements(Strategy.OR)
|
||||
.addCriterion("pill1", criterion(MItems.PILL_ANDROID))
|
||||
.addCriterion("pill2", criterion(MItems.PILL_HEAL))
|
||||
.addCriterion("pill3", criterion(MItems.PILL_HUMANE))
|
||||
.addCriterion("pill4", criterion(MItems.PILL_OBLIVION))
|
||||
.save(serializer, modLocation("regular/pill"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/pill"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(pill)
|
||||
@ -553,12 +555,12 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
hidden = true
|
||||
)
|
||||
.rewards(AdvancementRewards.Builder.experience(200))
|
||||
.requirements(RequirementsStrategy.AND)
|
||||
.requirements(Strategy.AND)
|
||||
.addCriterion("pill1", criterion(MItems.PILL_ANDROID))
|
||||
.addCriterion("pill2", criterion(MItems.PILL_HEAL))
|
||||
.addCriterion("pill3", criterion(MItems.PILL_HUMANE))
|
||||
.addCriterion("pill4", criterion(MItems.PILL_OBLIVION))
|
||||
.save(serializer, modLocation("regular/all_pills"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/all_pills"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(root)
|
||||
@ -571,10 +573,10 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
russian("Верните капсулу эссенции. Воспоминания...")
|
||||
},
|
||||
)
|
||||
.requirements(RequirementsStrategy.OR)
|
||||
.requirements(Strategy.OR)
|
||||
.addCriterion("essence1", criterion(MItems.ESSENCE_CAPSULE))
|
||||
.addCriterion("essence2", criterion(MItems.ESSENCE_DRIVE))
|
||||
.save(serializer, modLocation("regular/essence_capsule"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/essence_capsule"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(root)
|
||||
@ -587,6 +589,6 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
|
||||
russian("Пригвоздите что-либо (или кого-либо)")
|
||||
}
|
||||
)
|
||||
.addCriterion("damage", NailedEntityTrigger.Instance())
|
||||
.save(serializer, modLocation("regular/explosive_hammer"), existingFileHelper)
|
||||
.addCriterion("damage", NailedEntityTrigger.Instance().criterion())
|
||||
.save(serializer, modLocation("regular/explosive_hammer"))
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
package ru.dbotthepony.mc.otm.datagen.advancements
|
||||
|
||||
import net.minecraft.advancements.Advancement
|
||||
import net.minecraft.advancements.AdvancementHolder
|
||||
import net.minecraft.advancements.AdvancementRequirements.Strategy
|
||||
import net.minecraft.advancements.AdvancementRewards
|
||||
import net.minecraft.advancements.FrameType
|
||||
import net.minecraft.advancements.RequirementsStrategy
|
||||
import net.minecraft.advancements.critereon.EntityPredicate
|
||||
import net.minecraft.advancements.critereon.ItemPredicate
|
||||
import net.minecraft.advancements.critereon.MinMaxBounds.Doubles
|
||||
@ -30,9 +31,10 @@ import ru.dbotthepony.mc.otm.triggers.KillAsAndroidTrigger
|
||||
import ru.dbotthepony.mc.otm.triggers.NanobotsArmorTrigger
|
||||
import ru.dbotthepony.mc.otm.triggers.ShockwaveDamageMobTrigger
|
||||
import ru.dbotthepony.mc.otm.triggers.ShockwaveTrigger
|
||||
import java.util.*
|
||||
import java.util.function.Consumer
|
||||
|
||||
fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper: ExistingFileHelper, lang: MatteryLanguageProvider) {
|
||||
fun addAndroidAdvancements(serializer: Consumer<AdvancementHolder>, lang: MatteryLanguageProvider) {
|
||||
val translation = lang.MultiBuilder("otm.advancements.android")
|
||||
|
||||
val root = AdvancementBuilder()
|
||||
@ -48,8 +50,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
announceChat = false,
|
||||
background = modLocation("textures/block/decorative/metal_beam_top.png")
|
||||
)
|
||||
.addCriterion("became_android", BecomeAndroidTrigger.instance)
|
||||
.save(serializer, modLocation("android/root"), existingFileHelper)
|
||||
.addCriterion("became_android", BecomeAndroidTrigger.criterion)
|
||||
.save(serializer, modLocation("android/root"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(root)
|
||||
@ -64,8 +66,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
hidden = true,
|
||||
frameType = FrameType.CHALLENGE
|
||||
)
|
||||
.addCriterion("item", AndroidBatteryTrigger.Instance(ItemPredicate.Builder.item().of(MItems.ZPM_BATTERY).build()))
|
||||
.save(serializer, modLocation("android/zpm"), existingFileHelper)
|
||||
.addCriterion("item", AndroidBatteryTrigger.Instance(ItemPredicate.Builder.item().of(MItems.ZPM_BATTERY).build()).criterion())
|
||||
.save(serializer, modLocation("android/zpm"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(root)
|
||||
@ -80,10 +82,10 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
hidden = true,
|
||||
frameType = FrameType.GOAL
|
||||
)
|
||||
.requirements(RequirementsStrategy.OR)
|
||||
.addCriterion("item0", AndroidBatteryTrigger.Instance(ItemPredicate.Builder.item().of(MItems.QUANTUM_BATTERY).build()))
|
||||
.addCriterion("item1", AndroidBatteryTrigger.Instance(ItemPredicate.Builder.item().of(MItems.QUANTUM_CAPACITOR).build()))
|
||||
.save(serializer, modLocation("android/quantum_battery"), existingFileHelper)
|
||||
.requirements(Strategy.OR)
|
||||
.addCriterion("item0", AndroidBatteryTrigger.Instance(ItemPredicate.Builder.item().of(MItems.QUANTUM_BATTERY).build()).criterion())
|
||||
.addCriterion("item1", AndroidBatteryTrigger.Instance(ItemPredicate.Builder.item().of(MItems.QUANTUM_CAPACITOR).build()).criterion())
|
||||
.save(serializer, modLocation("android/quantum_battery"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(root)
|
||||
@ -97,8 +99,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
hidden = true,
|
||||
)
|
||||
.addCriterion("became_android", BecomeAndroidSleepTrigger.instance)
|
||||
.save(serializer, modLocation("android/become_thru_sleep"), existingFileHelper)
|
||||
.addCriterion("became_android", BecomeAndroidSleepTrigger.criterion)
|
||||
.save(serializer, modLocation("android/become_thru_sleep"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(root)
|
||||
@ -112,8 +114,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
hidden = true,
|
||||
)
|
||||
.addCriterion("became_android", BecomeAndroidDeathTrigger.instance)
|
||||
.save(serializer, modLocation("android/become_thru_death"), existingFileHelper)
|
||||
.addCriterion("became_android", BecomeAndroidDeathTrigger.criterion)
|
||||
.save(serializer, modLocation("android/become_thru_death"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(root)
|
||||
@ -128,8 +130,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
hidden = true,
|
||||
frameType = FrameType.GOAL
|
||||
)
|
||||
.addCriterion("become_humane", BecomeHumaneTrigger.instance)
|
||||
.save(serializer, modLocation("android/become_humane"), existingFileHelper)
|
||||
.addCriterion("become_humane", BecomeHumaneTrigger.criterion)
|
||||
.save(serializer, modLocation("android/become_humane"))
|
||||
|
||||
val attractor = AdvancementBuilder()
|
||||
.parent(root)
|
||||
@ -143,7 +145,7 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
)
|
||||
.addCriterion("has_item", criterion(MItems.PHANTOM_ATTRACTOR))
|
||||
.save(serializer, modLocation("regular/phantom_attractor"), existingFileHelper)
|
||||
.save(serializer, modLocation("regular/phantom_attractor"))
|
||||
|
||||
val researchAnything = AdvancementBuilder()
|
||||
.parent(root)
|
||||
@ -156,8 +158,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
russian("Исследуйте что либо за андроида")
|
||||
},
|
||||
)
|
||||
.addCriterion("research_anything", AndroidResearchTrigger.Instance(null))
|
||||
.save(serializer, modLocation("android/research_anything"), existingFileHelper)
|
||||
.addCriterion("research_anything", AndroidResearchTrigger.Instance(null).criterion())
|
||||
.save(serializer, modLocation("android/research_anything"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(researchAnything)
|
||||
@ -170,8 +172,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
russian("Исследуйте воздушные мешки, дабы быть вновь поплавком в воде")
|
||||
},
|
||||
)
|
||||
.addCriterion("air_bags", AndroidResearchTrigger.Instance(modLocation(MNames.AIR_BAGS)))
|
||||
.save(serializer, modLocation("android/research_air_bags"), existingFileHelper)
|
||||
.addCriterion("air_bags", AndroidResearchTrigger.Instance(modLocation(MNames.AIR_BAGS)).criterion())
|
||||
.save(serializer, modLocation("android/research_air_bags"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(researchAnything)
|
||||
@ -184,8 +186,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
russian("Исследуйте ночное зрение за андроида, дабы видеть во темноте")
|
||||
},
|
||||
)
|
||||
.addCriterion("night_vision", AndroidResearchTrigger.Instance(modLocation(MNames.NIGHT_VISION)))
|
||||
.save(serializer, modLocation("android/research_night_vision"), existingFileHelper)
|
||||
.addCriterion("night_vision", AndroidResearchTrigger.Instance(modLocation(MNames.NIGHT_VISION)).criterion())
|
||||
.save(serializer, modLocation("android/research_night_vision"))
|
||||
|
||||
val nanobots = AdvancementBuilder()
|
||||
.parent(researchAnything)
|
||||
@ -199,8 +201,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
hidden = true
|
||||
)
|
||||
.addCriterion("nanobots", AndroidResearchTrigger.Instance(modLocation(MNames.NANOBOTS)))
|
||||
.save(serializer, modLocation("android/research_nanobots"), existingFileHelper)
|
||||
.addCriterion("nanobots", AndroidResearchTrigger.Instance(modLocation(MNames.NANOBOTS)).criterion())
|
||||
.save(serializer, modLocation("android/research_nanobots"))
|
||||
|
||||
val shielding = AdvancementBuilder()
|
||||
.parent(nanobots)
|
||||
@ -215,8 +217,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
hidden = true,
|
||||
frameType = FrameType.GOAL
|
||||
)
|
||||
.addCriterion("damage", NanobotsArmorTrigger.Instance(Doubles.atLeast(10.0)))
|
||||
.save(serializer, modLocation("android/nanobots_armor_deflect"), existingFileHelper)
|
||||
.addCriterion("damage", NanobotsArmorTrigger.Instance(Doubles.atLeast(10.0)).criterion())
|
||||
.save(serializer, modLocation("android/nanobots_armor_deflect"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(shielding)
|
||||
@ -231,8 +233,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
hidden = true,
|
||||
frameType = FrameType.CHALLENGE
|
||||
)
|
||||
.addCriterion("damage", NanobotsArmorTrigger.Instance(Doubles.atLeast(20.0)))
|
||||
.save(serializer, modLocation("android/nanobots_armor_deflect2"), existingFileHelper)
|
||||
.addCriterion("damage", NanobotsArmorTrigger.Instance(Doubles.atLeast(20.0)).criterion())
|
||||
.save(serializer, modLocation("android/nanobots_armor_deflect2"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(researchAnything)
|
||||
@ -246,8 +248,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
frameType = FrameType.GOAL
|
||||
)
|
||||
.addCriterion("saved", FallDampenersSaveTrigger.instance)
|
||||
.save(serializer, modLocation("android/fall_dampeners_save"), existingFileHelper)
|
||||
.addCriterion("saved", FallDampenersSaveTrigger.criterion)
|
||||
.save(serializer, modLocation("android/fall_dampeners_save"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(researchAnything)
|
||||
@ -262,8 +264,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
frameType = FrameType.GOAL,
|
||||
hidden = true
|
||||
)
|
||||
.addCriterion("death", EnderTeleporterFallDeathTrigger.instance)
|
||||
.save(serializer, modLocation("android/ender_teleport_fall_death"), existingFileHelper)
|
||||
.addCriterion("death", EnderTeleporterFallDeathTrigger.criterion)
|
||||
.save(serializer, modLocation("android/ender_teleport_fall_death"))
|
||||
|
||||
val regen = AdvancementBuilder()
|
||||
.parent(nanobots)
|
||||
@ -276,8 +278,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
russian("Исследуйте регенерацию наноботов за андроида")
|
||||
},
|
||||
)
|
||||
.addCriterion("regen0", AndroidResearchTrigger.Instance(modLocation(MNames.NANOBOTS_REGENERATION_1)))
|
||||
.save(serializer, modLocation("android/regen"), existingFileHelper)
|
||||
.addCriterion("regen0", AndroidResearchTrigger.Instance(modLocation(MNames.NANOBOTS_REGENERATION_1)).criterion())
|
||||
.save(serializer, modLocation("android/regen"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(regen)
|
||||
@ -291,11 +293,11 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
frameType = FrameType.GOAL,
|
||||
)
|
||||
.addCriterion("regen0", AndroidResearchTrigger.Instance(modLocation(MNames.NANOBOTS_REGENERATION_1)))
|
||||
.addCriterion("regen1", AndroidResearchTrigger.Instance(modLocation(MNames.NANOBOTS_REGENERATION_2)))
|
||||
.addCriterion("regen2", AndroidResearchTrigger.Instance(modLocation(MNames.NANOBOTS_REGENERATION_3)))
|
||||
.addCriterion("regen3", AndroidResearchTrigger.Instance(modLocation(MNames.NANOBOTS_REGENERATION_4)))
|
||||
.save(serializer, modLocation("android/regen_all"), existingFileHelper)
|
||||
.addCriterion("regen0", AndroidResearchTrigger.Instance(modLocation(MNames.NANOBOTS_REGENERATION_1)).criterion())
|
||||
.addCriterion("regen1", AndroidResearchTrigger.Instance(modLocation(MNames.NANOBOTS_REGENERATION_2)).criterion())
|
||||
.addCriterion("regen2", AndroidResearchTrigger.Instance(modLocation(MNames.NANOBOTS_REGENERATION_3)).criterion())
|
||||
.addCriterion("regen3", AndroidResearchTrigger.Instance(modLocation(MNames.NANOBOTS_REGENERATION_4)).criterion())
|
||||
.save(serializer, modLocation("android/regen_all"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(researchAnything)
|
||||
@ -314,10 +316,10 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
DataGen.researchProvider.generatedView.stream()
|
||||
.filter { it.allBlockedBy.isEmpty() && it.allBlocking.isEmpty() }
|
||||
.forEach {
|
||||
advancement.addCriterion(it.id.toString(), AndroidResearchTrigger.Instance(it))
|
||||
advancement.addCriterion(it.id.toString(), AndroidResearchTrigger.Instance(it).criterion())
|
||||
}
|
||||
}
|
||||
.save(serializer, modLocation("android/research_everything"), existingFileHelper)
|
||||
.save(serializer, modLocation("android/research_everything"))
|
||||
|
||||
val shockwave = AdvancementBuilder()
|
||||
.parent(researchAnything)
|
||||
@ -330,8 +332,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
russian("Вызовите ударную волну при приземлении")
|
||||
},
|
||||
)
|
||||
.addCriterion("shockwave", ShockwaveTrigger.instance)
|
||||
.save(serializer, modLocation("android/shockwave"), existingFileHelper)
|
||||
.addCriterion("shockwave", ShockwaveTrigger.criterion)
|
||||
.save(serializer, modLocation("android/shockwave"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(shockwave)
|
||||
@ -345,8 +347,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
frameType = FrameType.GOAL
|
||||
)
|
||||
.addCriterion("shockwave_warden", ShockwaveDamageMobTrigger.Instance(EntityPredicate.Builder.entity().of(EntityType.WARDEN).build().wrap()))
|
||||
.save(serializer, modLocation("android/shockwave_warden"), existingFileHelper)
|
||||
.addCriterion("shockwave_warden", ShockwaveDamageMobTrigger.Instance(Optional.of(EntityPredicate.Builder.entity().of(EntityType.WARDEN).build().wrap())).criterion())
|
||||
.save(serializer, modLocation("android/shockwave_warden"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(root)
|
||||
@ -362,9 +364,9 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
hidden = true
|
||||
)
|
||||
.addCriterion("kill_wither", KillAsAndroidTrigger.Instance(
|
||||
predicate = EntityPredicate.Builder.entity().of(EntityType.WITHER).build().wrap(),
|
||||
))
|
||||
.save(serializer, modLocation("android/wither"), existingFileHelper)
|
||||
predicate = Optional.of(EntityPredicate.Builder.entity().of(EntityType.WITHER).build().wrap()),
|
||||
).criterion())
|
||||
.save(serializer, modLocation("android/wither"))
|
||||
|
||||
val underwater = AdvancementBuilder()
|
||||
.parent(root)
|
||||
@ -379,8 +381,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
frameType = FrameType.GOAL,
|
||||
hidden = true
|
||||
)
|
||||
.addCriterion("travel", AndroidTravelUnderwater.Instance(200.0))
|
||||
.save(serializer, modLocation("android/underwater"), existingFileHelper)
|
||||
.addCriterion("travel", AndroidTravelUnderwater.Instance(200.0).criterion())
|
||||
.save(serializer, modLocation("android/underwater"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(underwater)
|
||||
@ -395,8 +397,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
frameType = FrameType.CHALLENGE,
|
||||
hidden = true
|
||||
)
|
||||
.addCriterion("travel", AndroidTravelUnderwater.Instance(1046.0))
|
||||
.save(serializer, modLocation("android/underwater2"), existingFileHelper)
|
||||
.addCriterion("travel", AndroidTravelUnderwater.Instance(1046.0).criterion())
|
||||
.save(serializer, modLocation("android/underwater2"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(root)
|
||||
@ -412,8 +414,8 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
hidden = true
|
||||
)
|
||||
.addCriterion("kill_elder_guardian", KillAsAndroidTrigger.Instance(
|
||||
predicate = EntityPredicate.Builder.entity().of(EntityType.ELDER_GUARDIAN).build().wrap(),
|
||||
predicate = Optional.of(EntityPredicate.Builder.entity().of(EntityType.ELDER_GUARDIAN).build().wrap()),
|
||||
featurePredicate = KillAsAndroidTrigger.Not(KillAsAndroidTrigger.Has(AndroidFeatures.AIR_BAGS.registryName!!))
|
||||
))
|
||||
.save(serializer, modLocation("android/elder_guardian"), existingFileHelper)
|
||||
).criterion())
|
||||
.save(serializer, modLocation("android/elder_guardian"))
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package ru.dbotthepony.mc.otm.datagen.advancements
|
||||
|
||||
import net.minecraft.advancements.Advancement
|
||||
import net.minecraft.advancements.AdvancementHolder
|
||||
import net.minecraft.advancements.FrameType
|
||||
import net.minecraft.advancements.critereon.ItemPredicate
|
||||
import net.minecraft.world.item.ItemStack
|
||||
@ -17,7 +18,7 @@ import ru.dbotthepony.mc.otm.triggers.ExopackObtainedTrigger
|
||||
import ru.dbotthepony.mc.otm.triggers.ExopackSlotsExpandedTrigger
|
||||
import java.util.function.Consumer
|
||||
|
||||
fun addExopackAdvancements(serializer: Consumer<Advancement>, existingFileHelper: ExistingFileHelper, lang: MatteryLanguageProvider, root: Advancement, zpm: Advancement) {
|
||||
fun addExopackAdvancements(serializer: Consumer<AdvancementHolder>, lang: MatteryLanguageProvider, root: AdvancementHolder, zpm: AdvancementHolder) {
|
||||
val translation = lang.MultiBuilder("otm.advancements.exopack")
|
||||
|
||||
AdvancementBuilder()
|
||||
@ -33,8 +34,8 @@ fun addExopackAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
frameType = FrameType.GOAL
|
||||
)
|
||||
.addCriterion("zpm_battery", ExopackBatterySlotTrigger.Instance(ItemPredicate.Builder.item().of(MItems.ZPM_BATTERY).build()))
|
||||
.save(serializer, modLocation("exopack/zpm_battery"), existingFileHelper)
|
||||
.addCriterion("zpm_battery", ExopackBatterySlotTrigger.Instance(ItemPredicate.Builder.item().of(MItems.ZPM_BATTERY).build()).criterion())
|
||||
.save(serializer, modLocation("exopack/zpm_battery"))
|
||||
|
||||
val obtained = AdvancementBuilder()
|
||||
.parent(root)
|
||||
@ -48,8 +49,8 @@ fun addExopackAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
frameType = FrameType.GOAL
|
||||
)
|
||||
.addCriterion("obtained", ExopackObtainedTrigger.instance)
|
||||
.save(serializer, modLocation("exopack/obtained"), existingFileHelper)
|
||||
.addCriterion("obtained", ExopackObtainedTrigger.criterion)
|
||||
.save(serializer, modLocation("exopack/obtained"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(obtained)
|
||||
@ -62,8 +63,8 @@ fun addExopackAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
russian("Установите улучшение сетки крафта в ваш Экзопаке, который позволяет создавать предметы, требующие сетку крафта рабочего стола")
|
||||
},
|
||||
)
|
||||
.addCriterion("crafting", ExopackGainedCraftingTrigger.instance)
|
||||
.save(serializer, modLocation("exopack/crafting"), existingFileHelper)
|
||||
.addCriterion("crafting", ExopackGainedCraftingTrigger.criterion)
|
||||
.save(serializer, modLocation("exopack/crafting"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(obtained)
|
||||
@ -76,8 +77,8 @@ fun addExopackAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
russian("Установите модуль переплавки в ваш Экзопак, позволяющий переплавлять предметы прямо у вас в инвентаре")
|
||||
},
|
||||
)
|
||||
.addCriterion("smelting", ExopackGainedSmeltingTrigger.instance)
|
||||
.save(serializer, modLocation("exopack/smelting"), existingFileHelper)
|
||||
.addCriterion("smelting", ExopackGainedSmeltingTrigger.criterion)
|
||||
.save(serializer, modLocation("exopack/smelting"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(obtained)
|
||||
@ -90,8 +91,8 @@ fun addExopackAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
russian("Получите прямой доступ к содержимому вашего сундука края прямо из Экзопака")
|
||||
},
|
||||
)
|
||||
.addCriterion("ender_access", ExopackGainedEnderAccessTrigger.instance)
|
||||
.save(serializer, modLocation("ender_access/smelting"), existingFileHelper)
|
||||
.addCriterion("ender_access", ExopackGainedEnderAccessTrigger.criterion)
|
||||
.save(serializer, modLocation("ender_access/smelting"))
|
||||
|
||||
var size = AdvancementBuilder()
|
||||
.parent(obtained)
|
||||
@ -104,8 +105,8 @@ fun addExopackAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
russian("Улучшите размер инвентаря Экзопака")
|
||||
},
|
||||
)
|
||||
.addCriterion("size0", ExopackSlotsExpandedTrigger.Instance(minTotal = 1))
|
||||
.save(serializer, modLocation("exopack/size0"), existingFileHelper)
|
||||
.addCriterion("size0", ExopackSlotsExpandedTrigger.Instance(minTotal = 1).criterion())
|
||||
.save(serializer, modLocation("exopack/size0"))
|
||||
|
||||
val size0 = size
|
||||
|
||||
@ -120,8 +121,8 @@ fun addExopackAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
russian("Достигните 27 слотов хранилища Экзопака")
|
||||
},
|
||||
)
|
||||
.addCriterion("size1", ExopackSlotsExpandedTrigger.Instance(minTotal = 27))
|
||||
.save(serializer, modLocation("exopack/size1"), existingFileHelper)
|
||||
.addCriterion("size1", ExopackSlotsExpandedTrigger.Instance(minTotal = 27).criterion())
|
||||
.save(serializer, modLocation("exopack/size1"))
|
||||
|
||||
size = AdvancementBuilder()
|
||||
.parent(size)
|
||||
@ -135,8 +136,8 @@ fun addExopackAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
russian("Достигните 54 слотов хранилища Экзопака")
|
||||
},
|
||||
)
|
||||
.addCriterion("size2", ExopackSlotsExpandedTrigger.Instance(minTotal = 54))
|
||||
.save(serializer, modLocation("exopack/size2"), existingFileHelper)
|
||||
.addCriterion("size2", ExopackSlotsExpandedTrigger.Instance(minTotal = 54).criterion())
|
||||
.save(serializer, modLocation("exopack/size2"))
|
||||
|
||||
size = AdvancementBuilder()
|
||||
.parent(size)
|
||||
@ -151,8 +152,8 @@ fun addExopackAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
frameType = FrameType.GOAL
|
||||
)
|
||||
.addCriterion("size3", ExopackSlotsExpandedTrigger.Instance(minTotal = 108))
|
||||
.save(serializer, modLocation("exopack/size3"), existingFileHelper)
|
||||
.addCriterion("size3", ExopackSlotsExpandedTrigger.Instance(minTotal = 108).criterion())
|
||||
.save(serializer, modLocation("exopack/size3"))
|
||||
|
||||
size = AdvancementBuilder()
|
||||
.parent(size)
|
||||
@ -167,8 +168,8 @@ fun addExopackAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
frameType = FrameType.CHALLENGE
|
||||
)
|
||||
.addCriterion("size4", ExopackSlotsExpandedTrigger.Instance(minTotal = 432))
|
||||
.save(serializer, modLocation("exopack/size4"), existingFileHelper)
|
||||
.addCriterion("size4", ExopackSlotsExpandedTrigger.Instance(minTotal = 432).criterion())
|
||||
.save(serializer, modLocation("exopack/size4"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(size)
|
||||
@ -183,8 +184,8 @@ fun addExopackAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
frameType = FrameType.CHALLENGE
|
||||
)
|
||||
.addCriterion("size5", ExopackSlotsExpandedTrigger.Instance(minTotal = 1728))
|
||||
.save(serializer, modLocation("exopack/size5"), existingFileHelper)
|
||||
.addCriterion("size5", ExopackSlotsExpandedTrigger.Instance(minTotal = 1728).criterion())
|
||||
.save(serializer, modLocation("exopack/size5"))
|
||||
|
||||
var once = AdvancementBuilder()
|
||||
.parent(size0)
|
||||
@ -197,8 +198,8 @@ fun addExopackAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
russian("Улучшите хранилище Экзопака модулем на 9 слотов")
|
||||
},
|
||||
)
|
||||
.addCriterion("once0", ExopackSlotsExpandedTrigger.Instance(minGained = 9))
|
||||
.save(serializer, modLocation("exopack/once0"), existingFileHelper)
|
||||
.addCriterion("once0", ExopackSlotsExpandedTrigger.Instance(minGained = 9).criterion())
|
||||
.save(serializer, modLocation("exopack/once0"))
|
||||
|
||||
once = AdvancementBuilder()
|
||||
.parent(once)
|
||||
@ -211,8 +212,8 @@ fun addExopackAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
russian("Улучшите хранилище Экзопака модулем на 27 слотов")
|
||||
},
|
||||
)
|
||||
.addCriterion("once1", ExopackSlotsExpandedTrigger.Instance(minGained = 27))
|
||||
.save(serializer, modLocation("exopack/once1"), existingFileHelper)
|
||||
.addCriterion("once1", ExopackSlotsExpandedTrigger.Instance(minGained = 27).criterion())
|
||||
.save(serializer, modLocation("exopack/once1"))
|
||||
|
||||
once = AdvancementBuilder()
|
||||
.parent(once)
|
||||
@ -227,8 +228,8 @@ fun addExopackAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
frameType = FrameType.GOAL
|
||||
)
|
||||
.addCriterion("once2", ExopackSlotsExpandedTrigger.Instance(minGained = 54))
|
||||
.save(serializer, modLocation("exopack/once2"), existingFileHelper)
|
||||
.addCriterion("once2", ExopackSlotsExpandedTrigger.Instance(minGained = 54).criterion())
|
||||
.save(serializer, modLocation("exopack/once2"))
|
||||
|
||||
once = AdvancementBuilder()
|
||||
.parent(once)
|
||||
@ -243,8 +244,8 @@ fun addExopackAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
frameType = FrameType.GOAL
|
||||
)
|
||||
.addCriterion("once3", ExopackSlotsExpandedTrigger.Instance(minGained = 90))
|
||||
.save(serializer, modLocation("exopack/once3"), existingFileHelper)
|
||||
.addCriterion("once3", ExopackSlotsExpandedTrigger.Instance(minGained = 90).criterion())
|
||||
.save(serializer, modLocation("exopack/once3"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(once)
|
||||
@ -259,6 +260,6 @@ fun addExopackAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
frameType = FrameType.CHALLENGE
|
||||
)
|
||||
.addCriterion("once4", ExopackSlotsExpandedTrigger.Instance(minGained = 150))
|
||||
.save(serializer, modLocation("exopack/once4"), existingFileHelper)
|
||||
.addCriterion("once4", ExopackSlotsExpandedTrigger.Instance(minGained = 150).criterion())
|
||||
.save(serializer, modLocation("exopack/once4"))
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package ru.dbotthepony.mc.otm.datagen.advancements
|
||||
|
||||
import net.minecraft.advancements.Advancement
|
||||
import net.minecraft.advancements.Criterion
|
||||
import net.minecraft.advancements.CriterionTriggerInstance
|
||||
import net.minecraft.advancements.DisplayInfo
|
||||
import net.minecraft.advancements.FrameType
|
||||
@ -57,7 +58,7 @@ fun predicate(tag: TagKey<Item>): ItemPredicate {
|
||||
return ItemPredicate.Builder.item().of(tag).build()
|
||||
}
|
||||
|
||||
fun criterion(tag: TagKey<Item>): CriterionTriggerInstance {
|
||||
fun criterion(tag: TagKey<Item>): Criterion<*> {
|
||||
return InventoryChangeTrigger.TriggerInstance.hasItems(predicate(tag))
|
||||
}
|
||||
|
||||
@ -65,7 +66,7 @@ fun predicate(item: ItemLike): ItemPredicate {
|
||||
return ItemPredicate.Builder.item().of(item).build()
|
||||
}
|
||||
|
||||
fun criterion(item: ItemLike): CriterionTriggerInstance {
|
||||
fun criterion(item: ItemLike): Criterion<*> {
|
||||
return InventoryChangeTrigger.TriggerInstance.hasItems(predicate(item))
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,16 @@
|
||||
package ru.dbotthepony.mc.otm.datagen.advancements
|
||||
|
||||
import net.minecraft.advancements.Advancement
|
||||
import net.minecraft.advancements.AdvancementHolder
|
||||
import net.minecraft.advancements.FrameType
|
||||
import net.minecraft.advancements.RequirementsStrategy
|
||||
import net.minecraft.advancements.critereon.ItemPredicate
|
||||
import net.minecraft.network.chat.contents.TranslatableContents
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Items
|
||||
import net.minecraftforge.common.data.ExistingFileHelper
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.core.key
|
||||
import ru.dbotthepony.mc.otm.core.registryName
|
||||
import ru.dbotthepony.mc.otm.datagen.lang.MatteryLanguageProvider
|
||||
import ru.dbotthepony.mc.otm.datagen.modLocation
|
||||
import ru.dbotthepony.mc.otm.registry.MItemTags
|
||||
import ru.dbotthepony.mc.otm.registry.MItems
|
||||
import ru.dbotthepony.mc.otm.triggers.TakeItemOutOfReplicatorTrigger
|
||||
import java.util.function.Consumer
|
||||
@ -27,7 +23,7 @@ private data class CraftEntry(
|
||||
val russianName: String? = null,
|
||||
val russianSuffix: String? = null,
|
||||
) {
|
||||
fun make(serializer: Consumer<Advancement>, existingFileHelper: ExistingFileHelper, parent: Advancement, translation: MatteryLanguageProvider.MultiBuilder): Advancement {
|
||||
fun make(serializer: Consumer<AdvancementHolder>, parent: AdvancementHolder, translation: MatteryLanguageProvider.MultiBuilder): AdvancementHolder {
|
||||
val path = item.registryName!!.path
|
||||
|
||||
val translated = translation.add("$path.desc", "Craft a %s%s") {
|
||||
@ -50,11 +46,11 @@ private data class CraftEntry(
|
||||
description = TranslatableComponent(translated.contents.key, item.description, translatedSuffix),
|
||||
)
|
||||
.addCriterion("has_machine", criterion(item))
|
||||
.save(serializer, modLocation("machines/$path"), existingFileHelper)
|
||||
.save(serializer, modLocation("machines/$path"))
|
||||
}
|
||||
}
|
||||
|
||||
fun addMachineAdvancements(serializer: Consumer<Advancement>, existingFileHelper: ExistingFileHelper, lang: MatteryLanguageProvider, root: Advancement) {
|
||||
fun addMachineAdvancements(serializer: Consumer<AdvancementHolder>, lang: MatteryLanguageProvider, root: AdvancementHolder) {
|
||||
val translation = lang.MultiBuilder("otm.advancements.machine")
|
||||
|
||||
val chem = AdvancementBuilder()
|
||||
@ -69,7 +65,7 @@ fun addMachineAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
)
|
||||
.addCriterion("has_machine", criterion(MItems.CHEMICAL_GENERATOR))
|
||||
.save(serializer, modLocation("machines/chemical_generator"), existingFileHelper)
|
||||
.save(serializer, modLocation("machines/chemical_generator"))
|
||||
|
||||
val press = AdvancementBuilder()
|
||||
.parent(chem)
|
||||
@ -83,10 +79,10 @@ fun addMachineAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
)
|
||||
.addCriterion("has_machine", criterion(MItems.PLATE_PRESS))
|
||||
.save(serializer, modLocation("machines/plate_press"), existingFileHelper)
|
||||
.save(serializer, modLocation("machines/plate_press"))
|
||||
|
||||
CraftEntry(MItems.TWIN_PLATE_PRESS, "Twice the Thud",
|
||||
russianName = "Двойной стук").make(serializer, existingFileHelper, press, translation)
|
||||
russianName = "Двойной стук").make(serializer, press, translation)
|
||||
|
||||
val scanner = CraftEntry(MItems.MATTER_SCANNER, "Scanning Things that Matter",
|
||||
russianName = "Сканируем вещи которые материальны")
|
||||
@ -114,12 +110,12 @@ fun addMachineAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
val reconstructor = CraftEntry(MItems.MATTER_RECONSTRUCTOR, "Flipping Hourglass",
|
||||
russianName = "Переворачиваем песочные часы")
|
||||
|
||||
decomposer.make(serializer, existingFileHelper, press, translation).also {
|
||||
pattern.make(serializer, existingFileHelper, it, translation).also {
|
||||
scanner.make(serializer, existingFileHelper, it, translation)
|
||||
panel.make(serializer, existingFileHelper, it, translation)
|
||||
decomposer.make(serializer, press, translation).also {
|
||||
pattern.make(serializer, it, translation).also {
|
||||
scanner.make(serializer, it, translation)
|
||||
panel.make(serializer, it, translation)
|
||||
|
||||
replicator.make(serializer, existingFileHelper, it, translation).also {
|
||||
replicator.make(serializer, it, translation).also {
|
||||
AdvancementBuilder()
|
||||
.parent(it)
|
||||
.display(
|
||||
@ -132,8 +128,8 @@ fun addMachineAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
},
|
||||
frameType = FrameType.GOAL
|
||||
)
|
||||
.addCriterion("replicate_something", TakeItemOutOfReplicatorTrigger.Instance(ItemPredicate.Builder.item().of(MItems.MATTER_DUST).build(), true))
|
||||
.save(serializer, modLocation("machines/replicate_something"), existingFileHelper)
|
||||
.addCriterion("replicate_something", TakeItemOutOfReplicatorTrigger.Instance(ItemPredicate.Builder.item().of(MItems.MATTER_DUST).build(), true).criterion())
|
||||
.save(serializer, modLocation("machines/replicate_something"))
|
||||
|
||||
AdvancementBuilder()
|
||||
.parent(it)
|
||||
@ -147,20 +143,20 @@ fun addMachineAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
russian("Наблюдайте неудачный результат репликации, где ваш заказ рассыпался в материальную труху")
|
||||
},
|
||||
)
|
||||
.addCriterion("replicate_failure", TakeItemOutOfReplicatorTrigger.Instance(ItemPredicate.Builder.item().of(MItems.MATTER_DUST).build()))
|
||||
.save(serializer, modLocation("machines/replicate_failure"), existingFileHelper)
|
||||
.addCriterion("replicate_failure", TakeItemOutOfReplicatorTrigger.Instance(ItemPredicate.Builder.item().of(MItems.MATTER_DUST).build()).criterion())
|
||||
.save(serializer, modLocation("machines/replicate_failure"))
|
||||
}
|
||||
|
||||
reconstructor.make(serializer, existingFileHelper, it, translation)
|
||||
reconstructor.make(serializer, it, translation)
|
||||
}
|
||||
|
||||
bottler.make(serializer, existingFileHelper, it, translation)
|
||||
recycler.make(serializer, existingFileHelper, it, translation)
|
||||
capacitor.make(serializer, existingFileHelper, it, translation)
|
||||
bottler.make(serializer, it, translation)
|
||||
recycler.make(serializer, it, translation)
|
||||
capacitor.make(serializer, it, translation)
|
||||
}
|
||||
|
||||
counter.make(serializer, existingFileHelper, press, translation).also {
|
||||
battery.make(serializer, existingFileHelper, it, translation)
|
||||
counter.make(serializer, press, translation).also {
|
||||
battery.make(serializer, it, translation)
|
||||
}
|
||||
|
||||
val station = CraftEntry(MItems.ANDROID_STATION, "Android Home Page",
|
||||
@ -171,25 +167,25 @@ fun addMachineAdvancements(serializer: Consumer<Advancement>, existingFileHelper
|
||||
val charger = CraftEntry(MItems.ANDROID_CHARGER, "Android Home Router",
|
||||
russianName = "Домашняя страница андроидов")
|
||||
|
||||
station.make(serializer, existingFileHelper, press, translation).also {
|
||||
charger.make(serializer, existingFileHelper, it, translation)
|
||||
station.make(serializer, press, translation).also {
|
||||
charger.make(serializer, it, translation)
|
||||
}
|
||||
|
||||
CraftEntry(MItems.COBBLESTONE_GENERATOR, "Cobblestone: Infinity + 1",
|
||||
russianName = "Булыжник: бесконечность + 1",
|
||||
russianSuffix = "Смотрите, чтоб он не просыпался во все сундуки",
|
||||
englishSuffix = "Watch for not to spill it over all your chests").make(serializer, existingFileHelper, press, translation)
|
||||
englishSuffix = "Watch for not to spill it over all your chests").make(serializer, press, translation)
|
||||
|
||||
CraftEntry(MItems.POWERED_FURNACE, "One Big Resistor",
|
||||
russianName = "Один большой резистор",
|
||||
russianSuffix = "Каждый элемент электрической цепи способен испускать свет и тепло, единожды.",
|
||||
englishSuffix = "Any electrical element can emit light and heat, once.")
|
||||
.make(serializer, existingFileHelper, press, translation)
|
||||
.make(serializer, press, translation)
|
||||
.also {
|
||||
CraftEntry(MItems.POWERED_BLAST_FURNACE, "Big Microwave Oven",
|
||||
russianName = "Большая микроволновая печь").make(serializer, existingFileHelper, it, translation)
|
||||
russianName = "Большая микроволновая печь").make(serializer, it, translation)
|
||||
|
||||
CraftEntry(MItems.POWERED_SMOKER, "Small Microwave Oven",
|
||||
russianName = "Маленькая микроволновая печь").make(serializer, existingFileHelper, it, translation)
|
||||
russianName = "Маленькая микроволновая печь").make(serializer, it, translation)
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.datagen.recipes
|
||||
import com.google.common.collect.Lists
|
||||
import net.minecraft.data.recipes.FinishedRecipe
|
||||
import net.minecraft.data.recipes.RecipeCategory
|
||||
import net.minecraft.data.recipes.RecipeOutput
|
||||
import net.minecraft.data.recipes.SimpleCookingRecipeBuilder
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
@ -14,7 +15,7 @@ import ru.dbotthepony.mc.otm.registry.MItems
|
||||
import java.util.*
|
||||
import java.util.function.Consumer
|
||||
|
||||
private fun Consumer<FinishedRecipe>.addRecyclingRecipe(inputs: Collection<ItemLike>, result: Item, name: String) {
|
||||
private fun RecipeOutput.addRecyclingRecipe(inputs: Collection<ItemLike>, result: Item, name: String) {
|
||||
val inputStacks = inputs.map(::ItemStack)
|
||||
|
||||
SimpleCookingRecipeBuilder.smelting(
|
||||
@ -28,7 +29,7 @@ private fun Consumer<FinishedRecipe>.addRecyclingRecipe(inputs: Collection<ItemL
|
||||
).also { r -> inputs.forEach { r.unlockedBy(it) } }.save(this, modLocation("blasting/${name}"))
|
||||
}
|
||||
|
||||
fun addBlastingRecipes(consumer: Consumer<FinishedRecipe>) {
|
||||
fun addBlastingRecipes(consumer: RecipeOutput) {
|
||||
SimpleCookingRecipeBuilder.blasting(Ingredient.of(MItems.MIRROR_COMPOUND), RecipeCategory.MISC, MItems.MIRROR, 0.1f, 100).unlockedBy(MItems.MIRROR_COMPOUND).save(consumer)
|
||||
|
||||
SimpleCookingRecipeBuilder.smelting(Ingredient.of(MItemTags.TRITANIUM_PLATES), RecipeCategory.MISC, MItems.TRITANIUM_INGOT, 0f, 100).unlockedBy(MItemTags.TRITANIUM_PLATES).save(consumer, modLocation("tritanium_ingot_from_plates"))
|
||||
|
@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.datagen.recipes
|
||||
|
||||
import net.minecraft.data.recipes.FinishedRecipe
|
||||
import net.minecraft.data.recipes.RecipeCategory
|
||||
import net.minecraft.data.recipes.RecipeOutput
|
||||
import net.minecraft.data.recipes.ShapelessRecipeBuilder
|
||||
import net.minecraft.tags.ItemTags
|
||||
import net.minecraft.world.item.ItemStack
|
||||
@ -19,7 +20,7 @@ import ru.dbotthepony.mc.otm.recipe.ExplosiveHammerPrimingRecipe
|
||||
import ru.dbotthepony.mc.otm.recipe.UpgradeRecipe
|
||||
import java.util.function.Consumer
|
||||
|
||||
fun addCraftingTableRecipes(consumer: Consumer<FinishedRecipe>) {
|
||||
fun addCraftingTableRecipes(consumer: RecipeOutput) {
|
||||
val machinesCategory = RecipeCategory.DECORATIONS
|
||||
|
||||
MatteryRecipe(MRegistry.CARGO_CRATES.item, category = RecipeCategory.DECORATIONS)
|
||||
@ -407,7 +408,7 @@ fun addCraftingTableRecipes(consumer: Consumer<FinishedRecipe>) {
|
||||
.unlockedBy(MItemTags.TRITANIUM_INGOTS)
|
||||
.build(consumer)
|
||||
|
||||
consumer.accept(ExplosiveHammerPrimingRecipe(modLocation("hammer_priming"), Ingredient.of(Tags.Items.NUGGETS_IRON)).finishedRecipe)
|
||||
consumer.accept(ExplosiveHammerPrimingRecipe(Ingredient.of(Tags.Items.NUGGETS_IRON)).toFinished(modLocation("hammer_priming")))
|
||||
|
||||
MatteryRecipe(MItems.EXPLOSIVE_HAMMER, category = RecipeCategory.COMBAT)
|
||||
.rowB(Tags.Items.INGOTS_IRON)
|
||||
|
@ -15,7 +15,7 @@ import ru.dbotthepony.mc.otm.registry.MItems
|
||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||
import java.util.function.Consumer
|
||||
|
||||
private fun stairs(base: ItemLike, result: ItemLike, consumer: Consumer<FinishedRecipe>) {
|
||||
private fun stairs(base: ItemLike, result: ItemLike, consumer: RecipeOutput) {
|
||||
MatteryRecipe(result, 4, category = RecipeCategory.BUILDING_BLOCKS)
|
||||
.rowA(base)
|
||||
.rowAB(base, base)
|
||||
@ -24,14 +24,14 @@ private fun stairs(base: ItemLike, result: ItemLike, consumer: Consumer<Finished
|
||||
.build(consumer, modLocation("decorative/stairs/${base.asItem().registryName!!.path}"))
|
||||
}
|
||||
|
||||
private fun slab(base: ItemLike, result: ItemLike, consumer: Consumer<FinishedRecipe>) {
|
||||
private fun slab(base: ItemLike, result: ItemLike, consumer: RecipeOutput) {
|
||||
MatteryRecipe(result, 6, category = RecipeCategory.BUILDING_BLOCKS)
|
||||
.row(base, base, base)
|
||||
.unlockedBy(base)
|
||||
.build(consumer, modLocation("decorative/slabs/${base.asItem().registryName!!.path}"))
|
||||
}
|
||||
|
||||
private fun wall(base: ItemLike, result: ItemLike, consumer: Consumer<FinishedRecipe>) {
|
||||
private fun wall(base: ItemLike, result: ItemLike, consumer: RecipeOutput) {
|
||||
MatteryRecipe(result, 6, category = RecipeCategory.BUILDING_BLOCKS)
|
||||
.row(base, base, base)
|
||||
.row(base, base, base)
|
||||
@ -39,29 +39,29 @@ private fun wall(base: ItemLike, result: ItemLike, consumer: Consumer<FinishedRe
|
||||
.build(consumer, modLocation("decorative/walls/${base.asItem().registryName!!.path}"))
|
||||
}
|
||||
|
||||
private fun cut(base: ItemLike, result: ItemLike, amount: Int, consumer: Consumer<FinishedRecipe>) {
|
||||
private fun cut(base: ItemLike, result: ItemLike, amount: Int, consumer: RecipeOutput) {
|
||||
SingleItemRecipeBuilder
|
||||
.stonecutting(Ingredient.of(base), RecipeCategory.BUILDING_BLOCKS, result, amount)
|
||||
.unlockedBy(base)
|
||||
.save(consumer, modLocation("stonecutting/${result.asItem().registryName!!.path}_from_${base.asItem().registryName!!.path}"))
|
||||
}
|
||||
|
||||
private fun stairsWithCut(base: ItemLike, result: ItemLike, consumer: Consumer<FinishedRecipe>) {
|
||||
private fun stairsWithCut(base: ItemLike, result: ItemLike, consumer: RecipeOutput) {
|
||||
stairs(base, result, consumer)
|
||||
cut(base, result, 1, consumer)
|
||||
}
|
||||
|
||||
private fun slabWithCut(base: ItemLike, result: ItemLike, consumer: Consumer<FinishedRecipe>) {
|
||||
private fun slabWithCut(base: ItemLike, result: ItemLike, consumer: RecipeOutput) {
|
||||
slab(base, result, consumer)
|
||||
cut(base, result, 2, consumer)
|
||||
}
|
||||
|
||||
private fun wallWithCut(base: ItemLike, result: ItemLike, consumer: Consumer<FinishedRecipe>) {
|
||||
private fun wallWithCut(base: ItemLike, result: ItemLike, consumer: RecipeOutput) {
|
||||
wall(base, result, consumer)
|
||||
cut(base, result, 1, consumer)
|
||||
}
|
||||
|
||||
fun addDecorativesRecipes(provider: MatteryRecipeProvider, consumer: Consumer<FinishedRecipe>) {
|
||||
fun addDecorativesRecipes(provider: MatteryRecipeProvider, consumer: RecipeOutput) {
|
||||
// Напольная плитка
|
||||
for ((color, unrefinedItem) in MRegistry.UNREFINED_FLOOR_TILES.items) {
|
||||
MatteryRecipe(unrefinedItem, 24)
|
||||
|
@ -1,6 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.datagen.recipes
|
||||
|
||||
import net.minecraft.data.recipes.FinishedRecipe
|
||||
import net.minecraft.data.recipes.RecipeOutput
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.crafting.Ingredient
|
||||
import net.minecraftforge.common.Tags
|
||||
@ -10,12 +10,10 @@ import ru.dbotthepony.mc.otm.recipe.IngredientMatrix
|
||||
import ru.dbotthepony.mc.otm.recipe.MatterEntanglerRecipe
|
||||
import ru.dbotthepony.mc.otm.registry.MItemTags
|
||||
import ru.dbotthepony.mc.otm.registry.MItems
|
||||
import java.util.function.Consumer
|
||||
|
||||
fun addMatterEntanglerRecipes(consumer: Consumer<FinishedRecipe>) {
|
||||
fun addMatterEntanglerRecipes(consumer: RecipeOutput) {
|
||||
consumer.accept(
|
||||
MatterEntanglerRecipe(
|
||||
modLocation("quantum_capacitor"),
|
||||
IngredientMatrix.of(
|
||||
listOf(Ingredient.of(MItems.ELECTRIC_PARTS), Ingredient.of(MItemTags.GOLD_WIRES), Ingredient.of(MItems.ELECTRIC_PARTS)),
|
||||
listOf(Ingredient.of(MItems.BATTERY_CAPACITOR), Ingredient.of(MItems.QUANTUM_TRANSCEIVER), Ingredient.of(MItems.BATTERY_CAPACITOR)),
|
||||
@ -24,12 +22,11 @@ fun addMatterEntanglerRecipes(consumer: Consumer<FinishedRecipe>) {
|
||||
Decimal(40),
|
||||
400.0,
|
||||
ItemStack(MItems.QUANTUM_CAPACITOR, 2)
|
||||
).energetic().toFinished()
|
||||
).energetic().toFinished(modLocation("quantum_capacitor"))
|
||||
)
|
||||
|
||||
consumer.accept(
|
||||
MatterEntanglerRecipe(
|
||||
modLocation("quantum_battery"),
|
||||
IngredientMatrix.of(
|
||||
listOf(Ingredient.of(Tags.Items.STORAGE_BLOCKS_REDSTONE), Ingredient.of(MItemTags.GOLD_WIRES), Ingredient.of(Tags.Items.STORAGE_BLOCKS_REDSTONE)),
|
||||
listOf(Ingredient.of(MItems.BATTERY_DENSE), Ingredient.of(MItems.QUANTUM_TRANSCEIVER), Ingredient.of(MItems.BATTERY_DENSE)),
|
||||
@ -38,6 +35,6 @@ fun addMatterEntanglerRecipes(consumer: Consumer<FinishedRecipe>) {
|
||||
Decimal(120),
|
||||
600.0,
|
||||
ItemStack(MItems.QUANTUM_BATTERY, 2)
|
||||
).energetic().toFinished()
|
||||
).energetic().toFinished(modLocation("quantum_battery"))
|
||||
)
|
||||
}
|
||||
|
@ -2,9 +2,12 @@
|
||||
package ru.dbotthepony.mc.otm.datagen.recipes
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import net.minecraft.advancements.Advancement
|
||||
import net.minecraft.advancements.Criterion
|
||||
import net.minecraft.advancements.CriterionTriggerInstance
|
||||
import net.minecraft.data.recipes.FinishedRecipe
|
||||
import net.minecraft.data.recipes.RecipeCategory
|
||||
import net.minecraft.data.recipes.RecipeOutput
|
||||
import net.minecraft.data.recipes.ShapedRecipeBuilder
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.tags.TagKey
|
||||
@ -13,9 +16,9 @@ import net.minecraft.world.item.crafting.Ingredient
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer
|
||||
import net.minecraft.world.level.ItemLike
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.core.collect.JsonArrayCollector
|
||||
import ru.dbotthepony.mc.otm.core.registryName
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.core.toJsonStrict
|
||||
import ru.dbotthepony.mc.otm.datagen.modLocation
|
||||
import ru.dbotthepony.mc.otm.recipe.EnergyContainerRecipe
|
||||
import ru.dbotthepony.mc.otm.recipe.UpgradeRecipe
|
||||
@ -54,6 +57,18 @@ private data class RecipeRow(
|
||||
val c: RecipeCell?,
|
||||
)
|
||||
|
||||
private fun RecipeOutput.map(mapper: (FinishedRecipe) -> FinishedRecipe): RecipeOutput {
|
||||
return object : RecipeOutput {
|
||||
override fun accept(recipe: FinishedRecipe) {
|
||||
this@map.accept(mapper(recipe))
|
||||
}
|
||||
|
||||
override fun advancement(): Advancement.Builder {
|
||||
return this@map.advancement()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [ShapedRecipeBuilder] that doesn't suck
|
||||
*/
|
||||
@ -62,11 +77,11 @@ class MatteryRecipe(val result: ItemLike, val count: Int = 1, val category: Reci
|
||||
private val rows = arrayOfNulls<RecipeRow>(3)
|
||||
private var index = 0
|
||||
|
||||
private val unlockedBy = ArrayList<Pair<String, CriterionTriggerInstance>>().also {
|
||||
private val unlockedBy = ArrayList<Pair<String, Criterion<*>>>().also {
|
||||
it.add("has_result" to has(result))
|
||||
}
|
||||
|
||||
fun unlockedBy(name: String, trigger: CriterionTriggerInstance): MatteryRecipe {
|
||||
fun unlockedBy(name: String, trigger: Criterion<*>): MatteryRecipe {
|
||||
unlockedBy.add(name to trigger)
|
||||
return this
|
||||
}
|
||||
@ -163,55 +178,55 @@ class MatteryRecipe(val result: ItemLike, val count: Int = 1, val category: Reci
|
||||
return this
|
||||
}
|
||||
|
||||
private fun filter(consumer: Consumer<FinishedRecipe>): Consumer<FinishedRecipe> {
|
||||
private fun filter(): (FinishedRecipe) -> FinishedRecipe {
|
||||
if (upgradeSource != null) {
|
||||
check(copyPaths.isNotEmpty()) { "Defined upgrade recipe without nbt migration operations" }
|
||||
|
||||
return Consumer {
|
||||
consumer.accept(object : FinishedRecipe by it {
|
||||
return {
|
||||
object : FinishedRecipe by it {
|
||||
override fun serializeRecipeData(pJson: JsonObject) {
|
||||
it.serializeRecipeData(pJson)
|
||||
|
||||
pJson["copyPaths"] = copyPaths.stream().map { it.serialize() }.collect(JsonArrayCollector)
|
||||
pJson["copyPaths"] = UpgradeRecipe.COPY_PATHS_CODEC.toJsonStrict(copyPaths)
|
||||
pJson["source"] = upgradeSource!!.toString()
|
||||
}
|
||||
|
||||
override fun getType(): RecipeSerializer<*> {
|
||||
return UpgradeRecipe.Companion
|
||||
override fun type(): RecipeSerializer<*> {
|
||||
return UpgradeRecipe.CODEC
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return consumer
|
||||
return { it }
|
||||
}
|
||||
|
||||
fun build(consumer: Consumer<FinishedRecipe>, name: String? = null) {
|
||||
fun build(consumer: RecipeOutput, name: String? = null) {
|
||||
val builder = buildRegular()
|
||||
|
||||
if (name != null) {
|
||||
builder.save(filter(consumer), modLocation(
|
||||
builder.save(consumer.map(filter()), modLocation(
|
||||
if (result.asItem().registryName!!.namespace == OverdriveThatMatters.MOD_ID)
|
||||
"${result.asItem().registryName!!.path}_$name"
|
||||
else
|
||||
"${result.asItem().registryName!!.namespace}_${result.asItem().registryName!!.path}_$name"
|
||||
))
|
||||
} else {
|
||||
builder.save(filter(consumer))
|
||||
builder.save(consumer.map(filter()))
|
||||
}
|
||||
}
|
||||
|
||||
fun build(consumer: Consumer<FinishedRecipe>, name: ResourceLocation) {
|
||||
buildRegular().save(filter(consumer), name)
|
||||
fun build(consumer: RecipeOutput, name: ResourceLocation) {
|
||||
buildRegular().save(consumer.map(filter()), name)
|
||||
}
|
||||
|
||||
fun buildEnergetic(consumer: Consumer<FinishedRecipe>, name: String? = null) {
|
||||
build({
|
||||
consumer.accept(object : FinishedRecipe by it {
|
||||
override fun getType(): RecipeSerializer<*> {
|
||||
fun buildEnergetic(consumer: RecipeOutput, name: String? = null) {
|
||||
build(consumer.map {
|
||||
object : FinishedRecipe by it {
|
||||
override fun type(): RecipeSerializer<*> {
|
||||
return EnergyContainerRecipe.Companion
|
||||
}
|
||||
})
|
||||
}
|
||||
}, name)
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
package ru.dbotthepony.mc.otm.datagen.recipes
|
||||
|
||||
import com.google.common.collect.ImmutableList
|
||||
import net.minecraft.advancements.CriteriaTriggers
|
||||
import net.minecraft.advancements.Criterion
|
||||
import net.minecraft.advancements.critereon.ContextAwarePredicate
|
||||
import net.minecraft.advancements.critereon.EntityPredicate
|
||||
import net.minecraft.advancements.critereon.InventoryChangeTrigger
|
||||
@ -8,6 +11,7 @@ import net.minecraft.advancements.critereon.MinMaxBounds
|
||||
import net.minecraft.data.DataGenerator
|
||||
import net.minecraft.data.recipes.FinishedRecipe
|
||||
import net.minecraft.data.recipes.RecipeBuilder
|
||||
import net.minecraft.data.recipes.RecipeOutput
|
||||
import net.minecraft.data.recipes.RecipeProvider
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.tags.ItemTags
|
||||
@ -20,32 +24,32 @@ import net.minecraft.world.level.ItemLike
|
||||
import ru.dbotthepony.mc.otm.core.registryName
|
||||
import ru.dbotthepony.mc.otm.datagen.modLocation
|
||||
import ru.dbotthepony.mc.otm.recipe.PlatePressRecipe
|
||||
import java.util.LinkedList
|
||||
import java.util.*
|
||||
import java.util.function.Consumer
|
||||
import java.util.stream.Stream
|
||||
|
||||
private typealias RecipeBuilderCallback = (MatteryRecipeProvider, consumer: Consumer<FinishedRecipe>) -> Unit
|
||||
private typealias RecipeBuilderCallback = (MatteryRecipeProvider, consumer: RecipeOutput) -> Unit
|
||||
|
||||
fun has(p_176521_: MinMaxBounds.Ints, p_176522_: ItemLike): InventoryChangeTrigger.TriggerInstance {
|
||||
fun has(p_176521_: MinMaxBounds.Ints, p_176522_: ItemLike): Criterion<InventoryChangeTrigger.TriggerInstance> {
|
||||
return inventoryTrigger(ItemPredicate.Builder.item().of(p_176522_).withCount(p_176521_).build())
|
||||
}
|
||||
|
||||
fun has(p_125978_: ItemLike): InventoryChangeTrigger.TriggerInstance {
|
||||
fun has(p_125978_: ItemLike): Criterion<InventoryChangeTrigger.TriggerInstance> {
|
||||
return inventoryTrigger(ItemPredicate.Builder.item().of(p_125978_).build())
|
||||
}
|
||||
|
||||
fun has(p_125976_: TagKey<Item>): InventoryChangeTrigger.TriggerInstance {
|
||||
fun has(p_125976_: TagKey<Item>): Criterion<InventoryChangeTrigger.TriggerInstance> {
|
||||
return inventoryTrigger(ItemPredicate.Builder.item().of(p_125976_).build())
|
||||
}
|
||||
|
||||
fun inventoryTrigger(vararg p_126012_: ItemPredicate): InventoryChangeTrigger.TriggerInstance {
|
||||
return InventoryChangeTrigger.TriggerInstance(
|
||||
ContextAwarePredicate.ANY,
|
||||
fun inventoryTrigger(vararg p_126012_: ItemPredicate): Criterion<InventoryChangeTrigger.TriggerInstance> {
|
||||
return CriteriaTriggers.INVENTORY_CHANGED.createCriterion(InventoryChangeTrigger.TriggerInstance(
|
||||
Optional.empty(),
|
||||
MinMaxBounds.Ints.ANY,
|
||||
MinMaxBounds.Ints.ANY,
|
||||
MinMaxBounds.Ints.ANY,
|
||||
p_126012_
|
||||
)
|
||||
ImmutableList.copyOf(p_126012_)
|
||||
))
|
||||
}
|
||||
|
||||
fun <T : RecipeBuilder> T.unlockedBy(item: ItemLike): T {
|
||||
@ -75,7 +79,7 @@ class MatteryRecipeProvider(generatorIn: DataGenerator) : RecipeProvider(generat
|
||||
return this
|
||||
}
|
||||
|
||||
override fun buildRecipes(callback: Consumer<FinishedRecipe>) {
|
||||
override fun buildRecipes(callback: RecipeOutput) {
|
||||
for (lambda in callbacks) {
|
||||
lambda(this, callback)
|
||||
}
|
||||
@ -84,19 +88,18 @@ class MatteryRecipeProvider(generatorIn: DataGenerator) : RecipeProvider(generat
|
||||
fun plate(id: String, count: Int = 1, workTicks: Int = 200, experience: FloatProvider = ConstantFloat.ZERO) {
|
||||
exec { _, consumer ->
|
||||
consumer.accept(PlatePressRecipe(
|
||||
modLocation("plates/$id"),
|
||||
Ingredient.of(ItemTags.create(ResourceLocation("forge", "ingots/$id"))),
|
||||
Ingredient.of(ItemTags.create(ResourceLocation("forge", "plates/$id"))),
|
||||
count,
|
||||
workTicks,
|
||||
experience = experience
|
||||
).toFinished())
|
||||
).toFinished(modLocation("plates/$id")))
|
||||
}
|
||||
}
|
||||
|
||||
fun plate(id: String, ingredient: Ingredient, result: Ingredient, count: Int = 1, workTicks: Int = 200, experience: FloatProvider = ConstantFloat.ZERO) {
|
||||
exec { it, callback ->
|
||||
callback.accept(PlatePressRecipe(modLocation("plate_$id"), ingredient, result, count, workTicks, experience = experience).toFinished())
|
||||
callback.accept(PlatePressRecipe(ingredient, result, count, workTicks, experience = experience).toFinished(modLocation("plate_$id")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.datagen.recipes
|
||||
|
||||
import net.minecraft.data.recipes.FinishedRecipe
|
||||
import net.minecraft.data.recipes.RecipeCategory
|
||||
import net.minecraft.data.recipes.RecipeOutput
|
||||
import net.minecraft.data.recipes.SimpleCookingRecipeBuilder
|
||||
import net.minecraft.world.item.crafting.Ingredient
|
||||
import ru.dbotthepony.mc.otm.datagen.modLocation
|
||||
@ -9,7 +10,7 @@ import ru.dbotthepony.mc.otm.registry.MItemTags
|
||||
import ru.dbotthepony.mc.otm.registry.MItems
|
||||
import java.util.function.Consumer
|
||||
|
||||
fun addOreSmeltingRecipes(consumer: Consumer<FinishedRecipe>) {
|
||||
fun addOreSmeltingRecipes(consumer: RecipeOutput) {
|
||||
SimpleCookingRecipeBuilder.smelting(Ingredient.of(MItemTags.TRITANIUM_ORES), RecipeCategory.MISC, MItems.TRITANIUM_INGOT, 1f, 200).unlockedBy(MItemTags.TRITANIUM_ORES).save(consumer, modLocation("smelting/tritanium_ingot_from_ore_block"))
|
||||
SimpleCookingRecipeBuilder.blasting(Ingredient.of(MItemTags.TRITANIUM_ORES), RecipeCategory.MISC, MItems.TRITANIUM_INGOT, 1f, 100).unlockedBy(MItemTags.TRITANIUM_ORES).save(consumer, modLocation("blasting/tritanium_ingot_from_ore_block"))
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package ru.dbotthepony.mc.otm.datagen.recipes
|
||||
|
||||
import net.minecraft.data.recipes.FinishedRecipe
|
||||
import net.minecraft.data.recipes.RecipeOutput
|
||||
import net.minecraft.world.item.DyeColor
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
@ -16,20 +17,19 @@ import java.util.function.Consumer
|
||||
|
||||
private val Item.recipeName get() = registryName!!.namespace + "/" + registryName!!.path
|
||||
|
||||
private fun generate(consumer: Consumer<FinishedRecipe>, items: Map<out DyeColor?, Item>, amount: Int = 1) {
|
||||
private fun generate(consumer: RecipeOutput, items: Map<out DyeColor?, Item>, amount: Int = 1) {
|
||||
for ((targetColor, targetItem) in items) {
|
||||
if (targetColor == null) continue
|
||||
|
||||
consumer.accept(PainterRecipe(
|
||||
modLocation("painter/" + targetItem.recipeName),
|
||||
Ingredient.of(items.entries.stream().filter { it.key != null && it.key != targetColor }.map { ItemStack(it.value) }),
|
||||
ItemStack(targetItem),
|
||||
mapOf(targetColor to amount)
|
||||
).toFinished())
|
||||
).toFinished(modLocation("painter/" + targetItem.recipeName)))
|
||||
}
|
||||
}
|
||||
|
||||
private fun generate(consumer: Consumer<FinishedRecipe>, default: Item, items: Map<out DyeColor?, Item>, amount: Int = 1, cleaning: Boolean = true) {
|
||||
private fun generate(consumer: RecipeOutput, default: Item, items: Map<out DyeColor?, Item>, amount: Int = 1, cleaning: Boolean = true) {
|
||||
generate(consumer, items)
|
||||
|
||||
if (cleaning)
|
||||
@ -39,37 +39,34 @@ private fun generate(consumer: Consumer<FinishedRecipe>, default: Item, items: M
|
||||
if (k1 == null) continue
|
||||
|
||||
consumer.accept(PainterRecipe(
|
||||
modLocation("painter/" + default.recipeName + "/" + v1.recipeName),
|
||||
Ingredient.of(default),
|
||||
ItemStack(v1),
|
||||
mapOf(k1 to amount)
|
||||
).toFinished())
|
||||
).toFinished(modLocation("painter/" + default.recipeName + "/" + v1.recipeName)))
|
||||
}
|
||||
}
|
||||
|
||||
private fun cleaning(consumer: Consumer<FinishedRecipe>, to: Item, from: Map<out DyeColor?, Item>) {
|
||||
private fun cleaning(consumer: RecipeOutput, to: Item, from: Map<out DyeColor?, Item>) {
|
||||
consumer.accept(PainterRecipe(
|
||||
modLocation("painter/cleaning/" + to.recipeName),
|
||||
Ingredient.of(from.entries.stream().filter { it.key != null }.map { ItemStack(it.value) }),
|
||||
ItemStack(to),
|
||||
setOf()
|
||||
).toFinished())
|
||||
).toFinished(modLocation("painter/cleaning/" + to.recipeName)))
|
||||
}
|
||||
|
||||
private fun striped(consumer: Consumer<FinishedRecipe>, name: String, items: List<Pair<Item, Pair<DyeColor, DyeColor>>>, base: Map<DyeColor, Item>) {
|
||||
private fun striped(consumer: RecipeOutput, name: String, items: List<Pair<Item, Pair<DyeColor, DyeColor>>>, base: Map<DyeColor, Item>) {
|
||||
for ((stripeItem, colors) in items) {
|
||||
val (baseColor, stripe) = colors
|
||||
|
||||
consumer.accept(PainterRecipe(
|
||||
modLocation("painter/stripes_$name/${baseColor.getName()}/${stripe.getName()}"),
|
||||
Ingredient.of(base[baseColor]),
|
||||
ItemStack(stripeItem),
|
||||
setOf(stripe)
|
||||
).toFinished())
|
||||
).toFinished(modLocation("painter/stripes_$name/${baseColor.getName()}/${stripe.getName()}")))
|
||||
}
|
||||
}
|
||||
|
||||
fun addPainterRecipes(consumer: Consumer<FinishedRecipe>) {
|
||||
fun addPainterRecipes(consumer: RecipeOutput) {
|
||||
generate(consumer, mapOf(
|
||||
DyeColor.WHITE to Items.WHITE_WOOL,
|
||||
DyeColor.ORANGE to Items.ORANGE_WOOL,
|
||||
|
@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.datagen.recipes
|
||||
|
||||
import net.minecraft.data.recipes.FinishedRecipe
|
||||
import net.minecraft.data.recipes.RecipeCategory
|
||||
import net.minecraft.data.recipes.RecipeOutput
|
||||
import net.minecraft.data.recipes.ShapelessRecipeBuilder
|
||||
import net.minecraft.world.item.DyeColor
|
||||
import net.minecraft.world.item.ItemStack
|
||||
@ -14,8 +15,8 @@ import ru.dbotthepony.mc.otm.registry.MItems
|
||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||
import java.util.function.Consumer
|
||||
|
||||
fun addShapelessRecipes(consumer: Consumer<FinishedRecipe>) {
|
||||
for (color in DyeColor.values()) {
|
||||
fun addShapelessRecipes(consumer: RecipeOutput) {
|
||||
for (color in DyeColor.entries) {
|
||||
ShapelessRecipeBuilder(RecipeCategory.TRANSPORTATION, MItems.CARGO_CRATE_MINECARTS[color]!!, 1)
|
||||
.requires(Items.MINECART)
|
||||
.requires(MRegistry.CARGO_CRATES.items[color]!!)
|
||||
|
@ -0,0 +1,23 @@
|
||||
package ru.dbotthepony.mc.otm.mixin;
|
||||
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
|
||||
import static ru.dbotthepony.mc.otm.client.render.RenderHelperKt.popScissorRect;
|
||||
import static ru.dbotthepony.mc.otm.client.render.RenderHelperKt.pushScissorRect;
|
||||
|
||||
// because scissor stack fucking sucks.
|
||||
// mostly because it is not a stack at all.
|
||||
@Mixin(GuiGraphics.class)
|
||||
public abstract class GuiGraphicsMixin {
|
||||
@Overwrite
|
||||
public void enableScissor(int x0, int y0, int x1, int y1) {
|
||||
pushScissorRect(x0, y0, x1 - x0, y1 - y0);
|
||||
}
|
||||
|
||||
@Overwrite
|
||||
public void disableScissor() {
|
||||
popScissorRect();
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener
|
||||
import net.minecraft.util.profiling.ProfilerFiller
|
||||
import net.minecraftforge.event.AddReloadListenerEvent
|
||||
import net.minecraftforge.event.OnDatapackSyncEvent
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import net.minecraftforge.event.network.CustomPayloadEvent
|
||||
import net.minecraftforge.network.PacketDistributor
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.mc.otm.MINECRAFT_SERVER
|
||||
@ -27,11 +27,8 @@ import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.core.toNetwork
|
||||
import ru.dbotthepony.mc.otm.network.GenericNetworkChannel
|
||||
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
||||
import ru.dbotthepony.mc.otm.network.enqueueWork
|
||||
import ru.dbotthepony.mc.otm.network.packetHandled
|
||||
import ru.dbotthepony.mc.otm.onceServer
|
||||
import java.util.LinkedList
|
||||
import java.util.function.Supplier
|
||||
|
||||
object AndroidResearchManager : SimpleJsonResourceReloadListener(GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(), "otm_android_research"), Iterable<AndroidResearchType> {
|
||||
const val DIRECTORY = "otm_android_research"
|
||||
@ -114,7 +111,7 @@ object AndroidResearchManager : SimpleJsonResourceReloadListener(GsonBuilder().s
|
||||
LOGGER.debug("Constructed android research registry packet, ${buff.writerIndex()} bytes in size")
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
context.packetHandled = true
|
||||
|
||||
if (NULLABLE_MINECRAFT_SERVER is IntegratedServer) {
|
||||
|
@ -25,7 +25,6 @@ import ru.dbotthepony.mc.otm.core.collect.ListSet
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.core.isActuallyEmpty
|
||||
import ru.dbotthepony.mc.otm.data.ComponentCodec
|
||||
import ru.dbotthepony.mc.otm.data.IngredientCodec
|
||||
import ru.dbotthepony.mc.otm.data.JsonElementCodec
|
||||
import ru.dbotthepony.mc.otm.isClient
|
||||
import java.util.Optional
|
||||
@ -393,7 +392,7 @@ class AndroidResearchType(
|
||||
ListCodec(
|
||||
RecordCodecBuilder.create<Pair<Ingredient, Int>> {
|
||||
it.group(
|
||||
IngredientCodec.fieldOf("item").forGetter { it.first },
|
||||
Ingredient.CODEC.fieldOf("item").forGetter { it.first },
|
||||
Codec.intRange(1, Int.MAX_VALUE).optionalFieldOf("count", 1).forGetter { it.second }
|
||||
).apply(it, ::Pair)
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import net.minecraft.client.multiplayer.ClientLevel
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import net.minecraftforge.event.network.CustomPayloadEvent
|
||||
import ru.dbotthepony.mc.otm.config.AndroidConfig
|
||||
import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||
@ -21,12 +21,10 @@ import ru.dbotthepony.mc.otm.core.position
|
||||
import ru.dbotthepony.mc.otm.core.math.times
|
||||
import ru.dbotthepony.mc.otm.network.GenericNetworkChannel
|
||||
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
||||
import ru.dbotthepony.mc.otm.network.packetHandled
|
||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||
import java.util.UUID
|
||||
import java.util.WeakHashMap
|
||||
import java.util.function.Predicate
|
||||
import java.util.function.Supplier
|
||||
|
||||
private data class SharedItemEntityData(val owner: UUID? = null, val age: Int = 0, val lifespan: Int = 0, val hasPickupDelay: Boolean = true) {
|
||||
companion object {
|
||||
@ -46,8 +44,7 @@ class ItemEntityDataPacket(val itemUUID: Int, val owner: UUID? = null, val age:
|
||||
buff.writeBoolean(hasPickupDelay)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val level = minecraft.player?.level() as ClientLevel? ?: return
|
||||
val entity = level.getEntity(itemUUID) as ItemEntity? ?: return
|
||||
datatable[entity] = SharedItemEntityData(owner, age, lifespan, hasPickupDelay)
|
||||
|
@ -1,23 +1,17 @@
|
||||
package ru.dbotthepony.mc.otm.android.feature
|
||||
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.core.particles.ParticleTypes
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.sounds.SoundSource
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import net.minecraftforge.network.PacketDistributor
|
||||
import net.minecraftforge.network.PacketDistributor.TargetPoint
|
||||
import ru.dbotthepony.mc.otm.config.ClientConfig
|
||||
import ru.dbotthepony.mc.otm.config.AndroidConfig
|
||||
import net.minecraftforge.event.network.CustomPayloadEvent
|
||||
import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||
import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact
|
||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.client.render.ResearchIcons
|
||||
import ru.dbotthepony.mc.otm.config.AndroidConfig
|
||||
import ru.dbotthepony.mc.otm.config.ClientConfig
|
||||
import ru.dbotthepony.mc.otm.core.math.RGBAColor
|
||||
import ru.dbotthepony.mc.otm.core.math.Vector
|
||||
import ru.dbotthepony.mc.otm.core.math.plus
|
||||
@ -25,9 +19,6 @@ import ru.dbotthepony.mc.otm.network.GenericNetworkChannel
|
||||
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
||||
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
|
||||
import ru.dbotthepony.mc.otm.network.SmokeParticlesPacket
|
||||
import ru.dbotthepony.mc.otm.network.enqueueWork
|
||||
import ru.dbotthepony.mc.otm.network.packetHandled
|
||||
import ru.dbotthepony.mc.otm.network.sender
|
||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||
import ru.dbotthepony.mc.otm.registry.MSoundEvents
|
||||
import java.util.function.Supplier
|
||||
@ -37,16 +28,13 @@ object TriggerJumpBoostPacket : MatteryPacket {
|
||||
// no op
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
|
||||
context.enqueueWork {
|
||||
val mattery = context.sender?.matteryPlayer ?: return@enqueueWork
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val mattery = context.sender?.matteryPlayer ?: return
|
||||
|
||||
if (!mattery.isAndroid)
|
||||
return@enqueueWork
|
||||
return
|
||||
|
||||
val feature = mattery.getFeature(AndroidFeatures.JUMP_BOOST) ?: return@enqueueWork
|
||||
val feature = mattery.getFeature(AndroidFeatures.JUMP_BOOST) ?: return
|
||||
|
||||
if (feature.isActive && feature.cooldown <= 4 && mattery.androidEnergy.extractEnergyExact(AndroidConfig.JumpBoost.ENERGY_COST, false)) {
|
||||
feature.putOnCooldown()
|
||||
@ -62,7 +50,6 @@ object TriggerJumpBoostPacket : MatteryPacket {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class JumpBoostFeature(capability: MatteryPlayerCapability) : AndroidSwitchableFeature(AndroidFeatures.JUMP_BOOST, capability) {
|
||||
|
@ -1,54 +1,41 @@
|
||||
package ru.dbotthepony.mc.otm.android.feature
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import it.unimi.dsi.fastutil.objects.ReferenceArraySet
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.sounds.SoundSource
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.monster.warden.Warden
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.config.AndroidConfig
|
||||
import ru.dbotthepony.mc.otm.android.AndroidResearchManager
|
||||
import net.minecraftforge.event.network.CustomPayloadEvent
|
||||
import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||
import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact
|
||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||
import ru.dbotthepony.mc.otm.client.render.ResearchIcons
|
||||
import ru.dbotthepony.mc.otm.core.math.Vector
|
||||
import ru.dbotthepony.mc.otm.core.util.formatPower
|
||||
import ru.dbotthepony.mc.otm.core.math.getEllipsoidBlockPositions
|
||||
import ru.dbotthepony.mc.otm.config.AndroidConfig
|
||||
import ru.dbotthepony.mc.otm.core.damageType
|
||||
import ru.dbotthepony.mc.otm.core.getEntitiesInEllipsoid
|
||||
import ru.dbotthepony.mc.otm.core.getExplosionResistance
|
||||
import ru.dbotthepony.mc.otm.core.math.RGBAColor
|
||||
import ru.dbotthepony.mc.otm.core.math.Vector
|
||||
import ru.dbotthepony.mc.otm.core.math.getEllipsoidBlockPositions
|
||||
import ru.dbotthepony.mc.otm.core.math.minus
|
||||
import ru.dbotthepony.mc.otm.core.math.plus
|
||||
import ru.dbotthepony.mc.otm.core.position
|
||||
import ru.dbotthepony.mc.otm.core.math.roundToIntVector
|
||||
import ru.dbotthepony.mc.otm.core.math.times
|
||||
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
|
||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||
import ru.dbotthepony.mc.otm.client.ShiftPressedCond
|
||||
import ru.dbotthepony.mc.otm.core.damageType
|
||||
import ru.dbotthepony.mc.otm.core.math.RGBAColor
|
||||
import ru.dbotthepony.mc.otm.core.position
|
||||
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
||||
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
|
||||
import ru.dbotthepony.mc.otm.network.ShockwaveEffectPacket
|
||||
import ru.dbotthepony.mc.otm.network.enqueueWork
|
||||
import ru.dbotthepony.mc.otm.network.packetHandled
|
||||
import ru.dbotthepony.mc.otm.network.sender
|
||||
import ru.dbotthepony.mc.otm.onceServer
|
||||
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||
import ru.dbotthepony.mc.otm.registry.MDamageTypes
|
||||
import ru.dbotthepony.mc.otm.registry.MNames
|
||||
import ru.dbotthepony.mc.otm.registry.MSoundEvents
|
||||
import ru.dbotthepony.mc.otm.registry.MatteryDamageSource
|
||||
import ru.dbotthepony.mc.otm.triggers.ShockwaveDamageMobTrigger
|
||||
import ru.dbotthepony.mc.otm.triggers.ShockwaveTrigger
|
||||
import java.util.function.Supplier
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@ -57,10 +44,8 @@ object TriggerShockwavePacket : MatteryPacket {
|
||||
// no op
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
context.enqueueWork {
|
||||
val shockwave = context.sender?.matteryPlayer?.getFeature(AndroidFeatures.SHOCKWAVE) as ShockwaveFeature? ?: return@enqueueWork
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val shockwave = context.sender?.matteryPlayer?.getFeature(AndroidFeatures.SHOCKWAVE) ?: return
|
||||
|
||||
if (!shockwave.isOnCooldown && shockwave.isActive && shockwave.airTicks > 0) {
|
||||
onceServer { // delay by one tick so player update its position as well
|
||||
@ -68,7 +53,6 @@ object TriggerShockwavePacket : MatteryPacket {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ShockwaveFeature(capability: MatteryPlayerCapability) : AndroidSwitchableFeature(AndroidFeatures.SHOCKWAVE, capability) {
|
||||
|
@ -667,12 +667,11 @@ class ExplosionQueue(private val level: ServerLevel) : SavedData() {
|
||||
@JvmStatic
|
||||
fun queueForLevel(level: ServerLevel): ExplosionQueue {
|
||||
return level.dataStorage.computeIfAbsent(
|
||||
{
|
||||
Factory({ ExplosionQueue(level) }, {
|
||||
val factory = ExplosionQueue(level)
|
||||
factory.load(it)
|
||||
factory
|
||||
},
|
||||
{ ExplosionQueue(level) },
|
||||
}, TODO()),
|
||||
"otm_blackhole_explosion_queue"
|
||||
)
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M
|
||||
.recipeManager
|
||||
.byType(MRecipes.MATTER_ENTANGLER)
|
||||
.values
|
||||
.any { it.preemptivelyMatches(shadow, level!!) }
|
||||
.any { it.value.preemptivelyMatches(shadow, level!!) }
|
||||
}
|
||||
|
||||
override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
|
||||
@ -139,9 +139,9 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M
|
||||
.recipeManager
|
||||
.byType(MRecipes.MATTER_ENTANGLER)
|
||||
.values
|
||||
.firstOrNull { it.matches(inputs, level!!) } ?: return JobContainer.noItem()
|
||||
.firstOrNull { it.value.matches(inputs, level!!) } ?: return JobContainer.noItem()
|
||||
|
||||
val result = recipe.assemble(inputs, level!!.registryAccess())
|
||||
val result = recipe.value.assemble(inputs, level!!.registryAccess())
|
||||
|
||||
inputs.forEach { it.shrink(1) }
|
||||
inputs.setChanged()
|
||||
@ -149,8 +149,8 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M
|
||||
return JobContainer.success(
|
||||
Job(
|
||||
result,
|
||||
recipe.matter,
|
||||
recipe.ticks * MachinesConfig.MATTER_ENTANGLER.workTimeMultiplier
|
||||
recipe.value.matter,
|
||||
recipe.value.ticks * MachinesConfig.MATTER_ENTANGLER.workTimeMultiplier
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ class ItemMonitorBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte
|
||||
if (craftingRecipe != null && craftingRecipe.matches(craftingGrid, level)) return true
|
||||
if (justCheckForRecipeChange) return false
|
||||
|
||||
craftingRecipe = server.recipeManager.getRecipeFor(RecipeType.CRAFTING, craftingGrid, level).orElse(null)
|
||||
craftingRecipe = server.recipeManager.getRecipeFor(RecipeType.CRAFTING, craftingGrid, level).orElse(null)?.value
|
||||
Arrays.fill(craftingGridTuples, null)
|
||||
val poweredView = poweredView
|
||||
|
||||
|
@ -92,8 +92,8 @@ class PlatePressBlockEntity(
|
||||
.byType(MRecipes.PLATE_PRESS)
|
||||
.values
|
||||
.iterator()
|
||||
.filter { it.matches(inputContainer, id) }
|
||||
.maybe() ?: return JobContainer.noItem()
|
||||
.filter { it.value.matches(inputContainer, id) }
|
||||
.maybe()?.value ?: return JobContainer.noItem()
|
||||
|
||||
val toProcess = inputContainer[id].count.coerceAtMost(1 + upgrades.processingItems)
|
||||
|
||||
|
@ -108,12 +108,12 @@ class PoweredFurnaceBlockEntity(
|
||||
val level = level as? ServerLevel ?: return JobContainer.failure()
|
||||
|
||||
return level.recipeManager.getRecipeFor(recipeType as RecipeType<AbstractCookingRecipe>, inputs[id], level).map {
|
||||
val output = it.assemble(inputs[id], level.registryAccess())
|
||||
val output = it.value.assemble(inputs[id], level.registryAccess())
|
||||
val toProcess = inputs[id][0].count.coerceAtMost(upgrades.processingItems + 1)
|
||||
inputs[id][0].shrink(toProcess)
|
||||
|
||||
JobContainer.success(ItemJob(
|
||||
output.copyWithCount(toProcess), it.cookingTime * config.workTimeMultiplier, config.energyConsumption * toProcess, it.experience * toProcess
|
||||
output.copyWithCount(toProcess), it.value.cookingTime * config.workTimeMultiplier, config.energyConsumption * toProcess, it.value.experience * toProcess
|
||||
))
|
||||
}.orElse(JobContainer.noItem())
|
||||
}
|
||||
|
@ -520,10 +520,10 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
|
||||
return JobContainer.noItem()
|
||||
} else {
|
||||
val actual = recipe.get()
|
||||
val item = actual.assemble(input, level.registryAccess())
|
||||
val item = actual.value.assemble(input, level.registryAccess())
|
||||
input[0].shrink(1)
|
||||
input.setChanged(0)
|
||||
return JobContainer.success(ItemJob(item, actual.cookingTime.toDouble(), ExopackConfig.FURNACE_POWER_CONSUMPTION, actual.experience))
|
||||
return JobContainer.success(ItemJob(item, actual.value.cookingTime.toDouble(), ExopackConfig.FURNACE_POWER_CONSUMPTION, actual.value.experience))
|
||||
}
|
||||
}
|
||||
|
||||
@ -531,7 +531,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
|
||||
super.onJobTick(status)
|
||||
|
||||
if (isExopackVisible && ply.level().random.nextFloat() <= 0.05f) {
|
||||
MatteryPlayerNetworkChannel.send(PacketDistributor.TRACKING_ENTITY_AND_SELF.with { ply as ServerPlayer }, ExopackSmokePacket(ply.uuid))
|
||||
MatteryPlayerNetworkChannel.send(PacketDistributor.TRACKING_ENTITY_AND_SELF.with(ply as ServerPlayer), ExopackSmokePacket(ply.uuid))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,7 +217,7 @@ fun onMouseScrolled(event: MouseScrolled.Pre) {
|
||||
|
||||
for (widget in screen.renderables) {
|
||||
if (widget is Panel2Widget<*, *>) {
|
||||
if (widget.panel.mouseScrolledChecked(event.mouseX, event.mouseY, event.scrollDelta)) {
|
||||
if (widget.panel.mouseScrolledChecked(event.mouseX, event.mouseY, event.deltaX)) {
|
||||
event.isCanceled = true
|
||||
return
|
||||
}
|
||||
@ -226,7 +226,7 @@ fun onMouseScrolled(event: MouseScrolled.Pre) {
|
||||
val slot = screen.slotUnderMouse
|
||||
|
||||
if (slot != null && (slot.container == minecraft.player?.inventory && slot.containerSlot in 9 .. 35 || slot.container == minecraft.player?.matteryPlayer?.exopackContainer)) {
|
||||
widget.panel.mouseScrolledInner(event.mouseX, event.mouseY, event.scrollDelta)
|
||||
widget.panel.mouseScrolledInner(event.mouseX, event.mouseY, event.deltaX)
|
||||
event.isCanceled = true
|
||||
return
|
||||
}
|
||||
|
@ -54,7 +54,6 @@ import java.util.*
|
||||
import kotlin.collections.ArrayDeque
|
||||
import kotlin.collections.List
|
||||
import kotlin.collections.MutableSet
|
||||
import kotlin.collections.indices
|
||||
import kotlin.collections.isNotEmpty
|
||||
import kotlin.collections.withIndex
|
||||
|
||||
@ -565,9 +564,9 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
|
||||
return super.mouseReleased(p_97812_, p_97813_, p_97814_)
|
||||
}
|
||||
|
||||
override fun mouseScrolled(p_94686_: Double, p_94687_: Double, p_94688_: Double): Boolean {
|
||||
override fun mouseScrolled(mouseX: Double, mouseY: Double, scrollX: Double, scrollY: Double): Boolean {
|
||||
for (panel in panels) {
|
||||
if (panel.mouseScrolledChecked(p_94686_, p_94687_, p_94688_)) {
|
||||
if (panel.mouseScrolledChecked(mouseX, mouseY, scrollY)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -648,7 +647,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
|
||||
val mouseYf = mouseY.toFloat()
|
||||
|
||||
// dark background
|
||||
this.renderBackground(graphics)
|
||||
this.renderBackground(graphics, mouseX, mouseY, partialTick)
|
||||
|
||||
super.hoveredSlot = null
|
||||
var hovered = false
|
||||
|
@ -123,8 +123,8 @@ class PainterScreen(menu: PainterMenu, inventory: Inventory, title: Component) :
|
||||
buttons.forEach { it.remove() }
|
||||
buttons.clear()
|
||||
|
||||
for (recipe in menu.possibleRecipes.sortedWith(CreativeMenuItemComparator.map { it.output.item })) {
|
||||
object : LargeRectangleButtonPanel<PainterScreen>(this@PainterScreen, canvas.canvas, icon = ItemStackIcon(recipe.output, 14f, 14f).fixed()) {
|
||||
for (recipe in menu.possibleRecipes.sortedWith(CreativeMenuItemComparator.map { it.value.output.item })) {
|
||||
object : LargeRectangleButtonPanel<PainterScreen>(this@PainterScreen, canvas.canvas, icon = ItemStackIcon(recipe.value.output, 14f, 14f).fixed()) {
|
||||
init {
|
||||
buttons.add(this)
|
||||
dockRight = 1f
|
||||
@ -132,13 +132,13 @@ class PainterScreen(menu: PainterMenu, inventory: Inventory, title: Component) :
|
||||
}
|
||||
|
||||
override var isDisabled: Boolean
|
||||
get() = !recipe.canCraft(menu.dyeStoredDirect)
|
||||
get() = !recipe.value.canCraft(menu.dyeStoredDirect)
|
||||
set(value) {}
|
||||
|
||||
override fun innerRenderTooltips(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {
|
||||
val list = getTooltipFromItem(minecraft!!, recipe.output)
|
||||
val list = getTooltipFromItem(minecraft!!, recipe.value.output)
|
||||
|
||||
recipe.dyes.forEach {
|
||||
recipe.value.dyes.forEach {
|
||||
val (dye, amount) = it
|
||||
|
||||
if (amount == 1)
|
||||
|
@ -108,8 +108,8 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
|
||||
return this@EditablePanel.mouseDragged(p_94740_, p_94741_, p_94742_, p_94743_, p_94744_)
|
||||
}
|
||||
|
||||
override fun mouseScrolled(p_94734_: Double, p_94735_: Double, p_94736_: Double): Boolean {
|
||||
return this@EditablePanel.mouseScrolled(p_94734_, p_94735_, p_94736_)
|
||||
override fun mouseScrolled(mouseX: Double, mouseY: Double, scrollX: Double, scrollY: Double): Boolean {
|
||||
return this@EditablePanel.mouseScrolled(mouseX, mouseY, scrollY)
|
||||
}
|
||||
|
||||
override fun keyPressed(p_94745_: Int, p_94746_: Int, p_94747_: Int): Boolean {
|
||||
|
@ -169,14 +169,16 @@ class EntityRendererPanel<out S : Screen> @JvmOverloads constructor(
|
||||
return
|
||||
}
|
||||
|
||||
val renderX = width.toInt() / 2
|
||||
val renderY = (height * 0.9f).toInt()
|
||||
val renderX = this.width.toInt() / 2
|
||||
val renderY = (this.height * 0.9f).toInt()
|
||||
|
||||
InventoryScreen.renderEntityInInventoryFollowsMouse(
|
||||
graphics,
|
||||
renderX,
|
||||
renderY,
|
||||
this.width.toInt(), this.height.toInt(),
|
||||
renderScale,
|
||||
0f,
|
||||
absoluteX.toInt() + renderX - mouseX,
|
||||
absoluteY + height * 0.15f - mouseY,
|
||||
entity
|
||||
|
@ -46,8 +46,8 @@ class Panel2Widget<out S: Screen, out P : EditablePanel<S>>(
|
||||
return panel.mouseDraggedChecked(p_94740_, p_94741_, p_94742_, p_94743_, p_94744_)
|
||||
}
|
||||
|
||||
override fun mouseScrolled(p_94734_: Double, p_94735_: Double, p_94736_: Double): Boolean {
|
||||
return panel.mouseScrolledChecked(p_94734_, p_94735_, p_94736_)
|
||||
override fun mouseScrolled(mouseX: Double, mouseY: Double, scrollX: Double, scrollY: Double): Boolean {
|
||||
return panel.mouseScrolledChecked(mouseX, mouseY, scrollY)
|
||||
}
|
||||
|
||||
override fun keyPressed(p_94745_: Int, p_94746_: Int, p_94747_: Int): Boolean {
|
||||
|
@ -33,11 +33,6 @@ open class EditBoxPanel<out S : Screen>(
|
||||
new_widget.value = old_widget.value
|
||||
}
|
||||
|
||||
override fun tickInner() {
|
||||
super.tickInner()
|
||||
widget?.tick()
|
||||
}
|
||||
|
||||
override fun configureNew(widget: EditBox, recreation: Boolean) {
|
||||
widget.isFocused = isFocusedThis
|
||||
}
|
||||
|
@ -36,7 +36,8 @@ fun onCuriosSlotModifiersUpdated(event: SlotModifiersUpdatedEvent) {
|
||||
}
|
||||
|
||||
fun openCuriosScreen(carriedStack: ItemStack = ItemStack.EMPTY) {
|
||||
if (FMLEnvironment.dist.isClient) NetworkHandler.INSTANCE.send(PacketDistributor.SERVER.noArg(), CPacketOpenCurios(carriedStack))
|
||||
TODO()
|
||||
// if (FMLEnvironment.dist.isClient) NetworkHandler.INSTANCE.send(PacketDistributor.SERVER.noArg(), CPacketOpenCurios(carriedStack))
|
||||
}
|
||||
|
||||
private fun Player.getCuriosSlotsImpl(): List<PlayerSlot<Slot, Slot>> {
|
||||
|
@ -14,14 +14,15 @@ import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.MenuType
|
||||
import net.minecraft.world.inventory.Slot
|
||||
import net.minecraft.world.item.crafting.CraftingRecipe
|
||||
import net.minecraft.world.item.crafting.RecipeHolder
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.core.toImmutableList
|
||||
import ru.dbotthepony.mc.otm.menu.ExopackInventoryMenu
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class ExopackInventoryTransferHandler(private val helper: IRecipeTransferHandlerHelper) : IRecipeTransferHandler<ExopackInventoryMenu, CraftingRecipe> {
|
||||
private val transfer = helper.createUnregisteredRecipeTransferHandler(object : IRecipeTransferInfo<ExopackInventoryMenu, CraftingRecipe> {
|
||||
class ExopackInventoryTransferHandler(private val helper: IRecipeTransferHandlerHelper) : IRecipeTransferHandler<ExopackInventoryMenu, RecipeHolder<CraftingRecipe>> {
|
||||
private val transfer = helper.createUnregisteredRecipeTransferHandler(object : IRecipeTransferInfo<ExopackInventoryMenu, RecipeHolder<CraftingRecipe>> {
|
||||
override fun getContainerClass(): Class<out ExopackInventoryMenu> {
|
||||
return ExopackInventoryMenu::class.java
|
||||
}
|
||||
@ -30,24 +31,24 @@ class ExopackInventoryTransferHandler(private val helper: IRecipeTransferHandler
|
||||
return Optional.empty()
|
||||
}
|
||||
|
||||
override fun getRecipeType(): mezz.jei.api.recipe.RecipeType<CraftingRecipe> {
|
||||
override fun getRecipeType(): mezz.jei.api.recipe.RecipeType<RecipeHolder<CraftingRecipe>> {
|
||||
return RecipeTypes.CRAFTING
|
||||
}
|
||||
|
||||
override fun canHandle(container: ExopackInventoryMenu, recipe: CraftingRecipe): Boolean {
|
||||
override fun canHandle(container: ExopackInventoryMenu, recipe: RecipeHolder<CraftingRecipe>): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getRecipeSlots(
|
||||
container: ExopackInventoryMenu,
|
||||
recipe: CraftingRecipe
|
||||
recipe: RecipeHolder<CraftingRecipe>
|
||||
): List<Slot> {
|
||||
return container.craftingSlots
|
||||
}
|
||||
|
||||
override fun getInventorySlots(
|
||||
container: ExopackInventoryMenu,
|
||||
recipe: CraftingRecipe
|
||||
recipe: RecipeHolder<CraftingRecipe>
|
||||
): List<Slot> {
|
||||
return container.playerInventorySlots
|
||||
}
|
||||
@ -61,7 +62,7 @@ class ExopackInventoryTransferHandler(private val helper: IRecipeTransferHandler
|
||||
return Optional.empty()
|
||||
}
|
||||
|
||||
override fun getRecipeType(): mezz.jei.api.recipe.RecipeType<CraftingRecipe> {
|
||||
override fun getRecipeType(): mezz.jei.api.recipe.RecipeType<RecipeHolder<CraftingRecipe>> {
|
||||
return RecipeTypes.CRAFTING
|
||||
}
|
||||
|
||||
@ -88,7 +89,7 @@ class ExopackInventoryTransferHandler(private val helper: IRecipeTransferHandler
|
||||
|
||||
override fun transferRecipe(
|
||||
container: ExopackInventoryMenu,
|
||||
recipe: CraftingRecipe,
|
||||
recipe: RecipeHolder<CraftingRecipe>,
|
||||
recipeSlots: IRecipeSlotsView,
|
||||
player: Player,
|
||||
maxTransfer: Boolean,
|
||||
|
@ -87,9 +87,9 @@ class JEIPlugin : IModPlugin {
|
||||
override fun registerRecipes(registration: IRecipeRegistration) {
|
||||
val level = minecraft.level ?: throw NullPointerException("No ClientLevel. OLOLOLOLOLOLO")
|
||||
|
||||
registration.addRecipes(PlatePressRecipeCategory.recipeType, level.recipeManager.getAllRecipesFor(MRecipes.PLATE_PRESS).filter { !it.isIncomplete })
|
||||
registration.addRecipes(PainterRecipeCategory.recipeType, level.recipeManager.getAllRecipesFor(MRecipes.PAINTER).filter { !it.isIncomplete })
|
||||
registration.addRecipes(MatterEntanglerRecipeCategory.recipeType, level.recipeManager.getAllRecipesFor(MRecipes.MATTER_ENTANGLER).filter { !it.isIncomplete })
|
||||
registration.addRecipes(PlatePressRecipeCategory.recipeType, level.recipeManager.getAllRecipesFor(MRecipes.PLATE_PRESS).filter { !it.value.isIncomplete }.map { it.value })
|
||||
registration.addRecipes(PainterRecipeCategory.recipeType, level.recipeManager.getAllRecipesFor(MRecipes.PAINTER).filter { !it.value.isIncomplete }.map { it.value })
|
||||
registration.addRecipes(MatterEntanglerRecipeCategory.recipeType, level.recipeManager.getAllRecipesFor(MRecipes.MATTER_ENTANGLER).filter { !it.value.isIncomplete }.map { it.value })
|
||||
}
|
||||
|
||||
override fun registerRecipeTransferHandlers(registration: IRecipeTransferRegistration) {
|
||||
|
@ -13,15 +13,13 @@ import net.minecraft.world.inventory.InventoryMenu
|
||||
import net.minecraft.world.inventory.Slot
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Items
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import net.minecraftforge.event.network.CustomPayloadEvent
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
|
||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
||||
import ru.dbotthepony.mc.otm.menu.MatterySlot
|
||||
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
||||
import ru.dbotthepony.mc.otm.network.packetHandled
|
||||
import ru.dbotthepony.mc.otm.network.sender
|
||||
import java.util.*
|
||||
import java.util.function.Supplier
|
||||
|
||||
@ -226,8 +224,7 @@ class InventoryScrollPacket(val scroll: Int) : MatteryPacket {
|
||||
}.scroll = scroll
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
play(context.sender ?: throw IllegalStateException("Illegal side"))
|
||||
}
|
||||
|
||||
|
@ -2,23 +2,14 @@ package ru.dbotthepony.mc.otm.container
|
||||
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.ListTag
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraftforge.common.util.INBTSerializable
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.core.nbt.map
|
||||
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
||||
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
||||
import ru.dbotthepony.mc.otm.core.nbt.set
|
||||
import java.util.Arrays
|
||||
import java.util.LinkedList
|
||||
import java.util.*
|
||||
import java.util.function.Consumer
|
||||
import java.util.function.Supplier
|
||||
|
||||
class ItemFilter(
|
||||
val size: Int,
|
||||
|
@ -206,8 +206,8 @@ fun FriendlyByteBuf.readItemType(): Item {
|
||||
return ForgeRegistries.ITEMS.getValue(readInt()) ?: Items.AIR
|
||||
}
|
||||
|
||||
fun InputStream.readItemType(sizeLimit: NbtAccounter? = null): Item {
|
||||
return ForgeRegistries.ITEMS.getValue(readVarIntLE(sizeLimit)) ?: Items.AIR
|
||||
fun InputStream.readItemType(): Item {
|
||||
return ForgeRegistries.ITEMS.getValue(readVarIntLE()) ?: Items.AIR
|
||||
}
|
||||
|
||||
operator fun <T : Comparable<T>> StateHolder<*, *>.get(property: Property<T>): T {
|
||||
|
@ -699,10 +699,9 @@ class Decimal private constructor(val mag: BigInteger, marker: Nothing?) : Numbe
|
||||
fun FriendlyByteBuf.readDecimal() = Decimal.read(this)
|
||||
fun FriendlyByteBuf.writeDecimal(value: Decimal) = value.write(this)
|
||||
|
||||
fun InputStream.readDecimal(sizeLimit: NbtAccounter = NbtAccounter(512L)): Decimal {
|
||||
val size = readVarIntLE(sizeLimit)
|
||||
fun InputStream.readDecimal(): Decimal {
|
||||
val size = readVarIntLE()
|
||||
require(size >= 0) { "Negative payload size: $size" }
|
||||
sizeLimit.accountBytes(size.toLong())
|
||||
val bytes = ByteArray(size)
|
||||
read(bytes)
|
||||
return Decimal.fromByteArray(bytes)
|
||||
|
@ -117,13 +117,13 @@ fun CompoundTag.putJson(key: String, json: JsonElement) {
|
||||
putByteArray(key, bytes.array.copyOfRange(0, bytes.length))
|
||||
}
|
||||
|
||||
fun CompoundTag.getJson(key: String, sizeLimit: NbtAccounter = NbtAccounter.UNLIMITED): JsonElement? {
|
||||
fun CompoundTag.getJson(key: String, sizeLimit: NbtAccounter = NbtAccounter(1 shl 18, 512)): JsonElement? {
|
||||
val bytes = getByteArray(key)
|
||||
|
||||
if (bytes.isEmpty())
|
||||
return null
|
||||
|
||||
return FastByteArrayInputStream(bytes).readBinaryJson(sizeLimit)
|
||||
return FastByteArrayInputStream(bytes).readBinaryJson()
|
||||
}
|
||||
|
||||
fun CompoundTag.getBoolean(index: String, orElse: Boolean): Boolean {
|
||||
|
@ -19,7 +19,7 @@ private enum class BinaryElementType(private val predicate: Predicate<JsonElemen
|
||||
override fun write(stream: OutputStream, element: JsonElement) {
|
||||
}
|
||||
|
||||
override fun read(stream: InputStream, accounter: NbtAccounter): JsonElement {
|
||||
override fun read(stream: InputStream): JsonElement {
|
||||
return JsonNull.INSTANCE
|
||||
}
|
||||
},
|
||||
@ -29,8 +29,7 @@ private enum class BinaryElementType(private val predicate: Predicate<JsonElemen
|
||||
stream.writeDouble(element.asDouble)
|
||||
}
|
||||
|
||||
override fun read(stream: InputStream, accounter: NbtAccounter): JsonElement {
|
||||
accounter.accountBytes(8L)
|
||||
override fun read(stream: InputStream): JsonElement {
|
||||
return JsonPrimitive(stream.readDouble())
|
||||
}
|
||||
},
|
||||
@ -40,8 +39,7 @@ private enum class BinaryElementType(private val predicate: Predicate<JsonElemen
|
||||
stream.write(if (element.asBoolean) 1 else 0)
|
||||
}
|
||||
|
||||
override fun read(stream: InputStream, accounter: NbtAccounter): JsonElement {
|
||||
accounter.accountBytes(1L)
|
||||
override fun read(stream: InputStream): JsonElement {
|
||||
return JsonPrimitive(stream.read() > 0)
|
||||
}
|
||||
},
|
||||
@ -56,8 +54,8 @@ private enum class BinaryElementType(private val predicate: Predicate<JsonElemen
|
||||
throw IllegalArgumentException("Unknown number type: ${it::class.qualifiedName}")
|
||||
}
|
||||
|
||||
override fun read(stream: InputStream, accounter: NbtAccounter): JsonElement {
|
||||
return JsonPrimitive(stream.readVarLongLE(accounter))
|
||||
override fun read(stream: InputStream): JsonElement {
|
||||
return JsonPrimitive(stream.readVarLongLE())
|
||||
}
|
||||
},
|
||||
|
||||
@ -66,8 +64,8 @@ private enum class BinaryElementType(private val predicate: Predicate<JsonElemen
|
||||
stream.writeBinaryString(element.asString)
|
||||
}
|
||||
|
||||
override fun read(stream: InputStream, accounter: NbtAccounter): JsonElement {
|
||||
return JsonPrimitive(stream.readBinaryString(accounter))
|
||||
override fun read(stream: InputStream): JsonElement {
|
||||
return JsonPrimitive(stream.readBinaryString())
|
||||
}
|
||||
},
|
||||
|
||||
@ -76,8 +74,8 @@ private enum class BinaryElementType(private val predicate: Predicate<JsonElemen
|
||||
writeArray(stream, element, OutputStream::writeBinaryJson)
|
||||
}
|
||||
|
||||
override fun read(stream: InputStream, accounter: NbtAccounter): JsonElement {
|
||||
return readArray(stream, accounter, InputStream::readBinaryJson)
|
||||
override fun read(stream: InputStream): JsonElement {
|
||||
return readArray(stream, InputStream::readBinaryJson)
|
||||
}
|
||||
},
|
||||
|
||||
@ -92,8 +90,8 @@ private enum class BinaryElementType(private val predicate: Predicate<JsonElemen
|
||||
}
|
||||
}
|
||||
|
||||
override fun read(stream: InputStream, accounter: NbtAccounter): JsonElement {
|
||||
val count = stream.readVarIntLE(accounter)
|
||||
override fun read(stream: InputStream): JsonElement {
|
||||
val count = stream.readVarIntLE()
|
||||
|
||||
if (count == 0) return JsonObject()
|
||||
if (count < 0) throw JsonSyntaxException("Tried to read json object with $count elements in it")
|
||||
@ -102,13 +100,13 @@ private enum class BinaryElementType(private val predicate: Predicate<JsonElemen
|
||||
|
||||
for (i in 0 until count) {
|
||||
val key = try {
|
||||
stream.readBinaryString(accounter)
|
||||
stream.readBinaryString()
|
||||
} catch(err: Throwable) {
|
||||
throw JsonSyntaxException("Reading json object at $i", err)
|
||||
}
|
||||
|
||||
try {
|
||||
build.add(key, stream.readBinaryJson(accounter))
|
||||
build.add(key, stream.readBinaryJson())
|
||||
} catch(err: Throwable) {
|
||||
throw JsonSyntaxException("Reading json object at $i with name $key", err)
|
||||
}
|
||||
@ -123,8 +121,8 @@ private enum class BinaryElementType(private val predicate: Predicate<JsonElemen
|
||||
writeArray(stream, element, DOUBLE::write)
|
||||
}
|
||||
|
||||
override fun read(stream: InputStream, accounter: NbtAccounter): JsonElement {
|
||||
return readArray(stream, accounter, DOUBLE::read)
|
||||
override fun read(stream: InputStream): JsonElement {
|
||||
return readArray(stream, DOUBLE::read)
|
||||
}
|
||||
},
|
||||
|
||||
@ -133,8 +131,8 @@ private enum class BinaryElementType(private val predicate: Predicate<JsonElemen
|
||||
writeArray(stream, element, INT::write)
|
||||
}
|
||||
|
||||
override fun read(stream: InputStream, accounter: NbtAccounter): JsonElement {
|
||||
return readArray(stream, accounter, INT::read)
|
||||
override fun read(stream: InputStream): JsonElement {
|
||||
return readArray(stream, INT::read)
|
||||
}
|
||||
},
|
||||
|
||||
@ -143,8 +141,8 @@ private enum class BinaryElementType(private val predicate: Predicate<JsonElemen
|
||||
writeArray(stream, element, BOOLEAN::write)
|
||||
}
|
||||
|
||||
override fun read(stream: InputStream, accounter: NbtAccounter): JsonElement {
|
||||
return readArray(stream, accounter, BOOLEAN::read)
|
||||
override fun read(stream: InputStream): JsonElement {
|
||||
return readArray(stream, BOOLEAN::read)
|
||||
}
|
||||
},
|
||||
|
||||
@ -153,8 +151,8 @@ private enum class BinaryElementType(private val predicate: Predicate<JsonElemen
|
||||
writeArray(stream, element, NULL::write)
|
||||
}
|
||||
|
||||
override fun read(stream: InputStream, accounter: NbtAccounter): JsonElement {
|
||||
return readArray(stream, accounter, NULL::read)
|
||||
override fun read(stream: InputStream): JsonElement {
|
||||
return readArray(stream, NULL::read)
|
||||
}
|
||||
};
|
||||
|
||||
@ -167,26 +165,25 @@ private enum class BinaryElementType(private val predicate: Predicate<JsonElemen
|
||||
}
|
||||
}
|
||||
|
||||
protected fun readArray(stream: InputStream, accounter: NbtAccounter, reader: (InputStream, NbtAccounter) -> JsonElement): JsonArray {
|
||||
val count = stream.readVarIntLE(accounter)
|
||||
protected fun readArray(stream: InputStream, reader: (InputStream) -> JsonElement): JsonArray {
|
||||
val count = stream.readVarIntLE()
|
||||
|
||||
if (count == 0) return JsonArray()
|
||||
if (count < 0) throw JsonSyntaxException("Tried to read json array with $count elements in it")
|
||||
|
||||
return JsonArray(count).also {
|
||||
for (i in 0 until count) it.add(reader.invoke(stream, accounter))
|
||||
for (i in 0 until count) it.add(reader.invoke(stream))
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun write(stream: OutputStream, element: JsonElement)
|
||||
abstract fun read(stream: InputStream, accounter: NbtAccounter): JsonElement
|
||||
abstract fun read(stream: InputStream): JsonElement
|
||||
|
||||
companion object {
|
||||
val cached: ImmutableList<BinaryElementType> = ImmutableList.of(
|
||||
NULL, DOUBLE, BOOLEAN, INT, STRING, OBJECT,
|
||||
DOUBLE_ARRAY, INT_ARRAY, BOOLEAN_ARRAY, ARRAY)
|
||||
|
||||
val ordered: ImmutableList<BinaryElementType> = ImmutableList.copyOf(values())
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,9 +205,8 @@ fun OutputStream.writeBinaryJson(element: JsonElement) {
|
||||
/**
|
||||
* Reads json in binary form from stream
|
||||
*/
|
||||
fun InputStream.readBinaryJson(sizeLimit: NbtAccounter = NbtAccounter(1L shl 18 /* 256 KiB */)): JsonElement {
|
||||
sizeLimit.accountBytes(1L)
|
||||
fun InputStream.readBinaryJson(): JsonElement {
|
||||
val id = read() - 1
|
||||
val reader = BinaryElementType.ordered.getOrNull(id) ?: throw JsonParseException("Unknown element type ${id + 1}")
|
||||
return reader.read(this, sizeLimit)
|
||||
val reader = BinaryElementType.entries.getOrNull(id) ?: throw JsonParseException("Unknown element type ${id + 1}")
|
||||
return reader.read(this)
|
||||
}
|
||||
|
@ -12,8 +12,8 @@ import net.minecraft.nbt.NbtAccounter
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.network.chat.Component
|
||||
|
||||
fun FriendlyByteBuf.readBinaryJson(sizeLimit: NbtAccounter = NbtAccounter(1L shl 18)): JsonElement {
|
||||
return ByteBufInputStream(this).readBinaryJson(sizeLimit)
|
||||
fun FriendlyByteBuf.readBinaryJson(): JsonElement {
|
||||
return ByteBufInputStream(this).readBinaryJson()
|
||||
}
|
||||
|
||||
fun FriendlyByteBuf.writeBinaryJson(value: JsonElement) {
|
||||
@ -25,13 +25,13 @@ fun <S> FriendlyByteBuf.writeBinaryJsonWithCodec(codec: Codec<S>, value: S) {
|
||||
.get().map({ it }, { throw EncoderException("Failed to encode input data: ${it.message()}") }))
|
||||
}
|
||||
|
||||
fun <S> FriendlyByteBuf.readBinaryJsonWithCodec(codec: Codec<S>, sizeLimit: NbtAccounter = NbtAccounter(1L shl 18)): S {
|
||||
return codec.decode(JsonOps.INSTANCE, readBinaryJson(sizeLimit))
|
||||
fun <S> FriendlyByteBuf.readBinaryJsonWithCodec(codec: Codec<S>): S {
|
||||
return codec.decode(JsonOps.INSTANCE, readBinaryJson())
|
||||
.get().map({ it.first }, { throw DecoderException("Failed to decode data from network: ${it.message()}") })
|
||||
}
|
||||
|
||||
fun <S> FriendlyByteBuf.readBinaryJsonWithCodecIndirect(codec: Codec<S>, sizeLimit: NbtAccounter = NbtAccounter(1L shl 18)): DataResult<S> {
|
||||
return codec.decode(JsonOps.INSTANCE, readBinaryJson(sizeLimit)).map { it.first }
|
||||
fun <S> FriendlyByteBuf.readBinaryJsonWithCodecIndirect(codec: Codec<S>): DataResult<S> {
|
||||
return codec.decode(JsonOps.INSTANCE, readBinaryJson()).map { it.first }
|
||||
}
|
||||
|
||||
fun FriendlyByteBuf.readBinaryComponent(): Component {
|
||||
|
@ -30,9 +30,9 @@ fun OutputStream.writeNbt(value: CompoundTag) {
|
||||
}
|
||||
}
|
||||
|
||||
fun InputStream.readNbt(accounter: NbtAccounter = NbtAccounter(1L shl 18 /* 256 KiB */)): CompoundTag {
|
||||
fun InputStream.readNbt(): CompoundTag {
|
||||
return try {
|
||||
NbtIo.read(if (this is DataInputStream) this else DataInputStream(this), accounter)
|
||||
NbtIo.read(if (this is DataInputStream) this else DataInputStream(this))
|
||||
} catch (ioexception: IOException) {
|
||||
throw EncoderException(ioexception)
|
||||
}
|
||||
@ -62,19 +62,16 @@ fun OutputStream.writeItem(itemStack: ItemStack, limitedTag: Boolean = true) {
|
||||
}
|
||||
}
|
||||
|
||||
fun InputStream.readItem(sizeLimit: NbtAccounter = NbtAccounter(1L shl 18 /* 256 KiB */)): ItemStack {
|
||||
sizeLimit.accountBytes(1L)
|
||||
|
||||
fun InputStream.readItem(): ItemStack {
|
||||
if (read() == 0) {
|
||||
return ItemStack.EMPTY
|
||||
}
|
||||
|
||||
sizeLimit.accountBytes(9L)
|
||||
val item = (ForgeRegistries.ITEMS as ForgeRegistry<Item>).getValue(readInt())
|
||||
val itemStack = ItemStack(item, readInt())
|
||||
|
||||
if (read() != 0) {
|
||||
itemStack.readShareTag(readNbt(sizeLimit))
|
||||
itemStack.readShareTag(readNbt())
|
||||
}
|
||||
|
||||
return itemStack
|
||||
@ -99,7 +96,7 @@ fun OutputStream.writeFluidStack(value: FluidStack) {
|
||||
}
|
||||
}
|
||||
|
||||
fun InputStream.readFluidStack(sizeLimit: NbtAccounter = NbtAccounter(1L shl 14 /* 16 KiB */)): FluidStack {
|
||||
fun InputStream.readFluidStack(): FluidStack {
|
||||
if (read() == 0) {
|
||||
return FluidStack.EMPTY
|
||||
} else {
|
||||
@ -108,7 +105,7 @@ fun InputStream.readFluidStack(sizeLimit: NbtAccounter = NbtAccounter(1L shl 14
|
||||
val amount = readInt()
|
||||
|
||||
if (read() > 0) {
|
||||
return FluidStack(fluid, amount, readNbt(sizeLimit))
|
||||
return FluidStack(fluid, amount, readNbt())
|
||||
} else {
|
||||
return FluidStack(fluid, amount)
|
||||
}
|
||||
@ -122,11 +119,10 @@ fun OutputStream.writeBigDecimal(value: BigDecimal) {
|
||||
write(bytes)
|
||||
}
|
||||
|
||||
fun InputStream.readBigDecimal(sizeLimit: NbtAccounter = NbtAccounter(512L)): BigDecimal {
|
||||
fun InputStream.readBigDecimal(): BigDecimal {
|
||||
val scale = readInt()
|
||||
val size = readVarIntLE(sizeLimit)
|
||||
val size = readVarIntLE()
|
||||
require(size >= 0) { "Negative payload size: $size" }
|
||||
sizeLimit.accountBytes(size.toLong() + 4L)
|
||||
val bytes = ByteArray(size)
|
||||
read(bytes)
|
||||
return BigDecimal(BigInteger(bytes), scale)
|
||||
@ -215,8 +211,7 @@ fun InputStream.readFloat() = Float.fromBits(readInt())
|
||||
fun OutputStream.writeDouble(value: Double) = writeLong(value.toBits())
|
||||
fun InputStream.readDouble() = Double.fromBits(readLong())
|
||||
|
||||
fun InputStream.readVarIntLE(sizeLimit: NbtAccounter? = null): Int {
|
||||
sizeLimit?.accountBytes(1L)
|
||||
fun InputStream.readVarIntLE(): Int {
|
||||
val readFirst = read()
|
||||
|
||||
if (readFirst < 0) {
|
||||
@ -234,7 +229,6 @@ fun InputStream.readVarIntLE(sizeLimit: NbtAccounter? = null): Int {
|
||||
|
||||
while (nextBit != 0) {
|
||||
result = result or (read shl i)
|
||||
sizeLimit?.accountBytes(1L)
|
||||
read = read()
|
||||
|
||||
if (read < 0) {
|
||||
@ -314,10 +308,9 @@ fun OutputStream.writeVarLongLE(value: Long) {
|
||||
}
|
||||
}
|
||||
|
||||
fun InputStream.readBinaryString(sizeLimit: NbtAccounter = NbtAccounter(1L shl 18 /* 256 KiB */)): String {
|
||||
fun InputStream.readBinaryString(): String {
|
||||
val size = readVarIntLE()
|
||||
require(size >= 0) { "Negative payload size: $size" }
|
||||
sizeLimit.accountBytes(size.toLong())
|
||||
val bytes = ByteArray(size)
|
||||
read(bytes)
|
||||
return bytes.decodeToString()
|
||||
@ -329,8 +322,8 @@ fun OutputStream.writeBinaryString(input: String) {
|
||||
write(bytes)
|
||||
}
|
||||
|
||||
fun InputStream.readResourceLocation(sizeLimit: NbtAccounter = NbtAccounter(1L shl 18 /* 256 KiB */)): ResourceLocation {
|
||||
return ResourceLocation(readBinaryString(sizeLimit), readBinaryString(sizeLimit))
|
||||
fun InputStream.readResourceLocation(): ResourceLocation {
|
||||
return ResourceLocation(readBinaryString(), readBinaryString())
|
||||
}
|
||||
|
||||
fun OutputStream.writeResourceLocation(value: ResourceLocation) {
|
||||
|
@ -32,7 +32,7 @@ import kotlin.reflect.KClass
|
||||
* Also provides [copy] and [compare] methods
|
||||
*/
|
||||
interface IStreamCodec<V> {
|
||||
fun read(stream: DataInputStream, sizeLimit: NbtAccounter = NbtAccounter(1L shl 18 /* 256 KiB */)): V
|
||||
fun read(stream: DataInputStream): V
|
||||
fun write(stream: DataOutputStream, value: V)
|
||||
|
||||
/**
|
||||
@ -51,7 +51,7 @@ interface IStreamCodec<V> {
|
||||
}
|
||||
|
||||
class StreamCodec<V>(
|
||||
private val reader: (stream: DataInputStream, sizeLimit: NbtAccounter) -> V,
|
||||
private val reader: (stream: DataInputStream) -> V,
|
||||
private val writer: (stream: DataOutputStream, value: V) -> Unit,
|
||||
private val copier: ((value: V) -> V) = { it },
|
||||
private val comparator: ((a: V, b: V) -> Boolean) = { a, b -> a == b }
|
||||
@ -62,12 +62,11 @@ class StreamCodec<V>(
|
||||
writer: (stream: DataOutputStream, value: V) -> Unit,
|
||||
copier: ((value: V) -> V) = { it },
|
||||
comparator: ((a: V, b: V) -> Boolean) = { a, b -> a == b }
|
||||
) : this({ stream, sizeLimit -> sizeLimit.accountBytes(payloadSize); reader.invoke(stream) }, writer, copier, comparator)
|
||||
) : this({ stream -> reader.invoke(stream) }, writer, copier, comparator)
|
||||
|
||||
val nullable = object : IStreamCodec<V?> {
|
||||
override fun read(stream: DataInputStream, sizeLimit: NbtAccounter): V? {
|
||||
sizeLimit.accountBytes(1L)
|
||||
return if (stream.read() == 0) null else reader.invoke(stream, sizeLimit)
|
||||
override fun read(stream: DataInputStream): V? {
|
||||
return if (stream.read() == 0) null else reader.invoke(stream)
|
||||
}
|
||||
|
||||
override fun write(stream: DataOutputStream, value: V?) {
|
||||
@ -88,8 +87,8 @@ class StreamCodec<V>(
|
||||
}
|
||||
}
|
||||
|
||||
override fun read(stream: DataInputStream, sizeLimit: NbtAccounter): V {
|
||||
return reader.invoke(stream, sizeLimit)
|
||||
override fun read(stream: DataInputStream): V {
|
||||
return reader.invoke(stream)
|
||||
}
|
||||
|
||||
override fun write(stream: DataOutputStream, value: V) {
|
||||
@ -106,8 +105,8 @@ class StreamCodec<V>(
|
||||
}
|
||||
|
||||
class CollectionStreamCodec<E, C : MutableCollection<E>>(val elementCodec: IStreamCodec<E>, val collectionFactory: (Int) -> C) : IStreamCodec<C> {
|
||||
override fun read(stream: DataInputStream, sizeLimit: NbtAccounter): C {
|
||||
val size = stream.readVarIntLE(sizeLimit)
|
||||
override fun read(stream: DataInputStream): C {
|
||||
val size = stream.readVarIntLE()
|
||||
|
||||
if (size <= 0) {
|
||||
return collectionFactory.invoke(0)
|
||||
@ -116,7 +115,7 @@ class CollectionStreamCodec<E, C : MutableCollection<E>>(val elementCodec: IStre
|
||||
val collection = collectionFactory.invoke(size)
|
||||
|
||||
for (i in 0 until size) {
|
||||
collection.add(elementCodec.read(stream, sizeLimit))
|
||||
collection.add(elementCodec.read(stream))
|
||||
}
|
||||
|
||||
return collection
|
||||
@ -134,7 +133,7 @@ class CollectionStreamCodec<E, C : MutableCollection<E>>(val elementCodec: IStre
|
||||
}
|
||||
}
|
||||
|
||||
val NullValueCodec = StreamCodec({ _, _ -> null }, { _, _ -> })
|
||||
val NullValueCodec = StreamCodec({ _ -> null }, { _, _ -> })
|
||||
val BooleanValueCodec = StreamCodec(DataInputStream::readBoolean, 1L, DataOutputStream::writeBoolean) { a, b -> a == b }
|
||||
val ByteValueCodec = StreamCodec(DataInputStream::readByte, 1L, { s, v -> s.writeByte(v.toInt()) }) { a, b -> a == b }
|
||||
val ShortValueCodec = StreamCodec(DataInputStream::readShort, 2L, { s, v -> s.writeShort(v.toInt()) }) { a, b -> a == b }
|
||||
@ -147,18 +146,18 @@ val FluidStackValueCodec = StreamCodec(DataInputStream::readFluidStack, DataOutp
|
||||
val ItemValueCodec = StreamCodec(DataInputStream::readItemType, DataOutputStream::writeItemType) { a, b -> a === b }
|
||||
val DecimalValueCodec = StreamCodec(DataInputStream::readDecimal, DataOutputStream::writeDecimal)
|
||||
val BigDecimalValueCodec = StreamCodec(DataInputStream::readBigDecimal, DataOutputStream::writeBigDecimal)
|
||||
val UUIDValueCodec = StreamCodec({ s, a -> a.accountBytes(8L); UUID(s.readLong(), s.readLong()) }, { s, v -> s.writeLong(v.mostSignificantBits); s.writeLong(v.leastSignificantBits) })
|
||||
val UUIDValueCodec = StreamCodec({ s -> UUID(s.readLong(), s.readLong()) }, { s, v -> s.writeLong(v.mostSignificantBits); s.writeLong(v.leastSignificantBits) })
|
||||
val VarIntValueCodec = StreamCodec(DataInputStream::readVarIntLE, DataOutputStream::writeVarIntLE) { a, b -> a == b }
|
||||
val VarLongValueCodec = StreamCodec(DataInputStream::readVarLongLE, DataOutputStream::writeVarLongLE) { a, b -> a == b }
|
||||
val BinaryStringCodec = StreamCodec(DataInputStream::readBinaryString, DataOutputStream::writeBinaryString)
|
||||
val ResourceLocationValueCodec = StreamCodec(DataInputStream::readResourceLocation, DataOutputStream::writeResourceLocation)
|
||||
|
||||
val RGBCodec: StreamCodec<RGBAColor> = StreamCodec(
|
||||
{ s, a -> a.accountBytes(12L); RGBAColor(s.readFloat(), s.readFloat(), s.readFloat()) },
|
||||
{ s -> RGBAColor(s.readFloat(), s.readFloat(), s.readFloat()) },
|
||||
{ s, v -> s.writeFloat(v.red); s.writeFloat(v.green); s.writeFloat(v.blue) })
|
||||
|
||||
val RGBACodec: StreamCodec<RGBAColor> = StreamCodec(
|
||||
{ s, a -> a.accountBytes(16L); RGBAColor(s.readFloat(), s.readFloat(), s.readFloat(), s.readFloat()) },
|
||||
{ s -> RGBAColor(s.readFloat(), s.readFloat(), s.readFloat(), s.readFloat()) },
|
||||
{ s, v -> s.writeFloat(v.red); s.writeFloat(v.green); s.writeFloat(v.blue); s.writeFloat(v.alpha) })
|
||||
|
||||
class EnumValueCodec<V : Enum<V>>(clazz: Class<out V>) : IStreamCodec<V>, Codec<V> {
|
||||
@ -168,8 +167,8 @@ class EnumValueCodec<V : Enum<V>>(clazz: Class<out V>) : IStreamCodec<V>, Codec<
|
||||
for (v in values) put(v.name, v)
|
||||
}
|
||||
|
||||
override fun read(stream: DataInputStream, sizeLimit: NbtAccounter): V {
|
||||
val id = stream.readVarIntLE(sizeLimit)
|
||||
override fun read(stream: DataInputStream): V {
|
||||
val id = stream.readVarIntLE()
|
||||
return values.getOrNull(id) ?: throw NoSuchElementException("No such enum with index $id")
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,9 @@ import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.DataResult
|
||||
import com.mojang.serialization.DynamicOps
|
||||
import com.mojang.serialization.JsonOps
|
||||
import io.netty.buffer.ByteBuf
|
||||
import io.netty.buffer.Unpooled
|
||||
import net.minecraft.advancements.AdvancementHolder
|
||||
import net.minecraft.data.recipes.FinishedRecipe
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
@ -21,7 +24,15 @@ import ru.dbotthepony.mc.otm.core.util.readBinaryJsonWithCodecIndirect
|
||||
import ru.dbotthepony.mc.otm.core.util.writeBinaryJsonWithCodec
|
||||
import kotlin.collections.ArrayDeque
|
||||
import kotlin.concurrent.getOrSet
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
/**
|
||||
* 1.20.2: Mojang FINALLY moved json IO of recipes to codecs
|
||||
*
|
||||
* ...but they forgot to do the same for Networking them, Ingredient does not have codec for network.
|
||||
*
|
||||
* Mojang.... Mojang never changes.
|
||||
*/
|
||||
class Codec2RecipeSerializer<S : Recipe<*>>(
|
||||
val empty: S?,
|
||||
codec: (Codec2RecipeSerializer<S>.Context) -> Codec<S>,
|
||||
@ -29,15 +40,45 @@ class Codec2RecipeSerializer<S : Recipe<*>>(
|
||||
constructor(supplier: (Codec2RecipeSerializer<S>.Context) -> Codec<S>) : this(null, supplier)
|
||||
|
||||
private class CurrentContext {
|
||||
val idStack = ArrayDeque<ResourceLocation>()
|
||||
var isNetwork = 0
|
||||
}
|
||||
|
||||
inner class Context {
|
||||
val id: ResourceLocation
|
||||
get() = checkNotNull(context.idStack.lastOrNull()) { "Not currently deserializing recipe" }
|
||||
|
||||
val ingredients: Codec<Ingredient> get() = ActualIngredientCodec
|
||||
|
||||
fun <P : Recipe<*>> wrap(serializer: RecipeSerializer<P>): Codec<P> {
|
||||
return object : Codec<P> {
|
||||
override fun <T : Any?> encode(input: P, ops: DynamicOps<T>, prefix: T): DataResult<T> {
|
||||
if (context.isNetwork > 0) {
|
||||
val parent = Unpooled.buffer()
|
||||
val buff = FriendlyByteBuf(parent)
|
||||
serializer.toNetwork(buff, input)
|
||||
return DataResult.success(ops.createByteList(parent.nioBuffer()))
|
||||
} else {
|
||||
return serializer.codec().encode(input, ops, prefix)
|
||||
}
|
||||
}
|
||||
|
||||
override fun <T : Any?> decode(ops: DynamicOps<T>, input: T): DataResult<Pair<P, T>> {
|
||||
if (context.isNetwork > 0) {
|
||||
return ops.getByteBuffer(input).flatMap {
|
||||
val parent = Unpooled.buffer()
|
||||
val buff = FriendlyByteBuf(parent)
|
||||
parent.writeBytes(it)
|
||||
parent.setIndex(0, 0)
|
||||
val read = serializer.fromNetwork(buff)
|
||||
|
||||
if (read == null)
|
||||
DataResult.error { "Unable to read parent recipe from network" }
|
||||
else
|
||||
DataResult.success(Pair(read, ops.empty()))
|
||||
}
|
||||
} else {
|
||||
return serializer.codec().decode(ops, input)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val codec = codec.invoke(Context())
|
||||
@ -56,45 +97,30 @@ class Codec2RecipeSerializer<S : Recipe<*>>(
|
||||
}
|
||||
}
|
||||
|
||||
override fun fromJson(id: ResourceLocation, data: JsonObject): S {
|
||||
try {
|
||||
context.idStack.addLast(id)
|
||||
|
||||
return decode(JsonOps.INSTANCE, data).get().map(
|
||||
{ it.first },
|
||||
{ empty ?: throw JsonSyntaxException("Failed to deserialize recipe from JSON: ${it.message()}") }
|
||||
)
|
||||
} finally {
|
||||
context.idStack.removeLast()
|
||||
}
|
||||
override fun codec(): Codec<S> {
|
||||
return this
|
||||
}
|
||||
|
||||
override fun fromNetwork(id: ResourceLocation, data: FriendlyByteBuf): S? {
|
||||
override fun fromNetwork(data: FriendlyByteBuf): S? {
|
||||
try {
|
||||
context.idStack.addLast(id)
|
||||
context.isNetwork++
|
||||
|
||||
return data.readBinaryJsonWithCodecIndirect(this)
|
||||
.resultOrPartial { LOGGER.error("Failed to read recipe $id from network: $it") }.orElse(null)
|
||||
.resultOrPartial { LOGGER.error("Failed to read recipe from network: $it") }.orElse(null)
|
||||
} finally {
|
||||
context.isNetwork--
|
||||
context.idStack.removeLast()
|
||||
}
|
||||
}
|
||||
|
||||
override fun toNetwork(data: FriendlyByteBuf, recipe: S) {
|
||||
try {
|
||||
context.idStack.addLast(recipe.id)
|
||||
context.isNetwork++
|
||||
|
||||
data.writeBinaryJsonWithCodec(this, recipe)
|
||||
} finally {
|
||||
context.isNetwork--
|
||||
context.idStack.removeLast()
|
||||
}
|
||||
}
|
||||
|
||||
fun toFinished(recipe: S): FinishedRecipe {
|
||||
fun toFinished(recipe: S, id: ResourceLocation): FinishedRecipe {
|
||||
return object : FinishedRecipe {
|
||||
override fun serializeRecipeData(p_125967_: JsonObject) {
|
||||
encode(recipe, JsonOps.INSTANCE, p_125967_).get().map(
|
||||
@ -111,19 +137,15 @@ class Codec2RecipeSerializer<S : Recipe<*>>(
|
||||
)
|
||||
}
|
||||
|
||||
override fun getId(): ResourceLocation {
|
||||
return recipe.id
|
||||
override fun id(): ResourceLocation {
|
||||
return id
|
||||
}
|
||||
|
||||
override fun getType(): RecipeSerializer<*> {
|
||||
override fun type(): RecipeSerializer<*> {
|
||||
return this@Codec2RecipeSerializer
|
||||
}
|
||||
|
||||
override fun serializeAdvancement(): JsonObject? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getAdvancementId(): ResourceLocation? {
|
||||
override fun advancement(): AdvancementHolder? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
@ -134,7 +156,7 @@ class Codec2RecipeSerializer<S : Recipe<*>>(
|
||||
return if (context.isNetwork > 0) {
|
||||
networkIngredientCodec.encode(input, ops, prefix)
|
||||
} else {
|
||||
IngredientCodec.encode(input, ops, prefix)
|
||||
Ingredient.CODEC.encode(input, ops, prefix)
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,7 +164,7 @@ class Codec2RecipeSerializer<S : Recipe<*>>(
|
||||
return if (context.isNetwork > 0) {
|
||||
networkIngredientCodec.decode(ops, input)
|
||||
} else {
|
||||
IngredientCodec.decode(ops, input)
|
||||
Ingredient.CODEC.decode(ops, input)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -156,8 +178,14 @@ class Codec2RecipeSerializer<S : Recipe<*>>(
|
||||
* since RecipeSerializers are expected to be stateless. [Codec2RecipeSerializer], however, is stateful (threading PoV).
|
||||
* To make it stateless, [ThreadLocal] is used.
|
||||
*/
|
||||
private val contextHolder = ThreadLocal<CurrentContext>()
|
||||
private val context: CurrentContext
|
||||
get() = contextHolder.getOrSet { CurrentContext() }
|
||||
private val context by object : ThreadLocal<CurrentContext>() {
|
||||
override fun initialValue(): CurrentContext {
|
||||
return CurrentContext()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private operator fun <T> ThreadLocal<T>.getValue(companion: Codec2RecipeSerializer.Companion, property: KProperty<*>): T {
|
||||
return get()
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
package ru.dbotthepony.mc.otm.data
|
||||
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import com.google.gson.JsonSyntaxException
|
||||
import com.mojang.serialization.Codec
|
||||
import net.minecraft.world.level.storage.loot.Serializer
|
||||
import ru.dbotthepony.mc.otm.core.fromJsonStrict
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.core.toJsonStrict
|
||||
|
||||
class Codec2Serializer<T : Any>(val codec: Codec<T>, val embed: Boolean = true) : Serializer<T> {
|
||||
override fun serialize(data: JsonObject, value: T, context: JsonSerializationContext) {
|
||||
if (embed) {
|
||||
val result = codec.toJsonStrict(value, data)
|
||||
|
||||
if (result !is JsonObject) {
|
||||
throw RuntimeException("Expected JsonObject from codec, got ${result::class.qualifiedName}")
|
||||
}
|
||||
|
||||
val keys = ArrayList(data.keySet())
|
||||
for (k in keys) data.remove(k)
|
||||
for ((k, v) in result.entrySet()) data[k] = v
|
||||
} else {
|
||||
data["value"] = codec.toJsonStrict(value)
|
||||
}
|
||||
}
|
||||
|
||||
override fun deserialize(data: JsonObject, context: JsonDeserializationContext): T {
|
||||
if (embed) {
|
||||
return codec.fromJsonStrict(data)
|
||||
} else {
|
||||
return codec.fromJsonStrict(data["value"] ?: throw JsonSyntaxException("Missing 'value' element"))
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
package ru.dbotthepony.mc.otm.data
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import com.mojang.datafixers.util.Pair
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.DataResult
|
||||
import com.mojang.serialization.DynamicOps
|
||||
import com.mojang.serialization.JsonOps
|
||||
import com.mojang.serialization.MapCodec
|
||||
import com.mojang.serialization.MapLike
|
||||
import com.mojang.serialization.RecordBuilder
|
||||
import net.minecraft.advancements.critereon.ContextAwarePredicate
|
||||
import net.minecraft.advancements.critereon.DeserializationContext
|
||||
import net.minecraft.advancements.critereon.EntityPredicate
|
||||
import ru.dbotthepony.mc.otm.core.fromJsonStrict
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.core.toJsonStrict
|
||||
import java.util.Optional
|
||||
import java.util.stream.Stream
|
||||
|
||||
class Codec2TriggerSerializer<S : Any>(supplier: (Codec2TriggerSerializer<S>.Context) -> Codec<S>) : Codec<S> {
|
||||
private val codec = supplier.invoke(Context())
|
||||
|
||||
override fun <T : Any> encode(input: S, ops: DynamicOps<T>, prefix: T): DataResult<T> {
|
||||
return codec.encode(input, ops, prefix)
|
||||
}
|
||||
|
||||
override fun <T : Any> decode(ops: DynamicOps<T>, input: T): DataResult<Pair<S, T>> {
|
||||
return codec.decode(ops, input)
|
||||
}
|
||||
|
||||
fun fromJson(element: JsonObject, player: Optional<ContextAwarePredicate>, context: DeserializationContext): S {
|
||||
try {
|
||||
Companion.context.get().addLast(ThreadContext(player, context))
|
||||
return codec.fromJsonStrict(element)
|
||||
} finally {
|
||||
Companion.context.get().removeLast()
|
||||
}
|
||||
}
|
||||
|
||||
fun toJson(value: S): JsonObject {
|
||||
return codec.toJsonStrict(value) as JsonObject
|
||||
}
|
||||
|
||||
inner class Context {
|
||||
val playerPredicate: MapCodec<Optional<ContextAwarePredicate>>
|
||||
get() = CAPPredicate
|
||||
|
||||
val awareContextCodec: Codec<ContextAwarePredicate>
|
||||
get() = ActualCAPPredicate
|
||||
}
|
||||
|
||||
private data class ThreadContext(val player: Optional<ContextAwarePredicate>, val context: DeserializationContext)
|
||||
|
||||
private object ActualCAPPredicate : Codec<ContextAwarePredicate> {
|
||||
override fun <T : Any> encode(input: ContextAwarePredicate, ops: DynamicOps<T>, prefix: T): DataResult<T> {
|
||||
return try {
|
||||
DataResult.success(JsonOps.INSTANCE.convertTo(ops, input.toJson()))
|
||||
} catch (err: Exception) {
|
||||
DataResult.error { "Failed to serialize ContextAwarePredicate: " + err.message }
|
||||
}
|
||||
}
|
||||
|
||||
override fun <T : Any> decode(ops: DynamicOps<T>, input: T): DataResult<Pair<ContextAwarePredicate, T>> {
|
||||
val context = context.get().lastOrNull() ?: return DataResult.error { "Not current deserializing trigger instance" }
|
||||
|
||||
return try {
|
||||
DataResult.success(Pair(EntityPredicate.fromJson(JsonObject().also { it["a"] = ops.convertTo(JsonOps.INSTANCE, input) }, "a", context.context).get(), ops.empty()))
|
||||
} catch (err: Exception) {
|
||||
DataResult.error { "Failed to deserialize ContextAwarePredicate: " + err.message }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private object CAPPredicate : MapCodec<Optional<ContextAwarePredicate>>() {
|
||||
override fun <T : Any> keys(ops: DynamicOps<T>): Stream<T> {
|
||||
return Stream.of(ops.createString("player"))
|
||||
}
|
||||
|
||||
override fun <T : Any> decode(ops: DynamicOps<T>, input: MapLike<T>): DataResult<Optional<ContextAwarePredicate>> {
|
||||
return DataResult.success(context.get().lastOrNull()?.player ?: return DataResult.error { "Not currently deserializing trigger instance" })
|
||||
}
|
||||
|
||||
override fun <T : Any> encode(input: Optional<ContextAwarePredicate>, ops: DynamicOps<T>, prefix: RecordBuilder<T>): RecordBuilder<T> {
|
||||
if (input.isPresent) {
|
||||
return prefix.add("player", JsonOps.INSTANCE.convertTo(ops, input.get().toJson()))
|
||||
} else {
|
||||
return prefix
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val context = object : ThreadLocal<ArrayDeque<ThreadContext>>() {
|
||||
override fun initialValue(): ArrayDeque<ThreadContext> {
|
||||
return ArrayDeque()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,30 @@
|
||||
package ru.dbotthepony.mc.otm.data
|
||||
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.Dynamic
|
||||
import com.mojang.serialization.JsonOps
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.advancements.critereon.DamagePredicate
|
||||
import net.minecraft.advancements.critereon.DamageSourcePredicate
|
||||
import net.minecraft.advancements.critereon.EntityPredicate
|
||||
import net.minecraft.advancements.critereon.MinMaxBounds
|
||||
import kotlin.reflect.KProperty1
|
||||
|
||||
private val dealtReceived: Codec<Pair<MinMaxBounds.Doubles, MinMaxBounds.Doubles>> = RecordCodecBuilder.create {
|
||||
it.group(
|
||||
MinMaxBounds.Doubles.CODEC.fieldOf("dealt").forGetter { it.first },
|
||||
MinMaxBounds.Doubles.CODEC.fieldOf("taken").forGetter { it.second },
|
||||
).apply(it, ::Pair)
|
||||
}
|
||||
|
||||
val DamagePredicateCodec: Codec<DamagePredicate> = RecordCodecBuilder.create {
|
||||
it.group(
|
||||
dealtReceived.fieldOf("damage").forGetter { it.dealtDamage to it.takenDamage },
|
||||
Codec.BOOL.optionalFieldOf("blocked").forGetter { it.blocked },
|
||||
EntityPredicate.CODEC.optionalFieldOf("source_entity").forGetter { it.sourceEntity },
|
||||
DamageSourcePredicate.CODEC.optionalFieldOf("type").forGetter { it.type },
|
||||
).apply(it) { damage, blocked, source, type -> DamagePredicate(damage.first, damage.second, source, blocked, type) }
|
||||
}
|
||||
|
||||
fun <V, T1> simpleCodec(factory: (T1) -> V, field1: KProperty1<V, T1>, codec1: Codec<T1>): Codec<V> {
|
||||
return RecordCodecBuilder.create {
|
||||
|
@ -1,23 +0,0 @@
|
||||
package ru.dbotthepony.mc.otm.data
|
||||
|
||||
import com.google.gson.JsonSyntaxException
|
||||
import com.mojang.datafixers.util.Pair
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.DataResult
|
||||
import com.mojang.serialization.DynamicOps
|
||||
import com.mojang.serialization.JsonOps
|
||||
import net.minecraft.world.item.crafting.Ingredient
|
||||
|
||||
object IngredientCodec : Codec<Ingredient> {
|
||||
override fun <T : Any> encode(input: Ingredient, ops: DynamicOps<T>, prefix: T): DataResult<T> {
|
||||
return DataResult.success(JsonOps.INSTANCE.convertTo(ops, input.toJson()))
|
||||
}
|
||||
|
||||
override fun <T : Any> decode(ops: DynamicOps<T>, input: T): DataResult<Pair<Ingredient, T>> {
|
||||
try {
|
||||
return DataResult.success(Pair(Ingredient.fromJson(ops.convertTo(JsonOps.INSTANCE, input)), ops.empty()))
|
||||
} catch (err: JsonSyntaxException) {
|
||||
return DataResult.error { "Error decoding Ingredient: ${err.message}" }
|
||||
}
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package ru.dbotthepony.mc.otm.data
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParseException
|
||||
import com.google.gson.JsonSyntaxException
|
||||
import com.mojang.datafixers.util.Pair
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.DataResult
|
||||
import com.mojang.serialization.DynamicOps
|
||||
import com.mojang.serialization.JsonOps
|
||||
import net.minecraft.advancements.critereon.ItemPredicate
|
||||
|
||||
object ItemPredicateCodec : Codec<ItemPredicate> {
|
||||
override fun <T : Any> encode(input: ItemPredicate, ops: DynamicOps<T>, prefix: T): DataResult<T> {
|
||||
return DataResult.success(JsonOps.INSTANCE.convertTo(ops, input.serializeToJson().let { if (it is JsonObject) it.getRidOfNulls() else it }))
|
||||
}
|
||||
|
||||
override fun <T : Any> decode(ops: DynamicOps<T>, input: T): DataResult<Pair<ItemPredicate, T>> {
|
||||
return try {
|
||||
DataResult.success(Pair(ItemPredicate.fromJson(ops.convertTo(JsonOps.INSTANCE, input)), ops.empty()))
|
||||
} catch (err: JsonSyntaxException) {
|
||||
DataResult.error { "Failed to deserialize ItemPredicate: ${err.message}" }
|
||||
} catch (err: JsonParseException) {
|
||||
DataResult.error { "Failed to deserialize ItemPredicate: ${err.message}" }
|
||||
}
|
||||
}
|
||||
}
|
@ -5,7 +5,6 @@ import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.world.level.storage.loot.LootContext
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType
|
||||
import ru.dbotthepony.mc.otm.data.Codec2Serializer
|
||||
import ru.dbotthepony.mc.otm.registry.MLootItemConditions
|
||||
|
||||
/**
|
||||
@ -29,6 +28,12 @@ data class ChanceCondition(val chance: Double) : LootItemCondition, LootItemCond
|
||||
}
|
||||
|
||||
companion object {
|
||||
val SERIALIZER = Codec2Serializer<ChanceCondition>(RecordCodecBuilder.create { it.group(Codec.doubleRange(0.0, 1.0).fieldOf("chance").forGetter(ChanceCondition::chance)).apply(it, ::ChanceCondition) })
|
||||
val CODEC: Codec<ChanceCondition> by lazy {
|
||||
RecordCodecBuilder.create {
|
||||
it.group(
|
||||
Codec.doubleRange(0.0, 1.0).fieldOf("chance").forGetter(ChanceCondition::chance)
|
||||
).apply(it, ::ChanceCondition)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import net.minecraft.world.level.storage.loot.parameters.LootContextParams
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType
|
||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||
import ru.dbotthepony.mc.otm.data.Codec2Serializer
|
||||
import ru.dbotthepony.mc.otm.data.get
|
||||
import ru.dbotthepony.mc.otm.registry.MLootItemConditions
|
||||
|
||||
@ -49,7 +48,7 @@ data class ChanceWithPlaytimeCondition(
|
||||
}
|
||||
|
||||
companion object {
|
||||
val SERIALIZER = Codec2Serializer<ChanceWithPlaytimeCondition>(
|
||||
val CODEC: Codec<ChanceWithPlaytimeCondition> by lazy {
|
||||
RecordCodecBuilder.create {
|
||||
it.group(
|
||||
Codec.INT.optionalFieldOf("minPlaytime", 0).forGetter(ChanceWithPlaytimeCondition::minPlaytime),
|
||||
@ -58,6 +57,6 @@ data class ChanceWithPlaytimeCondition(
|
||||
Codec.DOUBLE.fieldOf("maxProbability").forGetter(ChanceWithPlaytimeCondition::maxProbability),
|
||||
).apply(it, ::ChanceWithPlaytimeCondition)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.data.condition
|
||||
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import net.minecraft.world.level.storage.loot.LootContext
|
||||
import net.minecraft.world.level.storage.loot.Serializer
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
|
||||
import net.minecraft.world.level.storage.loot.predicates.InvertedLootItemCondition
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
|
||||
@ -13,7 +9,7 @@ import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||
import ru.dbotthepony.mc.otm.data.get
|
||||
import ru.dbotthepony.mc.otm.registry.MLootItemConditions
|
||||
|
||||
object HasExoPackCondition : LootItemCondition, Serializer<HasExoPackCondition>, LootItemCondition.Builder {
|
||||
object HasExoPackCondition : LootItemCondition, LootItemCondition.Builder {
|
||||
override fun test(t: LootContext): Boolean {
|
||||
t[LootContextParams.LAST_DAMAGE_PLAYER]?.matteryPlayer?.let {
|
||||
return it.hasExopack
|
||||
@ -26,13 +22,6 @@ object HasExoPackCondition : LootItemCondition, Serializer<HasExoPackCondition>,
|
||||
return MLootItemConditions.HAS_EXOPACK
|
||||
}
|
||||
|
||||
override fun serialize(p_79325_: JsonObject, p_79326_: HasExoPackCondition, p_79327_: JsonSerializationContext) {
|
||||
}
|
||||
|
||||
override fun deserialize(p_79323_: JsonObject, p_79324_: JsonDeserializationContext): HasExoPackCondition {
|
||||
return this
|
||||
}
|
||||
|
||||
override fun build(): LootItemCondition {
|
||||
return this
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType
|
||||
import ru.dbotthepony.mc.otm.capability.items
|
||||
import ru.dbotthepony.mc.otm.core.collect.filter
|
||||
import ru.dbotthepony.mc.otm.data.Codec2Serializer
|
||||
import ru.dbotthepony.mc.otm.data.get
|
||||
import ru.dbotthepony.mc.otm.registry.MLootItemConditions
|
||||
|
||||
@ -58,7 +57,7 @@ data class ItemInInventoryCondition(
|
||||
}
|
||||
|
||||
companion object {
|
||||
val SERIALIZER = Codec2Serializer<ItemInInventoryCondition>(
|
||||
val CODEC: Codec<ItemInInventoryCondition> by lazy {
|
||||
RecordCodecBuilder.create {
|
||||
it.group(
|
||||
ItemStack.CODEC.fieldOf("item").forGetter(ItemInInventoryCondition::item),
|
||||
@ -67,6 +66,6 @@ data class ItemInInventoryCondition(
|
||||
Codec.BOOL.optionalFieldOf("matchCosmetics", false).forGetter(ItemInInventoryCondition::matchCosmetics),
|
||||
).apply(it, ::ItemInInventoryCondition)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.data.condition
|
||||
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import net.minecraft.world.level.storage.loot.LootContext
|
||||
import net.minecraft.world.level.storage.loot.Serializer
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
|
||||
import net.minecraft.world.level.storage.loot.predicates.InvertedLootItemCondition
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
|
||||
@ -13,7 +9,7 @@ import net.minecraftforge.common.util.FakePlayer
|
||||
import ru.dbotthepony.mc.otm.data.get
|
||||
import ru.dbotthepony.mc.otm.registry.MLootItemConditions
|
||||
|
||||
object KilledByRealPlayer : LootItemCondition, Serializer<KilledByRealPlayer>, LootItemCondition.Builder {
|
||||
object KilledByRealPlayer : LootItemCondition, LootItemCondition.Builder {
|
||||
override fun test(t: LootContext): Boolean {
|
||||
return t.hasParam(LootContextParams.LAST_DAMAGE_PLAYER) && t[LootContextParams.LAST_DAMAGE_PLAYER] !is FakePlayer
|
||||
}
|
||||
@ -22,13 +18,6 @@ object KilledByRealPlayer : LootItemCondition, Serializer<KilledByRealPlayer>, L
|
||||
return MLootItemConditions.KILLED_BY_REAL_PLAYER
|
||||
}
|
||||
|
||||
override fun serialize(p_79325_: JsonObject, p_79326_: KilledByRealPlayer, p_79327_: JsonSerializationContext) {
|
||||
}
|
||||
|
||||
override fun deserialize(p_79323_: JsonObject, p_79324_: JsonDeserializationContext): KilledByRealPlayer {
|
||||
return this
|
||||
}
|
||||
|
||||
override fun build(): LootItemCondition {
|
||||
return this
|
||||
}
|
||||
|
@ -1,11 +1,7 @@
|
||||
package ru.dbotthepony.mc.otm.data.condition
|
||||
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import net.minecraft.world.entity.OwnableEntity
|
||||
import net.minecraft.world.level.storage.loot.LootContext
|
||||
import net.minecraft.world.level.storage.loot.Serializer
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
|
||||
import net.minecraft.world.level.storage.loot.predicates.InvertedLootItemCondition
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
|
||||
@ -15,7 +11,7 @@ import ru.dbotthepony.mc.otm.NULLABLE_MINECRAFT_SERVER
|
||||
import ru.dbotthepony.mc.otm.data.get
|
||||
import ru.dbotthepony.mc.otm.registry.MLootItemConditions
|
||||
|
||||
object KilledByRealPlayerOrIndirectly : LootItemCondition, Serializer<KilledByRealPlayerOrIndirectly>, LootItemCondition.Builder {
|
||||
object KilledByRealPlayerOrIndirectly : LootItemCondition, LootItemCondition.Builder {
|
||||
override fun test(t: LootContext): Boolean {
|
||||
if (t.hasParam(LootContextParams.LAST_DAMAGE_PLAYER) && t[LootContextParams.LAST_DAMAGE_PLAYER] !is FakePlayer) {
|
||||
return true
|
||||
@ -43,13 +39,6 @@ object KilledByRealPlayerOrIndirectly : LootItemCondition, Serializer<KilledByRe
|
||||
return MLootItemConditions.KILLED_BY_REAL_PLAYER_OR_INDIRECTLY
|
||||
}
|
||||
|
||||
override fun serialize(p_79325_: JsonObject, p_79326_: KilledByRealPlayerOrIndirectly, p_79327_: JsonSerializationContext) {
|
||||
}
|
||||
|
||||
override fun deserialize(p_79323_: JsonObject, p_79324_: JsonDeserializationContext): KilledByRealPlayerOrIndirectly {
|
||||
return this
|
||||
}
|
||||
|
||||
override fun build(): LootItemCondition {
|
||||
return this
|
||||
}
|
||||
|
@ -1,28 +1,23 @@
|
||||
package ru.dbotthepony.mc.otm.data.loot
|
||||
|
||||
import com.google.common.collect.ImmutableList
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonDeserializationContext
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonPrimitive
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.BlockItem
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.storage.loot.LootContext
|
||||
import net.minecraft.world.level.storage.loot.Serializer
|
||||
import net.minecraft.world.level.storage.loot.functions.LootItemFunction
|
||||
import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
|
||||
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
|
||||
import ru.dbotthepony.mc.otm.core.nbt.getJson
|
||||
import ru.dbotthepony.mc.otm.core.nbt.set
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.core.stream
|
||||
import ru.dbotthepony.mc.otm.core.tagNotNull
|
||||
import ru.dbotthepony.mc.otm.core.collect.stream
|
||||
import ru.dbotthepony.mc.otm.core.nbt.getJson
|
||||
import ru.dbotthepony.mc.otm.registry.MItemFunctionTypes
|
||||
import java.util.Optional
|
||||
import java.util.stream.Stream
|
||||
|
||||
class CopyTileNbtFunction(filter: Stream<out String> = Stream.empty()) : LootItemFunction, LootItemFunction.Builder {
|
||||
@ -77,20 +72,16 @@ class CopyTileNbtFunction(filter: Stream<out String> = Stream.empty()) : LootIte
|
||||
return this
|
||||
}
|
||||
|
||||
companion object : Serializer<CopyTileNbtFunction> {
|
||||
override fun serialize(
|
||||
pJson: JsonObject,
|
||||
pValue: CopyTileNbtFunction,
|
||||
pSerializationContext: JsonSerializationContext
|
||||
) {
|
||||
pJson["filter"] = JsonArray().also { for (v in pValue.filter) it.add(v) }
|
||||
companion object {
|
||||
val CODEC: Codec<CopyTileNbtFunction> by lazy {
|
||||
RecordCodecBuilder.create {
|
||||
it.group(
|
||||
Codec.STRING.listOf()
|
||||
.optionalFieldOf("filter")
|
||||
.xmap({ it.orElseGet { listOf() } }, { if (it.isEmpty()) Optional.empty() else Optional.of(it) })
|
||||
.forGetter(CopyTileNbtFunction::filter),
|
||||
).apply(it, ::CopyTileNbtFunction)
|
||||
}
|
||||
|
||||
override fun deserialize(
|
||||
pJson: JsonObject,
|
||||
pSerializationContext: JsonDeserializationContext
|
||||
): CopyTileNbtFunction {
|
||||
return CopyTileNbtFunction((pJson["filter"] as? JsonArray)?.stream()?.filter { it is JsonPrimitive }?.map { it.asString!! } ?: Stream.empty())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,16 @@
|
||||
package ru.dbotthepony.mc.otm.data.loot
|
||||
|
||||
import com.google.common.collect.ImmutableList
|
||||
import com.google.gson.*
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.DataResult
|
||||
import com.mojang.serialization.Dynamic
|
||||
import com.mojang.serialization.JsonOps
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.storage.loot.Deserializers
|
||||
import net.minecraft.world.level.storage.loot.LootContext
|
||||
import net.minecraft.world.level.storage.loot.LootPool
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
|
||||
import net.minecraftforge.common.ForgeHooks
|
||||
import net.minecraftforge.common.loot.IGlobalLootModifier
|
||||
import net.minecraftforge.common.loot.LootModifier
|
||||
import java.util.Arrays
|
||||
import java.util.Deque
|
||||
import java.util.*
|
||||
import java.util.stream.Stream
|
||||
|
||||
class LootPoolAppender(conditions: Array<out LootItemCondition>, pools: Stream<LootPool>) : LootModifier(conditions) {
|
||||
@ -39,53 +31,11 @@ class LootPoolAppender(conditions: Array<out LootItemCondition>, pools: Stream<L
|
||||
return CODEC
|
||||
}
|
||||
|
||||
// TODO: remove reflection once Forge implement a way to provide lootpool deserialization context in non-reflective way
|
||||
companion object {
|
||||
private val lootPoolCodec: Codec<List<LootPool>>
|
||||
|
||||
private val forgeHooksLootContext by lazy {
|
||||
val field = ForgeHooks::class.java.getDeclaredField("lootContext")
|
||||
field.isAccessible = true
|
||||
field
|
||||
}
|
||||
|
||||
private val lootTableContextConstructor by lazy {
|
||||
val clazz = ForgeHooks::class.java.declaredClasses.firstOrNull { it.name.contains("LootTableContext") } ?: throw NoSuchElementException("Unable to find ForgeHooks\$LootTableContext!")
|
||||
val constructor = clazz.getDeclaredConstructor(ResourceLocation::class.java, Boolean::class.java)
|
||||
constructor.isAccessible = true
|
||||
constructor
|
||||
}
|
||||
|
||||
init {
|
||||
val serializer = Deserializers.createLootTableSerializer().create()
|
||||
val notExistingLocation = ResourceLocation("null", "null")
|
||||
|
||||
lootPoolCodec = Codec.list(Codec.PASSTHROUGH.flatXmap({
|
||||
val dequeueHolder = forgeHooksLootContext.get(null) as ThreadLocal<Deque<Any>>
|
||||
val deque = dequeueHolder.get() ?: java.util.ArrayDeque()
|
||||
dequeueHolder.set(deque)
|
||||
|
||||
try {
|
||||
deque.push(lootTableContextConstructor.newInstance(notExistingLocation, true))
|
||||
DataResult.success(serializer.fromJson(it.convert(JsonOps.INSTANCE).value, LootPool::class.java))
|
||||
} catch(err: JsonSyntaxException) {
|
||||
DataResult.error { err.message }
|
||||
} finally {
|
||||
deque.pop()
|
||||
}
|
||||
}, {
|
||||
try {
|
||||
DataResult.success(Dynamic(JsonOps.INSTANCE, serializer.toJsonTree(it)))
|
||||
} catch(err: JsonSyntaxException) {
|
||||
DataResult.error { err.message }
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
val CODEC: Codec<LootPoolAppender> =
|
||||
RecordCodecBuilder.create {
|
||||
codecStart(it).and(
|
||||
lootPoolCodec.fieldOf("pools").forGetter(LootPoolAppender::pools)
|
||||
LootPool.CODEC.listOf().fieldOf("pools").forGetter(LootPoolAppender::pools)
|
||||
).apply(it, ::LootPoolAppender)
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ class FluidCapsuleItem(val capacity: IntSupplier) : Item(Properties().stacksTo(6
|
||||
actionResult.result
|
||||
} else {
|
||||
val state = level.getBlockState(hitPos)
|
||||
val placePos = if (state.block is LiquidBlockContainer && (state.block as LiquidBlockContainer).canPlaceLiquid(level, hitPos, state, fluid.fluid)) hitPos else nextPos
|
||||
val placePos = if (state.block is LiquidBlockContainer && (state.block as LiquidBlockContainer).canPlaceLiquid(player, level, hitPos, state, fluid.fluid)) hitPos else nextPos
|
||||
|
||||
val actionResult = FluidUtil.tryPlaceFluid(player, level, hand, placePos, targetItem, fluid)
|
||||
if (!actionResult.isSuccess) return InteractionResultHolder.pass(item)
|
||||
|
@ -1,7 +1,7 @@
|
||||
package ru.dbotthepony.mc.otm.item
|
||||
|
||||
import net.minecraft.core.BlockSource
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.core.dispenser.BlockSource
|
||||
import net.minecraft.core.dispenser.DefaultDispenseItemBehavior
|
||||
import net.minecraft.core.dispenser.DispenseItemBehavior
|
||||
import net.minecraft.tags.BlockTags
|
||||
@ -67,11 +67,11 @@ class MinecartCargoCrateItem(val color: DyeColor?) : Item(Properties().stacksTo(
|
||||
private val default = DefaultDispenseItemBehavior()
|
||||
|
||||
override fun dispense(blockSource: BlockSource, itemStack: ItemStack): ItemStack {
|
||||
val direction = blockSource.blockState.getValue(DispenserBlock.FACING)
|
||||
val direction = blockSource.state.getValue(DispenserBlock.FACING)
|
||||
val level: Level = blockSource.level
|
||||
val x = blockSource.x() + direction.stepX.toDouble() * 1.125
|
||||
val y = floor(blockSource.y()) + direction.stepY.toDouble()
|
||||
val z = blockSource.z() + direction.stepZ.toDouble() * 1.125
|
||||
val x = blockSource.pos.x + direction.stepX.toDouble() * 1.125
|
||||
val y = blockSource.pos.y + direction.stepY.toDouble()
|
||||
val z = blockSource.pos.z + direction.stepZ.toDouble() * 1.125
|
||||
val blockpos = blockSource.pos.relative(direction)
|
||||
val blockstate = level.getBlockState(blockpos)
|
||||
val railshape =
|
||||
|
@ -1,5 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.item
|
||||
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
@ -23,7 +24,6 @@ import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.core.math.set
|
||||
import ru.dbotthepony.mc.otm.core.nbt.mapPresent
|
||||
import ru.dbotthepony.mc.otm.core.tagNotNull
|
||||
import ru.dbotthepony.mc.otm.data.Codec2Serializer
|
||||
import ru.dbotthepony.mc.otm.data.DecimalProvider
|
||||
import ru.dbotthepony.mc.otm.registry.MItemFunctionTypes
|
||||
import java.util.Optional
|
||||
@ -119,8 +119,7 @@ class ProceduralBatteryItem : Item(Properties().stacksTo(1)) {
|
||||
}
|
||||
|
||||
companion object {
|
||||
val SERIALIZER by lazy {
|
||||
Codec2Serializer<Randomizer>(
|
||||
val CODEC: Codec<Randomizer> by lazy {
|
||||
RecordCodecBuilder.create {
|
||||
it.group(
|
||||
DecimalProvider.CODEC.fieldOf("maxBatteryLevel").forGetter(Randomizer::maxBatteryLevel),
|
||||
@ -129,7 +128,6 @@ class ProceduralBatteryItem : Item(Properties().stacksTo(1)) {
|
||||
DecimalProvider.CODEC.optionalFieldOf("maxOutput").forGetter(Randomizer::maxOutput),
|
||||
).apply(it, ::Randomizer)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import net.minecraft.core.Direction
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.util.datafix.DataFixTypes
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Rarity
|
||||
@ -20,7 +21,7 @@ import net.minecraftforge.common.capabilities.ICapabilityProvider
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.event.TickEvent
|
||||
import net.minecraftforge.event.TickEvent.ServerTickEvent
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import net.minecraftforge.event.network.CustomPayloadEvent
|
||||
import net.minecraftforge.registries.ForgeRegistries
|
||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
@ -52,7 +53,6 @@ import ru.dbotthepony.mc.otm.isServerThread
|
||||
import ru.dbotthepony.mc.otm.lazyPerServer
|
||||
import ru.dbotthepony.mc.otm.network.GenericNetworkChannel
|
||||
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
||||
import ru.dbotthepony.mc.otm.network.packetHandled
|
||||
import java.util.*
|
||||
import java.util.function.Function
|
||||
import java.util.function.Supplier
|
||||
@ -155,7 +155,7 @@ class QuantumBatteryItem(val savedataID: String, val balanceValues: EnergyBalanc
|
||||
val clientData = Object2ObjectOpenHashMap<UUID, IValues>()
|
||||
|
||||
val serverData: Data by lazyPerServer {
|
||||
it.overworld().dataStorage.computeIfAbsent(::Data, ::Data, "otm_$savedataID")
|
||||
it.overworld().dataStorage.computeIfAbsent(SavedData.Factory(::Data, ::Data, DataFixTypes.SAVED_DATA_MAP_DATA), "otm_$savedataID")
|
||||
}
|
||||
|
||||
private inner class Power(private val stack: ItemStack) : IMatteryEnergyStorage, ICapabilityProvider {
|
||||
@ -377,8 +377,7 @@ class QuantumBatteryItem(val savedataID: String, val balanceValues: EnergyBalanc
|
||||
buff.writeDecimal(received)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val data = type.clientData.computeIfAbsent(uuid, Function { UnboundValues(it) })
|
||||
data.energy = energy
|
||||
data.passed = passed
|
||||
|
@ -1,5 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.item.exopack
|
||||
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.network.chat.Component
|
||||
@ -14,7 +15,6 @@ import net.minecraft.world.level.storage.loot.functions.LootItemFunctionType
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.core.nbt.set
|
||||
import ru.dbotthepony.mc.otm.core.tagNotNull
|
||||
import ru.dbotthepony.mc.otm.data.Codec2Serializer
|
||||
import ru.dbotthepony.mc.otm.registry.MItemFunctionTypes
|
||||
import java.util.*
|
||||
|
||||
@ -34,14 +34,12 @@ class ProceduralExopackSlotUpgradeItem : AbstractExopackSlotUpgradeItem(defaultP
|
||||
}
|
||||
|
||||
companion object {
|
||||
val SERIALIZER = Codec2Serializer<Randomizer>(
|
||||
RecordCodecBuilder.create {
|
||||
val CODEC: Codec<Randomizer> = RecordCodecBuilder.create {
|
||||
it.group(
|
||||
IntProvider.CODEC.fieldOf("slots").forGetter(Randomizer::slots),
|
||||
IntProvider.CODEC.optionalFieldOf("luck_bias", ConstantInt.ZERO).forGetter(Randomizer::luckBias),
|
||||
).apply(it, ::Randomizer)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,15 +18,12 @@ import net.minecraftforge.client.event.RenderHandEvent
|
||||
import net.minecraftforge.client.event.RenderPlayerEvent
|
||||
import net.minecraftforge.client.event.ViewportEvent
|
||||
import net.minecraftforge.event.TickEvent
|
||||
import net.minecraftforge.event.network.CustomPayloadEvent
|
||||
import net.minecraftforge.fml.LogicalSide
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import ru.dbotthepony.mc.otm.*
|
||||
import ru.dbotthepony.mc.otm.capability.matteryEnergy
|
||||
import ru.dbotthepony.mc.otm.client.font
|
||||
import ru.dbotthepony.mc.otm.client.render.RenderGravity
|
||||
import ru.dbotthepony.mc.otm.client.render.draw
|
||||
import ru.dbotthepony.mc.otm.client.render.renderRect
|
||||
import ru.dbotthepony.mc.otm.core.*
|
||||
import ru.dbotthepony.mc.otm.core.math.Angle
|
||||
import ru.dbotthepony.mc.otm.core.math.RGBAColor
|
||||
import ru.dbotthepony.mc.otm.core.math.Vector
|
||||
@ -42,11 +39,12 @@ import ru.dbotthepony.mc.otm.core.nbt.EMPTY_UUID
|
||||
import ru.dbotthepony.mc.otm.core.nbt.booleans
|
||||
import ru.dbotthepony.mc.otm.core.nbt.ints
|
||||
import ru.dbotthepony.mc.otm.core.nbt.uuids
|
||||
import ru.dbotthepony.mc.otm.core.tagNotNull
|
||||
import ru.dbotthepony.mc.otm.core.util.formatPower
|
||||
import ru.dbotthepony.mc.otm.network.MatteryPacket
|
||||
import ru.dbotthepony.mc.otm.network.WeaponNetworkChannel
|
||||
import java.util.*
|
||||
import java.util.function.Supplier
|
||||
import kotlin.collections.set
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.abs
|
||||
import kotlin.reflect.KClass
|
||||
@ -62,17 +60,13 @@ enum class WeaponScopePacket(val scope: Boolean) : MatteryPacket {
|
||||
buff.writeBoolean(scope)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.get().packetHandled = true
|
||||
|
||||
override fun play(context: CustomPayloadEvent.Context){
|
||||
// TODO: Manual synchronization
|
||||
context.get().enqueueWork {
|
||||
val stack = context.get().sender!!.mainHandItem
|
||||
val item = stack.item as? AbstractWeaponItem<*> ?: return@enqueueWork
|
||||
val stack = context.sender!!.mainHandItem
|
||||
val item = stack.item as? AbstractWeaponItem<*> ?: return
|
||||
|
||||
item.dataTable(stack).wantsToScope = scope
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf) = if (buff.readBoolean()) SCOPE_IN else SCOPE_OUT
|
||||
@ -86,13 +80,10 @@ enum class WeaponFireInputPacket(val primary: Boolean) : MatteryPacket {
|
||||
buff.writeBoolean(primary)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.get().packetHandled = true
|
||||
|
||||
override fun play(context: CustomPayloadEvent.Context){
|
||||
// TODO: Manual synchronization
|
||||
context.get().enqueueWork {
|
||||
val stack = context.get().sender!!.mainHandItem
|
||||
val item = stack.item as? AbstractWeaponItem<*> ?: return@enqueueWork
|
||||
val stack = context.sender!!.mainHandItem
|
||||
val item = stack.item as? AbstractWeaponItem<*> ?: return
|
||||
|
||||
// Listen server: client and server thread compete for lock
|
||||
// so it is very likely item is being in predicted context
|
||||
@ -100,13 +91,12 @@ enum class WeaponFireInputPacket(val primary: Boolean) : MatteryPacket {
|
||||
item.dataTable = null
|
||||
|
||||
if (primary)
|
||||
item.tryPrimaryFire(stack, context.get().sender!!)
|
||||
item.tryPrimaryFire(stack, context.sender!!)
|
||||
else
|
||||
item.trySecondaryFire(stack, context.get().sender!!)
|
||||
item.trySecondaryFire(stack, context.sender!!)
|
||||
|
||||
(item as AbstractWeaponItem<WeaponDataTable>).dataTable = predictedData
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf) = if (buff.readBoolean()) PRIMARY else SECONDARY
|
||||
|
@ -51,10 +51,10 @@ import net.minecraftforge.event.AddReloadListenerEvent
|
||||
import net.minecraftforge.event.OnDatapackSyncEvent
|
||||
import net.minecraftforge.event.RegisterCommandsEvent
|
||||
import net.minecraftforge.event.entity.player.ItemTooltipEvent
|
||||
import net.minecraftforge.event.network.CustomPayloadEvent
|
||||
import net.minecraftforge.event.server.ServerStartedEvent
|
||||
import net.minecraftforge.eventbus.api.IEventBus
|
||||
import net.minecraftforge.fml.ModList
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import net.minecraftforge.network.PacketDistributor
|
||||
import net.minecraftforge.registries.DeferredRegister
|
||||
import net.minecraftforge.registries.ForgeRegistries
|
||||
@ -107,7 +107,6 @@ import java.io.OutputStream
|
||||
import java.math.BigInteger
|
||||
import java.util.*
|
||||
import java.util.function.BooleanSupplier
|
||||
import java.util.function.Supplier
|
||||
import java.util.stream.Stream
|
||||
import java.util.zip.Deflater
|
||||
import java.util.zip.Inflater
|
||||
@ -443,19 +442,19 @@ object MatterManager {
|
||||
val ignoreDamageables = data["ignore_damageables"]?.asBoolean ?: false
|
||||
val allowBacktrack = data["allow_backtrack"]?.asBoolean ?: true
|
||||
|
||||
var stream = server.recipeManager.byType(findRecipeType).values.stream().filter { !it.isIncomplete }
|
||||
var stream = server.recipeManager.byType(findRecipeType).values.stream().filter { !it.value.isIncomplete }
|
||||
|
||||
if (ignoreDamageables) {
|
||||
stream = stream.filter { it.ingredients.stream().flatMap { it.items.stream() }.noneMatch { it.isDamageableItem } }
|
||||
stream = stream.filter { it.value.ingredients.stream().flatMap { it.items.stream() }.noneMatch { it.isDamageableItem } }
|
||||
}
|
||||
|
||||
stream.filter { it.getResultItem(server.registryAccess()).isNotEmpty }.map {
|
||||
stream.filter { it.value.getResultItem(server.registryAccess()).isNotEmpty }.map {
|
||||
try {
|
||||
ResolvedRecipe(
|
||||
it.ingredients.stream()
|
||||
it.value.ingredients.stream()
|
||||
.filter { !it.isActuallyEmpty }
|
||||
.map { it.items.stream().filter { it.isNotEmpty }.map(::RecipeEntry) },
|
||||
ImmutableStack(it.getResultItem(server.registryAccess())),
|
||||
ImmutableStack(it.value.getResultItem(server.registryAccess())),
|
||||
isCritical = isCritical,
|
||||
name = it.id,
|
||||
allowBacktrack = allowBacktrack
|
||||
@ -489,16 +488,16 @@ object MatterManager {
|
||||
val allowBacktrack = data["allow_backtrack"]?.asBoolean ?: true
|
||||
val ignoreDamageables = data["ignore_damageables"]?.asBoolean ?: false
|
||||
val isCritical = data["is_critical"]?.asBoolean ?: true
|
||||
var stream = server.recipeManager.byType(findRecipeType).values.stream().filter { !it.isIncomplete }
|
||||
var stream = server.recipeManager.byType(findRecipeType).values.stream().filter { !it.value.isIncomplete }
|
||||
|
||||
if (ignoreDamageables) {
|
||||
stream = stream.filter { it.ingredients.stream().flatMap { it.items.stream() }.noneMatch { it.isDamageableItem } }
|
||||
stream = stream.filter { it.value.ingredients.stream().flatMap { it.items.stream() }.noneMatch { it.isDamageableItem } }
|
||||
}
|
||||
|
||||
stream.map {
|
||||
try {
|
||||
// avoid reality snap when recipe has no output
|
||||
val resultItem = it.getResultItem(server.registryAccess())
|
||||
val resultItem = it.value.getResultItem(server.registryAccess())
|
||||
|
||||
if (resultItem.isEmpty) {
|
||||
null
|
||||
@ -506,17 +505,17 @@ object MatterManager {
|
||||
var width: Int
|
||||
var height: Int
|
||||
|
||||
if (it is IShapedRecipe<*>) {
|
||||
width = it.recipeWidth
|
||||
height = it.recipeHeight
|
||||
if (it.value is IShapedRecipe<*>) {
|
||||
width = (it.value as IShapedRecipe<*>).recipeWidth
|
||||
height = (it.value as IShapedRecipe<*>).recipeHeight
|
||||
} else {
|
||||
width = 3
|
||||
height = 3
|
||||
}
|
||||
|
||||
if (width * height < it.ingredients.size) {
|
||||
width = it.ingredients.size.coerceAtLeast(width)
|
||||
height = it.ingredients.size.coerceAtLeast(height)
|
||||
if (width * height < it.value.ingredients.size) {
|
||||
width = it.value.ingredients.size.coerceAtLeast(width)
|
||||
height = it.value.ingredients.size.coerceAtLeast(height)
|
||||
}
|
||||
|
||||
val container = TransientCraftingContainer(object : AbstractContainerMenu(null, 0) {
|
||||
@ -531,12 +530,12 @@ object MatterManager {
|
||||
|
||||
val realIngredients = ArrayList<ArrayList<RecipeEntry>>()
|
||||
|
||||
for (c in it.ingredients.indices) {
|
||||
if (it.ingredients[c].isActuallyEmpty) {
|
||||
for (c in it.value.ingredients.indices) {
|
||||
if (it.value.ingredients[c].isActuallyEmpty) {
|
||||
continue
|
||||
}
|
||||
|
||||
for ((i, ingredient) in it.ingredients.withIndex()) {
|
||||
for ((i, ingredient) in it.value.ingredients.withIndex()) {
|
||||
if (i != c) {
|
||||
container[i] = if (ingredient.isActuallyEmpty) ItemStack.EMPTY else ingredient.items.firstOrNull() ?: ItemStack.EMPTY
|
||||
}
|
||||
@ -544,11 +543,11 @@ object MatterManager {
|
||||
|
||||
val result = ArrayList<RecipeEntry>()
|
||||
|
||||
for (item in it.ingredients[c].items) {
|
||||
for (item in it.value.ingredients[c].items) {
|
||||
container[c] = item
|
||||
|
||||
if (!it.assemble(container, server.registryAccess()).isEmpty) {
|
||||
val residue = it.getRemainingItems(container)
|
||||
if (!it.value.assemble(container, server.registryAccess()).isEmpty) {
|
||||
val residue = it.value.getRemainingItems(container)
|
||||
|
||||
val thisResidue = residue[c]
|
||||
|
||||
@ -1640,7 +1639,7 @@ object MatterManager {
|
||||
if (event.player == null) {
|
||||
syncRegistry(PacketDistributor.ALL.noArg())
|
||||
} else {
|
||||
syncRegistry(PacketDistributor.PLAYER.with { event.player ?: throw ConcurrentModificationException() })
|
||||
syncRegistry(PacketDistributor.PLAYER.with(event.player!!))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1826,7 +1825,7 @@ object MatterManager {
|
||||
buff.writeBytes(payload, 0, length)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
if (SERVER_IS_LIVE)
|
||||
return // singleplayer or LAN host
|
||||
|
||||
|
@ -4,7 +4,6 @@ import com.google.common.collect.ImmutableList
|
||||
import com.mojang.datafixers.util.Pair
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList
|
||||
import it.unimi.dsi.fastutil.ints.IntCollection
|
||||
import it.unimi.dsi.fastutil.ints.IntList
|
||||
import it.unimi.dsi.fastutil.io.FastByteArrayInputStream
|
||||
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectFunction
|
||||
@ -25,7 +24,7 @@ import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper.hasBindingCurse
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import net.minecraftforge.event.network.CustomPayloadEvent
|
||||
import net.minecraftforge.network.PacketDistributor
|
||||
import ru.dbotthepony.mc.otm.capability.IMatteryUpgrade
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
@ -40,7 +39,6 @@ import ru.dbotthepony.mc.otm.container.IMatteryContainer
|
||||
import ru.dbotthepony.mc.otm.container.ItemFilter
|
||||
import ru.dbotthepony.mc.otm.container.UpgradeContainer
|
||||
import ru.dbotthepony.mc.otm.container.computeSortedIndices
|
||||
import ru.dbotthepony.mc.otm.container.sort
|
||||
import ru.dbotthepony.mc.otm.container.sortWithIndices
|
||||
import ru.dbotthepony.mc.otm.core.GetterSetter
|
||||
import ru.dbotthepony.mc.otm.core.collect.ConditionalEnumSet
|
||||
@ -62,9 +60,6 @@ import ru.dbotthepony.mc.otm.network.MatteryPacket
|
||||
import ru.dbotthepony.mc.otm.network.MenuFieldPacket
|
||||
import ru.dbotthepony.mc.otm.network.MenuNetworkChannel
|
||||
import ru.dbotthepony.mc.otm.network.SetCarriedPacket
|
||||
import ru.dbotthepony.mc.otm.network.enqueueWork
|
||||
import ru.dbotthepony.mc.otm.network.packetHandled
|
||||
import ru.dbotthepony.mc.otm.network.sender
|
||||
import ru.dbotthepony.mc.otm.network.synchronizer.FieldSynchronizer
|
||||
import ru.dbotthepony.mc.otm.network.synchronizer.IField
|
||||
import ru.dbotthepony.mc.otm.network.synchronizer.IMutableBooleanField
|
||||
@ -77,8 +72,6 @@ import java.util.function.Consumer
|
||||
import java.util.function.DoubleSupplier
|
||||
import java.util.function.IntSupplier
|
||||
import java.util.function.Predicate
|
||||
import java.util.function.Supplier
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
data class PlayerSlot<A : Slot, B : Slot>(val functional: A, val cosmetic: B? = null)
|
||||
|
||||
@ -126,18 +119,14 @@ abstract class MatteryMenu(
|
||||
buff.writeBytes(payload)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
|
||||
context.enqueueWork {
|
||||
val menu = context.sender?.containerMenu as? MatteryMenu ?: return@enqueueWork
|
||||
if (menu.containerId != containerId || !menu.stillValid(context.sender!!)) return@enqueueWork
|
||||
val input = menu.playerInputs.getOrNull(inputId) ?: return@enqueueWork
|
||||
if (!input.test(context.sender)) return@enqueueWork
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val menu = context.sender?.containerMenu as? MatteryMenu ?: return
|
||||
if (menu.containerId != containerId || !menu.stillValid(context.sender!!)) return
|
||||
val input = menu.playerInputs.getOrNull(inputId) ?: return
|
||||
if (!input.test(context.sender)) return
|
||||
input.invoke(input.codec.read(DataInputStream(FastByteArrayInputStream(payload))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Client->Server input
|
||||
@ -239,8 +228,6 @@ abstract class MatteryMenu(
|
||||
protected var inventorySlotIndexStart = 0
|
||||
protected var inventorySlotIndexEnd = 0
|
||||
|
||||
private val playerPacketDistributor = PacketDistributor.PLAYER.with { player as ServerPlayer }
|
||||
|
||||
fun addFilterSlots(slots: ItemFilter): List<GetterSetter<ItemStack>> {
|
||||
val result = ArrayList<GetterSetter<ItemStack>>(slots.size)
|
||||
|
||||
|
@ -11,7 +11,7 @@ import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.ClickAction
|
||||
import net.minecraft.world.inventory.ClickType
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import net.minecraftforge.event.network.CustomPayloadEvent
|
||||
import net.minecraftforge.network.PacketDistributor
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.core.addSorted
|
||||
@ -42,17 +42,14 @@ data class ItemViewInteractPacket(val stackID: Int, val type: ClickType, val act
|
||||
buff.writeEnum(action)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
context.enqueueWork {
|
||||
val sender = context.sender ?: return@enqueueWork
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val sender = context.sender ?: return
|
||||
|
||||
if (!sender.isSpectator) {
|
||||
sender.resetLastActionTime()
|
||||
(sender.containerMenu as? INetworkedItemViewProvider)?.networkedItemView?.playerInteract(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): ItemViewInteractPacket {
|
||||
@ -62,14 +59,11 @@ data class ItemViewInteractPacket(val stackID: Int, val type: ClickType, val act
|
||||
}
|
||||
|
||||
abstract class NetworkedItemViewPacket : MatteryPacket {
|
||||
final override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
context.enqueueWork {
|
||||
val get = Minecraft.getInstance().player?.containerMenu ?: return@enqueueWork
|
||||
final override fun play(context: CustomPayloadEvent.Context) {
|
||||
val get = Minecraft.getInstance().player?.containerMenu ?: return
|
||||
val view = (get as? INetworkedItemViewProvider)?.networkedItemView ?: throw IllegalStateException("No NetworkedItemView is present in currently open menu")
|
||||
action(view)
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun action(view: NetworkedItemView)
|
||||
}
|
||||
@ -249,7 +243,7 @@ class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val isRemote: Bo
|
||||
|
||||
fun network() {
|
||||
check(!isRemote) { "Not a server" }
|
||||
val consumer = PacketDistributor.PLAYER.with { ply as ServerPlayer }
|
||||
val consumer = PacketDistributor.PLAYER.with(ply as ServerPlayer)
|
||||
|
||||
for (packet in networkBacklog) {
|
||||
MenuNetworkChannel.send(consumer, packet)
|
||||
|
@ -5,6 +5,7 @@ import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.DyeColor
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.crafting.RecipeHolder
|
||||
import ru.dbotthepony.mc.otm.block.entity.decorative.PainterBlockEntity
|
||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||
@ -42,7 +43,7 @@ class PainterMenu(
|
||||
|
||||
val inputContainer = MatteryContainer(::rescan, 1)
|
||||
val outputContainer = MatteryContainer(1)
|
||||
private var lastRecipe: PainterRecipe? = null
|
||||
private var lastRecipe: RecipeHolder<PainterRecipe>? = null
|
||||
var selectedRecipe by mSynchronizer.Field(null, ResourceLocationValueCodec.nullable).also { it.addListener { rescan() } }
|
||||
|
||||
val isBulk = BooleanInputWithFeedback(this, tile?.let { it::isBulk })
|
||||
@ -53,7 +54,7 @@ class PainterMenu(
|
||||
|
||||
val inputSlot = object : MatterySlot(inputContainer, 0) {
|
||||
override fun mayPlace(itemStack: ItemStack): Boolean {
|
||||
return super.mayPlace(itemStack) && inventory.player.level().recipeManager.byType(MRecipes.PAINTER).values.any { it.input.test(itemStack) }
|
||||
return super.mayPlace(itemStack) && inventory.player.level().recipeManager.byType(MRecipes.PAINTER).values.any { it.value.input.test(itemStack) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,7 +66,7 @@ class PainterMenu(
|
||||
|
||||
override fun onTake(player: Player, itemStack: ItemStack) {
|
||||
if (itemStack.isNotEmpty) {
|
||||
lastRecipe?.dyes?.let { tile?.takeDyes(it) }
|
||||
lastRecipe?.value?.dyes?.let { tile?.takeDyes(it) }
|
||||
|
||||
if (isBulk.value) {
|
||||
val found = player.matteryPlayer!!.inventoryAndExopack
|
||||
@ -116,11 +117,11 @@ class PainterMenu(
|
||||
}
|
||||
|
||||
val listeners = ISubscriptable.Impl<Unit>()
|
||||
val possibleRecipes = ArrayList<PainterRecipe>()
|
||||
val possibleRecipes = ArrayList<RecipeHolder<PainterRecipe>>()
|
||||
|
||||
private fun rescan() {
|
||||
possibleRecipes.clear()
|
||||
possibleRecipes.addAll(inventory.player.level().recipeManager.byType(MRecipes.PAINTER).values.iterator().filter { it.input.test(inputContainer[0]) })
|
||||
possibleRecipes.addAll(inventory.player.level().recipeManager.byType(MRecipes.PAINTER).values.iterator().filter { it.value.input.test(inputContainer[0]) })
|
||||
listeners.accept(Unit)
|
||||
if (tile !is PainterBlockEntity) return
|
||||
|
||||
@ -129,10 +130,10 @@ class PainterMenu(
|
||||
} else {
|
||||
val recipe = inventory.player.level().recipeManager.byType(MRecipes.PAINTER)[selectedRecipe]
|
||||
|
||||
if (recipe == null || !recipe.canCraft(dyeStoredDirect) || !recipe.matches(inputContainer, inventory.player.level())) {
|
||||
if (recipe == null || !recipe.value.canCraft(dyeStoredDirect) || !recipe.value.matches(inputContainer, inventory.player.level())) {
|
||||
outputContainer.clearContent()
|
||||
} else {
|
||||
outputContainer[0] = recipe.assemble(inputContainer, inventory.player.level().registryAccess())
|
||||
outputContainer[0] = recipe.value.assemble(inputContainer, inventory.player.level().registryAccess())
|
||||
lastRecipe = recipe
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ class MatterEntanglerMenu(
|
||||
.recipeManager
|
||||
.byType(MRecipes.MATTER_ENTANGLER)
|
||||
.values
|
||||
.any { it.preemptivelyMatches(shadow, level) }
|
||||
.any { it.value.preemptivelyMatches(shadow, level) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,20 +5,17 @@ import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import net.minecraftforge.event.network.CustomPayloadEvent
|
||||
import net.minecraftforge.network.PacketDistributor
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.mc.otm.block.entity.matter.MatterPanelBlockEntity
|
||||
import ru.dbotthepony.mc.otm.capability.matter.*
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.core.GetterSetter
|
||||
import ru.dbotthepony.mc.otm.core.addSorted
|
||||
import ru.dbotthepony.mc.otm.core.map
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.core.util.DecimalValueCodec
|
||||
import ru.dbotthepony.mc.otm.core.util.ItemSorter
|
||||
import ru.dbotthepony.mc.otm.core.util.NullValueCodec
|
||||
import ru.dbotthepony.mc.otm.core.util.codec
|
||||
import ru.dbotthepony.mc.otm.core.util.writeCollection
|
||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphListener
|
||||
import ru.dbotthepony.mc.otm.graph.matter.MatterGraph
|
||||
@ -30,20 +27,16 @@ import ru.dbotthepony.mc.otm.registry.MMenus
|
||||
import java.util.*
|
||||
import java.util.function.Predicate
|
||||
import java.util.function.Supplier
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class CancelTaskPacket(val id: UUID) : MatteryPacket {
|
||||
override fun write(buff: FriendlyByteBuf) {
|
||||
buff.writeUUID(id)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
context.enqueueWork {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val sender = context.sender!!
|
||||
(sender.containerMenu as? MatterPanelMenu)?.receiveTaskCancel(sender, id)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): CancelTaskPacket {
|
||||
@ -58,10 +51,8 @@ class PatternsChangePacket(val isUpdate: Boolean, val patterns: Collection<Patte
|
||||
buff.writeCollection(patterns, PatternState::write)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
context.enqueueWork {
|
||||
val menu = minecraft.player?.containerMenu as? MatterPanelMenu ?: return@enqueueWork
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val menu = minecraft.player?.containerMenu as? MatterPanelMenu ?: return
|
||||
|
||||
if (isUpdate) {
|
||||
menu.networkPatternsUpdated(patterns)
|
||||
@ -69,7 +60,6 @@ class PatternsChangePacket(val isUpdate: Boolean, val patterns: Collection<Patte
|
||||
menu.networkPatternsRemoved(patterns)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): PatternsChangePacket {
|
||||
@ -84,10 +74,8 @@ class TasksChangePacket(val isUpdate: Boolean, val tasks: Collection<Replication
|
||||
buff.writeCollection(tasks, ReplicationTask::write)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
context.enqueueWork {
|
||||
val menu = minecraft.player?.containerMenu as? MatterPanelMenu ?: return@enqueueWork
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val menu = minecraft.player?.containerMenu as? MatterPanelMenu ?: return
|
||||
|
||||
if (isUpdate) {
|
||||
menu.networkTasksUpdated(tasks)
|
||||
@ -95,7 +83,6 @@ class TasksChangePacket(val isUpdate: Boolean, val tasks: Collection<Replication
|
||||
menu.networkTasksRemoved(tasks)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): TasksChangePacket {
|
||||
@ -112,15 +99,12 @@ class ReplicationRequestPacket(val id: UUID, amount: Int) : MatteryPacket {
|
||||
buff.writeInt(amount)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
context.enqueueWork {
|
||||
val sender = context.sender ?: return@enqueueWork
|
||||
val menu = sender.containerMenu as? MatterPanelMenu ?: return@enqueueWork
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val sender = context.sender ?: return
|
||||
val menu = sender.containerMenu as? MatterPanelMenu ?: return
|
||||
|
||||
menu.requestReplication(sender, id, amount)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): ReplicationRequestPacket {
|
||||
@ -339,7 +323,7 @@ class MatterPanelMenu(
|
||||
}
|
||||
|
||||
private fun sendNetwork(packet: Any) {
|
||||
MenuNetworkChannel.send(PacketDistributor.PLAYER.with { inventory.player as ServerPlayer }, packet)
|
||||
MenuNetworkChannel.send(inventory.player, packet)
|
||||
}
|
||||
|
||||
fun fullPatternBroadcast() {
|
||||
|
@ -9,8 +9,8 @@ import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraftforge.event.network.CustomPayloadEvent
|
||||
import net.minecraftforge.network.NetworkDirection
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import net.minecraftforge.network.PacketDistributor
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.mc.otm.android.AndroidResearchManager
|
||||
@ -21,7 +21,6 @@ import ru.dbotthepony.mc.otm.client.onceClient
|
||||
import ru.dbotthepony.mc.otm.item.QuantumBatteryItem
|
||||
import ru.dbotthepony.mc.otm.matter.MatterManager
|
||||
import java.util.*
|
||||
import java.util.function.Supplier
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class SmokeParticlesPacket(val x: Double, val y: Double, val z: Double) : MatteryPacket {
|
||||
@ -31,14 +30,11 @@ class SmokeParticlesPacket(val x: Double, val y: Double, val z: Double) : Matter
|
||||
buff.writeDouble(z)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
context.enqueueWork {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
minecraft.player?.level()?.let {
|
||||
makeSmoke(x, y, z, it.random, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): SmokeParticlesPacket {
|
||||
@ -104,13 +100,9 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v
|
||||
}
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
|
||||
context.enqueueWork {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
execute()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val backlog = WeakHashMap<Level, Object2ObjectOpenHashMap<BlockPos, ArrayList<BlockEntitySyncPacket>>>()
|
||||
@ -128,15 +120,15 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v
|
||||
}
|
||||
|
||||
object GenericNetworkChannel : MatteryNetworkChannel(
|
||||
version = "4",
|
||||
version = 5,
|
||||
name = "generic"
|
||||
) {
|
||||
fun makeSmoke(x: Double, y: Double, z: Double, level: Level) {
|
||||
send(PacketDistributor.NEAR.with { PacketDistributor.TargetPoint(x, y, z, 64.0, level.dimension()) }, SmokeParticlesPacket(x, y, z))
|
||||
send(PacketDistributor.NEAR.with(PacketDistributor.TargetPoint(x, y, z, 64.0, level.dimension())), SmokeParticlesPacket(x, y, z))
|
||||
}
|
||||
|
||||
fun makeSmoke(excluded: ServerPlayer, x: Double, y: Double, z: Double) {
|
||||
send(PacketDistributor.NEAR.with { PacketDistributor.TargetPoint(excluded, x, y, z, 64.0, excluded.level().dimension()) }, SmokeParticlesPacket(x, y, z))
|
||||
send(PacketDistributor.NEAR.with(PacketDistributor.TargetPoint(excluded, x, y, z, 64.0, excluded.level().dimension())), SmokeParticlesPacket(x, y, z))
|
||||
}
|
||||
|
||||
fun register() {
|
||||
@ -145,7 +137,7 @@ object GenericNetworkChannel : MatteryNetworkChannel(
|
||||
add(BlockEntitySyncPacket::class.java, BlockEntitySyncPacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT)
|
||||
add(ItemEntityDataPacket::class.java, ItemEntityDataPacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT)
|
||||
|
||||
add(AndroidResearchManager.SyncPacket::class.java, AndroidResearchManager::readSyncPacket, NetworkDirection.PLAY_TO_CLIENT)
|
||||
add(AndroidResearchManager.SyncPacket::class.java, AndroidResearchManager::readSyncPacket, NetworkDirection.PLAY_TO_CLIENT, handleOnMainThread = false)
|
||||
add(MatterManager.SyncPacket::class.java, MatterManager::readSyncPacket, NetworkDirection.PLAY_TO_CLIENT)
|
||||
|
||||
add(SmokeParticlesPacket::class, SmokeParticlesPacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT)
|
||||
|
@ -1,67 +1,48 @@
|
||||
package ru.dbotthepony.mc.otm.network
|
||||
|
||||
import java.util.function.Function
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraftforge.event.TickEvent
|
||||
import net.minecraftforge.event.TickEvent.ServerTickEvent
|
||||
import net.minecraftforge.event.server.ServerStoppedEvent
|
||||
import net.minecraftforge.event.server.ServerStoppingEvent
|
||||
import net.minecraftforge.event.network.CustomPayloadEvent
|
||||
import net.minecraftforge.network.Channel
|
||||
import net.minecraftforge.network.ChannelBuilder
|
||||
import net.minecraftforge.network.NetworkDirection
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import net.minecraftforge.network.NetworkRegistry
|
||||
import net.minecraftforge.network.PacketDistributor
|
||||
import net.minecraftforge.network.simple.SimpleChannel
|
||||
import net.minecraftforge.network.SimpleChannel
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.mc.otm.NULLABLE_MINECRAFT_SERVER
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import java.math.BigDecimal
|
||||
import java.math.BigInteger
|
||||
import java.util.Optional
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.concurrent.ConcurrentLinkedDeque
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
import java.util.concurrent.locks.LockSupport
|
||||
import java.util.function.BiConsumer
|
||||
import java.util.function.Supplier
|
||||
import java.util.function.Function
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
fun Supplier<NetworkEvent.Context>.enqueueWork(lambda: Runnable): CompletableFuture<Void> = get().enqueueWork(lambda)
|
||||
fun Supplier<NetworkEvent.Context>.enqueueWork(lambda: () -> Unit): CompletableFuture<Void> = get().enqueueWork(lambda)
|
||||
var Supplier<NetworkEvent.Context>.packetHandled: Boolean
|
||||
get() = get().packetHandled
|
||||
set(value) { get().packetHandled = value }
|
||||
|
||||
val Supplier<NetworkEvent.Context>.sender: ServerPlayer?
|
||||
get() = get().sender
|
||||
|
||||
interface MatteryPacket {
|
||||
fun write(buff: FriendlyByteBuf)
|
||||
fun play(context: Supplier<NetworkEvent.Context>)
|
||||
fun play(context: CustomPayloadEvent.Context)
|
||||
}
|
||||
|
||||
abstract class MatteryNetworkChannel(val version: String, val name: String) {
|
||||
val channel: SimpleChannel = NetworkRegistry.newSimpleChannel(
|
||||
ResourceLocation(OverdriveThatMatters.MOD_ID, name),
|
||||
{ version },
|
||||
{ it == version },
|
||||
{ it == version },
|
||||
)
|
||||
abstract class MatteryNetworkChannel(val version: Int, val name: String) {
|
||||
val channel: SimpleChannel = ChannelBuilder
|
||||
.named(ResourceLocation(OverdriveThatMatters.MOD_ID, name))
|
||||
.acceptedVersions(Channel.VersionTest.exact(version))
|
||||
.networkProtocolVersion(version)
|
||||
.simpleChannel()
|
||||
|
||||
fun sendToServer(packet: Any) = channel.sendToServer(packet)
|
||||
fun sendToServer(packet: Any) = channel.send(packet, PacketDistributor.SERVER.noArg())
|
||||
|
||||
fun send(ply: Player, packet: Any) {
|
||||
if (ply is ServerPlayer) {
|
||||
queue.add(Task(channel, PacketDistributor.PLAYER.with { ply }, packet))
|
||||
queue.add(Task(channel, PacketDistributor.PLAYER.with(ply), packet))
|
||||
}
|
||||
}
|
||||
|
||||
fun sendNow(ply: Player, packet: Any) {
|
||||
if (ply is ServerPlayer) {
|
||||
channel.send(PacketDistributor.PLAYER.with { ply }, packet)
|
||||
channel.send(packet, PacketDistributor.PLAYER.with(ply))
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,7 +51,7 @@ abstract class MatteryNetworkChannel(val version: String, val name: String) {
|
||||
return
|
||||
}
|
||||
|
||||
queue.add(Task(channel, PacketDistributor.TRACKING_ENTITY.with { entity }, packet))
|
||||
queue.add(Task(channel, PacketDistributor.TRACKING_ENTITY.with(entity), packet))
|
||||
}
|
||||
|
||||
fun sendTrackingAndSelf(entity: Entity, packet: Any) {
|
||||
@ -78,7 +59,7 @@ abstract class MatteryNetworkChannel(val version: String, val name: String) {
|
||||
return
|
||||
}
|
||||
|
||||
queue.add(Task(channel, PacketDistributor.TRACKING_ENTITY_AND_SELF.with { entity }, packet))
|
||||
queue.add(Task(channel, PacketDistributor.TRACKING_ENTITY_AND_SELF.with(entity), packet))
|
||||
}
|
||||
|
||||
fun send(distributor: PacketDistributor.PacketTarget, packet: Any) {
|
||||
@ -86,7 +67,7 @@ abstract class MatteryNetworkChannel(val version: String, val name: String) {
|
||||
}
|
||||
|
||||
fun sendNow(distributor: PacketDistributor.PacketTarget, packet: Any) {
|
||||
channel.send(distributor, packet)
|
||||
channel.send(packet, distributor)
|
||||
}
|
||||
|
||||
private var nextNetworkPacketID = 0
|
||||
@ -95,31 +76,43 @@ abstract class MatteryNetworkChannel(val version: String, val name: String) {
|
||||
packetClass: Class<T>,
|
||||
writer: BiConsumer<T, FriendlyByteBuf>,
|
||||
reader: Function<FriendlyByteBuf, T>,
|
||||
handler: BiConsumer<T, Supplier<NetworkEvent.Context>>,
|
||||
direction: NetworkDirection? = null
|
||||
handler: BiConsumer<T, CustomPayloadEvent.Context>,
|
||||
direction: NetworkDirection? = null,
|
||||
handleOnMainThread: Boolean = true,
|
||||
) {
|
||||
if (nextNetworkPacketID >= 256) {
|
||||
throw IndexOutOfBoundsException("Network message ID overflow!")
|
||||
}
|
||||
|
||||
@Suppress("INACCESSIBLE_TYPE")
|
||||
channel.registerMessage(nextNetworkPacketID++, packetClass, writer, reader, handler, if (direction == null) Optional.empty() else Optional.of(direction))
|
||||
val builder = channel.messageBuilder(packetClass, direction)
|
||||
|
||||
if (handleOnMainThread) {
|
||||
builder.consumerMainThread(handler)
|
||||
} else {
|
||||
builder.consumerNetworkThread(handler)
|
||||
}
|
||||
|
||||
builder.encoder(writer)
|
||||
builder.decoder(reader)
|
||||
builder.add()
|
||||
}
|
||||
|
||||
fun <T : MatteryPacket> add(
|
||||
packetClass: Class<T>,
|
||||
reader: Function<FriendlyByteBuf, T>,
|
||||
direction: NetworkDirection? = null
|
||||
direction: NetworkDirection? = null,
|
||||
handleOnMainThread: Boolean = true,
|
||||
) {
|
||||
add(packetClass, MatteryPacket::write, reader, MatteryPacket::play, direction)
|
||||
add(packetClass, MatteryPacket::write, reader, MatteryPacket::play, direction, handleOnMainThread)
|
||||
}
|
||||
|
||||
fun <T : MatteryPacket> add(
|
||||
packetClass: KClass<T>,
|
||||
reader: Function<FriendlyByteBuf, T>,
|
||||
direction: NetworkDirection? = null
|
||||
direction: NetworkDirection? = null,
|
||||
handleOnMainThread: Boolean = true,
|
||||
) {
|
||||
add(packetClass.java, MatteryPacket::write, reader, MatteryPacket::play, direction)
|
||||
add(packetClass.java, MatteryPacket::write, reader, MatteryPacket::play, direction, handleOnMainThread)
|
||||
}
|
||||
|
||||
private data class Task(val channel: SimpleChannel, val target: PacketDistributor.PacketTarget, val packet: Any)
|
||||
@ -150,7 +143,7 @@ abstract class MatteryNetworkChannel(val version: String, val name: String) {
|
||||
LockSupport.park()
|
||||
} else {
|
||||
try {
|
||||
task.channel.send(task.target, task.packet)
|
||||
task.channel.send(task.packet, task.target)
|
||||
} catch(err: Throwable) {
|
||||
logger.error("Error executing network dispatcher task", err)
|
||||
}
|
||||
|
@ -8,9 +8,9 @@ import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraftforge.event.network.CustomPayloadEvent
|
||||
import net.minecraftforge.network.NetworkDirection.PLAY_TO_CLIENT
|
||||
import net.minecraftforge.network.NetworkDirection.PLAY_TO_SERVER
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.mc.otm.android.AndroidActiveFeature
|
||||
import ru.dbotthepony.mc.otm.android.AndroidFeatureType
|
||||
@ -40,7 +40,6 @@ import ru.dbotthepony.mc.otm.registry.AndroidFeatures
|
||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.util.UUID
|
||||
import java.util.function.Supplier
|
||||
|
||||
class MatteryPlayerFieldPacket(val bytes: ByteArray, val length: Int, val isPublic: Boolean, val target: UUID? = null) : MatteryPacket {
|
||||
constructor(stream: FastByteArrayOutputStream, isPublic: Boolean, target: UUID? = null) : this(stream.array, stream.length, isPublic, target)
|
||||
@ -55,15 +54,13 @@ class MatteryPlayerFieldPacket(val bytes: ByteArray, val length: Int, val isPubl
|
||||
buff.writeBytes(bytes, 0, length)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
context.get().enqueueWork {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val player: MatteryPlayerCapability
|
||||
|
||||
if (target != null) {
|
||||
player = minecraft.level?.players()?.firstOrNull { it.uuid == target }?.matteryPlayer ?: return@enqueueWork
|
||||
player = minecraft.level?.players()?.firstOrNull { it.uuid == target }?.matteryPlayer ?: return
|
||||
} else {
|
||||
player = minecraft.player?.matteryPlayer ?: return@enqueueWork
|
||||
player = minecraft.player?.matteryPlayer ?: return
|
||||
}
|
||||
|
||||
if (isPublic) {
|
||||
@ -72,7 +69,6 @@ class MatteryPlayerFieldPacket(val bytes: ByteArray, val length: Int, val isPubl
|
||||
player.synchronizer.read(ByteArrayInputStream(bytes, 0, length))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): MatteryPlayerFieldPacket {
|
||||
@ -93,19 +89,16 @@ class AndroidResearchRequestPacket(val type: AndroidResearchType) : MatteryPacke
|
||||
buff.writeUtf(type.id.toString())
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
context.enqueueWork {
|
||||
val ply = context.get().sender ?: return@enqueueWork
|
||||
if (ply.isSpectator) return@enqueueWork
|
||||
val android = ply.matteryPlayer ?: return@enqueueWork
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val ply = context.sender ?: return
|
||||
if (ply.isSpectator) return
|
||||
val android = ply.matteryPlayer ?: return
|
||||
|
||||
if (!android.isAndroid || ply.containerMenu !is AndroidStationMenu)
|
||||
return@enqueueWork
|
||||
return
|
||||
|
||||
android.getResearch(type).research()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): AndroidResearchRequestPacket {
|
||||
@ -121,16 +114,11 @@ class AndroidResearchSyncPacket(val type: AndroidResearchType, val dataList: Fas
|
||||
buff.writeBytes(dataList.array, 0, dataList.length)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
dataBytes ?: throw NullPointerException("No data bytes array is present")
|
||||
|
||||
context.get().packetHandled = true
|
||||
context.get().enqueueWork {
|
||||
val android = minecraft.player?.matteryPlayer ?: return@enqueueWork
|
||||
|
||||
val android = minecraft.player?.matteryPlayer ?: return
|
||||
android.getResearch(type).applyNetworkPayload(ByteArrayInputStream(dataBytes))
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): AndroidResearchSyncPacket {
|
||||
@ -149,16 +137,11 @@ class AndroidFeatureSyncPacket(val type: AndroidFeatureType<*>, val dataList: Fa
|
||||
buff.writeBytes(dataList.array, 0, dataList.length)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
dataBytes ?: throw NullPointerException("No data bytes array is present")
|
||||
|
||||
context.get().packetHandled = true
|
||||
context.get().enqueueWork {
|
||||
val android = minecraft.player?.matteryPlayer ?: return@enqueueWork
|
||||
|
||||
val android = minecraft.player?.matteryPlayer ?: return
|
||||
android.computeIfAbsent(type).applyNetworkPayload(ByteArrayInputStream(dataBytes))
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): AndroidFeatureSyncPacket {
|
||||
@ -175,14 +158,10 @@ class AndroidFeatureRemovePacket(val type: AndroidFeatureType<*>) : MatteryPacke
|
||||
buff.writeInt(MRegistry.ANDROID_FEATURES.getID(type))
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.get().packetHandled = true
|
||||
context.get().enqueueWork {
|
||||
val android = minecraft.player?.matteryPlayer ?: return@enqueueWork
|
||||
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val android = minecraft.player?.matteryPlayer ?: return
|
||||
android.removeFeature(type)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): AndroidFeatureRemovePacket {
|
||||
@ -202,7 +181,7 @@ class PlayerIterationPacket(val iteration: Int, val deathLog: List<Pair<Int, Com
|
||||
}
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
context.packetHandled = true
|
||||
|
||||
MatteryGUI.iteration = iteration
|
||||
@ -234,17 +213,14 @@ class ExopackCarriedPacket(val itemStack: ItemStack, val containerState: Int) :
|
||||
buff.writeInt(containerState)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
context.enqueueWork {
|
||||
val mattery = minecraft.player?.matteryPlayer ?: return@enqueueWork
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val mattery = minecraft.player?.matteryPlayer ?: return
|
||||
|
||||
if (mattery.hasExopack) {
|
||||
mattery.exoPackMenu.carried = itemStack
|
||||
mattery.exoPackMenu.stateId = containerState
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): ExopackCarriedPacket {
|
||||
@ -260,33 +236,29 @@ class ExopackSlotPacket(val slotId: Int, val itemStack: ItemStack, val container
|
||||
buff.writeInt(containerState)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
if (slotId < 0) {
|
||||
LOGGER.error("Unknown slot with ID {} in exosuit menu", slotId)
|
||||
return
|
||||
}
|
||||
|
||||
context.enqueueWork {
|
||||
val mattery = minecraft.player?.matteryPlayer ?: return@enqueueWork
|
||||
val mattery = minecraft.player?.matteryPlayer ?: return
|
||||
|
||||
if (mattery.hasExopack) {
|
||||
if (slotId >= mattery.exoPackMenu.slots.size) {
|
||||
LOGGER.error("Unknown slot with ID {} in exosuit menu", slotId)
|
||||
return@enqueueWork
|
||||
return
|
||||
}
|
||||
|
||||
// don't duplicate data
|
||||
// really.
|
||||
if (mattery.exoPackMenu.slots[slotId].container == minecraft.player?.inventory && minecraft.player?.containerMenu !is ExopackInventoryMenu)
|
||||
return@enqueueWork
|
||||
return
|
||||
|
||||
mattery.exoPackMenu.slots[slotId].set(itemStack)
|
||||
mattery.exoPackMenu.stateId = containerState
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOGGER = LogManager.getLogger()
|
||||
@ -309,16 +281,13 @@ class ExopackMenuInitPacket(val slots: List<ItemStack>, val carried: ItemStack,
|
||||
buff.writeInt(containerState)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
context.enqueueWork {
|
||||
val mattery = minecraft.player?.matteryPlayer ?: return@enqueueWork
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val mattery = minecraft.player?.matteryPlayer ?: return
|
||||
|
||||
if (mattery.hasExopack) {
|
||||
mattery.exoPackMenu.initializeContents(containerState, slots, carried)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): ExopackMenuInitPacket {
|
||||
@ -340,17 +309,14 @@ class ExopackMenuInitPacket(val slots: List<ItemStack>, val carried: ItemStack,
|
||||
object ExopackMenuOpen : MatteryPacket {
|
||||
override fun write(buff: FriendlyByteBuf) {}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
context.enqueueWork {
|
||||
val player = context.sender ?: return@enqueueWork
|
||||
val mattery = player.matteryPlayer ?: return@enqueueWork
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val player = context.sender ?: return
|
||||
val mattery = player.matteryPlayer ?: return
|
||||
|
||||
if (mattery.hasExopack) {
|
||||
player.containerMenu = mattery.exoPackMenu
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SwitchAndroidFeaturePacket(val type: AndroidFeatureType<*>, val newState: Boolean) : MatteryPacket {
|
||||
@ -359,17 +325,14 @@ class SwitchAndroidFeaturePacket(val type: AndroidFeatureType<*>, val newState:
|
||||
buff.writeBoolean(newState)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
|
||||
context.enqueueWork {
|
||||
val matteryPlayer = context.sender?.matteryPlayer ?: return@enqueueWork
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val matteryPlayer = context.sender?.matteryPlayer ?: return
|
||||
|
||||
if (!matteryPlayer.isAndroid) {
|
||||
return@enqueueWork
|
||||
return
|
||||
}
|
||||
|
||||
val feature = matteryPlayer.getFeature(type) ?: return@enqueueWork
|
||||
val feature = matteryPlayer.getFeature(type) ?: return
|
||||
|
||||
if (feature is AndroidActiveFeature && feature.allowToSwitchByPlayer && (!matteryPlayer.ply.isSpectator || feature.allowToSwitchByPlayerWhileSpectator)) {
|
||||
matteryPlayer.features
|
||||
@ -382,7 +345,6 @@ class SwitchAndroidFeaturePacket(val type: AndroidFeatureType<*>, val newState:
|
||||
feature.isActive = newState
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): SwitchAndroidFeaturePacket {
|
||||
@ -396,23 +358,19 @@ class ActivateAndroidFeaturePacket(val type: AndroidFeatureType<*>) : MatteryPac
|
||||
buff.writeInt(MRegistry.ANDROID_FEATURES.getID(type))
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
|
||||
context.enqueueWork {
|
||||
val matteryPlayer = context.sender?.matteryPlayer ?: return@enqueueWork
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val matteryPlayer = context.sender?.matteryPlayer ?: return
|
||||
|
||||
if (!matteryPlayer.isAndroid || matteryPlayer.ply.isSpectator) {
|
||||
return@enqueueWork
|
||||
return
|
||||
}
|
||||
|
||||
val feature = matteryPlayer.getFeature(type) as? AndroidActiveFeature ?: return@enqueueWork
|
||||
val feature = matteryPlayer.getFeature(type) as? AndroidActiveFeature ?: return
|
||||
|
||||
if (feature.isActive || feature.allowToSwitchByPlayer) {
|
||||
feature.activate(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): ActivateAndroidFeaturePacket {
|
||||
@ -430,19 +388,16 @@ class PickItemFromInventoryPacket(
|
||||
buff.writeVarInt(sourceExosuitSlot)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
|
||||
context.enqueueWork {
|
||||
val player = context.sender ?: return@enqueueWork
|
||||
val mattery = player.matteryPlayer ?: return@enqueueWork
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
val player = context.sender ?: return
|
||||
val mattery = player.matteryPlayer ?: return
|
||||
|
||||
if (!mattery.hasExopack || sourceExosuitSlot !in 0 until mattery.exopackContainer.containerSize) {
|
||||
return@enqueueWork
|
||||
return
|
||||
}
|
||||
|
||||
if (!Inventory.isHotbarSlot(targetHotbarSlot)) {
|
||||
return@enqueueWork
|
||||
return
|
||||
}
|
||||
|
||||
player.inventory.selected = targetHotbarSlot
|
||||
@ -454,7 +409,6 @@ class PickItemFromInventoryPacket(
|
||||
|
||||
player.connection.send(ClientboundSetCarriedItemPacket(targetHotbarSlot))
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): PickItemFromInventoryPacket {
|
||||
@ -468,7 +422,7 @@ class GlitchPacket(val millis: Long) : MatteryPacket {
|
||||
buff.writeVarLong(millis)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
context.packetHandled = true
|
||||
GlitchRenderer.glitchFor(millis)
|
||||
}
|
||||
@ -487,7 +441,7 @@ class ShockwaveEffectPacket(val pos: Vector) : MatteryPacket {
|
||||
buff.writeDouble(pos.z)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
context.packetHandled = true
|
||||
ShockwaveRenderer.handle(this)
|
||||
}
|
||||
@ -502,7 +456,7 @@ class ShockwaveEffectPacket(val pos: Vector) : MatteryPacket {
|
||||
object DisplayExopackPacket : MatteryPacket {
|
||||
override fun write(buff: FriendlyByteBuf) {}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
context.packetHandled = true
|
||||
context.sender?.matteryPlayer?.isExopackVisible = true
|
||||
}
|
||||
@ -511,7 +465,7 @@ object DisplayExopackPacket : MatteryPacket {
|
||||
object HideExopackPacket : MatteryPacket {
|
||||
override fun write(buff: FriendlyByteBuf) {}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
context.packetHandled = true
|
||||
context.sender?.matteryPlayer?.isExopackVisible = false
|
||||
}
|
||||
@ -520,7 +474,7 @@ object HideExopackPacket : MatteryPacket {
|
||||
object EnableExopackGlowPacket : MatteryPacket {
|
||||
override fun write(buff: FriendlyByteBuf) {}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
context.packetHandled = true
|
||||
context.sender?.matteryPlayer?.exopackGlows = true
|
||||
}
|
||||
@ -529,7 +483,7 @@ object EnableExopackGlowPacket : MatteryPacket {
|
||||
object DisableExopackGlowPacket : MatteryPacket {
|
||||
override fun write(buff: FriendlyByteBuf) {}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
context.packetHandled = true
|
||||
context.sender?.matteryPlayer?.exopackGlows = false
|
||||
}
|
||||
@ -538,7 +492,7 @@ object DisableExopackGlowPacket : MatteryPacket {
|
||||
object ResetExopackColorPacket : MatteryPacket {
|
||||
override fun write(buff: FriendlyByteBuf) {}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
context.packetHandled = true
|
||||
context.sender?.matteryPlayer?.exopackColor = null
|
||||
}
|
||||
@ -551,7 +505,7 @@ data class SetExopackColorPacket(val color: RGBAColor) : MatteryPacket {
|
||||
buff.writeFloat(color.blue)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
context.packetHandled = true
|
||||
context.sender?.matteryPlayer?.exopackColor = color
|
||||
}
|
||||
@ -568,11 +522,10 @@ data class ExopackSmokePacket(val player: UUID) : MatteryPacket {
|
||||
buff.writeUUID(player)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
context.packetHandled = true
|
||||
// minecraft.player?.level()?.getPlayerByUUID(player)?.matteryPlayer?.spawnExopackSmoke = true
|
||||
|
||||
context.enqueueWork {
|
||||
minecraft.player?.level()?.getPlayerByUUID(player)?.let { ply ->
|
||||
if (ply != minecraft.player || minecraft.gameRenderer.mainCamera.isDetached) {
|
||||
var (x, y, z) = ply.position
|
||||
@ -599,8 +552,6 @@ data class ExopackSmokePacket(val player: UUID) : MatteryPacket {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): ExopackSmokePacket {
|
||||
return ExopackSmokePacket(buff.readUUID())
|
||||
@ -609,7 +560,7 @@ data class ExopackSmokePacket(val player: UUID) : MatteryPacket {
|
||||
}
|
||||
|
||||
object MatteryPlayerNetworkChannel : MatteryNetworkChannel(
|
||||
version = "6",
|
||||
version = 7,
|
||||
name = "player"
|
||||
) {
|
||||
fun register() {
|
||||
|
@ -3,8 +3,8 @@ package ru.dbotthepony.mc.otm.network
|
||||
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraftforge.event.network.CustomPayloadEvent
|
||||
import net.minecraftforge.network.NetworkDirection
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||
import ru.dbotthepony.mc.otm.client.minecraft
|
||||
import ru.dbotthepony.mc.otm.compat.vanilla.InventoryScrollPacket
|
||||
@ -20,7 +20,6 @@ import ru.dbotthepony.mc.otm.menu.data.StackAddPacket
|
||||
import ru.dbotthepony.mc.otm.menu.data.StackChangePacket
|
||||
import ru.dbotthepony.mc.otm.menu.data.StackRemovePacket
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.util.function.Supplier
|
||||
|
||||
class MenuFieldPacket(val containerId: Int, val bytes: ByteArray, val length: Int) : MatteryPacket {
|
||||
constructor(containerId: Int, stream: FastByteArrayOutputStream) : this(containerId, stream.array, stream.length)
|
||||
@ -30,20 +29,16 @@ class MenuFieldPacket(val containerId: Int, val bytes: ByteArray, val length: In
|
||||
buff.writeBytes(bytes, 0, length)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.packetHandled = true
|
||||
|
||||
context.enqueueWork {
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
if (containerId == ExopackInventoryMenu.CONTAINER_ID) {
|
||||
minecraft.player?.matteryPlayer?.exoPackMenu?.mSynchronizer?.read(ByteArrayInputStream(bytes, 0, length))
|
||||
} else {
|
||||
val menu = minecraft.player?.containerMenu as? MatteryMenu ?: return@enqueueWork
|
||||
val menu = minecraft.player?.containerMenu as? MatteryMenu ?: return
|
||||
|
||||
if (menu.containerId == containerId)
|
||||
menu.mSynchronizer.read(ByteArrayInputStream(bytes, 0, length))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun read(buff: FriendlyByteBuf): MenuFieldPacket {
|
||||
@ -59,9 +54,8 @@ class SetCarriedPacket(val item: ItemStack) : MatteryPacket {
|
||||
buff.writeItem(item)
|
||||
}
|
||||
|
||||
override fun play(context: Supplier<NetworkEvent.Context>) {
|
||||
context.get().packetHandled = true
|
||||
context.get().enqueueWork { minecraft.player?.containerMenu?.carried = item }
|
||||
override fun play(context: CustomPayloadEvent.Context) {
|
||||
minecraft.player?.containerMenu?.carried = item
|
||||
}
|
||||
|
||||
companion object {
|
||||
@ -72,7 +66,7 @@ class SetCarriedPacket(val item: ItemStack) : MatteryPacket {
|
||||
}
|
||||
|
||||
object MenuNetworkChannel : MatteryNetworkChannel(
|
||||
version = "4",
|
||||
version = 5,
|
||||
name = "menu"
|
||||
) {
|
||||
fun register() {
|
||||
|
@ -5,7 +5,7 @@ import ru.dbotthepony.mc.otm.item.weapon.WeaponFireInputPacket
|
||||
import ru.dbotthepony.mc.otm.item.weapon.WeaponScopePacket
|
||||
|
||||
object WeaponNetworkChannel : MatteryNetworkChannel(
|
||||
version = "2",
|
||||
version = 3,
|
||||
name = "weapon"
|
||||
) {
|
||||
fun register() {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package ru.dbotthepony.mc.otm.recipe
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import com.mojang.serialization.Codec
|
||||
import net.minecraft.core.NonNullList
|
||||
import net.minecraft.core.RegistryAccess
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
@ -20,6 +21,8 @@ import ru.dbotthepony.mc.otm.capability.iterator
|
||||
import ru.dbotthepony.mc.otm.container.util.iterator
|
||||
import ru.dbotthepony.mc.otm.container.util.stream
|
||||
import ru.dbotthepony.mc.otm.core.filterNotNull
|
||||
import ru.dbotthepony.mc.otm.core.fromJson
|
||||
import ru.dbotthepony.mc.otm.core.fromJsonStrict
|
||||
|
||||
class EnergyContainerRecipe(val parent: ShapedRecipe) : CraftingRecipe, IShapedRecipe<CraftingContainer> by parent {
|
||||
override fun canCraftInDimensions(p_43999_: Int, p_44000_: Int): Boolean {
|
||||
@ -30,10 +33,6 @@ class EnergyContainerRecipe(val parent: ShapedRecipe) : CraftingRecipe, IShapedR
|
||||
return parent.getResultItem(p_267052_)
|
||||
}
|
||||
|
||||
override fun getId(): ResourceLocation {
|
||||
return parent.id
|
||||
}
|
||||
|
||||
override fun category(): CraftingBookCategory {
|
||||
return parent.category()
|
||||
}
|
||||
@ -105,12 +104,16 @@ class EnergyContainerRecipe(val parent: ShapedRecipe) : CraftingRecipe, IShapedR
|
||||
}
|
||||
|
||||
companion object : RecipeSerializer<EnergyContainerRecipe> {
|
||||
override fun fromJson(id: ResourceLocation, data: JsonObject): EnergyContainerRecipe {
|
||||
return EnergyContainerRecipe(ShapedRecipe.Serializer.SHAPED_RECIPE.fromJson(id, data))
|
||||
private val codec by lazy {
|
||||
RecipeSerializer.SHAPED_RECIPE.codec().xmap(::EnergyContainerRecipe, EnergyContainerRecipe::parent)
|
||||
}
|
||||
|
||||
override fun fromNetwork(id: ResourceLocation, data: FriendlyByteBuf): EnergyContainerRecipe? {
|
||||
return ShapedRecipe.Serializer.SHAPED_RECIPE.fromNetwork(id, data)?.let(::EnergyContainerRecipe)
|
||||
override fun codec(): Codec<EnergyContainerRecipe> {
|
||||
return codec
|
||||
}
|
||||
|
||||
override fun fromNetwork(data: FriendlyByteBuf): EnergyContainerRecipe? {
|
||||
return ShapedRecipe.Serializer.SHAPED_RECIPE.fromNetwork(data)?.let(::EnergyContainerRecipe)
|
||||
}
|
||||
|
||||
override fun toNetwork(buff: FriendlyByteBuf, value: EnergyContainerRecipe) {
|
||||
|
@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.recipe
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonSyntaxException
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.core.NonNullList
|
||||
import net.minecraft.core.RegistryAccess
|
||||
import net.minecraft.data.recipes.FinishedRecipe
|
||||
@ -19,18 +20,15 @@ import ru.dbotthepony.mc.otm.container.util.stream
|
||||
import ru.dbotthepony.mc.otm.core.isActuallyEmpty
|
||||
import ru.dbotthepony.mc.otm.core.isNotEmpty
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.data.Codec2RecipeSerializer
|
||||
import ru.dbotthepony.mc.otm.item.tool.ExplosiveHammerItem
|
||||
import ru.dbotthepony.mc.otm.registry.MItems
|
||||
|
||||
class ExplosiveHammerPrimingRecipe(private val _id: ResourceLocation, val payload: Ingredient) : CraftingRecipe {
|
||||
class ExplosiveHammerPrimingRecipe(val payload: Ingredient) : CraftingRecipe {
|
||||
override fun isIncomplete(): Boolean {
|
||||
return payload.isActuallyEmpty
|
||||
}
|
||||
|
||||
override fun getId(): ResourceLocation {
|
||||
return _id
|
||||
}
|
||||
|
||||
override fun isSpecial(): Boolean {
|
||||
return true
|
||||
}
|
||||
@ -61,7 +59,7 @@ class ExplosiveHammerPrimingRecipe(private val _id: ResourceLocation, val payloa
|
||||
}
|
||||
|
||||
override fun getSerializer(): RecipeSerializer<*> {
|
||||
return Companion
|
||||
return CODEC
|
||||
}
|
||||
|
||||
override fun category(): CraftingBookCategory {
|
||||
@ -72,39 +70,15 @@ class ExplosiveHammerPrimingRecipe(private val _id: ResourceLocation, val payloa
|
||||
return NonNullList.of(Ingredient.of(), Ingredient.of(MItems.EXPLOSIVE_HAMMER), Ingredient.of(Tags.Items.GUNPOWDER), payload)
|
||||
}
|
||||
|
||||
val finishedRecipe = object : FinishedRecipe {
|
||||
override fun serializeRecipeData(pJson: JsonObject) {
|
||||
pJson["payload"] = payload.toJson()
|
||||
}
|
||||
fun toFinished(id: ResourceLocation) = CODEC.toFinished(this, id)
|
||||
|
||||
override fun getId(): ResourceLocation {
|
||||
return _id
|
||||
companion object {
|
||||
val CODEC = Codec2RecipeSerializer<ExplosiveHammerPrimingRecipe> { p ->
|
||||
RecordCodecBuilder.create {
|
||||
it.group(
|
||||
p.ingredients.fieldOf("payload").forGetter(ExplosiveHammerPrimingRecipe::payload)
|
||||
).apply(it, ::ExplosiveHammerPrimingRecipe)
|
||||
}
|
||||
|
||||
override fun getType(): RecipeSerializer<*> {
|
||||
return Companion
|
||||
}
|
||||
|
||||
override fun serializeAdvancement(): JsonObject? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getAdvancementId(): ResourceLocation? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
companion object : RecipeSerializer<ExplosiveHammerPrimingRecipe> {
|
||||
override fun fromJson(pRecipeId: ResourceLocation, pSerializedRecipe: JsonObject): ExplosiveHammerPrimingRecipe {
|
||||
return ExplosiveHammerPrimingRecipe(pRecipeId, Ingredient.fromJson(pSerializedRecipe["payload"] ?: throw JsonSyntaxException("Missing `payload` from hammer priming recipe in $pRecipeId")))
|
||||
}
|
||||
|
||||
override fun fromNetwork(pRecipeId: ResourceLocation, pBuffer: FriendlyByteBuf): ExplosiveHammerPrimingRecipe {
|
||||
return ExplosiveHammerPrimingRecipe(pRecipeId, Ingredient.fromNetwork(pBuffer))
|
||||
}
|
||||
|
||||
override fun toNetwork(pBuffer: FriendlyByteBuf, pRecipe: ExplosiveHammerPrimingRecipe) {
|
||||
pRecipe.payload.toNetwork(pBuffer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,6 @@ interface IMatterEntanglerRecipe : IMatteryRecipe<CraftingContainer> {
|
||||
}
|
||||
|
||||
open class MatterEntanglerRecipe(
|
||||
private val id: ResourceLocation,
|
||||
override val ingredients: IIngredientMatrix,
|
||||
override val matter: Decimal,
|
||||
override val ticks: Double,
|
||||
@ -73,10 +72,6 @@ open class MatterEntanglerRecipe(
|
||||
return result
|
||||
}
|
||||
|
||||
override fun getId(): ResourceLocation {
|
||||
return id
|
||||
}
|
||||
|
||||
override fun getSerializer(): RecipeSerializer<*> {
|
||||
return SERIALIZER
|
||||
}
|
||||
@ -97,8 +92,8 @@ open class MatterEntanglerRecipe(
|
||||
return true
|
||||
}
|
||||
|
||||
fun toFinished(): FinishedRecipe {
|
||||
return SERIALIZER.toFinished(this)
|
||||
fun toFinished(id: ResourceLocation): FinishedRecipe {
|
||||
return SERIALIZER.toFinished(this, id)
|
||||
}
|
||||
|
||||
fun energetic() = Energy(this)
|
||||
@ -113,8 +108,8 @@ open class MatterEntanglerRecipe(
|
||||
}
|
||||
}
|
||||
|
||||
fun toFinished(): FinishedRecipe {
|
||||
return ENERGY_SERIALIZER.toFinished(this)
|
||||
fun toFinished(id: ResourceLocation): FinishedRecipe {
|
||||
return ENERGY_SERIALIZER.toFinished(this, id)
|
||||
}
|
||||
|
||||
override fun getSerializer(): RecipeSerializer<*> {
|
||||
@ -131,8 +126,8 @@ open class MatterEntanglerRecipe(
|
||||
}
|
||||
}
|
||||
|
||||
fun toFinished(): FinishedRecipe {
|
||||
return MATTER_SERIALIZER.toFinished(this)
|
||||
fun toFinished(id: ResourceLocation): FinishedRecipe {
|
||||
return MATTER_SERIALIZER.toFinished(this, id)
|
||||
}
|
||||
|
||||
override fun getSerializer(): RecipeSerializer<*> {
|
||||
@ -150,7 +145,7 @@ open class MatterEntanglerRecipe(
|
||||
ItemStack.CODEC.fieldOf("result").forGetter(MatterEntanglerRecipe::result),
|
||||
Codec.STRING.optionalFieldOf("uuidKey", "uuid").forGetter(MatterEntanglerRecipe::uuidKey),
|
||||
UUIDUtil.STRING_CODEC.optionalFieldOf("fixedUuid").forGetter(MatterEntanglerRecipe::fixedUuid)
|
||||
).apply(it) { a, b, c, d, e, f -> MatterEntanglerRecipe(context.id, a, b, c, d, e, f) }
|
||||
).apply(it, ::MatterEntanglerRecipe)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,14 +14,12 @@ import net.minecraft.world.item.crafting.Recipe
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer
|
||||
import net.minecraft.world.item.crafting.RecipeType
|
||||
import net.minecraft.world.level.Level
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.block.entity.decorative.PainterBlockEntity
|
||||
import ru.dbotthepony.mc.otm.container.get
|
||||
import ru.dbotthepony.mc.otm.core.isActuallyEmpty
|
||||
import ru.dbotthepony.mc.otm.core.nbt.set
|
||||
import ru.dbotthepony.mc.otm.core.tagNotNull
|
||||
import ru.dbotthepony.mc.otm.data.Codec2RecipeSerializer
|
||||
import ru.dbotthepony.mc.otm.data.IngredientCodec
|
||||
import ru.dbotthepony.mc.otm.data.PredicatedCodecList
|
||||
import ru.dbotthepony.mc.otm.data.minRange
|
||||
import ru.dbotthepony.mc.otm.registry.MRecipes
|
||||
@ -29,17 +27,15 @@ import java.util.EnumMap
|
||||
import java.util.function.Predicate
|
||||
|
||||
class PainterRecipe(
|
||||
private val id: ResourceLocation,
|
||||
val input: Ingredient,
|
||||
val output: ItemStack,
|
||||
val dyes: Map<DyeColor, Int>
|
||||
) : Recipe<Container> {
|
||||
constructor(
|
||||
id: ResourceLocation,
|
||||
input: Ingredient,
|
||||
output: ItemStack,
|
||||
dyes: Set<DyeColor>
|
||||
) : this(id, input, output, dyes.associateWith { 1 })
|
||||
) : this(input, output, dyes.associateWith { 1 })
|
||||
|
||||
fun canCraft(storedDyes: Map<DyeColor, Int>): Boolean {
|
||||
if (isIncomplete) return false
|
||||
@ -96,10 +92,6 @@ class PainterRecipe(
|
||||
return output
|
||||
}
|
||||
|
||||
override fun getId(): ResourceLocation {
|
||||
return id
|
||||
}
|
||||
|
||||
override fun getSerializer(): RecipeSerializer<*> {
|
||||
return SERIALIZER
|
||||
}
|
||||
@ -108,8 +100,8 @@ class PainterRecipe(
|
||||
return MRecipes.PAINTER
|
||||
}
|
||||
|
||||
fun toFinished(): FinishedRecipe {
|
||||
return SERIALIZER.toFinished(this)
|
||||
fun toFinished(id: ResourceLocation): FinishedRecipe {
|
||||
return SERIALIZER.toFinished(this, id)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@ -123,7 +115,7 @@ class PainterRecipe(
|
||||
Codec.list(DyeColor.CODEC).xmap({ it.associateWith { 1 } }, { ArrayList(it.keys) }) to Predicate { it.values.all { it == 1 } },
|
||||
Codec.unboundedMap(DyeColor.CODEC, Codec.INT.minRange(1)) to Predicate { true }
|
||||
).fieldOf("dyes").forGetter(PainterRecipe::dyes),
|
||||
).apply(it) { a, b, c -> PainterRecipe(context.id, a, b, c) }
|
||||
).apply(it, ::PainterRecipe)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,11 +20,9 @@ import ru.dbotthepony.mc.otm.core.isActuallyEmpty
|
||||
import ru.dbotthepony.mc.otm.registry.MRecipes
|
||||
import ru.dbotthepony.mc.otm.core.registryName
|
||||
import ru.dbotthepony.mc.otm.data.Codec2RecipeSerializer
|
||||
import ru.dbotthepony.mc.otm.data.IngredientCodec
|
||||
import ru.dbotthepony.mc.otm.data.minRange
|
||||
|
||||
class PlatePressRecipe(
|
||||
private val id: ResourceLocation,
|
||||
val input: Ingredient,
|
||||
val output: Ingredient,
|
||||
val count: Int = 1,
|
||||
@ -70,15 +68,13 @@ class PlatePressRecipe(
|
||||
override fun canCraftInDimensions(p_43999_: Int, p_44000_: Int) = true
|
||||
override fun getResultItem(registry: RegistryAccess): ItemStack = outputStack
|
||||
|
||||
override fun getId() = id
|
||||
|
||||
override fun getSerializer(): RecipeSerializer<*> {
|
||||
return SERIALIZER
|
||||
}
|
||||
|
||||
override fun getType(): RecipeType<PlatePressRecipe> = MRecipes.PLATE_PRESS
|
||||
|
||||
fun toFinished() = SERIALIZER.toFinished(this)
|
||||
fun toFinished(id: ResourceLocation) = SERIALIZER.toFinished(this, id)
|
||||
|
||||
companion object {
|
||||
val SERIALIZER = Codec2RecipeSerializer<PlatePressRecipe> { context ->
|
||||
@ -89,7 +85,7 @@ class PlatePressRecipe(
|
||||
Codec.INT.minRange(1).optionalFieldOf("count", 1).forGetter(PlatePressRecipe::count),
|
||||
Codec.INT.minRange(0).optionalFieldOf("workTime", 200).forGetter(PlatePressRecipe::workTime),
|
||||
FloatProvider.CODEC.optionalFieldOf("experience", ConstantFloat.ZERO).forGetter(PlatePressRecipe::experience)
|
||||
).apply(it) { a, b, c, d, e -> PlatePressRecipe(context.id, a, b, c, d, e) }
|
||||
).apply(it, ::PlatePressRecipe)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,15 @@ package ru.dbotthepony.mc.otm.recipe
|
||||
import com.google.common.collect.ImmutableList
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonPrimitive
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.core.NonNullList
|
||||
import net.minecraft.core.RegistryAccess
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.util.GsonHelper
|
||||
import net.minecraft.util.StringRepresentable
|
||||
import net.minecraft.world.inventory.CraftingContainer
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.crafting.CraftingBookCategory
|
||||
@ -27,6 +30,7 @@ import ru.dbotthepony.mc.otm.core.tagNotNull
|
||||
import ru.dbotthepony.mc.otm.core.util.readBinaryJson
|
||||
import ru.dbotthepony.mc.otm.core.util.writeBinaryJson
|
||||
import ru.dbotthepony.mc.otm.core.collect.stream
|
||||
import ru.dbotthepony.mc.otm.data.Codec2RecipeSerializer
|
||||
import java.util.stream.Stream
|
||||
|
||||
class UpgradeRecipe(
|
||||
@ -34,6 +38,8 @@ class UpgradeRecipe(
|
||||
copyPaths: Stream<Op>,
|
||||
val source: ResourceLocation,
|
||||
) : CraftingRecipe, IShapedRecipe<CraftingContainer> by parent {
|
||||
constructor(parent: ShapedRecipe, copyPaths: Collection<Op>, source: ResourceLocation) : this(parent, copyPaths.stream(), source)
|
||||
|
||||
override fun matches(p_44002_: CraftingContainer, p_44003_: Level): Boolean {
|
||||
return parent.matches(p_44002_, p_44003_)
|
||||
}
|
||||
@ -70,10 +76,6 @@ class UpgradeRecipe(
|
||||
return parent.toastSymbol
|
||||
}
|
||||
|
||||
override fun getId(): ResourceLocation {
|
||||
return parent.id
|
||||
}
|
||||
|
||||
override fun isIncomplete(): Boolean {
|
||||
return parent.isIncomplete
|
||||
}
|
||||
@ -86,42 +88,39 @@ class UpgradeRecipe(
|
||||
return parent.category()
|
||||
}
|
||||
|
||||
enum class OpType {
|
||||
enum class OpType : StringRepresentable {
|
||||
DIRECT {
|
||||
override fun deserialize(obj: JsonObject): Op {
|
||||
return Direct(GsonHelper.getAsString(obj, "path"))
|
||||
override val codec: Codec<Direct> = RecordCodecBuilder.create {
|
||||
it.group(
|
||||
Codec.STRING.fieldOf("path").forGetter(Direct::path)
|
||||
).apply(it, ::Direct)
|
||||
}
|
||||
}, INDIRECT {
|
||||
override fun deserialize(obj: JsonObject): Op {
|
||||
return Indirect(GsonHelper.getAsString(obj, "source"), GsonHelper.getAsString(obj, "destination"))
|
||||
override val codec: Codec<Indirect> = RecordCodecBuilder.create {
|
||||
it.group(
|
||||
Codec.STRING.fieldOf("source").forGetter(Indirect::pathSource),
|
||||
Codec.STRING.fieldOf("destination").forGetter(Indirect::pathDestination),
|
||||
).apply(it, ::Indirect)
|
||||
}
|
||||
};
|
||||
|
||||
abstract fun deserialize(obj: JsonObject): Op
|
||||
override fun getSerializedName(): String {
|
||||
return name.lowercase()
|
||||
}
|
||||
|
||||
interface Op {
|
||||
val type: OpType
|
||||
fun apply(source: CompoundTag, destination: CompoundTag)
|
||||
fun serialize(json: JsonObject)
|
||||
|
||||
fun serialize(): JsonObject {
|
||||
return JsonObject().also {
|
||||
it["type"] = JsonPrimitive(type.name)
|
||||
serialize(it)
|
||||
}
|
||||
}
|
||||
abstract val codec: Codec<out Op>
|
||||
}
|
||||
|
||||
data class Direct(val path: String) : Op {
|
||||
sealed class Op {
|
||||
abstract val type: OpType
|
||||
abstract fun apply(source: CompoundTag, destination: CompoundTag)
|
||||
}
|
||||
|
||||
data class Direct(val path: String) : Op() {
|
||||
private val split = path.split('.')
|
||||
override val type: OpType
|
||||
get() = OpType.DIRECT
|
||||
|
||||
override fun serialize(json: JsonObject) {
|
||||
json["path"] = JsonPrimitive("path")
|
||||
}
|
||||
|
||||
override fun apply(source: CompoundTag, destination: CompoundTag) {
|
||||
var a = source
|
||||
var b = destination
|
||||
@ -149,18 +148,13 @@ class UpgradeRecipe(
|
||||
}
|
||||
}
|
||||
|
||||
data class Indirect(val pathSource: String, val pathDestination: String) : Op {
|
||||
data class Indirect(val pathSource: String, val pathDestination: String) : Op() {
|
||||
private val splitSource = pathSource.split('.')
|
||||
private val splitDestination = pathDestination.split('.')
|
||||
|
||||
override val type: OpType
|
||||
get() = OpType.INDIRECT
|
||||
|
||||
override fun serialize(json: JsonObject) {
|
||||
json["source"] = JsonPrimitive(pathSource)
|
||||
json["destination"] = JsonPrimitive(pathDestination)
|
||||
}
|
||||
|
||||
override fun apply(source: CompoundTag, destination: CompoundTag) {
|
||||
var a = source
|
||||
var b = destination
|
||||
@ -219,36 +213,23 @@ class UpgradeRecipe(
|
||||
}
|
||||
|
||||
override fun getSerializer(): RecipeSerializer<UpgradeRecipe> {
|
||||
return Companion
|
||||
return CODEC
|
||||
}
|
||||
|
||||
companion object : RecipeSerializer<UpgradeRecipe> {
|
||||
fun deserializeOp(json: JsonObject): Op {
|
||||
return OpType.valueOf(GsonHelper.getAsString(json, "type")).deserialize(json)
|
||||
companion object {
|
||||
val COPY_PATHS_CODEC: Codec<List<Op>> = StringRepresentable
|
||||
.fromEnum(OpType::values)
|
||||
.dispatch({ it.type }, { it.codec })
|
||||
.listOf()
|
||||
|
||||
val CODEC = Codec2RecipeSerializer<UpgradeRecipe> { p ->
|
||||
RecordCodecBuilder.create {
|
||||
it.group(
|
||||
p.wrap(ShapedRecipe.Serializer.SHAPED_RECIPE).fieldOf("parent").forGetter(UpgradeRecipe::parent),
|
||||
COPY_PATHS_CODEC.fieldOf("copyPaths").forGetter(UpgradeRecipe::copyPaths),
|
||||
ResourceLocation.CODEC.fieldOf("source").forGetter(UpgradeRecipe::source)
|
||||
).apply(it, ::UpgradeRecipe)
|
||||
}
|
||||
|
||||
override fun fromJson(id: ResourceLocation, data: JsonObject): UpgradeRecipe {
|
||||
return UpgradeRecipe(
|
||||
ShapedRecipe.Serializer.SHAPED_RECIPE.fromJson(id, data),
|
||||
GsonHelper.getAsJsonArray(data, "copyPaths").stream().map { deserializeOp(it as JsonObject) },
|
||||
ResourceLocation(GsonHelper.getAsString(data, "source"))
|
||||
)
|
||||
}
|
||||
|
||||
override fun fromNetwork(id: ResourceLocation, buff: FriendlyByteBuf): UpgradeRecipe? {
|
||||
val recipe = ShapedRecipe.Serializer.SHAPED_RECIPE.fromNetwork(id, buff) ?: return null
|
||||
|
||||
return UpgradeRecipe(
|
||||
recipe,
|
||||
buff.readCollection({ ArrayList<Op>(it) }, { deserializeOp(it.readBinaryJson() as JsonObject) }).stream(),
|
||||
buff.readResourceLocation()
|
||||
)
|
||||
}
|
||||
|
||||
override fun toNetwork(buff: FriendlyByteBuf, value: UpgradeRecipe) {
|
||||
ShapedRecipe.Serializer.SHAPED_RECIPE.toNetwork(buff, value.parent)
|
||||
buff.writeCollection(value.copyPaths) { it, v -> it.writeBinaryJson(v.serialize()) }
|
||||
buff.writeResourceLocation(value.source)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,9 @@ import ru.dbotthepony.mc.otm.item.exopack.ProceduralExopackSlotUpgradeItem
|
||||
object MItemFunctionTypes {
|
||||
private val registry = DeferredRegister.create(Registries.LOOT_FUNCTION_TYPE, OverdriveThatMatters.MOD_ID)
|
||||
|
||||
val COPY_TILE_NBT: LootItemFunctionType by registry.register("copy_tile_nbt") { LootItemFunctionType(CopyTileNbtFunction.Companion) }
|
||||
val PROCEDURAL_BATTERY: LootItemFunctionType by registry.register(MNames.PROCEDURAL_BATTERY) { LootItemFunctionType(ProceduralBatteryItem.Randomizer.SERIALIZER) }
|
||||
val PROCEDURAL_EXOPACK_UPGRADE: LootItemFunctionType by registry.register("exopack_upgrade") { LootItemFunctionType(ProceduralExopackSlotUpgradeItem.Randomizer.SERIALIZER) }
|
||||
val COPY_TILE_NBT: LootItemFunctionType by registry.register("copy_tile_nbt") { LootItemFunctionType(CopyTileNbtFunction.CODEC) }
|
||||
val PROCEDURAL_BATTERY: LootItemFunctionType by registry.register(MNames.PROCEDURAL_BATTERY) { LootItemFunctionType(ProceduralBatteryItem.Randomizer.CODEC) }
|
||||
val PROCEDURAL_EXOPACK_UPGRADE: LootItemFunctionType by registry.register("exopack_upgrade") { LootItemFunctionType(ProceduralExopackSlotUpgradeItem.Randomizer.CODEC) }
|
||||
|
||||
internal fun register(bus: IEventBus) {
|
||||
registry.register(bus)
|
||||
|
@ -6,6 +6,7 @@ import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType
|
||||
import net.minecraftforge.eventbus.api.IEventBus
|
||||
import net.minecraftforge.registries.DeferredRegister
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.data.SingletonCodec
|
||||
import ru.dbotthepony.mc.otm.data.condition.ChanceWithPlaytimeCondition
|
||||
import ru.dbotthepony.mc.otm.data.condition.HasExoPackCondition
|
||||
import ru.dbotthepony.mc.otm.data.condition.ItemInInventoryCondition
|
||||
@ -16,12 +17,12 @@ import ru.dbotthepony.mc.otm.data.condition.ChanceCondition
|
||||
object MLootItemConditions {
|
||||
private val registry = DeferredRegister.create(Registries.LOOT_CONDITION_TYPE, OverdriveThatMatters.MOD_ID)
|
||||
|
||||
val HAS_EXOPACK: LootItemConditionType by registry.register("has_exopack") { LootItemConditionType(HasExoPackCondition) }
|
||||
val CHANCE_WITH_PLAYTIME: LootItemConditionType by registry.register("chance_with_playtime") { LootItemConditionType(ChanceWithPlaytimeCondition.SERIALIZER) }
|
||||
val ITEM_IN_INVENTORY: LootItemConditionType by registry.register("item_in_inventory") { LootItemConditionType(ItemInInventoryCondition.SERIALIZER) }
|
||||
val KILLED_BY_REAL_PLAYER: LootItemConditionType by registry.register("killed_by_real_player") { LootItemConditionType(KilledByRealPlayer) }
|
||||
val KILLED_BY_REAL_PLAYER_OR_INDIRECTLY: LootItemConditionType by registry.register("killed_by_real_player_or_indirectly") { LootItemConditionType(KilledByRealPlayerOrIndirectly) }
|
||||
val CHANCE: LootItemConditionType by registry.register("chance") { LootItemConditionType(ChanceCondition.SERIALIZER) }
|
||||
val HAS_EXOPACK: LootItemConditionType by registry.register("has_exopack") { LootItemConditionType(SingletonCodec(HasExoPackCondition)) }
|
||||
val CHANCE_WITH_PLAYTIME: LootItemConditionType by registry.register("chance_with_playtime") { LootItemConditionType(ChanceWithPlaytimeCondition.CODEC) }
|
||||
val ITEM_IN_INVENTORY: LootItemConditionType by registry.register("item_in_inventory") { LootItemConditionType(ItemInInventoryCondition.CODEC) }
|
||||
val KILLED_BY_REAL_PLAYER: LootItemConditionType by registry.register("killed_by_real_player") { LootItemConditionType(SingletonCodec(KilledByRealPlayer)) }
|
||||
val KILLED_BY_REAL_PLAYER_OR_INDIRECTLY: LootItemConditionType by registry.register("killed_by_real_player_or_indirectly") { LootItemConditionType(SingletonCodec(KilledByRealPlayerOrIndirectly)) }
|
||||
val CHANCE: LootItemConditionType by registry.register("chance") { LootItemConditionType(ChanceCondition.CODEC) }
|
||||
|
||||
internal fun register(bus: IEventBus) {
|
||||
registry.register(bus)
|
||||
|
@ -45,8 +45,8 @@ object MRecipes {
|
||||
init {
|
||||
serializers.register("plate_press") { PlatePressRecipe.SERIALIZER }
|
||||
serializers.register("energy_container") { EnergyContainerRecipe.Companion }
|
||||
serializers.register("upgrade") { UpgradeRecipe.Companion }
|
||||
serializers.register("hammer_priming") { ExplosiveHammerPrimingRecipe.Companion }
|
||||
serializers.register("upgrade") { UpgradeRecipe.CODEC }
|
||||
serializers.register("hammer_priming") { ExplosiveHammerPrimingRecipe.CODEC }
|
||||
serializers.register("painter") { PainterRecipe.SERIALIZER }
|
||||
serializers.register("matter_entangler") { MatterEntanglerRecipe.SERIALIZER }
|
||||
serializers.register("matter_entangler_energetic") { MatterEntanglerRecipe.ENERGY_SERIALIZER }
|
||||
|
@ -290,28 +290,28 @@ object MRegistry {
|
||||
|
||||
private fun initializeCommon(event: FMLCommonSetupEvent) {
|
||||
event.enqueueWork {
|
||||
CriteriaTriggers.register(BlackHoleTrigger)
|
||||
CriteriaTriggers.register(BecomeAndroidTrigger)
|
||||
CriteriaTriggers.register(BecomeAndroidDeathTrigger)
|
||||
CriteriaTriggers.register(BecomeAndroidSleepTrigger)
|
||||
CriteriaTriggers.register(BecomeHumaneTrigger)
|
||||
CriteriaTriggers.register(AndroidResearchTrigger)
|
||||
CriteriaTriggers.register(ShockwaveDamageMobTrigger)
|
||||
CriteriaTriggers.register(ShockwaveTrigger)
|
||||
CriteriaTriggers.register(AndroidBatteryTrigger)
|
||||
CriteriaTriggers.register(NanobotsArmorTrigger)
|
||||
CriteriaTriggers.register(FallDampenersSaveTrigger)
|
||||
CriteriaTriggers.register(EnderTeleporterFallDeathTrigger)
|
||||
CriteriaTriggers.register(KillAsAndroidTrigger)
|
||||
CriteriaTriggers.register(AndroidTravelUnderwater)
|
||||
CriteriaTriggers.register(NailedEntityTrigger)
|
||||
CriteriaTriggers.register(ExopackObtainedTrigger)
|
||||
CriteriaTriggers.register(ExopackGainedSmeltingTrigger)
|
||||
CriteriaTriggers.register(ExopackGainedCraftingTrigger)
|
||||
CriteriaTriggers.register(ExopackGainedEnderAccessTrigger)
|
||||
CriteriaTriggers.register(ExopackSlotsExpandedTrigger)
|
||||
CriteriaTriggers.register(ExopackBatterySlotTrigger)
|
||||
CriteriaTriggers.register(TakeItemOutOfReplicatorTrigger)
|
||||
CriteriaTriggers.register(BlackHoleTrigger.id.toString(), BlackHoleTrigger)
|
||||
CriteriaTriggers.register(BecomeAndroidTrigger.id.toString(), BecomeAndroidTrigger)
|
||||
CriteriaTriggers.register(BecomeAndroidDeathTrigger.id.toString(), BecomeAndroidDeathTrigger)
|
||||
CriteriaTriggers.register(BecomeAndroidSleepTrigger.id.toString(), BecomeAndroidSleepTrigger)
|
||||
CriteriaTriggers.register(BecomeHumaneTrigger.id.toString(), BecomeHumaneTrigger)
|
||||
CriteriaTriggers.register(AndroidResearchTrigger.id.toString(), AndroidResearchTrigger)
|
||||
CriteriaTriggers.register(ShockwaveDamageMobTrigger.id.toString(), ShockwaveDamageMobTrigger)
|
||||
CriteriaTriggers.register(ShockwaveTrigger.id.toString(), ShockwaveTrigger)
|
||||
CriteriaTriggers.register(AndroidBatteryTrigger.id.toString(), AndroidBatteryTrigger)
|
||||
CriteriaTriggers.register(NanobotsArmorTrigger.id.toString(), NanobotsArmorTrigger)
|
||||
CriteriaTriggers.register(FallDampenersSaveTrigger.id.toString(), FallDampenersSaveTrigger)
|
||||
CriteriaTriggers.register(EnderTeleporterFallDeathTrigger.id.toString(), EnderTeleporterFallDeathTrigger)
|
||||
CriteriaTriggers.register(KillAsAndroidTrigger.id.toString(), KillAsAndroidTrigger)
|
||||
CriteriaTriggers.register(AndroidTravelUnderwater.id.toString(), AndroidTravelUnderwater)
|
||||
CriteriaTriggers.register(NailedEntityTrigger.id.toString(), NailedEntityTrigger)
|
||||
CriteriaTriggers.register(ExopackObtainedTrigger.id.toString(), ExopackObtainedTrigger)
|
||||
CriteriaTriggers.register(ExopackGainedSmeltingTrigger.id.toString(), ExopackGainedSmeltingTrigger)
|
||||
CriteriaTriggers.register(ExopackGainedCraftingTrigger.id.toString(), ExopackGainedCraftingTrigger)
|
||||
CriteriaTriggers.register(ExopackGainedEnderAccessTrigger.id.toString(), ExopackGainedEnderAccessTrigger)
|
||||
CriteriaTriggers.register(ExopackSlotsExpandedTrigger.id.toString(), ExopackSlotsExpandedTrigger)
|
||||
CriteriaTriggers.register(ExopackBatterySlotTrigger.id.toString(), ExopackBatterySlotTrigger)
|
||||
CriteriaTriggers.register(TakeItemOutOfReplicatorTrigger.id.toString(), TakeItemOutOfReplicatorTrigger)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,25 +2,22 @@ package ru.dbotthepony.mc.otm.triggers
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonPrimitive
|
||||
import net.minecraft.advancements.Criterion
|
||||
import net.minecraft.advancements.critereon.*
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.android.AndroidResearchType
|
||||
import ru.dbotthepony.mc.otm.core.nbt.set
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import java.util.Optional
|
||||
import java.util.function.Predicate
|
||||
|
||||
object AndroidResearchTrigger : SimpleCriterionTrigger<AndroidResearchTrigger.Instance>() {
|
||||
val ID = ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research")
|
||||
|
||||
override fun getId(): ResourceLocation {
|
||||
return ID
|
||||
}
|
||||
val id = ResourceLocation(OverdriveThatMatters.MOD_ID, "android_research")
|
||||
|
||||
override fun createInstance(
|
||||
p_66248_: JsonObject,
|
||||
p_286603_: ContextAwarePredicate,
|
||||
p_286603_: Optional<ContextAwarePredicate>,
|
||||
p_66250_: DeserializationContext
|
||||
): Instance {
|
||||
return Instance(
|
||||
@ -34,18 +31,20 @@ object AndroidResearchTrigger : SimpleCriterionTrigger<AndroidResearchTrigger.In
|
||||
}
|
||||
}
|
||||
|
||||
class Instance(val research: ResourceLocation?) : AbstractCriterionTriggerInstance(ID, ContextAwarePredicate.ANY), Predicate<AndroidResearchType> {
|
||||
class Instance(val research: ResourceLocation?) : AbstractCriterionTriggerInstance(Optional.empty()), Predicate<AndroidResearchType> {
|
||||
constructor(research: AndroidResearchType) : this(research.id)
|
||||
|
||||
override fun test(t: AndroidResearchType): Boolean {
|
||||
return research == null || t.id == research
|
||||
}
|
||||
|
||||
override fun serializeToJson(p_16979_: SerializationContext): JsonObject {
|
||||
return super.serializeToJson(p_16979_).also {
|
||||
override fun serializeToJson(): JsonObject {
|
||||
return super.serializeToJson().also {
|
||||
if (research != null)
|
||||
it["research"] = JsonPrimitive(research.toString())
|
||||
}
|
||||
}
|
||||
|
||||
fun criterion() = Criterion(AndroidResearchTrigger, this)
|
||||
}
|
||||
}
|
||||
|
@ -3,21 +3,24 @@ package ru.dbotthepony.mc.otm.triggers
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParseException
|
||||
import com.google.gson.JsonPrimitive
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.advancements.Criterion
|
||||
import net.minecraft.advancements.critereon.*
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.core.toJsonStrict
|
||||
import ru.dbotthepony.mc.otm.data.Codec2TriggerSerializer
|
||||
import ru.dbotthepony.mc.otm.data.minRange
|
||||
import java.util.Optional
|
||||
|
||||
object AndroidTravelUnderwater : SimpleCriterionTrigger<AndroidTravelUnderwater.Instance>() {
|
||||
val ID = ResourceLocation(OverdriveThatMatters.MOD_ID, "android_walk_underwater")
|
||||
val id = ResourceLocation(OverdriveThatMatters.MOD_ID, "android_walk_underwater")
|
||||
|
||||
override fun getId(): ResourceLocation {
|
||||
return ID
|
||||
}
|
||||
|
||||
override fun createInstance(pJson: JsonObject, pPlayer: ContextAwarePredicate, pContext: DeserializationContext): Instance {
|
||||
return Instance((pJson["distance_to_travel"] as? JsonPrimitive)?.asDouble ?: throw JsonParseException("Invalid 'distance_to_travel' value"))
|
||||
override fun createInstance(pJson: JsonObject, pPlayer: Optional<ContextAwarePredicate>, pContext: DeserializationContext): Instance {
|
||||
return codec.fromJson(pJson, pPlayer, pContext)
|
||||
}
|
||||
|
||||
fun trigger(player: ServerPlayer, travelled: Double) {
|
||||
@ -26,11 +29,20 @@ object AndroidTravelUnderwater : SimpleCriterionTrigger<AndroidTravelUnderwater.
|
||||
}
|
||||
}
|
||||
|
||||
class Instance(val distanceToTravel: Double) : AbstractCriterionTriggerInstance(ID, ContextAwarePredicate.ANY) {
|
||||
override fun serializeToJson(pConditions: SerializationContext): JsonObject {
|
||||
return super.serializeToJson(pConditions).also {
|
||||
it["distance_to_travel"] = JsonPrimitive(distanceToTravel)
|
||||
val codec = Codec2TriggerSerializer<Instance> { p ->
|
||||
RecordCodecBuilder.create {
|
||||
it.group(
|
||||
Codec.DOUBLE.minRange(0.0).fieldOf("distanceToTravel").forGetter(Instance::distanceToTravel),
|
||||
p.playerPredicate.forGetter { it.playerPredicate() }
|
||||
).apply(it, ::Instance)
|
||||
}
|
||||
}
|
||||
|
||||
class Instance(val distanceToTravel: Double, playerPredicate: Optional<ContextAwarePredicate> = Optional.empty()) : AbstractCriterionTriggerInstance(playerPredicate) {
|
||||
override fun serializeToJson(): JsonObject {
|
||||
return codec.toJson(this)
|
||||
}
|
||||
|
||||
fun criterion() = Criterion(AndroidTravelUnderwater, this)
|
||||
}
|
||||
}
|
||||
|
@ -3,16 +3,17 @@ package ru.dbotthepony.mc.otm.triggers
|
||||
import com.google.gson.JsonObject
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.advancements.Criterion
|
||||
import net.minecraft.advancements.critereon.AbstractCriterionTriggerInstance
|
||||
import net.minecraft.advancements.critereon.ContextAwarePredicate
|
||||
import net.minecraft.advancements.critereon.DeserializationContext
|
||||
import net.minecraft.advancements.critereon.SerializationContext
|
||||
import net.minecraft.advancements.critereon.SimpleCriterionTrigger
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.core.fromJsonStrict
|
||||
import ru.dbotthepony.mc.otm.core.toJsonStrict
|
||||
import java.util.Optional
|
||||
|
||||
val ExopackObtainedTrigger = SingletonTrigger(ResourceLocation(OverdriveThatMatters.MOD_ID, "exopack_obtained"))
|
||||
val ExopackGainedCraftingTrigger = SingletonTrigger(ResourceLocation(OverdriveThatMatters.MOD_ID, "exopack_gained_crafting"))
|
||||
@ -22,11 +23,7 @@ val ExopackGainedEnderAccessTrigger = SingletonTrigger(ResourceLocation(Overdriv
|
||||
val ExopackBatterySlotTrigger = ItemTrigger(ResourceLocation(OverdriveThatMatters.MOD_ID, "exopack_battery_slot"))
|
||||
|
||||
object ExopackSlotsExpandedTrigger : SimpleCriterionTrigger<ExopackSlotsExpandedTrigger.Instance>() {
|
||||
val ID = ResourceLocation(OverdriveThatMatters.MOD_ID, "exopack_expanded")
|
||||
|
||||
override fun getId(): ResourceLocation {
|
||||
return ID
|
||||
}
|
||||
val id = ResourceLocation(OverdriveThatMatters.MOD_ID, "exopack_expanded")
|
||||
|
||||
val codec: Codec<Instance> = RecordCodecBuilder.create {
|
||||
it.group(
|
||||
@ -39,18 +36,20 @@ object ExopackSlotsExpandedTrigger : SimpleCriterionTrigger<ExopackSlotsExpanded
|
||||
trigger(player) { it.minGained <= gained && it.minTotal <= total }
|
||||
}
|
||||
|
||||
override fun createInstance(p_66248_: JsonObject, p_286603_: ContextAwarePredicate, p_66250_: DeserializationContext): Instance {
|
||||
override fun createInstance(p_66248_: JsonObject, p_286603_: Optional<ContextAwarePredicate>, p_66250_: DeserializationContext): Instance {
|
||||
return codec.fromJsonStrict(p_66248_)
|
||||
}
|
||||
|
||||
data class Instance(val minGained: Int = 0, val minTotal: Int = 0) : AbstractCriterionTriggerInstance(ID, ContextAwarePredicate.ANY) {
|
||||
data class Instance(val minGained: Int = 0, val minTotal: Int = 0) : AbstractCriterionTriggerInstance(Optional.empty()) {
|
||||
init {
|
||||
require(minGained >= 0) { "Invalid minGained $minGained" }
|
||||
require(minTotal >= 0) { "Invalid minTotal $minTotal" }
|
||||
}
|
||||
|
||||
override fun serializeToJson(p_16979_: SerializationContext): JsonObject {
|
||||
override fun serializeToJson(): JsonObject {
|
||||
return codec.toJsonStrict(this) as JsonObject
|
||||
}
|
||||
|
||||
fun criterion() = Criterion(ExopackSlotsExpandedTrigger, this)
|
||||
}
|
||||
}
|
||||
|
@ -1,54 +1,62 @@
|
||||
package ru.dbotthepony.mc.otm.triggers
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.advancements.Criterion
|
||||
import net.minecraft.advancements.critereon.*
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.damagesource.DamageSource
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.data.Codec2TriggerSerializer
|
||||
import ru.dbotthepony.mc.otm.data.DamagePredicateCodec
|
||||
import java.util.Optional
|
||||
|
||||
abstract class HurtTrigger : SimpleCriterionTrigger<HurtTrigger.Instance>() {
|
||||
abstract val ID: ResourceLocation
|
||||
abstract val id: ResourceLocation
|
||||
|
||||
override fun getId(): ResourceLocation {
|
||||
return ID
|
||||
}
|
||||
|
||||
override fun createInstance(
|
||||
final override fun createInstance(
|
||||
p_66248_: JsonObject,
|
||||
p_286603_: ContextAwarePredicate,
|
||||
p_286603_: Optional<ContextAwarePredicate>,
|
||||
p_66250_: DeserializationContext
|
||||
): Instance {
|
||||
return Instance(
|
||||
EntityPredicate.fromJson(p_66248_, "entity_predicate", p_66250_),
|
||||
(p_66248_["damage"] as? JsonObject)?.let(DamagePredicate::fromJson) ?: DamagePredicate.ANY
|
||||
)
|
||||
return codec.fromJson(p_66248_, p_286603_, p_66250_)
|
||||
}
|
||||
|
||||
fun trigger(player: ServerPlayer, entity: LivingEntity, damage: Float, damageSource: DamageSource) {
|
||||
val context = EntityPredicate.createContext(player, entity)
|
||||
|
||||
trigger(player) {
|
||||
it.predicate.matches(context) && it.damagePredicate.matches(player, damageSource, damage, damage, false)
|
||||
it.predicate.map { it.matches(context) }.orElse(true) && it.damagePredicate.map { it.matches(player, damageSource, damage, damage, false) }.orElse(true)
|
||||
}
|
||||
}
|
||||
|
||||
val codec = Codec2TriggerSerializer<Instance> { p ->
|
||||
RecordCodecBuilder.create {
|
||||
it.group(
|
||||
p.awareContextCodec.optionalFieldOf("predicate").forGetter(Instance::predicate),
|
||||
DamagePredicateCodec.optionalFieldOf("damagePredicate").forGetter(Instance::damagePredicate),
|
||||
p.playerPredicate.forGetter { it.playerPredicate() }
|
||||
).apply(it, ::Instance)
|
||||
}
|
||||
}
|
||||
|
||||
inner class Instance(
|
||||
val predicate: ContextAwarePredicate = ContextAwarePredicate.ANY,
|
||||
val damagePredicate: DamagePredicate = DamagePredicate(
|
||||
val predicate: Optional<ContextAwarePredicate> = Optional.empty(),
|
||||
val damagePredicate: Optional<DamagePredicate> = Optional.of(DamagePredicate(
|
||||
MinMaxBounds.Doubles.atLeast(1.0),
|
||||
MinMaxBounds.Doubles.atLeast(1.0),
|
||||
EntityPredicate.ANY,
|
||||
null,
|
||||
DamageSourcePredicate.ANY
|
||||
)
|
||||
) : AbstractCriterionTriggerInstance(ID, ContextAwarePredicate.ANY) {
|
||||
override fun serializeToJson(pConditions: SerializationContext): JsonObject {
|
||||
return super.serializeToJson(pConditions).also {
|
||||
it["entity_predicate"] = predicate.toJson(pConditions)
|
||||
it["damage"] = damagePredicate.serializeToJson()
|
||||
}
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty()
|
||||
)),
|
||||
player: Optional<ContextAwarePredicate> = Optional.empty()
|
||||
) : AbstractCriterionTriggerInstance(player) {
|
||||
override fun serializeToJson(): JsonObject {
|
||||
return codec.toJson(this)
|
||||
}
|
||||
|
||||
fun criterion() = Criterion(this@HurtTrigger, this)
|
||||
}
|
||||
}
|
||||
|
@ -3,42 +3,42 @@ package ru.dbotthepony.mc.otm.triggers
|
||||
import com.google.gson.JsonObject
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.advancements.Criterion
|
||||
import net.minecraft.advancements.critereon.AbstractCriterionTriggerInstance
|
||||
import net.minecraft.advancements.critereon.ContextAwarePredicate
|
||||
import net.minecraft.advancements.critereon.DeserializationContext
|
||||
import net.minecraft.advancements.critereon.ItemPredicate
|
||||
import net.minecraft.advancements.critereon.SerializationContext
|
||||
import net.minecraft.advancements.critereon.SimpleCriterionTrigger
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import ru.dbotthepony.mc.otm.core.fromJsonStrict
|
||||
import ru.dbotthepony.mc.otm.core.toJsonStrict
|
||||
import ru.dbotthepony.mc.otm.data.ItemPredicateCodec
|
||||
|
||||
class ItemTrigger(val ID: ResourceLocation) : SimpleCriterionTrigger<ItemTrigger.Instance>() {
|
||||
override fun getId(): ResourceLocation {
|
||||
return ID
|
||||
}
|
||||
import ru.dbotthepony.mc.otm.data.Codec2TriggerSerializer
|
||||
import java.util.Optional
|
||||
|
||||
class ItemTrigger(val id: ResourceLocation) : SimpleCriterionTrigger<ItemTrigger.Instance>() {
|
||||
fun trigger(player: ServerPlayer, item: ItemStack) {
|
||||
trigger(player) { if (it.invert) !it.predicate.matches(item) else it.predicate.matches(item) }
|
||||
}
|
||||
|
||||
val codec: Codec<Instance> = RecordCodecBuilder.create {
|
||||
val codec = Codec2TriggerSerializer<Instance> { p ->
|
||||
RecordCodecBuilder.create {
|
||||
it.group(
|
||||
ItemPredicateCodec.fieldOf("predicate").forGetter(Instance::predicate),
|
||||
ItemPredicate.CODEC.fieldOf("predicate").forGetter(Instance::predicate),
|
||||
Codec.BOOL.optionalFieldOf("invert", false).forGetter(Instance::invert),
|
||||
p.playerPredicate.forGetter { it.playerPredicate() }
|
||||
).apply(it, ::Instance)
|
||||
}
|
||||
|
||||
override fun createInstance(p_66248_: JsonObject, p_286603_: ContextAwarePredicate, p_66250_: DeserializationContext): Instance {
|
||||
return codec.fromJsonStrict(p_66248_)
|
||||
}
|
||||
|
||||
inner class Instance(val predicate: ItemPredicate, val invert: Boolean = false) : AbstractCriterionTriggerInstance(ID, ContextAwarePredicate.ANY) {
|
||||
override fun serializeToJson(p_16979_: SerializationContext): JsonObject {
|
||||
return codec.toJsonStrict(this) as JsonObject
|
||||
override fun createInstance(p_66248_: JsonObject, p_286603_: Optional<ContextAwarePredicate>, p_66250_: DeserializationContext): Instance {
|
||||
return codec.fromJson(p_66248_, p_286603_, p_66250_)
|
||||
}
|
||||
|
||||
inner class Instance(val predicate: ItemPredicate, val invert: Boolean = false, player: Optional<ContextAwarePredicate> = Optional.empty()) : AbstractCriterionTriggerInstance(player) {
|
||||
override fun serializeToJson(): JsonObject {
|
||||
return codec.toJson(this)
|
||||
}
|
||||
|
||||
fun criterion() = Criterion(this@ItemTrigger, this)
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonSyntaxException
|
||||
import net.minecraft.advancements.Criterion
|
||||
import net.minecraft.advancements.critereon.*
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
@ -16,16 +17,13 @@ import ru.dbotthepony.mc.otm.core.asIterable
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.core.stream
|
||||
import ru.dbotthepony.mc.otm.registry.MRegistry
|
||||
import java.util.Optional
|
||||
import java.util.function.Predicate
|
||||
|
||||
object KillAsAndroidTrigger : SimpleCriterionTrigger<KillAsAndroidTrigger.Instance>() {
|
||||
val ID = ResourceLocation(OverdriveThatMatters.MOD_ID, "kill_as_android")
|
||||
val id = ResourceLocation(OverdriveThatMatters.MOD_ID, "kill_as_android")
|
||||
|
||||
override fun getId(): ResourceLocation {
|
||||
return ID
|
||||
}
|
||||
|
||||
override fun createInstance(pJson: JsonObject, pPlayer: ContextAwarePredicate, pContext: DeserializationContext): Instance {
|
||||
override fun createInstance(pJson: JsonObject, pPlayer: Optional<ContextAwarePredicate>, pContext: DeserializationContext): Instance {
|
||||
return Instance(
|
||||
predicate = EntityPredicate.fromJson(pJson, "predicate", pContext),
|
||||
playerPredicate = pPlayer,
|
||||
@ -164,16 +162,18 @@ object KillAsAndroidTrigger : SimpleCriterionTrigger<KillAsAndroidTrigger.Instan
|
||||
}
|
||||
|
||||
class Instance(
|
||||
val predicate: ContextAwarePredicate = ContextAwarePredicate.ANY,
|
||||
val predicate: Optional<ContextAwarePredicate> = Optional.empty(),
|
||||
val featurePredicate: FeaturePredicate = Always,
|
||||
playerPredicate: ContextAwarePredicate = ContextAwarePredicate.ANY,
|
||||
) : AbstractCriterionTriggerInstance(ID, playerPredicate) {
|
||||
override fun serializeToJson(pConditions: SerializationContext): JsonObject {
|
||||
return super.serializeToJson(pConditions).also {
|
||||
it["predicate"] = predicate.toJson(pConditions)
|
||||
playerPredicate: Optional<ContextAwarePredicate> = Optional.empty(),
|
||||
) : AbstractCriterionTriggerInstance(playerPredicate) {
|
||||
override fun serializeToJson(): JsonObject {
|
||||
return super.serializeToJson().also {
|
||||
predicate.ifPresent { p -> it["predicate"] = p.toJson() }
|
||||
it["feature_predicate"] = featurePredicate.toJson()
|
||||
}
|
||||
}
|
||||
|
||||
fun criterion() = Criterion(KillAsAndroidTrigger, this)
|
||||
}
|
||||
|
||||
fun onKill(event: LivingDeathEvent) {
|
||||
@ -187,7 +187,7 @@ object KillAsAndroidTrigger : SimpleCriterionTrigger<KillAsAndroidTrigger.Instan
|
||||
val context = EntityPredicate.createContext(killer, event.entity)
|
||||
|
||||
trigger(killer) {
|
||||
it.predicate.matches(context) &&
|
||||
it.predicate.map { it.matches(context) }.orElse(true) &&
|
||||
it.featurePredicate.test(data)
|
||||
}
|
||||
}
|
||||
|
@ -17,8 +17,10 @@ import net.minecraft.advancements.critereon.MinMaxBounds
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.PlayerAdvancements
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.world.Container
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||
import ru.dbotthepony.mc.otm.container.CombinedContainer
|
||||
@ -28,7 +30,9 @@ import ru.dbotthepony.mc.otm.container.util.iterator
|
||||
import ru.dbotthepony.mc.otm.core.collect.flatMap
|
||||
import ru.dbotthepony.mc.otm.core.collect.toList
|
||||
import ru.dbotthepony.mc.otm.core.isNotEmpty
|
||||
import java.util.Optional
|
||||
import java.util.stream.Collectors
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
|
||||
/**
|
||||
* This object detours all necessary InventoryChangeTrigger methods
|
||||
@ -86,14 +90,14 @@ object MatteryInventoryChangeTrigger : CriterionTrigger<InventoryChangeTrigger.T
|
||||
|
||||
nodes.add(Node(
|
||||
DefaultStrategy,
|
||||
{ predicates.iterator().flatMap { (it.items ?: listOf(null)).iterator() }.toList() },
|
||||
{ predicates.iterator().flatMap { (it.items.map { it.map { it.value() } }.orElse(listOf(null))).iterator() }.toList() },
|
||||
{ v, inventory: Container, item: ItemStack, slotsFull: Int, slotsEmpty: Int, slotsOccupied: Int -> v == null || item.item == v },
|
||||
{ inventory: Container, item: ItemStack, slotsFull: Int, slotsEmpty: Int, slotsOccupied: Int -> mutableListOf(item.item) }))
|
||||
|
||||
nodes.add(Node(
|
||||
DefaultStrategy,
|
||||
{ predicates.map { it.tag } },
|
||||
{ v, inventory: Container, item: ItemStack, slotsFull: Int, slotsEmpty: Int, slotsOccupied: Int -> v == null || item.`is`(v) },
|
||||
{ predicates.map { it.tag as Optional<TagKey<Item>> } },
|
||||
{ v, inventory: Container, item: ItemStack, slotsFull: Int, slotsEmpty: Int, slotsOccupied: Int -> v.isEmpty || item.`is`(v.get()) },
|
||||
{ inventory: Container, item: ItemStack, slotsFull: Int, slotsEmpty: Int, slotsOccupied: Int -> item.tags.collect(Collectors.toCollection(::ArrayList)) }))
|
||||
|
||||
nodes.add(Node(BoundsStrategy, { predicates.map { it.count } }, { v, inventory: Container, item: ItemStack, slotsFull: Int, slotsEmpty: Int, slotsOccupied: Int -> v.matches(item.count) }))
|
||||
@ -136,13 +140,13 @@ object MatteryInventoryChangeTrigger : CriterionTrigger<InventoryChangeTrigger.T
|
||||
|
||||
fun add(listener: CriterionTrigger.Listener<InventoryChangeTrigger.TriggerInstance>) {
|
||||
if (set.add(listener)) {
|
||||
search(listener.triggerInstance, tree, 0).forEach { it.add(listener) }
|
||||
search(listener.trigger, tree, 0).forEach { it.add(listener) }
|
||||
}
|
||||
}
|
||||
|
||||
fun remove(listener: CriterionTrigger.Listener<InventoryChangeTrigger.TriggerInstance>) {
|
||||
if (set.remove(listener)) {
|
||||
search(listener.triggerInstance, tree, 0).forEach { it.remove(listener) }
|
||||
search(listener.trigger, tree, 0).forEach { it.remove(listener) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,7 +172,7 @@ object MatteryInventoryChangeTrigger : CriterionTrigger<InventoryChangeTrigger.T
|
||||
if (nodeId + 1 == nodes.size) {
|
||||
for (l in v as Set<CriterionTrigger.Listener<InventoryChangeTrigger.TriggerInstance>>) {
|
||||
// переделываем matches у InventoryTriggerInstance
|
||||
with (l.triggerInstance) {
|
||||
with (l.trigger) {
|
||||
if (
|
||||
this.slotsFull.matches(slotsFull) &&
|
||||
this.slotsEmpty.matches(slotsEmpty) &&
|
||||
@ -212,10 +216,6 @@ object MatteryInventoryChangeTrigger : CriterionTrigger<InventoryChangeTrigger.T
|
||||
|
||||
private val listeners = Reference2ObjectOpenHashMap<PlayerAdvancements, ListenerTree>()
|
||||
|
||||
override fun getId(): ResourceLocation {
|
||||
return CriteriaTriggers.INVENTORY_CHANGED.id
|
||||
}
|
||||
|
||||
override fun addPlayerListener(advancements: PlayerAdvancements, instance: CriterionTrigger.Listener<InventoryChangeTrigger.TriggerInstance>) {
|
||||
listeners.computeIfAbsent(advancements, Reference2ObjectFunction { ListenerTree(it as PlayerAdvancements) }).add(instance)
|
||||
}
|
||||
|
@ -4,5 +4,5 @@ import net.minecraft.resources.ResourceLocation
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
|
||||
object NailedEntityTrigger : HurtTrigger() {
|
||||
override val ID = ResourceLocation(OverdriveThatMatters.MOD_ID, "hammer_nail_damage")
|
||||
override val id = ResourceLocation(OverdriveThatMatters.MOD_ID, "hammer_nail_damage")
|
||||
}
|
||||
|
@ -1,40 +1,45 @@
|
||||
package ru.dbotthepony.mc.otm.triggers
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.advancements.Criterion
|
||||
import net.minecraft.advancements.critereon.*
|
||||
import net.minecraft.advancements.critereon.MinMaxBounds.Doubles
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.core.nbt.set
|
||||
import ru.dbotthepony.mc.otm.core.set
|
||||
import ru.dbotthepony.mc.otm.data.Codec2TriggerSerializer
|
||||
import java.util.Optional
|
||||
|
||||
object NanobotsArmorTrigger : SimpleCriterionTrigger<NanobotsArmorTrigger.Instance>() {
|
||||
val ID = ResourceLocation(OverdriveThatMatters.MOD_ID, "nanobots_armor")
|
||||
|
||||
override fun getId(): ResourceLocation {
|
||||
return ID
|
||||
}
|
||||
val id = ResourceLocation(OverdriveThatMatters.MOD_ID, "nanobots_armor")
|
||||
|
||||
override fun createInstance(
|
||||
p_66248_: JsonObject,
|
||||
p_286603_: ContextAwarePredicate,
|
||||
p_286603_: Optional<ContextAwarePredicate>,
|
||||
p_66250_: DeserializationContext
|
||||
): Instance {
|
||||
return Instance(
|
||||
Doubles.fromJson(p_66248_["predicate"])
|
||||
)
|
||||
return codec.fromJson(p_66248_, p_286603_, p_66250_)
|
||||
}
|
||||
|
||||
val codec = Codec2TriggerSerializer<Instance> { p ->
|
||||
RecordCodecBuilder.create {
|
||||
it.group(
|
||||
Doubles.CODEC.fieldOf("predicate").forGetter(Instance::predicate),
|
||||
p.playerPredicate.forGetter { it.playerPredicate() },
|
||||
).apply(it, ::Instance)
|
||||
}
|
||||
}
|
||||
|
||||
fun trigger(player: ServerPlayer, damageAbsorbed: Double) {
|
||||
trigger(player) { it.predicate.matches(damageAbsorbed) }
|
||||
}
|
||||
|
||||
class Instance(val predicate: Doubles) : AbstractCriterionTriggerInstance(ID, ContextAwarePredicate.ANY) {
|
||||
override fun serializeToJson(p_16979_: SerializationContext): JsonObject {
|
||||
return super.serializeToJson(p_16979_).also {
|
||||
it["predicate"] = predicate.serializeToJson()
|
||||
}
|
||||
class Instance(val predicate: Doubles, player: Optional<ContextAwarePredicate> = Optional.empty()) : AbstractCriterionTriggerInstance(player) {
|
||||
override fun serializeToJson(): JsonObject {
|
||||
return codec.toJson((this))
|
||||
}
|
||||
|
||||
fun criterion() = Criterion(NanobotsArmorTrigger, this)
|
||||
}
|
||||
}
|
||||
|
@ -4,5 +4,5 @@ import net.minecraft.resources.ResourceLocation
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
|
||||
object ShockwaveDamageMobTrigger : HurtTrigger() {
|
||||
override val ID = ResourceLocation(OverdriveThatMatters.MOD_ID, "shockwave_damage_mob")
|
||||
override val id = ResourceLocation(OverdriveThatMatters.MOD_ID, "shockwave_damage_mob")
|
||||
}
|
||||
|
@ -1,25 +1,42 @@
|
||||
package ru.dbotthepony.mc.otm.triggers
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.advancements.Criterion
|
||||
import net.minecraft.advancements.critereon.AbstractCriterionTriggerInstance
|
||||
import net.minecraft.advancements.critereon.ContextAwarePredicate
|
||||
import net.minecraft.advancements.critereon.DeserializationContext
|
||||
import net.minecraft.advancements.critereon.SimpleCriterionTrigger
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import ru.dbotthepony.mc.otm.data.Codec2TriggerSerializer
|
||||
import java.util.Optional
|
||||
|
||||
class SingletonTrigger(val ID: ResourceLocation) : SimpleCriterionTrigger<AbstractCriterionTriggerInstance>() {
|
||||
override fun getId(): ResourceLocation {
|
||||
return ID
|
||||
}
|
||||
|
||||
override fun createInstance(p_66248_: JsonObject, p_286603_: ContextAwarePredicate, p_66250_: DeserializationContext): AbstractCriterionTriggerInstance {
|
||||
return instance
|
||||
class SingletonTrigger(val id: ResourceLocation) : SimpleCriterionTrigger<AbstractCriterionTriggerInstance>() {
|
||||
override fun createInstance(p_66248_: JsonObject, p_286603_: Optional<ContextAwarePredicate>, p_66250_: DeserializationContext): AbstractCriterionTriggerInstance {
|
||||
return codec.fromJson(p_66248_, p_286603_, p_66250_)
|
||||
}
|
||||
|
||||
fun trigger(player: ServerPlayer) {
|
||||
trigger(player) { true }
|
||||
}
|
||||
|
||||
val instance = object : AbstractCriterionTriggerInstance(ID, ContextAwarePredicate.ANY) {}
|
||||
val codec = Codec2TriggerSerializer<Instance> { p ->
|
||||
RecordCodecBuilder.create {
|
||||
it.group(
|
||||
p.playerPredicate.forGetter { it.playerPredicate() }
|
||||
).apply(it, ::Instance)
|
||||
}
|
||||
}
|
||||
|
||||
val empty = Instance()
|
||||
val criterion = Criterion(this@SingletonTrigger, empty)
|
||||
|
||||
inner class Instance(player: Optional<ContextAwarePredicate> = Optional.empty()) : AbstractCriterionTriggerInstance(player) {
|
||||
override fun serializeToJson(): JsonObject {
|
||||
return codec.toJson(this)
|
||||
}
|
||||
|
||||
fun criterion() = Criterion(this@SingletonTrigger, this)
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user