More, More and More Advancements

This commit is contained in:
DBotThePony 2022-10-02 17:41:00 +07:00
parent c657a2c9ad
commit b31ccdbae1
Signed by: DBot
GPG Key ID: DCC23B5715498507
25 changed files with 866 additions and 21 deletions

View File

@ -31,6 +31,7 @@ import ru.dbotthepony.mc.otm.core.registryName
import ru.dbotthepony.mc.otm.datagen.advancements.AdvancementProvider
import ru.dbotthepony.mc.otm.datagen.advancements.addAdvancements
import ru.dbotthepony.mc.otm.datagen.advancements.addAndroidAdvancements
import ru.dbotthepony.mc.otm.datagen.advancements.addMachineAdvancements
import ru.dbotthepony.mc.otm.datagen.blocks.addBlockStates
import ru.dbotthepony.mc.otm.datagen.blocks.addComplexBlockStates
import ru.dbotthepony.mc.otm.datagen.items.addItemModels
@ -354,6 +355,7 @@ object DataGen {
advancementProvider.exec { it, files ->
addAdvancements(it, files, languageProvider)
addAndroidAdvancements(it, files, languageProvider)
addMachineAdvancements(it, files, languageProvider)
}
addPlatePressRecipes(recipeProvider)

View File

@ -1,16 +1,20 @@
package ru.dbotthepony.mc.otm.datagen.advancements
import net.minecraft.advancements.Advancement
import net.minecraft.advancements.AdvancementRewards
import net.minecraft.advancements.FrameType
import net.minecraft.advancements.RequirementsStrategy
import net.minecraft.advancements.critereon.InventoryChangeTrigger
import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.ItemStack
import net.minecraftforge.common.data.ExistingFileHelper
import ru.dbotthepony.mc.otm.core.TranslatableComponent
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.registry.MRegistry
import ru.dbotthepony.mc.otm.triggers.BlackHoleTrigger
import java.util.function.Consumer
@ -32,7 +36,85 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
.addCriterion("has_tritanium_ingot", InventoryChangeTrigger.TriggerInstance.hasItems(MItems.TRITANIUM_INGOT))
.save(serializer, modLocation("regular/root"), existingFileHelper)
val crude = AdvancementBuilder()
.parent(root)
.display(
itemStack = ItemStack(MItems.BATTERY_CRUDE),
title = TranslatableComponent(translation.add("crude_battery", "Potato Power!")),
description = TranslatableComponent(translation.add("crude_battery.desc", "Put together a Crude Battery. Better hope for getter better power source soon")),
)
.addCriterion("has_item", criterion(MItems.BATTERY_CRUDE))
.save(serializer, modLocation("regular/crude_battery"), existingFileHelper)
val normal = AdvancementBuilder()
.parent(crude)
.display(
itemStack = ItemStack(MItems.BATTERY_NORMAL),
title = TranslatableComponent(translation.add("normal_battery", "Power Storage")),
description = TranslatableComponent(translation.add("normal_battery.desc", "Put together an Ordinary Battery")),
)
.addCriterion("has_item", criterion(MItems.BATTERY_NORMAL))
.save(serializer, modLocation("regular/normal_battery"), existingFileHelper)
AdvancementBuilder()
.parent(normal)
.display(
itemStack = ItemStack(MItems.BATTERY_DENSE),
title = TranslatableComponent(translation.add("dense_battery", "Extra Space Battery")),
description = TranslatableComponent(translation.add("dense_battery.desc", "Put together a Dense Battery. Better not to expose it to fires!")),
)
.addCriterion("has_item", criterion(MItems.BATTERY_DENSE))
.save(serializer, modLocation("regular/dense_battery"), existingFileHelper)
val capacitor = AdvancementBuilder()
.parent(normal)
.display(
itemStack = ItemStack(MItems.BATTERY_CAPACITOR),
title = TranslatableComponent(translation.add("capacitor_battery", "Supercapacitor")),
description = TranslatableComponent(translation.add("capacitor_battery.desc", "Put together a Capacitor Battery. Surely, you gonna need them somewhere...")),
)
.addCriterion("has_item", criterion(MItems.BATTERY_CAPACITOR))
.save(serializer, modLocation("regular/capacitor_battery"), existingFileHelper)
AdvancementBuilder()
.parent(capacitor)
.display(
itemStack = ItemStack(MItems.ENERGY_SWORD),
title = TranslatableComponent(translation.add("energy_sword", "Self Sharpening Blade")),
description = TranslatableComponent(translation.add("energy_sword.desc", "Wield an Energy Sword, a melee weapon intended to slice Creepers into creep-cakes. Rational folks won't attempt to slice their Android fellows...")),
frameType = FrameType.GOAL
)
.addCriterion("has_item", criterion(MItems.ENERGY_SWORD))
.save(serializer, modLocation("regular/energy_sword"), existingFileHelper)
AdvancementBuilder()
.parent(normal)
.display(
itemStack = ItemStack(MItems.QUANTUM_BATTERY),
title = TranslatableComponent(translation.add("quantum_battery", "Power, in Superposition")),
description = TranslatableComponent(translation.add("quantum_battery.desc", "Put together a Quantum Battery, powered by Ender technologies")),
frameType = FrameType.GOAL
)
.rewards(AdvancementRewards.Builder.experience(50))
.requirements(RequirementsStrategy.OR)
.addCriterion("has_item0", criterion(MItems.QUANTUM_BATTERY))
.addCriterion("has_item1", criterion(MItems.QUANTUM_CAPACITOR))
.save(serializer, modLocation("regular/quantum_battery"), existingFileHelper)
AdvancementBuilder()
.parent(root)
.display(
itemStack = ItemStack(MItems.ZPM_BATTERY),
title = TranslatableComponent(translation.add("zpm_battery", "Pocket Universe, as Power Source")),
description = TranslatableComponent(translation.add("zpm_battery.desc", "Find Zero Point Module, something from different universe of ours, created using technologies lost in time in all possible multiverses")),
frameType = FrameType.CHALLENGE,
hidden = true
)
.rewards(AdvancementRewards.Builder.experience(800))
.addCriterion("has_item", criterion(MItems.ZPM_BATTERY))
.save(serializer, modLocation("regular/zpm_battery"), existingFileHelper)
val blackhole = AdvancementBuilder()
.parent(root)
.display(
itemStack = ItemStack(MItems.BLACK_HOLE),
@ -42,6 +124,36 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
.addCriterion("pulled_by_black_hole", BlackHoleTrigger.Instance)
.save(serializer, modLocation("regular/black_hole"), existingFileHelper)
AdvancementBuilder()
.parent(blackhole)
.display(
itemStack = ItemStack(MItems.BLACK_HOLE_SCANNER),
title = TranslatableComponent(translation.add("black_hole_scanner", "Determining the Mass")),
description = TranslatableComponent(translation.add("black_hole_scanner.desc", "Craft the Singularity Scanner, to determine mass of Singularity from safe distance")),
)
.addCriterion("has_item", criterion(MItems.BLACK_HOLE_SCANNER))
.save(serializer, modLocation("regular/black_hole_scanner"), existingFileHelper)
AdvancementBuilder()
.parent(blackhole)
.display(
itemStack = ItemStack(MItems.GRAVITATION_STABILIZER),
title = TranslatableComponent(translation.add("stabilizer", "Reducing the Impact")),
description = TranslatableComponent(translation.add("stabilizer.desc", "Put together a device that defy physical laws and also defy gravity of Singularities. Better hope it does not cause any side effects")),
)
.addCriterion("has_item", criterion(MItems.GRAVITATION_STABILIZER))
.save(serializer, modLocation("regular/stabilizer"), existingFileHelper)
AdvancementBuilder()
.parent(blackhole)
.display(
itemStack = ItemStack(MItems.PORTABLE_GRAVITATION_STABILIZER),
title = TranslatableComponent(translation.add("portable_stabilizer", "Local Gravity Field")),
description = TranslatableComponent(translation.add("portable_stabilizer.desc", "Protect yourself from gravitational effect of Singularity using Portable Gravitation Stabilizer")),
)
.addCriterion("has_item", criterion(MItems.PORTABLE_GRAVITATION_STABILIZER))
.save(serializer, modLocation("regular/portable_stabilizer"), existingFileHelper)
val ore = AdvancementBuilder()
.parent(root)
.requirements(RequirementsStrategy.OR)
@ -85,6 +197,179 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
.addCriterion("hoe", criterion(MItems.TRITANIUM_HOE))
.save(serializer, modLocation("regular/hoe"), existingFileHelper)
val plate = AdvancementBuilder()
.parent(ingot)
.display(
itemStack = ItemStack(MItems.TRITANIUM_PLATE),
title = TranslatableComponent(translation.add("plate", "Hard Plating")),
description = TranslatableComponent(translation.add("plate.desc", "Roll down some Tritanium using Plate Press"))
)
.addCriterion("has_item", criterion(MItemTags.TRITANIUM_PLATES))
.save(serializer, modLocation("regular/plate"), existingFileHelper)
AdvancementBuilder()
.parent(plate)
.display(
itemStack = ItemStack(MItems.TRITANIUM_CHESTPLATE),
title = TranslatableComponent(translation.add("armor", "Composite Armor")),
description = TranslatableComponent(translation.add("armor.desc", "Bend some Tritanium plates into simple yet sturdy armor"))
)
.requirements(RequirementsStrategy.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)
val glass = AdvancementBuilder()
.parent(plate)
.display(
itemStack = ItemStack(MRegistry.INDUSTRIAL_GLASS.item),
title = TranslatableComponent(translation.add("industrial_glass", "Extra Hard Glass")),
description = TranslatableComponent(translation.add("industrial_glass.desc", "Manual says it should be bulletproof."))
)
.requirements(RequirementsStrategy.OR)
.also { advancement ->
MRegistry.INDUSTRIAL_GLASS.allItems.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
}
.save(serializer, modLocation("regular/industrial_glass"), existingFileHelper)
AdvancementBuilder()
.parent(glass)
.display(
itemStack = ItemStack(MRegistry.INDUSTRIAL_GLASS.getItem(DyeColor.GREEN)),
title = TranslatableComponent(translation.add("industrial_glass2", "Glass-tacular Artist")),
description = TranslatableComponent(translation.add("industrial_glass2.desc", "Paint Industrial Glass all possible colors"))
)
.requirements(RequirementsStrategy.AND)
.also { advancement ->
MRegistry.INDUSTRIAL_GLASS.allItems.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
}
.save(serializer, modLocation("regular/industrial_glass2"), existingFileHelper)
val cargoCrate = AdvancementBuilder()
.parent(plate)
.display(
itemStack = ItemStack(MRegistry.CARGO_CRATES.item),
title = TranslatableComponent(translation.add("cargo_crate", "Sturdy Item Stash")),
description = TranslatableComponent(translation.add("cargo_crate.desc", "Cargo Crates, like Double Chest, but Single."))
)
.requirements(RequirementsStrategy.OR)
.also { advancement ->
MRegistry.CARGO_CRATES.allItems.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
}
.save(serializer, modLocation("regular/cargo_crate"), existingFileHelper)
val cargoCrateInMinecart = AdvancementBuilder()
.parent(cargoCrate)
.display(
itemStack = ItemStack(MItems.CARGO_CRATE_MINECARTS[null]!!),
title = TranslatableComponent(translation.add("cargo_crate_minecart", "Crate On a Rail")),
description = TranslatableComponent(translation.add("cargo_crate_minecart.desc", "Drop a Cargo Crate onto Minecart and see how it goes"))
)
.requirements(RequirementsStrategy.OR)
.also { advancement ->
MItems.CARGO_CRATE_MINECARTS.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
}
.save(serializer, modLocation("regular/cargo_crate_minecart"), existingFileHelper)
AdvancementBuilder()
.parent(cargoCrateInMinecart)
.display(
itemStack = ItemStack(MItems.CARGO_CRATE_MINECARTS[DyeColor.GREEN]!!),
title = TranslatableComponent(translation.add("cargo_crate_minecart2", "A Motley Train")),
description = TranslatableComponent(translation.add("cargo_crate_minecart2.desc", "Have all color variants of Minecarts with Cargo Crates")),
frameType = FrameType.GOAL
)
.requirements(RequirementsStrategy.AND)
.also { advancement ->
MItems.CARGO_CRATE_MINECARTS.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
}
.save(serializer, modLocation("regular/cargo_crate_minecart2"), existingFileHelper)
AdvancementBuilder()
.parent(cargoCrate)
.display(
itemStack = ItemStack(MRegistry.CARGO_CRATES.item),
title = TranslatableComponent(translation.add("cargo_crate2", "Colorful Warehouse")),
description = TranslatableComponent(translation.add("cargo_crate2.desc", "Craft all color variants of Cargo Crates")),
frameType = FrameType.GOAL
)
.requirements(RequirementsStrategy.AND)
.also { advancement ->
MRegistry.CARGO_CRATES.allItems.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
}
.save(serializer, modLocation("regular/cargo_crate2"), existingFileHelper)
val tritaniumBlock = AdvancementBuilder()
.parent(plate)
.display(
itemStack = ItemStack(MRegistry.TRITANIUM_BLOCK.item),
title = TranslatableComponent(translation.add("tritanium_block", "Cold, Impregnable Wall")),
description = TranslatableComponent(translation.add("tritanium_block.desc", "Coat stones in Tritanium Plates, a cheap yet incredibly sturdy material"))
)
.requirements(RequirementsStrategy.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)) }
}
.save(serializer, modLocation("regular/tritanium_block"), existingFileHelper)
AdvancementBuilder()
.parent(tritaniumBlock)
.display(
itemStack = ItemStack(MItems.TRITANIUM_STRIPED_BLOCK),
title = TranslatableComponent(translation.add("striped_tritanium_block", "Old Fashion Color Touch")),
description = TranslatableComponent(translation.add("striped_tritanium_block.desc", "Pale Blue coat with Yellow stripe, I bet you know whose design is this"))
)
.addCriterion("has_item", criterion(MItems.TRITANIUM_STRIPED_BLOCK))
.save(serializer, modLocation("regular/striped_tritanium_block"), existingFileHelper)
val colorTritaniumBlock = AdvancementBuilder()
.parent(tritaniumBlock)
.display(
itemStack = ItemStack(MRegistry.TRITANIUM_BLOCK.getItem(DyeColor.GREEN)),
title = TranslatableComponent(translation.add("tritanium_block2", "Colorful Fortress")),
description = TranslatableComponent(translation.add("tritanium_block2.desc", "Put some paint over Tritanium Block to make it look fabulous"))
)
.requirements(RequirementsStrategy.OR)
.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)) }
}
.save(serializer, modLocation("regular/tritanium_block2"), existingFileHelper)
val colorfulTritaniumBlock = AdvancementBuilder()
.parent(colorTritaniumBlock)
.display(
itemStack = ItemStack(MRegistry.TRITANIUM_BLOCK.getItem(DyeColor.BLACK)),
title = TranslatableComponent(translation.add("tritanium_block3", "Paint Me A Castle")),
description = TranslatableComponent(translation.add("tritanium_block3.desc", "Craft all color variants of Tritanium Blocks")),
frameType = FrameType.GOAL
)
.rewards(AdvancementRewards.Builder.loot(modLocation("tritanium_block3")).addExperience(100))
.requirements(RequirementsStrategy.AND)
.also { advancement ->
MRegistry.TRITANIUM_BLOCK.items.values.forEach { advancement.addCriterion(it.registryName!!.path, criterion(it)) }
}
.save(serializer, modLocation("regular/tritanium_block3"), existingFileHelper)
AdvancementBuilder()
.parent(colorfulTritaniumBlock)
.display(
itemStack = ItemStack(MRegistry.TRITANIUM_STRIPED_BLOCK.getItem(DyeColor.BLACK, DyeColor.WHITE)),
title = TranslatableComponent(translation.add("tritanium_block4", "All The Colors")),
description = TranslatableComponent(translation.add("tritanium_block4.desc", "Craft ALL color variants of Tritanium Blocks including striped ones")),
frameType = FrameType.CHALLENGE
)
.rewards(AdvancementRewards.Builder.loot(modLocation("tritanium_block4")).addExperience(400))
.requirements(RequirementsStrategy.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)) }
}
.save(serializer, modLocation("regular/tritanium_block4"), existingFileHelper)
val pill = AdvancementBuilder()
.parent(root)
.display(
@ -108,6 +393,7 @@ fun addAdvancements(serializer: Consumer<Advancement>, existingFileHelper: Exist
frameType = FrameType.CHALLENGE,
hidden = true
)
.rewards(AdvancementRewards.Builder.experience(200))
.requirements(RequirementsStrategy.AND)
.addCriterion("pill1", criterion(MItems.PILL_ANDROID))
.addCriterion("pill2", criterion(MItems.PILL_HEAL))

View File

@ -1,12 +1,15 @@
package ru.dbotthepony.mc.otm.datagen.advancements
import net.minecraft.advancements.Advancement
import net.minecraft.advancements.AdvancementRewards
import net.minecraft.advancements.FrameType
import net.minecraft.advancements.RequirementsStrategy
import net.minecraft.advancements.critereon.DamagePredicate
import net.minecraft.advancements.critereon.DamageSourcePredicate
import net.minecraft.advancements.critereon.EntityPredicate
import net.minecraft.advancements.critereon.InventoryChangeTrigger
import net.minecraft.advancements.critereon.ItemPredicate
import net.minecraft.advancements.critereon.MinMaxBounds.Doubles
import net.minecraft.advancements.critereon.PlayerHurtEntityTrigger
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.EntityType
@ -20,11 +23,16 @@ 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.registry.MNames
import ru.dbotthepony.mc.otm.triggers.AndroidBatteryTrigger
import ru.dbotthepony.mc.otm.triggers.AndroidResearchTrigger
import ru.dbotthepony.mc.otm.triggers.BecomeAndroidDeathTrigger
import ru.dbotthepony.mc.otm.triggers.BecomeAndroidSleepTrigger
import ru.dbotthepony.mc.otm.triggers.BecomeAndroidTrigger
import ru.dbotthepony.mc.otm.triggers.BecomeHumaneTrigger
import ru.dbotthepony.mc.otm.triggers.EnderTeleporterFallDeathTrigger
import ru.dbotthepony.mc.otm.triggers.FallDampenersSaveTrigger
import ru.dbotthepony.mc.otm.triggers.NanobotsArmorTrigger
import ru.dbotthepony.mc.otm.triggers.PhantomSpawnDeniedTrigger
import ru.dbotthepony.mc.otm.triggers.ShockwaveDamageMobTrigger
import ru.dbotthepony.mc.otm.triggers.ShockwaveTrigger
import java.util.function.Consumer
@ -36,7 +44,7 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
.display(
itemStack = ItemStack(MItems.PILL_ANDROID),
title = TranslatableComponent(translation.add("root", "Androids and Humans")),
description = TranslatableComponent(translation.add("root.desc", "Can you make out who is cruel machine and who can make love?")),
description = TranslatableComponent(translation.add("root.desc", "Can you make out who is cruel machine and who can love?")),
showToast = false,
announceChat = false,
background = modLocation("textures/block/decorative/metal_beam_top.png")
@ -44,6 +52,32 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
.addCriterion("became_android", BecomeAndroidTrigger.Instance)
.save(serializer, modLocation("android/root"), existingFileHelper)
AdvancementBuilder()
.parent(root)
.display(
itemStack = ItemStack(MItems.ZPM_BATTERY),
title = TranslatableComponent(translation.add("zpm", "Fully Autonomous")),
description = TranslatableComponent(translation.add("zpm.desc", "Use Zero Point Module as internal battery power source. Only time is your enemy now")),
hidden = true,
frameType = FrameType.CHALLENGE
)
.addCriterion("item", AndroidBatteryTrigger.Instance(ItemPredicate.Builder.item().of(MItems.ZPM_BATTERY).build()))
.save(serializer, modLocation("android/zpm"), existingFileHelper)
AdvancementBuilder()
.parent(root)
.display(
itemStack = ItemStack(MItems.QUANTUM_BATTERY),
title = TranslatableComponent(translation.add("quantum_battery", "Wireless Charged")),
description = TranslatableComponent(translation.add("quantum_battery.desc", "Use Quantum Battery as internal battery power source, might as well have Fission Reactor charge other side of the link")),
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)
AdvancementBuilder()
.parent(root)
.display(
@ -78,6 +112,37 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
.addCriterion("become_humane", BecomeHumaneTrigger.Instance)
.save(serializer, modLocation("android/become_humane"), existingFileHelper)
val phantoms = AdvancementBuilder()
.parent(root)
.display(
itemStack = ItemStack(Items.PHANTOM_MEMBRANE),
title = TranslatableComponent(translation.add("phantom_spawn_denied", "Insomnia Immune")),
description = TranslatableComponent(translation.add("phantom_spawn_denied.desc", "Have Phantoms not come after you because you are not someone who needs to sleep")),
hidden = true
)
.addCriterion("phantom_spawn_denied", PhantomSpawnDeniedTrigger.Instance)
.save(serializer, modLocation("android/phantom_spawn_denied"), existingFileHelper)
val attractor = AdvancementBuilder()
.parent(phantoms)
.display(
itemStack = ItemStack(MItems.PHANTOM_ATTRACTOR),
title = TranslatableComponent(translation.add("phantom_attractor", "Eversleeping Decoy")),
description = TranslatableComponent(translation.add("phantom_attractor.desc", "Put together a Phantom Attractor, to be able to fight Phantoms as Android again")),
)
.addCriterion("has_item", criterion(MItems.PHANTOM_ATTRACTOR))
.save(serializer, modLocation("regular/phantom_attractor"), existingFileHelper)
AdvancementBuilder()
.parent(attractor)
.display(
itemStack = ItemStack(MItems.PHANTOM_ATTRACTOR),
title = TranslatableComponent(translation.add("phantom_attractor_research", "Deception of Phantoms")),
description = TranslatableComponent(translation.add("phantom_attractor_research.desc", "Research into how to attract Phantoms the same way as the ones who need to sleep")),
)
.addCriterion("researched", AndroidResearchTrigger.Instance(modLocation(MNames.PHANTOM_ATTRACTOR)))
.save(serializer, modLocation("regular/phantom_attractor_research"), existingFileHelper)
val researchAnything = AdvancementBuilder()
.parent(root)
.display(
@ -119,6 +184,53 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
.addCriterion("nanobots", AndroidResearchTrigger.Instance(modLocation(MNames.NANOBOTS)))
.save(serializer, modLocation("android/research_nanobots"), existingFileHelper)
val shielding = AdvancementBuilder()
.parent(nanobots)
.display(
itemStack = ItemStack(Items.SHIELD),
title = TranslatableComponent(translation.add("nanobots_armor_deflect", "Like a Concrete Wall")),
description = TranslatableComponent(translation.add("nanobots_armor_deflect.desc", "Have Nanobots absorb more than 5 hears of damage while you are left still functioning")),
hidden = true,
frameType = FrameType.GOAL
)
.addCriterion("damage", NanobotsArmorTrigger.Instance(Doubles.atLeast(10.0)))
.save(serializer, modLocation("android/nanobots_armor_deflect"), existingFileHelper)
AdvancementBuilder()
.parent(shielding)
.display(
itemStack = ItemStack(Items.SHIELD),
title = TranslatableComponent(translation.add("nanobots_armor_deflect2", "Unstoppable Force vs Immovable Object")),
description = TranslatableComponent(translation.add("nanobots_armor_deflect2.desc", "Have Nanobots absorb more than 10 hears of damage while you are left still functioning")),
hidden = true,
frameType = FrameType.CHALLENGE
)
.addCriterion("damage", NanobotsArmorTrigger.Instance(Doubles.atLeast(20.0)))
.save(serializer, modLocation("android/nanobots_armor_deflect2"), existingFileHelper)
AdvancementBuilder()
.parent(researchAnything)
.display(
itemStack = ItemStack(Items.FEATHER),
title = TranslatableComponent(translation.add("fall_dampeners_save", "Lucky Landing")),
description = TranslatableComponent(translation.add("fall_dampeners_save.desc", "Survive fall that would have otherwise be fatal without Fall Dampeners research")),
frameType = FrameType.GOAL
)
.addCriterion("saved", FallDampenersSaveTrigger.Instance)
.save(serializer, modLocation("android/fall_dampeners_save"), existingFileHelper)
AdvancementBuilder()
.parent(researchAnything)
.display(
itemStack = ItemStack(Items.SKELETON_SKULL),
title = TranslatableComponent(translation.add("ender_teleport_fall_death", "Navigation Error")),
description = TranslatableComponent(translation.add("ender_teleport_fall_death.desc", "Fall to your death moments after Teleporting")),
frameType = FrameType.GOAL,
hidden = true
)
.addCriterion("death", EnderTeleporterFallDeathTrigger.Instance)
.save(serializer, modLocation("android/ender_teleport_fall_death"), existingFileHelper)
val regen = AdvancementBuilder()
.parent(nanobots)
.display(
@ -151,6 +263,7 @@ fun addAndroidAdvancements(serializer: Consumer<Advancement>, existingFileHelper
description = TranslatableComponent(translation.add("research_all.desc", "Research everything (that don't block any other research)")),
frameType = FrameType.CHALLENGE
)
.rewards(AdvancementRewards.Builder.experience(400).addLootTable(modLocation("research_all_android")))
.also { advancement ->
DataGen.researchProvider.generatedView.stream()
.filter { it.allBlockedBy.isEmpty() && it.allBlocking.isEmpty() }

View File

@ -0,0 +1,85 @@
package ru.dbotthepony.mc.otm.datagen.advancements
import net.minecraft.advancements.Advancement
import net.minecraft.advancements.RequirementsStrategy
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import net.minecraftforge.common.data.ExistingFileHelper
import ru.dbotthepony.mc.otm.core.TranslatableComponent
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 java.util.function.Consumer
private data class CraftEntry(val item: Item, val englishName: String, val englishSuffix: String? = null)
fun addMachineAdvancements(serializer: Consumer<Advancement>, existingFileHelper: ExistingFileHelper, lang: MatteryLanguageProvider) {
val translation = lang.english.Prepended("otm.advancements.machine")
val root = AdvancementBuilder()
.requirements(RequirementsStrategy.OR)
.display(
itemStack = ItemStack(MItems.CHEMICAL_GENERATOR),
title = TranslatableComponent(translation.add("root", "Tritanium Empowered Machinery")),
description = TranslatableComponent(translation.add("root.desc", "Do not drop on anything if you want the latter preserved intact")),
showToast = false,
announceChat = false,
background = modLocation("textures/block/decorative/floor_tiles_gray.png")
)
.addCriterion("has_machine", criterion(MItemTags.MACHINES))
.addCriterion("has_tritanium_ingot", criterion(MItemTags.TRITANIUM_INGOTS))
.addCriterion("has_tritanium_plate_somehow", criterion(MItemTags.TRITANIUM_PLATES))
.save(serializer, modLocation("machines/root"), existingFileHelper)
val chem = AdvancementBuilder()
.parent(root)
.display(
itemStack = ItemStack(MItems.CHEMICAL_GENERATOR),
title = TranslatableComponent(translation.add("chemical_generator", "Burning the Organics")),
description = TranslatableComponent(translation.add("chemical_generator.desc", "Craft a Chemical Generator, better to put it outside")),
)
.addCriterion("has_machine", criterion(MItems.CHEMICAL_GENERATOR))
.save(serializer, modLocation("machines/chemical_generator"), existingFileHelper)
val press = AdvancementBuilder()
.parent(chem)
.display(
itemStack = ItemStack(MItems.PLATE_PRESS),
title = TranslatableComponent(translation.add("plate_press", "Bending the Material")),
description = TranslatableComponent(translation.add("plate_press.desc", "Craft a Plate Press, avoid having limbs inside during operation")),
)
.addCriterion("has_machine", criterion(MItems.PLATE_PRESS))
.save(serializer, modLocation("machines/plate_press"), existingFileHelper)
val entries = listOf(
CraftEntry(MItems.MATTER_SCANNER, "Scanning Things that Matter"),
CraftEntry(MItems.PATTERN_STORAGE, "Digital Knowledge Library"),
CraftEntry(MItems.MATTER_DECOMPOSER, "Decaying the Atoms", "Keep limbs outside of working chamber at all times"),
CraftEntry(MItems.MATTER_PANEL, "Indexing the Library"),
CraftEntry(MItems.MATTER_REPLICATOR, "Local Bakery", "Now let's bake perfect bread"),
CraftEntry(MItems.MATTER_BOTTLER, "Transfusing Pure Matter", "For those who loved to play with water in childhood"),
CraftEntry(MItems.MATTER_RECYCLER, "Refine and Redefine", "This is what waste recycling should look like"),
CraftEntry(MItems.MATTER_CAPACITOR_BANK, "Modular Matter Tank"),
CraftEntry(MItems.ENERGY_COUNTER, "Visualize Power Burn"),
CraftEntry(MItems.BATTERY_BANK, "Modular Power Tank", "By all means avoid urge to hammer incompatible batteries onto power bus."),
)
val built = mutableMapOf<Item, Advancement>()
for (entry in entries) {
val path = entry.item.registryName!!.path
built[entry.item] = AdvancementBuilder()
.parent(press)
.display(
itemStack = ItemStack(entry.item),
title = TranslatableComponent(translation.add(path, entry.englishName)),
description = TranslatableComponent(translation.add("$path.desc", "Craft a %s%s"), entry.item.description, if (entry.englishSuffix != null) ". " + entry.englishSuffix else ""),
)
.addCriterion("has_machine", criterion(entry.item))
.save(serializer, modLocation("machines/$path"), existingFileHelper)
}
}

View File

@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.datagen.items
import net.minecraft.resources.ResourceLocation
import ru.dbotthepony.mc.otm.core.registryName
import ru.dbotthepony.mc.otm.datagen.DataGen
import ru.dbotthepony.mc.otm.datagen.modLocation
import ru.dbotthepony.mc.otm.registry.MItems
import ru.dbotthepony.mc.otm.registry.MRegistry
@ -11,7 +12,14 @@ fun addItemModels(provider: MatteryItemModelProvider) {
provider.block(MItems.BATTERY_BANK)
provider.block(MItems.MATTER_CAPACITOR_BANK)
provider.block(MItems.PATTERN_STORAGE)
provider.block(MItems.BLACK_HOLE)
provider.exec {
provider
.withExistingParent(MItems.BLACK_HOLE.registryName!!.path, MatteryItemModelProvider.GENERATED)
.texture("layer0", modLocation("item/" + MItems.BLACK_HOLE.registryName!!.path))
.renderType("translucent")
}
provider.block(MItems.CARBON_FIBRE_BLOCK)
provider.block(MItems.DEEPSLATE_TRITANIUM_ORE)
provider.block(MItems.TRITANIUM_ORE)

View File

@ -40,6 +40,7 @@ class MatteryItemModelProvider(event: GatherDataEvent) : ItemModelProvider(event
withExistingParent(item.registryName!!.path, HANDHELD).texture("layer0", texture)
}
fun generated(item: Item) = generated(item, ResourceLocation(DataGen.MOD_ID, "item/${item.registryName!!.path}"))
fun generated(vararg items: Item) = items.forEach { generated(it, ResourceLocation(DataGen.MOD_ID, "item/${it.registryName!!.path}")) }
fun KOT(vararg items: Item) = items.forEach { generated(it, ResourceLocation(DataGen.MOD_ID, "block/ph_kitty")) }
fun generated(items: Collection<Item>) = items.forEach { generated(it, ResourceLocation(DataGen.MOD_ID, "item/${it.registryName!!.path}")) }
@ -77,8 +78,8 @@ class MatteryItemModelProvider(event: GatherDataEvent) : ItemModelProvider(event
}
companion object {
private val GENERATED = ResourceLocation("minecraft", "item/generated")
private val HANDHELD = ResourceLocation("minecraft", "item/handheld")
val GENERATED = ResourceLocation("minecraft", "item/generated")
val HANDHELD = ResourceLocation("minecraft", "item/handheld")
private val LOGGER = LogManager.getLogger()
}
}

View File

@ -78,7 +78,7 @@ class LootTables(generator: DataGenerator) : LootTableProvider(generator) {
}
}
fun provider(provider: LootTableCallback, context: LootContextParamSet) {
fun provider(context: LootContextParamSet, provider: LootTableCallback) {
providers.add(Pair(Supplier { provider }, context))
}

View File

@ -2,10 +2,15 @@ package ru.dbotthepony.mc.otm.datagen.loot
import net.minecraft.advancements.critereon.StatePropertiesPredicate
import net.minecraft.data.loot.BlockLoot
import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraft.world.level.block.state.properties.BlockStateProperties
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf
import net.minecraft.world.level.storage.loot.LootContext
import net.minecraft.world.level.storage.loot.entries.LootItem
import net.minecraft.world.level.storage.loot.entries.LootPoolEntries
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets
import net.minecraft.world.level.storage.loot.predicates.LootItemBlockStatePropertyCondition
import ru.dbotthepony.mc.otm.block.entity.ChemicalGeneratorBlockEntity
import ru.dbotthepony.mc.otm.block.entity.EnergyCounterBlockEntity
@ -16,7 +21,9 @@ import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity.Companion.REDSTONE_
import ru.dbotthepony.mc.otm.block.entity.matter.MatterBottlerBlockEntity
import ru.dbotthepony.mc.otm.block.entity.storage.AbstractStorageImportExport.Companion.FILTER_KEY
import ru.dbotthepony.mc.otm.block.entity.storage.StoragePowerSupplierBlockEntity
import ru.dbotthepony.mc.otm.datagen.modLocation
import ru.dbotthepony.mc.otm.registry.MBlocks
import ru.dbotthepony.mc.otm.registry.MItems
import ru.dbotthepony.mc.otm.registry.MRegistry
fun addLootTables(lootTables: LootTables) {
@ -55,6 +62,50 @@ fun addLootTables(lootTables: LootTables) {
.hasProperty(BlockStateProperties.DOUBLE_BLOCK_HALF, DoubleBlockHalf.LOWER))))
}
lootTables.provider(LootContextParamSets.ADVANCEMENT_ENTITY) {
it.accept(modLocation("research_all_android"), singleLootPool {
it.add(LootItem.lootTableItem(MItems.EXOSUIT_INVENTORY_UPGRADE_HUGE))
})
it.accept(modLocation("tritanium_block3"), singleLootPool {
it.add(LootItem.lootTableItem(Items.WHITE_DYE).setQuality(8))
it.add(LootItem.lootTableItem(Items.ORANGE_DYE).setQuality(8))
it.add(LootItem.lootTableItem(Items.MAGENTA_DYE).setQuality(8))
it.add(LootItem.lootTableItem(Items.LIGHT_BLUE_DYE).setQuality(8))
it.add(LootItem.lootTableItem(Items.YELLOW_DYE).setQuality(8))
it.add(LootItem.lootTableItem(Items.LIME_DYE).setQuality(8))
it.add(LootItem.lootTableItem(Items.PINK_DYE).setQuality(8))
it.add(LootItem.lootTableItem(Items.GRAY_DYE).setQuality(8))
it.add(LootItem.lootTableItem(Items.LIGHT_GRAY_DYE).setQuality(8))
it.add(LootItem.lootTableItem(Items.CYAN_DYE).setQuality(8))
it.add(LootItem.lootTableItem(Items.PURPLE_DYE).setQuality(8))
it.add(LootItem.lootTableItem(Items.BLUE_DYE).setQuality(8))
it.add(LootItem.lootTableItem(Items.BROWN_DYE).setQuality(8))
it.add(LootItem.lootTableItem(Items.GREEN_DYE).setQuality(8))
it.add(LootItem.lootTableItem(Items.RED_DYE).setQuality(8))
it.add(LootItem.lootTableItem(Items.BLACK_DYE).setQuality(8))
})
it.accept(modLocation("tritanium_block4"), singleLootPool {
it.add(LootItem.lootTableItem(Items.WHITE_DYE).setQuality(64))
it.add(LootItem.lootTableItem(Items.ORANGE_DYE).setQuality(64))
it.add(LootItem.lootTableItem(Items.MAGENTA_DYE).setQuality(64))
it.add(LootItem.lootTableItem(Items.LIGHT_BLUE_DYE).setQuality(64))
it.add(LootItem.lootTableItem(Items.YELLOW_DYE).setQuality(64))
it.add(LootItem.lootTableItem(Items.LIME_DYE).setQuality(64))
it.add(LootItem.lootTableItem(Items.PINK_DYE).setQuality(64))
it.add(LootItem.lootTableItem(Items.GRAY_DYE).setQuality(64))
it.add(LootItem.lootTableItem(Items.LIGHT_GRAY_DYE).setQuality(64))
it.add(LootItem.lootTableItem(Items.CYAN_DYE).setQuality(64))
it.add(LootItem.lootTableItem(Items.PURPLE_DYE).setQuality(64))
it.add(LootItem.lootTableItem(Items.BLUE_DYE).setQuality(64))
it.add(LootItem.lootTableItem(Items.BROWN_DYE).setQuality(64))
it.add(LootItem.lootTableItem(Items.GREEN_DYE).setQuality(64))
it.add(LootItem.lootTableItem(Items.RED_DYE).setQuality(64))
it.add(LootItem.lootTableItem(Items.BLACK_DYE).setQuality(64))
})
}
lootTables.tile(MBlocks.ENERGY_SERVO)
lootTables.tile(MBlocks.ENERGY_COUNTER,

View File

@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.datagen.tags
import net.minecraft.tags.BlockTags
import net.minecraft.tags.ItemTags
import net.minecraft.world.effect.MobEffects
import net.minecraft.world.item.BlockItem
import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.Items
import net.minecraft.world.item.Tiers
@ -70,6 +71,9 @@ fun addTags(tagsProvider: TagsProvider) {
tagsProvider.items.appender(ItemTags.TRAPDOORS).add(MItems.TRITANIUM_TRAPDOOR)
tagsProvider.blocks.appender(BlockTags.TRAPDOORS).add(MBlocks.TRITANIUM_TRAPDOOR)
tagsProvider.items.appender(MItemTags.MACHINES).add(MItems.MACHINES)
tagsProvider.blocks.appender(MBlockTags.MACHINES).add(MItems.MACHINES.stream().map { it as? BlockItem }.filter { it != null }.map { it!!.block })
tagsProvider.requiresPickaxe(listOf(
MBlocks.ANDROID_STATION,
MBlocks.BATTERY_BANK,

View File

@ -14,6 +14,7 @@ import net.minecraft.world.level.gameevent.GameEvent
import net.minecraftforge.data.event.GatherDataEvent
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.datagen.DataGen
import java.util.stream.Stream
import net.minecraft.data.tags.TagsProvider as MinecraftTagsProvider
interface MTagAppender<T> {
@ -27,6 +28,7 @@ interface MTagAppender<T> {
}
fun add(values: Collection<T>): TagsProvider
fun add(values: Stream<out T>): TagsProvider = add(values.toList())
fun addSafe(values: Collection<T>): Boolean {
var any = false

View File

@ -17,6 +17,7 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import ru.dbotthepony.mc.otm.android.AndroidResearchManager;
import ru.dbotthepony.mc.otm.android.feature.EnderTeleporterFeature;
import ru.dbotthepony.mc.otm.android.feature.NanobotsArmorFeature;
import ru.dbotthepony.mc.otm.block.entity.SynchronizedBlockEntity;
import ru.dbotthepony.mc.otm.block.entity.blackhole.ExplosionQueue;
@ -143,6 +144,8 @@ public final class OverdriveThatMatters {
EVENT_BUS.addListener(EventPriority.NORMAL, SynchronizedBlockEntity.Companion::onForget);
EVENT_BUS.addListener(EventPriority.NORMAL, SynchronizedBlockEntity.Companion::playerDisconnected);
EVENT_BUS.addListener(EventPriority.NORMAL, EnderTeleporterFeature.Companion::onEntityDeath);
MatteryPlayerNetworkChannel.INSTANCE.register();
MenuNetworkChannel.INSTANCE.register();
WeaponNetworkChannel.INSTANCE.register();

View File

@ -7,20 +7,25 @@ import com.mojang.math.Vector3f
import net.minecraft.ChatFormatting
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.nbt.CompoundTag
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.level.ClipContext
import net.minecraft.world.level.block.Block
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.HitResult
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraftforge.client.event.RenderLevelStageEvent
import net.minecraftforge.event.entity.living.LivingDeathEvent
import org.lwjgl.opengl.GL11.GL_LESS
import ru.dbotthepony.mc.otm.NULLABLE_MINECRAFT_SERVER
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.ServerConfig
import ru.dbotthepony.mc.otm.android.AndroidActiveFeature
import ru.dbotthepony.mc.otm.android.AndroidResearchManager
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.capability.extractEnergyInnerExact
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.client.render.ResearchIcons
import ru.dbotthepony.mc.otm.client.render.element
import ru.dbotthepony.mc.otm.core.Vector
@ -31,19 +36,34 @@ import ru.dbotthepony.mc.otm.core.component3
import ru.dbotthepony.mc.otm.core.formatPower
import ru.dbotthepony.mc.otm.core.genericPositions
import ru.dbotthepony.mc.otm.core.plus
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.core.shortestDistanceBetween
import ru.dbotthepony.mc.otm.core.times
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
import ru.dbotthepony.mc.otm.registry.MNames
import ru.dbotthepony.mc.otm.triggers.EnderTeleporterFallDeathTrigger
import kotlin.math.sin
class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiveFeature(AndroidFeatures.ENDER_TELEPORTER, capability) {
var cooldown by synchronizer.int()
var lastTeleport = 0
private set
private fun canUse(): Boolean {
return cooldown <= 0 && android.androidEnergy.extractEnergyInnerExact(ServerConfig.EnderTeleporter.ENERGY_COST, true).isPositive
}
override fun serializeNBT(): CompoundTag {
return super.serializeNBT().also {
it["cooldown"] = cooldown
}
}
override fun deserializeNBT(nbt: CompoundTag) {
super.deserializeNBT(nbt)
cooldown = nbt.getInt("cooldown")
}
private fun isValidPosition(blockPos: BlockPos): Boolean {
if (!Block.canSupportCenter(ply.level, blockPos.below(), Direction.UP) && !Block.canSupportRigidBlock(ply.level, blockPos.below())) {
return false
@ -107,6 +127,11 @@ class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiv
cooldown = ServerConfig.EnderTeleporter.COOLDOWN
val server = ply.server
if (server != null)
lastTeleport = server.tickCount
if (!isClient) android.androidEnergy.extractEnergyInner(ServerConfig.EnderTeleporter.ENERGY_COST, false)
ply.setPos(Vector(blockPos.x + 0.5, blockPos.y.toDouble(), blockPos.z + 0.5))
ply.deltaMovement = Vector(0.0, 0.0, 0.0)
@ -165,5 +190,18 @@ class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiv
ResourceLocation(OverdriveThatMatters.MOD_ID, MNames.ENDER_TELEPORTER),
"otm.gui.power_cost_per_use",
{ ServerConfig.EnderTeleporter.ENERGY_COST.formatPower().copy().withStyle(ChatFormatting.YELLOW) })
fun onEntityDeath(event: LivingDeathEvent) {
val android = event.entity.matteryPlayer ?: return
val server = NULLABLE_MINECRAFT_SERVER ?: return
if (android.isAndroid && event.source.isFall) {
val feature = android.getFeature(AndroidFeatures.ENDER_TELEPORTER) as EnderTeleporterFeature? ?: return
if (server.tickCount - feature.lastTeleport <= 120) {
EnderTeleporterFallDeathTrigger.trigger(event.entity as ServerPlayer)
}
}
}
}
}

View File

@ -2,7 +2,7 @@ package ru.dbotthepony.mc.otm.android.feature
import net.minecraft.ChatFormatting
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.damagesource.DamageSource
import net.minecraft.server.level.ServerPlayer
import net.minecraftforge.event.entity.living.LivingHurtEvent
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.ServerConfig
@ -13,17 +13,25 @@ import ru.dbotthepony.mc.otm.core.TextComponent
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
import ru.dbotthepony.mc.otm.registry.MNames
import ru.dbotthepony.mc.otm.triggers.FallDampenersSaveTrigger
class FallDampenersFeature(capability: MatteryPlayerCapability) : AndroidFeature(AndroidFeatures.FALL_DAMPENERS, capability) {
override fun onHurt(event: LivingHurtEvent) {
if (event.source.isFall) {
val reduction = (ServerConfig.FALL_DAMAGE_REDUCTION_PER_LEVEL * (level + 1)).toFloat()
val old = event.amount
if (reduction >= 1f) {
event.isCanceled = true
event.amount = 0f
} else {
event.amount *= (1f - reduction)
}
if (ply is ServerPlayer && ply.health > event.amount && ply.health <= old) {
FallDampenersSaveTrigger.trigger(ply as ServerPlayer)
}
}
}

View File

@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.android.feature
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.ChatFormatting
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
@ -19,6 +20,7 @@ import ru.dbotthepony.mc.otm.client.render.ResearchIcons
import ru.dbotthepony.mc.otm.core.Vector
import ru.dbotthepony.mc.otm.core.formatPower
import ru.dbotthepony.mc.otm.core.plus
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.network.MatteryPacket
import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel
import ru.dbotthepony.mc.otm.network.enqueueWork
@ -62,6 +64,17 @@ class JumpBoostFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF
}
})
override fun serializeNBT(): CompoundTag {
return super.serializeNBT().also {
it["cooldown"] = cooldown
}
}
override fun deserializeNBT(nbt: CompoundTag) {
super.deserializeNBT(nbt)
cooldown = nbt.getInt("cooldown")
}
fun putOnCooldown() {
cooldown = (ServerConfig.AndroidJumpBoost.BASE_COOLDOWN - ServerConfig.AndroidJumpBoost.COOLDOWN_REDUCTION * level).coerceAtLeast(0)
}

View File

@ -13,6 +13,8 @@ import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
import ru.dbotthepony.mc.otm.registry.StatNames
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.onceServer
import ru.dbotthepony.mc.otm.triggers.NanobotsArmorTrigger
import kotlin.math.roundToInt
class NanobotsArmorFeature(android: MatteryPlayerCapability) : AndroidFeature(AndroidFeatures.NANOBOTS_ARMOR, android) {
@ -48,6 +50,16 @@ class NanobotsArmorFeature(android: MatteryPlayerCapability) : AndroidFeature(An
val powerRequired = ENERGY_PER_HITPOINT * absorbed
val powerExtracted = android.androidEnergy.extractEnergyInner(powerRequired, false)
val realAbsorbed = (powerExtracted / ENERGY_PER_HITPOINT).toFloat()
val ply = ply
if (ply is ServerPlayer) {
onceServer {
if (!ply.hasDisconnected() && ply.isAlive)
NanobotsArmorTrigger.trigger(ply, realAbsorbed.toDouble())
}
}
event.amount = event.amount - realAbsorbed
(ply as ServerPlayer?)?.awardStat(StatNames.DAMAGE_ABSORBED, (realAbsorbed * 10f).roundToInt())
layers--

View File

@ -13,8 +13,9 @@ import ru.dbotthepony.mc.otm.core.ifPresentK
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.network.FieldSynchronizer
import ru.dbotthepony.mc.otm.registry.StatNames
import ru.dbotthepony.mc.otm.triggers.AndroidBatteryTrigger
class SynchronizedPowerWithBattery(
class AndroidPowerSource(
private val ply: Player,
synchronizer: FieldSynchronizer,
initialCharge: ImpreciseFraction,
@ -23,7 +24,13 @@ class SynchronizedPowerWithBattery(
private var battery by synchronizer.fraction(initialCharge)
private var maxBattery by synchronizer.fraction(maxCharge)
var item by synchronizer.item()
var item by synchronizer.item(setter = setter@{ value, access, setByRemote ->
access.write(value)
if (ply is ServerPlayer) {
AndroidBatteryTrigger.trigger(ply, value)
}
})
override fun serializeNBT(): CompoundTag {
return CompoundTag().also {

View File

@ -54,6 +54,7 @@ import ru.dbotthepony.mc.otm.triggers.BecomeAndroidDeathTrigger
import ru.dbotthepony.mc.otm.triggers.BecomeAndroidSleepTrigger
import ru.dbotthepony.mc.otm.triggers.BecomeAndroidTrigger
import ru.dbotthepony.mc.otm.triggers.BecomeHumaneTrigger
import ru.dbotthepony.mc.otm.triggers.PhantomSpawnDeniedTrigger
import java.util.*
import java.util.stream.Stream
import kotlin.collections.ArrayDeque
@ -226,7 +227,7 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
var willBecomeAndroid by synchronizer.bool()
var isAndroid by synchronizer.bool()
val androidEnergy = SynchronizedPowerWithBattery(ply, synchronizer, ServerConfig.ANDROID_MAX_ENERGY, ServerConfig.ANDROID_MAX_ENERGY)
val androidEnergy = AndroidPowerSource(ply, synchronizer, ServerConfig.ANDROID_MAX_ENERGY, ServerConfig.ANDROID_MAX_ENERGY)
fun invalidateNetworkState() {
invalidateNetworkIn = 10
@ -889,14 +890,23 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
fun canEntitySpawn(event: LivingSpawnEvent.CheckSpawn) {
if (event.spawnReason == MobSpawnType.NATURAL && event.entity is Phantom) {
for (ply in event.entity.level.players()) {
if (ply.matteryPlayer?.isAndroid == true && (ply.matteryPlayer?.getFeature(AndroidFeatures.PHANTOM_ATTRACTOR) as AndroidSwitchableFeature?)?.isActive != true) {
if (
ply.position.y in event.y - 36.0 .. event.y - 19.0 &&
ply.position.x in event.x - 12.0 .. event.x + 12.0 &&
ply.position.z in event.z - 12.0 .. event.z + 12.0
) {
event.result = Event.Result.DENY
return
if (ply.matteryPlayer?.isAndroid == true) {
val feature = (ply.matteryPlayer?.getFeature(AndroidFeatures.PHANTOM_ATTRACTOR) as AndroidSwitchableFeature?)
if (feature?.isActive != true) {
if (
ply.position.y in event.y - 36.0 .. event.y - 19.0 &&
ply.position.x in event.x - 12.0 .. event.x + 12.0 &&
ply.position.z in event.z - 12.0 .. event.z + 12.0
) {
event.result = Event.Result.DENY
if (feature == null && ply is ServerPlayer) {
PhantomSpawnDeniedTrigger.trigger(ply)
}
return
}
}
}
}

View File

@ -108,6 +108,15 @@ object MItems {
}
}
val MACHINES = LazyList(
::ANDROID_STATION, ::BATTERY_BANK, ::MATTER_DECOMPOSER, ::MATTER_CAPACITOR_BANK, ::MATTER_CABLE, ::PATTERN_STORAGE,
::MATTER_SCANNER, ::MATTER_PANEL, ::MATTER_REPLICATOR, ::MATTER_BOTTLER, ::ENERGY_COUNTER, ::CHEMICAL_GENERATOR,
::PLATE_PRESS, ::MATTER_RECYCLER, ::STORAGE_BUS, ::STORAGE_IMPORTER, ::STORAGE_EXPORTER, ::DRIVE_VIEWER,
::DRIVE_RACK, ::ITEM_MONITOR, ::STORAGE_CABLE, ::STORAGE_POWER_SUPPLIER, ::ENERGY_SERVO,
::PHANTOM_ATTRACTOR,
::GRAVITATION_STABILIZER,
)
val DEBUG_EXPLOSION_SMALL: Item by registry.register(MNames.DEBUG_EXPLOSION_SMALL) { BlockItem(MBlocks.DEBUG_EXPLOSION_SMALL, Item.Properties().stacksTo(64)) }
val DEBUG_SPHERE_POINTS: Item by registry.register(MNames.DEBUG_SPHERE_POINTS) { BlockItem(MBlocks.DEBUG_SPHERE_POINTS, Item.Properties().stacksTo(64)) }

View File

@ -2,9 +2,7 @@ package ru.dbotthepony.mc.otm.registry
import com.mojang.serialization.Lifecycle
import net.minecraft.advancements.CriteriaTriggers
import net.minecraft.client.renderer.block.model.ItemOverrides
import net.minecraft.client.renderer.item.ItemProperties
import net.minecraft.client.renderer.item.ItemPropertyFunction
import net.minecraft.core.BlockPos
import net.minecraft.core.Holder
import net.minecraft.core.Registry
@ -22,14 +20,12 @@ import net.minecraft.world.level.material.MaterialColor
import net.minecraftforge.eventbus.api.IEventBus
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext
import net.minecraftforge.registries.ForgeRegistry
import net.minecraftforge.registries.IForgeRegistry
import net.minecraftforge.registries.NewRegistryEvent
import net.minecraftforge.registries.RegistryBuilder
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.android.AndroidFeatureType
import ru.dbotthepony.mc.otm.android.AndroidResearchType
import ru.dbotthepony.mc.otm.android.feature.EnderTeleporterFeature
import ru.dbotthepony.mc.otm.android.feature.FallDampenersFeature
import ru.dbotthepony.mc.otm.android.feature.ItemMagnetFeature
@ -44,12 +40,17 @@ import ru.dbotthepony.mc.otm.registry.objects.ColoredDecorativeBlock
import ru.dbotthepony.mc.otm.registry.objects.CrateProperties
import ru.dbotthepony.mc.otm.registry.objects.DecorativeBlock
import ru.dbotthepony.mc.otm.registry.objects.StripedColoredDecorativeBlock
import ru.dbotthepony.mc.otm.triggers.AndroidBatteryTrigger
import ru.dbotthepony.mc.otm.triggers.AndroidResearchTrigger
import ru.dbotthepony.mc.otm.triggers.BecomeAndroidDeathTrigger
import ru.dbotthepony.mc.otm.triggers.BecomeAndroidSleepTrigger
import ru.dbotthepony.mc.otm.triggers.BecomeAndroidTrigger
import ru.dbotthepony.mc.otm.triggers.BecomeHumaneTrigger
import ru.dbotthepony.mc.otm.triggers.BlackHoleTrigger
import ru.dbotthepony.mc.otm.triggers.EnderTeleporterFallDeathTrigger
import ru.dbotthepony.mc.otm.triggers.FallDampenersSaveTrigger
import ru.dbotthepony.mc.otm.triggers.NanobotsArmorTrigger
import ru.dbotthepony.mc.otm.triggers.PhantomSpawnDeniedTrigger
import ru.dbotthepony.mc.otm.triggers.ShockwaveDamageMobTrigger
import ru.dbotthepony.mc.otm.triggers.ShockwaveTrigger
import java.util.function.Supplier
@ -275,6 +276,11 @@ object MRegistry {
CriteriaTriggers.register(AndroidResearchTrigger)
CriteriaTriggers.register(ShockwaveDamageMobTrigger)
CriteriaTriggers.register(ShockwaveTrigger)
CriteriaTriggers.register(PhantomSpawnDeniedTrigger)
CriteriaTriggers.register(AndroidBatteryTrigger)
CriteriaTriggers.register(NanobotsArmorTrigger)
CriteriaTriggers.register(FallDampenersSaveTrigger)
CriteriaTriggers.register(EnderTeleporterFallDeathTrigger)
}
}

View File

@ -65,6 +65,8 @@ object MItemTags {
val HARDENED_GLASS_RED: TagKey<Item> = ItemTags.create(ResourceLocation("forge", "hardened_glass/red"))
val HARDENED_GLASS_WHITE: TagKey<Item> = ItemTags.create(ResourceLocation("forge", "hardened_glass/white"))
val HARDENED_GLASS_YELLOW: TagKey<Item> = ItemTags.create(ResourceLocation("forge", "hardened_glass/yellow"))
val MACHINES: TagKey<Item> = ItemTags.create(ResourceLocation(OverdriveThatMatters.MOD_ID, "machines"))
}
@Suppress("unused")
@ -109,4 +111,6 @@ object MBlockTags {
val HARDENED_GLASS_RED: TagKey<Block> = BlockTags.create(ResourceLocation("forge", "hardened_glass/red"))
val HARDENED_GLASS_WHITE: TagKey<Block> = BlockTags.create(ResourceLocation("forge", "hardened_glass/white"))
val HARDENED_GLASS_YELLOW: TagKey<Block> = BlockTags.create(ResourceLocation("forge", "hardened_glass/yellow"))
val MACHINES: TagKey<Block> = BlockTags.create(ResourceLocation(OverdriveThatMatters.MOD_ID, "machines"))
}

View File

@ -0,0 +1,44 @@
package ru.dbotthepony.mc.otm.triggers
import com.google.gson.JsonObject
import net.minecraft.advancements.critereon.AbstractCriterionTriggerInstance
import net.minecraft.advancements.critereon.DeserializationContext
import net.minecraft.advancements.critereon.EntityPredicate.Composite
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.OverdriveThatMatters
import ru.dbotthepony.mc.otm.core.set
object AndroidBatteryTrigger : SimpleCriterionTrigger<AndroidBatteryTrigger.Instance>() {
val ID = ResourceLocation(OverdriveThatMatters.MOD_ID, "android_battery")
override fun getId(): ResourceLocation {
return ID
}
override fun createInstance(
p_66248_: JsonObject,
p_66249_: Composite,
p_66250_: DeserializationContext
): Instance {
return Instance(
ItemPredicate.fromJson(p_66248_["predicate"])
)
}
fun trigger(player: ServerPlayer, newItem: ItemStack) {
trigger(player) { it.predicate.matches(newItem) }
}
class Instance(val predicate: ItemPredicate) : AbstractCriterionTriggerInstance(ID, Composite.ANY) {
override fun serializeToJson(p_16979_: SerializationContext): JsonObject {
return super.serializeToJson(p_16979_).also {
it["predicate"] = predicate.serializeToJson()
}
}
}
}

View File

@ -0,0 +1,32 @@
package ru.dbotthepony.mc.otm.triggers
import com.google.gson.JsonObject
import net.minecraft.advancements.critereon.AbstractCriterionTriggerInstance
import net.minecraft.advancements.critereon.DeserializationContext
import net.minecraft.advancements.critereon.EntityPredicate.Composite
import net.minecraft.advancements.critereon.SimpleCriterionTrigger
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import ru.dbotthepony.mc.otm.OverdriveThatMatters
object EnderTeleporterFallDeathTrigger : SimpleCriterionTrigger<EnderTeleporterFallDeathTrigger.Instance>() {
val ID = ResourceLocation(OverdriveThatMatters.MOD_ID, "ender_teleporter_fall_death")
override fun getId(): ResourceLocation {
return ID
}
override fun createInstance(
p_66248_: JsonObject,
p_66249_: Composite,
p_66250_: DeserializationContext
): Instance {
return Instance
}
fun trigger(player: ServerPlayer) {
trigger(player) { true }
}
object Instance : AbstractCriterionTriggerInstance(ID, Composite.ANY)
}

View File

@ -0,0 +1,32 @@
package ru.dbotthepony.mc.otm.triggers
import com.google.gson.JsonObject
import net.minecraft.advancements.critereon.AbstractCriterionTriggerInstance
import net.minecraft.advancements.critereon.DeserializationContext
import net.minecraft.advancements.critereon.EntityPredicate.Composite
import net.minecraft.advancements.critereon.SimpleCriterionTrigger
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import ru.dbotthepony.mc.otm.OverdriveThatMatters
object FallDampenersSaveTrigger : SimpleCriterionTrigger<FallDampenersSaveTrigger.Instance>() {
val ID = ResourceLocation(OverdriveThatMatters.MOD_ID, "fall_dampeners_save")
override fun getId(): ResourceLocation {
return ID
}
override fun createInstance(
p_66248_: JsonObject,
p_66249_: Composite,
p_66250_: DeserializationContext
): Instance {
return Instance
}
fun trigger(player: ServerPlayer) {
trigger(player) { true }
}
object Instance : AbstractCriterionTriggerInstance(ID, Composite.ANY)
}

View File

@ -0,0 +1,43 @@
package ru.dbotthepony.mc.otm.triggers
import com.google.gson.JsonObject
import net.minecraft.advancements.critereon.AbstractCriterionTriggerInstance
import net.minecraft.advancements.critereon.DeserializationContext
import net.minecraft.advancements.critereon.EntityPredicate.Composite
import net.minecraft.advancements.critereon.MinMaxBounds.Doubles
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.set
object NanobotsArmorTrigger : SimpleCriterionTrigger<NanobotsArmorTrigger.Instance>() {
val ID = ResourceLocation(OverdriveThatMatters.MOD_ID, "nanobots_armor")
override fun getId(): ResourceLocation {
return ID
}
override fun createInstance(
p_66248_: JsonObject,
p_66249_: Composite,
p_66250_: DeserializationContext
): Instance {
return Instance(
Doubles.fromJson(p_66248_["predicate"])
)
}
fun trigger(player: ServerPlayer, damageAbsorbed: Double) {
trigger(player) { it.predicate.matches(damageAbsorbed) }
}
class Instance(val predicate: Doubles) : AbstractCriterionTriggerInstance(ID, Composite.ANY) {
override fun serializeToJson(p_16979_: SerializationContext): JsonObject {
return super.serializeToJson(p_16979_).also {
it["predicate"] = predicate.serializeToJson()
}
}
}
}

View File

@ -0,0 +1,32 @@
package ru.dbotthepony.mc.otm.triggers
import com.google.gson.JsonObject
import net.minecraft.advancements.critereon.AbstractCriterionTriggerInstance
import net.minecraft.advancements.critereon.DeserializationContext
import net.minecraft.advancements.critereon.EntityPredicate.Composite
import net.minecraft.advancements.critereon.SimpleCriterionTrigger
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import ru.dbotthepony.mc.otm.OverdriveThatMatters
object PhantomSpawnDeniedTrigger : SimpleCriterionTrigger<PhantomSpawnDeniedTrigger.Instance>() {
val ID = ResourceLocation(OverdriveThatMatters.MOD_ID, "phantom_spawn_denied")
override fun getId(): ResourceLocation {
return ID
}
override fun createInstance(
p_66248_: JsonObject,
p_66249_: Composite,
p_66250_: DeserializationContext
): Instance {
return Instance
}
fun trigger(player: ServerPlayer) {
trigger(player) { true }
}
object Instance : AbstractCriterionTriggerInstance(ID, Composite.ANY)
}