From 3334e8325aa3c0e1be5e720c6c220b18c2903f52 Mon Sep 17 00:00:00 2001 From: micle Date: Wed, 18 Aug 2021 16:01:31 +0100 Subject: [PATCH] Initial commit. --- build.gradle | 181 ++++++++++++++++++ .../totemofreviving/TotemOfReviving.java | 53 +++++ .../totemofreviving/data/DataGenerators.java | 24 +++ .../data/ModRecipeProvider.java | 56 ++++++ .../data/client/ModItemModelProvider.java | 28 +++ .../events/ServerTickEventHandler.java | 13 ++ .../items/RevivingChargeItem.java | 11 ++ .../items/StrawChargeItem.java | 11 ++ .../totemofreviving/items/StrawTotemItem.java | 82 ++++++++ .../items/TotemOfRevivingItem.java | 78 ++++++++ .../network/C2SRequestPlayerRevive.java | 86 +++++++++ .../network/C2SRequestTotemCharge.java | 63 ++++++ .../network/C2SRequestTotemTarget.java | 52 +++++ .../micle/totemofreviving/setup/ModItems.java | 18 ++ .../totemofreviving/setup/Registration.java | 25 +++ .../micle/totemofreviving/utils/Utils.java | 19 ++ src/main/resources/META-INF/mods.toml | 58 ++++++ .../assets/totemofreviving/lang/en_us.json | 6 + .../textures/item/reviving_charge.png | Bin 0 -> 259 bytes .../textures/item/straw_charge.png | Bin 0 -> 753 bytes .../textures/item/straw_totem.png | Bin 0 -> 5803 bytes .../textures/item/totem_of_reviving.png | Bin 0 -> 287 bytes src/main/resources/pack.mcmeta | 7 + 23 files changed, 871 insertions(+) create mode 100644 build.gradle create mode 100755 src/main/java/com/micle/totemofreviving/TotemOfReviving.java create mode 100755 src/main/java/com/micle/totemofreviving/data/DataGenerators.java create mode 100755 src/main/java/com/micle/totemofreviving/data/ModRecipeProvider.java create mode 100755 src/main/java/com/micle/totemofreviving/data/client/ModItemModelProvider.java create mode 100755 src/main/java/com/micle/totemofreviving/events/ServerTickEventHandler.java create mode 100755 src/main/java/com/micle/totemofreviving/items/RevivingChargeItem.java create mode 100755 src/main/java/com/micle/totemofreviving/items/StrawChargeItem.java create mode 100755 src/main/java/com/micle/totemofreviving/items/StrawTotemItem.java create mode 100755 src/main/java/com/micle/totemofreviving/items/TotemOfRevivingItem.java create mode 100755 src/main/java/com/micle/totemofreviving/network/C2SRequestPlayerRevive.java create mode 100755 src/main/java/com/micle/totemofreviving/network/C2SRequestTotemCharge.java create mode 100755 src/main/java/com/micle/totemofreviving/network/C2SRequestTotemTarget.java create mode 100755 src/main/java/com/micle/totemofreviving/setup/ModItems.java create mode 100755 src/main/java/com/micle/totemofreviving/setup/Registration.java create mode 100755 src/main/java/com/micle/totemofreviving/utils/Utils.java create mode 100755 src/main/resources/META-INF/mods.toml create mode 100755 src/main/resources/assets/totemofreviving/lang/en_us.json create mode 100755 src/main/resources/assets/totemofreviving/textures/item/reviving_charge.png create mode 100755 src/main/resources/assets/totemofreviving/textures/item/straw_charge.png create mode 100755 src/main/resources/assets/totemofreviving/textures/item/straw_totem.png create mode 100755 src/main/resources/assets/totemofreviving/textures/item/totem_of_reviving.png create mode 100755 src/main/resources/pack.mcmeta diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..265ba43 --- /dev/null +++ b/build.gradle @@ -0,0 +1,181 @@ +buildscript { + repositories { + // These repositories are only for Gradle plugins, put any other repositories in the repository block further below + maven { url = 'https://maven.minecraftforge.net' } + mavenCentral() + } + dependencies { + classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true + } +} +apply plugin: 'net.minecraftforge.gradle' +// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. +apply plugin: 'eclipse' +apply plugin: 'maven-publish' + +version = '1.0' +group = 'com.micle.totemofreviving' // http://maven.apache.org/guides/mini/guide-naming-conventions.html +archivesBaseName = 'totemofreviving' + +// Mojang ships Java 16 to end users in 1.17+ instead of Java 8 in 1.16 or lower, so your mod should target Java 16. +java.toolchain.languageVersion = JavaLanguageVersion.of(16) + +println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) +minecraft { + // The mappings can be changed at any time and must be in the following format. + // Channel: Version: + // snapshot YYYYMMDD Snapshot are built nightly. + // stable # Stables are built at the discretion of the MCP team. + // official MCVersion Official field/method names from Mojang mapping files + // + // You must be aware of the Mojang license when using the 'official' mappings. + // See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md + // + // Use non-default mappings at your own risk. They may not always work. + // Simply re-run your setup task after changing the mappings to update your workspace. + mappings channel: 'official', version: '1.17.1' + + // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // Currently, this location cannot be changed from the default. + + // Default run configurations. + // These can be tweaked, removed, or duplicated as needed. + runs { + client { + workingDirectory project.file('run') + + // Recommended logging data for a userdev environment + // The markers can be added/remove as needed separated by commas. + // "SCAN": For mods scan. + // "REGISTRIES": For firing of registry events. + // "REGISTRYDUMP": For getting the contents of all registries. + property 'forge.logging.markers', 'REGISTRIES' + + // Recommended logging level for the console + // You can set various levels here. + // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels + property 'forge.logging.console.level', 'debug' + + mods { + totemofreviving { + source sourceSets.main + } + } + } + + server { + workingDirectory project.file('run') + + // Recommended logging data for a userdev environment + // The markers can be added/remove as needed separated by commas. + // "SCAN": For mods scan. + // "REGISTRIES": For firing of registry events. + // "REGISTRYDUMP": For getting the contents of all registries. + property 'forge.logging.markers', 'REGISTRIES' + + // Recommended logging level for the console + // You can set various levels here. + // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels + property 'forge.logging.console.level', 'debug' + + mods { + totemofreviving { + source sourceSets.main + } + } + } + + data { + workingDirectory project.file('run') + + // Recommended logging data for a userdev environment + // The markers can be added/remove as needed separated by commas. + // "SCAN": For mods scan. + // "REGISTRIES": For firing of registry events. + // "REGISTRYDUMP": For getting the contents of all registries. + property 'forge.logging.markers', 'REGISTRIES' + + // Recommended logging level for the console + // You can set various levels here. + // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels + property 'forge.logging.console.level', 'debug' + + // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. + args '--mod', 'totemofreviving', '--all', + '--existing', file('src/main/resources').toString(), + '--existing', file('src/generated/resources').toString(), + '--output', file('src/generated/resources/') + + mods { + totemofreviving { + source sourceSets.main + } + } + } + } +} + +// Include resources generated by data generators. +sourceSets.main.resources { srcDir 'src/generated/resources' } + +repositories { + // Put repositories for dependencies here + // ForgeGradle automatically adds the Forge maven and Maven Central for you + + // If you have mod jar dependencies in ./libs, you can declare them as a repository like so: + // flatDir { + // dir 'libs' + // } +} + +dependencies { + // Specify the version of Minecraft to use. If this is any group other than 'net.minecraft', it is assumed + // that the dep is a ForgeGradle 'patcher' dependency, and its patches will be applied. + // The userdev artifact is a special name and will get all sorts of transformations applied to it. + minecraft 'net.minecraftforge:forge:1.17.1-37.0.33' + + // Real mod deobf dependency examples - these get remapped to your current mappings + // compileOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}:api") // Adds JEI API as a compile dependency + // runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}") // Adds the full JEI mod as a runtime dependency + // implementation fg.deobf("com.tterrag.registrate:Registrate:MC${mc_version}-${registrate_version}") // Adds registrate as a dependency + + // Examples using mod jars from ./libs + // implementation fg.deobf("blank:coolmod-${mc_version}:${coolmod_version}") + + // For more info... + // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html + // http://www.gradle.org/docs/current/userguide/dependency_management.html +} + +// Example for how to get properties into the manifest for reading at runtime. +jar { + manifest { + attributes([ + "Specification-Title" : "totemofreviving", + "Specification-Vendor" : "totemofrevivingsareus", + "Specification-Version" : "1", // We are version 1 of ourselves + "Implementation-Title" : project.name, + "Implementation-Version" : project.jar.archiveVersion, + "Implementation-Vendor" : "totemofrevivingsareus", + "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + ]) + } +} + +// Example configuration to allow publishing using the maven-publish plugin +// This is the preferred method to reobfuscate your jar file +jar.finalizedBy('reobfJar') +// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing +// publish.dependsOn('reobfJar') + +publishing { + publications { + mavenJava(MavenPublication) { + artifact jar + } + } + repositories { + maven { + url "file://${project.projectDir}/mcmodsrepo" + } + } +} diff --git a/src/main/java/com/micle/totemofreviving/TotemOfReviving.java b/src/main/java/com/micle/totemofreviving/TotemOfReviving.java new file mode 100755 index 0000000..7faa730 --- /dev/null +++ b/src/main/java/com/micle/totemofreviving/TotemOfReviving.java @@ -0,0 +1,53 @@ +package com.micle.totemofreviving; + +import com.micle.totemofreviving.network.C2SRequestPlayerRevive; +import com.micle.totemofreviving.network.C2SRequestTotemCharge; +import com.micle.totemofreviving.network.C2SRequestTotemTarget; +import com.micle.totemofreviving.setup.Registration; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.players.PlayerList; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fmllegacy.network.NetworkRegistry; +import net.minecraftforge.fmllegacy.network.simple.SimpleChannel; + +@Mod(TotemOfReviving.MOD_ID) +public class TotemOfReviving { + public static final String MOD_ID = "totemofreviving"; + public static PlayerList players; + + private static final String PROTOCOL_VERSION = "1"; + public static final SimpleChannel INSTANCE = NetworkRegistry.newSimpleChannel( + new ResourceLocation(TotemOfReviving.MOD_ID, "main"), + () -> PROTOCOL_VERSION, + PROTOCOL_VERSION::equals, + PROTOCOL_VERSION::equals + ); + + public TotemOfReviving() { + Registration.register(); + + int id = 0; + INSTANCE.registerMessage(id++, + C2SRequestPlayerRevive.class, + C2SRequestPlayerRevive::encode, + C2SRequestPlayerRevive::decode, + C2SRequestPlayerRevive::handle + ); + INSTANCE.registerMessage(id++, + C2SRequestTotemTarget.class, + C2SRequestTotemTarget::encode, + C2SRequestTotemTarget::decode, + C2SRequestTotemTarget::handle + ); + INSTANCE.registerMessage(id++, + C2SRequestTotemCharge.class, + C2SRequestTotemCharge::encode, + C2SRequestTotemCharge::decode, + C2SRequestTotemCharge::handle + ); + + // Register ourselves for server and other game events we are interested in + MinecraftForge.EVENT_BUS.register(this); + } +} diff --git a/src/main/java/com/micle/totemofreviving/data/DataGenerators.java b/src/main/java/com/micle/totemofreviving/data/DataGenerators.java new file mode 100755 index 0000000..a918425 --- /dev/null +++ b/src/main/java/com/micle/totemofreviving/data/DataGenerators.java @@ -0,0 +1,24 @@ +package com.micle.totemofreviving.data; + +import com.micle.totemofreviving.TotemOfReviving; +import com.micle.totemofreviving.data.client.ModItemModelProvider; +import net.minecraft.data.DataGenerator; +import net.minecraftforge.common.data.ExistingFileHelper; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.forge.event.lifecycle.GatherDataEvent; + +@Mod.EventBusSubscriber(modid = TotemOfReviving.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) +public class DataGenerators { + private DataGenerators() {} + + @SubscribeEvent + public static void gatherData(GatherDataEvent e) { + DataGenerator gen = e.getGenerator(); + ExistingFileHelper existing_file_helper = e.getExistingFileHelper(); + + gen.addProvider(new ModItemModelProvider(gen, existing_file_helper)); + + gen.addProvider(new ModRecipeProvider(gen)); + } +} diff --git a/src/main/java/com/micle/totemofreviving/data/ModRecipeProvider.java b/src/main/java/com/micle/totemofreviving/data/ModRecipeProvider.java new file mode 100755 index 0000000..8c046f6 --- /dev/null +++ b/src/main/java/com/micle/totemofreviving/data/ModRecipeProvider.java @@ -0,0 +1,56 @@ +package com.micle.totemofreviving.data; + +import com.micle.totemofreviving.setup.ModItems; +import net.minecraft.data.DataGenerator; +import net.minecraft.data.recipes.FinishedRecipe; +import net.minecraft.data.recipes.RecipeProvider; +import net.minecraft.data.recipes.ShapedRecipeBuilder; +import net.minecraft.world.item.Items; + +import java.util.function.Consumer; + +public class ModRecipeProvider extends RecipeProvider { + public ModRecipeProvider(DataGenerator generator_in) { + super(generator_in); + } + + @Override + protected void buildCraftingRecipes(Consumer consumer) { + ShapedRecipeBuilder.shaped(ModItems.TOTEM_OF_REVIVING.get()) + .define('#', Items.TOTEM_OF_UNDYING) + .define('@', Items.DIAMOND) + .pattern("@@@") + .pattern("@#@") + .pattern("@@@") + .unlockedBy("has_item", has(Items.TOTEM_OF_UNDYING)) + .save(consumer); + ShapedRecipeBuilder.shaped(ModItems.REVIVING_CHARGE.get()) + .define('#', Items.TOTEM_OF_UNDYING) + .define('@', Items.DIAMOND_BLOCK) + .define('E', Items.ENDER_PEARL) + .pattern("@E@") + .pattern("E#E") + .pattern("@E@") + .unlockedBy("has_item", has(ModItems.TOTEM_OF_REVIVING.get())) + .save(consumer); + ShapedRecipeBuilder.shaped(ModItems.STRAW_TOTEM.get()) + .define('W', Items.WHEAT) + .define('/', Items.STICK) + .define('S', Items.STRING) + .define('N', Items.IRON_NUGGET) + .pattern("NSN") + .pattern("NWN") + .pattern("N/N") + .unlockedBy("has_item", has(Items.WHEAT)) + .save(consumer); + ShapedRecipeBuilder.shaped(ModItems.STRAW_CHARGE.get()) + .define('W', Items.WHEAT) + .define('E', Items.EMERALD) + .define('I', Items.IRON_INGOT) + .pattern("IWI") + .pattern("WEW") + .pattern("IWI") + .unlockedBy("has_item", has(Items.EMERALD)) + .save(consumer); + } +} diff --git a/src/main/java/com/micle/totemofreviving/data/client/ModItemModelProvider.java b/src/main/java/com/micle/totemofreviving/data/client/ModItemModelProvider.java new file mode 100755 index 0000000..fe5aa2f --- /dev/null +++ b/src/main/java/com/micle/totemofreviving/data/client/ModItemModelProvider.java @@ -0,0 +1,28 @@ +package com.micle.totemofreviving.data.client; + +import com.micle.totemofreviving.TotemOfReviving; +import net.minecraft.data.DataGenerator; +import net.minecraftforge.client.model.generators.ItemModelBuilder; +import net.minecraftforge.client.model.generators.ItemModelProvider; +import net.minecraftforge.client.model.generators.ModelFile; +import net.minecraftforge.common.data.ExistingFileHelper; + +public class ModItemModelProvider extends ItemModelProvider { + public ModItemModelProvider(DataGenerator generator, ExistingFileHelper existing_file_helper) { + super(generator, TotemOfReviving.MOD_ID, existing_file_helper); + } + + @Override + protected void registerModels() { + ModelFile item_generated = getExistingFile(mcLoc("item/generated")); + + builder(item_generated, "totem_of_reviving"); + builder(item_generated, "reviving_charge"); + builder(item_generated, "straw_totem"); + builder(item_generated, "straw_charge"); + } + + private ItemModelBuilder builder(ModelFile item_generated, String name) { + return getBuilder(name).parent(item_generated).texture("layer0", "item/" + name); + } +} diff --git a/src/main/java/com/micle/totemofreviving/events/ServerTickEventHandler.java b/src/main/java/com/micle/totemofreviving/events/ServerTickEventHandler.java new file mode 100755 index 0000000..75ab9c4 --- /dev/null +++ b/src/main/java/com/micle/totemofreviving/events/ServerTickEventHandler.java @@ -0,0 +1,13 @@ +package com.micle.totemofreviving.events; + +import com.micle.totemofreviving.TotemOfReviving; +import net.minecraftforge.event.TickEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fmllegacy.server.ServerLifecycleHooks; + +public class ServerTickEventHandler { + @SubscribeEvent + public void onServerTick(TickEvent.ServerTickEvent event) { + TotemOfReviving.players = ServerLifecycleHooks.getCurrentServer().getPlayerList(); + } +} diff --git a/src/main/java/com/micle/totemofreviving/items/RevivingChargeItem.java b/src/main/java/com/micle/totemofreviving/items/RevivingChargeItem.java new file mode 100755 index 0000000..733968f --- /dev/null +++ b/src/main/java/com/micle/totemofreviving/items/RevivingChargeItem.java @@ -0,0 +1,11 @@ +package com.micle.totemofreviving.items; + +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.Rarity; + +public class RevivingChargeItem extends Item { + public RevivingChargeItem() { + super(new Item.Properties().tab(CreativeModeTab.TAB_MISC).rarity(Rarity.RARE)); + } +} diff --git a/src/main/java/com/micle/totemofreviving/items/StrawChargeItem.java b/src/main/java/com/micle/totemofreviving/items/StrawChargeItem.java new file mode 100755 index 0000000..595bcb1 --- /dev/null +++ b/src/main/java/com/micle/totemofreviving/items/StrawChargeItem.java @@ -0,0 +1,11 @@ +package com.micle.totemofreviving.items; + +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.Rarity; + +public class StrawChargeItem extends Item { + public StrawChargeItem() { + super(new Item.Properties().tab(CreativeModeTab.TAB_MISC).rarity(Rarity.UNCOMMON)); + } +} diff --git a/src/main/java/com/micle/totemofreviving/items/StrawTotemItem.java b/src/main/java/com/micle/totemofreviving/items/StrawTotemItem.java new file mode 100755 index 0000000..b5966b4 --- /dev/null +++ b/src/main/java/com/micle/totemofreviving/items/StrawTotemItem.java @@ -0,0 +1,82 @@ +package com.micle.totemofreviving.items; + +import com.micle.totemofreviving.TotemOfReviving; +import com.micle.totemofreviving.network.C2SRequestPlayerRevive; +import com.micle.totemofreviving.network.C2SRequestTotemCharge; +import com.micle.totemofreviving.network.C2SRequestTotemTarget; +import com.mojang.blaze3d.platform.InputConstants; +import net.minecraft.ChatFormatting; +import net.minecraft.client.KeyMapping; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.*; +import net.minecraft.world.level.Level; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +import java.util.List; + +public class StrawTotemItem extends Item { + public static final String TAG_CHARGE_AMOUNT = "charge"; + public static final String TAG_TARGET_INDEX = "target_index"; + public static final String TAG_TARGET_NAME = "target_name"; + public static final String TAG_FAIL_CHANCE = "fail_chance"; + public static final int STARTING_FAIL_CHANCE = 45; + private static final KeyMapping KEY_LSHIFT = new KeyMapping("StrawTotemItem_LSHIFT", InputConstants.KEY_LSHIFT, KeyMapping.CATEGORY_INTERFACE); + + public StrawTotemItem() { + super(new Item.Properties().tab(CreativeModeTab.TAB_MISC).stacksTo(1).rarity(Rarity.UNCOMMON)); + } + + @Override + public void appendHoverText(ItemStack stack, Level world, List tooltip, TooltipFlag flag) { + super.appendHoverText(stack, world, tooltip, flag); + tooltip.add(new TextComponent(ChatFormatting.GOLD + "Charges: " + ChatFormatting.GRAY + stack.getOrCreateTag().getInt(TAG_CHARGE_AMOUNT))); + tooltip.add(new TextComponent(ChatFormatting.GOLD + "Target: " + ChatFormatting.GRAY + stack.getOrCreateTag().getString(TAG_TARGET_NAME))); + tooltip.add(new TextComponent(ChatFormatting.GOLD + "Fail Chance: " + ChatFormatting.GRAY + stack.getOrCreateTag().getInt(TAG_FAIL_CHANCE))); + tooltip.add(new TextComponent( ChatFormatting.DARK_GRAY + "" + ChatFormatting.ITALIC + "\"Feels kinda funky.\"")); + tooltip.add(new TextComponent("")); + if (KEY_LSHIFT.isDown()) { + tooltip.add(new TextComponent(ChatFormatting.YELLOW + "R-CLICK")); + tooltip.add(new TextComponent(ChatFormatting.GOLD + "When other hand is empty: attempt to revive target.")); + tooltip.add(new TextComponent(ChatFormatting.GOLD + "When other hand has " + ChatFormatting.GRAY + "Straw Reviving Charge" + ChatFormatting.GOLD + ": charge totem.")); + tooltip.add(new TextComponent("")); + tooltip.add(new TextComponent(ChatFormatting.YELLOW + "SHIFT R-CLICK")); + tooltip.add(new TextComponent(ChatFormatting.GOLD + "Cycle through available targets.")); + } else { + tooltip.add(new TextComponent(ChatFormatting.GRAY + "[" + ChatFormatting.WHITE + "LSHIFT" + ChatFormatting.GRAY + "] for advanced tooltip.")); + } + } + + @Override + public void onCraftedBy(ItemStack stack, Level world, Player player) { + super.onCraftedBy(stack, world, player); + stack.getOrCreateTag().putInt(TAG_CHARGE_AMOUNT, 0); + stack.getOrCreateTag().putInt(TAG_FAIL_CHANCE, STARTING_FAIL_CHANCE); + } + + @Override + @OnlyIn(Dist.CLIENT) + public InteractionResultHolder use(Level world, Player player, InteractionHand hand) { + if (!world.isClientSide) { return super.use(world, player, hand); } + if (player.isCrouching()) { + TotemOfReviving.INSTANCE.sendToServer(new C2SRequestTotemTarget(player.getUUID(), hand)); + } else { + InteractionHand item_charge_hand = InteractionHand.MAIN_HAND; + if (hand.equals(InteractionHand.MAIN_HAND)) { + item_charge_hand = InteractionHand.OFF_HAND; + } + Item item_charge = player.getItemInHand(item_charge_hand).getItem(); + + if (item_charge instanceof StrawChargeItem) { + TotemOfReviving.INSTANCE.sendToServer(new C2SRequestTotemCharge(player.getUUID(), hand, item_charge_hand)); + } else { + TotemOfReviving.INSTANCE.sendToServer(new C2SRequestPlayerRevive(player.getUUID(), hand)); + } + } + return super.use(world, player, hand); + } +} diff --git a/src/main/java/com/micle/totemofreviving/items/TotemOfRevivingItem.java b/src/main/java/com/micle/totemofreviving/items/TotemOfRevivingItem.java new file mode 100755 index 0000000..68c36c7 --- /dev/null +++ b/src/main/java/com/micle/totemofreviving/items/TotemOfRevivingItem.java @@ -0,0 +1,78 @@ +package com.micle.totemofreviving.items; + +import com.micle.totemofreviving.TotemOfReviving; +import com.micle.totemofreviving.network.C2SRequestPlayerRevive; +import com.micle.totemofreviving.network.C2SRequestTotemCharge; +import com.micle.totemofreviving.network.C2SRequestTotemTarget; +import com.mojang.blaze3d.platform.InputConstants; +import net.minecraft.ChatFormatting; +import net.minecraft.client.KeyMapping; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.*; +import net.minecraft.world.level.Level; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +import java.util.List; + +public class TotemOfRevivingItem extends Item { + public static final String TAG_CHARGE_AMOUNT = "charge"; + public static final String TAG_TARGET_INDEX = "target_index"; + public static final String TAG_TARGET_NAME = "target_name"; + private static final KeyMapping KEY_LSHIFT = new KeyMapping("TotemOfRevivingItem_LSHIFT", InputConstants.KEY_LSHIFT, KeyMapping.CATEGORY_INTERFACE); + + public TotemOfRevivingItem() { + super(new Item.Properties().tab(CreativeModeTab.TAB_MISC).stacksTo(1).rarity(Rarity.RARE)); + } + + @Override + public void appendHoverText(ItemStack stack, Level world, List tooltip, TooltipFlag flag) { + super.appendHoverText(stack, world, tooltip, flag); + tooltip.add(new TextComponent(ChatFormatting.DARK_AQUA + "Charges: " + ChatFormatting.BLUE + stack.getOrCreateTag().getInt(TAG_CHARGE_AMOUNT)) { + }); + tooltip.add(new TextComponent(ChatFormatting.DARK_AQUA + "Target: " + ChatFormatting.BLUE + stack.getOrCreateTag().getString(TAG_TARGET_NAME))); + tooltip.add(new TextComponent("")); + if (KEY_LSHIFT.isDown()) { + tooltip.add(new TextComponent(ChatFormatting.AQUA + "R-CLICK")); + tooltip.add(new TextComponent(ChatFormatting.DARK_AQUA + "When other hand is empty: attempt to revive target.")); + tooltip.add(new TextComponent(ChatFormatting.DARK_AQUA + "When other hand has " + ChatFormatting.BLUE + "Reviving Charge" + ChatFormatting.DARK_AQUA + ": charge totem.")); + tooltip.add(new TextComponent("")); + tooltip.add(new TextComponent(ChatFormatting.AQUA + "SHIFT R-CLICK")); + tooltip.add(new TextComponent(ChatFormatting.DARK_AQUA + "Cycle through available targets.")); + } else { + tooltip.add(new TextComponent(ChatFormatting.GRAY + "[" + ChatFormatting.WHITE + "LSHIFT" + ChatFormatting.GRAY + "] for advanced tooltip.")); + } + } + + @Override + public void onCraftedBy(ItemStack stack, Level world, Player player) { + super.onCraftedBy(stack, world, player); + stack.getOrCreateTag().putInt(TAG_CHARGE_AMOUNT, 0); + } + + @Override + @OnlyIn(Dist.CLIENT) + public InteractionResultHolder use(Level world, Player player, InteractionHand hand) { + if (!world.isClientSide) { return super.use(world, player, hand); } + if (player.isCrouching()) { + TotemOfReviving.INSTANCE.sendToServer(new C2SRequestTotemTarget(player.getUUID(), hand)); + } else { + InteractionHand item_charge_hand = InteractionHand.MAIN_HAND; + if (hand.equals(InteractionHand.MAIN_HAND)) { + item_charge_hand = InteractionHand.OFF_HAND; + } + Item item_charge = player.getItemInHand(item_charge_hand).getItem(); + + if (item_charge instanceof RevivingChargeItem) { + TotemOfReviving.INSTANCE.sendToServer(new C2SRequestTotemCharge(player.getUUID(), hand, item_charge_hand)); + } else { + TotemOfReviving.INSTANCE.sendToServer(new C2SRequestPlayerRevive(player.getUUID(), hand)); + } + } + return super.use(world, player, hand); + } +} diff --git a/src/main/java/com/micle/totemofreviving/network/C2SRequestPlayerRevive.java b/src/main/java/com/micle/totemofreviving/network/C2SRequestPlayerRevive.java new file mode 100755 index 0000000..3ae4ad1 --- /dev/null +++ b/src/main/java/com/micle/totemofreviving/network/C2SRequestPlayerRevive.java @@ -0,0 +1,86 @@ +package com.micle.totemofreviving.network; + +import com.micle.totemofreviving.TotemOfReviving; +import com.micle.totemofreviving.items.StrawTotemItem; +import com.micle.totemofreviving.items.TotemOfRevivingItem; +import com.micle.totemofreviving.utils.Utils; +import net.minecraft.ChatFormatting; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.stats.Stats; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.GameType; +import net.minecraftforge.fmllegacy.network.NetworkEvent; + +import java.util.UUID; +import java.util.function.Supplier; + +public class C2SRequestPlayerRevive { + private final UUID player_uuid; + private final InteractionHand hand; + + public C2SRequestPlayerRevive(final UUID player_uuid, final InteractionHand hand) { + this.player_uuid = player_uuid; + this.hand = hand; + } + + public static void encode(final C2SRequestPlayerRevive msg, FriendlyByteBuf packet_buffer) { + packet_buffer.writeUUID( msg.player_uuid); + packet_buffer.writeEnum(msg.hand); + } + + public static C2SRequestPlayerRevive decode(final FriendlyByteBuf packet_buffer) { + return new C2SRequestPlayerRevive(packet_buffer.readUUID(), packet_buffer.readEnum(InteractionHand.class)); + } + + public static void handle(final C2SRequestPlayerRevive msg, final Supplier context_supplier) { + final NetworkEvent.Context context = context_supplier.get(); + context.enqueueWork(() -> { + final ServerPlayer sender = TotemOfReviving.players.getPlayer(msg.player_uuid); + if (sender == null) { return; } + + ItemStack item = sender.getItemInHand(msg.hand); + if (item.getOrCreateTag().getInt(TotemOfRevivingItem.TAG_TARGET_INDEX) > TotemOfReviving.players.getPlayerCount()-1 || item.getOrCreateTag().getString(TotemOfRevivingItem.TAG_TARGET_NAME).equals("")) { + sender.sendMessage(new TextComponent(ChatFormatting.RED + "Error getting target! (Try selecting the target again)"), sender.getUUID()); + } else { + ServerPlayer player_to_revive = TotemOfReviving.players.getPlayerByName(item.getOrCreateTag().getString(TotemOfRevivingItem.TAG_TARGET_NAME)); + ServerLevel player_to_revive_world = player_to_revive.getLevel(); + ServerLevel sender_world = sender.getLevel(); + int required_charge = player_to_revive.getStats().getValue(Stats.CUSTOM.get(Stats.DEATHS)); + if (player_to_revive.isSpectator()) { + if (player_to_revive_world.equals(sender_world)) { + if (item.getOrCreateTag().getInt(TotemOfRevivingItem.TAG_CHARGE_AMOUNT) >= required_charge) { + if (item.getOrCreateTag().contains(StrawTotemItem.TAG_FAIL_CHANCE)) { + int fail_chance = item.getOrCreateTag().getInt(StrawTotemItem.TAG_FAIL_CHANCE); + if (Utils.randomIntRange(0, 100) <= fail_chance) { + item.getOrCreateTag().putInt(StrawTotemItem.TAG_CHARGE_AMOUNT, item.getOrCreateTag().getInt(StrawTotemItem.TAG_CHARGE_AMOUNT)-required_charge); + item.getOrCreateTag().putInt(StrawTotemItem.TAG_FAIL_CHANCE, fail_chance-(5*required_charge)); + sender.addEffect(new MobEffectInstance(MobEffects.POISON, ((fail_chance*10) / 2), 1)); + return; + } else { + item.getOrCreateTag().putInt(StrawTotemItem.TAG_FAIL_CHANCE, fail_chance-(5*required_charge)); + } + } + player_to_revive.teleportTo(sender.getX(), sender.getY(), sender.getZ()); + player_to_revive.setGameMode(GameType.SURVIVAL); + item.getOrCreateTag().putInt(TotemOfRevivingItem.TAG_CHARGE_AMOUNT, item.getOrCreateTag().getInt(TotemOfRevivingItem.TAG_CHARGE_AMOUNT) - required_charge); + sender.sendMessage(new TextComponent(ChatFormatting.GRAY + "Successfully revived " + ChatFormatting.DARK_GRAY + player_to_revive.getDisplayName().getString()), sender.getUUID()); + } else { + sender.sendMessage(new TextComponent(ChatFormatting.GRAY + "Not enough charge! Required charge is: " + ChatFormatting.DARK_GRAY + required_charge), sender.getUUID()); + } + } else { + sender.sendMessage(new TextComponent(ChatFormatting.DARK_GRAY + player_to_revive.getDisplayName().getString() + ChatFormatting.GRAY + " is not in this dimension!"), sender.getUUID()); + } + } else { + sender.sendMessage(new TextComponent(ChatFormatting.DARK_GRAY + player_to_revive.getDisplayName().getString() + ChatFormatting.GRAY + " is not dead!"), sender.getUUID()); + } + } + }); + context.setPacketHandled(true); + } +} diff --git a/src/main/java/com/micle/totemofreviving/network/C2SRequestTotemCharge.java b/src/main/java/com/micle/totemofreviving/network/C2SRequestTotemCharge.java new file mode 100755 index 0000000..2dbbf0d --- /dev/null +++ b/src/main/java/com/micle/totemofreviving/network/C2SRequestTotemCharge.java @@ -0,0 +1,63 @@ +package com.micle.totemofreviving.network; + +import com.micle.totemofreviving.TotemOfReviving; +import com.micle.totemofreviving.items.StrawTotemItem; +import com.micle.totemofreviving.items.TotemOfRevivingItem; +import com.micle.totemofreviving.utils.Utils; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraftforge.fmllegacy.network.NetworkEvent; + +import java.util.UUID; +import java.util.function.Supplier; + +public class C2SRequestTotemCharge { + private final UUID player_uuid; + private final InteractionHand hand; + private final InteractionHand item_charge_hand; + + public C2SRequestTotemCharge(final UUID player_uuid, final InteractionHand hand, final InteractionHand item_charge_hand) { + this.player_uuid = player_uuid; + this.hand = hand; + this.item_charge_hand = item_charge_hand; + } + + public static void encode(final C2SRequestTotemCharge msg, final FriendlyByteBuf packet_buffer) { + packet_buffer.writeUUID(msg.player_uuid); + packet_buffer.writeEnum(msg.hand); + packet_buffer.writeEnum(msg.item_charge_hand); + } + + public static C2SRequestTotemCharge decode(final FriendlyByteBuf packet_buffer) { + return new C2SRequestTotemCharge(packet_buffer.readUUID(), packet_buffer.readEnum(InteractionHand.class), packet_buffer.readEnum(InteractionHand.class)); + } + + public static void handle(final C2SRequestTotemCharge msg, final Supplier context_supplier) { + final NetworkEvent.Context context = context_supplier.get(); + context.enqueueWork(() -> { + final ServerPlayer sender = TotemOfReviving.players.getPlayer(msg.player_uuid); + if (sender == null) { return; } + + ItemStack charge_item = sender.getItemInHand(msg.item_charge_hand); + ItemStack totem_item = sender.getItemInHand(msg.hand); + charge_item.setCount(charge_item.getCount()-1); + totem_item.getOrCreateTag().putInt(TotemOfRevivingItem.TAG_CHARGE_AMOUNT, totem_item.getOrCreateTag().getInt(TotemOfRevivingItem.TAG_CHARGE_AMOUNT)+1); + + if (totem_item.getOrCreateTag().contains(StrawTotemItem.TAG_FAIL_CHANCE)) { + int fail_chance = totem_item.getOrCreateTag().getInt(StrawTotemItem.TAG_FAIL_CHANCE); + if (Utils.randomIntRange(0, 100) <= fail_chance) { + sender.setItemInHand(msg.hand, new ItemStack(Items.AIR)); + sender.addEffect(new MobEffectInstance(MobEffects.POISON, ((fail_chance*10) / 2), 1)); + } else { + totem_item.getOrCreateTag().putInt(StrawTotemItem.TAG_FAIL_CHANCE, fail_chance+5); + } + } + }); + context.setPacketHandled(true); + } +} diff --git a/src/main/java/com/micle/totemofreviving/network/C2SRequestTotemTarget.java b/src/main/java/com/micle/totemofreviving/network/C2SRequestTotemTarget.java new file mode 100755 index 0000000..3d83e33 --- /dev/null +++ b/src/main/java/com/micle/totemofreviving/network/C2SRequestTotemTarget.java @@ -0,0 +1,52 @@ +package com.micle.totemofreviving.network; + +import com.micle.totemofreviving.TotemOfReviving; +import com.micle.totemofreviving.items.TotemOfRevivingItem; +import net.minecraft.ChatFormatting; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.fmllegacy.network.NetworkEvent; + +import java.util.UUID; +import java.util.function.Supplier; + +public class C2SRequestTotemTarget { + private final UUID player_uuid; + private final InteractionHand hand; + + public C2SRequestTotemTarget(final UUID player_uuid, final InteractionHand hand) { + this.player_uuid = player_uuid; + this.hand = hand; + } + + public static void encode(final C2SRequestTotemTarget msg, final FriendlyByteBuf packet_buffer) { + packet_buffer.writeUUID(msg.player_uuid); + packet_buffer.writeEnum(msg.hand); + } + + public static C2SRequestTotemTarget decode(final FriendlyByteBuf packet_buffer) { + return new C2SRequestTotemTarget(packet_buffer.readUUID(), packet_buffer.readEnum(InteractionHand.class)); + } + + public static void handle(final C2SRequestTotemTarget msg, final Supplier context_supplier) { + final NetworkEvent.Context context = context_supplier.get(); + context.enqueueWork(() -> { + final ServerPlayer sender = TotemOfReviving.players.getPlayer(msg.player_uuid); + if (sender == null) { return; } + + ItemStack item = sender.getItemInHand(msg.hand); + int current_player_index = item.getOrCreateTag().getInt(TotemOfRevivingItem.TAG_TARGET_INDEX) + 1; + if (current_player_index > TotemOfReviving.players.getPlayerCount()-1) { + current_player_index = 0; + } + + item.getOrCreateTag().putInt(TotemOfRevivingItem.TAG_TARGET_INDEX, current_player_index); + item.getOrCreateTag().putString(TotemOfRevivingItem.TAG_TARGET_NAME, TotemOfReviving.players.getPlayers().get(current_player_index).getDisplayName().getString()); + sender.sendMessage(new TextComponent(ChatFormatting.GRAY + "Target: " + ChatFormatting.DARK_GRAY + item.getOrCreateTag().getString(TotemOfRevivingItem.TAG_TARGET_NAME)), sender.getUUID()); + }); + context.setPacketHandled(true); + } +} diff --git a/src/main/java/com/micle/totemofreviving/setup/ModItems.java b/src/main/java/com/micle/totemofreviving/setup/ModItems.java new file mode 100755 index 0000000..90aa13d --- /dev/null +++ b/src/main/java/com/micle/totemofreviving/setup/ModItems.java @@ -0,0 +1,18 @@ +package com.micle.totemofreviving.setup; + +import com.micle.totemofreviving.items.RevivingChargeItem; +import com.micle.totemofreviving.items.StrawChargeItem; +import com.micle.totemofreviving.items.StrawTotemItem; +import com.micle.totemofreviving.items.TotemOfRevivingItem; +import net.minecraft.world.item.Item; +import net.minecraftforge.fmllegacy.RegistryObject; + +public class ModItems { + public static final RegistryObject TOTEM_OF_REVIVING = Registration.ITEMS.register("totem_of_reviving", TotemOfRevivingItem::new); + public static final RegistryObject REVIVING_CHARGE = Registration.ITEMS.register("reviving_charge", RevivingChargeItem::new); + public static final RegistryObject STRAW_TOTEM = Registration.ITEMS.register("straw_totem", StrawTotemItem::new); + public static final RegistryObject STRAW_CHARGE = Registration.ITEMS.register("straw_charge", StrawChargeItem::new); + + static void register() { + } +} diff --git a/src/main/java/com/micle/totemofreviving/setup/Registration.java b/src/main/java/com/micle/totemofreviving/setup/Registration.java new file mode 100755 index 0000000..5c605b7 --- /dev/null +++ b/src/main/java/com/micle/totemofreviving/setup/Registration.java @@ -0,0 +1,25 @@ +package com.micle.totemofreviving.setup; + +import com.micle.totemofreviving.TotemOfReviving; +import com.micle.totemofreviving.events.ServerTickEventHandler; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; + +public class Registration { + public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, TotemOfReviving.MOD_ID); + public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, TotemOfReviving.MOD_ID); + + public static void register() { + IEventBus mod_event_bus = FMLJavaModLoadingContext.get().getModEventBus(); + BLOCKS.register(mod_event_bus); + ITEMS.register(mod_event_bus); + MinecraftForge.EVENT_BUS.register(new ServerTickEventHandler()); + + ModItems.register(); + } +} diff --git a/src/main/java/com/micle/totemofreviving/utils/Utils.java b/src/main/java/com/micle/totemofreviving/utils/Utils.java new file mode 100755 index 0000000..36bdac6 --- /dev/null +++ b/src/main/java/com/micle/totemofreviving/utils/Utils.java @@ -0,0 +1,19 @@ +package com.micle.totemofreviving.utils; + +public class Utils { + public static float clamp(float val, float min, float max) { + return Math.max(min, Math.min(max, val)); + } + + public static int randomIntRange(int min, int max) { + return (int) randomDoubleRange(min, max); + } + + public static float randomFloatRange(float min, float max) { + return (float) randomDoubleRange(min, max); + } + + public static double randomDoubleRange(double min, double max) { + return ((Math.random() * (max - min)) + min); + } +} diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml new file mode 100755 index 0000000..84ec75e --- /dev/null +++ b/src/main/resources/META-INF/mods.toml @@ -0,0 +1,58 @@ +# This is an example mods.toml file. It contains the data relating to the loading mods. +# There are several mandatory fields (#mandatory), and many more that are optional (#optional). +# The overall format is standard TOML format, v0.5.0. +# Note that there are a couple of TOML lists in this file. +# Find more information on toml format here: https://github.com/toml-lang/toml +# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml +modLoader="javafml" #mandatory +# A version range to match for said mod loader - for regular FML @Mod it will be the forge version +loaderVersion="[37,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. +# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties. +# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here. +license="All rights reserved" +# A URL to refer people to when problems occur with this mod +#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional +# A list of mods - how many allowed here is determined by the individual mod loader +[[mods]] #mandatory +# The modid of the mod +modId="totemofreviving" #mandatory +# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it +# ${file.jarVersion} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata +# see the associated build.gradle script for how to populate this completely automatically during a build +version="${file.jarVersion}" #mandatory + # A display name for the mod +displayName="Micle's Totem of Reviving" #mandatory +# A URL to query for updates for this mod. See the JSON update specification https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/ +#updateJSONURL="https://change.me.example.invalid/updates.json" #optional +# A URL for the "homepage" for this mod, displayed in the mod UI +#displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional +# A file name (in the root of the mod JAR) containing a logo for display +#logoFile="examplemod.png" #optional +# A text field displayed in the mod UI +#credits="Thanks for this example mod goes to Java" #optional +# A text field displayed in the mod UI +authors="Micle" #optional +# The description text for the mod (multi line!) (#mandatory) +description=''' +Mod for reviving players in a hardcore world. +''' +# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. +[[dependencies.totemofreviving]] #optional + # the modid of the dependency + modId="forge" #mandatory + # Does this dependency have to exist - if not, ordering below must be specified + mandatory=true #mandatory + # The version range of the dependency + versionRange="[37,)" #mandatory + # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory + ordering="NONE" + # Side this dependency is applied on - BOTH, CLIENT or SERVER + side="BOTH" +# Here's another dependency +[[dependencies.totemofreviving]] + modId="minecraft" + mandatory=true +# This version range declares a minimum of the current minecraft version up to but not including the next major version + versionRange="[1.17.1,1.18)" + ordering="NONE" + side="BOTH" diff --git a/src/main/resources/assets/totemofreviving/lang/en_us.json b/src/main/resources/assets/totemofreviving/lang/en_us.json new file mode 100755 index 0000000..11a801d --- /dev/null +++ b/src/main/resources/assets/totemofreviving/lang/en_us.json @@ -0,0 +1,6 @@ +{ + "item.totemofreviving.totem_of_reviving": "Totem of Reviving", + "item.totemofreviving.reviving_charge": "Reviving charge", + "item.totemofreviving.straw_totem": "Straw Totem of Reviving", + "item.totemofreviving.straw_charge": "Straw reviving charge" +} \ No newline at end of file diff --git a/src/main/resources/assets/totemofreviving/textures/item/reviving_charge.png b/src/main/resources/assets/totemofreviving/textures/item/reviving_charge.png new file mode 100755 index 0000000000000000000000000000000000000000..b6081b123a682fabc59ecc92f637787294c57608 GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}H0G|+7W;F#Ka|3Q)CxN&?lbIcVf4|c?yV3DkJ;QD{pptVt9%}$8u96_X z;Quhdu<4A>d7vm~fk$L90|Vb75M~tB@M-`GMtHh7hG+!0`bF~{P~h3rvFqOdL#th5 zH>F6*?{P`~D88>dx9^sjP`8e@nape%$$jrq8o84Cn6eLETj(jqT5EFc&I{GYrW~^! pT^T!5CqIs_w3++lVEn^6X33lEi#5{{;(&HAc)I$ztaD0e0sy}^SIz(c literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/totemofreviving/textures/item/straw_charge.png b/src/main/resources/assets/totemofreviving/textures/item/straw_charge.png new file mode 100755 index 0000000000000000000000000000000000000000..2a2e23b1637bb574ea12d476b2957013fb798e88 GIT binary patch literal 753 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta new file mode 100755 index 0000000..44a5cc8 --- /dev/null +++ b/src/main/resources/pack.mcmeta @@ -0,0 +1,7 @@ +{ + "pack": { + "description": "totemofreviving resources", + "pack_format": 6, + "_comment": "A pack_format of 6 requires json lang files and some texture changes from 1.16.2. Note: we require v6 pack meta for all mods." + } +}