From fa47add8c7e0ad590db13746e4f9912b41c09ff5 Mon Sep 17 00:00:00 2001 From: MrQuentinet <32539717+mrquentin@users.noreply.github.com> Date: Sat, 20 Sep 2025 12:13:18 -0400 Subject: [PATCH 1/2] Add Logic for Wireless Cwu + Spotless --- .../blockstates/wireless_cwu_hatch.json | 28 +++ .../blockstates/wireless_cwu_transmitter.json | 76 +++++++++ .../assets/cosmiccore/lang/en_ud.json | 2 + .../assets/cosmiccore/lang/en_us.json | 2 + .../block/machine/wireless_cwu_hatch.json | 22 +++ .../machine/wireless_cwu_transmitter.json | 90 ++++++++++ .../models/item/wireless_cwu_hatch.json | 3 + .../models/item/wireless_cwu_transmitter.json | 3 + .../forge/tags/blocks/mineable/wrench.json | 42 ----- .../tags/blocks/mineable/pickaxe.json | 20 --- .../common/data/CosmicMachines.java | 31 ++++ .../armor/HelmetSanguineWarptechSuite.java | 4 +- .../multi/WirelessComputationTransmitter.java | 160 ++++++++++++++++++ ...ssComputationReceiverHatchPartMachine.java | 25 +++ .../GlobalWirelessVariableStorage.java | 1 + .../common/wireless/WirelessCwuStore.java | 87 ++++++++++ .../forge/ForgeCommonEventListener.java | 5 +- 17 files changed, 534 insertions(+), 67 deletions(-) create mode 100644 src/generated/resources/assets/cosmiccore/blockstates/wireless_cwu_hatch.json create mode 100644 src/generated/resources/assets/cosmiccore/blockstates/wireless_cwu_transmitter.json create mode 100644 src/generated/resources/assets/cosmiccore/models/block/machine/wireless_cwu_hatch.json create mode 100644 src/generated/resources/assets/cosmiccore/models/block/machine/wireless_cwu_transmitter.json create mode 100644 src/generated/resources/assets/cosmiccore/models/item/wireless_cwu_hatch.json create mode 100644 src/generated/resources/assets/cosmiccore/models/item/wireless_cwu_transmitter.json delete mode 100644 src/generated/resources/data/forge/tags/blocks/mineable/wrench.json delete mode 100644 src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json create mode 100644 src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/multi/WirelessComputationTransmitter.java create mode 100644 src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/part/WirelessComputationReceiverHatchPartMachine.java create mode 100644 src/main/java/com/ghostipedia/cosmiccore/common/wireless/WirelessCwuStore.java diff --git a/src/generated/resources/assets/cosmiccore/blockstates/wireless_cwu_hatch.json b/src/generated/resources/assets/cosmiccore/blockstates/wireless_cwu_hatch.json new file mode 100644 index 000000000..76d6cabe4 --- /dev/null +++ b/src/generated/resources/assets/cosmiccore/blockstates/wireless_cwu_hatch.json @@ -0,0 +1,28 @@ +{ + "variants": { + "facing=down": { + "model": "cosmiccore:block/machine/wireless_cwu_hatch", + "x": 90 + }, + "facing=east": { + "model": "cosmiccore:block/machine/wireless_cwu_hatch", + "y": 90 + }, + "facing=north": { + "model": "cosmiccore:block/machine/wireless_cwu_hatch" + }, + "facing=south": { + "model": "cosmiccore:block/machine/wireless_cwu_hatch", + "y": 180 + }, + "facing=up": { + "gtceu:z": 180, + "model": "cosmiccore:block/machine/wireless_cwu_hatch", + "x": 270 + }, + "facing=west": { + "model": "cosmiccore:block/machine/wireless_cwu_hatch", + "y": 270 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/cosmiccore/blockstates/wireless_cwu_transmitter.json b/src/generated/resources/assets/cosmiccore/blockstates/wireless_cwu_transmitter.json new file mode 100644 index 000000000..0c13531f5 --- /dev/null +++ b/src/generated/resources/assets/cosmiccore/blockstates/wireless_cwu_transmitter.json @@ -0,0 +1,76 @@ +{ + "variants": { + "facing=east,upwards_facing=east": { + "gtceu:z": 90, + "model": "cosmiccore:block/machine/wireless_cwu_transmitter", + "y": 90 + }, + "facing=east,upwards_facing=north": { + "model": "cosmiccore:block/machine/wireless_cwu_transmitter", + "y": 90 + }, + "facing=east,upwards_facing=south": { + "gtceu:z": 180, + "model": "cosmiccore:block/machine/wireless_cwu_transmitter", + "y": 90 + }, + "facing=east,upwards_facing=west": { + "gtceu:z": 270, + "model": "cosmiccore:block/machine/wireless_cwu_transmitter", + "y": 90 + }, + "facing=north,upwards_facing=east": { + "gtceu:z": 90, + "model": "cosmiccore:block/machine/wireless_cwu_transmitter" + }, + "facing=north,upwards_facing=north": { + "model": "cosmiccore:block/machine/wireless_cwu_transmitter" + }, + "facing=north,upwards_facing=south": { + "gtceu:z": 180, + "model": "cosmiccore:block/machine/wireless_cwu_transmitter" + }, + "facing=north,upwards_facing=west": { + "gtceu:z": 270, + "model": "cosmiccore:block/machine/wireless_cwu_transmitter" + }, + "facing=south,upwards_facing=east": { + "gtceu:z": 90, + "model": "cosmiccore:block/machine/wireless_cwu_transmitter", + "y": 180 + }, + "facing=south,upwards_facing=north": { + "model": "cosmiccore:block/machine/wireless_cwu_transmitter", + "y": 180 + }, + "facing=south,upwards_facing=south": { + "gtceu:z": 180, + "model": "cosmiccore:block/machine/wireless_cwu_transmitter", + "y": 180 + }, + "facing=south,upwards_facing=west": { + "gtceu:z": 270, + "model": "cosmiccore:block/machine/wireless_cwu_transmitter", + "y": 180 + }, + "facing=west,upwards_facing=east": { + "gtceu:z": 90, + "model": "cosmiccore:block/machine/wireless_cwu_transmitter", + "y": 270 + }, + "facing=west,upwards_facing=north": { + "model": "cosmiccore:block/machine/wireless_cwu_transmitter", + "y": 270 + }, + "facing=west,upwards_facing=south": { + "gtceu:z": 180, + "model": "cosmiccore:block/machine/wireless_cwu_transmitter", + "y": 270 + }, + "facing=west,upwards_facing=west": { + "gtceu:z": 270, + "model": "cosmiccore:block/machine/wireless_cwu_transmitter", + "y": 270 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/cosmiccore/lang/en_ud.json b/src/generated/resources/assets/cosmiccore/lang/en_ud.json index 6e9a4e146..36eb6f444 100644 --- a/src/generated/resources/assets/cosmiccore/lang/en_ud.json +++ b/src/generated/resources/assets/cosmiccore/lang/en_ud.json @@ -176,6 +176,8 @@ "block.cosmiccore.uxv_wireless_energy_hatch": "ɥɔʇɐH ʎbɹǝuƎ ssǝןǝɹıM ΛX∩ǝ§", "block.cosmiccore.vomahine_celestial_laser_bore": "ǝɹoᗺ ɹǝsɐꞀ ןɐıʇsǝןǝƆ ǝuıɥɐɯoΛ", "block.cosmiccore.wear_resistant_ruridit_casing": "buısɐƆ ʇıpıɹnᴚ ʇuɐʇsısǝᴚ ɹɐǝM", + "block.cosmiccore.wireless_cwu_hatch": "ɥɔʇɐH ɹǝʌıǝɔǝᴚ uoıʇɐʇndɯoƆ ssǝןǝɹıM", + "block.cosmiccore.wireless_cwu_transmitter": "ɹǝʇʇıɯsuɐɹ⟘ uoıʇɐʇndɯoƆ ssǝןǝɹıM", "block.cosmiccore.wireless_data_hatch": "ɥɔʇɐH ɐʇɐᗡ ssǝןǝɹıM", "block.cosmiccore.wireless_data_transmitter": "ɹǝʇʇıɯsuɐɹ⟘ ɐʇɐᗡ ssǝןǝɹıM", "block.cosmiccore.zblan_glass": "ssɐן⅁ uɐןqZ", diff --git a/src/generated/resources/assets/cosmiccore/lang/en_us.json b/src/generated/resources/assets/cosmiccore/lang/en_us.json index dabb35cb0..d51c334eb 100644 --- a/src/generated/resources/assets/cosmiccore/lang/en_us.json +++ b/src/generated/resources/assets/cosmiccore/lang/en_us.json @@ -176,6 +176,8 @@ "block.cosmiccore.uxv_wireless_energy_hatch": "§eUXV Wireless Energy Hatch", "block.cosmiccore.vomahine_celestial_laser_bore": "Vomahine Celestial Laser Bore", "block.cosmiccore.wear_resistant_ruridit_casing": "Wear Resistant Ruridit Casing", + "block.cosmiccore.wireless_cwu_hatch": "Wireless Computation Receiver Hatch", + "block.cosmiccore.wireless_cwu_transmitter": "Wireless Computation Transmitter", "block.cosmiccore.wireless_data_hatch": "Wireless Data Hatch", "block.cosmiccore.wireless_data_transmitter": "Wireless Data Transmitter", "block.cosmiccore.zblan_glass": "Zblan Glass", diff --git a/src/generated/resources/assets/cosmiccore/models/block/machine/wireless_cwu_hatch.json b/src/generated/resources/assets/cosmiccore/models/block/machine/wireless_cwu_hatch.json new file mode 100644 index 000000000..67b02a9d8 --- /dev/null +++ b/src/generated/resources/assets/cosmiccore/models/block/machine/wireless_cwu_hatch.json @@ -0,0 +1,22 @@ +{ + "parent": "minecraft:block/block", + "loader": "gtceu:machine", + "machine": "cosmiccore:wireless_cwu_hatch", + "replaceable_textures": [ + "bottom", + "top", + "side" + ], + "variants": { + "": { + "model": { + "parent": "cosmiccore:block/machine/part/wireless_data_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/cosmiccore/models/block/machine/wireless_cwu_transmitter.json b/src/generated/resources/assets/cosmiccore/models/block/machine/wireless_cwu_transmitter.json new file mode 100644 index 000000000..c7ce40361 --- /dev/null +++ b/src/generated/resources/assets/cosmiccore/models/block/machine/wireless_cwu_transmitter.json @@ -0,0 +1,90 @@ +{ + "parent": "minecraft:block/block", + "loader": "gtceu:machine", + "machine": "cosmiccore:wireless_cwu_transmitter", + "texture_overrides": { + "all": "gtceu:block/casings/hpca/high_power_casing" + }, + "variants": { + "is_formed=false,recipe_logic_status=idle": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/hpca/high_power_casing", + "overlay_front": "cosmiccore:block/multiblock/wireless_data_transmitter/overlay_front", + "overlay_front_emissive": "cosmiccore:block/multiblock/wireless_data_transmitter/overlay_front_emissive" + } + } + }, + "is_formed=false,recipe_logic_status=suspend": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/hpca/high_power_casing", + "overlay_front": "cosmiccore:block/multiblock/wireless_data_transmitter/overlay_front_paused", + "overlay_front_emissive": "cosmiccore:block/multiblock/wireless_data_transmitter/overlay_front_paused_emissive" + } + } + }, + "is_formed=false,recipe_logic_status=waiting": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/hpca/high_power_casing", + "overlay_front": "cosmiccore:block/multiblock/wireless_data_transmitter/overlay_front_active", + "overlay_front_emissive": "cosmiccore:block/multiblock/wireless_data_transmitter/overlay_front_active_emissive" + } + } + }, + "is_formed=false,recipe_logic_status=working": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/hpca/high_power_casing", + "overlay_front": "cosmiccore:block/multiblock/wireless_data_transmitter/overlay_front_active", + "overlay_front_emissive": "cosmiccore:block/multiblock/wireless_data_transmitter/overlay_front_active_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=idle": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/hpca/high_power_casing", + "overlay_front": "cosmiccore:block/multiblock/wireless_data_transmitter/overlay_front", + "overlay_front_emissive": "cosmiccore:block/multiblock/wireless_data_transmitter/overlay_front_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=suspend": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/hpca/high_power_casing", + "overlay_front": "cosmiccore:block/multiblock/wireless_data_transmitter/overlay_front_paused", + "overlay_front_emissive": "cosmiccore:block/multiblock/wireless_data_transmitter/overlay_front_paused_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=waiting": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/hpca/high_power_casing", + "overlay_front": "cosmiccore:block/multiblock/wireless_data_transmitter/overlay_front_active", + "overlay_front_emissive": "cosmiccore:block/multiblock/wireless_data_transmitter/overlay_front_active_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=working": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/hpca/high_power_casing", + "overlay_front": "cosmiccore:block/multiblock/wireless_data_transmitter/overlay_front_active", + "overlay_front_emissive": "cosmiccore:block/multiblock/wireless_data_transmitter/overlay_front_active_emissive" + } + } + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/cosmiccore/models/item/wireless_cwu_hatch.json b/src/generated/resources/assets/cosmiccore/models/item/wireless_cwu_hatch.json new file mode 100644 index 000000000..3672ddfb5 --- /dev/null +++ b/src/generated/resources/assets/cosmiccore/models/item/wireless_cwu_hatch.json @@ -0,0 +1,3 @@ +{ + "parent": "cosmiccore:block/machine/wireless_cwu_hatch" +} \ No newline at end of file diff --git a/src/generated/resources/assets/cosmiccore/models/item/wireless_cwu_transmitter.json b/src/generated/resources/assets/cosmiccore/models/item/wireless_cwu_transmitter.json new file mode 100644 index 000000000..ca2e8538e --- /dev/null +++ b/src/generated/resources/assets/cosmiccore/models/item/wireless_cwu_transmitter.json @@ -0,0 +1,3 @@ +{ + "parent": "cosmiccore:block/machine/wireless_cwu_transmitter" +} \ No newline at end of file diff --git a/src/generated/resources/data/forge/tags/blocks/mineable/wrench.json b/src/generated/resources/data/forge/tags/blocks/mineable/wrench.json deleted file mode 100644 index 84d73ed3d..000000000 --- a/src/generated/resources/data/forge/tags/blocks/mineable/wrench.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "values": [ - "cosmiccore:prismatic_tungstensteel_coil_block", - "cosmiccore:resonant_virtue_meld_coil_block", - "cosmiccore:naquadric_superalloy_coil_block", - "cosmiccore:reinforced_trinavine_coil_block", - "cosmiccore:psionic_galvorn_coil_block", - "cosmiccore:living_igniclad_coil_block", - "cosmiccore:programable_matter_coil_block", - "cosmiccore:shimmering_neutronium_coil_block", - "cosmiccore:causal_fabric_coil_block", - "cosmiccore:reflective_starmetal_casing", - "cosmiccore:tritanium_lined_heavy_neutronium_casing", - "cosmiccore:high_tolerance_rhenium_casing", - "cosmiccore:highly_flexible_reinforced_trinavine_casing", - "cosmiccore:dyson_solar_cell", - "cosmiccore:naquadah_pressure_resistant_casing", - "cosmiccore:resonantly_tuned_virtue_meld_casing", - "cosmiccore:steel_plated_bronze_casing", - "cosmiccore:alternator_flux_coiling", - "cosmiccore:plated_aerocloud", - "cosmiccore:high_powered_magnet", - "cosmiccore:fusion_grade_magnet", - "cosmiccore:stellar_neutronium_grade_magnet", - "cosmiccore:gilded_pthanterum_casing", - "cosmiccore:wear_resistant_ruridit_casing", - "cosmiccore:reinforced_naquadria_casing", - "cosmiccore:high_temperature_fission_casing", - "cosmiccore:cyclozine_chemically_repelling_casing", - "cosmiccore:cyclozine_chemically_repelling_pipe", - "cosmiccore:multi_purpose_interstellar_grade_casing", - "cosmiccore:ultra_powered_casing", - "cosmiccore:highly_conductive_fission_casing", - "cosmiccore:machine_casing_gearbox_pthanterum", - "cosmiccore:machine_casing_gearbox_naquadria", - "cosmiccore:heat_fan", - "cosmiccore:ludicrious_intake", - "cosmiccore:ultimate_intake", - "cosmiccore:radioactive_filter_casing", - "cosmiccore:zblan_glass" - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json deleted file mode 100644 index d9178d2da..000000000 --- a/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "values": [ - "cosmiccore:prismatic_tungstensteel_coil_block", - "cosmiccore:resonant_virtue_meld_coil_block", - "cosmiccore:naquadric_superalloy_coil_block", - "cosmiccore:reinforced_trinavine_coil_block", - "cosmiccore:psionic_galvorn_coil_block", - "cosmiccore:living_igniclad_coil_block", - "cosmiccore:programable_matter_coil_block", - "cosmiccore:shimmering_neutronium_coil_block", - "cosmiccore:causal_fabric_coil_block", - "cosmiccore:high_powered_magnet", - "cosmiccore:fusion_grade_magnet", - "cosmiccore:stellar_neutronium_grade_magnet", - "cosmiccore:heat_fan", - "cosmiccore:ludicrious_intake", - "cosmiccore:ultimate_intake", - "cosmiccore:radioactive_filter_casing" - ] -} \ No newline at end of file diff --git a/src/main/java/com/ghostipedia/cosmiccore/common/data/CosmicMachines.java b/src/main/java/com/ghostipedia/cosmiccore/common/data/CosmicMachines.java index 77b2c1914..810f25927 100644 --- a/src/main/java/com/ghostipedia/cosmiccore/common/data/CosmicMachines.java +++ b/src/main/java/com/ghostipedia/cosmiccore/common/data/CosmicMachines.java @@ -16,6 +16,7 @@ import com.ghostipedia.cosmiccore.common.machine.WirelessChargerMachine; import com.ghostipedia.cosmiccore.common.machine.multiblock.electric.MagneticFieldMachine; import com.ghostipedia.cosmiccore.common.machine.multiblock.electric.hpca.HPCAMachine; +import com.ghostipedia.cosmiccore.common.machine.multiblock.multi.WirelessComputationTransmitter; import com.ghostipedia.cosmiccore.common.machine.multiblock.multi.WirelessDataBankMachine; import com.ghostipedia.cosmiccore.common.machine.multiblock.part.*; import com.ghostipedia.cosmiccore.common.machine.multiblock.steam.WeakSteamParallelMultiBlockMachine; @@ -3486,6 +3487,27 @@ private static MachineDefinition[] registerTieredMachines(String name, .workableCasingModel(GTCEu.id("block/casings/hpca/high_power_casing"), CosmicCore.id("block/multiblock/wireless_data_transmitter")) .register(); + + public static final MultiblockMachineDefinition WIRELESS_CWU_TRANSMITTER = REGISTRATE + .multiblock("wireless_cwu_transmitter", WirelessComputationTransmitter::new) + .langValue("Wireless Computation Transmitter") + .rotationState(RotationState.NON_Y_AXIS) + .appearanceBlock(HIGH_POWER_CASING) + .recipeType(GTRecipeTypes.DUMMY_RECIPES) + .pattern(definition -> FactoryBlockPattern.start() + .aisle("AAA", "RAR", "AAA") + .aisle("AAA", "A A", "AIA") + .aisle("AMA", "ACA", "AAA") + .where("C", controller(blocks(definition.getBlock()))) + .where("I", abilities(PartAbility.INPUT_ENERGY)) + .where("M", abilities(PartAbility.MAINTENANCE)) + .where("R", abilities(PartAbility.COMPUTATION_DATA_RECEPTION)) + .where("A", blocks(HIGH_POWER_CASING.get())) + .build()) + .workableCasingModel(GTCEu.id("block/casings/hpca/high_power_casing"), + CosmicCore.id("block/multiblock/wireless_data_transmitter")) + .register(); + public static final MultiblockMachineDefinition LOCAL_POWER_CAPACITOR = REGISTRATE .multiblock("capacitor_array", PowerSubstationMachine::new) .langValue("Capacitor Array") @@ -3522,6 +3544,15 @@ private static MachineDefinition[] registerTieredMachines(String name, .overlayTieredHullModel("wireless_data_hatch") .register(); + public static final MachineDefinition WIRELESS_CWU_HATCH = REGISTRATE + .machine("wireless_cwu_hatch", WirelessComputationReceiverHatchPartMachine::new) + .langValue("Wireless Computation Receiver Hatch") + .rotationState(RotationState.ALL) + .abilities(PartAbility.COMPUTATION_DATA_RECEPTION) + .tier(UEV) + .overlayTieredHullModel("wireless_data_hatch") + .register(); + public static void init() { GTMultiMachines.LARGE_COMBUSTION_ENGINE.setRecipeTypes(new GTRecipeType[] { DUMMY_RECIPES }); GTMultiMachines.LARGE_COMBUSTION_ENGINE.setRenderXEIPreview(false); diff --git a/src/main/java/com/ghostipedia/cosmiccore/common/item/armor/HelmetSanguineWarptechSuite.java b/src/main/java/com/ghostipedia/cosmiccore/common/item/armor/HelmetSanguineWarptechSuite.java index 1cb743b67..07f841c6e 100644 --- a/src/main/java/com/ghostipedia/cosmiccore/common/item/armor/HelmetSanguineWarptechSuite.java +++ b/src/main/java/com/ghostipedia/cosmiccore/common/item/armor/HelmetSanguineWarptechSuite.java @@ -18,9 +18,9 @@ public HelmetSanguineWarptechSuite(ArmorItem.Type slot, int energyPerUse, long c @Override public void onArmorTick(Level world, Player player, ItemStack itemStack) { super.onArmorTick(world, player, itemStack); - if(world.isClientSide) return; + if (world.isClientSide) return; int foodLevel = player.getFoodData().getFoodLevel(); - if(foodLevel < 20) { + if (foodLevel < 20) { player.addEffect(new MobEffectInstance(MobEffects.SATURATION, 1, 1, false, false)); } } diff --git a/src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/multi/WirelessComputationTransmitter.java b/src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/multi/WirelessComputationTransmitter.java new file mode 100644 index 000000000..d4b334f59 --- /dev/null +++ b/src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/multi/WirelessComputationTransmitter.java @@ -0,0 +1,160 @@ +package com.ghostipedia.cosmiccore.common.machine.multiblock.multi; + +import com.ghostipedia.cosmiccore.common.wireless.WirelessCwuStore; +import com.ghostipedia.cosmiccore.utils.OwnershipUtils; + +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.capability.IControllable; +import com.gregtechceu.gtceu.api.capability.IEnergyContainer; +import com.gregtechceu.gtceu.api.capability.IOpticalComputationReceiver; +import com.gregtechceu.gtceu.api.capability.recipe.EURecipeCapability; +import com.gregtechceu.gtceu.api.capability.recipe.IO; +import com.gregtechceu.gtceu.api.machine.ConditionalSubscriptionHandler; +import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.feature.IFancyUIMachine; +import com.gregtechceu.gtceu.api.machine.feature.multiblock.IDisplayUIMachine; +import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMaintenanceMachine; +import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart; +import com.gregtechceu.gtceu.api.machine.multiblock.MultiblockDisplayText; +import com.gregtechceu.gtceu.api.machine.multiblock.PartAbility; +import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; +import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; +import com.gregtechceu.gtceu.api.misc.EnergyContainerList; +import com.gregtechceu.gtceu.common.machine.owner.FTBOwner; +import com.gregtechceu.gtceu.config.ConfigHolder; + +import com.lowdragmc.lowdraglib.utils.DummyWorld; + +import net.minecraft.network.chat.Component; +import net.minecraft.world.level.block.Block; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMaps; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +public class WirelessComputationTransmitter extends WorkableElectricMultiblockMachine + implements IFancyUIMachine, IDisplayUIMachine, IControllable { + + public static final int EUT_PER_HATCH = GTValues.VA[GTValues.LuV]; + + private IMaintenanceMachine maintenance; + private IEnergyContainer energyContainer; + + private final ConditionalSubscriptionHandler tickSubscription; + + protected UUID getTeamUUID() { + var team = ((FTBOwner) getOwner()).getPlayerTeam(getOwnerUUID()); + return team != null ? team.getTeamId() : getOwnerUUID(); + } + + public WirelessComputationTransmitter(IMachineBlockEntity holder, Object... args) { + super(holder, args); + this.energyContainer = new EnergyContainerList(new ArrayList<>()); + this.tickSubscription = new ConditionalSubscriptionHandler(this, this::tick, this::isSubscriptionActive); + } + + private boolean isSubscriptionActive() { + return isFormed(); + } + + private void tick() { + if (isWorkingEnabled() && isFormed()) { + getRecipeLogic() + .setStatus(isSubscriptionActive() ? RecipeLogic.Status.WORKING : RecipeLogic.Status.SUSPEND); + energyContainer.removeEnergy(calculateEnergyUsage()); + addHatchesToWirelessNetwork(); + } else { + removeHatchesFromWirelessNetwork(); + } + } + + @Override + public void onStructureFormed() { + super.onStructureFormed(); + if (getLevel() instanceof DummyWorld) return; + + List energyContainers = new ArrayList<>(); + Map ioMap = getMultiblockState().getMatchContext().getOrCreate("ioMap", Long2ObjectMaps::emptyMap); + + for (IMultiPart part : getParts()) { + IO io = ioMap.getOrDefault(part.self().getPos().asLong(), IO.BOTH); + if (part instanceof IMaintenanceMachine maintenanceMachine) + this.maintenance = maintenanceMachine; + if (io == IO.NONE || io == IO.OUT) continue; + for (var handler : part.getRecipeHandlers()) { + var handlerIO = handler.getHandlerIO(); + if (io != IO.BOTH && handlerIO != IO.BOTH && io != handlerIO) continue; + if (handler.hasCapability(EURecipeCapability.CAP) && + handler instanceof IEnergyContainer container) { + energyContainers.add(container); + } + } + } + + if (this.maintenance == null) { + onStructureInvalid(); + return; + } + + this.energyContainer = new EnergyContainerList(new ArrayList<>(energyContainers)); + + tickSubscription.updateSubscription(); + } + + private int calculateEnergyUsage() { + int receivers = getOpticalReceivers().size(); + boolean hasMaintenance = ConfigHolder.INSTANCE.machines.enableMaintenance && this.maintenance != null; + var maintenanceMultiplier = hasMaintenance ? (1 + (float) this.maintenance.getNumMaintenanceProblems() / 10) : + 1; + return (int) Math.floor(receivers * maintenanceMultiplier * EUT_PER_HATCH); + } + + @Override + public void onStructureInvalid() { + if (isWorkingEnabled() && getRecipeLogic().getStatus() == RecipeLogic.Status.WORKING) + removeHatchesFromWirelessNetwork(); + super.onStructureInvalid(); + this.energyContainer = new EnergyContainerList(new ArrayList<>()); + getRecipeLogic().setStatus(RecipeLogic.Status.SUSPEND); + tickSubscription.updateSubscription(); + } + + @Override + public void addDisplayText(List textList) { + MultiblockDisplayText.builder(textList, isFormed()) + .setWorkingStatus(true, isActive() && isWorkingEnabled()) + .setWorkingStatusKeys( + "gtceu.multiblock.idling", + "gtceu.multiblock.idling", + "gtceu.multiblock.data_bank.providing") + .addEnergyUsageExactLine(calculateEnergyUsage()) + .addWorkingStatusLine() + .addEmptyLine() + .addCustom(list -> OwnershipUtils.addOwnerLine(list, getOwner(), true)); + } + + private void addHatchesToWirelessNetwork() { + WirelessCwuStore.addHatches(getTeamUUID(), getOpticalReceivers()); + } + + private void removeHatchesFromWirelessNetwork() { + WirelessCwuStore.removeHatches(getTeamUUID(), getOpticalReceivers()); + } + + private List getOpticalReceivers() { + List receivers = new ArrayList<>(); + + for (var part : this.getParts()) { + Block block = part.self().getBlockState().getBlock(); + if (part instanceof IOpticalComputationReceiver receiver && + PartAbility.COMPUTATION_DATA_RECEPTION.isApplicable(block)) { + receivers.add(receiver); + } + } + + return receivers; + } +} diff --git a/src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/part/WirelessComputationReceiverHatchPartMachine.java b/src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/part/WirelessComputationReceiverHatchPartMachine.java new file mode 100644 index 000000000..f679b4623 --- /dev/null +++ b/src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/part/WirelessComputationReceiverHatchPartMachine.java @@ -0,0 +1,25 @@ +package com.ghostipedia.cosmiccore.common.machine.multiblock.part; + +import com.ghostipedia.cosmiccore.common.wireless.WirelessCwuStore; + +import com.gregtechceu.gtceu.api.capability.IOpticalComputationProvider; +import com.gregtechceu.gtceu.api.capability.IOpticalComputationReceiver; +import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.multiblock.part.MultiblockPartMachine; +import com.gregtechceu.gtceu.common.machine.owner.FTBOwner; + +public class WirelessComputationReceiverHatchPartMachine extends MultiblockPartMachine + implements IOpticalComputationReceiver { + + public WirelessComputationReceiverHatchPartMachine(IMachineBlockEntity holder) { + super(holder); + } + + @Override + public IOpticalComputationProvider getComputationProvider() { + var team = ((FTBOwner) getOwner()).getPlayerTeam(getOwnerUUID()); + var owner = team != null ? team.getTeamId() : getOwnerUUID(); + + return WirelessCwuStore.getWirelessCwuStore(owner); + } +} diff --git a/src/main/java/com/ghostipedia/cosmiccore/common/wireless/GlobalWirelessVariableStorage.java b/src/main/java/com/ghostipedia/cosmiccore/common/wireless/GlobalWirelessVariableStorage.java index 8b32b6c0f..286139f28 100644 --- a/src/main/java/com/ghostipedia/cosmiccore/common/wireless/GlobalWirelessVariableStorage.java +++ b/src/main/java/com/ghostipedia/cosmiccore/common/wireless/GlobalWirelessVariableStorage.java @@ -8,4 +8,5 @@ public abstract class GlobalWirelessVariableStorage { // Global wireless data stick map public static HashMap GlobalWirelessDataSticks = new HashMap<>(20, 0.9f); + public static HashMap GlobalWirelessCwu = new HashMap<>(20, 0.9f); } diff --git a/src/main/java/com/ghostipedia/cosmiccore/common/wireless/WirelessCwuStore.java b/src/main/java/com/ghostipedia/cosmiccore/common/wireless/WirelessCwuStore.java new file mode 100644 index 000000000..88aa2ecc6 --- /dev/null +++ b/src/main/java/com/ghostipedia/cosmiccore/common/wireless/WirelessCwuStore.java @@ -0,0 +1,87 @@ +package com.ghostipedia.cosmiccore.common.wireless; + +import com.gregtechceu.gtceu.api.capability.IOpticalComputationProvider; +import com.gregtechceu.gtceu.api.capability.IOpticalComputationReceiver; + +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +import static com.ghostipedia.cosmiccore.common.wireless.GlobalWirelessVariableStorage.GlobalWirelessCwu; + +public class WirelessCwuStore implements IOpticalComputationProvider { + + private final Set providers = new HashSet<>(); + + public void clearData() { + providers.clear(); + } + + public void addTransmitters(Set data) { + providers.addAll(data); + } + + public void removeTransmitters(Set data) { + data.forEach(providers::remove); + } + + public List getProviders() { + return providers.stream().toList(); + } + + @Override + public int requestCWUt(int cwut, boolean simulate, @NotNull Collection seen) { + if (seen.contains(this)) return 0; + // The max CWU/t that this Network Switch can provide, combining all its inputs. + seen.add(this); + Collection bridgeSeen = new ArrayList<>(seen); + int allocatedCWUt = 0; + for (var provider : providers) { + if (!provider.canBridge(bridgeSeen)) continue; + int allocated = provider.requestCWUt(cwut, simulate, seen); + allocatedCWUt += allocated; + cwut -= allocated; + if (cwut == 0) break; + } + return allocatedCWUt; + } + + @Override + public int getMaxCWUt(@NotNull Collection seen) { + if (seen.contains(this)) return 0; + // The max CWU/t that this Network Switch can provide, combining all its inputs. + seen.add(this); + Collection bridgeSeen = new ArrayList<>(seen); + int maximumCWUt = 0; + for (var provider : providers) { + if (!provider.canBridge(bridgeSeen)) continue; + maximumCWUt += provider.getMaxCWUt(seen); + } + return maximumCWUt; + } + + @Override + public boolean canBridge(@NotNull Collection collection) { + return false; + } + + public static WirelessCwuStore getWirelessCwuStore(UUID uuid) { + if (GlobalWirelessCwu.get(uuid) == null) + GlobalWirelessCwu.put(uuid, new WirelessCwuStore()); + return GlobalWirelessCwu.get(uuid); + } + + public static void addHatches(UUID uuid, List receivers) { + var dataStore = getWirelessCwuStore(uuid); + var providers = receivers.stream().map(IOpticalComputationReceiver::getComputationProvider).toList(); + dataStore.addTransmitters(new HashSet<>(providers)); + GlobalWirelessCwu.put(uuid, dataStore); + } + + public static void removeHatches(UUID uuid, List receivers) { + var dataStore = getWirelessCwuStore(uuid); + var providers = receivers.stream().map(IOpticalComputationReceiver::getComputationProvider).toList(); + dataStore.removeTransmitters(new HashSet<>(providers)); + GlobalWirelessCwu.put(uuid, dataStore); + } +} diff --git a/src/main/java/com/ghostipedia/cosmiccore/forge/ForgeCommonEventListener.java b/src/main/java/com/ghostipedia/cosmiccore/forge/ForgeCommonEventListener.java index 2e3c51245..f2d6808af 100644 --- a/src/main/java/com/ghostipedia/cosmiccore/forge/ForgeCommonEventListener.java +++ b/src/main/java/com/ghostipedia/cosmiccore/forge/ForgeCommonEventListener.java @@ -15,13 +15,12 @@ import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.machine.MultiblockMachineDefinition; - +import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.player.Player; From a889730477d0a25189ee26eefad8f8d8957a59fd Mon Sep 17 00:00:00 2001 From: MrQuentinet <32539717+mrquentin@users.noreply.github.com> Date: Sat, 4 Oct 2025 14:44:31 -0400 Subject: [PATCH 2/2] Add Logic for Wireless Cwu + Spotless --- .../common/data/CosmicMachines.java | 57 ++++ .../TemporaryResearchStationMachine.java | 21 ++ .../multi/WirelessComputationTransmitter.java | 288 +++++++++++++----- ...ssComputationReceiverHatchPartMachine.java | 48 ++- .../common/wireless/WirelessCwuStore.java | 74 +---- 5 files changed, 346 insertions(+), 142 deletions(-) create mode 100644 src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/TemporaryResearchStationMachine.java diff --git a/src/main/java/com/ghostipedia/cosmiccore/common/data/CosmicMachines.java b/src/main/java/com/ghostipedia/cosmiccore/common/data/CosmicMachines.java index 810f25927..6a9fde6fd 100644 --- a/src/main/java/com/ghostipedia/cosmiccore/common/data/CosmicMachines.java +++ b/src/main/java/com/ghostipedia/cosmiccore/common/data/CosmicMachines.java @@ -14,6 +14,7 @@ import com.ghostipedia.cosmiccore.common.data.materials.CosmicMaterials; import com.ghostipedia.cosmiccore.common.data.recipe.CosmicRecipeModifiers; import com.ghostipedia.cosmiccore.common.machine.WirelessChargerMachine; +import com.ghostipedia.cosmiccore.common.machine.multiblock.TemporaryResearchStationMachine; import com.ghostipedia.cosmiccore.common.machine.multiblock.electric.MagneticFieldMachine; import com.ghostipedia.cosmiccore.common.machine.multiblock.electric.hpca.HPCAMachine; import com.ghostipedia.cosmiccore.common.machine.multiblock.multi.WirelessComputationTransmitter; @@ -51,11 +52,15 @@ import com.gregtechceu.gtceu.common.block.BoilerFireboxType; import com.gregtechceu.gtceu.common.data.*; import com.gregtechceu.gtceu.common.data.machines.GTMultiMachines; +import com.gregtechceu.gtceu.common.data.machines.GTResearchMachines; import com.gregtechceu.gtceu.common.data.models.GTModels; import com.gregtechceu.gtceu.common.machine.multiblock.electric.ActiveTransformerMachine; import com.gregtechceu.gtceu.common.machine.multiblock.electric.FusionReactorMachine; import com.gregtechceu.gtceu.common.machine.multiblock.electric.PowerSubstationMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.research.ResearchStationMachine; +import com.gregtechceu.gtceu.common.registry.GTRegistration; import com.gregtechceu.gtceu.config.ConfigHolder; +import com.gregtechceu.gtceu.data.lang.LangHandler; import com.gregtechceu.gtceu.utils.FormattingUtil; import net.minecraft.ChatFormatting; @@ -3553,6 +3558,58 @@ private static MachineDefinition[] registerTieredMachines(String name, .overlayTieredHullModel("wireless_data_hatch") .register(); + public static final MultiblockMachineDefinition TMP_RESEARCH_STATION = GTRegistration.REGISTRATE + .multiblock("tmp_research_station", TemporaryResearchStationMachine::new) + .rotationState(RotationState.NON_Y_AXIS) + .recipeType(GTRecipeTypes.RESEARCH_STATION_RECIPES) + .appearanceBlock(ADVANCED_COMPUTER_CASING) + .tooltips(LangHandler.getMultiLang("gtceu.machine.research_station.tooltip")) + .pattern(definition -> FactoryBlockPattern.start() + .aisle("XXX", "VVV", "PPP", "PPP", "PPP", "VVV", "XXX") + .aisle("XXX", "VAV", "AAA", "AAA", "AAA", "VAV", "XXX") + .aisle("XXX", "VAV", "XAX", "XSX", "XAX", "VAV", "XXX") + .aisle("XXX", "XAX", "---", "---", "---", "XAX", "XXX") + .aisle(" X ", "XAX", "---", "---", "---", "XAX", " X ") + .aisle(" X ", "XAX", "-A-", "-H-", "-A-", "XAX", " X ") + .aisle(" ", "XXX", "---", "---", "---", "XXX", " ") + .where('S', controller(blocks(definition.getBlock()))) + .where('X', blocks(COMPUTER_CASING.get())) + .where(' ', any()) + .where('-', air()) + .where('V', blocks(COMPUTER_HEAT_VENT.get())) + .where('A', blocks(ADVANCED_COMPUTER_CASING.get())) + .where('P', blocks(COMPUTER_CASING.get()) + .or(abilities(PartAbility.INPUT_ENERGY).setMinGlobalLimited(1).setMaxGlobalLimited(2, 1)) + .or(abilities(PartAbility.COMPUTATION_DATA_RECEPTION).setExactLimit(1)) + .or(autoAbilities(true, false, false))) + .where('H', abilities(PartAbility.OBJECT_HOLDER)) + .build()) + .shapeInfo(definition -> MultiblockShapeInfo.builder() + .aisle("---", "XXX", "---", "---", "---", "XXX", "---") + .aisle("-X-", "XAX", "-A-", "-H-", "-A-", "XAX", "-X-") + .aisle("-X-", "XAX", "---", "---", "---", "XAX", "-X-") + .aisle("XXX", "XAX", "---", "---", "---", "XAX", "XXX") + .aisle("XXX", "VAV", "XAX", "XSX", "XAX", "VAV", "XXX") + .aisle("XXX", "VAV", "AAA", "AAA", "AAA", "VAV", "XXX") + .aisle("XXX", "VVV", "POP", "PEP", "PMP", "VVV", "XXX") + .where('S', GTResearchMachines.RESEARCH_STATION, Direction.NORTH) + .where('X', COMPUTER_CASING.get()) + .where('-', Blocks.AIR) + .where('V', COMPUTER_HEAT_VENT.get()) + .where('A', ADVANCED_COMPUTER_CASING.get()) + .where('P', COMPUTER_CASING.get()) + .where('O', GTResearchMachines.COMPUTATION_HATCH_RECEIVER, Direction.SOUTH) + .where('E', GTMachines.ENERGY_INPUT_HATCH[GTValues.LuV], Direction.SOUTH) + .where('M', ConfigHolder.INSTANCE.machines.enableMaintenance ? + GTMachines.MAINTENANCE_HATCH.getBlock().defaultBlockState().setValue( + GTMachines.MAINTENANCE_HATCH.get().getRotationState().property, Direction.SOUTH) : + COMPUTER_CASING.getDefaultState()) + .where('H', GTResearchMachines.OBJECT_HOLDER, Direction.SOUTH) + .build()) + .sidedWorkableCasingModel(GTCEu.id("block/casings/hpca/advanced_computer_casing"), + GTCEu.id("block/multiblock/research_station")) + .register(); + public static void init() { GTMultiMachines.LARGE_COMBUSTION_ENGINE.setRecipeTypes(new GTRecipeType[] { DUMMY_RECIPES }); GTMultiMachines.LARGE_COMBUSTION_ENGINE.setRenderXEIPreview(false); diff --git a/src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/TemporaryResearchStationMachine.java b/src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/TemporaryResearchStationMachine.java new file mode 100644 index 000000000..9c20a2859 --- /dev/null +++ b/src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/TemporaryResearchStationMachine.java @@ -0,0 +1,21 @@ +package com.ghostipedia.cosmiccore.common.machine.multiblock; + +import com.gregtechceu.gtceu.api.capability.IOpticalComputationProvider; +import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.research.ResearchStationMachine; + +public class TemporaryResearchStationMachine extends ResearchStationMachine { + public TemporaryResearchStationMachine(IMachineBlockEntity holder, Object... args) { + super(holder, args); + } + + @Override + public void onStructureFormed() { + super.onStructureFormed(); + } + + @Override + public ResearchStationRecipeLogic getRecipeLogic() { + return super.getRecipeLogic(); + } +} diff --git a/src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/multi/WirelessComputationTransmitter.java b/src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/multi/WirelessComputationTransmitter.java index d4b334f59..a2050c762 100644 --- a/src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/multi/WirelessComputationTransmitter.java +++ b/src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/multi/WirelessComputationTransmitter.java @@ -1,16 +1,14 @@ package com.ghostipedia.cosmiccore.common.machine.multiblock.multi; import com.ghostipedia.cosmiccore.common.wireless.WirelessCwuStore; -import com.ghostipedia.cosmiccore.utils.OwnershipUtils; - import com.gregtechceu.gtceu.api.GTValues; -import com.gregtechceu.gtceu.api.capability.IControllable; -import com.gregtechceu.gtceu.api.capability.IEnergyContainer; -import com.gregtechceu.gtceu.api.capability.IOpticalComputationReceiver; +import com.gregtechceu.gtceu.api.capability.*; +import com.gregtechceu.gtceu.api.capability.recipe.CWURecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.EURecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.IO; -import com.gregtechceu.gtceu.api.machine.ConditionalSubscriptionHandler; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.feature.IFancyUIMachine; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IDisplayUIMachine; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMaintenanceMachine; @@ -18,57 +16,52 @@ import com.gregtechceu.gtceu.api.machine.multiblock.MultiblockDisplayText; import com.gregtechceu.gtceu.api.machine.multiblock.PartAbility; import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; +import com.gregtechceu.gtceu.api.machine.trait.NotifiableComputationContainer; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.misc.EnergyContainerList; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.research.ResearchStationMachine; import com.gregtechceu.gtceu.common.machine.owner.FTBOwner; import com.gregtechceu.gtceu.config.ConfigHolder; import com.lowdragmc.lowdraglib.utils.DummyWorld; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import lombok.Getter; import net.minecraft.network.chat.Component; -import net.minecraft.world.level.block.Block; import it.unimi.dsi.fastutil.longs.Long2ObjectMaps; +import net.minecraft.server.TickTask; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.Block; +import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import javax.annotation.Nullable; +import java.util.*; public class WirelessComputationTransmitter extends WorkableElectricMultiblockMachine - implements IFancyUIMachine, IDisplayUIMachine, IControllable { + implements IFancyUIMachine, IDisplayUIMachine, IControllable, IOpticalComputationProvider { public static final int EUT_PER_HATCH = GTValues.VA[GTValues.LuV]; + private final WirelessComputationHandler computationHandler = new WirelessComputationHandler(this); + private IMaintenanceMachine maintenance; private IEnergyContainer energyContainer; - private final ConditionalSubscriptionHandler tickSubscription; + @Getter + private int energyUsage = 0; + + @Nullable + private TickableSubscription tickSubscription; protected UUID getTeamUUID() { var team = ((FTBOwner) getOwner()).getPlayerTeam(getOwnerUUID()); return team != null ? team.getTeamId() : getOwnerUUID(); } - public WirelessComputationTransmitter(IMachineBlockEntity holder, Object... args) { - super(holder, args); + public WirelessComputationTransmitter(IMachineBlockEntity holder) { + super(holder); this.energyContainer = new EnergyContainerList(new ArrayList<>()); - this.tickSubscription = new ConditionalSubscriptionHandler(this, this::tick, this::isSubscriptionActive); - } - - private boolean isSubscriptionActive() { - return isFormed(); - } - - private void tick() { - if (isWorkingEnabled() && isFormed()) { - getRecipeLogic() - .setStatus(isSubscriptionActive() ? RecipeLogic.Status.WORKING : RecipeLogic.Status.SUSPEND); - energyContainer.removeEnergy(calculateEnergyUsage()); - addHatchesToWirelessNetwork(); - } else { - removeHatchesFromWirelessNetwork(); - } } @Override @@ -84,77 +77,234 @@ public void onStructureFormed() { if (part instanceof IMaintenanceMachine maintenanceMachine) this.maintenance = maintenanceMachine; if (io == IO.NONE || io == IO.OUT) continue; - for (var handler : part.getRecipeHandlers()) { - var handlerIO = handler.getHandlerIO(); - if (io != IO.BOTH && handlerIO != IO.BOTH && io != handlerIO) continue; - if (handler.hasCapability(EURecipeCapability.CAP) && - handler instanceof IEnergyContainer container) { - energyContainers.add(container); - } + for (var handlerList : part.getRecipeHandlers()) { + if (!handlerList.isValid(io)) continue; + handlerList.getCapability(EURecipeCapability.CAP).stream() + .filter(IEnergyContainer.class::isInstance) + .map(IEnergyContainer.class::cast) + .forEach(energyContainers::add); } } + this.energyContainer = new EnergyContainerList(energyContainers); + this.energyUsage = calculateEnergyUsage(); + if (this.maintenance == null) { onStructureInvalid(); return; } - this.energyContainer = new EnergyContainerList(new ArrayList<>(energyContainers)); + List receivers = new ArrayList<>(); + for (var part : getParts()) { + Block block = part.self().getBlockState().getBlock(); + if (!PartAbility.COMPUTATION_DATA_RECEPTION.isApplicable(block)) continue; + if (part instanceof IOpticalComputationHatch hatch) receivers.add(hatch); + else { + var handlerLists = part.getRecipeHandlers(); + for (var handlerList : handlerLists) { + handlerList.getCapability(CWURecipeCapability.CAP).stream() + .filter(IOpticalComputationHatch.class::isInstance) + .map(IOpticalComputationHatch.class::cast) + .forEach(receivers::add); + } + } + } + + computationHandler.onStructureFormed(receivers); + WirelessCwuStore.setWirelessSource(getTeamUUID(), this); - tickSubscription.updateSubscription(); + if (getLevel() instanceof ServerLevel serverLevel) + serverLevel.getServer().tell(new TickTask(0, this::updateTickSubscription)); } - private int calculateEnergyUsage() { - int receivers = getOpticalReceivers().size(); - boolean hasMaintenance = ConfigHolder.INSTANCE.machines.enableMaintenance && this.maintenance != null; - var maintenanceMultiplier = hasMaintenance ? (1 + (float) this.maintenance.getNumMaintenanceProblems() / 10) : - 1; - return (int) Math.floor(receivers * maintenanceMultiplier * EUT_PER_HATCH); + protected int calculateEnergyUsage() { + int receivers = 0; + int transmitters = 0; + for (var part : this.getParts()) { + Block block = part.self().getBlockState().getBlock(); + if (PartAbility.COMPUTATION_DATA_RECEPTION.isApplicable(block)) { + ++receivers; + } + if (PartAbility.COMPUTATION_DATA_TRANSMISSION.isApplicable(block)) { + ++transmitters; + } + } + return EUT_PER_HATCH * (receivers + transmitters); } @Override public void onStructureInvalid() { - if (isWorkingEnabled() && getRecipeLogic().getStatus() == RecipeLogic.Status.WORKING) - removeHatchesFromWirelessNetwork(); super.onStructureInvalid(); + WirelessCwuStore.resetWirelessSource(getTeamUUID()); this.energyContainer = new EnergyContainerList(new ArrayList<>()); - getRecipeLogic().setStatus(RecipeLogic.Status.SUSPEND); - tickSubscription.updateSubscription(); + this.energyUsage = 0; + this.computationHandler.reset(); + } + + @Override + public void onLoad() { + super.onLoad(); + if (getLevel() instanceof ServerLevel serverLevel) + serverLevel.getServer().tell(new TickTask(0, this::updateTickSubscription)); + } + + @Override + public void onUnload() { + super.onUnload(); + if (tickSubscription != null) { + tickSubscription.unsubscribe(); + tickSubscription = null; + } + } + + @Override + public int requestCWUt(int cwut, boolean simulate, @NotNull Collection seen) { + seen.add(this); + return isActive() && !getRecipeLogic().isWaiting() ? computationHandler.requestCWUt(cwut, simulate, seen) : 0; + } + + @Override + public int getMaxCWUt(@NotNull Collection seen) { + seen.add(this); + return isFormed() ? computationHandler.getMaxCWUt(seen) : 0; + } + + @Override + public boolean canBridge(@NotNull Collection seen) { + seen.add(this); + return true; + } + + private void updateTickSubscription() { + if (isFormed()) { + tickSubscription = subscribeServerTick(tickSubscription, this::tick); + } else if (tickSubscription != null) { + tickSubscription.unsubscribe(); + tickSubscription = null; + } + } + + private void tick() { + int energyToConsume = this.getEnergyUsage(); + boolean hasMaintenance = ConfigHolder.INSTANCE.machines.enableMaintenance && this.maintenance != null; + if (hasMaintenance) energyToConsume += this.maintenance.getNumMaintenanceProblems() * energyToConsume / 10; + + if (getRecipeLogic().isWaiting() && energyContainer.getInputPerSec() > 19L * energyToConsume) { + getRecipeLogic().setStatus(RecipeLogic.Status.IDLE); + } + + if (this.energyContainer.getEnergyStored() >= energyToConsume) { + if (!getRecipeLogic().isWaiting()) { + long consumed = this.energyContainer.removeEnergy(energyToConsume); + if (consumed == energyToConsume) getRecipeLogic().setStatus(RecipeLogic.Status.WORKING); + else getRecipeLogic().setWaiting(Component.translatable("gtceu.recipe_logic.insufficient_in") + .append(": ").append(EURecipeCapability.CAP.getName())); + } + } else getRecipeLogic().setWaiting(Component.translatable("gtceu.recipe_logic.insufficient_in") + .append(": ").append(EURecipeCapability.CAP.getName())); + + updateTickSubscription(); + } + + @Override + public int getProgress() { + return 0; + } + + @Override + public int getMaxProgress() { + return 0; } @Override public void addDisplayText(List textList) { MultiblockDisplayText.builder(textList, isFormed()) - .setWorkingStatus(true, isActive() && isWorkingEnabled()) + .setWorkingStatus(true, isActive() && isWorkingEnabled()) // transform into two-state system for display .setWorkingStatusKeys( "gtceu.multiblock.idling", "gtceu.multiblock.idling", "gtceu.multiblock.data_bank.providing") - .addEnergyUsageExactLine(calculateEnergyUsage()) - .addWorkingStatusLine() - .addEmptyLine() - .addCustom(list -> OwnershipUtils.addOwnerLine(list, getOwner(), true)); + .addEnergyUsageExactLine(getEnergyUsage()) + .addComputationUsageLine(computationHandler.getMaxCWUtForDisplay()) + .addWorkingStatusLine(); } - private void addHatchesToWirelessNetwork() { - WirelessCwuStore.addHatches(getTeamUUID(), getOpticalReceivers()); - } + private static class WirelessComputationHandler extends NotifiableComputationContainer { - private void removeHatchesFromWirelessNetwork() { - WirelessCwuStore.removeHatches(getTeamUUID(), getOpticalReceivers()); - } + private final Set providers = new ObjectOpenHashSet<>(); + + public WirelessComputationHandler(MetaMachine machine) { + super(machine, IO.IN, false); + } - private List getOpticalReceivers() { - List receivers = new ArrayList<>(); + public void onStructureFormed(Collection providers) { + reset(); + this.providers.addAll(providers); + } - for (var part : this.getParts()) { - Block block = part.self().getBlockState().getBlock(); - if (part instanceof IOpticalComputationReceiver receiver && - PartAbility.COMPUTATION_DATA_RECEPTION.isApplicable(block)) { - receivers.add(receiver); + private void reset() { + providers.clear(); + } + + @Override + public int requestCWUt(int cwut, boolean simulate, @NotNull Collection seen) { + if (seen.contains(this)) return 0; + seen.add(this); + + Collection bridgeSeen = new ArrayList<>(seen); + int allocatedCWUt = 0; + for (var provider : providers) { + if (!provider.canBridge(bridgeSeen)) continue; + int allocated = provider.requestCWUt(cwut, simulate, seen); + allocatedCWUt += allocated; + cwut -= allocated; + if (cwut == 0) break; + } + return allocatedCWUt; + } + + public int getMaxCWUtForDisplay() { + Collection seen = new ArrayList<>(); + seen.add(this); + + Collection bridgeSeen = new ArrayList<>(seen); + int maximumCWUt = 0; + for (var provider : providers) { + if (!provider.canBridge(bridgeSeen)) continue; + maximumCWUt += provider.getMaxCWUt(seen); + } + return maximumCWUt; + } + + @Override + public int getMaxCWUt(@NotNull Collection seen) { + if (seen.contains(this)) return 0; + seen.add(this); + + Collection bridgeSeen = new ArrayList<>(seen); + int maximumCWUt = 0; + for (var provider : providers) { + if (!provider.canBridge(bridgeSeen)) continue; + maximumCWUt += provider.getMaxCWUt(seen); } + return maximumCWUt; } - return receivers; + @Override + public boolean canBridge(@NotNull Collection seen) { + if (seen.contains(this)) return false; + seen.add(this); + for (var provider : providers) { + if (provider.canBridge(seen)) { + return true; + } + } + return false; + } + + @Override + public IOpticalComputationProvider getComputationProvider() { + return this; + } } } diff --git a/src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/part/WirelessComputationReceiverHatchPartMachine.java b/src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/part/WirelessComputationReceiverHatchPartMachine.java index f679b4623..d51de04a6 100644 --- a/src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/part/WirelessComputationReceiverHatchPartMachine.java +++ b/src/main/java/com/ghostipedia/cosmiccore/common/machine/multiblock/part/WirelessComputationReceiverHatchPartMachine.java @@ -1,25 +1,57 @@ package com.ghostipedia.cosmiccore.common.machine.multiblock.part; import com.ghostipedia.cosmiccore.common.wireless.WirelessCwuStore; - import com.gregtechceu.gtceu.api.capability.IOpticalComputationProvider; -import com.gregtechceu.gtceu.api.capability.IOpticalComputationReceiver; +import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.multiblock.part.MultiblockPartMachine; +import com.gregtechceu.gtceu.api.machine.trait.NotifiableComputationContainer; import com.gregtechceu.gtceu.common.machine.owner.FTBOwner; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.BlockHitResult; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +public class WirelessComputationReceiverHatchPartMachine extends MultiblockPartMachine{ -public class WirelessComputationReceiverHatchPartMachine extends MultiblockPartMachine - implements IOpticalComputationReceiver { + protected NotifiableComputationContainer computationContainer; public WirelessComputationReceiverHatchPartMachine(IMachineBlockEntity holder) { super(holder); + this.computationContainer = new WirelessComputationContainer(this); } @Override - public IOpticalComputationProvider getComputationProvider() { - var team = ((FTBOwner) getOwner()).getPlayerTeam(getOwnerUUID()); - var owner = team != null ? team.getTeamId() : getOwnerUUID(); + public boolean shouldOpenUI(Player player, InteractionHand hand, BlockHitResult hit) { + return false; + } + + @Override + public boolean canShared() { + return false; + } + + private static class WirelessComputationContainer extends NotifiableComputationContainer + implements IOpticalComputationProvider { + public WirelessComputationContainer(MetaMachine machine) { + super(machine, IO.IN, true); + } + + @Override + public boolean canBridge(@NotNull Collection seen) { + seen.add(this); + return true; + } - return WirelessCwuStore.getWirelessCwuStore(owner); + @Override + public @Nullable IOpticalComputationProvider getComputationProvider() { + var team = ((FTBOwner) this.machine.getOwner()).getPlayerTeam(this.machine.getOwnerUUID()); + var uuid = team != null ? team.getTeamId() : this.machine.getOwnerUUID(); + return WirelessCwuStore.getWirelessCwuStore(uuid).getWirelessSource(); + } } } diff --git a/src/main/java/com/ghostipedia/cosmiccore/common/wireless/WirelessCwuStore.java b/src/main/java/com/ghostipedia/cosmiccore/common/wireless/WirelessCwuStore.java index 88aa2ecc6..bcddd2925 100644 --- a/src/main/java/com/ghostipedia/cosmiccore/common/wireless/WirelessCwuStore.java +++ b/src/main/java/com/ghostipedia/cosmiccore/common/wireless/WirelessCwuStore.java @@ -1,87 +1,31 @@ package com.ghostipedia.cosmiccore.common.wireless; import com.gregtechceu.gtceu.api.capability.IOpticalComputationProvider; -import com.gregtechceu.gtceu.api.capability.IOpticalComputationReceiver; - -import org.jetbrains.annotations.NotNull; +import lombok.Getter; import java.util.*; import static com.ghostipedia.cosmiccore.common.wireless.GlobalWirelessVariableStorage.GlobalWirelessCwu; -public class WirelessCwuStore implements IOpticalComputationProvider { - - private final Set providers = new HashSet<>(); - - public void clearData() { - providers.clear(); - } - - public void addTransmitters(Set data) { - providers.addAll(data); - } - - public void removeTransmitters(Set data) { - data.forEach(providers::remove); - } +public class WirelessCwuStore { - public List getProviders() { - return providers.stream().toList(); - } - - @Override - public int requestCWUt(int cwut, boolean simulate, @NotNull Collection seen) { - if (seen.contains(this)) return 0; - // The max CWU/t that this Network Switch can provide, combining all its inputs. - seen.add(this); - Collection bridgeSeen = new ArrayList<>(seen); - int allocatedCWUt = 0; - for (var provider : providers) { - if (!provider.canBridge(bridgeSeen)) continue; - int allocated = provider.requestCWUt(cwut, simulate, seen); - allocatedCWUt += allocated; - cwut -= allocated; - if (cwut == 0) break; - } - return allocatedCWUt; - } - - @Override - public int getMaxCWUt(@NotNull Collection seen) { - if (seen.contains(this)) return 0; - // The max CWU/t that this Network Switch can provide, combining all its inputs. - seen.add(this); - Collection bridgeSeen = new ArrayList<>(seen); - int maximumCWUt = 0; - for (var provider : providers) { - if (!provider.canBridge(bridgeSeen)) continue; - maximumCWUt += provider.getMaxCWUt(seen); - } - return maximumCWUt; - } - - @Override - public boolean canBridge(@NotNull Collection collection) { - return false; - } + @Getter + private IOpticalComputationProvider wirelessSource; public static WirelessCwuStore getWirelessCwuStore(UUID uuid) { - if (GlobalWirelessCwu.get(uuid) == null) - GlobalWirelessCwu.put(uuid, new WirelessCwuStore()); + GlobalWirelessCwu.computeIfAbsent(uuid, k -> new WirelessCwuStore()); return GlobalWirelessCwu.get(uuid); } - public static void addHatches(UUID uuid, List receivers) { + public static void setWirelessSource(UUID uuid, IOpticalComputationProvider wirelessSource) { var dataStore = getWirelessCwuStore(uuid); - var providers = receivers.stream().map(IOpticalComputationReceiver::getComputationProvider).toList(); - dataStore.addTransmitters(new HashSet<>(providers)); + dataStore.wirelessSource = wirelessSource; GlobalWirelessCwu.put(uuid, dataStore); } - public static void removeHatches(UUID uuid, List receivers) { + public static void resetWirelessSource(UUID uuid) { var dataStore = getWirelessCwuStore(uuid); - var providers = receivers.stream().map(IOpticalComputationReceiver::getComputationProvider).toList(); - dataStore.removeTransmitters(new HashSet<>(providers)); + dataStore.wirelessSource = null; GlobalWirelessCwu.put(uuid, dataStore); } }