From d7df43bc080ada12752c9f414cd419bc7e9058b6 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 13 Mar 2025 02:14:10 +0200 Subject: [PATCH] Add /rpinfo for info on the mod, remove cooldowns fully, add petting on rightclick, fix bee food and redo FoodEating mixin --- README.MD | 62 +++++++++++++++---- src/main/java/ovh/sad/animalrp/AnimalRP.java | 56 +++++++++++++++-- .../java/ovh/sad/animalrp/animals/Bee.java | 6 +- .../sad/animalrp/commands/InfoCommand.java | 34 ++++++++++ .../ovh/sad/animalrp/mixin/FoodEating.java | 14 +++-- .../java/ovh/sad/animalrp/util/Cooldown.java | 35 ----------- 6 files changed, 148 insertions(+), 59 deletions(-) create mode 100644 src/main/java/ovh/sad/animalrp/commands/InfoCommand.java delete mode 100644 src/main/java/ovh/sad/animalrp/util/Cooldown.java diff --git a/README.MD b/README.MD index 9dfaede..3e501b9 100644 --- a/README.MD +++ b/README.MD @@ -1,13 +1,53 @@ -# AnimalRP port to Fabric +# **AnimalRPs mod** -Order of importance: -TODO: +## **Animal listing** +1. Bee + Doubleclicking shift you will float (levitation 5 for 1 second), allowing for better movement up hills as example. **Your superfoods are all flowers.** +2. Cat + You take significantly less damage when falling (5 hearts). You can still die, don't count on your cat-powers catching you every time. **Your superfood is all types of eatable fish.** +3. Fox + You do more damage to mobs (25%). **Your superfoods are glow berries and apples.** +4. Dog + You get speed 2 when doing damage. **Your superfood are uncooked meats.** -- [ ] Database -- [ ] Player leashing -- [No] Cooldowns -- [No] Emotes -- [x] Bee -- [x] Cat -- [x] Dog -- [x] Fox \ No newline at end of file +## **Chat** +Chat while you are a animal is very different. When you speak, your words will become furry-ified and every time you talk you'll have animal sounds come out of you. You can disable this via /chatmodoff, and turn it back on via /chatmodon. + +If you do not want to see these chat changes, run /disableanimalchat. This will disable them for you, and you only. + +## **Superfoods** +Superfoods are items that when eaten, give you stackable **Speed II** and insane amounts of saturation (9.4 points) and hunger (4 points). + +## **How to add a new animal?** + +1. Create a new class in animals/MyCoolAnimal.java +2. Use this template +``` +public class MyCoolAnimal extends Animal { + TextDestroyer destroyer = new TextDestroyer(new String[]{ + "I'm Cool!" + }, new String[][]{ + {"g", "z"} + }); + + public MyCoolAnimal() { + super("coolanimal", "awsome!", "#00ff00"); + this.moodSounds.put(Mood.HAPPY, Sound.ENTITY_FOX_EAT); + this.moodSounds.put(Mood.CUTE, Sound.ENTITY_FOX_SLEEP); + this.moodSounds.put(Mood.SAD, Sound.ENTITY_FOX_SNIFF); + this.moodSounds.put(Mood.STRESSED, Sound.ENTITY_FOX_AGGRO); + this.moodSounds.put(Mood.ANGRY, Sound.ENTITY_FOX_BITE); + + this.superfoods.add(Material.POTATO); + } + + @Override + public String chatTransformations(String message) { + return this.destroyer.destroy(message); + } +} +``` +3. Change the info in the TextDestroyer initialization +4. Change the info in the super() call, it is written as "name", "catchphrase", "color". +5. Change the moodSounds and implement all sounds for the moods. +6. Add superfoods (foods that the animal likes) \ No newline at end of file diff --git a/src/main/java/ovh/sad/animalrp/AnimalRP.java b/src/main/java/ovh/sad/animalrp/AnimalRP.java index 813bda3..cbac811 100644 --- a/src/main/java/ovh/sad/animalrp/AnimalRP.java +++ b/src/main/java/ovh/sad/animalrp/AnimalRP.java @@ -1,26 +1,35 @@ package ovh.sad.animalrp; +import eu.pb4.placeholders.api.*; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; +import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents; +import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; +import net.fabricmc.fabric.api.event.player.UseEntityCallback; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.sound.SoundCategory; +import net.minecraft.util.ActionResult; import net.minecraft.util.Identifier; import ovh.sad.animalrp.animals.Animal; import ovh.sad.animalrp.animals.Cat; import ovh.sad.animalrp.animals.Dog; import ovh.sad.animalrp.animals.Fox; import ovh.sad.animalrp.animals.Bee; +import ovh.sad.animalrp.commands.InfoCommand; import ovh.sad.animalrp.commands.InteractionCommand; import ovh.sad.animalrp.commands.NoChatCommand; import ovh.sad.animalrp.commands.TfCommand; import ovh.sad.animalrp.util.HashmapStore; import ovh.sad.animalrp.util.Mood; -import eu.pb4.placeholders.api.PlaceholderContext; -import eu.pb4.placeholders.api.PlaceholderHandler; -import eu.pb4.placeholders.api.PlaceholderResult; -import eu.pb4.placeholders.api.Placeholders; import java.util.HashMap; +import java.util.Map; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -38,6 +47,9 @@ public class AnimalRP implements ModInitializer { public static final String MOD_ID = "animal-rp"; public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + private static final Map lastPetTimes = new ConcurrentHashMap<>(); + private static final long COOLDOWN_MS = 1000; + @Override public void onInitialize() { @@ -79,6 +91,7 @@ ZZZzz /,`.-'`' -. ;-;;,_ CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { (new TfCommand()).Command(dispatcher, registryAccess, environment); (new NoChatCommand()).Command(dispatcher, registryAccess, environment); + (new InfoCommand()).Command(dispatcher, registryAccess, environment); (new InteractionCommand("headpats", Mood.HAPPY, "%s petted you! %s", "You petted %s! %s")) .Command(dispatcher, registryAccess, environment); @@ -101,5 +114,40 @@ ZZZzz /,`.-'`' -. ;-;;,_ ServerLifecycleEvents.SERVER_STOPPING.register((server) -> { executor.shutdownNow(); }); + UseEntityCallback.EVENT.register((attacker, world, hand , attackeee, ehr) -> { + if(!(attackeee instanceof PlayerEntity)) { + return ActionResult.PASS; + } + PlayerEntity attackee = (PlayerEntity) attackeee; + + Animal attackerAnimal = AnimalRP.users.get(attacker.getUuid()); + if(attackerAnimal == null) return ActionResult.PASS; + Animal attackeeAnimal = AnimalRP.users.get(attackee.getUuid()); + if(attackeeAnimal == null) return ActionResult.PASS; + + UUID attackerId = attacker.getUuid(); + long currentTime = System.currentTimeMillis(); + + if (lastPetTimes.getOrDefault(attackerId, 0L) + COOLDOWN_MS > currentTime) { + return ActionResult.PASS; + } + lastPetTimes.put(attackerId, currentTime); + + + attackee.sendMessage(TextParserUtils.formatText( + String.format("%s petted you! %s", + "" + attacker.getName().getString() + "", + "" + attackerAnimal.catchphrase)), false); + attacker.sendMessage(TextParserUtils.formatText( + String.format("You petted %s! %s", + "" + attackee.getName().getString() + "", + "" + attackeeAnimal.catchphrase)), false); + attacker.getWorld().playSound(attackee, attackee.getBlockPos(), + attackeeAnimal.moodSounds.get(Mood.CUTE), SoundCategory.PLAYERS, 1F, + 1); + + System.out.println(attackee.getNameForScoreboard() + " was rightclicked by " + attacker.getNameForScoreboard()); + return ActionResult.PASS; + }); } } \ No newline at end of file diff --git a/src/main/java/ovh/sad/animalrp/animals/Bee.java b/src/main/java/ovh/sad/animalrp/animals/Bee.java index 20b919b..64c81b3 100644 --- a/src/main/java/ovh/sad/animalrp/animals/Bee.java +++ b/src/main/java/ovh/sad/animalrp/animals/Bee.java @@ -74,6 +74,9 @@ public class Bee extends Animal { this.moodSounds.put(Mood.SAD, SoundEvents.ENTITY_BEE_HURT); this.moodSounds.put(Mood.STRESSED, SoundEvents.ENTITY_BEE_STING); this.moodSounds.put(Mood.ANGRY, SoundEvents.ENTITY_BEE_LOOP_AGGRESSIVE); + + this.superfoods.addAll(allFlowers); + UseItemCallback.EVENT.register((player, world, hand) -> { Animal animal = AnimalRP.users.get(player.getUuid()); @@ -112,12 +115,9 @@ public class Bee extends Animal { FoodComponent food = new FoodComponent.Builder() .alwaysEdible() - .nutrition(4) - .saturationModifier(9.4f) .build(); ConsumableComponent consumable = ConsumableComponents.food() - .consumeEffect(new ApplyEffectsConsumeEffect(new StatusEffectInstance(StatusEffects.SPEED, 20 * 4, 1, true, true, true))) .build(); item.set(DataComponentTypes.FOOD, food); diff --git a/src/main/java/ovh/sad/animalrp/commands/InfoCommand.java b/src/main/java/ovh/sad/animalrp/commands/InfoCommand.java new file mode 100644 index 0000000..48949bd --- /dev/null +++ b/src/main/java/ovh/sad/animalrp/commands/InfoCommand.java @@ -0,0 +1,34 @@ +package ovh.sad.animalrp.commands; + +import java.util.UUID; + +import com.mojang.brigadier.CommandDispatcher; + +import eu.pb4.placeholders.api.TextParserUtils; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.server.command.CommandManager; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.text.Text; +import ovh.sad.animalrp.AnimalRP; +import ovh.sad.animalrp.util.HashmapStore; + +public class InfoCommand { + public void Command(CommandDispatcher dispatcher, CommandRegistryAccess registryAccess, + CommandManager.RegistrationEnvironment environment) { + dispatcher.register(CommandManager.literal("rpinfo").executes(context -> { + context.getSource().sendFeedback(() -> TextParserUtils.formatText("AnimalRPs is a mod that adds animals to Minecraft."), false); + context.getSource().sendFeedback(() -> TextParserUtils.formatText("Usage of this mod is very simple."), false); + context.getSource().sendFeedback(() -> TextParserUtils.formatText("- To select a animal, use: /tf"), false); + context.getSource().sendFeedback(() -> TextParserUtils.formatText("- To turn off animals, use: /tf off"), false); + context.getSource().sendFeedback(() -> TextParserUtils.formatText("- Don't want the chat changes? Use: /disableanimalchat."), false); + context.getSource().sendFeedback(() -> Text.empty(), false); + context.getSource().sendFeedback(() -> TextParserUtils.formatText("- To see what the animals do, visit: https://git.sad.ovh/sophie/animalrpfabric"), false); + context.getSource().sendFeedback(() -> TextParserUtils.formatText("- To pet someone, rightclick on them (they must be a animal!)"), false); + context.getSource().sendFeedback(() -> Text.empty(), false); + context.getSource().sendFeedback(() -> TextParserUtils.formatText("Available animals: " + String.join(", ", AnimalRP.animals.keySet().stream().toList())), false); + + return 0; + })); + } + +} \ No newline at end of file diff --git a/src/main/java/ovh/sad/animalrp/mixin/FoodEating.java b/src/main/java/ovh/sad/animalrp/mixin/FoodEating.java index a506d1f..560cc8e 100644 --- a/src/main/java/ovh/sad/animalrp/mixin/FoodEating.java +++ b/src/main/java/ovh/sad/animalrp/mixin/FoodEating.java @@ -1,5 +1,6 @@ package ovh.sad.animalrp.mixin; +import net.minecraft.item.Item; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -17,13 +18,14 @@ import ovh.sad.animalrp.AnimalRP; import ovh.sad.animalrp.animals.Animal; import ovh.sad.animalrp.animals.Bee; -@Mixin(value = LivingEntity.class) +@Mixin(value = Item.class) public class FoodEating { - @Inject(method = "eatFood", at = @At("HEAD")) - public void eatFood(World world, ItemStack stack, FoodComponent foodComponent, CallbackInfoReturnable cfr) { - LivingEntity entity = (LivingEntity) (Object) this; - if (entity.getType().equals(EntityType.PLAYER)) { - ServerPlayerEntity player = (ServerPlayerEntity) entity; + @Inject(method = "finishUsing", at = @At("HEAD")) + public void finishUsing(ItemStack stack, World world, LivingEntity user, CallbackInfoReturnable cfr) { + if(world.isClient()) return; + + if (user.getType().equals(EntityType.PLAYER)) { + ServerPlayerEntity player = (ServerPlayerEntity) user; Animal animal = AnimalRP.users.get(player.getUuid()); diff --git a/src/main/java/ovh/sad/animalrp/util/Cooldown.java b/src/main/java/ovh/sad/animalrp/util/Cooldown.java deleted file mode 100644 index dc5f12a..0000000 --- a/src/main/java/ovh/sad/animalrp/util/Cooldown.java +++ /dev/null @@ -1,35 +0,0 @@ -package ovh.sad.animalrp.util; - -import com.google.gson.JsonObject; - -public class Cooldown { - public long timeCreated; - public Integer length; - public String type; - - public long getTime() { - return this.timeCreated - (System.currentTimeMillis() - this.length); - } - - public boolean isExpired() { - return this.getTime() <= 0; - } - - public JsonObject toJson() { - JsonObject obj = new JsonObject(); - obj.addProperty("timeCreated", this.timeCreated); - obj.addProperty("length", this.length); - obj.addProperty("type", this.type); - - return obj; - } - - public static Cooldown fromJson(JsonObject obj) { - Cooldown cldn = new Cooldown(); - cldn.timeCreated = obj.get("timeCreated").getAsLong(); - cldn.length = obj.get("length").getAsInt(); - cldn.type = obj.get("type").getAsString(); - - return cldn; - } -} \ No newline at end of file