-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reworked block bumping to use an Event instead of entrypoints. No mor…
…e golden hammer!!!!!
- Loading branch information
1 parent
c211a28
commit 3a410d7
Showing
18 changed files
with
340 additions
and
518 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
src/main/java/com/floralquafloral/bumping/BlockBumpCallback.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package com.floralquafloral.bumping; | ||
|
||
import com.floralquafloral.mariodata.MarioClientSideData; | ||
import com.floralquafloral.mariodata.MarioData; | ||
import com.floralquafloral.mariodata.moveable.MarioTravelData; | ||
import net.fabricmc.fabric.api.event.Event; | ||
import net.fabricmc.fabric.api.event.EventFactory; | ||
import net.minecraft.block.BlockState; | ||
import net.minecraft.util.ActionResult; | ||
import net.minecraft.util.math.BlockPos; | ||
import net.minecraft.util.math.Direction; | ||
import net.minecraft.world.World; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
/** | ||
* Callback for Mario bumping a block in the world. | ||
* Used on the client and server. | ||
* On the client, called before the block is visibly displaced and the attempt is networked to the server. | ||
* On the server, called before the block is given a redstone signal. | ||
* Upon return: | ||
* - PASS falls back to further processing. | ||
* - DISPLACE cancels further processing and displaces the block. | ||
* - BREAK cancels further processing and destroys the block, dropping an item. | ||
* - CANCEL cancels further processing and does not bump the block (or network the attempt!!!). | ||
* - CANCEL_NETWORKED cancels further processing and does not visually displace the block, but will still be networked | ||
* if it occurs on the client. | ||
*/ | ||
public interface BlockBumpCallback { | ||
Event<BlockBumpCallback> EVENT = EventFactory.createArrayBacked(BlockBumpCallback.class, | ||
listeners -> (marioData, marioClientData, marioTravelData, world, blockPos, blockState, strength, modifier, direction) -> { | ||
for(BlockBumpCallback listener : listeners) { | ||
BlockBumpResult result = listener.bump( | ||
marioData, marioClientData, marioTravelData, | ||
world, blockPos, blockState, | ||
strength, modifier, direction | ||
); | ||
if(result != BlockBumpResult.PASS) return result; | ||
} | ||
|
||
|
||
return BlockBumpResult.PASS; | ||
} | ||
); | ||
|
||
BlockBumpResult bump( | ||
MarioData marioData, @Nullable MarioClientSideData marioClientData, @Nullable MarioTravelData marioTravelData, | ||
World world, BlockPos blockPos, BlockState blockState, | ||
int strength, int modifier, Direction direction | ||
); | ||
} |
132 changes: 132 additions & 0 deletions
132
src/main/java/com/floralquafloral/bumping/BlockBumpHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package com.floralquafloral.bumping; | ||
|
||
import com.floralquafloral.mariodata.MarioClientSideData; | ||
import com.floralquafloral.mariodata.MarioData; | ||
import com.floralquafloral.mariodata.moveable.MarioTravelData; | ||
import net.minecraft.block.Block; | ||
import net.minecraft.block.BlockState; | ||
import net.minecraft.registry.RegistryKeys; | ||
import net.minecraft.registry.tag.TagKey; | ||
import net.minecraft.util.Identifier; | ||
import net.minecraft.util.crash.CrashException; | ||
import net.minecraft.util.crash.CrashReport; | ||
import net.minecraft.util.crash.CrashReportSection; | ||
import net.minecraft.util.math.BlockPos; | ||
import net.minecraft.util.math.Direction; | ||
import net.minecraft.world.World; | ||
import org.jetbrains.annotations.Contract; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
import static com.floralquafloral.MarioQuaMario.MOD_ID; | ||
|
||
public class BlockBumpHandler { | ||
public static final TagKey<Block> UNBUMPABLE = | ||
TagKey.of(RegistryKeys.BLOCK, Identifier.of(MOD_ID, "unbumpable")); | ||
public static final TagKey<Block> BUMP_REGARDLESS_OF_HARDNESS = | ||
TagKey.of(RegistryKeys.BLOCK, Identifier.of(MOD_ID, "bump_regardless_of_hardness")); | ||
public static final TagKey<Block> EXTREMELY_EASY_TO_BUMP = | ||
TagKey.of(RegistryKeys.BLOCK, Identifier.of(MOD_ID, "extremely_easy_to_bump")); | ||
public static final TagKey<Block> UNBREAKABLE_FROM_BUMPING = | ||
TagKey.of(RegistryKeys.BLOCK, Identifier.of(MOD_ID, "unbreakable_from_bumping")); | ||
|
||
public static final TagKey<Block> DO_NOT_POWER = | ||
TagKey.of(RegistryKeys.BLOCK, Identifier.of(MOD_ID, "do_not_power_on_bump")); | ||
|
||
public static final Set<BlockPos> FORCED_SIGNALS = new HashSet<>(); | ||
public static final Set<ForcedSignalSpot> FORCED_SIGNALS_DATA = new HashSet<>(); | ||
|
||
public static BlockBumpResult processBumpResult( | ||
MarioData marioData, @Nullable MarioClientSideData marioClientData, @Nullable MarioTravelData marioTravelData, | ||
World world, BlockPos blockPos, BlockState blockState, | ||
int strength, int modifier, Direction direction | ||
) { | ||
BlockBumpResult result = getBumpResult( | ||
marioData, marioClientData, marioTravelData, | ||
world, blockPos, blockState, | ||
strength, modifier, direction | ||
); | ||
|
||
if(result == BlockBumpResult.PASS) { | ||
CrashReport crashReport = CrashReport.create(new InvalidBumpResultException(), "Bumping a block"); | ||
throw new CrashException(crashReport); | ||
} | ||
|
||
if(result == BlockBumpResult.BREAK) world.breakBlock(blockPos, true, marioData.getMario()); | ||
else if(result == BlockBumpResult.DISPLACE) { | ||
// Apply redstone power | ||
if(!blockState.isIn(BlockBumpHandler.DO_NOT_POWER)) { | ||
BlockBumpHandler.FORCED_SIGNALS.add(blockPos); | ||
BlockBumpHandler.FORCED_SIGNALS_DATA.add(new BlockBumpHandler.ForcedSignalSpot(blockPos, world)); | ||
world.updateNeighbor(blockPos, blockState.getBlock(), blockPos); | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
|
||
private static class InvalidBumpResultException extends RuntimeException {} | ||
|
||
private static BlockBumpResult getBumpResult( | ||
MarioData marioData, @Nullable MarioClientSideData marioClientData, @Nullable MarioTravelData marioTravelData, | ||
World world, BlockPos blockPos, BlockState blockState, | ||
int strength, int modifier, Direction direction | ||
) { | ||
BlockBumpResult result = BlockBumpCallback.EVENT.invoker().bump( | ||
marioData, marioClientData, marioTravelData, | ||
world, blockPos, blockState, | ||
strength, modifier, direction | ||
); | ||
if (result != BlockBumpResult.PASS) | ||
return result; | ||
else { | ||
if(blockState.isIn(BlockBumpHandler.UNBUMPABLE)) return BlockBumpResult.CANCEL; | ||
if(blockState.isIn(BlockBumpHandler.BUMP_REGARDLESS_OF_HARDNESS) && strength >= 4) return BlockBumpResult.DISPLACE; | ||
if(blockState.isIn(BlockBumpHandler.EXTREMELY_EASY_TO_BUMP) && strength >= 1) return BlockBumpResult.DISPLACE; | ||
|
||
int modifiedStrength = strength + modifier; | ||
|
||
float adjustedHardness = blockState.getHardness(world, blockPos); | ||
if(blockState.isTransparent(world, blockPos) && !blockState.hasSidedTransparency()) adjustedHardness *= 0.5F; | ||
|
||
if(adjustedHardness == -1 || modifiedStrength <= 1) return BlockBumpResult.CANCEL; | ||
|
||
BlockBumpResult strongEnoughToBreakResult = | ||
blockState.isIn(UNBREAKABLE_FROM_BUMPING) ? BlockBumpResult.DISPLACE : BlockBumpResult.BREAK; | ||
|
||
// Super Mario spin-jumping can destroy fairly fragile blocks (ice, leaves). | ||
// Failing to destroy a block in this manner won't bump it at all. | ||
if(modifiedStrength == 2) | ||
return (adjustedHardness <= 0.25F) ? strongEnoughToBreakResult : BlockBumpResult.CANCEL; | ||
|
||
BlockBumpResult failedToBreakResult = (adjustedHardness <= 0.75F * Math.max(strength, modifiedStrength)) | ||
? BlockBumpResult.DISPLACE : BlockBumpResult.CANCEL; | ||
|
||
// Small Mario ground-pounding or bopping a ceiling can only break exceptionally fragile blocks (candles, moss, scaffolding). | ||
if(modifiedStrength == 3) | ||
return (adjustedHardness < 0.2F) ? strongEnoughToBreakResult : failedToBreakResult; | ||
|
||
// If we get to this point, we know for sure modifiedStrength >= 3. | ||
// Super Mario gets a bonus to breaking bricks | ||
if(blockState.getBlock().toString().contains("brick")) adjustedHardness -= 1; | ||
|
||
// Super Mario ground-pounding or bopping a ceiling can break somewhat fragile blocks (dirt, pumpkins), | ||
// and relatively weak brick blocks (mud bricks, stone bricks, NOT end bricks) | ||
return (adjustedHardness <= modifiedStrength * 0.25F) ? strongEnoughToBreakResult : failedToBreakResult; | ||
} | ||
} | ||
|
||
public static class ForcedSignalSpot { | ||
public final BlockPos POSITION; | ||
public final World WORLD; | ||
public int delay; | ||
|
||
private ForcedSignalSpot(BlockPos position, World world) { | ||
this.POSITION = position; | ||
this.WORLD = world; | ||
this.delay = 3; | ||
} | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
src/main/java/com/floralquafloral/bumping/BlockBumpResult.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.floralquafloral.bumping; | ||
|
||
public enum BlockBumpResult { | ||
PASS, | ||
DISPLACE, | ||
BREAK, | ||
CANCEL, | ||
CANCEL_NETWORKED | ||
} |
Oops, something went wrong.