diff --git a/dependencies.gradle b/dependencies.gradle index e1427063a8..449dd14302 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -65,6 +65,12 @@ dependencies { modImplementation(forge.javd) { transitive = false } modRuntimeOnly("curse.maven:trenzalore-870210:4848244") + modCompileOnly(forge.ftbteams) + modCompileOnly(forge.ftblibrary) + + modCompileOnly(forge.argonauts) + modCompileOnly(forge.resourceful) + // Runtime only testing mods //modRuntimeOnly(forge.worldStripper) } diff --git a/settings.gradle b/settings.gradle index f708b7a5ba..5d5dc8d938 100644 --- a/settings.gradle +++ b/settings.gradle @@ -35,7 +35,7 @@ dependencyResolutionManagement { def auVersion = "1.20.1-0.6.0" // Forge - def forgeVersion = "47.1.3" + def forgeVersion = "47.1.47" def registrateForgeVersion = "MC1.20-1.3.3" def createForgeVersion = "0.5.1.f-33" def flywheelForgeVersion = "0.6.10-10" @@ -44,6 +44,10 @@ dependencyResolutionManagement { def curiosForgeVersion = "5.9.1" def worldStripperForgeFile = "4578579" def javdVersion = "4803995" + def ftbteamsForgeFile = "5267190" + def ftblibraryForgeFile = "5567591" + def argonautsForgeFile = "5263580" + def resourcefulForgeFile = "5659871" // Libs def quiltMappingsVersion = "5" // https://lambdaurora.dev/tools/import_quilt.html @@ -58,7 +62,7 @@ dependencyResolutionManagement { def mixinextrasVersion = "0.2.0" def shimmerVersion = "0.2.4" def lombokPluginVersion = "8.7.1" - + forge { version("forgeShortVersion", forgeVersion) def minecraftForge = version("minecraftForge", "${minecraftVersion}-${forgeVersion}") @@ -125,6 +129,18 @@ dependencyResolutionManagement { def javd = version("javd", javdVersion) library("javd", "curse.maven", "javd-370890").versionRef(javd) + + def ftbteams = version("ftbteams", ftbteamsForgeFile) + library("ftbteams", "curse.maven", "ftb-teams-forge-404468").versionRef(ftbteams) + + def ftblibrary = version("ftblibrary", ftblibraryForgeFile) + library("ftblibrary", "curse.maven", "ftb-library-forge-404465").versionRef(ftblibrary) + + def argonautslib = version("argonauts", argonautsForgeFile) + library("argonauts", "curse.maven", "argonauts-845833").versionRef(argonautslib) + + def resourceful = version("resourceful", resourcefulForgeFile) + library("resourceful", "curse.maven", "resourceful-lib-570073").versionRef(resourceful) } libs { diff --git a/src/generated/resources/assets/gtceu/compass/nodes/materials/frame.json b/src/generated/resources/assets/gtceu/compass/nodes/materials/frame.json index 01d8df4995..39cfd375c8 100644 --- a/src/generated/resources/assets/gtceu/compass/nodes/materials/frame.json +++ b/src/generated/resources/assets/gtceu/compass/nodes/materials/frame.json @@ -4,8 +4,8 @@ "res": "gtceu:aluminium_frame" }, "items": [ - "#forge:frames", - "#minecraft:climbable" + "#minecraft:climbable", + "#forge:frames" ], "page": "gtceu:materials/frame", "position": [ diff --git a/src/generated/resources/assets/gtceu/lang/en_ud.json b/src/generated/resources/assets/gtceu/lang/en_ud.json index f0ccff0fc4..a0ddc38c98 100644 --- a/src/generated/resources/assets/gtceu/lang/en_ud.json +++ b/src/generated/resources/assets/gtceu/lang/en_ud.json @@ -23,10 +23,12 @@ "behavior.portable_scanner.environmental_hazard": "ɯdd %s - ɹ§%s :ʞunɥƆ uI pɹɐzɐH ןɐʇuǝɯuoɹıʌuƎ", "behavior.portable_scanner.environmental_hazard.nothing": "ɹ§buıɥʇoN9§ :ʞunɥƆ uI pɹɐzɐH ןɐʇuǝɯuoɹıʌuƎ", "behavior.portable_scanner.eu_per_sec": "ʇ/∩Ǝ %s :)puoɔǝs ʇsɐן( ǝbɐɹǝʌⱯ", + "behavior.portable_scanner.guild_name": "ɹ§%s :ǝɯɐN pןın⅁ᄅ§", "behavior.portable_scanner.local_hazard": "ɯdd %s - ɹ§%s :ɐǝɹⱯ uI pɹɐzɐH ןɐɔoꞀ", "behavior.portable_scanner.local_hazard.nothing": "ɹ§buıɥʇoN9§ :ɐǝɹⱯ uI pɹɐzɐH ןɐɔoꞀ", "behavior.portable_scanner.machine_disabled": "˙pǝןqɐsıᗡ", "behavior.portable_scanner.machine_front_facing": "%s :buıɔɐℲ ʇuoɹℲ", + "behavior.portable_scanner.machine_ownership": "ɹ§%s :ǝdʎ⟘ ɹǝuʍO ǝuıɥɔɐWᄅ§", "behavior.portable_scanner.machine_power_loss": "˙ssoן ɹǝʍod oʇ ǝnp uʍop ʇnɥS", "behavior.portable_scanner.machine_progress": "%s / %s :pɐoꞀ/ssǝɹboɹԀ", "behavior.portable_scanner.machine_upwards_facing": "%s :buıɔɐℲ spɹɐʍd∩", @@ -42,10 +44,12 @@ "behavior.portable_scanner.multiblock_energy_output": "%s :ɹǝı⟘ ʇ/∩Ǝ %s :ʇndʇnO ʎbɹǝuƎ xɐW", "behavior.portable_scanner.multiblock_maintenance": "%s :sɯǝןqoɹԀ", "behavior.portable_scanner.multiblock_parallel": "%s :buıssǝɔoɹԀ ıʇןnW", + "behavior.portable_scanner.player_name": "ɹ§%s :ǝuıןuO ɹǝʎɐןԀㄥ§ 'ɹ§%s :ǝɯɐN ɹǝʎɐןԀᄅ§", "behavior.portable_scanner.position": "----- %s :ᗡ %s :Z %s :ʎ %s :X -----", "behavior.portable_scanner.state": "%s :%s", "behavior.portable_scanner.tank": "%s ᗺɯ %s / ᗺɯ %s :%s ʞuɐ⟘", "behavior.portable_scanner.tanks_empty": "ʎʇdɯƎ sʞuɐ⟘ ןןⱯ", + "behavior.portable_scanner.team_name": "ɹ§%s :ǝɯɐN ɯɐǝ⟘ᄅ§", "behavior.portable_scanner.workable_consumption": "Ɐ %s ʇɐ ʇ/∩Ǝ %s :sǝs∩ ʎןqɐqoɹԀ", "behavior.portable_scanner.workable_production": "Ɐ %s ʇɐ ʇ/∩Ǝ %s :sǝɔnpoɹԀ ʎןqɐqoɹԀ", "behavior.portable_scanner.workable_progress": "s %s / s %s :ssǝɹboɹԀ", @@ -2287,6 +2291,8 @@ "config.gtceu.option.ldFluidPipeMinDistance": "ǝɔuɐʇsıᗡuıWǝdıԀpınןℲpן", "config.gtceu.option.ldItemPipeMinDistance": "ǝɔuɐʇsıᗡuıWǝdıԀɯǝʇIpן", "config.gtceu.option.liquidBoilerBaseOutput": "ʇndʇnOǝsɐᗺɹǝןıoᗺpınbıן", + "config.gtceu.option.machineOwnerBreak": "ʞɐǝɹᗺɹǝuʍOǝuıɥɔɐɯ", + "config.gtceu.option.machineOwnerGUI": "I∩⅁ɹǝuʍOǝuıɥɔɐɯ", "config.gtceu.option.machineSounds": "spunoSǝuıɥɔɐɯ", "config.gtceu.option.machines": "sǝuıɥɔɐɯ", "config.gtceu.option.machinesEmissiveTextures": "sǝɹnʇxǝ⟘ǝʌıssıɯƎsǝuıɥɔɐɯ", diff --git a/src/generated/resources/assets/gtceu/lang/en_us.json b/src/generated/resources/assets/gtceu/lang/en_us.json index 08b1471817..a885320d34 100644 --- a/src/generated/resources/assets/gtceu/lang/en_us.json +++ b/src/generated/resources/assets/gtceu/lang/en_us.json @@ -23,10 +23,12 @@ "behavior.portable_scanner.environmental_hazard": "Environmental Hazard In Chunk: %s§r - %s ppm", "behavior.portable_scanner.environmental_hazard.nothing": "Environmental Hazard In Chunk: §6Nothing§r", "behavior.portable_scanner.eu_per_sec": "Average (last second): %s EU/t", + "behavior.portable_scanner.guild_name": "§2Guild Name: %s§r", "behavior.portable_scanner.local_hazard": "Local Hazard In Area: %s§r - %s ppm", "behavior.portable_scanner.local_hazard.nothing": "Local Hazard In Area: §6Nothing§r", "behavior.portable_scanner.machine_disabled": "Disabled.", "behavior.portable_scanner.machine_front_facing": "Front Facing: %s", + "behavior.portable_scanner.machine_ownership": "§2Machine Owner Type: %s§r", "behavior.portable_scanner.machine_power_loss": "Shut down due to power loss.", "behavior.portable_scanner.machine_progress": "Progress/Load: %s / %s", "behavior.portable_scanner.machine_upwards_facing": "Upwards Facing: %s", @@ -42,10 +44,12 @@ "behavior.portable_scanner.multiblock_energy_output": "Max Energy Output: %s EU/t Tier: %s", "behavior.portable_scanner.multiblock_maintenance": "Problems: %s", "behavior.portable_scanner.multiblock_parallel": "Multi Processing: %s", + "behavior.portable_scanner.player_name": "§2Player Name: %s§r, §7Player Online: %s§r", "behavior.portable_scanner.position": "----- X: %s Y: %s Z: %s D: %s -----", "behavior.portable_scanner.state": "%s: %s", "behavior.portable_scanner.tank": "Tank %s: %s mB / %s mB %s", "behavior.portable_scanner.tanks_empty": "All Tanks Empty", + "behavior.portable_scanner.team_name": "§2Team Name: %s§r", "behavior.portable_scanner.workable_consumption": "Probably Uses: %s EU/t at %s A", "behavior.portable_scanner.workable_production": "Probably Produces: %s EU/t at %s A", "behavior.portable_scanner.workable_progress": "Progress: %s s / %s s", @@ -2287,6 +2291,8 @@ "config.gtceu.option.ldFluidPipeMinDistance": "ldFluidPipeMinDistance", "config.gtceu.option.ldItemPipeMinDistance": "ldItemPipeMinDistance", "config.gtceu.option.liquidBoilerBaseOutput": "liquidBoilerBaseOutput", + "config.gtceu.option.machineOwnerBreak": "machineOwnerBreak", + "config.gtceu.option.machineOwnerGUI": "machineOwnerGUI", "config.gtceu.option.machineSounds": "machineSounds", "config.gtceu.option.machines": "machines", "config.gtceu.option.machinesEmissiveTextures": "machinesEmissiveTextures", diff --git a/src/generated/resources/data/minecraft/tags/blocks/logs_that_burn.json b/src/generated/resources/data/minecraft/tags/blocks/logs_that_burn.json index 39f4a40dc7..9598805d7d 100644 --- a/src/generated/resources/data/minecraft/tags/blocks/logs_that_burn.json +++ b/src/generated/resources/data/minecraft/tags/blocks/logs_that_burn.json @@ -5,4 +5,4 @@ "gtceu:rubber_wood", "gtceu:stripped_rubber_wood" ] -} +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/items/logs_that_burn.json b/src/generated/resources/data/minecraft/tags/items/logs_that_burn.json index 0e9a2d0809..9598805d7d 100644 --- a/src/generated/resources/data/minecraft/tags/items/logs_that_burn.json +++ b/src/generated/resources/data/minecraft/tags/items/logs_that_burn.json @@ -1,5 +1,8 @@ { "values": [ - "gtceu:rubber_log" + "gtceu:rubber_log", + "gtceu:stripped_rubber_log", + "gtceu:rubber_wood", + "gtceu:stripped_rubber_wood" ] } \ No newline at end of file diff --git a/src/main/java/com/gregtechceu/gtceu/GTCEu.java b/src/main/java/com/gregtechceu/gtceu/GTCEu.java index 2fd290325e..8f3f8a66ac 100644 --- a/src/main/java/com/gregtechceu/gtceu/GTCEu.java +++ b/src/main/java/com/gregtechceu/gtceu/GTCEu.java @@ -86,6 +86,14 @@ public static boolean isJAVDLoaded() { return LDLib.isModLoaded(GTValues.MODID_JAVD); } + public static boolean isFTBTeamsLoaded() { + return LDLib.isModLoaded(GTValues.MODID_FTBTEAMS); + } + + public static boolean isArgonautsLoaded() { + return LDLib.isModLoaded(GTValues.MODID_ARGONAUTS); + } + @Deprecated(forRemoval = true, since = "1.0.21") public static boolean isHighTier() { return GTCEuAPI.isHighTier(); diff --git a/src/main/java/com/gregtechceu/gtceu/api/GTValues.java b/src/main/java/com/gregtechceu/gtceu/api/GTValues.java index a578c17d0d..0e0690639a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/GTValues.java +++ b/src/main/java/com/gregtechceu/gtceu/api/GTValues.java @@ -115,7 +115,9 @@ public static int[] tiersBetween(int minInclusive, int maxInclusive) { MODID_CURIOS = "curios", MODID_AE2WTLIB = "ae2wtlib", MODID_SHIMMER = "shimmer", - MODID_JAVD = "javd"; + MODID_JAVD = "javd", + MODID_FTBTEAMS = "ftbteams", + MODID_ARGONAUTS = "argonauts"; /** * Spray painting compat modids diff --git a/src/main/java/com/gregtechceu/gtceu/api/block/IMachineBlock.java b/src/main/java/com/gregtechceu/gtceu/api/block/IMachineBlock.java index 4054009335..83f3798d64 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/block/IMachineBlock.java +++ b/src/main/java/com/gregtechceu/gtceu/api/block/IMachineBlock.java @@ -4,11 +4,16 @@ import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.common.machine.owner.ArgonautsOwner; +import com.gregtechceu.gtceu.common.machine.owner.FTBOwner; +import com.gregtechceu.gtceu.common.machine.owner.IMachineOwner; +import com.gregtechceu.gtceu.common.machine.owner.PlayerOwner; import com.lowdragmc.lowdraglib.client.renderer.IBlockRendererProvider; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; @@ -19,8 +24,14 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.DirectionProperty; +import dev.ftb.mods.ftbteams.FTBTeamsAPIImpl; +import dev.ftb.mods.ftbteams.api.Team; +import earth.terrarium.argonauts.api.guild.Guild; +import earth.terrarium.argonauts.common.handlers.guild.GuildHandler; import org.jetbrains.annotations.Nullable; +import java.util.Optional; + /** * @author KilaBash * @date 2023/3/31 @@ -77,4 +88,22 @@ default BlockEntityTicker getTicker(Level level, Bloc } return null; } + + default void setMachineOwner(MetaMachine machine, ServerPlayer player) { + if (IMachineOwner.MachineOwnerType.FTB.isAvailable()) { + Optional team = FTBTeamsAPIImpl.INSTANCE.getManager().getTeamForPlayerID(player.getUUID()); + if (team.isPresent()) { + machine.holder.setOwner(new FTBOwner(team.get(), player.getUUID())); + return; + } + } + if (IMachineOwner.MachineOwnerType.ARGONAUTS.isAvailable()) { + Guild guild = GuildHandler.read(player.server).get(player); + if (guild != null) { + machine.holder.setOwner(new ArgonautsOwner(guild, player.getUUID())); + return; + } + } + machine.holder.setOwner(new PlayerOwner(player.getUUID())); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/block/MetaMachineBlock.java b/src/main/java/com/gregtechceu/gtceu/api/block/MetaMachineBlock.java index f0328c80dd..f2cffcfaa9 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/block/MetaMachineBlock.java +++ b/src/main/java/com/gregtechceu/gtceu/api/block/MetaMachineBlock.java @@ -11,6 +11,7 @@ import com.gregtechceu.gtceu.api.machine.MultiblockMachineDefinition; import com.gregtechceu.gtceu.api.machine.feature.*; import com.gregtechceu.gtceu.common.data.GTItems; +import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.utils.GTUtil; import com.lowdragmc.lowdraglib.client.renderer.IRenderer; @@ -127,6 +128,12 @@ public void setPlacedBy(Level pLevel, BlockPos pPos, BlockState pState, @Nullabl ItemStack pStack) { if (!pLevel.isClientSide) { var machine = getMachine(pLevel, pPos); + if (machine != null) { + if (player instanceof ServerPlayer sPlayer) { + setMachineOwner(machine, sPlayer); + machine.markDirty(); + } + } if (machine instanceof IDropSaveMachine dropSaveMachine) { CompoundTag tag = pStack.getTag(); if (tag != null) { @@ -282,6 +289,11 @@ public InteractionResult use(BlockState state, Level world, BlockPos pos, Player ItemStack itemStack = player.getItemInHand(hand); boolean shouldOpenUi = true; + if (machine != null && machine.holder.getOwner() == null && player instanceof ServerPlayer) { + setMachineOwner(machine, (ServerPlayer) player); + machine.markDirty(); + } + Set types = ToolHelper.getToolTypes(itemStack); if (machine != null && !types.isEmpty() && ToolHelper.canUse(itemStack)) { var result = machine.onToolClick(types, itemStack, new UseOnContext(player, hand, hit)); @@ -307,12 +319,25 @@ public InteractionResult use(BlockState state, Level world, BlockPos pos, Player var result = interactedMachine.onUse(state, world, pos, player, hand, hit); if (result != InteractionResult.PASS) return result; } - if (shouldOpenUi && machine instanceof IUIMachine uiMachine) { + if (shouldOpenUi && machine instanceof IUIMachine uiMachine && + canOpenOwnerMachine(player, machine.getHolder())) { return uiMachine.tryToOpenUI(player, hand, hit); } return shouldOpenUi ? InteractionResult.PASS : InteractionResult.CONSUME; } + public boolean canOpenOwnerMachine(Player player, IMachineBlockEntity machine) { + if (!ConfigHolder.INSTANCE.machines.machineOwnerGUI) return true; + if (machine.getOwner() == null) return true; + return machine.getOwner().isPlayerInTeam(player) || machine.getOwner().isPlayerFriendly(player); + } + + public static boolean canBreakOwnerMachine(Player player, IMachineBlockEntity machine) { + if (!ConfigHolder.INSTANCE.machines.machineOwnerBreak) return true; + if (machine.getOwner() == null) return true; + return machine.getOwner().isPlayerInTeam(player); + } + public boolean canConnectRedstone(BlockGetter level, BlockPos pos, Direction side) { return getMachine(level, pos).canConnectRedstone(side); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/blockentity/MetaMachineBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/api/blockentity/MetaMachineBlockEntity.java index fc64c16e70..0047290076 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/blockentity/MetaMachineBlockEntity.java +++ b/src/main/java/com/gregtechceu/gtceu/api/blockentity/MetaMachineBlockEntity.java @@ -15,6 +15,7 @@ import com.gregtechceu.gtceu.api.misc.LaserContainerList; import com.gregtechceu.gtceu.api.pipenet.longdistance.ILDEndpoint; import com.gregtechceu.gtceu.client.renderer.GTRendererProvider; +import com.gregtechceu.gtceu.common.machine.owner.IMachineOwner; import com.gregtechceu.gtceu.common.pipelike.fluidpipe.longdistance.LDFluidEndpointMachine; import com.gregtechceu.gtceu.common.pipelike.item.longdistance.LDItemEndpointMachine; @@ -25,10 +26,12 @@ import com.lowdragmc.lowdraglib.side.fluid.forge.FluidTransferHelperImpl; import com.lowdragmc.lowdraglib.side.item.IItemTransfer; import com.lowdragmc.lowdraglib.side.item.forge.ItemTransferHelperImpl; +import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; import com.lowdragmc.lowdraglib.syncdata.managed.MultiManagedStorage; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.entity.BlockEntity; @@ -45,13 +48,11 @@ import appeng.api.networking.IInWorldGridNodeHost; import appeng.capabilities.Capabilities; import lombok.Getter; +import lombok.Setter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; +import java.util.*; /** * @author KilaBash @@ -63,6 +64,10 @@ public class MetaMachineBlockEntity extends BlockEntity implements IMachineBlock public final MultiManagedStorage managedStorage = new MultiManagedStorage(); @Getter public final MetaMachine metaMachine; + @Setter + @Getter + @Persisted + private IMachineOwner owner; private final long offset = GTValues.RNG.nextInt(20); protected MetaMachineBlockEntity(BlockEntityType type, BlockPos pos, BlockState blockState) { @@ -317,4 +322,20 @@ public AABB getRenderBoundingBox() { } return new AABB(worldPosition.offset(-1, 0, -1), worldPosition.offset(2, 2, 2)); } + + @Override + protected void saveAdditional(CompoundTag tag) { + super.saveAdditional(tag); + if (owner != null) { + tag.put("owner", owner.write()); + } + } + + @Override + public void load(CompoundTag tag) { + super.load(tag); + if (tag.contains("owner")) { + this.owner = IMachineOwner.create(tag.getCompound("owner")); + } + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/IMachineBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/api/machine/IMachineBlockEntity.java index 9da6b13811..0f59590c2c 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/IMachineBlockEntity.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/IMachineBlockEntity.java @@ -2,6 +2,7 @@ import com.gregtechceu.gtceu.api.block.IMachineBlock; import com.gregtechceu.gtceu.api.item.tool.IToolGridHighLight; +import com.gregtechceu.gtceu.common.machine.owner.IMachineOwner; import com.lowdragmc.lowdraglib.syncdata.blockentity.IAsyncAutoSyncBlockEntity; import com.lowdragmc.lowdraglib.syncdata.blockentity.IAutoPersistBlockEntity; @@ -81,4 +82,10 @@ default void loadCustomPersistedData(CompoundTag tag) { IAutoPersistBlockEntity.super.loadCustomPersistedData(tag); getMetaMachine().loadCustomPersistedData(tag); } + + default void setOwner(IMachineOwner owner) {} + + default IMachineOwner getOwner() { + return null; + } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/blockentity/KineticMachineBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/common/blockentity/KineticMachineBlockEntity.java index 4fb38f54b4..1d46782939 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/blockentity/KineticMachineBlockEntity.java +++ b/src/main/java/com/gregtechceu/gtceu/common/blockentity/KineticMachineBlockEntity.java @@ -10,6 +10,7 @@ import com.lowdragmc.lowdraglib.LDLib; import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; +import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; import com.lowdragmc.lowdraglib.syncdata.managed.MultiManagedStorage; import net.minecraft.ChatFormatting; @@ -44,6 +45,7 @@ import java.util.List; import java.util.Set; +import java.util.UUID; import java.util.function.BiFunction; /** @@ -59,6 +61,12 @@ public class KineticMachineBlockEntity extends KineticBlockEntity implements IMa private final long offset = GTValues.RNG.nextInt(20); public float workingSpeed; public boolean reActivateSource; + @DescSynced + private UUID owner; + @Getter + @DescSynced + private String ownerName; + private Class ownerType; protected KineticMachineBlockEntity(BlockEntityType typeIn, BlockPos pos, BlockState state) { super(typeIn, pos, state); diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/PortableScannerBehavior.java b/src/main/java/com/gregtechceu/gtceu/common/item/PortableScannerBehavior.java index 641e7c225a..3d0b3c16a4 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/PortableScannerBehavior.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/PortableScannerBehavior.java @@ -200,6 +200,9 @@ public int addScannerInfo(Player player, Level level, BlockPos pos, DisplayMode // General machine information if (mode == DisplayMode.SHOW_ALL || mode == DisplayMode.SHOW_MACHINE_INFO) { + if (machineBlockEntity.getOwner() != null) { + machineBlockEntity.getOwner().displayInfo(list); + } if (machine.getDefinition() instanceof MultiblockMachineDefinition multi && multi.isAllowExtendedFacing()) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/owner/ArgonautsOwner.java b/src/main/java/com/gregtechceu/gtceu/common/machine/owner/ArgonautsOwner.java new file mode 100644 index 0000000000..c4019391d5 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/owner/ArgonautsOwner.java @@ -0,0 +1,89 @@ +package com.gregtechceu.gtceu.common.machine.owner; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.entity.player.Player; +import net.minecraftforge.server.ServerLifecycleHooks; + +import earth.terrarium.argonauts.api.guild.Guild; +import earth.terrarium.argonauts.common.handlers.guild.GuildHandler; +import lombok.Getter; + +import java.util.List; +import java.util.UUID; + +public final class ArgonautsOwner implements IMachineOwner { + + @Getter + private Guild guild; + @Getter + private UUID playerUUID; + private MinecraftServer server; + + public ArgonautsOwner() {} + + public ArgonautsOwner(Guild guild, UUID player) { + this.guild = guild; + this.playerUUID = player; + this.server = ServerLifecycleHooks.getCurrentServer(); + } + + @Override + public void save(CompoundTag tag) { + tag.putUUID("guildUUID", guild.id()); + tag.putUUID("playerUUID", playerUUID); + } + + @Override + public void load(CompoundTag tag) { + this.playerUUID = tag.getUUID("playerUUID"); + this.server = ServerLifecycleHooks.getCurrentServer(); + var handler = GuildHandler.read(server); + this.guild = GuildHandler.API.get(server, tag.getUUID("guildUUID")); + } + + @Override + public boolean isPlayerInTeam(Player player) { + if (player.getUUID().equals(this.playerUUID)) return true; + var otherGuild = GuildHandler.read(server).get(server, player.getUUID()); + if (otherGuild != null && otherGuild.equals(this.guild)) return true; + + return false; + } + + @Override + public boolean isPlayerFriendly(Player player) { + if (guild.isPublic()) return true; + + if (guild.members().isMember(player.getUUID())) return true; + if (guild.members().isInvited(player.getUUID())) return true; + if (guild.members().isAllied(player.getUUID())) return true; + return false; + } + + @Override + public void displayInfo(List compList) { + compList.add(Component.translatable("behavior.portable_scanner.machine_ownership", type().getName())); + compList.add(Component.translatable("behavior.portable_scanner.guild_name", guild.displayName().getString())); + var serverPlayer = ServerLifecycleHooks.getCurrentServer().getPlayerList().getPlayer(playerUUID); + final String[] playerName = new String[1]; + boolean isOnline; + if (serverPlayer != null) { + playerName[0] = serverPlayer.getDisplayName().getString(); + isOnline = true; + } else { + var cache = ServerLifecycleHooks.getCurrentServer().getProfileCache(); + if (cache != null) { + cache.get(playerUUID).ifPresent(value -> playerName[0] = value.getName()); + } + isOnline = false; + } + compList.add(Component.translatable("behavior.portable_scanner.player_name", playerName[0], isOnline)); + } + + @Override + public MachineOwnerType type() { + return MachineOwnerType.ARGONAUTS; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/owner/FTBOwner.java b/src/main/java/com/gregtechceu/gtceu/common/machine/owner/FTBOwner.java new file mode 100644 index 0000000000..d094d87457 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/owner/FTBOwner.java @@ -0,0 +1,79 @@ +package com.gregtechceu.gtceu.common.machine.owner; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Player; +import net.minecraftforge.server.ServerLifecycleHooks; + +import dev.ftb.mods.ftbteams.FTBTeamsAPIImpl; +import dev.ftb.mods.ftbteams.api.Team; +import lombok.Getter; + +import java.util.List; +import java.util.UUID; + +public final class FTBOwner implements IMachineOwner { + + @Getter + private Team team; + @Getter + private UUID playerUUID; + + public FTBOwner() {} + + public FTBOwner(Team team, UUID player) { + this.team = team; + this.playerUUID = player; + } + + @Override + public void save(CompoundTag tag) { + tag.putUUID("teamUUID", team.getTeamId()); + tag.putUUID("playerUUID", playerUUID); + } + + @Override + public void load(CompoundTag tag) { + this.team = FTBTeamsAPIImpl.INSTANCE.getManager().getTeamByID(tag.getUUID("teamUUID")).orElse(null); + this.playerUUID = tag.getUUID("playerUUID"); + } + + @Override + public boolean isPlayerInTeam(Player player) { + if (player.getUUID().equals(this.playerUUID)) return true; + if (FTBTeamsAPIImpl.INSTANCE.getManager().arePlayersInSameTeam(player.getUUID(), this.playerUUID)) return true; + + return false; + } + + @Override + public boolean isPlayerFriendly(Player player) { + if (team.getRankForPlayer(player.getUUID()).isAllyOrBetter()) return true; + return false; + } + + @Override + public void displayInfo(List compList) { + compList.add(Component.translatable("behavior.portable_scanner.machine_ownership", type().getName())); + compList.add(Component.translatable("behavior.portable_scanner.team_name", team.getName())); + var serverPlayer = ServerLifecycleHooks.getCurrentServer().getPlayerList().getPlayer(playerUUID); + final String[] playerName = new String[1]; + boolean isOnline; + if (serverPlayer != null) { + playerName[0] = serverPlayer.getDisplayName().getString(); + isOnline = true; + } else { + var cache = ServerLifecycleHooks.getCurrentServer().getProfileCache(); + if (cache != null) { + cache.get(playerUUID).ifPresent(value -> playerName[0] = value.getName()); + } + isOnline = false; + } + compList.add(Component.translatable("behavior.portable_scanner.player_name", playerName[0], isOnline)); + } + + @Override + public MachineOwnerType type() { + return MachineOwnerType.FTB; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/owner/IMachineOwner.java b/src/main/java/com/gregtechceu/gtceu/common/machine/owner/IMachineOwner.java new file mode 100644 index 0000000000..9f90afd18f --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/owner/IMachineOwner.java @@ -0,0 +1,82 @@ +package com.gregtechceu.gtceu.common.machine.owner; + +import com.gregtechceu.gtceu.GTCEu; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Player; + +import lombok.Getter; + +import java.util.List; +import java.util.function.BooleanSupplier; + +public sealed interface IMachineOwner permits PlayerOwner, ArgonautsOwner, FTBOwner { + + void save(CompoundTag tag); + + void load(CompoundTag tag); + + MachineOwnerType type(); + + void displayInfo(List compList); + + static IMachineOwner create(CompoundTag tag) { + MachineOwnerType type = MachineOwnerType.VALUES[tag.getInt("type")]; + if (!type.isAvailable()) { + GTCEu.LOGGER.warn("Machine ownership system: {} is not available", type.name()); + return null; + } + IMachineOwner owner = switch (type) { + case PLAYER -> new PlayerOwner(); + case FTB -> new FTBOwner(); + case ARGONAUTS -> new ArgonautsOwner(); + }; + owner.load(tag); + return owner; + } + + default CompoundTag write() { + var tag = new CompoundTag(); + tag.putInt("type", type().ordinal()); + save(tag); + return tag; + } + + boolean isPlayerInTeam(Player player); + + boolean isPlayerFriendly(Player player); + + enum MachineOwnerType { + + PLAYER, + FTB(GTCEu::isFTBTeamsLoaded, "FTB Teams"), + ARGONAUTS(GTCEu::isArgonautsLoaded, "Argonauts Guild"); + + public static final MachineOwnerType[] VALUES = values(); + + private BooleanSupplier availabilitySupplier; + private boolean available; + + @Getter + private final String name; + + private MachineOwnerType(BooleanSupplier availabilitySupplier, String name) { + this.availabilitySupplier = availabilitySupplier; + this.name = name; + } + + private MachineOwnerType() { + this.available = true; + this.name = "Player"; + } + + public boolean isAvailable() { + if (availabilitySupplier != null) { + this.available = availabilitySupplier.getAsBoolean(); + this.availabilitySupplier = null; + } + return available; + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/owner/PlayerOwner.java b/src/main/java/com/gregtechceu/gtceu/common/machine/owner/PlayerOwner.java new file mode 100644 index 0000000000..062e8402af --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/owner/PlayerOwner.java @@ -0,0 +1,67 @@ +package com.gregtechceu.gtceu.common.machine.owner; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Player; +import net.minecraftforge.server.ServerLifecycleHooks; + +import lombok.Getter; + +import java.util.List; +import java.util.UUID; + +public final class PlayerOwner implements IMachineOwner { + + @Getter + private UUID playerUUID; + + public PlayerOwner() {} + + public PlayerOwner(UUID player) { + this.playerUUID = player; + } + + @Override + public void save(CompoundTag tag) { + tag.putUUID("UUID", playerUUID); + } + + @Override + public void load(CompoundTag tag) { + this.playerUUID = tag.getUUID("UUID"); + } + + @Override + public boolean isPlayerInTeam(Player player) { + return true; + } + + @Override + public boolean isPlayerFriendly(Player player) { + return true; + } + + @Override + public void displayInfo(List compList) { + compList.add(Component.translatable("behavior.portable_scanner.machine_ownership", type().getName())); + var serverPlayer = ServerLifecycleHooks.getCurrentServer().getPlayerList().getPlayer(playerUUID); + final String[] playerName = new String[1]; + boolean isOnline; + if (serverPlayer != null) { + playerName[0] = serverPlayer.getDisplayName().getString(); + isOnline = true; + } else { + var cache = ServerLifecycleHooks.getCurrentServer().getProfileCache(); + if (cache != null) { + cache.get(playerUUID).ifPresent(value -> playerName[0] = value.getName()); + } + isOnline = false; + } + compList.add(Component.translatable("behavior.portable_scanner.player_name", playerName[0], isOnline)); + } + + @Override + public MachineOwnerType type() { + return MachineOwnerType.PLAYER; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java b/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java index 00e79c0fa2..d2595fab50 100644 --- a/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java +++ b/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java @@ -389,6 +389,13 @@ public static class MachineConfigs { @Configurable.Comment({ "Minimum distance betweeb Long Distance Fluid Pipe Endpoints", "Default: 50" }) public int ldFluidPipeMinDistance = 50; + @Configurable + @Configurable.Comment({ "Whether non owners can open a machine gui", "Default: false" }) + public boolean machineOwnerGUI = true; + @Configurable + @Configurable.Comment({ "Whether non owners can break a machine", "Default: false" }) + public boolean machineOwnerBreak = true; + /** * Addons mods should not reference this config directly. * Use {@link GTCEuAPI#isHighTier()} instead. diff --git a/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java b/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java index f2a7226c4a..3350d6555c 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java @@ -771,6 +771,10 @@ public static void init(RegistrateLangProvider provider) { provider.add("behavior.portable_scanner.amp_per_sec", "Average (last second): %s A"); provider.add("behavior.portable_scanner.machine_disabled", "Disabled."); provider.add("behavior.portable_scanner.machine_front_facing", "Front Facing: %s"); + provider.add("behavior.portable_scanner.machine_ownership", "§2Machine Owner Type: %s§r"); + provider.add("behavior.portable_scanner.guild_name", "§2Guild Name: %s§r"); + provider.add("behavior.portable_scanner.team_name", "§2Team Name: %s§r"); + provider.add("behavior.portable_scanner.player_name", "§2Player Name: %s§r, §7Player Online: %s§r"); provider.add("behavior.portable_scanner.machine_power_loss", "Shut down due to power loss."); provider.add("behavior.portable_scanner.machine_progress", "Progress/Load: %s / %s"); provider.add("behavior.portable_scanner.machine_upwards_facing", "Upwards Facing: %s"); diff --git a/src/main/java/com/gregtechceu/gtceu/forge/ForgeCommonEventListener.java b/src/main/java/com/gregtechceu/gtceu/forge/ForgeCommonEventListener.java index 38bc9b8849..2cf95924d5 100644 --- a/src/main/java/com/gregtechceu/gtceu/forge/ForgeCommonEventListener.java +++ b/src/main/java/com/gregtechceu/gtceu/forge/ForgeCommonEventListener.java @@ -18,6 +18,7 @@ import com.gregtechceu.gtceu.api.item.IComponentItem; import com.gregtechceu.gtceu.api.item.TagPrefixItem; import com.gregtechceu.gtceu.api.item.armor.ArmorComponentItem; +import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.feature.IInteractedMachine; import com.gregtechceu.gtceu.api.registry.GTRegistries; import com.gregtechceu.gtceu.common.capability.EnvironmentalHazardSavedData; @@ -71,6 +72,7 @@ import net.minecraftforge.event.entity.living.MobSpawnEvent; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent; +import net.minecraftforge.event.level.BlockEvent; import net.minecraftforge.event.level.ChunkWatchEvent; import net.minecraftforge.event.level.LevelEvent; import net.minecraftforge.eventbus.api.EventPriority; @@ -208,6 +210,16 @@ public static void onLeftClickBlock(PlayerInteractEvent.LeftClickBlock event) { } } + @SubscribeEvent + public static void onBreakEvent(BlockEvent.BreakEvent event) { + var machine = MetaMachine.getMachine(event.getLevel(), event.getPos()); + if (machine != null) { + if (!MetaMachineBlock.canBreakOwnerMachine(event.getPlayer(), machine.holder)) { + event.setCanceled(true); + } + } + } + @SubscribeEvent public static void registerCommand(RegisterCommandsEvent event) { GTCommands.register(event.getDispatcher(), event.getBuildContext());