Merge branch '1.21' into new-container-api

This commit is contained in:
DBotThePony 2025-03-05 09:49:31 +07:00
commit 892beddfc6
Signed by: DBot
GPG Key ID: DCC23B5715498507
64 changed files with 1497 additions and 86 deletions

View File

@ -190,7 +190,7 @@ dependencies {
compileOnly("curse.maven:resourceful-config-714059:${resourceful_config_id}") compileOnly("curse.maven:resourceful-config-714059:${resourceful_config_id}")
compileOnly("curse.maven:botarium-704113:${botarium_id}") compileOnly("curse.maven:botarium-704113:${botarium_id}")
compileOnly("curse.maven:ad-astra-635042:${ad_astra_id}") compileOnly("curse.maven:ad-astra-635042:${ad_astra_id}")
//runtimeOnly("curse.maven:worldedit-225608:${worldedit_id}") runtimeOnly("curse.maven:worldedit-225608:${worldedit_id}")
runtimeOnly("me.shedaniel.cloth:cloth-config-neoforge:${cloth_config_version}") runtimeOnly("me.shedaniel.cloth:cloth-config-neoforge:${cloth_config_version}")
implementation("io.wispforest:condensed_creative-neoforge:${condensed_creative_version}") implementation("io.wispforest:condensed_creative-neoforge:${condensed_creative_version}")

View File

@ -585,6 +585,7 @@ object DataGen {
addDecorativeLoot(lootTableProvider) addDecorativeLoot(lootTableProvider)
addAdvancementLoot(lootTableProvider) addAdvancementLoot(lootTableProvider)
addVaultLoot(lootTableProvider) addVaultLoot(lootTableProvider)
addEntityLoot(lootTableProvider)
addChestLootTables(lootTableProvider) addChestLootTables(lootTableProvider)
recipeProvider.exec { _, consumer -> recipeProvider.exec { _, consumer ->

View File

@ -114,6 +114,17 @@ fun addItemModels(provider: MatteryItemModelProvider) {
provider.handheld(MItems.CHEST_UPGRADER) provider.handheld(MItems.CHEST_UPGRADER)
provider.exec {
val path = MItems.CONFIGURATOR.registryName!!.path
val ready = provider.withExistingParent("${path}_ready", MatteryItemModelProvider.HANDHELD)
.texture("layer0", modLocation("item/${path}_ready"))
provider.withExistingParent(path, MatteryItemModelProvider.HANDHELD)
.texture("layer0", modLocation("item/$path"))
.override().predicate(modLocation("has_configuration_saved"), 1f).model(ready).end()
}
provider.generated(MItems.BREAD_MONSTER_SPAWN_EGG, modLocation("item/egg/bread_monster")) provider.generated(MItems.BREAD_MONSTER_SPAWN_EGG, modLocation("item/egg/bread_monster"))
provider.generated(MItems.LOADER_SPAWN_EGG, modLocation("item/egg/loader")) provider.generated(MItems.LOADER_SPAWN_EGG, modLocation("item/egg/loader"))

View File

@ -192,6 +192,10 @@ private fun misc(provider: MatteryLanguageProvider) {
gui("holo_screen.resize_text", "Resize text automatically") gui("holo_screen.resize_text", "Resize text automatically")
gui("holo_screen.do_not_resize_text", "Do not resize text") gui("holo_screen.do_not_resize_text", "Do not resize text")
gui("abc", "ABC")
gui("use_standard_font", "Use standard font")
gui("use_small_font", "Use small font")
gui("ticks", "Ticks") gui("ticks", "Ticks")
gui("power_cost_per_use", "Power cost per use: %s") gui("power_cost_per_use", "Power cost per use: %s")
@ -826,6 +830,7 @@ private fun items(provider: MatteryLanguageProvider) {
add(MItems.REINFORCED_IRON_PLATE, "desc", "A sturdier and more durable Iron Plate") add(MItems.REINFORCED_IRON_PLATE, "desc", "A sturdier and more durable Iron Plate")
add(MItems.ARMOR_ASSEMBLY, "Armor assembly") add(MItems.ARMOR_ASSEMBLY, "Armor assembly")
add(MItems.CARBON_MESH, "Carbon Mesh") add(MItems.CARBON_MESH, "Carbon Mesh")
add(MItems.DISPLAY_SCREEN, "Display Screen")
add(MItems.GRAVITATIONAL_DISRUPTOR, "Spacetime Equalizer") add(MItems.GRAVITATIONAL_DISRUPTOR, "Spacetime Equalizer")
@ -859,6 +864,12 @@ private fun items(provider: MatteryLanguageProvider) {
add(MItems.ENERGY_SWORD, "desc3", "Always strikes surrounding enemies with full damage if empowered") add(MItems.ENERGY_SWORD, "desc3", "Always strikes surrounding enemies with full damage if empowered")
add(MItems.ENERGY_SWORD, "desc4", "Does not benefit from Sweeping Edge enchantment") add(MItems.ENERGY_SWORD, "desc4", "Does not benefit from Sweeping Edge enchantment")
add(MItems.FALLING_SUN, "◄ Falling Sun ►")
add(MItems.FALLING_SUN, "desc", "Prototype weapon, needs power to operate")
add(MItems.FALLING_SUN, "desc2", "Deals extra damage to androids when empowered")
add(MItems.FALLING_SUN, "desc3", "Always strikes surrounding enemies with full damage if empowered")
add(MItems.FALLING_SUN, "desc4", "Does not benefit from Sweeping Edge enchantment")
add(MItems.PORTABLE_CONDENSATION_DRIVE, "Portable Condensation Drive") add(MItems.PORTABLE_CONDENSATION_DRIVE, "Portable Condensation Drive")
add(MItems.PORTABLE_DENSE_CONDENSATION_DRIVE, "Portable Dense Condensation Drive") add(MItems.PORTABLE_DENSE_CONDENSATION_DRIVE, "Portable Dense Condensation Drive")
add(MItems.TRITANIUM_ORE_CLUMP, "Raw Tritanium") add(MItems.TRITANIUM_ORE_CLUMP, "Raw Tritanium")
@ -918,6 +929,12 @@ private fun items(provider: MatteryLanguageProvider) {
add(MItems.CHEST_UPGRADER, "desc", "Replaces placed chests and barrels with cargo crates while keeping storage contents") add(MItems.CHEST_UPGRADER, "desc", "Replaces placed chests and barrels with cargo crates while keeping storage contents")
add(MItems.CHEST_UPGRADER, "desc2", "Hold desired crates in the opposite hand") add(MItems.CHEST_UPGRADER, "desc2", "Hold desired crates in the opposite hand")
add(MItems.CONFIGURATOR, "Configurator")
add(MItems.CONFIGURATOR, "desc", "Copies configuration from one block to another")
add(MItems.CONFIGURATOR, "desc2", "Sneak-use on block to copy, use to paste")
add(MItems.CONFIGURATOR, "desc3", "Use on air while sneaking to clear saved configuration")
add(MItems.CONFIGURATOR, "desc_saved", "Saved configuration for: %s")
add(MItems.BREAD_MONSTER_SPAWN_EGG, "Bread Monster Spawn Egg") add(MItems.BREAD_MONSTER_SPAWN_EGG, "Bread Monster Spawn Egg")
add(MEntityTypes.BREAD_MONSTER, "Bread Monster") add(MEntityTypes.BREAD_MONSTER, "Bread Monster")
@ -975,6 +992,11 @@ private fun gui(provider: MatteryLanguageProvider) {
gui("flow_direction_set", "Flow direction set to %s") gui("flow_direction_set", "Flow direction set to %s")
gui("tick_timer_set", "Timer set to %s ticks") gui("tick_timer_set", "Timer set to %s ticks")
gui("config_copied", "Copied configuration for %s")
gui("config_pasted", "Applied saved configuration")
gui("config_cleared", "Configuration cleared")
gui("config_missing", "No configuration to apply")
gui("black_hole_generator.help0", "Generates energy using angular momentum of Singularities") gui("black_hole_generator.help0", "Generates energy using angular momentum of Singularities")
gui("black_hole_generator.help1", "The stronger gravity Singularity has, the more power is generated!") gui("black_hole_generator.help1", "The stronger gravity Singularity has, the more power is generated!")
gui("black_hole_generator.help2", "Using Spacetime Normalizers will reduce gravitation strength of Singularity, which will reduce power output.") gui("black_hole_generator.help2", "Using Spacetime Normalizers will reduce gravitation strength of Singularity, which will reduce power output.")

View File

@ -202,6 +202,10 @@ private fun misc(provider: MatteryLanguageProvider) {
gui("holo_screen.resize_text", "Изменять размер текста автоматически") gui("holo_screen.resize_text", "Изменять размер текста автоматически")
gui("holo_screen.do_not_resize_text", "Не менять размер текста") gui("holo_screen.do_not_resize_text", "Не менять размер текста")
gui("abc", "АБВ")
gui("use_standard_font", "Использовать стандартный шрифт")
gui("use_small_font", "Использовать уменьшенный шрифт")
gui("ticks", "Тиков") gui("ticks", "Тиков")
gui("power_cost_per_use", "Энергии на операцию: %s") gui("power_cost_per_use", "Энергии на операцию: %s")
@ -819,6 +823,7 @@ private fun items(provider: MatteryLanguageProvider) {
add(MItems.REINFORCED_IRON_PLATE, "desc", "Более надёжная и прочная железная пластина") add(MItems.REINFORCED_IRON_PLATE, "desc", "Более надёжная и прочная железная пластина")
add(MItems.ARMOR_ASSEMBLY, "Стройка брони") add(MItems.ARMOR_ASSEMBLY, "Стройка брони")
add(MItems.CARBON_MESH, "Углеродная сетка") add(MItems.CARBON_MESH, "Углеродная сетка")
add(MItems.DISPLAY_SCREEN, "Экран дисплея")
add(MItems.GRAVITATIONAL_DISRUPTOR, "Маяк уравнения пространства-времени") add(MItems.GRAVITATIONAL_DISRUPTOR, "Маяк уравнения пространства-времени")
@ -852,6 +857,12 @@ private fun items(provider: MatteryLanguageProvider) {
add(MItems.ENERGY_SWORD, "desc3", "Всегда наносит полный урон по площади если имеет заряд") add(MItems.ENERGY_SWORD, "desc3", "Всегда наносит полный урон по площади если имеет заряд")
add(MItems.ENERGY_SWORD, "desc4", "Зачарование 'Разящий клинок' не имеет никакого эффекта на данном оружии") add(MItems.ENERGY_SWORD, "desc4", "Зачарование 'Разящий клинок' не имеет никакого эффекта на данном оружии")
add(MItems.FALLING_SUN, "◄ Падающее Солнце ►")
add(MItems.FALLING_SUN, "desc", "Прототип,требует энергию для работы")
add(MItems.FALLING_SUN, "desc2", "Наносит дополнительный урон андроидам если имеет заряд")
add(MItems.FALLING_SUN, "desc3", "Всегда наносит полный урон по площади если имеет заряд")
add(MItems.FALLING_SUN, "desc4", "Зачарование 'Разящий клинок' не имеет никакого эффекта на данном оружии")
add(MItems.PORTABLE_CONDENSATION_DRIVE, "Portable Condensation Drive") add(MItems.PORTABLE_CONDENSATION_DRIVE, "Portable Condensation Drive")
add(MItems.PORTABLE_DENSE_CONDENSATION_DRIVE, "Portable Dense Condensation Drive") add(MItems.PORTABLE_DENSE_CONDENSATION_DRIVE, "Portable Dense Condensation Drive")
add(MItems.TRITANIUM_ORE_CLUMP, "Рудный тритан") add(MItems.TRITANIUM_ORE_CLUMP, "Рудный тритан")
@ -911,6 +922,12 @@ private fun items(provider: MatteryLanguageProvider) {
add(MItems.CHEST_UPGRADER, "desc", "Заменяет установленные сундуки и бочки грузовыми ящиками с сохранением содержимого") add(MItems.CHEST_UPGRADER, "desc", "Заменяет установленные сундуки и бочки грузовыми ящиками с сохранением содержимого")
add(MItems.CHEST_UPGRADER, "desc2", "Удерживайте необходимые ящики в противоположной руке") add(MItems.CHEST_UPGRADER, "desc2", "Удерживайте необходимые ящики в противоположной руке")
add(MItems.CONFIGURATOR, "Конфигуратор")
add(MItems.CONFIGURATOR, "desc", "Копирует настройки между блоками")
add(MItems.CONFIGURATOR, "desc2", "Использование крадясь на блоке копирует настройки, простое использование применяет")
add(MItems.CONFIGURATOR, "desc3", "Используйте крадясь на воздухе для очистки")
add(MItems.CONFIGURATOR, "desc_saved", "Сохранены настройки для: %s")
add(MItems.BREAD_MONSTER_SPAWN_EGG, "Яйцо призыва хлебного монстра") add(MItems.BREAD_MONSTER_SPAWN_EGG, "Яйцо призыва хлебного монстра")
add(MEntityTypes.BREAD_MONSTER, "Хлебный монстр") add(MEntityTypes.BREAD_MONSTER, "Хлебный монстр")
@ -968,6 +985,11 @@ private fun gui(provider: MatteryLanguageProvider) {
gui("flow_direction_set", "Направление потока установлено на %s") gui("flow_direction_set", "Направление потока установлено на %s")
gui("tick_timer_set", "Таймер установлен на %s тиков") gui("tick_timer_set", "Таймер установлен на %s тиков")
gui("config_copied", "Скопированы настройки для %s")
gui("config_pasted", "Настройки применены")
gui("config_cleared", "Настройки очищены")
gui("config_missing", "Нет настроек для применения")
gui("black_hole_generator.help0", "Генерирует электричество используя угловое ускорение сингулярностей") gui("black_hole_generator.help0", "Генерирует электричество используя угловое ускорение сингулярностей")
gui("black_hole_generator.help1", "Чем сильнее гравитационное поле сингулярности, тем больше генерация!") gui("black_hole_generator.help1", "Чем сильнее гравитационное поле сингулярности, тем больше генерация!")
gui("black_hole_generator.help2", "Использование стабилизаторов пространства-времени ослабляет гравитационное поле, снижая генерацию") gui("black_hole_generator.help2", "Использование стабилизаторов пространства-времени ослабляет гравитационное поле, снижая генерацию")

View File

@ -0,0 +1,21 @@
package ru.dbotthepony.mc.otm.datagen.loot
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets
import ru.dbotthepony.mc.otm.datagen.modLootTable
import ru.dbotthepony.mc.otm.registry.game.MItems
fun addEntityLoot(loot: LootTables) {
loot.builder(LootContextParamSets.ENTITY, modLootTable("entities/loader")) {
lootPool {
item(MItems.MECHANICAL_PARTS) {
setCount(1, 3)
setWeight(7)
}
item(MItems.ELECTRIC_PARTS) {
setCount(1, 1)
setWeight(1)
}
setRolls(1)
}
}
}

View File

@ -1,8 +1,14 @@
package ru.dbotthepony.mc.otm.datagen.loot package ru.dbotthepony.mc.otm.datagen.loot
import net.minecraft.util.valueproviders.UniformInt
import net.minecraft.world.item.Items import net.minecraft.world.item.Items
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.data.world.UniformDecimal
import ru.dbotthepony.mc.otm.datagen.modLootTable import ru.dbotthepony.mc.otm.datagen.modLootTable
import ru.dbotthepony.mc.otm.item.ProceduralBatteryItem
import ru.dbotthepony.mc.otm.item.exopack.ProceduralExopackSlotUpgradeItem
import ru.dbotthepony.mc.otm.item.matter.MatterDustItem
import ru.dbotthepony.mc.otm.registry.game.MItems import ru.dbotthepony.mc.otm.registry.game.MItems
fun addChestLootTables(loot: LootTables) { fun addChestLootTables(loot: LootTables) {
@ -28,24 +34,93 @@ fun addChestLootTables(loot: LootTables) {
item(Items.COPPER_INGOT) { setCount(minimal = 1, maximal = 3) } item(Items.COPPER_INGOT) { setCount(minimal = 1, maximal = 3) }
item(Items.EXPOSED_COPPER) { setCount(minimal = 1, maximal = 2) } item(Items.EXPOSED_COPPER) { setCount(minimal = 1, maximal = 2) }
setRolls(3) item(MItems.ExopackUpgrades.INVENTORY_UPGRADE_PROCEDURAL) {
chanceCondition(0.1)
setWeight(1)
apply(ProceduralExopackSlotUpgradeItem.Randomizer(UniformInt.of(1, 9), UniformInt.of(0, 3)))
}
setRolls(7)
} }
} }
loot.builder(LootContextParamSets.CHEST, modLootTable("frigate_cargo")) { loot.builder(LootContextParamSets.CHEST, modLootTable("frigate_cargo")) {
lootPool { lootPool {
item(Items.IRON_INGOT) { setCount(minimal = 1, maximal = 3) } item(Items.IRON_INGOT) {
setCount(minimal = 1, maximal = 3)
setWeight(3)
}
item(Items.GOLD_INGOT) { setCount(minimal = 1, maximal = 3) } item(Items.GOLD_INGOT) { setCount(minimal = 1, maximal = 3) }
item(Items.EMERALD) { setCount(minimal = 1, maximal = 3) } item(Items.EMERALD) { setCount(minimal = 1, maximal = 3) }
item(MItems.TRITANIUM_INGOT) { setCount(minimal = 1, maximal = 3) } item(MItems.TRITANIUM_INGOT) { setCount(minimal = 1, maximal = 3) }
item(MItems.MECHANICAL_PARTS) { setCount(minimal = 2, maximal = 3) } item(MItems.MECHANICAL_PARTS) {
setCount(minimal = 2, maximal = 3)
setWeight(2)
}
item(MItems.CIRCUIT_PLATING) { setCount(minimal = 2, maximal = 3) } item(MItems.CIRCUIT_PLATING) { setCount(minimal = 2, maximal = 3) }
item(MItems.ENERGY_BUS) { setCount(minimal = 0, maximal = 2) }
item(MItems.ROFLITE_ALLOY_INGOT) { setCount(minimal = 0, maximal = 3) }
item(MItems.WITHERED_STEEL) { setCount(minimal = 0, maximal = 3) }
item(Items.SADDLE) { setCount(minimal = 0, maximal = 1) } item(Items.SADDLE) { setCount(minimal = 0, maximal = 1) }
item(Items.DIAMOND) { setCount(minimal = 0, maximal = 3) } item(Items.DIAMOND) { setCount(minimal = 0, maximal = 3) }
setRolls(3) item(MItems.ExopackUpgrades.INVENTORY_UPGRADE_PROCEDURAL) {
chanceCondition(0.2)
setWeight(3)
apply(ProceduralExopackSlotUpgradeItem.Randomizer(UniformInt.of(1, 9), UniformInt.of(0, 3)))
}
item(MItems.ExopackUpgrades.INVENTORY_UPGRADE_PROCEDURAL) {
chanceCondition(0.1)
setWeight(2)
apply(ProceduralExopackSlotUpgradeItem.Randomizer(UniformInt.of(9, 18), UniformInt.of(0, 3)))
}
item(MItems.PROCEDURAL_BATTERY) {
chanceCondition(0.05)
setWeight(1)
apply(
ProceduralBatteryItem.Randomizer(
maxBatteryLevel = UniformDecimal(Decimal(10_000_000), Decimal(50_000_000)),
batteryLevel = UniformDecimal(Decimal(0), Decimal(25_000_000)),
maxInput = UniformDecimal(Decimal(1_000), Decimal(5_000)),
))
}
item(MItems.ZPM_BATTERY) {
chanceCondition(0.001)
setWeight(1)
}
item(MItems.MATTER_DUST) {
chanceCondition(0.1)
setWeight(4)
apply(MatterDustItem.Randomizer(UniformDecimal(Decimal(100), Decimal(2_500))))
}
setRolls(12)
}
}
loot.builder(LootContextParamSets.CHEST, modLootTable("laboratory/supply")) {
lootPool {
item(Items.BREAD) { setCount(minimal = 2, maximal = 3) }
item(Items.HONEY_BOTTLE) { setCount(minimal = 1, maximal = 2) }
item(MItems.NUTRIENT_PASTE) { setCount(minimal = 2, maximal = 3) }
item(Items.SNOWBALL) { setCount(minimal = 1, maximal = 5) }
item(Items.PACKED_ICE) { setCount(minimal = 2, maximal = 3) }
setRolls(7)
}
}
loot.builder(LootContextParamSets.CHEST, modLootTable("laboratory/reward")) {
lootPool {
item(MItems.NUTRIENT_PASTE) { setCount(minimal = 2, maximal = 3) }
setRolls(5)
} }
} }
} }

View File

@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.datagen.models
import net.minecraft.world.item.DyeColor import net.minecraft.world.item.DyeColor
import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.WaterloggedTransparentBlock
import net.neoforged.neoforge.client.model.generators.BlockModelProvider import net.neoforged.neoforge.client.model.generators.BlockModelProvider
import net.neoforged.neoforge.data.event.GatherDataEvent import net.neoforged.neoforge.data.event.GatherDataEvent
import ru.dbotthepony.mc.otm.datagen.DataGen import ru.dbotthepony.mc.otm.datagen.DataGen
@ -81,7 +82,6 @@ class MatteryBlockModelProvider(event: GatherDataEvent) : BlockModelProvider(eve
} }
} }
} }
fun decorativeCubeAll(subdir: String, vararg blocks: Block) { fun decorativeCubeAll(subdir: String, vararg blocks: Block) {
for (block in blocks) { for (block in blocks) {
exec { exec {

View File

@ -100,4 +100,10 @@ fun addComponentRecipes(consumer: RecipeOutput) {
.row(MItemTags.COPPER_WIRES, MItems.MECHANICAL_PARTS, MItemTags.COPPER_WIRES) .row(MItemTags.COPPER_WIRES, MItems.MECHANICAL_PARTS, MItemTags.COPPER_WIRES)
.unlockedBy(MItems.ELECTROMAGNET) .unlockedBy(MItems.ELECTROMAGNET)
.build(consumer) .build(consumer)
MatteryRecipe(MItems.DISPLAY_SCREEN, 3)
.row(MItemTags.IRON_PLATES, Tags.Items.DUSTS_GLOWSTONE, Tags.Items.GLASS_PANES_COLORLESS)
.row(MItemTags.IRON_PLATES, Tags.Items.DUSTS_REDSTONE, Tags.Items.GLASS_PANES_COLORLESS)
.row(MItemTags.IRON_PLATES, Tags.Items.DUSTS_GLOWSTONE, Tags.Items.GLASS_PANES_COLORLESS)
.build(consumer)
} }

View File

@ -52,8 +52,8 @@ fun addCraftingTableRecipes(consumer: RecipeOutput) {
.save(consumer, modLocation("holo_sign_reset")) .save(consumer, modLocation("holo_sign_reset"))
MatteryRecipe(MBlocks.DRIVE_VIEWER[null]!!, category = machinesCategory) MatteryRecipe(MBlocks.DRIVE_VIEWER[null]!!, category = machinesCategory)
.rowAC(MItemTags.IRON_PLATES, MItemTags.IRON_PLATES) .rowBC(MItems.DISPLAY_SCREEN, Tags.Items.GLASS_PANES)
.row(Tags.Items.DUSTS_GLOWSTONE, MItems.MACHINE_FRAME, Tags.Items.GLASS_BLOCKS) .row(MItemTags.IRON_PLATES, MItems.MACHINE_FRAME, MItemTags.IRON_PLATES)
.row(MItemTags.BASIC_CIRCUIT, MItems.MATTER_IO_PORT, MItemTags.BASIC_CIRCUIT) .row(MItemTags.BASIC_CIRCUIT, MItems.MATTER_IO_PORT, MItemTags.BASIC_CIRCUIT)
.unlockedBy(MItems.MATTER_IO_PORT) .unlockedBy(MItems.MATTER_IO_PORT)
.build(consumer) .build(consumer)
@ -75,9 +75,9 @@ fun addCraftingTableRecipes(consumer: RecipeOutput) {
.build(consumer) .build(consumer)
MatteryRecipe(MBlocks.MATTER_PANEL[null]!!, category = machinesCategory) MatteryRecipe(MBlocks.MATTER_PANEL[null]!!, category = machinesCategory)
.row(MItems.ELECTRIC_PARTS, MItemTags.TRITANIUM_PLATES, Tags.Items.GLASS_BLOCKS) .row(MItems.ELECTRIC_PARTS, MItemTags.TRITANIUM_PLATES, Tags.Items.GLASS_PANES)
.row(MItems.MATTER_CABLE, Tags.Items.DUSTS_GLOWSTONE, Tags.Items.GLASS_BLOCKS) .row(MItems.MATTER_CABLE, MItems.DISPLAY_SCREEN, Tags.Items.GLASS_PANES)
.row(MItemTags.ADVANCED_CIRCUIT, MItemTags.TRITANIUM_PLATES, Tags.Items.GLASS_BLOCKS) .row(MItemTags.ADVANCED_CIRCUIT, MItemTags.TRITANIUM_PLATES, Tags.Items.GLASS_PANES)
.unlockedBy(Tags.Items.GLASS_BLOCKS) .unlockedBy(Tags.Items.GLASS_BLOCKS)
.build(consumer) .build(consumer)
@ -99,7 +99,7 @@ fun addCraftingTableRecipes(consumer: RecipeOutput) {
MatteryRecipe(MBlocks.ENERGY_COUNTER[null]!!, category = machinesCategory) MatteryRecipe(MBlocks.ENERGY_COUNTER[null]!!, category = machinesCategory)
.row(MItemTags.TRITANIUM_PLATES, MItems.ENERGY_BUS, MItemTags.TRITANIUM_PLATES) .row(MItemTags.TRITANIUM_PLATES, MItems.ENERGY_BUS, MItemTags.TRITANIUM_PLATES)
.row(MItemTags.BASIC_CIRCUIT, Tags.Items.DUSTS_GLOWSTONE, MItemTags.HARDENED_GLASS_PANES_COLORLESS) .row(MItemTags.BASIC_CIRCUIT, MItems.DISPLAY_SCREEN, MItemTags.HARDENED_GLASS_PANES)
.row(MItemTags.TRITANIUM_PLATES, MItems.ENERGY_BUS, MItemTags.TRITANIUM_PLATES) .row(MItemTags.TRITANIUM_PLATES, MItems.ENERGY_BUS, MItemTags.TRITANIUM_PLATES)
.unlockedBy(MItems.ENERGY_BUS) .unlockedBy(MItems.ENERGY_BUS)
.build(consumer) .build(consumer)
@ -223,7 +223,7 @@ fun addCraftingTableRecipes(consumer: RecipeOutput) {
.build(consumer) .build(consumer)
MatteryRecipe(MItems.BLACK_HOLE_SCANNER, category = RecipeCategory.TOOLS) MatteryRecipe(MItems.BLACK_HOLE_SCANNER, category = RecipeCategory.TOOLS)
.row(MItemTags.IRON_PLATES, Tags.Items.GLASS_PANES_COLORLESS, MItemTags.IRON_PLATES) .row(MItemTags.IRON_PLATES, MItems.DISPLAY_SCREEN, MItemTags.IRON_PLATES)
.row(MItemTags.GOLD_WIRES, MItems.GRAVITATION_FIELD_SENSOR, MItemTags.ADVANCED_CIRCUIT) .row(MItemTags.GOLD_WIRES, MItems.GRAVITATION_FIELD_SENSOR, MItemTags.ADVANCED_CIRCUIT)
.rowAC(Tags.Items.DUSTS_GLOWSTONE, MItemTags.TRITANIUM_PLATES) .rowAC(Tags.Items.DUSTS_GLOWSTONE, MItemTags.TRITANIUM_PLATES)
.unlockedBy(MItems.GRAVITATION_FIELD_SENSOR) .unlockedBy(MItems.GRAVITATION_FIELD_SENSOR)
@ -585,4 +585,12 @@ fun addCraftingTableRecipes(consumer: RecipeOutput) {
.unlockedBy(MItems.DILITHIUM_CRYSTAL) .unlockedBy(MItems.DILITHIUM_CRYSTAL)
.unlockedBy(MItems.DILITHIUM_CRYSTAL_BLOCK) .unlockedBy(MItems.DILITHIUM_CRYSTAL_BLOCK)
.save(consumer, modLocation("dilithium_crystal/from_block")) .save(consumer, modLocation("dilithium_crystal/from_block"))
MatteryRecipe(MItems.CONFIGURATOR, category = RecipeCategory.TOOLS)
.rowA(MItemTags.IRON_PLATES)
.row(Tags.Items.GLASS_PANES, Tags.Items.DUSTS_REDSTONE, MItems.DISPLAY_SCREEN)
.row(MItemTags.IRON_PLATES, MItemTags.BASIC_CIRCUIT, MItems.DILITHIUM_CRYSTAL)
.unlockedBy(MItems.DILITHIUM_CRYSTAL)
.unlockedBy(MItems.DISPLAY_SCREEN)
.build(consumer)
} }

View File

@ -433,11 +433,11 @@ fun addDecorativesRecipes(provider: MatteryRecipeProvider, consumer: RecipeOutpu
for ((color, item) in MRegistry.COMPUTER_TERMINAL.allItems) { for ((color, item) in MRegistry.COMPUTER_TERMINAL.allItems) {
val builder = MatteryRecipe(item, category = RecipeCategory.DECORATIONS) val builder = MatteryRecipe(item, category = RecipeCategory.DECORATIONS)
builder.row(MItemTags.BASIC_CIRCUIT, MItemTags.TRITANIUM_PLATES, MItemTags.HARDENED_GLASS_PANES_COLORLESS)
if (color != null) { if (color != null) {
builder.rowB(color.tag) builder.rowB(color.tag)
} }
builder.row(MItemTags.TRITANIUM_PLATES, MItems.DISPLAY_SCREEN, MItemTags.HARDENED_GLASS_PANES_COLORLESS)
builder.rowB(MItemTags.BASIC_CIRCUIT)
builder.build(consumer) builder.build(consumer)
} }

View File

@ -5,11 +5,11 @@ import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import ru.dbotthepony.mc.otm.core.IMatteryLevel; import ru.dbotthepony.mc.otm.core.IMatteryLevel;
import ru.dbotthepony.mc.otm.core.util.CMWCRandom; import ru.dbotthepony.mc.otm.core.util.Xoshiro256SSRandom;
@Mixin(Level.class) @Mixin(Level.class)
public abstract class LevelMixin implements IMatteryLevel { public abstract class LevelMixin implements IMatteryLevel {
public final RandomSource otm_random = new CMWCRandom(); public final RandomSource otm_random = new Xoshiro256SSRandom();
@Override @Override
public @NotNull RandomSource getOtmRandom() { public @NotNull RandomSource getOtmRandom() {

View File

@ -96,6 +96,11 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
*/ */
protected val savetablesLevel = Savetables() protected val savetablesLevel = Savetables()
/**
* Savetables for things configured from user input
*/
protected val savetablesConfig = Savetables()
/** /**
* "shortcut" for getting [BlockRotation] * "shortcut" for getting [BlockRotation]
* *
@ -269,6 +274,7 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
*/ */
open fun saveShared(nbt: CompoundTag, registry: Provider) { open fun saveShared(nbt: CompoundTag, registry: Provider) {
savetables.serializeNBT(nbt, registry) savetables.serializeNBT(nbt, registry)
saveConfiguration(nbt, registry)
} }
/** /**
@ -282,6 +288,15 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
super.loadAdditional(nbt, registry) super.loadAdditional(nbt, registry)
savetables.deserializeNBT(registry, nbt) savetables.deserializeNBT(registry, nbt)
savetablesLevel.deserializeNBT(registry, nbt) savetablesLevel.deserializeNBT(registry, nbt)
loadConfiguration(nbt, registry)
}
fun saveConfiguration(nbt: CompoundTag, registry: Provider) {
savetablesConfig.serializeNBT(nbt, registry)
}
fun loadConfiguration(nbt: CompoundTag, registry: Provider) {
savetablesConfig.deserializeNBT(registry, nbt)
} }
@Suppress("OVERRIDE_DEPRECATION") @Suppress("OVERRIDE_DEPRECATION")

View File

@ -56,7 +56,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
} }
init { init {
savetables.stateful(::redstoneControl, REDSTONE_CONTROL_KEY) savetablesConfig.stateful(::redstoneControl, REDSTONE_CONTROL_KEY)
} }
protected open val defaultDisplayName: Component protected open val defaultDisplayName: Component
@ -146,9 +146,9 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
init { init {
// https://tenor.com/view/simp-metal-gear-liquid-snake-running-gif-16717852 // https://tenor.com/view/simp-metal-gear-liquid-snake-running-gif-16717852
savetables.enum(::flow, "fluid_${side}_flow", FlowDirection::valueOf) savetablesConfig.enum(::flow, "fluid_${side}_flow", FlowDirection::valueOf)
savetables.bool(::automatePull, "fluid_${side}_pull") savetablesConfig.bool(::automatePull, "fluid_${side}_pull")
savetables.bool(::automatePush, "fluid_${side}_push") savetablesConfig.bool(::automatePush, "fluid_${side}_push")
} }
var flow by syncher.enum(possibleModes, setter = { access, value -> var flow by syncher.enum(possibleModes, setter = { access, value ->
@ -375,9 +375,9 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
} }
init { init {
savetables.enum(::energyFlow, "energy_${side}_flow", FlowDirection::valueOf) savetablesConfig.enum(::energyFlow, "energy_${side}_flow", FlowDirection::valueOf)
savetables.bool(::automatePull, "energy_${side}_pull") savetablesConfig.bool(::automatePull, "energy_${side}_pull")
savetables.bool(::automatePush, "energy_${side}_push") savetablesConfig.bool(::automatePush, "energy_${side}_push")
dirtyListeners.addListener(Runnable { dirtyListeners.addListener(Runnable {
updateTickerState() updateTickerState()
@ -626,9 +626,9 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
} }
init { init {
savetables.bool(::automatePull, "itemhandler_${side}_automatePull") savetablesConfig.bool(::automatePull, "itemhandler_${side}_automatePull")
savetables.bool(::automatePush, "itemhandler_${side}_automatePush") savetablesConfig.bool(::automatePush, "itemhandler_${side}_automatePush")
savetables.enum(::mode, "itemhandler_${side}_mode", ItemHandlerMode::valueOf) savetablesConfig.enum(::mode, "itemhandler_${side}_mode", ItemHandlerMode::valueOf)
waitForServerLevel { waitForServerLevel {
redstoneControl.addListener(::updateTickerState) redstoneControl.addListener(::updateTickerState)

View File

@ -73,7 +73,7 @@ abstract class MatteryWorkerBlockEntity<JobType : IJob>(
var balanceInputs = false var balanceInputs = false
init { init {
savetables.bool(::balanceInputs) savetablesConfig.bool(::balanceInputs)
} }
protected open fun jobUpdated(new: JobType?, old: JobType?, id: Int) {} protected open fun jobUpdated(new: JobType?, old: JobType?, id: Int) {}

View File

@ -118,9 +118,9 @@ class BlackHoleGeneratorBlockEntity(blockPos: BlockPos, blockState: BlockState)
exposeSideless(MatteryCapability.BLOCK_ENERGY, energy) exposeSideless(MatteryCapability.BLOCK_ENERGY, energy)
exposeSideless(Capabilities.EnergyStorage.BLOCK, energy) exposeSideless(Capabilities.EnergyStorage.BLOCK, energy)
savetables.enum(::mode, map = Mode::valueOf) savetablesConfig.enum(::mode, map = Mode::valueOf)
savetables.decimal(::injectionRate) savetablesConfig.decimal(::injectionRate)
savetables.decimal(::targetMass) savetablesConfig.decimal(::targetMass)
} }
private fun findBlackHoleRange(): Int { private fun findBlackHoleRange(): Int {

View File

@ -5,8 +5,7 @@ import net.minecraft.core.BlockPos
import net.minecraft.core.HolderLookup import net.minecraft.core.HolderLookup
import net.minecraft.core.registries.Registries import net.minecraft.core.registries.Registries
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.LongTag import net.minecraft.nbt.Tag
import net.minecraft.nbt.StringTag
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceKey import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
@ -35,8 +34,6 @@ import ru.dbotthepony.mc.otm.container.HandlerFilter
import ru.dbotthepony.mc.otm.container.slotted.FilteredContainerSlot import ru.dbotthepony.mc.otm.container.slotted.FilteredContainerSlot
import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.nbt.map
import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.core.otmRandom import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.menu.decorative.CargoCrateMenu import ru.dbotthepony.mc.otm.menu.decorative.CargoCrateMenu
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
@ -101,14 +98,20 @@ class CargoCrateBlockEntity(
override fun saveLevel(nbt: CompoundTag, registry: HolderLookup.Provider) { override fun saveLevel(nbt: CompoundTag, registry: HolderLookup.Provider) {
super.saveLevel(nbt, registry) super.saveLevel(nbt, registry)
lootTable?.let { nbt[LOOT_TABLE_KEY] = it.toString() }
lootTableSeed?.let { nbt[LOOT_TABLE_SEED_KEY] = it } if (lootTable != null) {
nbt.putString(LOOT_TABLE_KEY, lootTable!!.location().toString())
nbt.putLong(LOOT_TABLE_SEED_KEY, lootTableSeed ?: 0L)
}
} }
override fun loadAdditional(nbt: CompoundTag, registry: HolderLookup.Provider) { override fun loadAdditional(nbt: CompoundTag, registry: HolderLookup.Provider) {
super.loadAdditional(nbt, registry) super.loadAdditional(nbt, registry)
lootTable = nbt.map(LOOT_TABLE_KEY) { it: StringTag -> ResourceLocation.tryParse(it.asString)?.let { ResourceKey.create(Registries.LOOT_TABLE, it) } }
lootTableSeed = (nbt[LOOT_TABLE_SEED_KEY] as LongTag?)?.asLong if (nbt.contains(LOOT_TABLE_KEY, Tag.TAG_STRING.toInt())) {
lootTable = ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.tryParse(nbt.getString(LOOT_TABLE_KEY)))
lootTableSeed = if (nbt.contains(LOOT_TABLE_SEED_KEY, Tag.TAG_LONG.toInt())) nbt.getLong(LOOT_TABLE_SEED_KEY) else 0L
}
} }
fun unpackLootTable(ply: Player? = null) { fun unpackLootTable(ply: Player? = null) {

View File

@ -61,19 +61,25 @@ class HoloSignBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryB
access.accept(value) access.accept(value)
}).delegate }).delegate
var smallerFont by syncher.boolean(false, setter = { access, value ->
setChanged()
access.accept(value)
}).delegate
var isLocked = false var isLocked = false
init { init {
savetables.string(::signText) savetablesConfig.string(::signText)
savetablesLevel.bool(::isLocked) savetablesLevel.bool(::isLocked)
savetables.stateful(::redstoneControl) savetablesConfig.stateful(::redstoneControl)
savetables.float(::textRed) savetablesConfig.float(::textRed)
savetables.float(::textGreen) savetablesConfig.float(::textGreen)
savetables.float(::textBlue) savetablesConfig.float(::textBlue)
savetables.float(::textAlpha) savetablesConfig.float(::textAlpha)
savetables.bool(::textAutoScale) savetablesConfig.bool(::textAutoScale)
savetablesConfig.bool(::smallerFont)
} }
override fun createMenu(p_39954_: Int, p_39955_: Inventory, p_39956_: Player): AbstractContainerMenu { override fun createMenu(p_39954_: Int, p_39955_: Inventory, p_39956_: Player): AbstractContainerMenu {

View File

@ -116,7 +116,7 @@ class PainterBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDe
init { init {
addDroppableContainer(dyeInput) addDroppableContainer(dyeInput)
savetables.stateful(dyeInput, INVENTORY_KEY) savetables.stateful(dyeInput, INVENTORY_KEY)
savetables.bool(::isBulk) savetablesConfig.bool(::isBulk)
exposeGlobally(Capabilities.FluidHandler.BLOCK, this) exposeGlobally(Capabilities.FluidHandler.BLOCK, this)
} }

View File

@ -100,8 +100,8 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
exposeGlobally(MatteryCapability.MATTER_BLOCK, matter) exposeGlobally(MatteryCapability.MATTER_BLOCK, matter)
exposeGlobally(MatteryCapability.MATTER_NODE, matterNode) exposeGlobally(MatteryCapability.MATTER_NODE, matterNode)
savetables.bool(::isBottling) savetablesConfig.bool(::isBottling)
savetables.bool(::spitItemsWhenCantWork) savetablesConfig.bool(::spitItemsWhenCantWork)
savetables.stateful(::energy, ENERGY_KEY) savetables.stateful(::energy, ENERGY_KEY)
savetables.stateful(::matter, MATTER_STORAGE_KEY) savetables.stateful(::matter, MATTER_STORAGE_KEY)
savetables.stateful(::bottling) savetables.stateful(::bottling)

View File

@ -84,7 +84,7 @@ class MatterPanelBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte
exposeGlobally(MatteryCapability.MATTER_NODE, matterNode) exposeGlobally(MatteryCapability.MATTER_NODE, matterNode)
exposeGlobally(MatteryCapability.REPLICATION_TASK, this) exposeGlobally(MatteryCapability.REPLICATION_TASK, this)
savetables.bool(::isProvidingTasks) savetablesConfig.bool(::isProvidingTasks)
} }
override fun setLevel(level: Level) { override fun setLevel(level: Level) {

View File

@ -63,9 +63,9 @@ class DriveRackBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery
savetables.stateful(::energy, ENERGY_KEY) savetables.stateful(::energy, ENERGY_KEY)
savetables.stateful(::container, INVENTORY_KEY) savetables.stateful(::container, INVENTORY_KEY)
exposeGlobally(MatteryCapability.STORAGE_NODE, cell) exposeGlobally(MatteryCapability.STORAGE_NODE, cell)
savetables.int(::insertPriority) savetablesConfig.int(::insertPriority)
savetables.int(::extractPriority) savetablesConfig.int(::extractPriority)
savetables.enum(::mode, map = FlowDirection::valueOf) savetablesConfig.enum(::mode, map = FlowDirection::valueOf)
redstoneControl.addListener(Consumer { redstoneControl.addListener(Consumer {
cell.isDetached = it cell.isDetached = it

View File

@ -131,7 +131,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
} }
init { init {
savetables.codec(::filter, ItemFilter.CODEC, FILTER_KEY, Supplier { ItemFilter(MAX_FILTERS) }) savetablesConfig.codec(::filter, ItemFilter.CODEC, FILTER_KEY, Supplier { ItemFilter(MAX_FILTERS) })
} }
override fun setLevel(level: Level) { override fun setLevel(level: Level) {

View File

@ -112,7 +112,7 @@ abstract class AbstractStorageImportExport(
} }
init { init {
savetables.codec(::filter, ItemFilter.CODEC, FILTER_KEY, Supplier { ItemFilter(MAX_FILTERS) }) savetablesConfig.codec(::filter, ItemFilter.CODEC, FILTER_KEY, Supplier { ItemFilter(MAX_FILTERS) })
} }
companion object { companion object {

View File

@ -78,7 +78,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
} }
init { init {
savetables.int(::displayChartOnBlock) savetablesConfig.int(::displayChartOnBlock)
savetables.stateful(::history5s) savetables.stateful(::history5s)
savetables.stateful(::history15s) savetables.stateful(::history15s)
savetables.stateful(::history1m) savetables.stateful(::history1m)

View File

@ -12,6 +12,7 @@ import net.minecraft.client.gui.screens.DeathScreen
import net.minecraft.client.gui.screens.InBedChatScreen import net.minecraft.client.gui.screens.InBedChatScreen
import net.minecraft.client.player.LocalPlayer import net.minecraft.client.player.LocalPlayer
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.network.chat.Style
import net.minecraft.world.effect.MobEffects import net.minecraft.world.effect.MobEffects
import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
@ -112,6 +113,10 @@ object MatteryGUI {
event.registerAbove(VanillaGuiLayers.CAMERA_OVERLAYS, loc("android_low_power"), AndroidLowPowerLayer()) event.registerAbove(VanillaGuiLayers.CAMERA_OVERLAYS, loc("android_low_power"), AndroidLowPowerLayer())
} }
val SMALL_FONT = loc("small")
val SMALL_FONT_STYLE: Style = Style.EMPTY.withFont(SMALL_FONT)
val STANDARD_FONT_STYLE: Style = Style.EMPTY
class AndroidEnergyBarLayer : LayeredDraw.Layer { class AndroidEnergyBarLayer : LayeredDraw.Layer {
override fun render( override fun render(
graphics: GuiGraphics, graphics: GuiGraphics,
@ -163,9 +168,8 @@ object MatteryGUI {
} }
val formattedPower = mattery.androidEnergy.batteryLevel.formatPower() val formattedPower = mattery.androidEnergy.batteryLevel.formatPower()
val scale = if (ClientConfig.HUD.USE_SMALL_FONT) 1f else ClientConfig.HUD.BAR_TEXT_SCALE.toFloat()
val scale = ClientConfig.HUD.BAR_TEXT_SCALE.toFloat() guiGraphics.draw(formattedPower.withStyle(if (ClientConfig.HUD.USE_SMALL_FONT) SMALL_FONT_STYLE else STANDARD_FONT_STYLE), left + CHARGE_BG.width + 2f + scale, top + CHARGE_BG.height / 2f + scale, font = gui.font, scale = scale, gravity = RenderGravity.CENTER_LEFT, color = RGBAColor.FULL_POWER, drawOutline = true)
guiGraphics.draw(formattedPower, left + CHARGE_BG.width + 2f + scale, top + CHARGE_BG.height / 2f + scale, font = gui.font, scale = scale, gravity = RenderGravity.CENTER_LEFT, color = RGBAColor.YELLOW, drawOutline = true)
RenderSystem.disableBlend() RenderSystem.disableBlend()
RenderSystem.enableDepthTest() RenderSystem.enableDepthTest()
@ -230,8 +234,8 @@ object MatteryGUI {
if (ply.absorptionAmount > 0) if (ply.absorptionAmount > 0)
formattedHealth = TextComponent("%d+%d/%d".format(ply.health.toInt(), ply.absorptionAmount.toInt(), ply.maxHealth.toInt())) formattedHealth = TextComponent("%d+%d/%d".format(ply.health.toInt(), ply.absorptionAmount.toInt(), ply.maxHealth.toInt()))
val scale = ClientConfig.HUD.BAR_TEXT_SCALE.toFloat() val scale = if (ClientConfig.HUD.USE_SMALL_FONT) 1f else ClientConfig.HUD.BAR_TEXT_SCALE.toFloat()
guiGraphics.draw(formattedHealth, left - 2f, top + HEALTH_BG.height / 2f + 1f * scale, scale = scale, gravity = RenderGravity.CENTER_RIGHT, color = getHealthColorForPlayer(ply), drawOutline = true) guiGraphics.draw(formattedHealth.withStyle(if (ClientConfig.HUD.USE_SMALL_FONT) SMALL_FONT_STYLE else STANDARD_FONT_STYLE), left - 2f, top + HEALTH_BG.height / 2f + 1f * scale, scale = scale, gravity = RenderGravity.CENTER_RIGHT, color = getHealthColorForPlayer(ply), drawOutline = true)
RenderSystem.disableBlend() RenderSystem.disableBlend()
RenderSystem.enableDepthTest() RenderSystem.enableDepthTest()

View File

@ -4,6 +4,7 @@ import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.client.renderer.MultiBufferSource import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import net.minecraft.network.chat.MutableComponent
import ru.dbotthepony.mc.otm.block.entity.decorative.HoloSignBlockEntity import ru.dbotthepony.mc.otm.block.entity.decorative.HoloSignBlockEntity
import ru.dbotthepony.mc.otm.client.font import ru.dbotthepony.mc.otm.client.font
import ru.dbotthepony.mc.otm.client.render.DynamicBufferSource import ru.dbotthepony.mc.otm.client.render.DynamicBufferSource
@ -12,6 +13,9 @@ import ru.dbotthepony.mc.otm.client.render.draw
import ru.dbotthepony.mc.otm.core.get import ru.dbotthepony.mc.otm.core.get
import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom
import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.client.MatteryGUI.SMALL_FONT_STYLE
import ru.dbotthepony.mc.otm.client.MatteryGUI.STANDARD_FONT_STYLE
import ru.dbotthepony.mc.otm.core.TextComponent
import ru.dbotthepony.mc.otm.core.math.rotateWithBlockFacing import ru.dbotthepony.mc.otm.core.math.rotateWithBlockFacing
class HoloSignRenderer(private val context: BlockEntityRendererProvider.Context) : BlockEntityRenderer<HoloSignBlockEntity> { class HoloSignRenderer(private val context: BlockEntityRendererProvider.Context) : BlockEntityRenderer<HoloSignBlockEntity> {
@ -31,7 +35,8 @@ class HoloSignRenderer(private val context: BlockEntityRendererProvider.Context)
poseStack.translate(0.5f, 0.5f, 0.75f) poseStack.translate(0.5f, 0.5f, 0.75f)
poseStack.scale(0.01f, 0.01f, 0.01f) poseStack.scale(0.01f, 0.01f, 0.01f)
val lines = tile.signText.split('\n') val style = if (tile.smallerFont) SMALL_FONT_STYLE else STANDARD_FONT_STYLE
val lines: List<MutableComponent> = tile.signText.split('\n').map { TextComponent(it).withStyle(style) }
val totalHeight = lines.size * font.lineHeight + (lines.size - 1) * 2f val totalHeight = lines.size * font.lineHeight + (lines.size - 1) * 2f
var y = -totalHeight / 2f var y = -totalHeight / 2f

View File

@ -11,6 +11,8 @@ import ru.dbotthepony.mc.otm.client.screen.panels.input.NetworkedStringInputPane
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.kommons.math.RGBAColor import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.block.entity.decorative.HoloSignBlockEntity import ru.dbotthepony.mc.otm.block.entity.decorative.HoloSignBlockEntity
import ru.dbotthepony.mc.otm.client.MatteryGUI.SMALL_FONT_STYLE
import ru.dbotthepony.mc.otm.client.render.TextIcon
import ru.dbotthepony.mc.otm.client.render.Widgets18 import ru.dbotthepony.mc.otm.client.render.Widgets18
import ru.dbotthepony.mc.otm.client.screen.panels.button.BooleanButtonPanel import ru.dbotthepony.mc.otm.client.screen.panels.button.BooleanButtonPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
@ -84,6 +86,16 @@ class HoloSignScreen(menu: HoloSignMenu, inventory: Inventory, title: Component)
tooltipInactive = TranslatableComponent("otm.gui.lock_holo_screen.unlocked") tooltipInactive = TranslatableComponent("otm.gui.lock_holo_screen.unlocked")
)) ))
controls.addButton(BooleanButtonPanel.square18(
this@HoloSignScreen,
frame,
prop = menu.smallerFont,
iconActive = TextIcon(font = font, text = TranslatableComponent("otm.gui.abc").withStyle(SMALL_FONT_STYLE)),
iconInactive = TextIcon(font = font, text = TranslatableComponent("otm.gui.abc")),
tooltipActive = TranslatableComponent("otm.gui.use_small_font"),
tooltipInactive = TranslatableComponent("otm.gui.use_standard_font")
))
return frame return frame
} }
} }

View File

@ -69,6 +69,10 @@ object ClientConfig : AbstractConfig("client", ModConfig.Type.CLIENT) {
var BAR_TEXT_SCALE: Double by builder var BAR_TEXT_SCALE: Double by builder
.defineInRange("BAR_TEXT_SCALE", 0.5, 0.5, 1.0) .defineInRange("BAR_TEXT_SCALE", 0.5, 0.5, 1.0)
var USE_SMALL_FONT: Boolean by builder
.comment("Use smaller font on HUD bars", "(Scale is ignored)")
.define("USE_SMALL_FONT", false)
init { init {
builder.pop() builder.pop()
} }

View File

@ -1,12 +1,14 @@
package ru.dbotthepony.mc.otm.config package ru.dbotthepony.mc.otm.config
import ru.dbotthepony.mc.otm.item.weapon.EnergySwordItem import ru.dbotthepony.mc.otm.item.weapon.EnergySwordItem
import ru.dbotthepony.mc.otm.item.weapon.FallingSunItem
object ToolsConfig : AbstractConfig("tools") { object ToolsConfig : AbstractConfig("tools") {
val AXES_BREAK_LEAVES_INSTANTLY: Boolean by builder.define("AXES_BREAK_LEAVES_INSTANTLY", true) val AXES_BREAK_LEAVES_INSTANTLY: Boolean by builder.define("AXES_BREAK_LEAVES_INSTANTLY", true)
init { init {
EnergySwordItem.registerConfig(builder) EnergySwordItem.registerConfig(builder)
FallingSunItem.registerConfig(builder)
} }
object ExplosiveHammer { object ExplosiveHammer {

View File

@ -4,34 +4,35 @@ import net.minecraft.util.Mth
import net.minecraft.util.RandomSource import net.minecraft.util.RandomSource
import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian
import net.minecraft.world.level.levelgen.PositionalRandomFactory import net.minecraft.world.level.levelgen.PositionalRandomFactory
import net.minecraft.world.level.levelgen.RandomSupport
import java.lang.StringBuilder import java.lang.StringBuilder
import java.util.random.RandomGenerator import java.util.random.RandomGenerator
class CMWCRandom(seed: Long = System.nanoTime()) : RandomGenerator, RandomSource { /**
* Random number generator with insane period of at least 2^511
*/
class CMWCRandom(seed: Long = RandomSupport.generateUniqueSeed()) : RandomGenerator, RandomSource {
private val state = IntArray(CMWC_STATE_SIZE) private val state = IntArray(CMWC_STATE_SIZE)
private var carry = 0 private var carry = 0
private var stateIndex = 0 private var stateIndex = 0
private val gaussian = MarsagliaPolarGaussian(this) private val gaussian = MarsagliaPolarGaussian(this)
var seed: Long = seed
private set
init { init {
setSeed(seed) setSeed(seed)
} }
override fun setSeed(seed: Long) { override fun setSeed(seed: Long) {
this.seed = seed val rng = LCG64Random(seed)
carry = Integer.remainderUnsigned(seed.toInt(), CMWC_CARRY_MAX)
// init state with regular LCG produced values // init state with regular LCG produced values
state[0] = seed.toInt() for (i in 1 until state.size) {
state[1] = seed.shr(32).toInt() state[i] = rng.nextInt()
for (i in 2 until state.size) {
state[i] = 69069 * state[i - 2] + 362437
} }
do {
carry = rng.nextInt()
} while(carry !in 0 until CMWC_CARRY_MAX)
stateIndex = state.size - 1 stateIndex = state.size - 1
gaussian.reset() gaussian.reset()
} }
@ -109,7 +110,7 @@ class CMWCRandom(seed: Long = System.nanoTime()) : RandomGenerator, RandomSource
} }
companion object { companion object {
const val CMWC_STATE_SIZE = 256 // 4096 const val CMWC_STATE_SIZE = 32 // 4096
const val CMWC_CARRY_MAX = 809430660 const val CMWC_CARRY_MAX = 809430660
} }
} }

View File

@ -25,7 +25,7 @@ import kotlin.math.absoluteValue
import kotlin.math.max import kotlin.math.max
import kotlin.math.roundToInt import kotlin.math.roundToInt
private fun concat(numbers: String, suffix: Any): Component { private fun concat(numbers: String, suffix: Any): MutableComponent {
if (suffix == "") if (suffix == "")
return TextComponent(numbers) return TextComponent(numbers)
else if (suffix is Component) else if (suffix is Component)
@ -177,7 +177,7 @@ private fun resplice(number: String, decimals: Int): String {
return String(resplice) return String(resplice)
} }
fun Long.formatSiComponent(suffix: Any = "", decimalPlaces: Int = 3, formatAsReadable: BooleanSupplier = never, bias: Int = 0): Component { fun Long.formatSiComponent(suffix: Any = "", decimalPlaces: Int = 3, formatAsReadable: BooleanSupplier = never, bias: Int = 0): MutableComponent {
require(decimalPlaces >= 0) { "Invalid amount of decimal places required: $decimalPlaces" } require(decimalPlaces >= 0) { "Invalid amount of decimal places required: $decimalPlaces" }
if (formatAsReadable.asBoolean) { if (formatAsReadable.asBoolean) {
@ -193,18 +193,18 @@ fun Long.formatSiComponent(suffix: Any = "", decimalPlaces: Int = 3, formatAsRea
return TranslatableComponent(prefix.neighbour(bias).formatLocaleKey, "%.${decimalPlaces}f".format(this.toDouble() / prefix.long!!.toDouble()), suffix) return TranslatableComponent(prefix.neighbour(bias).formatLocaleKey, "%.${decimalPlaces}f".format(this.toDouble() / prefix.long!!.toDouble()), suffix)
} }
fun Int.formatSiComponent(suffix: Any = "", decimalPlaces: Int = 3, formatAsReadable: BooleanSupplier = never, bias: Int = 0): Component { fun Int.formatSiComponent(suffix: Any = "", decimalPlaces: Int = 3, formatAsReadable: BooleanSupplier = never, bias: Int = 0): MutableComponent {
return toLong().formatSiComponent(suffix, decimalPlaces, formatAsReadable, bias) return toLong().formatSiComponent(suffix, decimalPlaces, formatAsReadable, bias)
} }
fun Double.formatSiComponent(suffix: Any = "", decimalPlaces: Int = 3, formatAsReadable: BooleanSupplier = never, bias: Int = 0): Component { fun Double.formatSiComponent(suffix: Any = "", decimalPlaces: Int = 3, formatAsReadable: BooleanSupplier = never, bias: Int = 0): MutableComponent {
require(decimalPlaces >= 0) { "Invalid amount of decimal places required: $decimalPlaces" } require(decimalPlaces >= 0) { "Invalid amount of decimal places required: $decimalPlaces" }
if (formatAsReadable.asBoolean && this.absoluteValue >= 1.0) return concat(reformat("%.${decimalPlaces}f".format(this)), suffix) if (formatAsReadable.asBoolean && this.absoluteValue >= 1.0) return concat(reformat("%.${decimalPlaces}f".format(this)), suffix)
val prefix = SiPrefix.determine(this) val prefix = SiPrefix.determine(this)
return TranslatableComponent(prefix.neighbour(bias).formatLocaleKey, "%.${decimalPlaces}f".format(this / prefix.double), suffix) return TranslatableComponent(prefix.neighbour(bias).formatLocaleKey, "%.${decimalPlaces}f".format(this / prefix.double), suffix)
} }
fun Decimal.formatSiComponent(suffix: Any = "", decimalPlaces: Int = 3, formatAsReadable: BooleanSupplier = never, bias: Int = 0): Component { fun Decimal.formatSiComponent(suffix: Any = "", decimalPlaces: Int = 3, formatAsReadable: BooleanSupplier = never, bias: Int = 0): MutableComponent {
require(decimalPlaces >= 0) { "Invalid amount of decimal places required: $decimalPlaces" } require(decimalPlaces >= 0) { "Invalid amount of decimal places required: $decimalPlaces" }
if (this == Decimal.POSITIVE_INFINITY) return concat("", suffix) if (this == Decimal.POSITIVE_INFINITY) return concat("", suffix)
if (this == Decimal.NEGATIVE_INFINITY) return concat("-∞", suffix) if (this == Decimal.NEGATIVE_INFINITY) return concat("-∞", suffix)

View File

@ -0,0 +1,95 @@
package ru.dbotthepony.mc.otm.core.util
import net.minecraft.util.Mth
import net.minecraft.util.RandomSource
import net.minecraft.world.level.levelgen.LegacyRandomSource
import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian
import net.minecraft.world.level.levelgen.PositionalRandomFactory
import net.minecraft.world.level.levelgen.RandomSupport
import java.lang.StringBuilder
import java.util.random.RandomGenerator
/**
* Simple and insanely fast random number generator, which can be used for seeding (initializing internal state) of other number generators.
*
* While can be used on its own, it probably shouldn't.
*
* Differs from [LegacyRandomSource] (also LCG, created by [RandomSource.create]) Minecraft uses in:
* * Different constants (with supposedly/expected better statistical properties)
* * Always use upper 32 bits instead of implementing BitRandomSource and sampling some upper bits
* * Uses all bits from provided seed
*/
class LCG64Random(private var seed: Long = RandomSupport.generateUniqueSeed()) : RandomGenerator, RandomSource {
private val gaussian = MarsagliaPolarGaussian(this)
override fun setSeed(seed: Long) {
this.seed = seed
gaussian.reset()
}
override fun nextInt(): Int {
this.seed = MULTIPLIER * this.seed + INCREMENT
return this.seed.ushr(32).toInt()
}
override fun nextLong(): Long {
val a = nextInt().toLong() and 0xFFFFFFFFL
val b = nextInt().toLong() and 0xFFFFFFFFL
return a.shl(32) or b
}
override fun nextInt(bound: Int): Int {
return super<RandomGenerator>.nextInt(bound)
}
override fun nextInt(origin: Int, bound: Int): Int {
return super<RandomGenerator>.nextInt(origin, bound)
}
override fun nextBoolean(): Boolean {
return super.nextBoolean()
}
override fun nextFloat(): Float {
return super.nextFloat()
}
override fun nextDouble(): Double {
return super.nextDouble()
}
override fun nextGaussian(): Double {
return gaussian.nextGaussian()
}
override fun fork(): RandomSource {
return LCG64Random(nextLong())
}
override fun forkPositional(): PositionalRandomFactory {
return Positional(nextLong())
}
class Positional(val seed: Long) : PositionalRandomFactory {
override fun at(x: Int, y: Int, z: Int): RandomSource {
return LCG64Random(Mth.getSeed(x, y, z).xor(seed))
}
override fun fromHashOf(name: String): RandomSource {
return LCG64Random(name.hashCode().toLong().xor(seed))
}
override fun fromSeed(seed: Long): RandomSource {
return LCG64Random(seed)
}
override fun parityConfigString(builder: StringBuilder) {
throw UnsupportedOperationException()
}
}
companion object {
const val MULTIPLIER = 6364136223846793005
const val INCREMENT = 1442695040888963407
}
}

View File

@ -0,0 +1,132 @@
package ru.dbotthepony.mc.otm.core.util
import it.unimi.dsi.fastutil.HashCommon
import net.minecraft.util.Mth
import net.minecraft.util.RandomSource
import net.minecraft.world.level.levelgen.MarsagliaPolarGaussian
import net.minecraft.world.level.levelgen.PositionalRandomFactory
import net.minecraft.world.level.levelgen.RandomSupport
import java.lang.StringBuilder
import java.util.random.RandomGenerator
/**
* Excellent number generator with guaranteed period of 2^255
*/
class Xoshiro256SSRandom private constructor(
private var s0: Long,
private var s1: Long,
private var s2: Long,
private var s3: Long,
marker: Nothing?
) : RandomGenerator, RandomSource {
private val gaussian = MarsagliaPolarGaussian(this)
init {
require(
s0 != 0L ||
s1 != 0L ||
s2 != 0L ||
s3 != 0L
) { "Xoshiro can't operate with seed being entirely zero" }
}
constructor(s0: Long, s1: Long, s2: Long, s3: Long) : this(s0, s1, s2, s3, null) {
// discard some values so generator can get going if provided seed was "weak"
for (i in 0 until 32)
nextLong()
}
constructor(seed: Long) : this(1L, 2L, 3L, 4L, null) {
setSeed(seed)
}
constructor() : this(RandomSupport.generateUniqueSeed(), RandomSupport.generateUniqueSeed(), RandomSupport.generateUniqueSeed(), RandomSupport.generateUniqueSeed(), null)
override fun setSeed(seed: Long) {
val rng = LCG64Random(seed)
s0 = rng.nextLong()
s1 = rng.nextLong()
s2 = rng.nextLong()
s3 = rng.nextLong()
gaussian.reset()
}
override fun nextInt(): Int {
// sample upper bits
return nextLong().ushr(32).toInt()
}
override fun nextLong(): Long {
val result = (s1 * 5).rotateLeft(7) * 9
val t = s1.shl(17)
s2 = s2.xor(s0)
s3 = s3.xor(s1)
s1 = s1.xor(s2)
s0 = s0.xor(s3)
s2 = s2.xor(t)
s3 = s3.rotateLeft(45)
return result
}
override fun nextInt(bound: Int): Int {
return super<RandomGenerator>.nextInt(bound)
}
override fun nextInt(origin: Int, bound: Int): Int {
return super<RandomGenerator>.nextInt(origin, bound)
}
override fun nextBoolean(): Boolean {
return super.nextBoolean()
}
override fun nextFloat(): Float {
return super.nextFloat()
}
override fun nextDouble(): Double {
return super.nextDouble()
}
override fun nextGaussian(): Double {
return gaussian.nextGaussian()
}
override fun fork(): RandomSource {
return Xoshiro256SSRandom(nextLong(), nextLong(), nextLong(), nextLong())
}
override fun forkPositional(): PositionalRandomFactory {
return Positional(nextLong(), nextLong(), nextLong(), nextLong())
}
class Positional(
val s0: Long,
val s1: Long,
val s2: Long,
val s3: Long,
) : PositionalRandomFactory {
override fun at(x: Int, y: Int, z: Int): RandomSource {
val rng = LCG64Random(Mth.getSeed(x, y, z))
return Xoshiro256SSRandom(
s0.rotateLeft(11).xor(rng.nextLong()),
s1.rotateLeft(22).xor(rng.nextLong()),
s2.rotateLeft(33).xor(rng.nextLong()),
s3.rotateLeft(44).xor(rng.nextLong()),
)
}
override fun fromHashOf(name: String): RandomSource {
return Xoshiro256SSRandom(s0, HashCommon.murmurHash3(name.hashCode().toLong()).xor(s1), s2, s3)
}
override fun fromSeed(seed: Long): RandomSource {
return Xoshiro256SSRandom(seed)
}
override fun parityConfigString(builder: StringBuilder) {
throw UnsupportedOperationException()
}
}
}

View File

@ -3,6 +3,10 @@ package ru.dbotthepony.mc.otm.entity
import net.minecraft.network.syncher.EntityDataAccessor import net.minecraft.network.syncher.EntityDataAccessor
import net.minecraft.network.syncher.EntityDataSerializers import net.minecraft.network.syncher.EntityDataSerializers
import net.minecraft.network.syncher.SynchedEntityData import net.minecraft.network.syncher.SynchedEntityData
import net.minecraft.resources.ResourceKey
import net.minecraft.core.registries.Registries
import ru.dbotthepony.mc.otm.core.ResourceLocation
import net.minecraft.world.level.storage.loot.LootTable
import net.minecraft.sounds.SoundEvent import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundEvents import net.minecraft.sounds.SoundEvents
import net.minecraft.world.entity.AnimationState import net.minecraft.world.entity.AnimationState
@ -21,6 +25,7 @@ import net.minecraft.world.entity.ai.navigation.PathNavigation
import net.minecraft.world.entity.monster.Monster import net.minecraft.world.entity.monster.Monster
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.registry.game.MSoundEvents import ru.dbotthepony.mc.otm.registry.game.MSoundEvents
@ -100,6 +105,11 @@ class Loader(type: EntityType<Loader>, level: Level) : Monster(type, level) {
return success return success
} }
override fun getDefaultLootTable(): ResourceKey<LootTable> {
return ResourceKey.create(Registries.LOOT_TABLE,
ResourceLocation(OverdriveThatMatters.MOD_ID, "entities/loader"))
}
override fun aiStep() { override fun aiStep() {
super.aiStep() super.aiStep()

View File

@ -0,0 +1,111 @@
package ru.dbotthepony.mc.otm.item
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.InteractionHand
import net.minecraft.world.InteractionResult
import net.minecraft.world.InteractionResultHolder
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.item.context.UseOnContext
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Blocks
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
import ru.dbotthepony.mc.otm.core.TextComponent
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.registry.game.MDataComponentTypes
import ru.dbotthepony.mc.otm.server.sendActionBarMessage
class ConfiguratorItem : MatteryItem(Properties().stacksTo(1)) {
init {
addSimpleDescription()
addSimpleDescription("2")
addSimpleDescription("3")
}
override fun appendHoverText(
stack: ItemStack,
context: TooltipContext,
components: MutableList<Component>,
tooltipType: TooltipFlag
) {
super.appendHoverText(stack, context, components, tooltipType)
val tag = getConfiguration(stack)
val block = stack.getOrDefault(MDataComponentTypes.Configurator.BLOCK, Blocks.AIR.defaultBlockState())
if (!tag.isEmpty && !block.isAir) {
components.add(TranslatableComponent("$descriptionId.desc_saved", block.block.name))
}
}
override fun use(level: Level, player: Player, hand: InteractionHand): InteractionResultHolder<ItemStack?> {
if (player is ServerPlayer && player.isCrouching) {
val stack = player.getItemInHand(hand)
setConfiguration(stack, CompoundTag())
stack.set(MDataComponentTypes.Configurator.BLOCK, Blocks.AIR.defaultBlockState())
player.sendActionBarMessage(TranslatableComponent("otm.gui.config_cleared"))
return InteractionResultHolder.success(stack)
}
return super.use(level, player, hand)
}
override fun onItemUseFirst(stack: ItemStack, context: UseOnContext): InteractionResult {
val player = context.player
if (player == null) return super.useOn(context)
val level = context.level
val tile = level.getBlockEntity(context.clickedPos)
if (tile == null || tile !is MatteryBlockEntity) return super.useOn(context)
if (player.isCrouching == true) {
if (player is ServerPlayer) {
val tag = CompoundTag()
tile.saveConfiguration(tag, level.registryAccess())
if (tag.isEmpty) return super.onItemUseFirst(stack, context)
setConfiguration(stack, tag)
val block = level.getBlockState(context.clickedPos)
stack.set(MDataComponentTypes.Configurator.BLOCK, block)
player.sendActionBarMessage(TranslatableComponent("otm.gui.config_copied", block.block.name))
}
return InteractionResult.SUCCESS
}
val tag = getConfiguration(stack)
if (!tag.isEmpty) {
if (player is ServerPlayer) {
tile.loadConfiguration(tag, level.registryAccess())
player.sendActionBarMessage(TranslatableComponent("otm.gui.config_pasted"))
}
return InteractionResult.SUCCESS
} else {
if (player is ServerPlayer) {
player.sendActionBarMessage(TranslatableComponent("otm.gui.config_missing"))
}
return InteractionResult.FAIL
}
return super.useOn(context)
}
fun getConfiguration(stack: ItemStack): CompoundTag {
return stack.getOrDefault(MDataComponentTypes.Configurator.CONFIGURATION, CompoundTag())
}
fun setConfiguration(stack: ItemStack, tag: CompoundTag) {
stack.set(MDataComponentTypes.Configurator.CONFIGURATION, tag)
}
}

View File

@ -0,0 +1,232 @@
package ru.dbotthepony.mc.otm.item.weapon
import net.minecraft.core.BlockPos
import net.minecraft.core.component.DataComponents
import net.minecraft.tags.BlockTags
import net.minecraft.world.entity.EquipmentSlotGroup
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.attributes.AttributeModifier
import net.minecraft.world.entity.ai.attributes.Attributes
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Rarity
import net.minecraft.world.item.component.ItemAttributeModifiers
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.state.BlockState
import net.neoforged.neoforge.capabilities.Capabilities
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent
import net.neoforged.neoforge.common.ItemAbilities
import net.neoforged.neoforge.common.ItemAbility
import net.neoforged.neoforge.common.ModConfigSpec
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.energy.EnergyConsumerItem
import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact
import ru.dbotthepony.mc.otm.capability.energy.getBarColor
import ru.dbotthepony.mc.otm.capability.energy.getBarWidth
import ru.dbotthepony.mc.otm.capability.matteryEnergy
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.core.damageType
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
import ru.dbotthepony.mc.otm.core.math.defineDecimal
import ru.dbotthepony.mc.otm.core.math.nextVariance
import ru.dbotthepony.mc.otm.core.otmRandom
import ru.dbotthepony.mc.otm.core.util.WriteOnce
import ru.dbotthepony.mc.otm.item.MatteryItem
import ru.dbotthepony.mc.otm.item.addSimpleDescription
import ru.dbotthepony.mc.otm.registry.CapabilitiesRegisterListener
import ru.dbotthepony.mc.otm.registry.MDamageTypes
import ru.dbotthepony.mc.otm.registry.MatteryDamageSource
class FallingSunItem : MatteryItem(Properties().stacksTo(1).rarity(Rarity.EPIC)), CapabilitiesRegisterListener {
private val chargedAttributes: ItemAttributeModifiers
private val dischargedAttributes: ItemAttributeModifiers
init {
var builder = ItemAttributeModifiers.builder()
builder.add(Attributes.ATTACK_DAMAGE, AttributeModifier(BASE_ATTACK_DAMAGE_ID, 13.0, AttributeModifier.Operation.ADD_VALUE), EquipmentSlotGroup.MAINHAND)
builder.add(Attributes.ATTACK_SPEED, AttributeModifier(BASE_ATTACK_SPEED_ID, -3.4, AttributeModifier.Operation.ADD_VALUE), EquipmentSlotGroup.MAINHAND)
builder.add(Attributes.SWEEPING_DAMAGE_RATIO, AttributeModifier(ResourceLocation(OverdriveThatMatters.MOD_ID, "energy_sword_sweeping_edge"), 1.0, AttributeModifier.Operation.ADD_VALUE), EquipmentSlotGroup.MAINHAND)
chargedAttributes = builder.build()
builder = ItemAttributeModifiers.builder()
builder.add(Attributes.ATTACK_DAMAGE, AttributeModifier(BASE_ATTACK_DAMAGE_ID, 5.5, AttributeModifier.Operation.ADD_VALUE), EquipmentSlotGroup.MAINHAND)
builder.add(Attributes.ATTACK_SPEED, AttributeModifier(BASE_ATTACK_SPEED_ID, -3.4, AttributeModifier.Operation.ADD_VALUE), EquipmentSlotGroup.MAINHAND)
dischargedAttributes = builder.build()
}
override fun isEnchantable(p_41456_: ItemStack): Boolean {
return p_41456_.count == 1
}
override fun getEnchantmentValue(stack: ItemStack): Int {
return 12
}
override fun getDestroySpeed(itemStack: ItemStack, blockState: BlockState): Float {
val energy = itemStack.getCapability(MatteryCapability.ITEM_ENERGY) ?: return 1f
if (blockState.`is`(Blocks.COBWEB)) {
return if (energy.batteryLevel < COBWEB_POWER_COST) 2f else 25f
} else if (blockState.`is`(BlockTags.SWORD_EFFICIENT)) {
return if (energy.batteryLevel < PLANT_POWER_COST) 1.5f else 8f
} else {
return 1f
}
}
override fun canAttackBlock(p_41441_: BlockState, p_41442_: Level, p_41443_: BlockPos, p_41444_: Player): Boolean {
return !p_41444_.isCreative
}
override fun hurtEnemy(itemStack: ItemStack, victim: LivingEntity, attacker: LivingEntity): Boolean {
if (attacker is Player && attacker.isCreative) {
victim.matteryPlayer?.let {
if (it.isAndroid) {
victim.invulnerableTime = 0
victim.hurt(MatteryDamageSource(attacker.level().registryAccess().damageType(MDamageTypes.EMP), attacker, itemStack), 8f)
}
}
return true
}
itemStack.getCapability(MatteryCapability.ITEM_ENERGY)?.let {
if (it.extractEnergyExact(ENERGY_PER_SWING, false)) {
it.extractEnergy(attacker.level().otmRandom.nextVariance(ENERGY_PER_SWING_VARIANCE), false)
victim.matteryPlayer?.let {
if (it.isAndroid && it.androidEnergy.extractEnergyExact(ENERGY_ZAP, false)) {
it.androidEnergy.extractEnergy(attacker.level().otmRandom.nextVariance(ENERGY_ZAP_VARIANCE), false)
victim.hurt(MatteryDamageSource(attacker.level().registryAccess().damageType(MDamageTypes.EMP), attacker, itemStack), 8f)
}
}
}
}
return true
}
override fun isBarVisible(p_150899_: ItemStack): Boolean {
return p_150899_.matteryEnergy != null
}
override fun getBarWidth(p_150900_: ItemStack): Int {
return p_150900_.matteryEnergy?.getBarWidth() ?: super.getBarWidth(p_150900_)
}
override fun getBarColor(p_150901_: ItemStack): Int {
return p_150901_.matteryEnergy?.getBarColor() ?: super.getBarColor(p_150901_)
}
init {
tooltips.itemEnergy()
addSimpleDescription()
addSimpleDescription("2")
addSimpleDescription("3")
addSimpleDescription("4")
}
override fun mineBlock(
itemStack: ItemStack,
p_41417_: Level,
blockState: BlockState,
p_41419_: BlockPos,
user: LivingEntity
): Boolean {
if (blockState.getDestroySpeed(p_41417_, p_41419_) > 0f && (user !is Player || !user.isCreative)) {
val energy = itemStack.matteryEnergy
if (blockState.`is`(BlockTags.SWORD_EFFICIENT)) {
if (energy?.extractEnergyExact(PLANT_POWER_COST, false) == true)
energy.extractEnergyExact(user.level().otmRandom.nextVariance(PLANT_POWER_COST_VARIANCE), false)
}
if (blockState.`is`(Blocks.COBWEB)) {
if (energy?.extractEnergyExact(COBWEB_POWER_COST, false) == true)
energy.extractEnergyExact(user.level().otmRandom.nextVariance(COBWEB_POWER_COST_VARIANCE), false)
}
}
return true
}
override fun isCorrectToolForDrops(stack: ItemStack, state: BlockState): Boolean {
val energy = stack.matteryEnergy ?: return super.isCorrectToolForDrops(stack, state)
if (state.`is`(BlockTags.SWORD_EFFICIENT) && energy.batteryLevel >= PLANT_POWER_COST)
return true
else if (state.`is`(Blocks.COBWEB) && energy.batteryLevel >= COBWEB_POWER_COST)
return true
return super.isCorrectToolForDrops(stack, state)
}
private fun cap(stack: ItemStack) = EnergyConsumerItem(stack, MAX_ENERGY)
override fun registerCapabilities(event: RegisterCapabilitiesEvent) {
event.registerItem(MatteryCapability.ITEM_ENERGY, { o, _ -> cap(o) }, this)
event.registerItem(Capabilities.EnergyStorage.ITEM, { o, _ -> cap(o) }, this)
}
override fun getDefaultAttributeModifiers(stack: ItemStack): ItemAttributeModifiers {
val energy = cap(stack)
if (energy.batteryLevel >= ENERGY_PER_SWING) {
return chargedAttributes
}
return dischargedAttributes
}
override fun canPerformAction(stack: ItemStack, toolAction: ItemAbility): Boolean {
if (cap(stack).extractEnergyExact(ENERGY_PER_SWING, true)) {
return ItemAbilities.DEFAULT_SWORD_ACTIONS.contains(toolAction)
}
return false
}
companion object {
val MAX_ENERGY get() = _MAX_ENERGY.get()
val ENERGY_ZAP get() = _ENERGY_ZAP.get()
val ENERGY_ZAP_VARIANCE get() = _ENERGY_ZAP_VARIANCE.get()
val ENERGY_PER_SWING get() = _ENERGY_PER_SWING.get()
val ENERGY_PER_SWING_VARIANCE get() = _ENERGY_PER_SWING_VARIANCE.get()
val COBWEB_POWER_COST get() = _COBWEB_POWER_COST.get()
val COBWEB_POWER_COST_VARIANCE get() = _COBWEB_POWER_COST_VARIANCE.get()
val PLANT_POWER_COST get() = _PLANT_POWER_COST.get()
val PLANT_POWER_COST_VARIANCE get() = _PLANT_POWER_COST_VARIANCE.get()
private var _MAX_ENERGY: DecimalConfigValue by WriteOnce()
private var _ENERGY_ZAP: DecimalConfigValue by WriteOnce()
private var _ENERGY_ZAP_VARIANCE: DecimalConfigValue by WriteOnce()
private var _ENERGY_PER_SWING: DecimalConfigValue by WriteOnce()
private var _ENERGY_PER_SWING_VARIANCE: DecimalConfigValue by WriteOnce()
private var _COBWEB_POWER_COST: DecimalConfigValue by WriteOnce()
private var _COBWEB_POWER_COST_VARIANCE: DecimalConfigValue by WriteOnce()
private var _PLANT_POWER_COST: DecimalConfigValue by WriteOnce()
private var _PLANT_POWER_COST_VARIANCE: DecimalConfigValue by WriteOnce()
fun registerConfig(builder: ModConfigSpec.Builder) {
builder.comment("Falling Sun values").push("FallingSun")
_MAX_ENERGY = builder.defineDecimal("MAX_ENERGY", Decimal(3_500_000), Decimal.ZERO)
_ENERGY_ZAP = builder.comment("Extra energy required when hitting androids").defineDecimal("ENERGY_ZAP", Decimal(4_000), Decimal.ZERO)
_ENERGY_ZAP_VARIANCE = builder.comment("Random deviation from ENERGY_ZAP").defineDecimal("ENERGY_ZAP_VARIANCE", Decimal(1200), Decimal.ZERO)
_ENERGY_PER_SWING = builder.defineDecimal("ENERGY_PER_SWING", Decimal(3_000), Decimal.ZERO)
_ENERGY_PER_SWING_VARIANCE = builder.comment("Random deviation from ENERGY_PER_SWING").defineDecimal("ENERGY_PER_SWING_VARIANCE", Decimal(600), Decimal.ZERO)
_COBWEB_POWER_COST = builder.defineDecimal("COBWEB_POWER_COST", Decimal(2_500), Decimal.ZERO)
_COBWEB_POWER_COST_VARIANCE = builder.comment("Random deviation from COBWEB_POWER_COST").defineDecimal("COBWEB_POWER_COST_VARIANCE", Decimal(500), Decimal.ZERO)
_PLANT_POWER_COST = builder.defineDecimal("PLANT_POWER_COST", Decimal(500), Decimal.ZERO)
_PLANT_POWER_COST_VARIANCE = builder.comment("Random deviation from PLANT_POWER_COST").defineDecimal("PLANT_POWER_COST_VARIANCE", Decimal(100), Decimal.ZERO)
builder.pop()
}
}
}

View File

@ -24,6 +24,7 @@ class HoloSignMenu(
val textBlue = FloatInputWithFeedback(this) val textBlue = FloatInputWithFeedback(this)
val textAlpha = FloatInputWithFeedback(this) val textAlpha = FloatInputWithFeedback(this)
val textAutoScale = BooleanInputWithFeedback(this) val textAutoScale = BooleanInputWithFeedback(this)
val smallerFont = BooleanInputWithFeedback(this)
init { init {
text.filter { it.isCreative || !locked.value } text.filter { it.isCreative || !locked.value }
@ -36,6 +37,7 @@ class HoloSignMenu(
textAlpha.filter { it.isCreative || !locked.value } textAlpha.filter { it.isCreative || !locked.value }
textAutoScale.filter { it.isCreative || !locked.value } textAutoScale.filter { it.isCreative || !locked.value }
smallerFont.filter { it.isCreative || !locked.value }
if (tile != null) { if (tile != null) {
text.withConsumer { tile.signText = HoloSignBlockEntity.truncate(it, tile.isLocked) }.withSupplier(tile::signText) text.withConsumer { tile.signText = HoloSignBlockEntity.truncate(it, tile.isLocked) }.withSupplier(tile::signText)
@ -46,6 +48,7 @@ class HoloSignMenu(
locked.with(tile::isLocked) locked.with(tile::isLocked)
redstone.with(tile.redstoneControl::redstoneSetting) redstone.with(tile.redstoneControl::redstoneSetting)
textAutoScale.with(tile::textAutoScale) textAutoScale.with(tile::textAutoScale)
smallerFont.with(tile::smallerFont)
} }
} }
} }

View File

@ -194,10 +194,12 @@ object MNames {
const val TRITANIUM_SHIELD = "tritanium_shield" const val TRITANIUM_SHIELD = "tritanium_shield"
const val ENERGY_SWORD = "energy_sword" const val ENERGY_SWORD = "energy_sword"
const val FALLING_SUN = "falling_sun"
const val PLASMA_RIFLE = "plasma_rifle" const val PLASMA_RIFLE = "plasma_rifle"
const val CHEST_UPGRADER = "chest_upgrader" const val CHEST_UPGRADER = "chest_upgrader"
const val CONFIGURATOR = "configurator"
const val WITHERED_STEEL_SWORD = "withered_steel_sword" const val WITHERED_STEEL_SWORD = "withered_steel_sword"
@ -230,6 +232,7 @@ object MNames {
const val MIRROR_COMPOUND = "mirror_compound" const val MIRROR_COMPOUND = "mirror_compound"
const val MIRROR = "mirror" const val MIRROR = "mirror"
const val BLANK_MACHINE_UPGRADE = "blank_machine_upgrade" const val BLANK_MACHINE_UPGRADE = "blank_machine_upgrade"
const val DISPLAY_SCREEN = "display_screen"
const val ENERGY_BUS = "energy_bus" const val ENERGY_BUS = "energy_bus"

View File

@ -6,6 +6,7 @@ import net.minecraft.core.BlockPos
import net.minecraft.core.cauldron.CauldronInteraction import net.minecraft.core.cauldron.CauldronInteraction
import net.minecraft.core.component.DataComponents import net.minecraft.core.component.DataComponents
import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.nbt.CompoundTag
import net.minecraft.world.entity.EntityType import net.minecraft.world.entity.EntityType
import net.minecraft.world.item.DyeColor import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.Item import net.minecraft.world.item.Item
@ -42,6 +43,8 @@ import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.isClient import ru.dbotthepony.mc.otm.isClient
import ru.dbotthepony.mc.otm.item.armor.TritaniumArmorItem import ru.dbotthepony.mc.otm.item.armor.TritaniumArmorItem
import ru.dbotthepony.mc.otm.item.weapon.EnergySwordItem import ru.dbotthepony.mc.otm.item.weapon.EnergySwordItem
import ru.dbotthepony.mc.otm.item.weapon.FallingSunItem
import ru.dbotthepony.mc.otm.registry.game.MDataComponentTypes
import ru.dbotthepony.mc.otm.registry.game.MItems import ru.dbotthepony.mc.otm.registry.game.MItems
import ru.dbotthepony.mc.otm.registry.game.MStats import ru.dbotthepony.mc.otm.registry.game.MStats
import ru.dbotthepony.mc.otm.registry.objects.ColoredDecorativeBlock import ru.dbotthepony.mc.otm.registry.objects.ColoredDecorativeBlock
@ -284,6 +287,14 @@ object MRegistry : IBlockItemRegistryAcceptor {
} }
} }
ItemProperties.register(MItems.FALLING_SUN, ResourceLocation(OverdriveThatMatters.MOD_ID, "is_powered")) { stack, _, _, _ ->
if ((stack.matteryEnergy?.batteryLevel ?: Decimal.ZERO) >= FallingSunItem.ENERGY_PER_SWING) {
1f
} else {
0f
}
}
ItemProperties.register(MItems.EXPLOSIVE_HAMMER, ResourceLocation(OverdriveThatMatters.MOD_ID, "is_primed")) { stack, level, entity, _ -> ItemProperties.register(MItems.EXPLOSIVE_HAMMER, ResourceLocation(OverdriveThatMatters.MOD_ID, "is_primed")) { stack, level, entity, _ ->
if (MItems.EXPLOSIVE_HAMMER.isPrimed(stack) || entity == null) { if (MItems.EXPLOSIVE_HAMMER.isPrimed(stack) || entity == null) {
1f 1f
@ -307,6 +318,11 @@ object MRegistry : IBlockItemRegistryAcceptor {
} }
} }
} }
ItemProperties.register(MItems.CONFIGURATOR, ResourceLocation(OverdriveThatMatters.MOD_ID, "has_configuration_saved")) { stack, _, _, _ ->
val tag = stack.getOrDefault(MDataComponentTypes.Configurator.CONFIGURATION, CompoundTag())
if (tag.isEmpty) 0f else 1f
}
} }
} }

View File

@ -18,6 +18,7 @@ import net.minecraft.world.level.block.SoundType
import net.minecraft.world.level.block.StairBlock import net.minecraft.world.level.block.StairBlock
import net.minecraft.world.level.block.TransparentBlock import net.minecraft.world.level.block.TransparentBlock
import net.minecraft.world.level.block.WallBlock import net.minecraft.world.level.block.WallBlock
import net.minecraft.world.level.block.WaterloggedTransparentBlock
import net.minecraft.world.level.block.state.BlockBehaviour import net.minecraft.world.level.block.state.BlockBehaviour
import net.minecraft.world.level.block.state.properties.BlockStateProperties import net.minecraft.world.level.block.state.properties.BlockStateProperties
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument import net.minecraft.world.level.block.state.properties.NoteBlockInstrument
@ -266,7 +267,7 @@ object MBlocks {
} }
val METAL_MESH: Block by registry.register(MNames.METAL_MESH) { val METAL_MESH: Block by registry.register(MNames.METAL_MESH) {
TransparentBlock(BlockBehaviour.Properties.of() WaterloggedTransparentBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_GRAY) .mapColor(MapColor.COLOR_GRAY)
.noOcclusion() .noOcclusion()
.sound(SoundType.COPPER_GRATE) .sound(SoundType.COPPER_GRATE)

View File

@ -263,6 +263,7 @@ private fun addMainCreativeTabItems(consumer: CreativeModeTab.Output) {
accept(MItems.GRAVITATIONAL_DISRUPTOR) accept(MItems.GRAVITATIONAL_DISRUPTOR)
accept(MItems.CHEST_UPGRADER) accept(MItems.CHEST_UPGRADER)
accept(MItems.CONFIGURATOR)
accept(MItems.ESSENCE_SERVO) accept(MItems.ESSENCE_SERVO)

View File

@ -5,9 +5,11 @@ import com.mojang.serialization.Codec
import net.minecraft.core.UUIDUtil import net.minecraft.core.UUIDUtil
import net.minecraft.core.component.DataComponentType import net.minecraft.core.component.DataComponentType
import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.RegistryFriendlyByteBuf import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.network.codec.StreamCodec import net.minecraft.network.codec.StreamCodec
import net.minecraft.util.StringRepresentable import net.minecraft.util.StringRepresentable
import net.minecraft.world.level.block.state.BlockState
import net.neoforged.bus.api.IEventBus import net.neoforged.bus.api.IEventBus
import net.neoforged.neoforge.fluids.SimpleFluidContent import net.neoforged.neoforge.fluids.SimpleFluidContent
import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.capability.FlowDirection
@ -17,6 +19,7 @@ import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.data.codec.DecimalCodec import ru.dbotthepony.mc.otm.data.codec.DecimalCodec
import ru.dbotthepony.mc.otm.item.tool.RedstoneInteractorItem import ru.dbotthepony.mc.otm.item.tool.RedstoneInteractorItem
import ru.dbotthepony.mc.otm.network.StreamCodecs import ru.dbotthepony.mc.otm.network.StreamCodecs
import ru.dbotthepony.mc.otm.network.streamCodec
import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.MDeferredRegister
import java.util.UUID import java.util.UUID
@ -34,6 +37,16 @@ object MDataComponentTypes {
} }
} }
private class CompoundTagComponent : DataComponentType<CompoundTag> {
override fun codec(): Codec<CompoundTag> {
return CompoundTag.CODEC
}
override fun streamCodec(): StreamCodec<in RegistryFriendlyByteBuf, CompoundTag> {
return CompoundTag.CODEC.streamCodec()
}
}
val FLUID_STACK by registry.register("fluid_stack") { val FLUID_STACK by registry.register("fluid_stack") {
object : DataComponentType<SimpleFluidContent> { object : DataComponentType<SimpleFluidContent> {
override fun codec(): Codec<SimpleFluidContent> { override fun codec(): Codec<SimpleFluidContent> {
@ -81,6 +94,26 @@ object MDataComponentTypes {
} }
} }
object Configurator {
val BLOCK: DataComponentType<BlockState> by registry.register("configurator_block") {
object : DataComponentType<BlockState> {
override fun codec(): Codec<BlockState?>? {
return BlockState.CODEC
}
override fun streamCodec(): StreamCodec<in RegistryFriendlyByteBuf, BlockState?> {
return BlockState.CODEC.streamCodec()
}
}
}
val CONFIGURATION: DataComponentType<CompoundTag> by registry.register("configurator_configuration") { CompoundTagComponent() }
}
init {
Configurator
}
fun register(bus: IEventBus) { fun register(bus: IEventBus) {
registry.register(bus) registry.register(bus)
} }

View File

@ -43,6 +43,7 @@ import ru.dbotthepony.mc.otm.core.collect.SupplierMap
import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.item.BatteryItem import ru.dbotthepony.mc.otm.item.BatteryItem
import ru.dbotthepony.mc.otm.item.ChestUpgraderItem import ru.dbotthepony.mc.otm.item.ChestUpgraderItem
import ru.dbotthepony.mc.otm.item.ConfiguratorItem
import ru.dbotthepony.mc.otm.item.CrudeBatteryItem import ru.dbotthepony.mc.otm.item.CrudeBatteryItem
import ru.dbotthepony.mc.otm.item.EssenceServoItem import ru.dbotthepony.mc.otm.item.EssenceServoItem
import ru.dbotthepony.mc.otm.item.FluidCapsuleItem import ru.dbotthepony.mc.otm.item.FluidCapsuleItem
@ -72,6 +73,7 @@ import ru.dbotthepony.mc.otm.item.tool.ExplosiveHammerItem
import ru.dbotthepony.mc.otm.item.tool.MatteryAxeItem import ru.dbotthepony.mc.otm.item.tool.MatteryAxeItem
import ru.dbotthepony.mc.otm.item.tool.RedstoneInteractorItem import ru.dbotthepony.mc.otm.item.tool.RedstoneInteractorItem
import ru.dbotthepony.mc.otm.item.weapon.EnergySwordItem import ru.dbotthepony.mc.otm.item.weapon.EnergySwordItem
import ru.dbotthepony.mc.otm.item.weapon.FallingSunItem
import ru.dbotthepony.mc.otm.item.weapon.WitheredSteelSwordItem import ru.dbotthepony.mc.otm.item.weapon.WitheredSteelSwordItem
import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.MDeferredRegister
import ru.dbotthepony.mc.otm.registry.MItemTags import ru.dbotthepony.mc.otm.registry.MItemTags
@ -407,6 +409,7 @@ object MItems {
val EXPLOSIVE_HAMMER: ExplosiveHammerItem by registry.register("explosive_hammer") { ExplosiveHammerItem() } val EXPLOSIVE_HAMMER: ExplosiveHammerItem by registry.register("explosive_hammer") { ExplosiveHammerItem() }
val ENERGY_SWORD: Item by registry.register(MNames.ENERGY_SWORD) { EnergySwordItem() } val ENERGY_SWORD: Item by registry.register(MNames.ENERGY_SWORD) { EnergySwordItem() }
val FALLING_SUN: Item by registry.register(MNames.FALLING_SUN) { FallingSunItem() }
val WITHERED_STEEL_SWORD: Item by registry.register(MNames.WITHERED_STEEL_SWORD) { WitheredSteelSwordItem(Item.Properties().durability(420)) } val WITHERED_STEEL_SWORD: Item by registry.register(MNames.WITHERED_STEEL_SWORD) { WitheredSteelSwordItem(Item.Properties().durability(420)) }
@ -557,6 +560,7 @@ object MItems {
val ELECTROMOTOR: Item by registry.register(MNames.ELECTROMOTOR) { Item(DEFAULT_PROPERTIES) } val ELECTROMOTOR: Item by registry.register(MNames.ELECTROMOTOR) { Item(DEFAULT_PROPERTIES) }
val MIRROR_COMPOUND: Item by registry.register(MNames.MIRROR_COMPOUND) { Item(DEFAULT_PROPERTIES) } val MIRROR_COMPOUND: Item by registry.register(MNames.MIRROR_COMPOUND) { Item(DEFAULT_PROPERTIES) }
val MIRROR: Item by registry.register(MNames.MIRROR) { MatteryItem(DEFAULT_PROPERTIES).addSimpleDescription() } val MIRROR: Item by registry.register(MNames.MIRROR) { MatteryItem(DEFAULT_PROPERTIES).addSimpleDescription() }
val DISPLAY_SCREEN: Item by registry.register(MNames.DISPLAY_SCREEN) { Item(DEFAULT_PROPERTIES) }
/** /**
* List of components for everything else * List of components for everything else
@ -586,6 +590,7 @@ object MItems {
MItems::ELECTROMOTOR, MItems::ELECTROMOTOR,
MItems::MIRROR_COMPOUND, MItems::MIRROR_COMPOUND,
MItems::MIRROR, MItems::MIRROR,
MItems::DISPLAY_SCREEN,
MItems::CARBON_MESH, MItems::CARBON_MESH,
MItems::ARMOR_ASSEMBLY, MItems::ARMOR_ASSEMBLY,
@ -621,6 +626,7 @@ object MItems {
MItems::ELECTROMOTOR, MItems::ELECTROMOTOR,
MItems::MIRROR_COMPOUND, MItems::MIRROR_COMPOUND,
MItems::MIRROR, MItems::MIRROR,
MItems::DISPLAY_SCREEN,
MItems::CARBON_MESH, MItems::CARBON_MESH,
MItems::ARMOR_ASSEMBLY, MItems::ARMOR_ASSEMBLY,
@ -672,6 +678,8 @@ object MItems {
val ROFLITE_ALLOY_INGOT: Item by registry.register(MNames.ROFLITE_ALLOY_INGOT) { Item(DEFAULT_PROPERTIES) } val ROFLITE_ALLOY_INGOT: Item by registry.register(MNames.ROFLITE_ALLOY_INGOT) { Item(DEFAULT_PROPERTIES) }
val ROFLITE_ALLOY_BLOCK: BlockItem by registry.register(MNames.ROFLITE_ALLOY_BLOCK) { BlockItem(MBlocks.ROFLITE_ALLOY_BLOCK, DEFAULT_PROPERTIES) } val ROFLITE_ALLOY_BLOCK: BlockItem by registry.register(MNames.ROFLITE_ALLOY_BLOCK) { BlockItem(MBlocks.ROFLITE_ALLOY_BLOCK, DEFAULT_PROPERTIES) }
val CONFIGURATOR: Item by registry.register(MNames.CONFIGURATOR) { ConfiguratorItem() }
init { init {
MRegistry.registerItems(registry) MRegistry.registerItems(registry)
} }

View File

@ -0,0 +1,9 @@
package ru.dbotthepony.mc.otm.server
import net.minecraft.network.chat.Component
import net.minecraft.network.protocol.game.ClientboundSetActionBarTextPacket
import net.minecraft.server.level.ServerPlayer
fun ServerPlayer.sendActionBarMessage(component: Component) {
this.connection.send(ClientboundSetActionBarTextPacket(component))
}

View File

@ -0,0 +1,30 @@
{
"providers": [
{
"type": "space",
"advances": {
" ": 4
}
},
{
"type": "bitmap",
"file": "overdrive_that_matters:font/small.png",
"chars": [
"\u0020\u0021\u0022\u0023\u0024\u0025\u0026\u0027\u0028\u0029\u002a\u002b\u002c\u002d\u002e\u002f",
"\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u003a\u003b\u003c\u003d\u003e\u003f",
"\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004a\u004b\u004c\u004d\u004e\u004f",
"\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057\u0058\u0059\u005a\u005b\u005c\u005d\u005e\u005f",
"\u0060\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068\u0069\u006a\u006b\u006c\u006d\u006e\u006f",
"\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077\u0078\u0079\u007a\u007b\u007c\u007d\u007e\u221E",
"\u0410\u0411\u0412\u0413\u0414\u0415\u0401\u0416\u0417\u0418\u0419\u041A\u041B\u041C\u041D\u041E",
"\u041F\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042D\u042E",
"\u042F\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
"\u0430\u0431\u0432\u0433\u0434\u0435\u0451\u0436\u0437\u0438\u0439\u043A\u043B\u043C\u043D\u043E",
"\u043F\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C\u044D\u044E",
"\u044F\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
],
"height": 6,
"ascent": 6
}
]
}

View File

@ -0,0 +1,22 @@
{
"loader": "neoforge:separate_transforms",
"gui_light": "front",
"base":
{
"parent": "overdrive_that_matters:item/falling_sun_unpowered"
},
"perspectives": {
"gui": {
"parent": "overdrive_that_matters:item/falling_sun_inventory"
},
"fixed": {
"parent": "overdrive_that_matters:item/falling_sun_inventory"
},
"ground": {
"parent": "overdrive_that_matters:item/falling_sun_inventory"
}
},
"overrides": [
{ "predicate": { "overdrive_that_matters:is_powered": 1.0 }, "model": "overdrive_that_matters:item/falling_sun_powered" }
]
}

View File

@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "overdrive_that_matters:item/falling_sun_icon"
}
}

View File

@ -0,0 +1,241 @@
{
"loader": "neoforge:separate_transforms",
"gui_light": "front",
"base":
{
"texture_size": [32, 32],
"textures": {
"0": "overdrive_that_matters:item/falling_sun",
"1": "overdrive_that_matters:item/falling_sun_charge",
"particle": "overdrive_that_matters:item/falling_sun"
},
"elements": [
{
"name": "frame",
"from": [7.999, 8, 9.6],
"to": [8.002, 22, 11.6],
"rotation": {"angle": 0, "axis": "y", "origin": [6, 11, 10.6]},
"faces": {
"east": {"uv": [11.5, 0, 10.5, 7], "texture": "#0"},
"west": {"uv": [10.5, 0, 11.5, 7], "texture": "#0"}
}
},
{
"name": "frame",
"from": [8, 22, 9.6],
"to": [8, 29, 11.6],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 22, 9.6]},
"faces": {
"east": {"uv": [12.5, 0, 11.5, 3.5], "texture": "#0"},
"west": {"uv": [11.5, 0, 12.5, 3.5], "texture": "#0"}
}
},
{
"name": "cap",
"from": [7.4, 6, 7.6],
"to": [8.6, 11, 9.6],
"rotation": {"angle": 0, "axis": "y", "origin": [6.5, 7, 7.6]},
"faces": {
"north": {"uv": [7.5, 4, 8, 6.5], "texture": "#0"},
"east": {"uv": [9, 4, 8, 6.5], "texture": "#0"},
"south": {"uv": [9, 4, 9.5, 6.5], "texture": "#0"},
"west": {"uv": [8, 4, 9, 6.5], "texture": "#0"},
"up": {"uv": [8, 3.5, 9, 4], "rotation": 90, "texture": "#0"}
}
},
{
"name": "handle",
"from": [7, -5, 4],
"to": [9, -4, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [7, -5, 7]},
"faces": {
"north": {"uv": [8, 10, 9, 10.5], "texture": "#0"},
"east": {"uv": [7.5, 7, 8, 10], "rotation": 270, "texture": "#0"},
"south": {"uv": [8, 6.5, 9, 7], "texture": "#0"},
"west": {"uv": [7.5, 7, 8, 10], "rotation": 90, "texture": "#0"},
"up": {"uv": [8, 7, 9, 10], "rotation": 180, "texture": "#0"},
"down": {"uv": [9, 7, 10, 10], "texture": "#0"}
}
},
{
"name": "handle",
"from": [8, -4, 4.6],
"to": [8, 3, 7.6],
"rotation": {"angle": 0, "axis": "y", "origin": [6, -3, 5.6]},
"faces": {
"east": {"uv": [9, 0, 10.5, 3.5], "texture": "#0"},
"west": {"uv": [10.5, 0, 9, 3.5], "texture": "#0"}
}
},
{
"name": "handle",
"from": [7.5, -4, 7.2],
"to": [8.5, 3, 9.2],
"rotation": {"angle": 0, "axis": "y", "origin": [6.5, -3, 7.2]},
"faces": {
"north": {"uv": [7, 0, 7.5, 3.5], "texture": "#0"},
"east": {"uv": [8.5, 0, 7.5, 3.5], "texture": "#0"},
"south": {"uv": [8.5, 0, 9, 3.5], "texture": "#0"},
"west": {"uv": [7.5, 0, 8.5, 3.5], "texture": "#0"}
}
},
{
"name": "guard",
"from": [6.5, 5, 4],
"to": [9.5, 6, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [7.5, 5, 7]},
"faces": {
"north": {"uv": [4, 8, 5.5, 8.5], "texture": "#0"},
"east": {"uv": [3.5, 5, 4, 8], "rotation": 270, "texture": "#0"},
"south": {"uv": [4, 4.5, 5.5, 5], "rotation": 180, "texture": "#0"},
"west": {"uv": [5.5, 5, 6, 8], "rotation": 90, "texture": "#0"},
"up": {"uv": [4, 5, 5.5, 8], "rotation": 180, "texture": "#0"},
"down": {"uv": [6, 5, 7.5, 8], "texture": "#0"}
}
},
{
"name": "guard",
"from": [6.5, 3, 4],
"to": [9.5, 4, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [7.5, 3, 7]},
"faces": {
"north": {"uv": [4, 8, 5.5, 8.5], "texture": "#0"},
"east": {"uv": [3.5, 5, 4, 8], "rotation": 270, "texture": "#0"},
"south": {"uv": [4, 4.5, 5.5, 5], "rotation": 180, "texture": "#0"},
"west": {"uv": [5.5, 5, 6, 8], "rotation": 90, "texture": "#0"},
"up": {"uv": [4, 5, 5.5, 8], "rotation": 180, "texture": "#0"},
"down": {"uv": [6, 5, 7.5, 8], "texture": "#0"}
}
},
{
"name": "blade",
"from": [7.5, 4, 4.5],
"to": [8.5, 22, 9.5],
"rotation": {"angle": 0, "axis": "y", "origin": [7.5, 6, 5.5]},
"faces": {
"north": {"uv": [0, 0.5, 0.5, 9.5], "texture": "#0"},
"east": {"uv": [3, 0.5, 0.5, 9.5], "texture": "#0"},
"south": {"uv": [3, 0.5, 3.5, 9.5], "texture": "#0"},
"west": {"uv": [0.5, 0.5, 3, 9.5], "texture": "#0"},
"up": {"uv": [0.5, 0, 3, 0.5], "rotation": 90, "texture": "#0"}
}
},
{
"name": "blade",
"from": [7.501, 22.001, 4.501],
"to": [8.499, 29.999, 9.499],
"rotation": {"angle": 22.5, "axis": "x", "origin": [7.5, 22, 4.5]},
"faces": {
"north": {"uv": [3.5, 0.5, 4, 4.5], "texture": "#0"},
"east": {"uv": [6.5, 0.5, 4, 4.5], "texture": "#0"},
"south": {"uv": [6.5, 0.5, 7, 4.5], "texture": "#0"},
"west": {"uv": [4, 0.5, 6.5, 4.5], "texture": "#0"},
"up": {"uv": [4, 0, 6.5, 0.5], "rotation": 90, "texture": "#0"}
}
},
{
"from": [7.501, 26.801, 8.601],
"to": [8.499, 25.799, 9.699],
"rotation": {"angle": 22.5, "axis": "x", "origin": [7.5, 26.8, 8.6]},
"faces": {
"north": {"uv": [4.5, 1.5, 5, 2], "texture": "#0"},
"south": {"uv": [5.5, 1.5, 6, 2], "texture": "#0"},
"up": {"uv": [5, 2, 5.5, 2.5], "rotation": 90, "texture": "#0"},
"down": {"uv": [5, 1, 5.5, 1.5], "texture": "#0"}
}
},
{
"name": "charge",
"from": [7.6, 6, 3.8],
"to": [8.4, 22, 10.2],
"rotation": {"angle": 0, "axis": "y", "origin": [6.5, 12, 4]},
"faces": {
"north": {"uv": [4, 4, 4.5, 12], "texture": "#1"},
"east": {"uv": [1, 4, 4, 12], "texture": "#1"},
"south": {"uv": [7.5, 4, 8, 12], "texture": "#1"},
"west": {"uv": [4.5, 4, 7.5, 12], "texture": "#1"}
}
},
{
"name": "charge",
"from": [7.6, 21.9, 3.8],
"to": [8.4, 30.8, 10.2],
"rotation": {"angle": 22.5, "axis": "x", "origin": [6.5, 22, 4]},
"faces": {
"north": {"uv": [4, 2.5, 4.5, 5], "texture": "#1"},
"east": {"uv": [1, 2.5, 4, 5], "texture": "#1"},
"south": {"uv": [7.5, 2.5, 8, 5], "texture": "#1"},
"west": {"uv": [4.5, 2.5, 7.5, 5], "texture": "#1"},
"up": {"uv": [3.5, 0.5, 6, 1], "rotation": 90, "texture": "#1"}
}
},
{
"name": "battery",
"from": [7.5, 7, 9.6],
"to": [8.5, 8, 11.6],
"rotation": {"angle": -22.5, "axis": "x", "origin": [7.5, 7, 9.6]},
"faces": {
"east": {"uv": [12.5, 0.5, 13, 1.5], "rotation": 270, "texture": "#0"},
"south": {"uv": [12.5, 0, 13, 0.5], "texture": "#0"},
"west": {"uv": [12.5, 0.5, 13, 1.5], "rotation": 90, "texture": "#0"},
"up": {"uv": [12.5, 0.5, 13, 1.5], "rotation": 180, "texture": "#0"},
"down": {"uv": [12.5, 0.5, 13, 1.5], "texture": "#0"}
}
},
{
"name": "battery",
"from": [7.5, 9, 9.6],
"to": [8.5, 10, 11.6],
"rotation": {"angle": -22.5, "axis": "x", "origin": [7.5, 9, 9.6]},
"faces": {
"east": {"uv": [12.5, 0.5, 13, 1.5], "rotation": 270, "texture": "#0"},
"south": {"uv": [12.5, 0, 13, 0.5], "texture": "#0"},
"west": {"uv": [12.5, 0.5, 13, 1.5], "rotation": 90, "texture": "#0"},
"up": {"uv": [12.5, 0.5, 13, 1.5], "rotation": 180, "texture": "#0"},
"down": {"uv": [12.5, 0.5, 13, 1.5], "texture": "#0"}
}
}
],
"display": {
"thirdperson_righthand": {
"translation": [0, 5.75, 1.25]
},
"thirdperson_lefthand": {
"translation": [0, 5.75, 1.25]
},
"firstperson_righthand": {
"rotation": [-35, 0, 0],
"translation": [1.5, 1.5, -3.5]
},
"firstperson_lefthand": {
"rotation": [-35, 0, 0],
"translation": [1.5, 0, -3.5]
},
"ground": {
"rotation": [-60, 0, 0],
"translation": [0, 2, 0],
"scale": [0.5, 0.5, 0.5]
},
"gui": {
"rotation": [0, 90, 0],
"translation": [0, -1.5, 0],
"scale": [0.5, 0.5, 0.5]
},
"head": {
"rotation": [-127, 0, 0],
"translation": [0, 12.25, 0]
}
}
},
"perspectives": {
"gui": {
"parent": "overdrive_that_matters:item/falling_sun_inventory"
},
"fixed": {
"parent": "overdrive_that_matters:item/falling_sun_inventory"
},
"ground": {
"parent": "overdrive_that_matters:item/falling_sun_inventory"
}
}
}

View File

@ -0,0 +1,200 @@
{
"credit": "Made with Blockbench",
"texture_size": [32, 32],
"textures": {
"0": "overdrive_that_matters:item/falling_sun",
"particle": "overdrive_that_matters:item/falling_sun"
},
"elements": [
{
"name": "frame",
"from": [7.999, 8, 9.6],
"to": [8.002, 22, 11.6],
"rotation": {"angle": 0, "axis": "y", "origin": [6, 11, 10.6]},
"faces": {
"east": {"uv": [11.5, 0, 10.5, 7], "texture": "#0"},
"west": {"uv": [10.5, 0, 11.5, 7], "texture": "#0"}
}
},
{
"name": "frame",
"from": [8, 22, 9.6],
"to": [8, 29, 11.6],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 22, 9.6]},
"faces": {
"east": {"uv": [12.5, 0, 11.5, 3.5], "texture": "#0"},
"west": {"uv": [11.5, 0, 12.5, 3.5], "texture": "#0"}
}
},
{
"name": "cap",
"from": [7.4, 6, 7.6],
"to": [8.6, 11, 9.6],
"rotation": {"angle": 0, "axis": "y", "origin": [6.5, 7, 7.6]},
"faces": {
"north": {"uv": [7.5, 4, 8, 6.5], "texture": "#0"},
"east": {"uv": [9, 4, 8, 6.5], "texture": "#0"},
"south": {"uv": [9, 4, 9.5, 6.5], "texture": "#0"},
"west": {"uv": [8, 4, 9, 6.5], "texture": "#0"},
"up": {"uv": [8, 3.5, 9, 4], "rotation": 90, "texture": "#0"}
}
},
{
"name": "handle",
"from": [7, -5, 4],
"to": [9, -4, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [7, -5, 7]},
"faces": {
"north": {"uv": [8, 10, 9, 10.5], "texture": "#0"},
"east": {"uv": [7.5, 7, 8, 10], "rotation": 270, "texture": "#0"},
"south": {"uv": [8, 6.5, 9, 7], "texture": "#0"},
"west": {"uv": [7.5, 7, 8, 10], "rotation": 90, "texture": "#0"},
"up": {"uv": [8, 7, 9, 10], "rotation": 180, "texture": "#0"},
"down": {"uv": [9, 7, 10, 10], "texture": "#0"}
}
},
{
"name": "handle",
"from": [8, -4, 4.6],
"to": [8, 3, 7.6],
"rotation": {"angle": 0, "axis": "y", "origin": [6, -3, 5.6]},
"faces": {
"east": {"uv": [9, 0, 10.5, 3.5], "texture": "#0"},
"west": {"uv": [10.5, 0, 9, 3.5], "texture": "#0"}
}
},
{
"name": "handle",
"from": [7.5, -4, 7.2],
"to": [8.5, 3, 9.2],
"rotation": {"angle": 0, "axis": "y", "origin": [6.5, -3, 7.2]},
"faces": {
"north": {"uv": [7, 0, 7.5, 3.5], "texture": "#0"},
"east": {"uv": [8.5, 0, 7.5, 3.5], "texture": "#0"},
"south": {"uv": [8.5, 0, 9, 3.5], "texture": "#0"},
"west": {"uv": [7.5, 0, 8.5, 3.5], "texture": "#0"}
}
},
{
"name": "guard",
"from": [6.5, 5, 4],
"to": [9.5, 6, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [7.5, 5, 7]},
"faces": {
"north": {"uv": [4, 8, 5.5, 8.5], "texture": "#0"},
"east": {"uv": [3.5, 5, 4, 8], "rotation": 270, "texture": "#0"},
"south": {"uv": [4, 4.5, 5.5, 5], "rotation": 180, "texture": "#0"},
"west": {"uv": [5.5, 5, 6, 8], "rotation": 90, "texture": "#0"},
"up": {"uv": [4, 5, 5.5, 8], "rotation": 180, "texture": "#0"},
"down": {"uv": [6, 5, 7.5, 8], "texture": "#0"}
}
},
{
"name": "guard",
"from": [6.5, 3, 4],
"to": [9.5, 4, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [7.5, 3, 7]},
"faces": {
"north": {"uv": [4, 8, 5.5, 8.5], "texture": "#0"},
"east": {"uv": [3.5, 5, 4, 8], "rotation": 270, "texture": "#0"},
"south": {"uv": [4, 4.5, 5.5, 5], "rotation": 180, "texture": "#0"},
"west": {"uv": [5.5, 5, 6, 8], "rotation": 90, "texture": "#0"},
"up": {"uv": [4, 5, 5.5, 8], "rotation": 180, "texture": "#0"},
"down": {"uv": [6, 5, 7.5, 8], "texture": "#0"}
}
},
{
"name": "blade",
"from": [7.5, 4, 4.5],
"to": [8.5, 22, 9.5],
"rotation": {"angle": 0, "axis": "y", "origin": [7.5, 6, 5.5]},
"faces": {
"north": {"uv": [0, 0.5, 0.5, 9.5], "texture": "#0"},
"east": {"uv": [3, 0.5, 0.5, 9.5], "texture": "#0"},
"south": {"uv": [3, 0.5, 3.5, 9.5], "texture": "#0"},
"west": {"uv": [0.5, 0.5, 3, 9.5], "texture": "#0"},
"up": {"uv": [0.5, 0, 3, 0.5], "rotation": 90, "texture": "#0"}
}
},
{
"name": "blade",
"from": [7.501, 22.001, 4.501],
"to": [8.499, 29.999, 9.499],
"rotation": {"angle": 22.5, "axis": "x", "origin": [7.5, 22, 4.5]},
"faces": {
"north": {"uv": [3.5, 0.5, 4, 4.5], "texture": "#0"},
"east": {"uv": [6.5, 0.5, 4, 4.5], "texture": "#0"},
"south": {"uv": [6.5, 0.5, 7, 4.5], "texture": "#0"},
"west": {"uv": [4, 0.5, 6.5, 4.5], "texture": "#0"},
"up": {"uv": [4, 0, 6.5, 0.5], "rotation": 90, "texture": "#0"}
}
},
{
"from": [7.501, 26.801, 8.601],
"to": [8.499, 25.799, 9.699],
"rotation": {"angle": 22.5, "axis": "x", "origin": [7.5, 26.8, 8.6]},
"faces": {
"north": {"uv": [4.5, 1.5, 5, 2], "texture": "#0"},
"south": {"uv": [5.5, 1.5, 6, 2], "texture": "#0"},
"up": {"uv": [5, 2, 5.5, 2.5], "rotation": 90, "texture": "#0"},
"down": {"uv": [5, 1, 5.5, 1.5], "texture": "#0"}
}
},
{
"name": "battery",
"from": [7.5, 6.5, 8.6],
"to": [8.5, 7.5, 10.6],
"rotation": {"angle": -22.5, "axis": "x", "origin": [7.5, 6.5, 8.6]},
"faces": {
"east": {"uv": [12.5, 0.5, 13, 1.5], "rotation": 270, "texture": "#0"},
"south": {"uv": [12.5, 0, 13, 0.5], "texture": "#0"},
"west": {"uv": [12.5, 0.5, 13, 1.5], "rotation": 90, "texture": "#0"},
"up": {"uv": [12.5, 0.5, 13, 1.5], "rotation": 180, "texture": "#0"},
"down": {"uv": [12.5, 0.5, 13, 1.5], "texture": "#0"}
}
},
{
"name": "battery",
"from": [7.5, 8.5, 8.6],
"to": [8.5, 9.5, 10.6],
"rotation": {"angle": -22.5, "axis": "x", "origin": [7.5, 8.5, 8.6]},
"faces": {
"east": {"uv": [12.5, 0.5, 13, 1.5], "rotation": 270, "texture": "#0"},
"south": {"uv": [12.5, 0, 13, 0.5], "texture": "#0"},
"west": {"uv": [12.5, 0.5, 13, 1.5], "rotation": 90, "texture": "#0"},
"up": {"uv": [12.5, 0.5, 13, 1.5], "rotation": 180, "texture": "#0"},
"down": {"uv": [12.5, 0.5, 13, 1.5], "texture": "#0"}
}
}
],
"display": {
"thirdperson_righthand": {
"translation": [0, 5.75, 1.25]
},
"thirdperson_lefthand": {
"translation": [0, 5.75, 1.25]
},
"firstperson_righthand": {
"rotation": [-35, 0, 0],
"translation": [1.5, 1.5, -3.5]
},
"firstperson_lefthand": {
"rotation": [-35, 0, 0],
"translation": [1.5, 0, -3.5]
},
"ground": {
"rotation": [-60, 0, 0],
"translation": [0, 2, 0],
"scale": [0.5, 0.5, 0.5]
},
"gui": {
"rotation": [0, 90, 0],
"translation": [0, -1.5, 0],
"scale": [0.5, 0.5, 0.5]
},
"head": {
"rotation": [-127, 0, 0],
"translation": [0, 12.25, 0]
}
}
}

View File

@ -1,5 +1,4 @@
{ {
"credit": "Made with Blockbench",
"parent": "minecraft:item/handheld", "parent": "minecraft:item/handheld",
"textures": { "textures": {
"layer0": "overdrive_that_matters:item/withered_steel_sword_handheld" "layer0": "overdrive_that_matters:item/withered_steel_sword_handheld"
@ -7,18 +6,18 @@
"display": { "display": {
"thirdperson_righthand": { "thirdperson_righthand": {
"rotation": [0, -90, 55], "rotation": [0, -90, 55],
"translation": [0, 4, 0.5], "translation": [0, 5.75, 0.5],
"scale": [0.85, 0.85, 0.85] "scale": [1, 1, 0.85]
}, },
"thirdperson_lefthand": { "thirdperson_lefthand": {
"rotation": [0, 90, -55], "rotation": [0, 90, -55],
"translation": [0, 4, 0.5], "translation": [0, 5.75, 0.5],
"scale": [0.85, 0.85, 0.85] "scale": [1, 1, 0.85]
}, },
"firstperson_righthand": { "firstperson_righthand": {
"rotation": [0, -90, 25], "rotation": [0, -90, 25],
"translation": [1.13, 3.2, 1.13], "translation": [1.13, 3.2, 1.13],
"scale": [0.68, 0.68, 0.68] "scale": [0.74, 0.74, 0.68]
}, },
"firstperson_lefthand": { "firstperson_lefthand": {
"rotation": [0, 90, -25], "rotation": [0, 90, -25],

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1 @@
{ "animation": { "frametime": 1 } }

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

View File

@ -0,0 +1,40 @@
{
"attributes": {
"range_bonus": 0.25,
"two_handed": true,
"pose": "bettercombat:pose_two_handed_katana",
"category": "claymore",
"attacks": [
{
"hitbox": "HORIZONTAL_PLANE",
"damage_multiplier": 0.75,
"angle": 120,
"upswing": 0.5,
"animation": "bettercombat:two_handed_slash_horizontal_right",
"swing_sound": {
"id": "bettercombat:scythe_slash"
}
},
{
"hitbox": "HORIZONTAL_PLANE",
"damage_multiplier": 0.75,
"angle": 120,
"upswing": 0.5,
"animation": "bettercombat:two_handed_slash_horizontal_left",
"swing_sound": {
"id": "bettercombat:scythe_slash"
}
},
{
"hitbox": "VERTICAL_PLANE",
"damage_multiplier": 1,
"angle": 120,
"upswing": 0.8,
"animation": "bettercombat:two_handed_slash_vertical_right",
"swing_sound": {
"id": "bettercombat:scythe_slash"
}
}
]
}
}