Compare commits

..

4 Commits

13 changed files with 208 additions and 78 deletions

View File

@ -1,8 +1,12 @@
package xyz.pixelatedw.finalbeta;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import net.fabricmc.api.ModInitializer;
public class MainMod implements ModInitializer {
public static final Logger LOGGER = LogManager.getLogger();
@Override
public void onInitialize() {

View File

@ -36,6 +36,8 @@ public class ModConfig {
"Allows 2 or more items of the same type to be repaired using a crafting table using the same formula as modern day vanilla uses");
public static final Option<Boolean> ENABLE_WHITE_WOOL_RECIPE = make("Enable White Wool Recipe", true,
"Allows dyed wool to be dyed back white using bone meal");
public static final Option<Boolean> ENABLE_GHASTS_INSTA_DEATH = make("Enable Ghast Insta Death", true,
"Allows ghasts to die in 1 shot when their fireballs get reflected at them");
public static final Option<Boolean> FIX_BOW_MODEL = make("Fix bow model", true,
"Makes the box model held by players and skeletons bigger and facing forward");
@ -51,6 +53,8 @@ public class ModConfig {
"Fixes pickaxes not being effective agaist certain blocks that it should be effective on");
public static final Option<Boolean> FIX_AXE_EFFECTIVENESS = make("Fix axe effectiveness", true,
"Fixes axes not being effective agaist certain blocks that it should be effective on");
public static final Option<Boolean> FIX_SHOVEL_EFFECTIVENESS = make("Fix shovel effectiveness", true,
"Fixes shovels not being effective agaist certain blocks that it should be effective on");
public static final Option<Boolean> FIX_SADDLES_NOT_DROPPING = make("Fix saddles not dropping", true,
"Fixes saddles not dropping when killing saddled pigs");
public static final Option<Boolean> FIX_FURNACE_LAVA_BUCKET = make("Fix furnace lava bucket", true,
@ -59,6 +63,8 @@ public class ModConfig {
"Drops 3 books when breaking a bookshelf");
public static final Option<Boolean> FIX_DOUBLE_DOORS = make("Fix Double Doors", true,
"Fixes double doors not being in their correct state when pressure plates are used to open them");
public static final Option<Boolean> FIX_SLABS_RECIPE = make("Fix Slabs Recipe", true,
"Givs two slabs for every block, since 1 block = 2 slabs => 3 blocks = 6 slabs (instead of 3)");
private static ModConfig instance = new ModConfig();
public static final ModConfig instance() {

View File

@ -2,7 +2,6 @@ package xyz.pixelatedw.finalbeta;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.Duration;
import java.util.HashMap;
@ -11,9 +10,6 @@ import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.Player;
import net.minecraft.item.ItemInstance;
import net.minecraft.item.ItemType;
import net.minecraft.recipe.RecipeRegistry;
import net.minecraft.tile.Tile;
import net.minecraft.tile.WoolTile;
public class WyHelper {
@ -22,7 +18,6 @@ public class WyHelper {
public static final String PLAY_TIME_TAG = "PlayTime";
public static long playTime;
// Look if they're allowed to hold all block and item data in fucking arrays
// I am also allowed to abuse maps to extend the shitty metadata excuse
// doors have ok ? I don't even care about the overhead at this point.
@ -33,36 +28,42 @@ public class WyHelper {
INSTANCE = getInstance();
}
public static Field getField(Class clz, String... names) {
for (String name : names) {
try {
Field field = clz.getDeclaredField(name);
field.setAccessible(true);
return field;
} catch (NoSuchFieldException ex) {
continue;
}
}
return null;
}
public static Method getMethod(Class clz, String[] names, Class<?>... params) {
for (String name : names) {
try {
Method method = clz.getDeclaredMethod(name, params);
method.setAccessible(true);
return method;
} catch (NoSuchMethodException ex) {
continue;
}
}
return null;
}
public static Minecraft getInstance() {
if (INSTANCE != null) {
return INSTANCE;
} else {
try {
Field field = null;
try {
field = Minecraft.class.getDeclaredField("instance");
} catch (NoSuchFieldException ex) {
try {
field = Minecraft.class.getDeclaredField("field_2791");
} catch (NoSuchFieldException | SecurityException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
if (field == null) {
return null;
}
field.setAccessible(true);
return (Minecraft) field.get(null);
return (Minecraft) getField(Minecraft.class, "instance", "field_2791").get(null);
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
return null;
}
return null;
}
}
@ -88,41 +89,17 @@ public class WyHelper {
return val < min ? min : Math.min(val, max);
}
public static void registerWhiteWoolRecipe() {
Method method = null;
try {
method = RecipeRegistry.class.getDeclaredMethod("addShapelessRecipe", ItemInstance.class, Object[].class);
} catch (NoSuchMethodException ex) {
try {
method = RecipeRegistry.class.getDeclaredMethod("method_542", ItemInstance.class, Object[].class);
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
if (method == null) {
return;
}
try {
method.setAccessible(true);
// Makes new recipes for all colored wools so they can be dyed back
// white using bone meal
for (int colorId = 0; colorId < 16; ++colorId) {
method.invoke(RecipeRegistry.getInstance(), new ItemInstance(Tile.WOOL, 1, 0), new Object[]{
new ItemInstance(Tile.WOOL, 1, WoolTile.method_2(colorId)), new ItemInstance(ItemType.dyePowder, 1, 15)});
}
} catch (SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
ex.printStackTrace();
}
}
public static void cheatCommand(Player player) {
// player.level.setLevelTime(0);
// player.level.getProperties().setRaining(false);
// player.level.getProperties().setRainTime(0);
// player.level.getProperties().setThundering(false);
// player.level.getProperties().setThunderTime(0);
player.dropItem(new ItemInstance(ItemType.pickaxeIron, 1, 100));
player.dropItem(new ItemInstance(ItemType.pickaxeIron, 1, 150));
player.dropItem(new ItemInstance(ItemType.pickaxeDiamond, 1, 150));
// player.dropItem(new ItemInstance(Tile.WOOD, 64));
// player.dropItem(new ItemInstance(ItemType.snowball, 60));
player.level.setLevelTime(0);
player.level.getProperties().setRaining(false);
player.level.getProperties().setRainTime(0);
player.level.getProperties().setThundering(false);
player.level.getProperties().setThunderTime(0);
}
}

View File

@ -27,6 +27,11 @@ public class CraftingContainerMixin {
for (int i = 0; i < inventory.getInvSize(); i++) {
ItemInstance item = inventory.getInvItem(i);
if ((item != null && item.method_723() <= 0) || (item != null && resultItem != null && item.itemId != resultItem.itemId)) {
resultItem = null;
break;
}
if (item != null && item.method_723() > 0) {
if (resultItem == null) {
resultItem = new ItemInstance(item.itemId, 1, item.getDamage());

View File

@ -1,5 +1,8 @@
package xyz.pixelatedw.finalbeta.mixin;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -7,6 +10,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.container.Container;
import net.minecraft.inventory.CraftingInventory;
import net.minecraft.item.ItemInstance;
import net.minecraft.item.ItemType;
import net.minecraft.recipe.RecipeRegistry;
import net.minecraft.tile.Tile;
import net.minecraft.tile.WoolTile;
import xyz.pixelatedw.finalbeta.ModConfig;
import xyz.pixelatedw.finalbeta.WyHelper;
@ -18,8 +26,27 @@ public class CraftingInventoryMixin {
@Inject(method = "<init>", at = @At("TAIL"))
public void init(Container container, int x, int y, CallbackInfo ci) {
if (ModConfig.ENABLE_WHITE_WOOL_RECIPE.get() && !hasCustomRecipesRegistered) {
WyHelper.registerWhiteWoolRecipe();
registerWhiteWoolRecipe();
hasCustomRecipesRegistered = true;
}
}
private static void registerWhiteWoolRecipe() {
Method method = WyHelper.getMethod(RecipeRegistry.class, new String[] { "addShapelessRecipe", "method_542" }, ItemInstance.class, Object[].class);
if (method == null) {
return;
}
try {
// Makes new recipes for all colored wools so they can be dyed back
// white using bone meal
for (int colorId = 0; colorId < 16; ++colorId) {
method.invoke(RecipeRegistry.getInstance(), new ItemInstance(Tile.WOOL, 1, 0), new Object[]{
new ItemInstance(Tile.WOOL, 1, WoolTile.method_2(colorId)), new ItemInstance(ItemType.dyePowder, 1, 15)});
}
} catch (SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
ex.printStackTrace();
}
}
}

View File

@ -4,12 +4,18 @@ 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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.animal.Chicken;
import net.minecraft.entity.animal.Pig;
import net.minecraft.entity.monster.Ghast;
import net.minecraft.entity.player.Player;
import net.minecraft.entity.projectile.Snowball;
import net.minecraft.item.ItemType;
import xyz.pixelatedw.finalbeta.ModConfig;
import xyz.pixelatedw.finalbeta.WyHelper;
@Mixin(LivingEntity.class)
public class LivingEntityMixin {
@ -33,4 +39,25 @@ public class LivingEntityMixin {
}
}
}
@Inject(method = "damage", at = @At("HEAD"), cancellable = true)
public void damage(Entity thrower, int damage, CallbackInfoReturnable<Boolean> cir) {
LivingEntity entity = (LivingEntity) (Object) this;
if (ModConfig.ENABLE_GHASTS_INSTA_DEATH.get() && thrower != null && entity instanceof Ghast && thrower instanceof Snowball) {
LivingEntity fireballThrower = ((Snowball) thrower).field_2193;
if (fireballThrower instanceof Player) {
entity.damage(fireballThrower, 1_000);
cir.setReturnValue(true);
}
}
}
@Inject(method = "travel", at = @At("HEAD"))
public void travel(float f, float f1, CallbackInfo ci) {
LivingEntity entity = (LivingEntity) (Object) this;
if (ModConfig.ADD_MORE_SOUNDS.get() && entity.isOnLadder() && entity.velocityY != 0 && entity.field_1645 % 20 == 0 && !entity.onGround) {
float pitch = WyHelper.clamp(0.85f + entity.level.rand.nextFloat() / 2, 0.0f, 1.0f);
entity.level.playSound(entity.x, entity.y, entity.z, "sound3.step.ladder", 0.3f, pitch);
}
}
}

View File

@ -57,8 +57,8 @@ public class MinecartMixin {
}
if (speed >= 0.01D && ModConfig.ADD_MORE_SOUNDS.get()) {
if (minecart.field_1645 % 33 == 1) {
minecart.level.playSound(x, y, z, "minecart.base", volume, pitch);
if (minecart.field_1645 % 39 == 1) {
minecart.level.playSound(x, y, z, "sound3.minecart.base", volume, pitch);
}
}
}

View File

@ -12,11 +12,11 @@ import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.client.Minecraft;
import xyz.pixelatedw.finalbeta.MainMod;
import xyz.pixelatedw.finalbeta.ModConfig;
@Mixin(Minecraft.class)
public class MinecraftMixin {
@Redirect(method = "init()V", at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/Display;create()V"), remap = false)
public void createDisplay() throws LWJGLException {
// Why the fuck is this even a thing ? What was its intended purpose ? I NEED TO KNOW
@ -32,9 +32,9 @@ public class MinecraftMixin {
String type = string.substring(0, split);
String newSound = string.substring(split + 1);
// For now only allow the minecart sounds, allowing all of them causes weird effects with same name sounds when the game decides which one to use
// XXX Could always incorporate the sound3 part into the sound's name and have it accessible as sound3.random.bow for example, which would avoid the overlap with current sounds
if (type.equalsIgnoreCase("sound3") && newSound.startsWith("minecart/")) {
mc.soundHelper.method_2011(newSound, file);
if (type.equalsIgnoreCase("sound3")) {
MainMod.LOGGER.info("Registered a new sound sound3/" + newSound + " from " + file);
mc.soundHelper.method_2011("sound3/" + newSound, file);
}
}
}

View File

@ -0,0 +1,35 @@
package xyz.pixelatedw.finalbeta.mixin;
import java.util.List;
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 net.minecraft.item.ItemInstance;
import net.minecraft.item.StoneSlabItem;
import net.minecraft.recipe.Recipe;
import net.minecraft.recipe.RecipeRegistry;
import xyz.pixelatedw.finalbeta.ModConfig;
@Mixin(RecipeRegistry.class)
public class RecipeRegistryMixin {
@Shadow
private List<Recipe> recipes;
@Inject(method = "<init>", at = @At("TAIL"))
private void recipesChanges(CallbackInfo ci) {
if(ModConfig.FIX_SLABS_RECIPE.get()) {
for (Recipe recipe : this.recipes) {
ItemInstance itemStack = recipe.getOutput();
if (itemStack.getType() instanceof StoneSlabItem) {
itemStack.count = 6;
}
}
}
}
}

View File

@ -1,8 +1,6 @@
package xyz.pixelatedw.finalbeta.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
import net.minecraft.client.util.ResourceDownloadThread;
@ -11,8 +9,8 @@ public class ResourceDownloadThreadMixin {
private static final String RESOURCES_URL = "http://mcresources.modification-station.net/MinecraftResources/";
@ModifyConstant(method = "run", constant = @Constant(stringValue = "http://s3.amazonaws.com/MinecraftResources/"), remap = false)
private String getResourcesUrl(String def) {
return RESOURCES_URL;
}
// @ModifyConstant(method = "run", constant = @Constant(stringValue = "http://s3.amazonaws.com/MinecraftResources/"), remap = false)
// private String getResourcesUrl(String def) {
// return RESOURCES_URL;
// }
}

View File

@ -0,0 +1,41 @@
package xyz.pixelatedw.finalbeta.mixin;
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.projectile.Snowball;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.maths.Vec3d;
import xyz.pixelatedw.finalbeta.ModConfig;
@Mixin(Snowball.class)
public class SnowballMixin {
// Note, this is actually the "fireball" used by Ghasts. I guess they didn't have the fire charges done yet
@Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;damage(Lnet/minecraft/entity/Entity;I)Z", shift = At.Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true)
private void newDamageRouter(CallbackInfo ci, Vec3d _v1, Vec3d _v2, HitResult result) {
Snowball fireball = ((Snowball)(Object)this);
if (ModConfig.ENABLE_GHASTS_INSTA_DEATH.get() && result != null && !fireball.level.isClient) {
if (result.entity != null && result.entity.damage(fireball, 0)) {
}
fireball.level.createExplosion((Entity) null, fireball.x, fireball.y, fireball.z, 1.0F, true);
fireball.remove();
ci.cancel();
}
}
@Inject(method = "damage", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getRotation()Lnet/minecraft/util/maths/Vec3d;"), cancellable = true)
public void damage(Entity attacker, int damage, CallbackInfoReturnable<Boolean> cir) {
Snowball fireball = ((Snowball)(Object)this);
if (ModConfig.ENABLE_GHASTS_INSTA_DEATH.get() && attacker instanceof LivingEntity) {
fireball.field_2193 = (LivingEntity) attacker;
}
}
}

View File

@ -8,6 +8,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.item.tool.HatchetItem;
import net.minecraft.item.tool.PickaxeItem;
import net.minecraft.item.tool.ShovelItem;
import net.minecraft.item.tool.ToolItem;
import net.minecraft.item.tool.ToolMaterial;
import net.minecraft.tile.Tile;
@ -28,6 +29,11 @@ public class ToolItemMixin {
Tile.STAIRS_WOOD, Tile.DOOR_WOOD, Tile.WOODEN_PRESSURE_PLATE, Tile.JUKEBOX, Tile.NOTEBLOCK, Tile.PUMPKIN, Tile.LIT_PUMPKIN,
Tile.STANDING_SIGN, Tile.WALL_SIGN, Tile.TRAPDOOR, Tile.LADDER, Tile.WORKBENCH, Tile.FENCE};
private static final Tile[] SHOVEL_BLOCKS = new Tile[]{Tile.GRASS, Tile.DIRT, Tile.SAND, Tile.GRAVEL, Tile.SNOW, Tile.SNOW_BLOCK,
Tile.CLAY, Tile.FARMLAND,
// Here starts the list of blocks that are not affected by default
Tile.SOUL_SAND};
@Shadow
public Tile[] field_2712;
@ -39,6 +45,8 @@ public class ToolItemMixin {
this.field_2712 = PICKAXE_BLOCKS;
} else if (tool instanceof HatchetItem && ModConfig.FIX_AXE_EFFECTIVENESS.get()) {
this.field_2712 = HATCHET_BLOCKS;
} else if (tool instanceof ShovelItem && ModConfig.FIX_SHOVEL_EFFECTIVENESS.get()) {
this.field_2712 = SHOVEL_BLOCKS;
}
}
}

View File

@ -38,7 +38,9 @@
"LevelMixin",
"DoorTileMixin",
"CraftingContainerMixin",
"CraftingInventoryMixin"
"CraftingInventoryMixin",
"RecipeRegistryMixin",
"SnowballMixin"
],
"injectors": {
"defaultRequire": -1