Skip to content

Commit

Permalink
feat: add files
Browse files Browse the repository at this point in the history
  • Loading branch information
rootEnginear committed Oct 14, 2023
1 parent fb75368 commit 7bf10fe
Show file tree
Hide file tree
Showing 20 changed files with 436 additions and 41 deletions.
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
<img align="right" height="128" width="128" alt="" loading="lazy" decoding="async" src="./src/main/resources/icon.png"/>

# Playground
# Bit by Bit

This is the beginning of awesome mods!
Eat foods Bit by Bit. Save the rest for later or split it with your friends.

> **Important**
> Required [Babric](https://github.com/Turnip-Labs/babric-instance-repo/releases) to run the mod.
## Features
## Credits

- Feature #1
- Feature #2
- Feature #3
- Eating sound by Mojang
- SoundHelper by [@UselessBullets/PrismaticLibe](https://github.com/UselessBullets/BTA_Babric_PrismaticLibe)
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ loader_version=0.14.19-babric.1-bta
# halplibe_version=2.3.0

# Mod
mod_version=1.0.0
mod_version=1.2.0
mod_group=rootenginear
mod_name=playground
mod_name=bitbybit
20 changes: 20 additions & 0 deletions src/main/java/rootenginear/bitbybit/BitByBit.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package rootenginear.bitbybit;

import net.fabricmc.api.ModInitializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import rootenginear.bitbybit.utils.SoundHelper;

public class BitByBit implements ModInitializer {
public static final String MOD_ID = "bitbybit";
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);

@Override
public void onInitialize() {
SoundHelper.addSound(MOD_ID, "eat1.ogg");
SoundHelper.addSound(MOD_ID, "eat2.ogg");
SoundHelper.addSound(MOD_ID, "eat3.ogg");

LOGGER.info("Bit by Bit initialized.");
}
}
43 changes: 43 additions & 0 deletions src/main/java/rootenginear/bitbybit/mixin/EntityWolfMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package rootenginear.bitbybit.mixin;

import net.minecraft.core.entity.animal.EntityWolf;
import net.minecraft.core.entity.player.EntityPlayer;
import net.minecraft.core.item.ItemFood;
import net.minecraft.core.item.ItemStack;
import net.minecraft.core.player.gamemode.Gamemode;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

@Mixin(value = {EntityWolf.class}, remap = false)
public class EntityWolfMixin {
@Redirect(
method = "interact(Lnet/minecraft/core/entity/player/EntityPlayer;)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/core/entity/player/EntityPlayer;getGamemode()Lnet/minecraft/core/player/gamemode/Gamemode;"
)
)
private Gamemode nibbleFood(EntityPlayer entityplayer) {
ItemStack itemstack = entityplayer.inventory.getCurrentItem();

if (entityplayer.getGamemode().consumeBlocks) {
itemstack.damageItem(1, entityplayer);
if (((ItemFood) itemstack.getItem()).getHealAmount() == 0) {
return Gamemode.survival;
}
}
return Gamemode.creative;
}

@Redirect(
method = "interact(Lnet/minecraft/core/entity/player/EntityPlayer;)Z",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/core/item/ItemFood;getHealAmount()I"
)
)
public int healFromNibble(ItemFood item) {
return 1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package rootenginear.bitbybit.mixin;

import net.minecraft.client.Minecraft;
import net.minecraft.core.entity.player.EntityPlayer;
import net.minecraft.core.item.Item;
import net.minecraft.core.item.ItemBucketIceCream;
import net.minecraft.core.item.ItemStack;
import net.minecraft.core.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import rootenginear.bitbybit.mixin.adapter.ItemAccessor;
import rootenginear.bitbybit.utils.ItemFoodEatEffect;

@Mixin(value = {ItemBucketIceCream.class}, remap = false)
public class ItemBucketIceCreamOverride {
@Shadow
protected int healAmount;

@Inject(method = "<init>", at = @At("RETURN"))
private void init(CallbackInfo ci) {
((ItemAccessor) this).setFoodMaxDamage(healAmount);
}

@Unique
public boolean consumeFood(ItemStack itemstack, EntityPlayer entityplayer) {
if (itemstack.stackSize <= 0) return false;

if (entityplayer.getGamemode().consumeBlocks) {
itemstack.damageItem(1, entityplayer);
if (itemstack.getItemDamageForDisplay() == healAmount) {
--itemstack.stackSize;
}
}
return true;
}

/**
* @author rootEnginear.bitbybit
* @reason Make food eat bit by bit
*/
@Overwrite
public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) {
if (entityplayer.health < 20 && consumeFood(itemstack, entityplayer)) {
ItemFoodEatEffect.playEatEffect(itemstack, world, entityplayer);
entityplayer.heal(1);
}
if (itemstack.stackSize == 0) return new ItemStack(Item.bucket);
return itemstack;
}

/**
* @author rootEnginear.bitbybit
* @reason Show how much leftover heals
* @implNote Somewhat buggy in multiplayer
*/
@Overwrite
public int getHealAmount() {
ItemStack currentItem = Minecraft.getMinecraft(Minecraft.class).thePlayer.inventory.getCurrentItem();
int damage = 0;
if (currentItem != null) damage = currentItem.getItemDamageForDisplay();
return healAmount - damage;
}
}
66 changes: 66 additions & 0 deletions src/main/java/rootenginear/bitbybit/mixin/ItemFoodOverride.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package rootenginear.bitbybit.mixin;

import net.minecraft.client.Minecraft;
import net.minecraft.core.entity.player.EntityPlayer;
import net.minecraft.core.item.ItemFood;
import net.minecraft.core.item.ItemStack;
import net.minecraft.core.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import rootenginear.bitbybit.mixin.adapter.ItemAccessor;
import rootenginear.bitbybit.utils.ItemFoodEatEffect;

@Mixin(value = {ItemFood.class}, remap = false)
public class ItemFoodOverride {
@Shadow
protected int healAmount;

@Inject(method = "<init>", at = @At("RETURN"))
private void init(CallbackInfo ci) {
((ItemAccessor) this).setFoodMaxDamage(healAmount);
}

@Unique
public boolean consumeFood(ItemStack itemstack, EntityPlayer entityplayer) {
if (itemstack.stackSize <= 0) return false;

if (entityplayer.getGamemode().consumeBlocks) {
itemstack.damageItem(1, entityplayer);
if (itemstack.getItemDamageForDisplay() == healAmount) {
--itemstack.stackSize;
}
}
return true;
}

/**
* @author rootEnginear.bitbybit
* @reason Make food eat bit by bit
*/
@Overwrite
public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) {
if (entityplayer.health < 20 && consumeFood(itemstack, entityplayer)) {
ItemFoodEatEffect.playEatEffect(itemstack, world, entityplayer);
entityplayer.heal(1);
}
return itemstack;
}

/**
* @author rootEnginear.bitbybit
* @reason Show how much leftover heals
* @implNote Somewhat buggy in multiplayer
*/
@Overwrite
public int getHealAmount() {
ItemStack currentItem = Minecraft.getMinecraft(Minecraft.class).thePlayer.inventory.getCurrentItem();
int damage = 0;
if (currentItem != null) damage = currentItem.getItemDamageForDisplay();
return healAmount - damage;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package rootenginear.bitbybit.mixin;

import net.minecraft.core.item.ItemFoodStackable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import rootenginear.bitbybit.mixin.adapter.ItemAccessor;

@Mixin(value = {ItemFoodStackable.class}, remap = false)
public abstract class ItemFoodStackableOverride {
@Inject(method = "<init>", at = @At("RETURN"))
private void init(CallbackInfo ci) {
((ItemAccessor) this).setMaxStackSize(1);
}
}
23 changes: 23 additions & 0 deletions src/main/java/rootenginear/bitbybit/mixin/ItemSoupOverride.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package rootenginear.bitbybit.mixin;

import net.minecraft.core.entity.player.EntityPlayer;
import net.minecraft.core.item.Item;
import net.minecraft.core.item.ItemSoup;
import net.minecraft.core.item.ItemStack;
import net.minecraft.core.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;

@Mixin(value = {ItemSoup.class}, remap = false)
public class ItemSoupOverride extends ItemFoodOverride {
/**
* @author rootEnginear.bitbybit
* @reason Make food eat bit by bit
*/
@Overwrite
public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) {
super.onItemRightClick(itemstack, world, entityplayer);
if (itemstack.stackSize == 0) return new ItemStack(Item.bowl);
return itemstack;
}
}
39 changes: 39 additions & 0 deletions src/main/java/rootenginear/bitbybit/mixin/RenderGlobalMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package rootenginear.bitbybit.mixin;

import net.minecraft.client.Minecraft;
import net.minecraft.client.render.RenderGlobal;
import net.minecraft.core.entity.fx.EntitySlimeFX;
import net.minecraft.core.item.Item;
import net.minecraft.core.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Mixin(value = {RenderGlobal.class}, remap = false)
public class RenderGlobalMixin {
@Shadow
private Minecraft mc;

@Shadow
private World worldObj;

@Inject(method = "addParticle(Ljava/lang/String;DDDDDDD)V", at = @At("HEAD"), cancellable = true)
public void addFoodParticle(String particleId, double x, double y, double z, double motionX, double motionY, double motionZ, double maxDistance, CallbackInfo ci) {
Pattern foodItemPattern = Pattern.compile("bitbybit\\.(.+)");
Matcher foodMatch = foodItemPattern.matcher(particleId);
if (foodMatch.matches() && this.mc != null && this.mc.activeCamera != null && this.mc.effectRenderer != null) {
double d6 = this.mc.activeCamera.getX() - x;
double d7 = this.mc.activeCamera.getY() - y;
double d8 = this.mc.activeCamera.getZ() - z;
if (!(d6 * d6 + d7 * d7 + d8 * d8 > maxDistance * maxDistance)) {
this.mc.effectRenderer.addEffect(new EntitySlimeFX(this.worldObj, x, y, z, Item.itemsList[Integer.parseInt(foodMatch.group(1))]));
}
ci.cancel();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package rootenginear.bitbybit.mixin.adapter;

import net.minecraft.core.item.Item;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;

@Mixin(value = {Item.class}, remap = false)
public interface ItemAccessor {
@Invoker("setMaxDamage")
Item setFoodMaxDamage(int i);

@Accessor("maxStackSize")
void setMaxStackSize(int maxStackSize);
}
31 changes: 31 additions & 0 deletions src/main/java/rootenginear/bitbybit/utils/ItemFoodEatEffect.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package rootenginear.bitbybit.utils;

import net.minecraft.core.entity.player.EntityPlayer;
import net.minecraft.core.item.ItemStack;
import net.minecraft.core.world.World;

import java.util.Random;

public class ItemFoodEatEffect {
public static void playEatEffect(ItemStack itemstack, World world, EntityPlayer entityplayer) {
final Random rand = new Random();

final double yRotRad = entityplayer.yRot * Math.PI / 180.0F;
final double xRotRad = entityplayer.xRot * Math.PI / 180.0F;

final double mouthDistConst = 0.3F;
final double mouthShift = Math.cos(xRotRad) * mouthDistConst;
final double xShift = Math.sin(yRotRad) * mouthShift;
final double zShift = Math.cos(yRotRad) * mouthShift;
final double yShift = Math.sin(xRotRad) * 0.3F;

for (int i = 0; i < 2; i++) {
world.spawnParticle("bitbybit." + itemstack.getItem().id, entityplayer.x - xShift, entityplayer.y - 0.2F - yShift, entityplayer.z + zShift, 0.0, 0.0, 0.0);
}

final float volume = ((float) (rand.nextInt(3) + 1)) / 0.5F;
final float pitch = ((float) rand.nextInt(5)) / 10.0F + 0.8F;

world.playSoundAtEntity(entityplayer, "bitbybit.eat", volume, pitch);
}
}
Loading

0 comments on commit 7bf10fe

Please sign in to comment.