Allow Alchemite, Blast Phials, Injections, Incubated Eggs, and Greatwood/Thaumium boats to be shot by dispensers.

This commit is contained in:
koolkrafter5 committed 2025-08-15 08:51:13 -04:00
1 parent 76258cd038
commit 543482942a
5 files changed
+193 -12

No files matched your search

@@ -8,16 +8,24 @@ package com.kentington.thaumichorizons.common;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDispenser;
import net.minecraft.block.material.MapColor;
import net.minecraft.block.material.Material;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.dispenser.BehaviorDefaultDispenseItem;
import net.minecraft.dispenser.BehaviorProjectileDispense;
import net.minecraft.dispenser.IBlockSource;
import net.minecraft.dispenser.IPosition;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.IProjectile;
import net.minecraft.entity.monster.EntityBlaze;
import net.minecraft.entity.monster.EntityEnderman;
import net.minecraft.entity.monster.EntityGhast;
@@ -44,7 +52,9 @@ import net.minecraft.item.crafting.ShapelessRecipes;
import net.minecraft.nbt.NBTTagByte;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.Potion;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Configuration;
@@ -57,6 +67,7 @@ import net.minecraftforge.oredict.ShapelessOreRecipe;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.google.common.collect.Sets;
import com.kentington.thaumichorizons.client.lib.RenderEventHandler;
import com.kentington.thaumichorizons.common.blocks.BlockAlchemite;
import com.kentington.thaumichorizons.common.blocks.BlockBloodInfuser;
@@ -132,6 +143,7 @@ import com.kentington.thaumichorizons.common.entities.EntitySyringe;
import com.kentington.thaumichorizons.common.entities.EntityTaintPig;
import com.kentington.thaumichorizons.common.entities.EntityVoltSlime;
import com.kentington.thaumichorizons.common.entities.ItemSpawnerEgg;
import com.kentington.thaumichorizons.common.handlers.BehaviorDispenseBoat;
import com.kentington.thaumichorizons.common.items.ItemAmuletMirror;
import com.kentington.thaumichorizons.common.items.ItemBarChocolate;
import com.kentington.thaumichorizons.common.items.ItemBoatGreatwood;
@@ -3631,6 +3643,7 @@ public class ThaumicHorizons {
new ItemStack(Items.dye, 1, 0), new ItemStack(Items.dye, 1, 15) },
10));
addAspectsToAllTheThings();
registerDispenserBehavior();
}
public static CreatureInfusionRecipe getCreatureInfusion(EntityLivingBase entityContained,
@@ -3889,6 +3902,96 @@ public class ThaumicHorizons {
(new AspectList()).add(Aspect.WEAPON, 3).add(Aspect.BEAST, 3));
}
private static void registerDispenserBehavior() {
BlockDispenser.dispenseBehaviorRegistry
.putObject(Item.getItemFromBlock(blockAlchemite), new BehaviorDefaultDispenseItem() {
@Override
protected ItemStack dispenseStack(IBlockSource dispenser, ItemStack dispensedItem) {
EnumFacing enumfacing = BlockDispenser.func_149937_b(dispenser.getBlockMetadata());
World world = dispenser.getWorld();
int x = dispenser.getXInt() + enumfacing.getFrontOffsetX();
int y = dispenser.getYInt() + enumfacing.getFrontOffsetY();
int z = dispenser.getZInt() + enumfacing.getFrontOffsetZ();
EntityAlchemitePrimed primedAlchemite = new EntityAlchemitePrimed(
world,
x + 0.5F,
y + 0.5F,
z + 0.5F,
null);
world.spawnEntityInWorld(primedAlchemite);
world.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, "game.tnt.primed", 1.0F, 1.0F);
dispensedItem.stackSize--;
return dispensedItem;
}
});
BlockDispenser.dispenseBehaviorRegistry.putObject(itemSyringeInjection, new BehaviorDefaultDispenseItem() {
@Override
public ItemStack dispenseStack(IBlockSource dispenser, ItemStack stack) {
if (!(stack.getItem() instanceof ItemSyringeInjection)) {
return super.dispenseStack(dispenser, stack);
}
World world = dispenser.getWorld();
EnumFacing facing = BlockDispenser.func_149937_b(dispenser.getBlockMetadata());
double spawnX = dispenser.getX() + facing.getFrontOffsetX();
double spawnY = dispenser.getY() + facing.getFrontOffsetY();
double spawnZ = dispenser.getZ() + facing.getFrontOffsetZ();
IProjectile projectile = createProjectile(
(ItemSyringeInjection) stack.getItem(),
stack,
world,
spawnX,
spawnY,
spawnZ);
projectile.setThrowableHeading(
facing.getFrontOffsetX(),
facing.getFrontOffsetY() + 0.1F,
facing.getFrontOffsetZ(),
1.1F, // velocity
6F // inaccuracy
);
world.spawnEntityInWorld((Entity) projectile);
stack.stackSize--;
return stack;
}
private IProjectile createProjectile(ItemSyringeInjection item, ItemStack stack, World world, double x,
double y, double z) {
if (item.isPhial(stack.getItemDamage())) {
return new EntityBlastPhial(world, x, y, z, stack);
} else {
return new EntitySyringe(world, x, y, z, stack.stackTagCompound);
}
}
@Override
protected void playDispenseSound(IBlockSource source) {
source.getWorld().playAuxSFX(1002, source.getXInt(), source.getYInt(), source.getZInt(), 0);
}
});
BlockDispenser.dispenseBehaviorRegistry.putObject(itemEggIncubated, new BehaviorProjectileDispense() {
protected IProjectile getProjectileEntity(World worldIn, IPosition position) {
return new EntityEggIncubated(worldIn, position.getX(), position.getY(), position.getZ());
}
});
BlockDispenser.dispenseBehaviorRegistry.putObject(
itemBoatGreatwood,
new BehaviorDispenseBoat(Collections.singleton(Material.water), EntityBoatGreatwood::new));
BlockDispenser.dispenseBehaviorRegistry.putObject(
itemBoatThaumium,
new BehaviorDispenseBoat(Sets.newHashSet(Material.water, Material.lava), EntityBoatThaumium::new));
}
static IRecipe shapelessOreDictRecipe(ItemStack res, Object[] params) {
ShapelessOreRecipe rec = new ShapelessOreRecipe(res, params);
CraftingManager.getInstance().getRecipeList().add(rec);
@@ -29,6 +29,7 @@ public class BlockAlchemite extends BlockTNT {
this.setBlockName("ThaumicHorizons_alchemite");
this.setBlockTextureName("ThaumicHorizons:alchemite");
this.setCreativeTab(ThaumicHorizons.tabTH);
this.setStepSound(soundTypeGrass); // same place/break sound as TNT
}
public void onBlockDestroyedByExplosion(final World p_149723_1_, final int p_149723_2_, final int p_149723_3_,
@@ -12,23 +12,27 @@ import net.minecraft.world.World;
public class EntityBlastPhial extends EntityPotion {
public EntityBlastPhial(final World p_i1790_1_) {
super(p_i1790_1_);
public EntityBlastPhial(final World world) {
super(world);
}
public EntityBlastPhial(final World p_i1790_1_, final EntityLivingBase p_i1790_2_, final float power,
final ItemStack p_i1790_3_) {
super(p_i1790_1_, p_i1790_2_, p_i1790_3_);
public EntityBlastPhial(final World world, final double x, final double y, final double z, final ItemStack stack) {
super(world, x, y, z, stack);
}
public EntityBlastPhial(final World world, final EntityLivingBase thrower, final float power,
final ItemStack stack) {
super(world, thrower, stack);
this.setSize(0.25f, 0.25f);
this.setSize(0.5f, 0.5f);
this.setLocationAndAngles(
p_i1790_2_.posX,
p_i1790_2_.posY + p_i1790_2_.getEyeHeight(),
p_i1790_2_.posZ,
p_i1790_2_.rotationYaw,
p_i1790_2_.rotationPitch);
thrower.posX,
thrower.posY + thrower.getEyeHeight(),
thrower.posZ,
thrower.rotationYaw,
thrower.rotationPitch);
this.posX -= MathHelper.cos(this.rotationYaw / 180.0f * (float) Math.PI) * 0.16f;
this.posY -= 0.10000000149011612;
this.posY -= 0.1;
this.posZ -= MathHelper.sin(this.rotationYaw / 180.0f * (float) Math.PI) * 0.16f;
this.setPosition(this.posX, this.posY, this.posZ);
this.yOffset = 0.0f;
@@ -39,6 +39,7 @@ import io.netty.buffer.ByteBuf;
public class EntitySyringe extends Entity implements IProjectile, IEntityAdditionalSpawnData {
public int color;
public int canBePickedUp;
public NBTTagCompound effects;
private boolean inGround;
private int field_145791_d;
@@ -50,7 +51,6 @@ public class EntitySyringe extends Entity implements IProjectile, IEntityAdditio
private int ticksInAir;
private int knockbackStrength;
private EntityLivingBase shootingEntity;
private int canBePickedUp;
private byte arrowShake;
private double damage;
@@ -146,6 +146,13 @@ public class EntitySyringe extends Entity implements IProjectile, IEntityAdditio
this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, p_i1756_3_ * 1.5f, 1.0f);
}
public EntitySyringe(World world, double x, double y, double z, NBTTagCompound effects) {
this(world, x, y, z);
this.effects = effects;
this.color = this.effects.getInteger("color");
this.canBePickedUp = 1;
}
public void writeEntityToNBT(final NBTTagCompound p_70014_1_) {
p_70014_1_.setTag("effects", this.effects);
p_70014_1_.setShort("xTile", (short) this.field_145791_d);
@@ -0,0 +1,66 @@
package com.kentington.thaumichorizons.common.handlers;
import java.util.Set;
import net.minecraft.block.BlockDispenser;
import net.minecraft.block.material.Material;
import net.minecraft.dispenser.BehaviorDefaultDispenseItem;
import net.minecraft.dispenser.IBlockSource;
import net.minecraft.entity.item.EntityBoat;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
public class BehaviorDispenseBoat extends BehaviorDefaultDispenseItem {
public interface BoatFactory {
EntityBoat create(World world, double x, double y, double z);
}
private final Set<Material> validMaterials;
private final BoatFactory boatFactory;
public BehaviorDispenseBoat(Set<Material> validMaterials, BoatFactory boatFactory) {
this.validMaterials = validMaterials;
this.boatFactory = boatFactory;
}
@Override
protected ItemStack dispenseStack(IBlockSource dispenser, ItemStack stack) {
EnumFacing facing = BlockDispenser.func_149937_b(dispenser.getBlockMetadata());
World world = dispenser.getWorld();
// Calculate spawn position slightly in front of the dispenser
double spawnX = dispenser.getX() + (facing.getFrontOffsetX() * 1.25F);
double spawnY = dispenser.getY() + (facing.getFrontOffsetY() * 1.125F) - 0.5F;
double spawnZ = dispenser.getZ() + (facing.getFrontOffsetZ() * 1.25F);
// Block coordinates in front of the dispenser
int targetX = dispenser.getXInt() + facing.getFrontOffsetX();
int targetY = dispenser.getYInt() + facing.getFrontOffsetY();
int targetZ = dispenser.getZInt() + facing.getFrontOffsetZ();
Material frontMaterial = world.getBlock(targetX, targetY, targetZ).getMaterial();
if (validMaterials.contains(frontMaterial)) {
spawnY++;
} else if (!Material.air.equals(frontMaterial)) {
return stack;
}
EntityBoat boat = boatFactory.create(world, spawnX, spawnY, spawnZ);
boat.rotationYaw = switch (facing) {
case NORTH -> 90.0F;
case WEST -> 180.0F;
case EAST -> 0.0F;
default -> -90.0F; // SOUTH or other
};
world.spawnEntityInWorld(boat);
stack.stackSize--;
return stack;
}
}