Skip to content

Commit bace42a

Browse files
committed
gargoyle particles, sounds & hitboxes
1 parent 602c33c commit bace42a

25 files changed

+278
-46
lines changed

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ dependencies {
9797
annotationProcessor "org.spongepowered:mixin:${mixin_version}:processor"
9898

9999
// Compatibilities
100-
runtimeOnly(fg.deobf("maven.modrinth:create:${create_version}"))
100+
implementation(fg.deobf("maven.modrinth:create:${create_version}"))
101101

102102
// For dev testing
103103
runtimeOnly(fg.deobf("maven.modrinth:scannable:${scannable_version}"))
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
// 1.20.1 2024-02-29T16:37:03.2403501 Sound Definitions
2-
47254237d13fdbae0fc8e5a730e2c1370f1a0156 assets/oreganized/sounds.json
1+
// 1.20.1 2024-08-13T20:16:24.7249289 Sound Definitions
2+
1c624d0138bd1190491dbcf118dbe3556f4f0713 assets/oreganized/sounds.json

src/generated/resources/assets/oreganized/lang/en_us.json

+1
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
"item.oreganized.smithing_template.electrum_upgrade.additions_slot_description": "Add Electrum Ingot",
133133
"item.oreganized.smithing_template.electrum_upgrade.applies_to": "Diamond Equipment",
134134
"item.oreganized.smithing_template.electrum_upgrade.ingredients": "Electrum Ingot",
135+
"subtitles.block.gargoyle.growl": "Gargoyle growls",
135136
"subtitles.entity.shrapnel_bomb.primed": "Shrapnel Bomb fizzes",
136137
"tooltip.oreganized.wip.description": "Usages for this item will be available in a future release",
137138
"tooltip.oreganized.wip.title": "Work In Progress",

src/generated/resources/assets/oreganized/sounds.json

+8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
{
2+
"block.gargoyle.growl": {
3+
"sounds": [
4+
"oreganized:block/gargoyle_growl_1",
5+
"oreganized:block/gargoyle_growl_2",
6+
"oreganized:block/gargoyle_growl_3"
7+
],
8+
"subtitle": "subtitles.block.gargoyle.growl"
9+
},
210
"entity.bolt_hit": {
311
"sounds": [
412
"oreganized:entity/bolt_hit"

src/main/java/galena/oreganized/Oreganized.java

+15-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.teamabnormals.blueprint.core.util.DataUtil;
66
import com.teamabnormals.blueprint.core.util.registry.RegistryHelper;
77
import galena.oreganized.client.OreganizedClient;
8+
import galena.oreganized.compat.create.CreateCompat;
89
import galena.oreganized.content.block.MoltenLeadCauldronBlock;
910
import galena.oreganized.content.entity.LeadBoltEntity;
1011
import galena.oreganized.data.OAdvancements;
@@ -32,6 +33,7 @@
3233
import galena.oreganized.index.OParticleTypes;
3334
import galena.oreganized.index.OPotions;
3435
import galena.oreganized.index.OStructures;
36+
import galena.oreganized.network.OreganizedNetwork;
3537
import galena.oreganized.world.AddItemLootModifier;
3638
import net.minecraft.DetectedVersion;
3739
import net.minecraft.client.renderer.item.ItemProperties;
@@ -79,6 +81,7 @@
7981
import net.minecraftforge.eventbus.api.IEventBus;
8082
import net.minecraftforge.eventbus.api.SubscribeEvent;
8183
import net.minecraftforge.fluids.FluidInteractionRegistry;
84+
import net.minecraftforge.fml.ModList;
8285
import net.minecraftforge.fml.common.Mod;
8386
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
8487
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
@@ -104,6 +107,7 @@ public class Oreganized {
104107
public static ResourceLocation modLoc(String location) {
105108
return new ResourceLocation(MOD_ID, location);
106109
}
110+
107111
public static final RegistryHelper REGISTRY_HELPER = new RegistryHelper(MOD_ID);
108112

109113
private static final DeferredRegister<Codec<? extends IGlobalLootModifier>> LOOT_MODIFIERS = DeferredRegister.create(ForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, Oreganized.MOD_ID);
@@ -139,6 +143,12 @@ public Oreganized() {
139143

140144
REGISTRY_HELPER.register(modBus);
141145

146+
OreganizedNetwork.register();
147+
148+
if (ModList.get().isLoaded("create")) {
149+
CreateCompat.register();
150+
}
151+
142152
//CompatHandler.register();
143153

144154
//context.registerConfig(ModConfig.Type.COMMON, OreganizedConfig.COMMON_SPEC);
@@ -181,9 +191,9 @@ private void setup(FMLCommonSetupEvent event) {
181191

182192
CauldronInteraction.addDefaultInteractions(MoltenLeadCauldronBlock.INTERACTION_MAP);
183193

184-
PotionBrewing.addMix(Potions.WATER, OItems.LEAD_INGOT.get(), OPotions.STUNNING.get());
185-
PotionBrewing.addMix(OPotions.STUNNING.get(), Items.REDSTONE, OPotions.LONG_STUNNING.get());
186-
PotionBrewing.addMix(OPotions.STUNNING.get(), Items.GLOWSTONE_DUST, OPotions.STRONG_STUNNING.get());
194+
PotionBrewing.addMix(Potions.WATER, OItems.LEAD_INGOT.get(), OPotions.STUNNING.get());
195+
PotionBrewing.addMix(OPotions.STUNNING.get(), Items.REDSTONE, OPotions.LONG_STUNNING.get());
196+
PotionBrewing.addMix(OPotions.STUNNING.get(), Items.GLOWSTONE_DUST, OPotions.STRONG_STUNNING.get());
187197

188198
FireBlock fire = (FireBlock) Blocks.FIRE;
189199
fire.setFlammable(OBlocks.SHRAPNEL_BOMB.get(), 15, 100);
@@ -305,8 +315,8 @@ public void buildCreativeModeTabContents(BuildCreativeModeTabContentsEvent event
305315
putAfter(entries, OBlocks.LEAD_PILLAR.get(), OBlocks.CUT_LEAD);
306316
putAfter(entries, OBlocks.LEAD_BRICKS.get(), OBlocks.LEAD_PILLAR);
307317
}
308-
if(tab == CreativeModeTabs.FUNCTIONAL_BLOCKS) {
309-
putBefore(entries,Blocks.CHEST, OBlocks.LEAD_BOLT_CRATE);
318+
if (tab == CreativeModeTabs.FUNCTIONAL_BLOCKS) {
319+
putBefore(entries, Blocks.CHEST, OBlocks.LEAD_BOLT_CRATE);
310320
}
311321
if (tab == CreativeModeTabs.COLORED_BLOCKS) {
312322
putBefore(entries, Items.SHULKER_BOX, OBlocks.WHITE_CRYSTAL_GLASS);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package galena.oreganized.client.particle;
2+
3+
import net.minecraft.client.multiplayer.ClientLevel;
4+
import net.minecraft.client.particle.GlowParticle;
5+
import net.minecraft.client.particle.Particle;
6+
import net.minecraft.client.particle.ParticleProvider;
7+
import net.minecraft.client.particle.SpriteSet;
8+
import net.minecraft.core.particles.SimpleParticleType;
9+
import org.jetbrains.annotations.Nullable;
10+
11+
public class VengeanceParticleProvider implements ParticleProvider<SimpleParticleType> {
12+
13+
private final ParticleProvider<SimpleParticleType> inner;
14+
15+
public VengeanceParticleProvider(SpriteSet sprites) {
16+
inner = new GlowParticle.WaxOffProvider(sprites);
17+
}
18+
19+
@Override
20+
public @Nullable Particle createParticle(SimpleParticleType type, ClientLevel level, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) {
21+
var particle = (GlowParticle) inner.createParticle(type, level, x, y, z, xSpeed, ySpeed, zSpeed);
22+
particle.quadSize *= 2F;
23+
return particle;
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package galena.oreganized.compat.create;
2+
3+
import com.simibubi.create.content.kinetics.mechanicalArm.ArmInteractionPointType;
4+
5+
public class CreateCompat {
6+
7+
public static void register() {
8+
ArmInteractionPointType.register(new GargoyleArmPointType());
9+
}
10+
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package galena.oreganized.compat.create;
2+
3+
import com.simibubi.create.content.kinetics.mechanicalArm.AllArmInteractionPointTypes;
4+
import com.simibubi.create.content.kinetics.mechanicalArm.ArmInteractionPoint;
5+
import com.simibubi.create.content.kinetics.mechanicalArm.ArmInteractionPointType;
6+
import galena.oreganized.Oreganized;
7+
import galena.oreganized.content.entity.GargoyleBlockEntity;
8+
import galena.oreganized.index.OBlocks;
9+
import net.minecraft.core.BlockPos;
10+
import net.minecraft.world.item.ItemStack;
11+
import net.minecraft.world.level.Level;
12+
import net.minecraft.world.level.block.state.BlockState;
13+
import org.jetbrains.annotations.Nullable;
14+
15+
public class GargoyleArmPointType extends ArmInteractionPointType {
16+
17+
public GargoyleArmPointType() {
18+
super(Oreganized.modLoc("gargoyle"));
19+
}
20+
21+
@Override
22+
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
23+
return state.is(OBlocks.GARGOYLE.get());
24+
}
25+
26+
@Override
27+
public @Nullable ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
28+
return new Point(level, pos, state);
29+
}
30+
31+
public class Point extends AllArmInteractionPointTypes.DepositOnlyArmInteractionPoint {
32+
33+
public Point(Level level, BlockPos pos, BlockState state) {
34+
super(GargoyleArmPointType.this, level, pos, state);
35+
}
36+
37+
@Override
38+
public ItemStack insert(ItemStack stack, boolean simulate) {
39+
var blockEntity = level.getBlockEntity(pos);
40+
if (!(blockEntity instanceof GargoyleBlockEntity gargoyle)) return stack;
41+
42+
var cloned = stack.copy();
43+
gargoyle.interact(level, pos, null, cloned, simulate);
44+
return cloned;
45+
}
46+
}
47+
}

src/main/java/galena/oreganized/content/block/GargoyleBlock.java

+69-11
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import net.minecraft.world.InteractionResult;
1313
import net.minecraft.world.entity.player.Player;
1414
import net.minecraft.world.item.context.BlockPlaceContext;
15+
import net.minecraft.world.level.BlockGetter;
1516
import net.minecraft.world.level.Level;
1617
import net.minecraft.world.level.block.Block;
1718
import net.minecraft.world.level.block.DispenserBlock;
@@ -24,22 +25,30 @@
2425
import net.minecraft.world.level.block.state.StateDefinition;
2526
import net.minecraft.world.level.block.state.properties.EnumProperty;
2627
import net.minecraft.world.phys.BlockHitResult;
28+
import net.minecraft.world.phys.Vec3;
29+
import net.minecraft.world.phys.shapes.CollisionContext;
30+
import net.minecraft.world.phys.shapes.Shapes;
31+
import net.minecraft.world.phys.shapes.VoxelShape;
2732
import org.jetbrains.annotations.Nullable;
2833

34+
import java.util.Map;
35+
2936
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.HORIZONTAL_FACING;
3037

3138
public class GargoyleBlock extends HorizontalDirectionalBlock implements EntityBlock {
3239

3340
public static final EnumProperty<AttachmentType> ATTACHMENT = EnumProperty.create("attachment", AttachmentType.class);
3441

42+
public final Map<BlockState, VoxelShape> SHAPES = getShapeForEachState(this::getShapeFor);
43+
3544
public static final DispenseItemBehavior DISPENSE_ITEM_BEHAVIOR = (source, stack) -> {
3645
var dispenser = source.getBlockState();
3746
var facing = dispenser.getValue(DispenserBlock.FACING);
3847
var targetPos = source.getPos().relative(facing);
3948
var target = source.getLevel().getBlockEntity(targetPos);
4049

4150
if (target instanceof GargoyleBlockEntity gargoyle) {
42-
gargoyle.interact(source.getLevel(), targetPos, null, stack);
51+
gargoyle.interact(source.getLevel(), targetPos, null, stack, false);
4352
}
4453

4554
return stack;
@@ -98,7 +107,7 @@ public InteractionResult use(BlockState state, Level level, BlockPos pos, Player
98107
var blockEntity = level.getBlockEntity(pos);
99108
if (blockEntity instanceof GargoyleBlockEntity gargoyle) {
100109
var stack = player.getItemInHand(hand);
101-
return gargoyle.interact(level, pos, player, stack);
110+
return gargoyle.interact(level, pos, player, stack, false);
102111
}
103112

104113
return super.use(state, level, pos, player, hand, hit);
@@ -109,16 +118,9 @@ public void animateTick(BlockState state, Level level, BlockPos pos, RandomSourc
109118
super.animateTick(state, level, pos, random);
110119

111120
if (random.nextBoolean() && level.isRainingAt(pos.above())) {
112-
var facing = state.getValue(FACING).getOpposite();
113-
var attachment = state.getValue(ATTACHMENT);
114121
double spread = random.nextDouble() * 0.1 - 0.05;
115-
double offsetX = facing.getAxis() == Direction.Axis.X ? facing.getStepX() * attachment.horizontalOffset : spread;
116-
double offsetZ = facing.getAxis() == Direction.Axis.Z ? facing.getStepZ() * attachment.horizontalOffset : spread;
117-
118-
double x = pos.getX() + 0.5 + offsetX;
119-
double y = pos.getY() + attachment.verticalOffset;
120-
double z = pos.getZ() + 0.5 + offsetZ;
121-
level.addParticle(ParticleTypes.DRIPPING_DRIPSTONE_WATER, x, y, z, 0.0, 0.0, 0.0);
122+
var offset = AttachmentType.offset(state, pos, spread);
123+
level.addParticle(ParticleTypes.DRIPPING_DRIPSTONE_WATER, offset.x, offset.y, offset.z, 0.0, 0.0, 0.0);
122124
}
123125
}
124126

@@ -142,10 +144,66 @@ public enum AttachmentType implements StringRepresentable {
142144
this.verticalOffset = verticalOffset;
143145
}
144146

147+
public static Vec3 offset(BlockState state, BlockPos pos, double spread) {
148+
var facing = state.getValue(FACING).getOpposite();
149+
var attachment = state.getValue(ATTACHMENT);
150+
double offsetX = facing.getAxis() == Direction.Axis.X ? facing.getStepX() * attachment.horizontalOffset : spread;
151+
double offsetZ = facing.getAxis() == Direction.Axis.Z ? facing.getStepZ() * attachment.horizontalOffset : spread;
152+
153+
double x = pos.getX() + 0.5 + offsetX;
154+
double y = pos.getY() + attachment.verticalOffset;
155+
double z = pos.getZ() + 0.5 + offsetZ;
156+
157+
return new Vec3(x, y, z);
158+
}
159+
145160
@Override
146161
public String getSerializedName() {
147162
return this.name;
148163
}
149164
}
150165

166+
protected VoxelShape getShapeFor(BlockState state) {
167+
var facing = state.getValue(FACING);
168+
var attachment = state.getValue(ATTACHMENT);
169+
170+
var xOffset = facing == Direction.EAST ? 1 : 0;
171+
var xSize = facing.getAxis() == Direction.Axis.X ? 1 : 0;
172+
var zOffset = facing == Direction.SOUTH ? 1 : 0;
173+
var zSize = facing.getAxis() == Direction.Axis.Z ? 1 : 0;
174+
175+
if (attachment == AttachmentType.FLOOR) {
176+
177+
var base = box(0.0, 0.0, 0.0, 16.0, 2.0, 16.0);
178+
var legs = box(xOffset * 11.0, 2.0, zOffset * 11.0, xOffset * 11.0 + 5.0 * xSize + 16.0 * zSize, 12.0, zOffset * 11.0 + 5.0 * zSize + 16.0 * xSize);
179+
var arms = box(xOffset * 12.0 + zSize - facing.getStepX() * 7.0, 2.0, zOffset * 12.0 + xSize - facing.getStepZ() * 7.0, xOffset * 12.0 + 4.0 * xSize + 15.0 * zSize - facing.getStepX() * 7.0, 17.0, zOffset * 12.0 + 4.0 * zSize + 15.0 * xSize - facing.getStepZ() * 7.0);
180+
var body = box(zSize * 2.0 + xOffset * 5.0 + 1.0, 7.0, xSize * 2.0 + zOffset * 5.0 + 1.0, xSize * 10.0 + xOffset * 5.0 + zSize * 13.0, 16.0, zSize * 10.0 + zOffset * 5.0 + xSize * 13.0);
181+
var head = box(zSize * 4.0 + xSize * 10.0 - xOffset * 10.0, 7.0, xSize * 4.0 + zSize * 10.0 - zOffset * 10.0, zSize * 12.0 + xSize * 16.0 - xOffset * 10.0, 15.0, xSize * 12.0 + zSize * 16.0 - zOffset * 10.0);
182+
183+
return Shapes.or(base, legs, arms, body, head);
184+
}
185+
186+
if (attachment == AttachmentType.WALL) {
187+
var base = box(xOffset * 14.0, 0.0, zOffset * 14.0, xOffset * 14.0 + 2.0 * xSize + 16.0 * zSize, 16.0, zOffset * 14.0 + 2.0 * zSize + 16.0 * xSize);
188+
var head = box(0.0, 0.0, 0.0, 8.0, 8.0, 8.0)
189+
.move(facing.getStepX() * -1.25, 5.0 / 16.0, facing.getStepZ() * -1.25)
190+
.move(xOffset * 0.5, 0.0, zOffset * 0.5)
191+
.move(zSize * 0.25, 0.0, xSize * 0.25);
192+
var body = box(0.0, 0.0, 0.0, 9.0, 9.0, 9.0)
193+
.move(facing.getStepX() * -11.0 / 16.0, 7.0 / 16.0, facing.getStepZ() * -11.0 / 16.0)
194+
.move(xOffset * 7.0 / 16.0, 0.0, zOffset * 7.0 / 16.0)
195+
.move(zSize * 0.25, 0.0, xSize * 0.25);
196+
var log = box(xOffset * 14.0, 0.0, zOffset * 14.0, xOffset * 14.0 + 4.0 * xSize + 4.0 * zSize, 4.0, zOffset * 14.0 + 4.0 * zSize + 16.0 * xSize)
197+
.move(xSize * 0.125 - xOffset * 0.375, 0.0, zSize * 0.125 - zOffset * 0.375);
198+
199+
return Shapes.or(base, body, head, log);
200+
}
201+
202+
return box(0.0, 0.0, 0.0, 16.0, 16.0, 16.0);
203+
}
204+
205+
@Override
206+
public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
207+
return SHAPES.get(state);
208+
}
151209
}

src/main/java/galena/oreganized/content/entity/GargoyleBlockEntity.java

+31-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
package galena.oreganized.content.entity;
22

3+
import galena.oreganized.content.block.GargoyleBlock;
34
import galena.oreganized.index.OBlockEntities;
5+
import galena.oreganized.index.OParticleTypes;
6+
import galena.oreganized.index.OSoundEvents;
47
import galena.oreganized.index.OTags;
8+
import galena.oreganized.network.OreganizedNetwork;
9+
import galena.oreganized.network.packet.GargoyleParticlePacket;
510
import galena.oreganized.world.ScaredOfGargoyleGoal;
611
import net.minecraft.core.BlockPos;
712
import net.minecraft.nbt.CompoundTag;
813
import net.minecraft.nbt.NbtUtils;
14+
import net.minecraft.sounds.SoundSource;
15+
import net.minecraft.util.ParticleUtils;
16+
import net.minecraft.util.valueproviders.UniformInt;
917
import net.minecraft.world.InteractionResult;
1018
import net.minecraft.world.entity.Mob;
1119
import net.minecraft.world.entity.MobType;
@@ -16,6 +24,7 @@
1624
import net.minecraft.world.level.block.state.BlockState;
1725
import net.minecraft.world.phys.AABB;
1826
import net.minecraft.world.phys.Vec3;
27+
import net.minecraftforge.network.PacketDistributor;
1928
import org.jetbrains.annotations.Nullable;
2029

2130
import java.util.Collection;
@@ -74,17 +83,38 @@ public void load(CompoundTag tag) {
7483
if (tag.contains("cooldown")) growlCooldown = tag.getInt("cooldown");
7584
}
7685

77-
public InteractionResult interact(Level level, BlockPos pos, @Nullable Player player, ItemStack stack) {
86+
public InteractionResult interact(Level level, BlockPos pos, @Nullable Player player, ItemStack stack, boolean simulate) {
7887
if (!stack.is(OTags.Items.GARGOYLE_SNACK)) return InteractionResult.PASS;
7988

8089
if (player == null || !player.getAbilities().instabuild) {
8190
stack.shrink(1);
8291
}
8392

93+
if (simulate) return InteractionResult.SUCCESS;
94+
8495
getTargets(level, pos).forEach(mob -> {
8596
mob.getPersistentData().put(ScaredOfGargoyleGoal.AVOID_TAG_KEY, NbtUtils.writeBlockPos(pos));
8697
});
8798

99+
level.playSound(null, pos.getX(), pos.getY(), pos.getZ(), OSoundEvents.GARGOYLE_GROWL.get(), SoundSource.BLOCKS, 1.0F, 1.0F);
100+
101+
if (!level.isClientSide) {
102+
OreganizedNetwork.CHANNEL.send(PacketDistributor.DIMENSION.with(level::dimension), new GargoyleParticlePacket(pos));
103+
}
104+
88105
return InteractionResult.SUCCESS;
89106
}
107+
108+
public void spawnParticles() {
109+
var pos = getBlockPos();
110+
var state = getBlockState();
111+
var facing = state.getValue(GargoyleBlock.FACING);
112+
var attachment = state.getValue(GargoyleBlock.ATTACHMENT);
113+
114+
ParticleUtils.spawnParticlesOnBlockFaces(level, pos, OParticleTypes.VENGEANCE.get(), UniformInt.of(0, 2));
115+
116+
if (attachment == GargoyleBlock.AttachmentType.WALL) {
117+
ParticleUtils.spawnParticlesOnBlockFaces(level, pos.relative(facing.getOpposite()), OParticleTypes.VENGEANCE.get(), UniformInt.of(0, 1));
118+
}
119+
}
90120
}

0 commit comments

Comments
 (0)