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:botarium-704113:${botarium_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}")
implementation("io.wispforest:condensed_creative-neoforge:${condensed_creative_version}")

View File

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

View File

@ -114,6 +114,17 @@ fun addItemModels(provider: MatteryItemModelProvider) {
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.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.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("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.ARMOR_ASSEMBLY, "Armor assembly")
add(MItems.CARBON_MESH, "Carbon Mesh")
add(MItems.DISPLAY_SCREEN, "Display Screen")
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, "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_DENSE_CONDENSATION_DRIVE, "Portable Dense Condensation Drive")
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, "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(MEntityTypes.BREAD_MONSTER, "Bread Monster")
@ -975,6 +992,11 @@ private fun gui(provider: MatteryLanguageProvider) {
gui("flow_direction_set", "Flow direction set to %s")
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.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.")

View File

@ -202,6 +202,10 @@ private fun misc(provider: MatteryLanguageProvider) {
gui("holo_screen.resize_text", "Изменять размер текста автоматически")
gui("holo_screen.do_not_resize_text", "Не менять размер текста")
gui("abc", "АБВ")
gui("use_standard_font", "Использовать стандартный шрифт")
gui("use_small_font", "Использовать уменьшенный шрифт")
gui("ticks", "Тиков")
gui("power_cost_per_use", "Энергии на операцию: %s")
@ -819,6 +823,7 @@ private fun items(provider: MatteryLanguageProvider) {
add(MItems.REINFORCED_IRON_PLATE, "desc", "Более надёжная и прочная железная пластина")
add(MItems.ARMOR_ASSEMBLY, "Стройка брони")
add(MItems.CARBON_MESH, "Углеродная сетка")
add(MItems.DISPLAY_SCREEN, "Экран дисплея")
add(MItems.GRAVITATIONAL_DISRUPTOR, "Маяк уравнения пространства-времени")
@ -852,6 +857,12 @@ private fun items(provider: MatteryLanguageProvider) {
add(MItems.ENERGY_SWORD, "desc3", "Всегда наносит полный урон по площади если имеет заряд")
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_DENSE_CONDENSATION_DRIVE, "Portable Dense Condensation Drive")
add(MItems.TRITANIUM_ORE_CLUMP, "Рудный тритан")
@ -911,6 +922,12 @@ private fun items(provider: MatteryLanguageProvider) {
add(MItems.CHEST_UPGRADER, "desc", "Заменяет установленные сундуки и бочки грузовыми ящиками с сохранением содержимого")
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(MEntityTypes.BREAD_MONSTER, "Хлебный монстр")
@ -968,6 +985,11 @@ private fun gui(provider: MatteryLanguageProvider) {
gui("flow_direction_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.help1", "Чем сильнее гравитационное поле сингулярности, тем больше генерация!")
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
import net.minecraft.util.valueproviders.UniformInt
import net.minecraft.world.item.Items
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.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
fun addChestLootTables(loot: LootTables) {
@ -28,24 +34,93 @@ fun addChestLootTables(loot: LootTables) {
item(Items.COPPER_INGOT) { setCount(minimal = 1, maximal = 3) }
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")) {
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.EMERALD) { 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.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.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.level.block.Block
import net.minecraft.world.level.block.WaterloggedTransparentBlock
import net.neoforged.neoforge.client.model.generators.BlockModelProvider
import net.neoforged.neoforge.data.event.GatherDataEvent
import ru.dbotthepony.mc.otm.datagen.DataGen
@ -81,7 +82,6 @@ class MatteryBlockModelProvider(event: GatherDataEvent) : BlockModelProvider(eve
}
}
}
fun decorativeCubeAll(subdir: String, vararg blocks: Block) {
for (block in blocks) {
exec {

View File

@ -100,4 +100,10 @@ fun addComponentRecipes(consumer: RecipeOutput) {
.row(MItemTags.COPPER_WIRES, MItems.MECHANICAL_PARTS, MItemTags.COPPER_WIRES)
.unlockedBy(MItems.ELECTROMAGNET)
.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"))
MatteryRecipe(MBlocks.DRIVE_VIEWER[null]!!, category = machinesCategory)
.rowAC(MItemTags.IRON_PLATES, MItemTags.IRON_PLATES)
.row(Tags.Items.DUSTS_GLOWSTONE, MItems.MACHINE_FRAME, Tags.Items.GLASS_BLOCKS)
.rowBC(MItems.DISPLAY_SCREEN, Tags.Items.GLASS_PANES)
.row(MItemTags.IRON_PLATES, MItems.MACHINE_FRAME, MItemTags.IRON_PLATES)
.row(MItemTags.BASIC_CIRCUIT, MItems.MATTER_IO_PORT, MItemTags.BASIC_CIRCUIT)
.unlockedBy(MItems.MATTER_IO_PORT)
.build(consumer)
@ -75,9 +75,9 @@ fun addCraftingTableRecipes(consumer: RecipeOutput) {
.build(consumer)
MatteryRecipe(MBlocks.MATTER_PANEL[null]!!, category = machinesCategory)
.row(MItems.ELECTRIC_PARTS, MItemTags.TRITANIUM_PLATES, Tags.Items.GLASS_BLOCKS)
.row(MItems.MATTER_CABLE, Tags.Items.DUSTS_GLOWSTONE, Tags.Items.GLASS_BLOCKS)
.row(MItemTags.ADVANCED_CIRCUIT, MItemTags.TRITANIUM_PLATES, Tags.Items.GLASS_BLOCKS)
.row(MItems.ELECTRIC_PARTS, MItemTags.TRITANIUM_PLATES, Tags.Items.GLASS_PANES)
.row(MItems.MATTER_CABLE, MItems.DISPLAY_SCREEN, Tags.Items.GLASS_PANES)
.row(MItemTags.ADVANCED_CIRCUIT, MItemTags.TRITANIUM_PLATES, Tags.Items.GLASS_PANES)
.unlockedBy(Tags.Items.GLASS_BLOCKS)
.build(consumer)
@ -99,7 +99,7 @@ fun addCraftingTableRecipes(consumer: RecipeOutput) {
MatteryRecipe(MBlocks.ENERGY_COUNTER[null]!!, category = machinesCategory)
.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)
.unlockedBy(MItems.ENERGY_BUS)
.build(consumer)
@ -223,7 +223,7 @@ fun addCraftingTableRecipes(consumer: RecipeOutput) {
.build(consumer)
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)
.rowAC(Tags.Items.DUSTS_GLOWSTONE, MItemTags.TRITANIUM_PLATES)
.unlockedBy(MItems.GRAVITATION_FIELD_SENSOR)
@ -585,4 +585,12 @@ fun addCraftingTableRecipes(consumer: RecipeOutput) {
.unlockedBy(MItems.DILITHIUM_CRYSTAL)
.unlockedBy(MItems.DILITHIUM_CRYSTAL_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) {
val builder = MatteryRecipe(item, category = RecipeCategory.DECORATIONS)
builder.row(MItemTags.BASIC_CIRCUIT, MItemTags.TRITANIUM_PLATES, MItemTags.HARDENED_GLASS_PANES_COLORLESS)
if (color != null) {
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)
}

View File

@ -5,11 +5,11 @@ import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin;
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)
public abstract class LevelMixin implements IMatteryLevel {
public final RandomSource otm_random = new CMWCRandom();
public final RandomSource otm_random = new Xoshiro256SSRandom();
@Override
public @NotNull RandomSource getOtmRandom() {

View File

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

View File

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

View File

@ -73,7 +73,7 @@ abstract class MatteryWorkerBlockEntity<JobType : IJob>(
var balanceInputs = false
init {
savetables.bool(::balanceInputs)
savetablesConfig.bool(::balanceInputs)
}
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(Capabilities.EnergyStorage.BLOCK, energy)
savetables.enum(::mode, map = Mode::valueOf)
savetables.decimal(::injectionRate)
savetables.decimal(::targetMass)
savetablesConfig.enum(::mode, map = Mode::valueOf)
savetablesConfig.decimal(::injectionRate)
savetablesConfig.decimal(::targetMass)
}
private fun findBlackHoleRange(): Int {

View File

@ -5,8 +5,7 @@ import net.minecraft.core.BlockPos
import net.minecraft.core.HolderLookup
import net.minecraft.core.registries.Registries
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.LongTag
import net.minecraft.nbt.StringTag
import net.minecraft.nbt.Tag
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceKey
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.SlottedContainer
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.menu.decorative.CargoCrateMenu
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
@ -101,14 +98,20 @@ class CargoCrateBlockEntity(
override fun saveLevel(nbt: CompoundTag, registry: HolderLookup.Provider) {
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) {
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) {

View File

@ -61,19 +61,25 @@ class HoloSignBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryB
access.accept(value)
}).delegate
var smallerFont by syncher.boolean(false, setter = { access, value ->
setChanged()
access.accept(value)
}).delegate
var isLocked = false
init {
savetables.string(::signText)
savetablesConfig.string(::signText)
savetablesLevel.bool(::isLocked)
savetables.stateful(::redstoneControl)
savetablesConfig.stateful(::redstoneControl)
savetables.float(::textRed)
savetables.float(::textGreen)
savetables.float(::textBlue)
savetables.float(::textAlpha)
savetablesConfig.float(::textRed)
savetablesConfig.float(::textGreen)
savetablesConfig.float(::textBlue)
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 {

View File

@ -116,7 +116,7 @@ class PainterBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDe
init {
addDroppableContainer(dyeInput)
savetables.stateful(dyeInput, INVENTORY_KEY)
savetables.bool(::isBulk)
savetablesConfig.bool(::isBulk)
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_NODE, matterNode)
savetables.bool(::isBottling)
savetables.bool(::spitItemsWhenCantWork)
savetablesConfig.bool(::isBottling)
savetablesConfig.bool(::spitItemsWhenCantWork)
savetables.stateful(::energy, ENERGY_KEY)
savetables.stateful(::matter, MATTER_STORAGE_KEY)
savetables.stateful(::bottling)

View File

@ -84,7 +84,7 @@ class MatterPanelBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte
exposeGlobally(MatteryCapability.MATTER_NODE, matterNode)
exposeGlobally(MatteryCapability.REPLICATION_TASK, this)
savetables.bool(::isProvidingTasks)
savetablesConfig.bool(::isProvidingTasks)
}
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(::container, INVENTORY_KEY)
exposeGlobally(MatteryCapability.STORAGE_NODE, cell)
savetables.int(::insertPriority)
savetables.int(::extractPriority)
savetables.enum(::mode, map = FlowDirection::valueOf)
savetablesConfig.int(::insertPriority)
savetablesConfig.int(::extractPriority)
savetablesConfig.enum(::mode, map = FlowDirection::valueOf)
redstoneControl.addListener(Consumer {
cell.isDetached = it

View File

@ -131,7 +131,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
}
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) {

View File

@ -112,7 +112,7 @@ abstract class AbstractStorageImportExport(
}
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 {

View File

@ -78,7 +78,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
}
init {
savetables.int(::displayChartOnBlock)
savetablesConfig.int(::displayChartOnBlock)
savetables.stateful(::history5s)
savetables.stateful(::history15s)
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.player.LocalPlayer
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.Style
import net.minecraft.world.effect.MobEffects
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
@ -112,6 +113,10 @@ object MatteryGUI {
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 {
override fun render(
graphics: GuiGraphics,
@ -163,9 +168,8 @@ object MatteryGUI {
}
val formattedPower = mattery.androidEnergy.batteryLevel.formatPower()
val scale = ClientConfig.HUD.BAR_TEXT_SCALE.toFloat()
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)
val scale = if (ClientConfig.HUD.USE_SMALL_FONT) 1f else 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)
RenderSystem.disableBlend()
RenderSystem.enableDepthTest()
@ -230,8 +234,8 @@ object MatteryGUI {
if (ply.absorptionAmount > 0)
formattedHealth = TextComponent("%d+%d/%d".format(ply.health.toInt(), ply.absorptionAmount.toInt(), ply.maxHealth.toInt()))
val scale = 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)
val scale = if (ClientConfig.HUD.USE_SMALL_FONT) 1f else ClientConfig.HUD.BAR_TEXT_SCALE.toFloat()
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.enableDepthTest()

View File

@ -4,6 +4,7 @@ import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
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.client.font
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.math.BlockRotationFreedom
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
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.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
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.kommons.math.RGBAColor
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.screen.panels.button.BooleanButtonPanel
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")
))
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
}
}

View File

@ -69,6 +69,10 @@ object ClientConfig : AbstractConfig("client", ModConfig.Type.CLIENT) {
var BAR_TEXT_SCALE: Double by builder
.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 {
builder.pop()
}

View File

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

View File

@ -4,34 +4,35 @@ 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
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 var carry = 0
private var stateIndex = 0
private val gaussian = MarsagliaPolarGaussian(this)
var seed: Long = seed
private set
init {
setSeed(seed)
}
override fun setSeed(seed: Long) {
this.seed = seed
carry = Integer.remainderUnsigned(seed.toInt(), CMWC_CARRY_MAX)
val rng = LCG64Random(seed)
// init state with regular LCG produced values
state[0] = seed.toInt()
state[1] = seed.shr(32).toInt()
for (i in 2 until state.size) {
state[i] = 69069 * state[i - 2] + 362437
for (i in 1 until state.size) {
state[i] = rng.nextInt()
}
do {
carry = rng.nextInt()
} while(carry !in 0 until CMWC_CARRY_MAX)
stateIndex = state.size - 1
gaussian.reset()
}
@ -109,7 +110,7 @@ class CMWCRandom(seed: Long = System.nanoTime()) : RandomGenerator, RandomSource
}
companion object {
const val CMWC_STATE_SIZE = 256 // 4096
const val CMWC_STATE_SIZE = 32 // 4096
const val CMWC_CARRY_MAX = 809430660
}
}

View File

@ -25,7 +25,7 @@ import kotlin.math.absoluteValue
import kotlin.math.max
import kotlin.math.roundToInt
private fun concat(numbers: String, suffix: Any): Component {
private fun concat(numbers: String, suffix: Any): MutableComponent {
if (suffix == "")
return TextComponent(numbers)
else if (suffix is Component)
@ -177,7 +177,7 @@ private fun resplice(number: String, decimals: Int): String {
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" }
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)
}
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)
}
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" }
if (formatAsReadable.asBoolean && this.absoluteValue >= 1.0) return concat(reformat("%.${decimalPlaces}f".format(this)), suffix)
val prefix = SiPrefix.determine(this)
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" }
if (this == Decimal.POSITIVE_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.EntityDataSerializers
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.SoundEvents
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.player.Player
import net.minecraft.world.level.Level
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.registry.game.MSoundEvents
@ -100,6 +105,11 @@ class Loader(type: EntityType<Loader>, level: Level) : Monster(type, level) {
return success
}
override fun getDefaultLootTable(): ResourceKey<LootTable> {
return ResourceKey.create(Registries.LOOT_TABLE,
ResourceLocation(OverdriveThatMatters.MOD_ID, "entities/loader"))
}
override fun 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 textAlpha = FloatInputWithFeedback(this)
val textAutoScale = BooleanInputWithFeedback(this)
val smallerFont = BooleanInputWithFeedback(this)
init {
text.filter { it.isCreative || !locked.value }
@ -36,6 +37,7 @@ class HoloSignMenu(
textAlpha.filter { it.isCreative || !locked.value }
textAutoScale.filter { it.isCreative || !locked.value }
smallerFont.filter { it.isCreative || !locked.value }
if (tile != null) {
text.withConsumer { tile.signText = HoloSignBlockEntity.truncate(it, tile.isLocked) }.withSupplier(tile::signText)
@ -46,6 +48,7 @@ class HoloSignMenu(
locked.with(tile::isLocked)
redstone.with(tile.redstoneControl::redstoneSetting)
textAutoScale.with(tile::textAutoScale)
smallerFont.with(tile::smallerFont)
}
}
}

View File

@ -194,10 +194,12 @@ object MNames {
const val TRITANIUM_SHIELD = "tritanium_shield"
const val ENERGY_SWORD = "energy_sword"
const val FALLING_SUN = "falling_sun"
const val PLASMA_RIFLE = "plasma_rifle"
const val CHEST_UPGRADER = "chest_upgrader"
const val CONFIGURATOR = "configurator"
const val WITHERED_STEEL_SWORD = "withered_steel_sword"
@ -230,6 +232,7 @@ object MNames {
const val MIRROR_COMPOUND = "mirror_compound"
const val MIRROR = "mirror"
const val BLANK_MACHINE_UPGRADE = "blank_machine_upgrade"
const val DISPLAY_SCREEN = "display_screen"
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.component.DataComponents
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.nbt.CompoundTag
import net.minecraft.world.entity.EntityType
import net.minecraft.world.item.DyeColor
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.item.armor.TritaniumArmorItem
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.MStats
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, _ ->
if (MItems.EXPLOSIVE_HAMMER.isPrimed(stack) || entity == null) {
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.TransparentBlock
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.properties.BlockStateProperties
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) {
TransparentBlock(BlockBehaviour.Properties.of()
WaterloggedTransparentBlock(BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_GRAY)
.noOcclusion()
.sound(SoundType.COPPER_GRATE)

View File

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

View File

@ -5,9 +5,11 @@ import com.mojang.serialization.Codec
import net.minecraft.core.UUIDUtil
import net.minecraft.core.component.DataComponentType
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.RegistryFriendlyByteBuf
import net.minecraft.network.codec.StreamCodec
import net.minecraft.util.StringRepresentable
import net.minecraft.world.level.block.state.BlockState
import net.neoforged.bus.api.IEventBus
import net.neoforged.neoforge.fluids.SimpleFluidContent
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.item.tool.RedstoneInteractorItem
import ru.dbotthepony.mc.otm.network.StreamCodecs
import ru.dbotthepony.mc.otm.network.streamCodec
import ru.dbotthepony.mc.otm.registry.MDeferredRegister
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") {
object : DataComponentType<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) {
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.item.BatteryItem
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.EssenceServoItem
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.RedstoneInteractorItem
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.registry.MDeferredRegister
import ru.dbotthepony.mc.otm.registry.MItemTags
@ -407,6 +409,7 @@ object MItems {
val EXPLOSIVE_HAMMER: ExplosiveHammerItem by registry.register("explosive_hammer") { ExplosiveHammerItem() }
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)) }
@ -557,6 +560,7 @@ object MItems {
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: 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
@ -586,6 +590,7 @@ object MItems {
MItems::ELECTROMOTOR,
MItems::MIRROR_COMPOUND,
MItems::MIRROR,
MItems::DISPLAY_SCREEN,
MItems::CARBON_MESH,
MItems::ARMOR_ASSEMBLY,
@ -621,6 +626,7 @@ object MItems {
MItems::ELECTROMOTOR,
MItems::MIRROR_COMPOUND,
MItems::MIRROR,
MItems::DISPLAY_SCREEN,
MItems::CARBON_MESH,
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_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 {
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",
"textures": {
"layer0": "overdrive_that_matters:item/withered_steel_sword_handheld"
@ -7,18 +6,18 @@
"display": {
"thirdperson_righthand": {
"rotation": [0, -90, 55],
"translation": [0, 4, 0.5],
"scale": [0.85, 0.85, 0.85]
"translation": [0, 5.75, 0.5],
"scale": [1, 1, 0.85]
},
"thirdperson_lefthand": {
"rotation": [0, 90, -55],
"translation": [0, 4, 0.5],
"scale": [0.85, 0.85, 0.85]
"translation": [0, 5.75, 0.5],
"scale": [1, 1, 0.85]
},
"firstperson_righthand": {
"rotation": [0, -90, 25],
"translation": [1.13, 3.2, 1.13],
"scale": [0.68, 0.68, 0.68]
"scale": [0.74, 0.74, 0.68]
},
"firstperson_lefthand": {
"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"
}
}
]
}
}