From edd952ec6afd60052410b3d791ee1548c90961d9 Mon Sep 17 00:00:00 2001 From: 70000hp <105080577+70000hp@users.noreply.github.com> Date: Thu, 3 Jul 2025 15:09:09 -0400 Subject: [PATCH] Interactions for the logic block --- .../hbm/blocks/generic/BlockWandSpawner.java | 32 +++++- .../hbm/blocks/generic/DungeonSpawner.java | 34 +++++- .../world/gen/util/DungeonSpawnerActions.java | 105 ++++++++++++++---- .../gen/util/DungeonSpawnerConditions.java | 7 +- .../gen/util/DungeonSpawnerInteractions.java | 80 +++++++++++++ 5 files changed, 230 insertions(+), 28 deletions(-) create mode 100644 src/main/java/com/hbm/world/gen/util/DungeonSpawnerInteractions.java diff --git a/src/main/java/com/hbm/blocks/generic/BlockWandSpawner.java b/src/main/java/com/hbm/blocks/generic/BlockWandSpawner.java index 6d4a6f8a3..b6c042838 100644 --- a/src/main/java/com/hbm/blocks/generic/BlockWandSpawner.java +++ b/src/main/java/com/hbm/blocks/generic/BlockWandSpawner.java @@ -16,6 +16,7 @@ import com.hbm.util.i18n.I18nUtil; import com.hbm.world.gen.INBTTileEntityTransformable; import com.hbm.world.gen.util.DungeonSpawnerActions; import com.hbm.world.gen.util.DungeonSpawnerConditions; +import com.hbm.world.gen.util.DungeonSpawnerInteractions; import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -146,6 +147,16 @@ public class BlockWandSpawner extends BlockContainer implements ILookOverlay, IT spawner.conditionID = conditionNames.get(indexC); + return true; + case HAND_DRILL: + List interactionNames = DungeonSpawnerInteractions.getInteractionNames(); + int indexI = interactionNames.indexOf(spawner.interactionID); + + indexI += player.isSneaking() ? -1 : 1; + indexI = MathHelper.clamp_int(indexI, 0, interactionNames.size() - 1); + + spawner.interactionID = interactionNames.get(indexI); + return true; default: return false; @@ -163,6 +174,8 @@ public class BlockWandSpawner extends BlockContainer implements ILookOverlay, IT List text = new ArrayList<>(); text.add("Action: " + spawner.actionID); text.add("Condition: " + spawner.conditionID); + text.add("Interaction: " + (spawner.interactionID != null ? spawner.interactionID : "None")); + String block; if(spawner.disguise != null && spawner.disguise != Blocks.air) @@ -171,6 +184,7 @@ public class BlockWandSpawner extends BlockContainer implements ILookOverlay, IT block = "None"; text.add("Disguise Block: " + block); + ILookOverlay.printGeneric(event, I18nUtil.resolveKey(getUnlocalizedName() + ".name"), 0xffff00, 0x404000, text); } @@ -178,7 +192,8 @@ public class BlockWandSpawner extends BlockContainer implements ILookOverlay, IT public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { list.add(EnumChatFormatting.GOLD + "Use screwdriver to cycle forwards through the action list, shift click to go back"); list.add(EnumChatFormatting.GOLD + "Use defuser to cycle forwards through the condition list, shift click to go back"); - list.add(EnumChatFormatting.BLUE + "Use a detonator to transform"); + list.add(EnumChatFormatting.GOLD + "Use hand drill to cycle forwards through the interaction list, shift click to go back"); + list.add(EnumChatFormatting.YELLOW + "Use a detonator to transform"); } @Override @@ -206,9 +221,8 @@ public class BlockWandSpawner extends BlockContainer implements ILookOverlay, IT int disguiseMeta = -1; public String actionID = "PHASE_ABERRATOR"; - public String conditionID = "ABERRATOR"; - - public boolean noDisguise; + public String conditionID = "EMPTY"; + public String interactionID; @Override public void updateEntity() { @@ -241,6 +255,7 @@ public class BlockWandSpawner extends BlockContainer implements ILookOverlay, IT DungeonSpawner.TileEntityDungeonSpawner spawner = (DungeonSpawner.TileEntityDungeonSpawner) te; spawner.actionID = actionID; spawner.conditionID = conditionID; + spawner.interactionID = interactionID; spawner.direction = ForgeDirection.getOrientation(placedRotation); spawner.disguise = disguise; spawner.disguiseMeta = disguiseMeta; @@ -258,6 +273,7 @@ public class BlockWandSpawner extends BlockContainer implements ILookOverlay, IT super.writeToNBT(nbt); nbt.setString("actionID", actionID); nbt.setString("conditionID", conditionID); + nbt.setString("interactionID", interactionID); nbt.setInteger("rotation", placedRotation); if(disguise != null){ nbt.setString("disguise", GameRegistry.findUniqueIdentifierFor(disguise).toString()); @@ -270,6 +286,7 @@ public class BlockWandSpawner extends BlockContainer implements ILookOverlay, IT super.readFromNBT(nbt); actionID = nbt.getString("actionID"); conditionID = nbt.getString("conditionID"); + interactionID = nbt.getString("interactionID"); placedRotation = nbt.getInteger("rotation"); if(nbt.hasKey("disguise")){ disguise = Block.getBlockFromName(nbt.getString("disguise")); @@ -282,6 +299,7 @@ public class BlockWandSpawner extends BlockContainer implements ILookOverlay, IT buf.writeInt(placedRotation); BufferUtil.writeString(buf, actionID); BufferUtil.writeString(buf, conditionID); + BufferUtil.writeString(buf, interactionID); buf.writeInt(Block.getIdFromBlock(disguise)); buf.writeInt(disguiseMeta); } @@ -291,6 +309,7 @@ public class BlockWandSpawner extends BlockContainer implements ILookOverlay, IT placedRotation = buf.readInt(); actionID = BufferUtil.readString(buf); conditionID = BufferUtil.readString(buf); + interactionID = BufferUtil.readString(buf); disguise = Block.getBlockById(buf.readInt()); disguiseMeta = buf.readInt(); } @@ -300,8 +319,10 @@ public class BlockWandSpawner extends BlockContainer implements ILookOverlay, IT NBTTagCompound nbt = new NBTTagCompound(); nbt.setString("actionID", actionID); nbt.setString("conditionID", conditionID); + if(interactionID != null) + nbt.setString("interactionID", interactionID); if(disguise != null){ - nbt.setString("disguise", disguise.getUnlocalizedName()); + nbt.setString("disguise", GameRegistry.findUniqueIdentifierFor(disguise).toString()); nbt.setInteger("disguiseMeta", disguiseMeta); } @@ -312,6 +333,7 @@ public class BlockWandSpawner extends BlockContainer implements ILookOverlay, IT public void pasteSettings(NBTTagCompound nbt, int index, World world, EntityPlayer player, int x, int y, int z) { actionID = nbt.getString("actionID"); conditionID = nbt.getString("conditionID"); + interactionID = nbt.getString("interactionID"); if(nbt.hasKey("disguise")){ disguise = Block.getBlockFromName(nbt.getString("disguise")); disguiseMeta = nbt.getInteger("disguiseMeta"); diff --git a/src/main/java/com/hbm/blocks/generic/DungeonSpawner.java b/src/main/java/com/hbm/blocks/generic/DungeonSpawner.java index bba6ebfe7..52dbb6099 100644 --- a/src/main/java/com/hbm/blocks/generic/DungeonSpawner.java +++ b/src/main/java/com/hbm/blocks/generic/DungeonSpawner.java @@ -12,6 +12,7 @@ import com.hbm.world.gen.util.DungeonSpawnerActions; import com.hbm.world.gen.util.DungeonSpawnerConditions; import com.hbm.util.Vec3NT; +import com.hbm.world.gen.util.DungeonSpawnerInteractions; import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -59,22 +60,38 @@ public class DungeonSpawner extends BlockContainer { return super.getIcon(world, x, y, z, side); } + @Override + public boolean onBlockActivated(World worldIn, int x, int y, int z, EntityPlayer player, int side, float subX, float subY, float subZ) { + TileEntity te = worldIn.getTileEntity(x, y, z); + if(te instanceof TileEntityDungeonSpawner && ((TileEntityDungeonSpawner) te).interaction != null) { + ((TileEntityDungeonSpawner) te).interaction.accept(new Object[]{worldIn, te, x, y, z, player, side, subX, subY, subZ}); + return true; + } + return super.onBlockActivated(worldIn, x, y, z, player, side, subX, subY, subZ); + } public static class TileEntityDungeonSpawner extends TileEntity { + //phase is incremented per condition check, timer counts since last condition check by default public int phase = 0; public int timer = 0; public Block disguise; public int disguiseMeta; + /**Actions always get called before conditions, use the phase and timer variables in order to control behavior via conditions*/ public String conditionID = "ABERRATOR"; - //actions always get called before conditions, use the phase timer in order to control behavior via condition public String actionID = "ABERRATOR"; + /**Interactions are called on right click, and passes on the parameters of the right click to consumer*/ + public String interactionID; public Function condition; public Consumer action; + /**Consists of world instance, TileEntity instance, three ints for coordinates, one int for block side, and player instance, in that order **/ + public Consumer interaction; + + public EntityPlayer player; public ForgeDirection direction = ForgeDirection.UNKNOWN; @Override @@ -87,6 +104,10 @@ public class DungeonSpawner extends BlockContainer { if(condition == null){ condition = DungeonSpawnerConditions.conditions.get(conditionID); } + if(interaction == null && interactionID != null){ + interaction = DungeonSpawnerInteractions.interactions.get(interactionID); + } + if(action == null || condition == null){ worldObj.setBlock(xCoord,yCoord,zCoord, Blocks.air); return; @@ -105,8 +126,12 @@ public class DungeonSpawner extends BlockContainer { public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); nbt.setInteger("phase", phase); - nbt.setString("conditionID", conditionID); + nbt.setString("actionID", actionID); + nbt.setString("conditionID", conditionID); + if(interactionID != null) + nbt.setString("interactionID", interactionID); + nbt.setInteger("direction", direction.ordinal()); if(disguise != null){ nbt.setInteger("disguiseMeta", disguiseMeta); @@ -118,8 +143,13 @@ public class DungeonSpawner extends BlockContainer { public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); this.phase = nbt.getInteger("phase"); + + this.actionID = nbt.getString("actionID"); this.conditionID = nbt.getString("conditionID"); + if(nbt.hasKey("interactionID")) this.interactionID = nbt.getString("interactionID"); + this.direction = ForgeDirection.getOrientation(nbt.getInteger("direction")); + if(nbt.hasKey("disguise")){ disguiseMeta = nbt.getInteger("disguiseMeta"); disguise = Block.getBlockFromName(nbt.getString("disguise")); diff --git a/src/main/java/com/hbm/world/gen/util/DungeonSpawnerActions.java b/src/main/java/com/hbm/world/gen/util/DungeonSpawnerActions.java index 1e32d9dc7..fee835c2e 100644 --- a/src/main/java/com/hbm/world/gen/util/DungeonSpawnerActions.java +++ b/src/main/java/com/hbm/world/gen/util/DungeonSpawnerActions.java @@ -1,7 +1,7 @@ package com.hbm.world.gen.util; +import com.hbm.blocks.BlockDummyable; import com.hbm.blocks.ModBlocks; -import com.hbm.blocks.generic.BlockPedestal; import com.hbm.blocks.generic.BlockSkeletonHolder; import com.hbm.blocks.generic.DungeonSpawner; import com.hbm.entity.item.EntityFallingBlockNT; @@ -9,34 +9,30 @@ import com.hbm.entity.missile.EntityMissileTier2; import com.hbm.entity.mob.EntityUndeadSoldier; import com.hbm.items.ItemEnums; import com.hbm.items.ModItems; -import com.hbm.main.ModEventHandler; +import com.hbm.tileentity.TileEntityDoorGeneric; import com.hbm.tileentity.machine.storage.TileEntityCrateBase; +import com.hbm.util.ContaminationUtil; import com.hbm.util.MobUtil; import com.hbm.util.Vec3NT; import com.hbm.world.WorldUtil; +import net.minecraft.block.Block; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.effect.EntityLightningBolt; import net.minecraft.entity.monster.EntityZombie; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.inventory.IInventory; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.AxisAlignedBB; -import net.minecraft.util.ChatComponentText; -import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.*; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Random; +import java.util.*; import java.util.function.Consumer; public class DungeonSpawnerActions { - public static HashMap> actions = new HashMap<>(); + public static LinkedHashMap> actions = new LinkedHashMap<>(); public static Consumer PHASE_ABERRATOR = (tile) -> { World world = tile.getWorldObj(); @@ -122,14 +118,10 @@ public class DungeonSpawnerActions { Vec3NT vec = new Vec3NT(5, 0, 0); for (int i = 0; i < 10; i++) { EntityZombie mob = new EntityZombie(world); - for (int j = 0; j < 7; j++) { - mob.setPositionAndRotation(x + 0.5 + vec.xCoord, world.getHeightValue(x,z), z + 0.5 + vec.zCoord, i * 36F, 0); - MobUtil.assignItemsToEntity(mob, MobUtil.slotPoolAdv, new Random()); - if (mob.getCanSpawnHere()) { - world.spawnEntityInWorld(mob); - break; - } - } + mob.setPositionAndRotation(x + 0.5 + vec.xCoord, world.getHeightValue(x,z), z + 0.5 + vec.zCoord, i * 36F, 0); + MobUtil.assignItemsToEntity(mob, MobUtil.slotPoolAdv, new Random()); + world.spawnEntityInWorld(mob); + vec.rotateAroundYDeg(36D); } world.setBlock(x, y, z, ModBlocks.block_steel); @@ -178,6 +170,78 @@ public class DungeonSpawnerActions { world.setBlock(x,y,z, ModBlocks.block_electrical_scrap); }; + public static Consumer RAD_CONTAINMENT_SYSTEM = (tile) -> { + World world = tile.getWorldObj(); + int x = tile.xCoord; + int y = tile.yCoord; + int z = tile.zCoord; + + ForgeDirection direction = tile.direction.getOpposite(); + ForgeDirection rot = direction.getRotation(ForgeDirection.UP); + + AxisAlignedBB bb = AxisAlignedBB.getBoundingBox(x - rot.offsetX, y - 1, z - rot.offsetZ, x + rot.offsetX + direction.offsetX * 15, y + 1, z + rot.offsetZ + direction.offsetZ * 15).expand(2,2,2); + + List entities = world.getEntitiesWithinAABB(EntityLivingBase.class, bb); + + for(EntityLivingBase e : entities) { + + Vec3 vec = Vec3.createVectorHelper(e.posX - (x + 0.5), (e.posY + e.getEyeHeight()) - (y + 0.5), e.posZ - (z + 0.5)); + double len = vec.lengthVector(); + vec = vec.normalize(); + + len = Math.max(len,1D); + + float res = 0; + + for(int i = 1; i < len; i++) { + + int ix = (int)Math.floor(x + 0.5 + vec.xCoord * i); + int iy = (int)Math.floor(y + 0.5 + vec.yCoord * i); + int iz = (int)Math.floor(z + 0.5 + vec.zCoord * i); + + res += world.getBlock(ix, iy, iz).getExplosionResistance(null); + } + + if(res < 1) + res = 1; + + float eRads = 100F; + eRads /= (float)res; + eRads /= (float)(len * len); + + ContaminationUtil.contaminate(e, ContaminationUtil.HazardType.RADIATION, ContaminationUtil.ContaminationType.HAZMAT2, eRads); + } + + if (tile.phase == 2 && tile.timer > 40){ + world.getClosestPlayer(x,y,z, 25).addChatMessage(new ChatComponentText( + EnumChatFormatting.LIGHT_PURPLE + "[RAD CONTAINMENT SYSTEM]" + + EnumChatFormatting.RESET + " Diagnostics found containment failure, commencing lockdown")); + + for(int i = 1; i < 20; i++) { + int checkX, checkY, checkZ; + checkX = x + direction.offsetX * i; + checkY = y + 1; + checkZ = z + direction.offsetZ * i; + Block block = world.getBlock(checkX, checkY,checkZ); + TileEntity te = null; + if(block instanceof BlockDummyable){ + int[] coreCoords = ((BlockDummyable) block).findCore(world,checkX,checkY,checkZ); + te = world.getTileEntity(coreCoords[0], coreCoords[1], coreCoords[2]); + } + + if (te instanceof TileEntityDoorGeneric) { + TileEntityDoorGeneric door = (TileEntityDoorGeneric) te; + door.setPins(456); + door.close(); + door.lock(); + break; + } + } + + tile.phase = 3; + } + }; + public static List getActionNames(){ return new ArrayList<>(actions.keySet()); } @@ -189,6 +253,7 @@ public class DungeonSpawnerActions { actions.put("FODDER_WAVE", FODDER_WAVE); actions.put("PUZZLE_TEST", PUZZLE_TEST); actions.put("MISSILE_STRIKE", MISSILE_STRIKE); + actions.put("IRRADIATE_ENTITIES_AOE", RAD_CONTAINMENT_SYSTEM); } diff --git a/src/main/java/com/hbm/world/gen/util/DungeonSpawnerConditions.java b/src/main/java/com/hbm/world/gen/util/DungeonSpawnerConditions.java index 0a634c271..83dd773e8 100644 --- a/src/main/java/com/hbm/world/gen/util/DungeonSpawnerConditions.java +++ b/src/main/java/com/hbm/world/gen/util/DungeonSpawnerConditions.java @@ -15,12 +15,16 @@ import net.minecraft.world.World; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.function.Function; public class DungeonSpawnerConditions { - public static HashMap> conditions = new HashMap<>(); + public static LinkedHashMap> conditions = new LinkedHashMap<>(); + + /**For use with interactions, for having them handle all conditional tasks*/ + public static Function EMPTY = (tile) -> false; public static Function ABERRATOR = (tile) -> { World world = tile.getWorldObj(); @@ -82,6 +86,7 @@ public class DungeonSpawnerConditions { //register new conditions here static { + conditions.put("EMPTY", EMPTY); conditions.put("ABERRATOR", ABERRATOR); conditions.put("PLAYER_CUBE_5", PLAYER_CUBE_5); conditions.put("REDSTONE", REDSTONE); diff --git a/src/main/java/com/hbm/world/gen/util/DungeonSpawnerInteractions.java b/src/main/java/com/hbm/world/gen/util/DungeonSpawnerInteractions.java new file mode 100644 index 000000000..32c19b81d --- /dev/null +++ b/src/main/java/com/hbm/world/gen/util/DungeonSpawnerInteractions.java @@ -0,0 +1,80 @@ +package com.hbm.world.gen.util; + +import com.hbm.blocks.generic.DungeonSpawner.TileEntityDungeonSpawner; +import com.hbm.entity.missile.EntityMissileTier2; +import com.hbm.items.ModItems; +import com.hbm.potion.HbmPotion; +import com.hbm.tileentity.TileEntityDoorGeneric; +import com.hbm.util.Vec3NT; +import com.hbm.world.WorldUtil; +import net.minecraft.block.Block; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.potion.PotionEffect; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.function.Consumer; + +/**Interactions are called when the player right-clicks the block**/ +public class DungeonSpawnerInteractions { + + /**Consumer consists of world instance, tile entity instance, three ints for coordinates, one int for block side, and player instance, + * in that order **/ + public static LinkedHashMap> interactions = new LinkedHashMap<>(); + + public static Consumer TEST = (array) -> { + World world = (World) array[0]; + TileEntityDungeonSpawner spawner = (TileEntityDungeonSpawner) array[1]; + int x = (int) array[2]; + int y = (int) array[3]; + int z = (int) array[4]; + EntityPlayer player = (EntityPlayer) array[5]; + int side = (int) array[6]; + + if(spawner.phase > 1) return; + + if(player.getHeldItem() != null) + player.getHeldItem().stackSize--; + + spawner.phase++; + }; + + public static Consumer RAD_CONTAINMENT_SYSTEM = (array) -> { + TileEntityDungeonSpawner spawner = (TileEntityDungeonSpawner) array[1]; + EntityPlayer player = (EntityPlayer) array[5]; + + if(player.getHeldItem() != null && player.getHeldItem().getItem() == ModItems.key){ + player.getHeldItem().stackSize--; + player.addChatMessage(new ChatComponentText( + EnumChatFormatting.LIGHT_PURPLE + "[RAD CONTAINMENT SYSTEM]" + + EnumChatFormatting.RESET + " Radiation treatment administered")); + player.addPotionEffect(new PotionEffect(HbmPotion.radaway.getId(), 3 * 60 * 20, 4)); + player.addPotionEffect(new PotionEffect(HbmPotion.radx.getId(), 3 * 60 * 20, 4)); + spawner.phase = 2; + spawner.timer = 0; + } + }; + + + + public static List getInteractionNames(){ + return new ArrayList<>(interactions.keySet()); + } + + //register new interactions here + static{ + interactions.put("TEST", TEST); + interactions.put("RADAWAY_INJECTOR", RAD_CONTAINMENT_SYSTEM); + } + + + +}