Compare commits
27 Commits
worldgen-p
...
1.21
Author | SHA1 | Date | |
---|---|---|---|
ad71619b72 | |||
e9a0983ab2 | |||
77443ee801 | |||
1cfa2be1dd | |||
389d0648b1 | |||
bb501e2c7e | |||
8fbf7d4c2c | |||
5f64f5708b | |||
1fc5c76224 | |||
cc372ed871 | |||
85950c6a90 | |||
16515ecc92 | |||
2922af8715 | |||
822ab97066 | |||
43c02b37a8 | |||
8f9103ca48 | |||
9a6cc53189 | |||
2453c60d76 | |||
a54382b74e | |||
d35da8c7f4 | |||
afb6cd5907 | |||
578d86410b | |||
9e1ae327ea | |||
cc7fe1ea2f | |||
3e59eb5595 | |||
4faef9d7c9 | |||
55856e6aec |
@ -209,6 +209,9 @@ dependencies {
|
|||||||
// runtimeOnly("curse.maven:integrated-tunnels-251389:4344632")
|
// runtimeOnly("curse.maven:integrated-tunnels-251389:4344632")
|
||||||
|
|
||||||
implementation("mekanism:Mekanism:${mc_version}-${mekanism_version}")
|
implementation("mekanism:Mekanism:${mc_version}-${mekanism_version}")
|
||||||
|
|
||||||
|
implementation("curse.maven:iron-chests-228756:5491156")
|
||||||
|
implementation("curse.maven:iron-shulker-boxes-314911:5491246")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,6 +271,8 @@ minecraft {
|
|||||||
|
|
||||||
mixin {
|
mixin {
|
||||||
config("$mod_id.mixins.json")
|
config("$mod_id.mixins.json")
|
||||||
|
config("$mod_id.ironchest.mixins.json")
|
||||||
|
config("$mod_id.ironshulkerbox.mixins.json")
|
||||||
// config("$mod_id.ad_astra.mixins.json")
|
// config("$mod_id.ad_astra.mixins.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,13 +128,17 @@ fun addItemModels(provider: MatteryItemModelProvider) {
|
|||||||
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"))
|
||||||
|
|
||||||
provider.generatedTiered(MItems.BATTERIES, "battery_tier")
|
provider.capacitorWithGauge(MItems.BATTERY_CRUDE, 10, "battery_gauge_", modLocation("item/battery_tier0"))
|
||||||
|
provider.capacitorWithGauge(MItems.BATTERY_BASIC, 10, "battery_gauge_", modLocation("item/battery_tier1"))
|
||||||
|
provider.capacitorWithGauge(MItems.BATTERY_NORMAL, 10, "battery_gauge_", modLocation("item/battery_tier2"))
|
||||||
|
provider.capacitorWithGauge(MItems.BATTERY_DENSE, 10, "battery_gauge_", modLocation("item/battery_tier3"))
|
||||||
|
provider.capacitorWithGauge(MItems.BATTERY_CAPACITOR, 10, "battery_gauge_", modLocation("item/battery_tier4"))
|
||||||
provider.generated(MItems.BATTERY_CREATIVE)
|
provider.generated(MItems.BATTERY_CREATIVE)
|
||||||
provider.generated(MItems.PROCEDURAL_BATTERY, modLocation("item/battery_procedural"))
|
provider.capacitorWithGauge(MItems.PROCEDURAL_BATTERY, 9, "battery_procedural_gauge_", modLocation("item/battery_procedural"))
|
||||||
|
|
||||||
provider.generated(MItems.MATTER_CAPACITOR_BASIC, modLocation("item/matter_capacitor_tier1"))
|
provider.capacitorWithGauge(MItems.MATTER_CAPACITOR_BASIC, 8, "matter_capacitor_gauge_", modLocation("item/matter_capacitor_tier1"))
|
||||||
provider.generated(MItems.MATTER_CAPACITOR_NORMAL, modLocation("item/matter_capacitor_tier2"))
|
provider.capacitorWithGauge(MItems.MATTER_CAPACITOR_NORMAL, 8, "matter_capacitor_gauge_", modLocation("item/matter_capacitor_tier2"))
|
||||||
provider.generated(MItems.MATTER_CAPACITOR_DENSE, modLocation("item/matter_capacitor_tier3"))
|
provider.capacitorWithGauge(MItems.MATTER_CAPACITOR_DENSE, 8, "matter_capacitor_gauge_", modLocation("item/matter_capacitor_tier3"))
|
||||||
provider.generated(MItems.MATTER_CAPACITOR_CREATIVE)
|
provider.generated(MItems.MATTER_CAPACITOR_CREATIVE)
|
||||||
|
|
||||||
provider.generated(MItems.MachineUpgrades.Basic.BLANK, modLocation("item/machine_upgrade_tier1"))
|
provider.generated(MItems.MachineUpgrades.Basic.BLANK, modLocation("item/machine_upgrade_tier1"))
|
||||||
@ -182,8 +186,8 @@ fun addItemModels(provider: MatteryItemModelProvider) {
|
|||||||
provider.upgrade(MItems.MachineUpgrades.Creative.MATTER_STORAGE_FLAT_SMALL, "matter", "creative")
|
provider.upgrade(MItems.MachineUpgrades.Creative.MATTER_STORAGE_FLAT_SMALL, "matter", "creative")
|
||||||
|
|
||||||
|
|
||||||
provider.generated(MItems.QUANTUM_BATTERY)
|
provider.capacitorWithGauge(MItems.QUANTUM_BATTERY, 10, "battery_gauge_")
|
||||||
provider.generated(MItems.QUANTUM_CAPACITOR)
|
provider.capacitorWithGauge(MItems.QUANTUM_CAPACITOR, 10, "battery_gauge_")
|
||||||
provider.generated(MItems.QUANTUM_BATTERY_CREATIVE)
|
provider.generated(MItems.QUANTUM_BATTERY_CREATIVE)
|
||||||
|
|
||||||
provider.generated(MItems.PATTERN_DRIVE_NORMAL, modLocation("item/pattern_drive_tier1"))
|
provider.generated(MItems.PATTERN_DRIVE_NORMAL, modLocation("item/pattern_drive_tier1"))
|
||||||
|
@ -143,6 +143,33 @@ class MatteryItemModelProvider(event: GatherDataEvent) : ItemModelProvider(event
|
|||||||
.texture("layer1", modLocation("item/machine_upgrade_icon_$upgradeType"))
|
.texture("layer1", modLocation("item/machine_upgrade_icon_$upgradeType"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun capacitorWithGauge(item: Item, fillTextures: Int, gaugePrefix: String, baseTexture: ResourceLocation? = null) = exec {
|
||||||
|
val path = item.registryName!!.path
|
||||||
|
val texture = baseTexture ?: modLocation("item/$path")
|
||||||
|
|
||||||
|
val empty = withExistingParent("${path}_empty", GENERATED)
|
||||||
|
.texture("layer0", texture)
|
||||||
|
|
||||||
|
val basic = withExistingParent(path, GENERATED)
|
||||||
|
.texture("layer0", texture)
|
||||||
|
.texture("layer1", modLocation("item/${gaugePrefix}$fillTextures"))
|
||||||
|
.override()
|
||||||
|
.predicate(modLocation("capacitor_gauge"), 0f)
|
||||||
|
.model(empty)
|
||||||
|
.end()
|
||||||
|
|
||||||
|
for (i in 1 .. fillTextures) {
|
||||||
|
val model = withExistingParent("${path}_fill_$i", GENERATED)
|
||||||
|
.texture("layer0", texture)
|
||||||
|
.texture("layer1", modLocation("item/${gaugePrefix}$i"))
|
||||||
|
|
||||||
|
basic.override()
|
||||||
|
.predicate(modLocation("capacitor_gauge"), i.toFloat() / fillTextures.toFloat())
|
||||||
|
.model(model)
|
||||||
|
.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val ARMOR_TRIM_MATERIALS = listOf("quartz", "iron", "netherite", "redstone", "copper", "gold", "emerald", "diamond", "lapis", "amethyst")
|
val ARMOR_TRIM_MATERIALS = listOf("quartz", "iron", "netherite", "redstone", "copper", "gold", "emerald", "diamond", "lapis", "amethyst")
|
||||||
val GENERATED = ResourceLocation("minecraft", "item/generated")
|
val GENERATED = ResourceLocation("minecraft", "item/generated")
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironchest;
|
||||||
|
|
||||||
|
import com.progwml6.ironchest.common.block.regular.entity.CopperChestBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironchest.MatteryIronChestMenu;
|
||||||
|
|
||||||
|
@Mixin(CopperChestBlockEntity.class)
|
||||||
|
public abstract class CopperChestBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronChestMenu.copper(containerId, inventory, ((CopperChestBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironchest;
|
||||||
|
|
||||||
|
import com.progwml6.ironchest.common.block.regular.entity.CrystalChestBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironchest.MatteryIronChestMenu;
|
||||||
|
|
||||||
|
@Mixin(CrystalChestBlockEntity.class)
|
||||||
|
public abstract class CrystalChestBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronChestMenu.crystal(containerId, inventory, ((CrystalChestBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironchest;
|
||||||
|
|
||||||
|
import com.progwml6.ironchest.common.block.regular.entity.DiamondChestBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironchest.MatteryIronChestMenu;
|
||||||
|
|
||||||
|
@Mixin(DiamondChestBlockEntity.class)
|
||||||
|
public abstract class DiamondChestBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronChestMenu.diamond(containerId, inventory, ((DiamondChestBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironchest;
|
||||||
|
|
||||||
|
import com.progwml6.ironchest.common.block.regular.entity.DirtChestBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironchest.MatteryIronChestMenu;
|
||||||
|
|
||||||
|
@Mixin(DirtChestBlockEntity.class)
|
||||||
|
public abstract class DirtChestBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronChestMenu.dirt(containerId, inventory, ((DirtChestBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironchest;
|
||||||
|
|
||||||
|
import com.progwml6.ironchest.common.block.regular.entity.GoldChestBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironchest.MatteryIronChestMenu;
|
||||||
|
|
||||||
|
@Mixin(GoldChestBlockEntity.class)
|
||||||
|
public abstract class GoldChestBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronChestMenu.gold(containerId, inventory, ((GoldChestBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironchest;
|
||||||
|
|
||||||
|
import com.progwml6.ironchest.common.block.regular.entity.IronChestBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironchest.MatteryIronChestMenu;
|
||||||
|
|
||||||
|
@Mixin(IronChestBlockEntity.class)
|
||||||
|
public abstract class IronChestBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronChestMenu.iron(containerId, inventory, ((IronChestBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironchest;
|
||||||
|
|
||||||
|
import com.progwml6.ironchest.common.block.regular.entity.ObsidianChestBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironchest.MatteryIronChestMenu;
|
||||||
|
|
||||||
|
@Mixin(ObsidianChestBlockEntity.class)
|
||||||
|
public abstract class ObsidianChestBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronChestMenu.obsidian(containerId, inventory, ((ObsidianChestBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironchest;
|
||||||
|
|
||||||
|
import com.progwml6.ironchest.common.block.trapped.entity.TrappedCopperChestBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironchest.MatteryIronChestMenu;
|
||||||
|
|
||||||
|
@Mixin(TrappedCopperChestBlockEntity.class)
|
||||||
|
public abstract class TrappedCopperChestBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronChestMenu.copper(containerId, inventory, ((TrappedCopperChestBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironchest;
|
||||||
|
|
||||||
|
import com.progwml6.ironchest.common.block.trapped.entity.TrappedCrystalChestBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironchest.MatteryIronChestMenu;
|
||||||
|
|
||||||
|
@Mixin(TrappedCrystalChestBlockEntity.class)
|
||||||
|
public abstract class TrappedCrystalChestBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronChestMenu.crystal(containerId, inventory, ((TrappedCrystalChestBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironchest;
|
||||||
|
|
||||||
|
import com.progwml6.ironchest.common.block.trapped.entity.TrappedDiamondChestBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironchest.MatteryIronChestMenu;
|
||||||
|
|
||||||
|
@Mixin(TrappedDiamondChestBlockEntity.class)
|
||||||
|
public abstract class TrappedDiamondChestBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronChestMenu.diamond(containerId, inventory, ((TrappedDiamondChestBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironchest;
|
||||||
|
|
||||||
|
import com.progwml6.ironchest.common.block.trapped.entity.TrappedDirtChestBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironchest.MatteryIronChestMenu;
|
||||||
|
|
||||||
|
@Mixin(TrappedDirtChestBlockEntity.class)
|
||||||
|
public abstract class TrappedDirtChestBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronChestMenu.dirt(containerId, inventory, ((TrappedDirtChestBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironchest;
|
||||||
|
|
||||||
|
import com.progwml6.ironchest.common.block.trapped.entity.TrappedGoldChestBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironchest.MatteryIronChestMenu;
|
||||||
|
|
||||||
|
@Mixin(TrappedGoldChestBlockEntity.class)
|
||||||
|
public abstract class TrappedGoldChestBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronChestMenu.gold(containerId, inventory, ((TrappedGoldChestBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironchest;
|
||||||
|
|
||||||
|
import com.progwml6.ironchest.common.block.trapped.entity.TrappedIronChestBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironchest.MatteryIronChestMenu;
|
||||||
|
|
||||||
|
@Mixin(TrappedIronChestBlockEntity.class)
|
||||||
|
public abstract class TrappedIronChestBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronChestMenu.iron(containerId, inventory, ((TrappedIronChestBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironchest;
|
||||||
|
|
||||||
|
import com.progwml6.ironchest.common.block.trapped.entity.TrappedObsidianChestBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironchest.MatteryIronChestMenu;
|
||||||
|
|
||||||
|
@Mixin(TrappedObsidianChestBlockEntity.class)
|
||||||
|
public abstract class TrappedObsidianChestBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronChestMenu.obsidian(containerId, inventory, ((TrappedObsidianChestBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironshulkerbox;
|
||||||
|
|
||||||
|
import com.progwml6.ironshulkerbox.common.block.entity.CopperShulkerBoxBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironshulkerbox.MatteryIronShulkerBoxMenu;
|
||||||
|
|
||||||
|
@Mixin(CopperShulkerBoxBlockEntity.class)
|
||||||
|
public abstract class CopperShulkerBoxBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronShulkerBoxMenu.copper(containerId, inventory, ((CopperShulkerBoxBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironshulkerbox;
|
||||||
|
|
||||||
|
import com.progwml6.ironshulkerbox.common.block.entity.CrystalShulkerBoxBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironshulkerbox.MatteryIronShulkerBoxMenu;
|
||||||
|
|
||||||
|
@Mixin(CrystalShulkerBoxBlockEntity.class)
|
||||||
|
public abstract class CrystalShulkerBoxBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronShulkerBoxMenu.crystal(containerId, inventory, ((CrystalShulkerBoxBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironshulkerbox;
|
||||||
|
|
||||||
|
import com.progwml6.ironshulkerbox.common.block.entity.DiamondShulkerBoxBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironshulkerbox.MatteryIronShulkerBoxMenu;
|
||||||
|
|
||||||
|
@Mixin(DiamondShulkerBoxBlockEntity.class)
|
||||||
|
public abstract class DiamondShulkerBoxBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronShulkerBoxMenu.diamond(containerId, inventory, ((DiamondShulkerBoxBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironshulkerbox;
|
||||||
|
|
||||||
|
import com.progwml6.ironshulkerbox.common.block.entity.GoldShulkerBoxBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironshulkerbox.MatteryIronShulkerBoxMenu;
|
||||||
|
|
||||||
|
@Mixin(GoldShulkerBoxBlockEntity.class)
|
||||||
|
public abstract class GoldShulkerBoxBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronShulkerBoxMenu.gold(containerId, inventory, ((GoldShulkerBoxBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironshulkerbox;
|
||||||
|
|
||||||
|
import com.progwml6.ironshulkerbox.common.block.entity.IronShulkerBoxBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironshulkerbox.MatteryIronShulkerBoxMenu;
|
||||||
|
|
||||||
|
@Mixin(IronShulkerBoxBlockEntity.class)
|
||||||
|
public abstract class IronShulkerBoxBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronShulkerBoxMenu.iron(containerId, inventory, ((IronShulkerBoxBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.mixin.ironshulkerbox;
|
||||||
|
|
||||||
|
import com.progwml6.ironshulkerbox.common.block.entity.ObsidianShulkerBoxBlockEntity;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironshulkerbox.MatteryIronShulkerBoxMenu;
|
||||||
|
|
||||||
|
@Mixin(ObsidianShulkerBoxBlockEntity.class)
|
||||||
|
public abstract class ObsidianShulkerBoxBlockEntityMixin {
|
||||||
|
@Overwrite(remap = false)
|
||||||
|
public AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
|
||||||
|
return MatteryIronShulkerBoxMenu.obsidian(containerId, inventory, ((ObsidianShulkerBoxBlockEntity)(Object) this));
|
||||||
|
}
|
||||||
|
}
|
@ -44,6 +44,10 @@ import ru.dbotthepony.mc.otm.client.render.blockentity.BatteryBankRenderer
|
|||||||
import ru.dbotthepony.mc.otm.client.render.blockentity.MatterBatteryBankRenderer
|
import ru.dbotthepony.mc.otm.client.render.blockentity.MatterBatteryBankRenderer
|
||||||
import ru.dbotthepony.mc.otm.compat.curios.isCuriosLoaded
|
import ru.dbotthepony.mc.otm.compat.curios.isCuriosLoaded
|
||||||
import ru.dbotthepony.mc.otm.compat.curios.onCuriosSlotModifiersUpdated
|
import ru.dbotthepony.mc.otm.compat.curios.onCuriosSlotModifiersUpdated
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironchest.IronChestMenuTypes
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironchest.isIronChestLoaded
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironshulkerbox.IronShulkersMenuTypes
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironshulkerbox.isIronShulkersLoaded
|
||||||
import ru.dbotthepony.mc.otm.compat.vanilla.MatteryChestMenu
|
import ru.dbotthepony.mc.otm.compat.vanilla.MatteryChestMenu
|
||||||
import ru.dbotthepony.mc.otm.compat.vanilla.VanillaMenuTypes
|
import ru.dbotthepony.mc.otm.compat.vanilla.VanillaMenuTypes
|
||||||
import ru.dbotthepony.mc.otm.config.PlayerConfig
|
import ru.dbotthepony.mc.otm.config.PlayerConfig
|
||||||
@ -134,6 +138,14 @@ object OverdriveThatMatters {
|
|||||||
StorageStack.register(MOD_BUS)
|
StorageStack.register(MOD_BUS)
|
||||||
VanillaMenuTypes.register(MOD_BUS)
|
VanillaMenuTypes.register(MOD_BUS)
|
||||||
|
|
||||||
|
if (isIronChestLoaded) {
|
||||||
|
IronChestMenuTypes.register(MOD_BUS)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isIronShulkersLoaded) {
|
||||||
|
IronShulkersMenuTypes.register(MOD_BUS)
|
||||||
|
}
|
||||||
|
|
||||||
MCreativeTabs.initialize(MOD_BUS)
|
MCreativeTabs.initialize(MOD_BUS)
|
||||||
|
|
||||||
MOD_BUS.addListener(::registerNetworkPackets)
|
MOD_BUS.addListener(::registerNetworkPackets)
|
||||||
|
@ -348,6 +348,17 @@ abstract class MatteryBlockEntity(type: BlockEntityType<*>, pos: BlockPos, state
|
|||||||
private var cache: BlockCapabilityCache<T, in Direction?>? = null
|
private var cache: BlockCapabilityCache<T, in Direction?>? = null
|
||||||
private val listeners = Listenable.Impl<T?>()
|
private val listeners = Listenable.Impl<T?>()
|
||||||
|
|
||||||
|
private val lookupProvider = Supplier<T?> {
|
||||||
|
if (isRemoved)
|
||||||
|
return@Supplier null
|
||||||
|
|
||||||
|
val get = cache?.capability
|
||||||
|
provider = Supplier { get }
|
||||||
|
return@Supplier get
|
||||||
|
}
|
||||||
|
|
||||||
|
private var provider: Supplier<T?> = lookupProvider
|
||||||
|
|
||||||
override fun addListener(listener: Consumer<T?>): Listenable.L {
|
override fun addListener(listener: Consumer<T?>): Listenable.L {
|
||||||
return listeners.addListener(listener)
|
return listeners.addListener(listener)
|
||||||
}
|
}
|
||||||
@ -358,23 +369,21 @@ abstract class MatteryBlockEntity(type: BlockEntityType<*>, pos: BlockPos, state
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun get(): T? {
|
override fun get(): T? {
|
||||||
if (isRemoved)
|
return provider.get()
|
||||||
return null
|
|
||||||
|
|
||||||
return cache?.capability
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val isPresent: Boolean
|
val isPresent: Boolean
|
||||||
get() = cache?.capability != null
|
get() = get() != null
|
||||||
|
|
||||||
val isEmpty: Boolean
|
val isEmpty: Boolean
|
||||||
get() = cache?.capability == null
|
get() = get() == null
|
||||||
|
|
||||||
fun rebuildCache() {
|
fun rebuildCache() {
|
||||||
if (!SERVER_IS_LIVE) return
|
if (!SERVER_IS_LIVE) return
|
||||||
val level = level as? ServerLevel
|
val level = level as? ServerLevel
|
||||||
|
|
||||||
val creationVersion = ++currentVersion
|
val creationVersion = ++currentVersion
|
||||||
|
provider = lookupProvider
|
||||||
|
|
||||||
if (level == null) {
|
if (level == null) {
|
||||||
cache = null
|
cache = null
|
||||||
@ -388,12 +397,21 @@ abstract class MatteryBlockEntity(type: BlockEntityType<*>, pos: BlockPos, state
|
|||||||
{ !isRemoved || creationVersion != currentVersion },
|
{ !isRemoved || creationVersion != currentVersion },
|
||||||
// IllegalStateException("Do not call getCapability on an invalid cache or from the invalidation listener!")
|
// IllegalStateException("Do not call getCapability on an invalid cache or from the invalidation listener!")
|
||||||
// what a shame.
|
// what a shame.
|
||||||
{ if (SERVER_IS_LIVE) onceServer { if (!isRemoved && creationVersion == currentVersion) listeners.accept(cache?.capability) } })
|
{
|
||||||
|
provider = lookupProvider
|
||||||
|
if (SERVER_IS_LIVE) onceServer { if (!isRemoved && creationVersion == currentVersion) listeners.accept(get()) }
|
||||||
|
})
|
||||||
|
|
||||||
onceServer {
|
onceServer {
|
||||||
if (!isRemoved && creationVersion == currentVersion) listeners.accept(cache?.capability)
|
if (!isRemoved && creationVersion == currentVersion) listeners.accept(get())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun removeCache() {
|
||||||
|
cache = null
|
||||||
|
currentVersion++
|
||||||
|
provider = Supplier { null }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val syncher = SynchableGroup()
|
val syncher = SynchableGroup()
|
||||||
@ -424,6 +442,7 @@ abstract class MatteryBlockEntity(type: BlockEntityType<*>, pos: BlockPos, state
|
|||||||
|
|
||||||
override fun setRemoved() {
|
override fun setRemoved() {
|
||||||
super.setRemoved()
|
super.setRemoved()
|
||||||
|
capabilityCaches.forEach { it.removeCache() }
|
||||||
unsubscribe()
|
unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ abstract class EnergyCableBlockEntity(type: BlockEntityType<*>, blockPos: BlockP
|
|||||||
|
|
||||||
val sides get() = energySides
|
val sides get() = energySides
|
||||||
|
|
||||||
val currentlyTransferringTo = ObjectArraySet<Pair<Node, RelativeSide>>()
|
val currentlyTransferringTo = ObjectArraySet<Pair<Node, CableSide>>()
|
||||||
|
|
||||||
override fun onNeighbour(link: Link) {
|
override fun onNeighbour(link: Link) {
|
||||||
if (link is DirectionLink) {
|
if (link is DirectionLink) {
|
||||||
|
@ -74,8 +74,8 @@ private class LinkedPriorityQueue<T : Comparable<T>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableGraph>() {
|
class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableGraph>() {
|
||||||
private val livelyNodes = HashSet<Pair<EnergyCableBlockEntity.Node, RelativeSide>>()
|
private val livelyNodes = HashSet<Pair<EnergyCableBlockEntity.Node, EnergyCableBlockEntity.CableSide>>()
|
||||||
private val livelyNodesList = ArrayList<Pair<EnergyCableBlockEntity.Node, RelativeSide>>()
|
private val livelyNodesList = ArrayList<Pair<EnergyCableBlockEntity.Node, EnergyCableBlockEntity.CableSide>>()
|
||||||
|
|
||||||
fun addLivelyNode(node: EnergyCableBlockEntity.Node) {
|
fun addLivelyNode(node: EnergyCableBlockEntity.Node) {
|
||||||
when (contains(node)) {
|
when (contains(node)) {
|
||||||
@ -83,7 +83,7 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
|
|||||||
ContainsStatus.DOES_NOT_BELONG -> throw IllegalArgumentException("$node does not belong to $this")
|
ContainsStatus.DOES_NOT_BELONG -> throw IllegalArgumentException("$node does not belong to $this")
|
||||||
ContainsStatus.CONTAINS -> {
|
ContainsStatus.CONTAINS -> {
|
||||||
for (dir in RelativeSide.entries) {
|
for (dir in RelativeSide.entries) {
|
||||||
val pair = node to dir
|
val pair = node to node.sides[dir]!!
|
||||||
|
|
||||||
if (livelyNodes.add(pair)) {
|
if (livelyNodes.add(pair)) {
|
||||||
livelyNodesList.add(pair)
|
livelyNodesList.add(pair)
|
||||||
@ -589,7 +589,7 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
|
|||||||
|
|
||||||
override fun onNodeRemoved(node: EnergyCableBlockEntity.Node) {
|
override fun onNodeRemoved(node: EnergyCableBlockEntity.Node) {
|
||||||
for (dir in RelativeSide.entries) {
|
for (dir in RelativeSide.entries) {
|
||||||
val pair = node to dir
|
val pair = node to node.sides[dir]!!
|
||||||
|
|
||||||
if (livelyNodes.remove(pair)) {
|
if (livelyNodes.remove(pair)) {
|
||||||
check(livelyNodesList.remove(pair))
|
check(livelyNodesList.remove(pair))
|
||||||
@ -617,7 +617,7 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
|
|||||||
|
|
||||||
override fun onNodeAdded(node: EnergyCableBlockEntity.Node) {
|
override fun onNodeAdded(node: EnergyCableBlockEntity.Node) {
|
||||||
for (dir in RelativeSide.entries) {
|
for (dir in RelativeSide.entries) {
|
||||||
val pair = node to dir
|
val pair = node to node.sides[dir]!!
|
||||||
check(livelyNodes.add(pair))
|
check(livelyNodes.add(pair))
|
||||||
livelyNodesList.add(pair)
|
livelyNodesList.add(pair)
|
||||||
}
|
}
|
||||||
@ -649,8 +649,7 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val (node, relSide) = pair
|
val (node, side) = pair
|
||||||
val side = node.sides[relSide]!!
|
|
||||||
|
|
||||||
if (!side.isEnabled) {
|
if (!side.isEnabled) {
|
||||||
indicesToRemove.add(i)
|
indicesToRemove.add(i)
|
||||||
|
@ -29,6 +29,7 @@ import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
|||||||
import ru.dbotthepony.mc.otm.util.math.Decimal
|
import ru.dbotthepony.mc.otm.util.math.Decimal
|
||||||
import ru.dbotthepony.mc.otm.util.countingLazy
|
import ru.dbotthepony.mc.otm.util.countingLazy
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode
|
import ru.dbotthepony.mc.otm.graph.matter.SimpleMatterNode
|
||||||
|
import ru.dbotthepony.mc.otm.util.math.toDecimal
|
||||||
import java.util.function.BooleanSupplier
|
import java.util.function.BooleanSupplier
|
||||||
|
|
||||||
class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
||||||
@ -197,16 +198,25 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
|||||||
|
|
||||||
if (matter.storedMatter.isPositive) {
|
if (matter.storedMatter.isPositive) {
|
||||||
val energyRatio = if (energyRate <= Decimal.ZERO) Decimal.ONE else energy.extractEnergy(energyRate, true) / energyRate
|
val energyRatio = if (energyRate <= Decimal.ZERO) Decimal.ONE else energy.extractEnergy(energyRate, true) / energyRate
|
||||||
val matterRatio = matter.extractMatter(capability.receiveMatter(rate.coerceAtMost(matter.storedMatter), true), true) / rate
|
val matterTransferred = matter.extractMatter(capability.receiveMatter(rate.coerceAtMost(matter.storedMatter), true), true)
|
||||||
|
val matterRatio = matterTransferred / rate
|
||||||
|
|
||||||
val minRatio = minOf(matterRatio, energyRatio)
|
if (matterRatio == Decimal.ZERO && matterTransferred > Decimal.ZERO) {
|
||||||
|
// transferring very little matter, transfer this time for free
|
||||||
if (minRatio > Decimal.ZERO) {
|
|
||||||
isWorking = true
|
isWorking = true
|
||||||
energy.extractEnergy(energyRate * minRatio, false)
|
matter.extractMatter(capability.receiveMatter(matter.storedMatter, false), false)
|
||||||
matter.extractMatter(capability.receiveMatter(rate * minRatio, false), false)
|
|
||||||
workProgress = ((capability.storedMatter - initialCapacity!!) / capability.maxStoredMatter).toFloat()
|
workProgress = ((capability.storedMatter - initialCapacity!!) / capability.maxStoredMatter).toFloat()
|
||||||
slot.setChanged()
|
slot.setChanged()
|
||||||
|
} else {
|
||||||
|
val minRatio = minOf(matterRatio, energyRatio)
|
||||||
|
|
||||||
|
if (minRatio > Decimal.ZERO) {
|
||||||
|
isWorking = true
|
||||||
|
energy.extractEnergy(energyRate * minRatio, false)
|
||||||
|
matter.extractMatter(capability.receiveMatter(rate * minRatio, false), false)
|
||||||
|
workProgress = ((capability.storedMatter - initialCapacity!!) / capability.maxStoredMatter).toFloat()
|
||||||
|
slot.setChanged()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (spitItemsWhenCantWork) {
|
if (spitItemsWhenCantWork) {
|
||||||
@ -262,20 +272,28 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
|||||||
initialCapacity = initialCapacity ?: it.storedMatter
|
initialCapacity = initialCapacity ?: it.storedMatter
|
||||||
|
|
||||||
hasCapacitors = true
|
hasCapacitors = true
|
||||||
val rate = MachinesConfig.MatterBottler.RATE * (1.0 + upgrades.speedBonus)
|
val rate = MachinesConfig.MatterBottler.RATE * (Decimal.ONE + upgrades.speedBonus.toDecimal())
|
||||||
val energyRate = MachinesConfig.MatterBottler.VALUES.energyConsumption * (1.0 + upgrades.speedBonus)
|
val energyRate = MachinesConfig.MatterBottler.VALUES.energyConsumption * (Decimal.ONE + upgrades.speedBonus.toDecimal())
|
||||||
|
|
||||||
val energyRatio = if (energyRate <= Decimal.ZERO) Decimal.ONE else energy.extractEnergy(energyRate, true) / energyRate
|
val energyRatio = if (energyRate <= Decimal.ZERO) Decimal.ONE else energy.extractEnergy(energyRate, true) / energyRate
|
||||||
val matterRatio = matter.receiveMatter(it.extractMatterChecked(rate, true), true) / rate
|
val matterExtracted = matter.receiveMatter(it.extractMatterChecked(rate, true), true)
|
||||||
|
val matterRatio = matterExtracted / rate
|
||||||
|
|
||||||
val minRatio = minOf(energyRatio, matterRatio)
|
if (matterRatio == Decimal.ZERO && matterExtracted > Decimal.ZERO) {
|
||||||
|
// very little matter extracted, extract this one for free
|
||||||
if (minRatio > Decimal.ZERO) {
|
|
||||||
any = true
|
any = true
|
||||||
energy.extractEnergy(energyRate * energyRatio, false)
|
matter.receiveMatter(it.extractMatterChecked(matterExtracted, false), false)
|
||||||
matter.receiveMatter(it.extractMatterChecked(rate * minRatio, false), false)
|
|
||||||
|
|
||||||
workProgress = 1f - (it.storedMatter / initialCapacity!!).toFloat()
|
workProgress = 1f - (it.storedMatter / initialCapacity!!).toFloat()
|
||||||
|
} else {
|
||||||
|
val minRatio = minOf(energyRatio, matterRatio)
|
||||||
|
|
||||||
|
if (minRatio > Decimal.ZERO) {
|
||||||
|
any = true
|
||||||
|
energy.extractEnergy(energyRate * energyRatio, false)
|
||||||
|
matter.receiveMatter(it.extractMatterChecked(rate * minRatio, false), false)
|
||||||
|
|
||||||
|
workProgress = 1f - (it.storedMatter / initialCapacity!!).toFloat()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
|
@ -31,7 +31,7 @@ import ru.dbotthepony.mc.otm.menu.MatteryMenuSlot
|
|||||||
import java.util.Collections.emptyIterator
|
import java.util.Collections.emptyIterator
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
|
|
||||||
val isCosmeticArmorLoaded by lazy {
|
internal val isCosmeticArmorLoaded by lazy {
|
||||||
ModList.get().isLoaded("cosmeticarmorreworked")
|
ModList.get().isLoaded("cosmeticarmorreworked")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ import java.util.Collections.emptyIterator
|
|||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
val isCuriosLoaded by lazy {
|
internal val isCuriosLoaded by lazy {
|
||||||
ModList.get().isLoaded(CuriosApi.MODID)
|
ModList.get().isLoaded(CuriosApi.MODID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.compat.ironchest
|
||||||
|
|
||||||
|
import com.progwml6.ironchest.IronChests
|
||||||
|
import com.progwml6.ironchest.common.block.IronChestsTypes
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.core.registries.Registries
|
||||||
|
import net.minecraft.world.Container
|
||||||
|
import net.minecraft.world.flag.FeatureFlags
|
||||||
|
import net.minecraft.world.inventory.MenuType
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import net.neoforged.bus.api.IEventBus
|
||||||
|
import net.neoforged.fml.ModList
|
||||||
|
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent
|
||||||
|
import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent
|
||||||
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
|
import ru.dbotthepony.mc.otm.capability.IQuickStackContainer
|
||||||
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
|
import ru.dbotthepony.mc.otm.compat.vanilla.VanillaChestScreen
|
||||||
|
import ru.dbotthepony.mc.otm.menu.MatteryMenuSlot
|
||||||
|
import ru.dbotthepony.mc.otm.menu.makeSlots
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MDeferredRegister
|
||||||
|
|
||||||
|
internal val isIronChestLoaded by lazy {
|
||||||
|
ModList.get().isLoaded(IronChests.MODID)
|
||||||
|
}
|
||||||
|
|
||||||
|
object IronChestMenuTypes {
|
||||||
|
private val registrar = MDeferredRegister(Registries.MENU, OverdriveThatMatters.MOD_ID)
|
||||||
|
|
||||||
|
val IRON by registrar.register("ironchest_iron") { MenuType(MatteryIronChestMenu::iron, FeatureFlags.VANILLA_SET) }
|
||||||
|
val GOLD by registrar.register("ironchest_gold") { MenuType(MatteryIronChestMenu::gold, FeatureFlags.VANILLA_SET) }
|
||||||
|
val DIAMOND by registrar.register("ironchest_diamond") { MenuType(MatteryIronChestMenu::diamond, FeatureFlags.VANILLA_SET) }
|
||||||
|
val COPPER by registrar.register("ironchest_copper") { MenuType(MatteryIronChestMenu::copper, FeatureFlags.VANILLA_SET) }
|
||||||
|
val CRYSTAL by registrar.register("ironchest_crystal") { MenuType(MatteryIronChestMenu::crystal, FeatureFlags.VANILLA_SET) }
|
||||||
|
val OBSIDIAN by registrar.register("ironchest_obsidian") { MenuType(MatteryIronChestMenu::obsidian, FeatureFlags.VANILLA_SET) }
|
||||||
|
val DIRT by registrar.register("ironchest_dirt") { MenuType(MatteryIronChestMenu::dirt, FeatureFlags.VANILLA_SET) }
|
||||||
|
|
||||||
|
private fun provider(level: Level, pos: BlockPos, state: BlockState, blockEntity: BlockEntity?, context: Void?): IQuickStackContainer? {
|
||||||
|
val container = blockEntity as? Container ?: return null
|
||||||
|
return IQuickStackContainer.Simple(makeSlots(container, ::MatteryMenuSlot))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun registerCapabilities(event: RegisterCapabilitiesEvent) {
|
||||||
|
IronChestsTypes.entries.map { IronChestsTypes.get(it) }.forEach {
|
||||||
|
event.registerBlock(MatteryCapability.QUICK_STACK_CONTAINER, ::provider, *it.toTypedArray())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun register(bus: IEventBus) {
|
||||||
|
registrar.register(bus)
|
||||||
|
bus.addListener(this::registerScreens)
|
||||||
|
bus.addListener(this::registerCapabilities)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerScreens(event: RegisterMenuScreensEvent) {
|
||||||
|
event.register(IRON, ::VanillaChestScreen)
|
||||||
|
event.register(GOLD, ::VanillaChestScreen)
|
||||||
|
event.register(DIAMOND, ::VanillaChestScreen)
|
||||||
|
event.register(COPPER, ::VanillaChestScreen)
|
||||||
|
event.register(CRYSTAL, ::VanillaChestScreen)
|
||||||
|
event.register(OBSIDIAN, ::VanillaChestScreen)
|
||||||
|
event.register(DIRT, ::VanillaChestScreen)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.compat.ironchest
|
||||||
|
|
||||||
|
import com.progwml6.ironchest.common.block.IronChestsTypes
|
||||||
|
import net.minecraft.world.Container
|
||||||
|
import net.minecraft.world.SimpleContainer
|
||||||
|
import net.minecraft.world.entity.player.Inventory
|
||||||
|
import net.minecraft.world.inventory.MenuType
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraft.world.item.Items
|
||||||
|
import ru.dbotthepony.mc.otm.compat.vanilla.AbstractVanillaChestMenu
|
||||||
|
import ru.dbotthepony.mc.otm.container.EnhancedContainer
|
||||||
|
import ru.dbotthepony.mc.otm.menu.MatteryMenuSlot
|
||||||
|
import ru.dbotthepony.mc.otm.menu.QuickMoveInput
|
||||||
|
import ru.dbotthepony.mc.otm.menu.makeSlots
|
||||||
|
|
||||||
|
class MatteryIronChestMenu(
|
||||||
|
type: MenuType<*>, containerId: Int,
|
||||||
|
inventory: Inventory, chestType: IronChestsTypes,
|
||||||
|
container: Container = EnhancedContainer.Simple(chestType.size),
|
||||||
|
) : AbstractVanillaChestMenu(type, containerId, inventory, container) {
|
||||||
|
override val columns = chestType.rowLength
|
||||||
|
override val rows = chestType.size / chestType.rowLength
|
||||||
|
|
||||||
|
override val containerSlots = if (chestType == IronChestsTypes.DIRT) makeSlots(container, ::MDirtChestSlot) else makeSlots(container, ::MatteryMenuSlot)
|
||||||
|
|
||||||
|
init {
|
||||||
|
container.startOpen(player)
|
||||||
|
addStorageSlot(containerSlots)
|
||||||
|
addInventorySlots()
|
||||||
|
}
|
||||||
|
|
||||||
|
override val quickMoveToStorage = QuickMoveInput.create(this, playerCombinedInventorySlots, containerSlots)
|
||||||
|
override val quickMoveFromStorage = QuickMoveInput.create(this, containerSlots, playerInventorySlots, false)
|
||||||
|
|
||||||
|
class MDirtChestSlot(container: Container, slot: Int) : MatteryMenuSlot(container, slot) {
|
||||||
|
override fun mayPlace(stack: ItemStack): Boolean = stack.isEmpty || stack.`is`(Items.DIRT)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun iron(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(IronChestsTypes.IRON.size), chestType: IronChestsTypes = IronChestsTypes.IRON): MatteryIronChestMenu {
|
||||||
|
return MatteryIronChestMenu(IronChestMenuTypes.IRON, containerId, inventory, chestType, container)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun gold(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(IronChestsTypes.GOLD.size), chestType: IronChestsTypes = IronChestsTypes.GOLD): MatteryIronChestMenu {
|
||||||
|
return MatteryIronChestMenu(IronChestMenuTypes.GOLD, containerId, inventory, chestType, container)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun diamond(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(IronChestsTypes.DIAMOND.size), chestType: IronChestsTypes = IronChestsTypes.DIAMOND): MatteryIronChestMenu {
|
||||||
|
return MatteryIronChestMenu(IronChestMenuTypes.DIAMOND, containerId, inventory, chestType, container)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun copper(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(IronChestsTypes.COPPER.size), chestType: IronChestsTypes = IronChestsTypes.COPPER): MatteryIronChestMenu {
|
||||||
|
return MatteryIronChestMenu(IronChestMenuTypes.COPPER, containerId, inventory, chestType, container)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun crystal(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(IronChestsTypes.CRYSTAL.size), chestType: IronChestsTypes = IronChestsTypes.CRYSTAL): MatteryIronChestMenu {
|
||||||
|
return MatteryIronChestMenu(IronChestMenuTypes.CRYSTAL, containerId, inventory, chestType, container)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun obsidian(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(IronChestsTypes.OBSIDIAN.size), chestType: IronChestsTypes = IronChestsTypes.OBSIDIAN): MatteryIronChestMenu {
|
||||||
|
return MatteryIronChestMenu(IronChestMenuTypes.OBSIDIAN, containerId, inventory, chestType, container)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun dirt(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(IronChestsTypes.DIRT.size), chestType: IronChestsTypes = IronChestsTypes.DIRT): MatteryIronChestMenu {
|
||||||
|
return MatteryIronChestMenu(IronChestMenuTypes.DIRT, containerId, inventory, chestType, container)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.compat.ironshulkerbox
|
||||||
|
|
||||||
|
import com.progwml6.ironshulkerbox.IronShulkerBoxes
|
||||||
|
import com.progwml6.ironshulkerbox.common.block.IronShulkerBoxesTypes
|
||||||
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.core.registries.Registries
|
||||||
|
import net.minecraft.world.Container
|
||||||
|
import net.minecraft.world.flag.FeatureFlags
|
||||||
|
import net.minecraft.world.inventory.MenuType
|
||||||
|
import net.minecraft.world.item.DyeColor
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
|
import net.neoforged.bus.api.IEventBus
|
||||||
|
import net.neoforged.fml.ModList
|
||||||
|
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent
|
||||||
|
import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent
|
||||||
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
|
import ru.dbotthepony.mc.otm.capability.IQuickStackContainer
|
||||||
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
|
import ru.dbotthepony.mc.otm.compat.ironshulkerbox.MatteryIronShulkerBoxMenu.Slot
|
||||||
|
import ru.dbotthepony.mc.otm.compat.vanilla.VanillaChestScreen
|
||||||
|
import ru.dbotthepony.mc.otm.menu.makeSlots
|
||||||
|
import ru.dbotthepony.mc.otm.registry.MDeferredRegister
|
||||||
|
import kotlin.collections.toTypedArray
|
||||||
|
|
||||||
|
internal val isIronShulkersLoaded by lazy {
|
||||||
|
ModList.get().isLoaded(IronShulkerBoxes.MODID)
|
||||||
|
}
|
||||||
|
|
||||||
|
object IronShulkersMenuTypes {
|
||||||
|
private val registrar = MDeferredRegister(Registries.MENU, OverdriveThatMatters.MOD_ID)
|
||||||
|
|
||||||
|
val IRON by registrar.register("ironshulkerbox_iron") { MenuType(MatteryIronShulkerBoxMenu::iron, FeatureFlags.VANILLA_SET) }
|
||||||
|
val GOLD by registrar.register("ironshulkerbox_gold") { MenuType(MatteryIronShulkerBoxMenu::gold, FeatureFlags.VANILLA_SET) }
|
||||||
|
val DIAMOND by registrar.register("ironshulkerbox_diamond") { MenuType(MatteryIronShulkerBoxMenu::diamond, FeatureFlags.VANILLA_SET) }
|
||||||
|
val COPPER by registrar.register("ironshulkerbox_copper") { MenuType(MatteryIronShulkerBoxMenu::copper, FeatureFlags.VANILLA_SET) }
|
||||||
|
val CRYSTAL by registrar.register("ironshulkerbox_crystal") { MenuType(MatteryIronShulkerBoxMenu::crystal, FeatureFlags.VANILLA_SET) }
|
||||||
|
val OBSIDIAN by registrar.register("ironshulkerbox_obsidian") { MenuType(MatteryIronShulkerBoxMenu::obsidian, FeatureFlags.VANILLA_SET) }
|
||||||
|
|
||||||
|
private fun provider(level: Level, pos: BlockPos, state: BlockState, blockEntity: BlockEntity?, context: Void?): IQuickStackContainer? {
|
||||||
|
val container = blockEntity as? Container ?: return null
|
||||||
|
return IQuickStackContainer.Simple(makeSlots(container, ::Slot))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun registerCapabilities(event: RegisterCapabilitiesEvent) {
|
||||||
|
val colors = DyeColor.entries.toMutableList<DyeColor?>().also { it.add(0, null) }
|
||||||
|
|
||||||
|
IronShulkerBoxesTypes.entries.forEach { type ->
|
||||||
|
event.registerBlock(MatteryCapability.QUICK_STACK_CONTAINER, ::provider, *colors.map { IronShulkerBoxesTypes.get(type, it) }.toTypedArray())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun register(bus: IEventBus) {
|
||||||
|
registrar.register(bus)
|
||||||
|
bus.addListener(this::registerScreens)
|
||||||
|
bus.addListener(this::registerCapabilities)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerScreens(event: RegisterMenuScreensEvent) {
|
||||||
|
event.register(IRON, ::VanillaChestScreen)
|
||||||
|
event.register(GOLD, ::VanillaChestScreen)
|
||||||
|
event.register(DIAMOND, ::VanillaChestScreen)
|
||||||
|
event.register(COPPER, ::VanillaChestScreen)
|
||||||
|
event.register(CRYSTAL, ::VanillaChestScreen)
|
||||||
|
event.register(OBSIDIAN, ::VanillaChestScreen)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.compat.ironshulkerbox
|
||||||
|
|
||||||
|
import com.progwml6.ironshulkerbox.common.block.IronShulkerBoxesTypes
|
||||||
|
import net.minecraft.world.Container
|
||||||
|
import net.minecraft.world.SimpleContainer
|
||||||
|
import net.minecraft.world.entity.player.Inventory
|
||||||
|
import net.minecraft.world.inventory.MenuType
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import ru.dbotthepony.mc.otm.compat.vanilla.AbstractVanillaChestMenu
|
||||||
|
import ru.dbotthepony.mc.otm.container.EnhancedContainer
|
||||||
|
import ru.dbotthepony.mc.otm.menu.MatteryMenuSlot
|
||||||
|
import ru.dbotthepony.mc.otm.menu.QuickMoveInput
|
||||||
|
import ru.dbotthepony.mc.otm.menu.makeSlots
|
||||||
|
|
||||||
|
class MatteryIronShulkerBoxMenu(
|
||||||
|
type: MenuType<*>, containerId: Int,
|
||||||
|
inventory: Inventory, boxType: IronShulkerBoxesTypes,
|
||||||
|
container: Container = EnhancedContainer.Simple(boxType.size)
|
||||||
|
) : AbstractVanillaChestMenu(type, containerId, inventory, container) {
|
||||||
|
override val rows: Int = boxType.size / boxType.rowLength
|
||||||
|
override val columns: Int = boxType.rowLength
|
||||||
|
|
||||||
|
override val containerSlots = makeSlots(container, ::Slot)
|
||||||
|
|
||||||
|
init {
|
||||||
|
container.startOpen(player)
|
||||||
|
addStorageSlot(containerSlots)
|
||||||
|
addInventorySlots()
|
||||||
|
}
|
||||||
|
|
||||||
|
override val quickMoveToStorage = QuickMoveInput.create(this, playerCombinedInventorySlots, containerSlots)
|
||||||
|
override val quickMoveFromStorage = QuickMoveInput.create(this, containerSlots, playerInventorySlots, false)
|
||||||
|
|
||||||
|
class Slot(container: Container, slot: Int) : MatteryMenuSlot(container, slot) {
|
||||||
|
override fun mayPlace(stack: ItemStack): Boolean {
|
||||||
|
return super.mayPlace(stack) && stack.item.canFitInsideContainerItems()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun iron(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(IronShulkerBoxesTypes.IRON.size), boxType: IronShulkerBoxesTypes = IronShulkerBoxesTypes.IRON): MatteryIronShulkerBoxMenu {
|
||||||
|
return MatteryIronShulkerBoxMenu(IronShulkersMenuTypes.IRON, containerId, inventory, boxType, container)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun gold(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(IronShulkerBoxesTypes.GOLD.size), boxType: IronShulkerBoxesTypes = IronShulkerBoxesTypes.GOLD): MatteryIronShulkerBoxMenu {
|
||||||
|
return MatteryIronShulkerBoxMenu(IronShulkersMenuTypes.GOLD, containerId, inventory, boxType, container)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun diamond(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(IronShulkerBoxesTypes.DIAMOND.size), boxType: IronShulkerBoxesTypes = IronShulkerBoxesTypes.DIAMOND): MatteryIronShulkerBoxMenu {
|
||||||
|
return MatteryIronShulkerBoxMenu(IronShulkersMenuTypes.DIAMOND, containerId, inventory, boxType, container)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun copper(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(IronShulkerBoxesTypes.COPPER.size), boxType: IronShulkerBoxesTypes = IronShulkerBoxesTypes.COPPER): MatteryIronShulkerBoxMenu {
|
||||||
|
return MatteryIronShulkerBoxMenu(IronShulkersMenuTypes.COPPER, containerId, inventory, boxType, container)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun crystal(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(IronShulkerBoxesTypes.CRYSTAL.size), boxType: IronShulkerBoxesTypes = IronShulkerBoxesTypes.CRYSTAL): MatteryIronShulkerBoxMenu {
|
||||||
|
return MatteryIronShulkerBoxMenu(IronShulkersMenuTypes.CRYSTAL, containerId, inventory, boxType, container)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun obsidian(containerId: Int, inventory: Inventory, container: Container = SimpleContainer(IronShulkerBoxesTypes.OBSIDIAN.size), boxType: IronShulkerBoxesTypes = IronShulkerBoxesTypes.OBSIDIAN): MatteryIronShulkerBoxMenu {
|
||||||
|
return MatteryIronShulkerBoxMenu(IronShulkersMenuTypes.OBSIDIAN, containerId, inventory, boxType, container)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,7 @@ import net.minecraft.world.inventory.Slot
|
|||||||
import net.neoforged.fml.ModList
|
import net.neoforged.fml.ModList
|
||||||
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
|
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
|
||||||
|
|
||||||
val isItemBordersLoaded by lazy {
|
internal val isItemBordersLoaded by lazy {
|
||||||
ModList.get().isLoaded("itemborders")
|
ModList.get().isLoaded("itemborders")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,6 +163,13 @@ class MatterDustItem : Item(Properties().stacksTo(64)), IMatterItem {
|
|||||||
return matter(stack) >= ItemsConfig.MATTER_DUST_CAPACITY
|
return matter(stack) >= ItemsConfig.MATTER_DUST_CAPACITY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun makeStack(matterValue: Decimal = Decimal.ONE, count: Int = 1): ItemStack {
|
||||||
|
val stack = ItemStack(this, count)
|
||||||
|
matter(stack, matterValue)
|
||||||
|
|
||||||
|
return stack
|
||||||
|
}
|
||||||
|
|
||||||
override fun overrideStackedOnOther(
|
override fun overrideStackedOnOther(
|
||||||
pStack: ItemStack,
|
pStack: ItemStack,
|
||||||
pSlot: Slot,
|
pSlot: Slot,
|
||||||
|
@ -189,6 +189,35 @@ interface MatteryStreamCodec<in S : ByteBuf, V> : StreamCodec<@UnsafeVariance S,
|
|||||||
val values: List<V> = listOf(*this.clazz.enumConstants!!)
|
val values: List<V> = listOf(*this.clazz.enumConstants!!)
|
||||||
val valuesMap = values.associateBy { it.name }
|
val valuesMap = values.associateBy { it.name }
|
||||||
|
|
||||||
|
private val nullable = object : MatteryStreamCodec<S, V?> {
|
||||||
|
override fun decode(stream: S): V? {
|
||||||
|
val value = stream.readVarInt()
|
||||||
|
|
||||||
|
if (value == 0) {
|
||||||
|
return null
|
||||||
|
} else {
|
||||||
|
val id = value ushr 1
|
||||||
|
return values.getOrNull(id) ?: throw NoSuchElementException("No such enum with index $id")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun encode(stream: S, value: V?) {
|
||||||
|
if (value == null) {
|
||||||
|
stream.writeVarInt(0)
|
||||||
|
} else {
|
||||||
|
stream.writeVarInt(1 or (value.ordinal shl 1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun copy(value: V?): V? {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun compare(a: V?, b: V?): Boolean {
|
||||||
|
return a === b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun decode(stream: S): V {
|
override fun decode(stream: S): V {
|
||||||
val id = stream.readVarInt()
|
val id = stream.readVarInt()
|
||||||
return values.getOrNull(id) ?: throw NoSuchElementException("No such enum with index $id")
|
return values.getOrNull(id) ?: throw NoSuchElementException("No such enum with index $id")
|
||||||
@ -206,6 +235,10 @@ interface MatteryStreamCodec<in S : ByteBuf, V> : StreamCodec<@UnsafeVariance S,
|
|||||||
return a === b
|
return a === b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun nullable(): MatteryStreamCodec<S, V?> {
|
||||||
|
return nullable
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/**
|
/**
|
||||||
* FIXME: enums with abstract methods which get compiled to subclasses, whose DO NOT expose "parent's" enum constants array
|
* FIXME: enums with abstract methods which get compiled to subclasses, whose DO NOT expose "parent's" enum constants array
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package ru.dbotthepony.mc.otm.network
|
package ru.dbotthepony.mc.otm.network
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf
|
import io.netty.buffer.ByteBuf
|
||||||
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.core.UUIDUtil
|
import net.minecraft.core.UUIDUtil
|
||||||
import net.minecraft.network.FriendlyByteBuf
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
import net.minecraft.network.codec.ByteBufCodecs
|
import net.minecraft.network.codec.ByteBufCodecs
|
||||||
@ -10,6 +11,7 @@ import net.minecraft.world.level.block.Block
|
|||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import ru.dbotthepony.kommons.math.RGBAColor
|
import ru.dbotthepony.kommons.math.RGBAColor
|
||||||
import ru.dbotthepony.mc.otm.container.ItemFilter
|
import ru.dbotthepony.mc.otm.container.ItemFilter
|
||||||
|
import ru.dbotthepony.mc.otm.util.math.RelativeSide
|
||||||
import ru.dbotthepony.mc.otm.util.readDecimal
|
import ru.dbotthepony.mc.otm.util.readDecimal
|
||||||
import ru.dbotthepony.mc.otm.util.writeDecimal
|
import ru.dbotthepony.mc.otm.util.writeDecimal
|
||||||
import ru.dbotthepony.mc.otm.util.readBlockType
|
import ru.dbotthepony.mc.otm.util.readBlockType
|
||||||
@ -35,6 +37,10 @@ object StreamCodecs {
|
|||||||
val RESOURCE_LOCATION = ResourceLocation.STREAM_CODEC.wrap()
|
val RESOURCE_LOCATION = ResourceLocation.STREAM_CODEC.wrap()
|
||||||
val BLOCK_STATE: MatteryStreamCodec<ByteBuf, BlockState> = ByteBufCodecs.idMapper(Block.BLOCK_STATE_REGISTRY).wrap()
|
val BLOCK_STATE: MatteryStreamCodec<ByteBuf, BlockState> = ByteBufCodecs.idMapper(Block.BLOCK_STATE_REGISTRY).wrap()
|
||||||
val BLOCK_TYPE = MatteryStreamCodec.Of(FriendlyByteBuf::writeBlockType, FriendlyByteBuf::readBlockType)
|
val BLOCK_TYPE = MatteryStreamCodec.Of(FriendlyByteBuf::writeBlockType, FriendlyByteBuf::readBlockType)
|
||||||
|
val RELATIVE_SIDE = MatteryStreamCodec.Enum<FriendlyByteBuf, RelativeSide>(RelativeSide::class.java)
|
||||||
|
val DIRECTION = MatteryStreamCodec.Enum<FriendlyByteBuf, Direction>(Direction::class.java)
|
||||||
|
val RELATIVE_SIDE_NULLABLE = RELATIVE_SIDE.nullable()
|
||||||
|
val DIRECTION_NULLABLE = DIRECTION.nullable()
|
||||||
|
|
||||||
val RGBA: MatteryStreamCodec<ByteBuf, RGBAColor> = StreamCodec.of<ByteBuf, RGBAColor>(
|
val RGBA: MatteryStreamCodec<ByteBuf, RGBAColor> = StreamCodec.of<ByteBuf, RGBAColor>(
|
||||||
{ s, v -> s.writeFloat(v.red); s.writeFloat(v.green); s.writeFloat(v.blue); s.writeFloat(v.alpha) },
|
{ s, v -> s.writeFloat(v.red); s.writeFloat(v.green); s.writeFloat(v.blue); s.writeFloat(v.alpha) },
|
||||||
|
@ -1,8 +1,19 @@
|
|||||||
package ru.dbotthepony.mc.otm.network.syncher
|
package ru.dbotthepony.mc.otm.network.syncher
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ReferenceLinkedOpenHashMap
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap
|
||||||
import it.unimi.dsi.fastutil.ints.IntArraySet
|
import it.unimi.dsi.fastutil.ints.IntArraySet
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntCollection
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntIterator
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntSet
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectIterator
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectSet
|
||||||
|
import it.unimi.dsi.fastutil.objects.Reference2ObjectLinkedOpenHashMap
|
||||||
|
import it.unimi.dsi.fastutil.objects.ReferenceCollection
|
||||||
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet
|
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet
|
||||||
|
import it.unimi.dsi.fastutil.objects.ReferenceSet
|
||||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||||
import ru.dbotthepony.kommons.util.KOptional
|
import ru.dbotthepony.kommons.util.KOptional
|
||||||
import ru.dbotthepony.mc.otm.util.IDAllocator
|
import ru.dbotthepony.mc.otm.util.IDAllocator
|
||||||
@ -10,29 +21,39 @@ import java.io.Closeable
|
|||||||
import java.util.concurrent.ConcurrentLinkedQueue
|
import java.util.concurrent.ConcurrentLinkedQueue
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new [DynamicSynchableGroup] where [T] is itself an [ISynchable]
|
||||||
|
*/
|
||||||
|
fun <T : ISynchable> DynamicSynchableGroup(reader: RegistryFriendlyByteBuf.() -> T, writer: T.(RegistryFriendlyByteBuf) -> Unit): DynamicSynchableGroup<T> {
|
||||||
|
return DynamicSynchableGroup(reader, { this }, writer)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Syncher group/set, which deals with synchables of only one type, and which are created and removed
|
* Syncher group/set, which deals with synchables of only one type, and which are created and removed
|
||||||
* on remote (e.g. server adding and removing synchables at will), which makes it distinct from
|
* on remote (e.g. server adding and removing synchables at will), which makes it distinct from
|
||||||
* [SynchableGroup], in which attached synchables are created/removed manually on both sides.
|
* [SynchableGroup], in which attached synchables are created/removed manually on both sides.
|
||||||
*/
|
*/
|
||||||
class DynamicSynchableGroup<T : ISynchable>(
|
class DynamicSynchableGroup<T : Any>(
|
||||||
/**
|
/**
|
||||||
* Constructs new [T] instance locally, when remote created one.
|
* Constructs new [T] instance locally, when remote created one.
|
||||||
* Data written by [writer] must be read here, if there is any.
|
* Data written by [writer] must be read here, if there is any.
|
||||||
*/
|
*/
|
||||||
private val reader: RegistryFriendlyByteBuf.() -> T,
|
private val reader: RegistryFriendlyByteBuf.() -> T,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an [ISynchable] out of value [T] for synching state
|
||||||
|
*/
|
||||||
|
private val synchable: T.() -> ISynchable,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows to write additional data to network stream during
|
* Allows to write additional data to network stream during
|
||||||
* first-time networking of [T] to remote
|
* first-time networking of [T] to remote
|
||||||
*/
|
*/
|
||||||
private val writer: T.(RegistryFriendlyByteBuf) -> Unit = {}
|
private val writer: T.(RegistryFriendlyByteBuf) -> Unit = {},
|
||||||
) : ISynchable, MutableSet<T> {
|
) : ISynchable, ReferenceSet<T> {
|
||||||
constructor(factory: () -> T) : this({ factory() }, {})
|
|
||||||
|
|
||||||
private inner class RemoteState(val listener: Runnable) : IRemoteState {
|
private inner class RemoteState(val listener: Runnable) : IRemoteState {
|
||||||
private inner class RemoteSlot(val slot: Slot<T>, fromConstructor: Boolean) : Runnable, Closeable {
|
private inner class RemoteSlot(val slot: Slot<T>, fromConstructor: Boolean) : Runnable, Closeable {
|
||||||
val remoteState = slot.synchable.createRemoteState(this)
|
val remoteState = synchable(slot.value).createRemoteState(this)
|
||||||
val isDirty = AtomicBoolean(true)
|
val isDirty = AtomicBoolean(true)
|
||||||
var isRemoved = false
|
var isRemoved = false
|
||||||
private set
|
private set
|
||||||
@ -91,6 +112,7 @@ class DynamicSynchableGroup<T : ISynchable>(
|
|||||||
checkNotNull(removed)
|
checkNotNull(removed)
|
||||||
check(removed.slot == element)
|
check(removed.slot == element)
|
||||||
removed.close()
|
removed.close()
|
||||||
|
removals.add(element.id)
|
||||||
listener.run()
|
listener.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +136,7 @@ class DynamicSynchableGroup<T : ISynchable>(
|
|||||||
firstTime.forEach {
|
firstTime.forEach {
|
||||||
stream.writeByte(ADD_ENTRY)
|
stream.writeByte(ADD_ENTRY)
|
||||||
stream.writeVarInt(it.slot.id)
|
stream.writeVarInt(it.slot.id)
|
||||||
writer(it.slot.synchable, stream)
|
writer(it.slot.value, stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
firstTime.clear()
|
firstTime.clear()
|
||||||
@ -177,11 +199,12 @@ class DynamicSynchableGroup<T : ISynchable>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class Slot<T : Any>(val synchable: T, val id: Int)
|
private class Slot<T : Any>(val value: T, val id: Int)
|
||||||
|
|
||||||
|
private var defaultReturnValue: T? = null
|
||||||
private val remoteStates = ArrayList<RemoteState>()
|
private val remoteStates = ArrayList<RemoteState>()
|
||||||
private val value2slot = HashMap<T, Slot<T>>()
|
private val value2slot = Reference2ObjectLinkedOpenHashMap<T, Slot<T>>()
|
||||||
private val id2slot = Int2ObjectOpenHashMap<Slot<T>>()
|
private val id2slot = Int2ReferenceLinkedOpenHashMap<Slot<T>>()
|
||||||
private val idAllocator = IDAllocator()
|
private val idAllocator = IDAllocator()
|
||||||
|
|
||||||
override val hasRemotes: Boolean
|
override val hasRemotes: Boolean
|
||||||
@ -199,7 +222,7 @@ class DynamicSynchableGroup<T : ISynchable>(
|
|||||||
REMOVE_ENTRY -> {
|
REMOVE_ENTRY -> {
|
||||||
val id = stream.readVarInt()
|
val id = stream.readVarInt()
|
||||||
val slot = checkNotNull(id2slot.remove(id)) { "No such slot with ID: $id" }
|
val slot = checkNotNull(id2slot.remove(id)) { "No such slot with ID: $id" }
|
||||||
check(value2slot.remove(slot.synchable) == value2slot)
|
check(value2slot.remove(slot.value) == slot)
|
||||||
remoteStates.forEach { it.remove(slot) }
|
remoteStates.forEach { it.remove(slot) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +235,7 @@ class DynamicSynchableGroup<T : ISynchable>(
|
|||||||
|
|
||||||
if (id2slot.containsKey(id)) {
|
if (id2slot.containsKey(id)) {
|
||||||
val slot = id2slot.remove(id)!!
|
val slot = id2slot.remove(id)!!
|
||||||
check(value2slot.remove(slot.synchable) == value2slot)
|
check(value2slot.remove(slot.value) == slot)
|
||||||
remoteStates.forEach { it.remove(slot) }
|
remoteStates.forEach { it.remove(slot) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,7 +248,7 @@ class DynamicSynchableGroup<T : ISynchable>(
|
|||||||
SYNC_ENTRY -> {
|
SYNC_ENTRY -> {
|
||||||
val id = stream.readVarInt()
|
val id = stream.readVarInt()
|
||||||
val slot = checkNotNull(id2slot.get(id)) { "No such slot with ID: $id" }
|
val slot = checkNotNull(id2slot.get(id)) { "No such slot with ID: $id" }
|
||||||
slot.synchable.read(stream)
|
synchable(slot.value).read(stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
CLEAR -> {
|
CLEAR -> {
|
||||||
@ -287,8 +310,8 @@ class DynamicSynchableGroup<T : ISynchable>(
|
|||||||
return value2slot.isEmpty()
|
return value2slot.isEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun iterator(): MutableIterator<T> {
|
override fun iterator(): ObjectIterator<T> {
|
||||||
return object : MutableIterator<T> {
|
return object : ObjectIterator<T> {
|
||||||
private val parent = value2slot.values.iterator()
|
private val parent = value2slot.values.iterator()
|
||||||
private var last: KOptional<Slot<T>> = KOptional()
|
private var last: KOptional<Slot<T>> = KOptional()
|
||||||
|
|
||||||
@ -299,7 +322,7 @@ class DynamicSynchableGroup<T : ISynchable>(
|
|||||||
override fun next(): T {
|
override fun next(): T {
|
||||||
val slot = parent.next()
|
val slot = parent.next()
|
||||||
last = KOptional(slot)
|
last = KOptional(slot)
|
||||||
return slot.synchable
|
return slot.value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun remove() {
|
override fun remove() {
|
||||||
@ -312,15 +335,15 @@ class DynamicSynchableGroup<T : ISynchable>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun remove(element: T): Boolean {
|
private fun removeBySlot(slot: Slot<T>) {
|
||||||
if (element !in value2slot) {
|
value2slot.remove(slot.value)
|
||||||
return false
|
id2slot.remove(slot.id)
|
||||||
}
|
|
||||||
|
|
||||||
val slot = value2slot.remove(element)!!
|
|
||||||
checkNotNull(id2slot.remove(slot.id))
|
|
||||||
remoteStates.forEach { it.remove(slot) }
|
remoteStates.forEach { it.remove(slot) }
|
||||||
idAllocator.release(slot.id)
|
idAllocator.release(slot.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove(element: T): Boolean {
|
||||||
|
removeBySlot(value2slot.remove(element) ?: return false)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,6 +367,341 @@ class DynamicSynchableGroup<T : ISynchable>(
|
|||||||
return any
|
return any
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Representation of this synchable group as an [Int2ReferenceMap]. Changes made to [DynamicSynchableGroup] are reflected in this map
|
||||||
|
* and vice versa. Entries can be put at arbitrary keys, but negative keys should be avoided, since they are not efficiently
|
||||||
|
* networked, and hence will create a lot of network traffic if synchables with negative keys get frequently updated.
|
||||||
|
*/
|
||||||
|
val asMap: Int2ReferenceMap<T> by lazy {
|
||||||
|
object : Int2ReferenceMap<T> {
|
||||||
|
override fun isEmpty(): Boolean {
|
||||||
|
return this@DynamicSynchableGroup.isEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove(key: Int): T? {
|
||||||
|
val slot = id2slot.remove(key) ?: return null
|
||||||
|
removeBySlot(slot)
|
||||||
|
return slot.value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getOrDefault(key: Int, defaultValue: T): T {
|
||||||
|
return super.getOrDefault(key, defaultValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val size: Int
|
||||||
|
get() = this@DynamicSynchableGroup.size
|
||||||
|
|
||||||
|
override fun put(key: Int, value: T): T? {
|
||||||
|
val slot = Slot(value, key)
|
||||||
|
val oldSlot = id2slot.put(key, slot)
|
||||||
|
|
||||||
|
if (oldSlot?.value === value)
|
||||||
|
return value
|
||||||
|
|
||||||
|
if (oldSlot != null) {
|
||||||
|
remoteStates.forEach { it.remove(oldSlot) }
|
||||||
|
value2slot.remove(oldSlot.value)
|
||||||
|
} else {
|
||||||
|
idAllocator.allocate(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
value2slot[value] = slot
|
||||||
|
remoteStates.forEach { it.add(slot) }
|
||||||
|
|
||||||
|
return oldSlot?.value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun get(key: Int): T? {
|
||||||
|
return id2slot.get(key)?.value ?: defaultReturnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun containsKey(key: Int): Boolean {
|
||||||
|
return id2slot.containsKey(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun defaultReturnValue(rv: T?) {
|
||||||
|
defaultReturnValue = rv
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun defaultReturnValue(): T? {
|
||||||
|
return defaultReturnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun putAll(from: Map<out Int, T>) {
|
||||||
|
from.forEach { (k, v) ->
|
||||||
|
put(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun containsValue(value: T): Boolean {
|
||||||
|
return value2slot.containsKey(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val entrySet: ObjectSet<Int2ReferenceMap.Entry<T>> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||||
|
object : ObjectSet<Int2ReferenceMap.Entry<T>> {
|
||||||
|
inner class Entry(private val ikey: Int) : Int2ReferenceMap.Entry<T> {
|
||||||
|
override val value: T
|
||||||
|
get() = id2slot[ikey]?.value ?: throw NoSuchElementException()
|
||||||
|
|
||||||
|
override fun setValue(newValue: T): T? {
|
||||||
|
return put(ikey, newValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getIntKey(): Int {
|
||||||
|
return ikey
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
return this === other || other is Int2ReferenceMap.Entry<*> && other.intKey == ikey && other.value === id2slot[ikey]?.value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return ikey * 31 + (id2slot[ikey] as Slot<T>?).hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "Map.Entry[$ikey, ${id2slot[ikey]?.value}]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val size: Int
|
||||||
|
get() = id2slot.size
|
||||||
|
|
||||||
|
override fun add(element: Int2ReferenceMap.Entry<T>): Boolean {
|
||||||
|
return put(element.intKey, element.value) != null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addAll(elements: Collection<Int2ReferenceMap.Entry<T>>): Boolean {
|
||||||
|
var any = false
|
||||||
|
elements.forEach { any = add(it) || any }
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun clear() {
|
||||||
|
this@DynamicSynchableGroup.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun iterator(): ObjectIterator<Int2ReferenceMap.Entry<T>> {
|
||||||
|
return object : ObjectIterator<Int2ReferenceMap.Entry<T>> {
|
||||||
|
private val parent = id2slot.int2ReferenceEntrySet().iterator()
|
||||||
|
private var last: Slot<T>? = null
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean {
|
||||||
|
return parent.hasNext()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove() {
|
||||||
|
if (last == null)
|
||||||
|
throw NoSuchElementException()
|
||||||
|
|
||||||
|
parent.remove()
|
||||||
|
removeBySlot(last!!)
|
||||||
|
last = null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): Int2ReferenceMap.Entry<T> {
|
||||||
|
val value = parent.next()
|
||||||
|
last = value.value
|
||||||
|
return Entry(value.intKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove(element: Int2ReferenceMap.Entry<T>): Boolean {
|
||||||
|
val slot = id2slot.get(element.intKey)
|
||||||
|
|
||||||
|
if (slot?.value === element.value) {
|
||||||
|
this@DynamicSynchableGroup.removeBySlot(slot)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun removeAll(elements: Collection<Int2ReferenceMap.Entry<T>>): Boolean {
|
||||||
|
var any = false
|
||||||
|
elements.forEach { any = remove(it) || any }
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun retainAll(elements: Collection<Int2ReferenceMap.Entry<T>>): Boolean {
|
||||||
|
if (elements.isEmpty()) {
|
||||||
|
val isNotEmpty = id2slot.isNotEmpty()
|
||||||
|
this@DynamicSynchableGroup.clear()
|
||||||
|
return isNotEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
var any = false
|
||||||
|
val itr = id2slot.int2ReferenceEntrySet().iterator()
|
||||||
|
|
||||||
|
for (entry in itr) {
|
||||||
|
if (elements.none { it.intKey == entry.intKey && it.value === entry.value.value }) {
|
||||||
|
any = true
|
||||||
|
itr.remove()
|
||||||
|
removeBySlot(entry.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun contains(element: Int2ReferenceMap.Entry<T>): Boolean {
|
||||||
|
return id2slot.get(element.intKey)?.value === element.value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun containsAll(elements: Collection<Int2ReferenceMap.Entry<T>>): Boolean {
|
||||||
|
return elements.all { contains(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isEmpty(): Boolean {
|
||||||
|
return id2slot.isEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun int2ReferenceEntrySet(): ObjectSet<Int2ReferenceMap.Entry<T>> {
|
||||||
|
return entrySet
|
||||||
|
}
|
||||||
|
|
||||||
|
override val keys: IntSet by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||||
|
object : IntSet {
|
||||||
|
override fun add(key: Int): Boolean {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addAll(c: IntCollection): Boolean {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addAll(elements: Collection<Int>): Boolean {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun clear() {
|
||||||
|
this@DynamicSynchableGroup.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun iterator(): IntIterator {
|
||||||
|
return object : IntIterator {
|
||||||
|
private val parent = id2slot.keys.iterator()
|
||||||
|
private var last = -1
|
||||||
|
private var hasLast = false
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean {
|
||||||
|
return parent.hasNext()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove() {
|
||||||
|
if (!hasLast)
|
||||||
|
throw NoSuchElementException()
|
||||||
|
|
||||||
|
hasLast = false
|
||||||
|
val slot = id2slot.get(last)
|
||||||
|
parent.remove()
|
||||||
|
removeBySlot(slot)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextInt(): Int {
|
||||||
|
last = parent.nextInt()
|
||||||
|
hasLast = true
|
||||||
|
return last
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove(k: Int): Boolean {
|
||||||
|
removeBySlot(id2slot.get(k) ?: return false)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun removeAll(c: IntCollection): Boolean {
|
||||||
|
val itr = c.iterator()
|
||||||
|
var any = false
|
||||||
|
|
||||||
|
while (itr.hasNext()) {
|
||||||
|
any = remove(itr.nextInt()) || any
|
||||||
|
}
|
||||||
|
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun removeAll(elements: Collection<Int>): Boolean {
|
||||||
|
val itr = elements.iterator()
|
||||||
|
var any = false
|
||||||
|
|
||||||
|
while (itr.hasNext()) {
|
||||||
|
any = remove(itr.next()) || any
|
||||||
|
}
|
||||||
|
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun retainAll(c: IntCollection): Boolean {
|
||||||
|
val itr = id2slot.values.iterator()
|
||||||
|
var any = false
|
||||||
|
|
||||||
|
for (slot in itr) {
|
||||||
|
if (!c.contains(slot.id)) {
|
||||||
|
itr.remove()
|
||||||
|
check(value2slot.remove(slot.value) == slot)
|
||||||
|
remoteStates.forEach { it.remove(slot) }
|
||||||
|
any = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun retainAll(elements: Collection<Int>): Boolean {
|
||||||
|
val itr = id2slot.values.iterator()
|
||||||
|
var any = false
|
||||||
|
|
||||||
|
for (slot in itr) {
|
||||||
|
if (!elements.contains(slot.id)) {
|
||||||
|
itr.remove()
|
||||||
|
check(value2slot.remove(slot.value) == slot)
|
||||||
|
remoteStates.forEach { it.remove(slot) }
|
||||||
|
any = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return any
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun contains(key: Int): Boolean {
|
||||||
|
return id2slot.containsKey(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun containsAll(c: IntCollection): Boolean {
|
||||||
|
return id2slot.keys.containsAll(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun containsAll(elements: Collection<Int>): Boolean {
|
||||||
|
return id2slot.keys.containsAll(elements)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isEmpty(): Boolean {
|
||||||
|
return id2slot.isEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toArray(a: IntArray?): IntArray {
|
||||||
|
return id2slot.keys.toArray(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toIntArray(): IntArray {
|
||||||
|
return id2slot.keys.toIntArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
override val size: Int
|
||||||
|
get() = id2slot.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val values: ReferenceCollection<T>
|
||||||
|
get() = this@DynamicSynchableGroup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val END = 0
|
private const val END = 0
|
||||||
private const val ADD_ENTRY = 1
|
private const val ADD_ENTRY = 1
|
||||||
|
@ -36,6 +36,7 @@ import ru.dbotthepony.mc.otm.block.decorative.CargoCrateBlock
|
|||||||
import ru.dbotthepony.mc.otm.block.decorative.ComputerTerminalBlock
|
import ru.dbotthepony.mc.otm.block.decorative.ComputerTerminalBlock
|
||||||
import ru.dbotthepony.mc.otm.block.decorative.StarChairBlock
|
import ru.dbotthepony.mc.otm.block.decorative.StarChairBlock
|
||||||
import ru.dbotthepony.mc.otm.block.decorative.TritaniumPressurePlate
|
import ru.dbotthepony.mc.otm.block.decorative.TritaniumPressurePlate
|
||||||
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.matteryEnergy
|
import ru.dbotthepony.mc.otm.capability.matteryEnergy
|
||||||
import ru.dbotthepony.mc.otm.client.MatteryGUI
|
import ru.dbotthepony.mc.otm.client.MatteryGUI
|
||||||
import ru.dbotthepony.mc.otm.util.ResourceLocation
|
import ru.dbotthepony.mc.otm.util.ResourceLocation
|
||||||
@ -317,6 +318,21 @@ object MRegistry : IBlockItemRegistryAcceptor {
|
|||||||
val tag = stack.getOrDefault(MDataComponentTypes.Configurator.CONFIGURATION, CompoundTag())
|
val tag = stack.getOrDefault(MDataComponentTypes.Configurator.CONFIGURATION, CompoundTag())
|
||||||
if (tag.isEmpty) 0f else 1f
|
if (tag.isEmpty) 0f else 1f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (item in MItems.MATTER_CAPACITORS) {
|
||||||
|
ItemProperties.register(item, ResourceLocation(OverdriveThatMatters.MOD_ID, "capacitor_gauge")) { stack, _, _, _ ->
|
||||||
|
val cap = stack.getCapability(MatteryCapability.MATTER_ITEM) ?: return@register 1f
|
||||||
|
(cap.storedMatter / cap.maxStoredMatter).toFloat()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (item in MItems.ALL_BATTERIES.toMutableList().also { it.add(MItems.PROCEDURAL_BATTERY) }) {
|
||||||
|
ItemProperties.register(item, ResourceLocation(OverdriveThatMatters.MOD_ID, "capacitor_gauge")) { stack, _, _, _ ->
|
||||||
|
val energy = stack.matteryEnergy ?: return@register 1f
|
||||||
|
|
||||||
|
(energy.batteryLevel / energy.maxBatteryLevel).toFloat()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ private fun addMainCreativeTabItems(consumer: CreativeModeTab.Output) {
|
|||||||
|
|
||||||
accept(MItems.GRILL.values)
|
accept(MItems.GRILL.values)
|
||||||
|
|
||||||
// accept(MItems.MATTER_DUST)
|
accept(MItems.MATTER_DUST.makeStack())
|
||||||
|
|
||||||
accept(MItems.TRITANIUM_ORE)
|
accept(MItems.TRITANIUM_ORE)
|
||||||
accept(MItems.DEEPSLATE_TRITANIUM_ORE)
|
accept(MItems.DEEPSLATE_TRITANIUM_ORE)
|
||||||
|
@ -1,37 +1,58 @@
|
|||||||
package ru.dbotthepony.mc.otm.util
|
package ru.dbotthepony.mc.otm.util
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntAVLTreeSet
|
import it.unimi.dsi.fastutil.ints.IntRBTreeSet
|
||||||
|
|
||||||
class IDAllocator {
|
class IDAllocator {
|
||||||
private var highestID = 0
|
private var nextID = -1
|
||||||
private val gaps = IntAVLTreeSet()
|
private val gaps = IntRBTreeSet()
|
||||||
|
private val sparseAllocations = IntRBTreeSet()
|
||||||
|
|
||||||
|
private fun increaseHighestID(): Int {
|
||||||
|
while (sparseAllocations.remove(++nextID)) {}
|
||||||
|
return nextID
|
||||||
|
}
|
||||||
|
|
||||||
fun allocate(): Int {
|
fun allocate(): Int {
|
||||||
if (gaps.isEmpty()) {
|
if (gaps.isEmpty()) {
|
||||||
return highestID++
|
return increaseHighestID()
|
||||||
} else {
|
} else {
|
||||||
return gaps.removeFirst()
|
return gaps.removeFirst()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun allocate(id: Int): Boolean {
|
||||||
|
if (id < 0) {
|
||||||
|
return true // not handling negative IDs
|
||||||
|
} else if (id > nextID) {
|
||||||
|
sparseAllocations.add(id)
|
||||||
|
return true
|
||||||
|
} else if (id == nextID) {
|
||||||
|
increaseHighestID()
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return gaps.remove(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun release(id: Int) {
|
fun release(id: Int) {
|
||||||
if (id >= 0) {
|
if (id < 0) {
|
||||||
throw IllegalArgumentException("Invalid ID: $id")
|
return // not handling negative IDs
|
||||||
} else if (id >= highestID) {
|
} else if (sparseAllocations.remove(id)) {
|
||||||
throw IllegalArgumentException("Not tracking ID: $id (highest known ID is ${highestID - 1})")
|
return // was allocated above highest ID
|
||||||
|
} else if (id > nextID) {
|
||||||
|
throw IllegalArgumentException("Not tracking ID: $id (highest known ID is ${nextID})")
|
||||||
} else if (id in gaps) {
|
} else if (id in gaps) {
|
||||||
throw IllegalArgumentException("ID is already free: $id")
|
throw IllegalArgumentException("ID is already free: $id")
|
||||||
}
|
} else if (id == nextID) {
|
||||||
|
nextID--
|
||||||
if (id + 1 == highestID) {
|
|
||||||
highestID--
|
|
||||||
} else {
|
} else {
|
||||||
gaps.add(id)
|
check(gaps.add(id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reset() {
|
fun reset() {
|
||||||
highestID = 0
|
nextID = -1
|
||||||
gaps.clear()
|
gaps.clear()
|
||||||
|
sparseAllocations.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,17 @@ fun IntArray.shuffle(random: RandomSource): IntArray {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T> Array<T>.shuffle(random: RandomSource): Array<T> {
|
||||||
|
for (i in lastIndex downTo 1) {
|
||||||
|
val j = random.nextInt(i + 1)
|
||||||
|
val copy = this[i]
|
||||||
|
this[i] = this[j]
|
||||||
|
this[j] = copy
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
fun <L : IntList> L.shuffle(random: RandomSource): L {
|
fun <L : IntList> L.shuffle(random: RandomSource): L {
|
||||||
for (i in lastIndex downTo 1) {
|
for (i in lastIndex downTo 1) {
|
||||||
val j = random.nextInt(i + 1)
|
val j = random.nextInt(i + 1)
|
||||||
|
@ -20,7 +20,21 @@ operator fun BlockPos.plus(other: BlockRotation): BlockPos {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum class RelativeSide(val default: Direction) {
|
enum class RelativeSide(val default: Direction) {
|
||||||
FRONT(Direction.NORTH), BACK(Direction.SOUTH), LEFT(Direction.WEST), RIGHT(Direction.EAST), TOP(Direction.UP), BOTTOM(Direction.DOWN)
|
FRONT(Direction.NORTH), BACK(Direction.SOUTH), LEFT(Direction.WEST), RIGHT(Direction.EAST), TOP(Direction.UP), BOTTOM(Direction.DOWN);
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun defaultOf(direction: Direction): RelativeSide {
|
||||||
|
return when (direction) {
|
||||||
|
Direction.DOWN -> BOTTOM
|
||||||
|
Direction.UP -> TOP
|
||||||
|
Direction.NORTH -> FRONT
|
||||||
|
Direction.SOUTH -> BACK
|
||||||
|
Direction.WEST -> LEFT
|
||||||
|
Direction.EAST -> RIGHT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"code_injector": "coremods/code_injector.js",
|
"code_injector": "coremods/code_injector.js",
|
||||||
"chest_menus": "coremods/chest_menus.js",
|
"chest_menus": "coremods/chest_menus.js",
|
||||||
"limb_brush_overclock": "coremods/limb_brush_overclock.js"
|
"limb_brush_overclock": "coremods/limb_brush_overclock.js",
|
||||||
|
"iron_chest_menus": "coremods/iron_chest_menus.js"
|
||||||
}
|
}
|
After Width: | Height: | Size: 368 B |
After Width: | Height: | Size: 376 B |
After Width: | Height: | Size: 372 B |
After Width: | Height: | Size: 377 B |
After Width: | Height: | Size: 374 B |
After Width: | Height: | Size: 374 B |
After Width: | Height: | Size: 374 B |
After Width: | Height: | Size: 374 B |
After Width: | Height: | Size: 377 B |
After Width: | Height: | Size: 373 B |
Before Width: | Height: | Size: 262 B After Width: | Height: | Size: 486 B |
After Width: | Height: | Size: 366 B |
After Width: | Height: | Size: 376 B |
After Width: | Height: | Size: 386 B |
After Width: | Height: | Size: 379 B |
After Width: | Height: | Size: 388 B |
After Width: | Height: | Size: 378 B |
After Width: | Height: | Size: 388 B |
After Width: | Height: | Size: 380 B |
After Width: | Height: | Size: 389 B |
Before Width: | Height: | Size: 484 B After Width: | Height: | Size: 471 B |
Before Width: | Height: | Size: 505 B After Width: | Height: | Size: 489 B |
Before Width: | Height: | Size: 505 B After Width: | Height: | Size: 489 B |
Before Width: | Height: | Size: 505 B After Width: | Height: | Size: 489 B |
Before Width: | Height: | Size: 508 B After Width: | Height: | Size: 494 B |
After Width: | Height: | Size: 371 B |
After Width: | Height: | Size: 384 B |
After Width: | Height: | Size: 385 B |
After Width: | Height: | Size: 398 B |
After Width: | Height: | Size: 384 B |
After Width: | Height: | Size: 397 B |
After Width: | Height: | Size: 386 B |
After Width: | Height: | Size: 397 B |
Before Width: | Height: | Size: 480 B After Width: | Height: | Size: 466 B |
Before Width: | Height: | Size: 491 B After Width: | Height: | Size: 480 B |
Before Width: | Height: | Size: 491 B After Width: | Height: | Size: 480 B |
Before Width: | Height: | Size: 491 B After Width: | Height: | Size: 480 B |
Before Width: | Height: | Size: 493 B After Width: | Height: | Size: 483 B |
Before Width: | Height: | Size: 494 B After Width: | Height: | Size: 484 B |
Before Width: | Height: | Size: 498 B After Width: | Height: | Size: 488 B |
45
src/main/resources/coremods/iron_chest_menus.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
var Opcodes = Java.type('org.objectweb.asm.Opcodes')
|
||||||
|
var MethodNode = Java.type('org.objectweb.asm.tree.MethodNode')
|
||||||
|
var VarInsnNode = Java.type('org.objectweb.asm.tree.VarInsnNode')
|
||||||
|
var MethodInsnNode = Java.type('org.objectweb.asm.tree.MethodInsnNode')
|
||||||
|
var InsnNode = Java.type('org.objectweb.asm.tree.InsnNode')
|
||||||
|
var TypeInsnNode = Java.type('org.objectweb.asm.tree.TypeInsnNode')
|
||||||
|
|
||||||
|
|
||||||
|
var isOwnPatches = [
|
||||||
|
'com.progwml6.ironchest.common.block.regular.entity.AbstractIronChestBlockEntity$1',
|
||||||
|
]
|
||||||
|
|
||||||
|
function initializeCoreMod() {
|
||||||
|
var result = {}
|
||||||
|
|
||||||
|
for (i in isOwnPatches) {
|
||||||
|
var clazz = isOwnPatches[i]
|
||||||
|
|
||||||
|
result[clazz] = {
|
||||||
|
'target': {
|
||||||
|
'type': 'METHOD',
|
||||||
|
'class': clazz,
|
||||||
|
'methodName': 'isOwnContainer',
|
||||||
|
'methodDesc': '(Lnet/minecraft/world/entity/player/Player;)Z'
|
||||||
|
},
|
||||||
|
'transformer': function(node) {
|
||||||
|
for (var i = 0; i < node.instructions.size(); i++) {
|
||||||
|
var instr = node.instructions.get(i)
|
||||||
|
|
||||||
|
if ((instr.getOpcode() == Opcodes.INSTANCEOF || instr.getOpcode() == Opcodes.CHECKCAST) && instr.desc == 'com/progwml6/ironchest/common/inventory/IronChestMenu') {
|
||||||
|
instr.desc = 'ru/dbotthepony/mc/otm/compat/ironchest/MatteryIronChestMenu'
|
||||||
|
} else if (instr.getOpcode() == Opcodes.INVOKEVIRTUAL && instr.owner == 'com/progwml6/ironchest/common/inventory/IronChestMenu' && instr.name == 'getContainer') {
|
||||||
|
instr.owner = 'ru/dbotthepony/mc/otm/compat/ironchest/MatteryIronChestMenu'
|
||||||
|
instr.name = 'getContainer'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"required": false,
|
||||||
|
"package": "ru.dbotthepony.mc.otm.mixin.ironchest",
|
||||||
|
"compatibilityLevel": "JAVA_21",
|
||||||
|
"minVersion": "0.8",
|
||||||
|
"mixins": [
|
||||||
|
"IronChestBlockEntityMixin",
|
||||||
|
"GoldChestBlockEntityMixin",
|
||||||
|
"DiamondChestBlockEntityMixin",
|
||||||
|
"CopperChestBlockEntityMixin",
|
||||||
|
"CrystalChestBlockEntityMixin",
|
||||||
|
"ObsidianChestBlockEntityMixin",
|
||||||
|
"DirtChestBlockEntityMixin",
|
||||||
|
"TrappedIronChestBlockEntityMixin",
|
||||||
|
"TrappedGoldChestBlockEntityMixin",
|
||||||
|
"TrappedDiamondChestBlockEntityMixin",
|
||||||
|
"TrappedCopperChestBlockEntityMixin",
|
||||||
|
"TrappedCrystalChestBlockEntityMixin",
|
||||||
|
"TrappedObsidianChestBlockEntityMixin",
|
||||||
|
"TrappedDirtChestBlockEntityMixin"
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"required": false,
|
||||||
|
"package": "ru.dbotthepony.mc.otm.mixin.ironshulkerbox",
|
||||||
|
"compatibilityLevel": "JAVA_21",
|
||||||
|
"minVersion": "0.8",
|
||||||
|
"mixins": [
|
||||||
|
"IronShulkerBoxBlockEntityMixin",
|
||||||
|
"GoldShulkerBoxBlockEntityMixin",
|
||||||
|
"DiamondShulkerBoxBlockEntityMixin",
|
||||||
|
"CopperShulkerBoxBlockEntityMixin",
|
||||||
|
"CrystalShulkerBoxBlockEntityMixin",
|
||||||
|
"ObsidianShulkerBoxBlockEntityMixin"
|
||||||
|
]
|
||||||
|
}
|