Skip to content

Commit

Permalink
Added Create Mod integration ( For when they can eventually fix their…
Browse files Browse the repository at this point in the history
  • Loading branch information
Sollace committed Oct 22, 2023
1 parent 435e4d7 commit 38a545e
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package eu.ha3.presencefootsteps.compat;

import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;

public interface ContraptionCollidable {
BlockState getCollidedStateAt(BlockPos pos);
}
46 changes: 46 additions & 0 deletions src/main/java/eu/ha3/presencefootsteps/compat/PFMixinPlugin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package eu.ha3.presencefootsteps.compat;

import java.util.List;
import java.util.Set;

import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;

import net.fabricmc.loader.api.FabricLoader;

public class PFMixinPlugin implements IMixinConfigPlugin {
private static final String MIXIN_PACKAGE = "eu.ha3.presencefootsteps.mixins.compat";

@Override
public void onLoad(String mixinPackage) { }

@Override
public String getRefMapperConfig() {
return null;
}

@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
if (mixinClassName.startsWith(MIXIN_PACKAGE)) {
if (mixinClassName.indexOf("create") != -1) {
return FabricLoader.getInstance().isModLoaded("create");
}
}
return true;
}

@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) { }

@Override
public List<String> getMixins() {
return null;
}

@Override
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { }

@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package eu.ha3.presencefootsteps.mixins.compat.create;

import org.apache.logging.log4j.util.TriConsumer;
import org.spongepowered.asm.mixin.Dynamic;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import eu.ha3.presencefootsteps.compat.ContraptionCollidable;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;

@Mixin(value = Entity.class, priority = 9999 /* Run us last */)
abstract class MEntity implements ContraptionCollidable {

private int lastCollidedContraptionStateTick = -1;
private BlockState lastCollidedContraptionState = Blocks.AIR.getDefaultState();

@Dynamic(
value = "forCollission(center, consumer) - Private member injected by Create. See: https://github.com/Fabricators-of-Create/Create/blob/49cc17e3de33c965b1c409130abe436821f7410c/src/main/java/com/simibubi/create/foundation/mixin/client/EntityContraptionInteractionMixin.java#L81C21-L81C21"
)
@Shadow
private void forCollision(Vec3d anchorPos, TriConsumer<Object, BlockState, BlockPos> action) {}

@Override
public BlockState getCollidedStateAt(BlockPos pos) {
if (lastCollidedContraptionStateTick != ((Entity)(Object)this).age) {
lastCollidedContraptionStateTick = ((Entity)(Object)this).age;
forCollision(((Entity)(Object)this).getPos().add(0, -0.2, 0), (unused, state, p) -> {
if (pos.equals(p)) {
lastCollidedContraptionState = state;
}
});
}
return lastCollidedContraptionState;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ public final void produceStep(LivingEntity ply, @Nullable State event, double ve

acoustics.playAcoustic(ply, "_SWIM", state, options);

playedSound |= solver.playAssociation(ply, solver.findAssociation(ply.getWorld(), ply.getBlockPos().down(), Solver.MESSY_FOLIAGE_STRATEGY), event);
playedSound |= solver.playAssociation(ply, solver.findAssociation(ply, ply.getBlockPos().down(), Solver.MESSY_FOLIAGE_STRATEGY), event);
} else {
if (!ply.isSneaky() || event.isExtraLoud()) {
playedSound |= solver.playAssociation(ply, solver.findAssociation(ply, verticalOffsetAsMinus, isRightFoot), event);
Expand Down Expand Up @@ -310,7 +310,7 @@ private void simulateBrushes(LivingEntity ply) {
return;
}

Association assos = solver.findAssociation(ply.getWorld(), BlockPos.ofFloored(
Association assos = solver.findAssociation(ply, BlockPos.ofFloored(
ply.getX(),
ply.getY() - 0.1D - (ply.hasVehicle() ? ply.getHeightOffset() : 0) - (ply.isOnGround() ? 0 : 0.25D),
ply.getZ()
Expand Down
50 changes: 30 additions & 20 deletions src/main/java/eu/ha3/presencefootsteps/world/PFSolver.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package eu.ha3.presencefootsteps.world;

import eu.ha3.presencefootsteps.compat.ContraptionCollidable;
import eu.ha3.presencefootsteps.sound.Isolator;
import eu.ha3.presencefootsteps.sound.Options;
import eu.ha3.presencefootsteps.sound.State;
Expand Down Expand Up @@ -106,7 +107,7 @@ private Association findAssociation(Entity player, BlockPos pos) {
collider = collider.expand(0.3, 0.5, 0.3);
}

Association worked = findAssociation(player.getWorld(), pos, collider);
Association worked = findAssociation(player, pos, collider);

// If it didn't work, the player has walked over the air on the border of a block.
// ------ ------ --> z
Expand Down Expand Up @@ -146,9 +147,9 @@ private Association findAssociation(Entity player, BlockPos pos) {
// < maxofX- maxofX+ >
// Take the maximum border to produce the sound
if (isXdangMax) { // If we are in the positive border, add 1, else subtract 1
worked = findAssociation(player.getWorld(), pos.east(xdang > 0 ? 1 : -1), collider);
worked = findAssociation(player, pos.east(xdang > 0 ? 1 : -1), collider);
} else {
worked = findAssociation(player.getWorld(), pos.south(zdang > 0 ? 1 : -1), collider);
worked = findAssociation(player, pos.south(zdang > 0 ? 1 : -1), collider);
}

// If that didn't work, then maybe the footstep hit in the
Expand All @@ -160,14 +161,14 @@ private Association findAssociation(Entity player, BlockPos pos) {

// Take the maximum direction and try with the orthogonal direction of it
if (isXdangMax) {
return findAssociation(player.getWorld(), pos.south(zdang > 0 ? 1 : -1), collider);
return findAssociation(player, pos.south(zdang > 0 ? 1 : -1), collider);
}

return findAssociation(player.getWorld(), pos.east(xdang > 0 ? 1 : -1), collider);
return findAssociation(player, pos.east(xdang > 0 ? 1 : -1), collider);
}

private String findForGolem(World world, BlockPos pos, String substrate) {
List<Entity> golems = world.getEntitiesByClass(Entity.class, new Box(pos), e -> !(e instanceof PlayerEntity));
List<Entity> golems = world.getEntitiesByClass(Entity.class, new Box(pos).expand(0.5, 0, 0.5), e -> !(e instanceof PlayerEntity));

if (!golems.isEmpty()) {
String golem = isolator.getGolemMap().getAssociation(golems.get(0).getType(), substrate);
Expand All @@ -182,14 +183,24 @@ private String findForGolem(World world, BlockPos pos, String substrate) {
return Emitter.UNASSIGNED;
}

private Association findAssociation(World world, BlockPos pos, Box collider) {
BlockState in = world.getBlockState(pos);
private BlockState getBlockStateAt(Entity entity, BlockPos pos) {
World world = entity.getWorld();
BlockState state = world.getBlockState(pos);

if (state.isAir() && (entity instanceof ContraptionCollidable collidable)) {
state = collidable.getCollidedStateAt(pos);
}
return state;
}

private Association findAssociation(Entity entity, BlockPos pos, Box collider) {
BlockState in = getBlockStateAt(entity, pos);

BlockPos up = pos.up();
BlockState above = world.getBlockState(up);
BlockState above = getBlockStateAt(entity, up);
// Try to see if the block above is a carpet...

String association = findForGolem(world, up, Lookup.CARPET_SUBSTRATE);
String association = findForGolem(entity.getWorld(), up, Lookup.CARPET_SUBSTRATE);
boolean wasGolem = false;
String wetAssociation = Emitter.NOT_EMITTER;

Expand All @@ -207,9 +218,9 @@ private Association findAssociation(World world, BlockPos pos, Box collider) {
// This condition implies that if the carpet is NOT_EMITTER, solving will
// CONTINUE with the actual block surface the player is walking on
// check the height of the block. If it's something very short, like a carpet, also look through it
if (in.isAir() || in.getCollisionShape(world, pos).getMax(Axis.Y) < 0.3F) {
if (in.isAir() || in.getCollisionShape(entity.getWorld(), pos).getMax(Axis.Y) < 0.3F) {
BlockPos down = pos.down();
BlockState below = world.getBlockState(down);
BlockState below = getBlockStateAt(entity, down);

association = isolator.getBlockMap().getAssociation(below, Lookup.FENCE_SUBSTRATE);

Expand All @@ -220,17 +231,17 @@ private Association findAssociation(World world, BlockPos pos, Box collider) {
}
}

VoxelShape shape = in.getCollisionShape(world, pos);
VoxelShape shape = in.getCollisionShape(entity.getWorld(), pos);
if (shape.isEmpty()) {
shape = in.getOutlineShape(world, pos);
shape = in.getOutlineShape(entity.getWorld(), pos);
}
if (!shape.isEmpty() && !shape.getBoundingBox().offset(pos).intersects(collider)) {
logger.debug("Skipping due to hitbox miss");
return Association.NOT_EMITTER;
}

if (!Emitter.isResult(association)) {
association = findForGolem(world, pos, Lookup.EMPTY_SUBSTRATE);
association = findForGolem(entity.getWorld(), pos, Lookup.EMPTY_SUBSTRATE);

if (!Emitter.isEmitter(association)) {
association = isolator.getBlockMap().getAssociation(in, Lookup.EMPTY_SUBSTRATE);
Expand All @@ -251,7 +262,7 @@ private Association findAssociation(World world, BlockPos pos, Box collider) {
}
}

if (Emitter.isEmitter(association) && (world.hasRain(up) || (!wasGolem && (in.getFluidState().isIn(FluidTags.WATER) || above.getFluidState().isIn(FluidTags.WATER))))) {
if (Emitter.isEmitter(association) && (entity.getWorld().hasRain(up) || (!wasGolem && (in.getFluidState().isIn(FluidTags.WATER) || above.getFluidState().isIn(FluidTags.WATER))))) {
// Only if the block is open to the sky during rain
// or the block is submerged
// or the block is waterlogged
Expand All @@ -277,10 +288,9 @@ private Association findAssociation(World world, BlockPos pos, Box collider) {
return Association.NOT_EMITTER;
}

// Check for primitive in register
BlockSoundGroup sounds = in.getSoundGroup();
String substrate = String.format(Locale.ENGLISH, "%.2f_%.2f", sounds.volume, sounds.pitch);

// Check for primitive in register
String primitive = isolator.getPrimitiveMap().getAssociation(sounds, substrate);

if (Emitter.isResult(primitive)) {
Expand All @@ -291,12 +301,12 @@ private Association findAssociation(World world, BlockPos pos, Box collider) {
}

@Override
public Association findAssociation(World world, BlockPos pos, String strategy) {
public Association findAssociation(LivingEntity ply, BlockPos pos, String strategy) {
if (!MESSY_FOLIAGE_STRATEGY.equals(strategy)) {
return Association.NOT_EMITTER;
}

BlockState above = world.getBlockState(pos.up());
BlockState above = getBlockStateAt(ply, pos.up());

String foliage = isolator.getBlockMap().getAssociation(above, Lookup.FOLIAGE_SUBSTRATE);

Expand Down
4 changes: 1 addition & 3 deletions src/main/java/eu/ha3/presencefootsteps/world/Solver.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import net.minecraft.entity.LivingEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

import eu.ha3.presencefootsteps.sound.State;

/**
Expand Down Expand Up @@ -45,5 +43,5 @@ public interface Solver {
* Find an association for a certain block assuming the player is standing on
* it, using a custom strategy which strategies are defined by the solver.
*/
Association findAssociation(World w, BlockPos pos, String strategy);
Association findAssociation(LivingEntity ply, BlockPos pos, String strategy);
}
4 changes: 3 additions & 1 deletion src/main/resources/presencefootsteps.mixin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"required": true,
"minVersion": "0.7",
"package": "eu.ha3.presencefootsteps.mixins",
"plugin" : "eu.ha3.presencefootsteps.compat.PFMixinPlugin",
"refmap": "presencefootsteps.mixin.refmap.json",
"compatibilityLevel": "JAVA_17",
"client": [
Expand All @@ -10,6 +11,7 @@
"MClientPlayNetworkHandler",
"MDebugHud",
"MLivingEntity",
"MSoundSystem"
"MSoundSystem",
"compat.create.MEntity"
]
}

0 comments on commit 38a545e

Please sign in to comment.