first commit
This commit is contained in:
commit
2f5a4bc647
74 changed files with 2126 additions and 0 deletions
13
animalrp-fabric/bin/main/animalrp.mixins.json
Normal file
13
animalrp-fabric/bin/main/animalrp.mixins.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"required": true,
|
||||
"package": "ovh.sad.animalrp.fabric.mixin",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"server": [
|
||||
"DecoratedMessage",
|
||||
"FoodEating",
|
||||
"Sneaking"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
||||
32
animalrp-fabric/bin/main/fabric.mod.json
Normal file
32
animalrp-fabric/bin/main/fabric.mod.json
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "animalrp",
|
||||
"version": "${version}",
|
||||
"name": "AnimalRP",
|
||||
"description": "AnimalRP, an plugin for furry minecraft servers that mangles your text, adds specific types of animals that have different improvements and more!",
|
||||
"authors": [
|
||||
"@fucksophie"
|
||||
],
|
||||
"contact": {
|
||||
"homepage": "https://sad.ovh",
|
||||
"sources": "https://git.sad.ovh/sophie/animalrp2"
|
||||
},
|
||||
"license": "CC0-1.0",
|
||||
"icon": "assets/animal-rp/icon.png",
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"server": [
|
||||
"ovh.sad.animalrp.fabric.AnimalRPFabric"
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
"animal-rp.mixins.json"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.4",
|
||||
"minecraft": "~1.21.1",
|
||||
"java": ">=21",
|
||||
"fabric-api": "*",
|
||||
"placeholder-api": "*"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
61
animalrp-fabric/build.gradle
Normal file
61
animalrp-fabric/build.gradle
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import net.fabricmc.loom.task.RemapJarTask
|
||||
|
||||
plugins {
|
||||
id 'fabric-loom' version '1.7-SNAPSHOT'
|
||||
id "com.github.johnrengelman.shadow" version "8.1.1"
|
||||
}
|
||||
|
||||
archivesBaseName = 'animalrp'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
||||
maven { url 'https://maven.fabricmc.net/' }
|
||||
maven {
|
||||
url "https://maven.nucleoid.xyz/"
|
||||
name "Nucleoid"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||
include(modImplementation("eu.pb4:placeholder-api:2.4.1+1.21"))
|
||||
|
||||
implementation project(':animalrp-common')
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property 'version', project.mod_version
|
||||
filesMatching('**/fabric.mod.json') {
|
||||
expand 'version': project.mod_version
|
||||
}
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
archiveFileName = "animalrpfabric-${project.mod_version}-dev.jar"
|
||||
|
||||
dependencies {
|
||||
exclude('net.fabricmc:.*')
|
||||
include(dependency('ovh.sad:.*'))
|
||||
include(dependency('ovh.sad.animalrp:.*'))
|
||||
// We don't want to include the mappings in the jar do we?
|
||||
exclude '/mappings/*'
|
||||
}
|
||||
}
|
||||
|
||||
task remappedShadowJar(type: RemapJarTask) {
|
||||
dependsOn tasks.shadowJar
|
||||
input = tasks.shadowJar.archiveFile
|
||||
addNestedDependencies = true
|
||||
archiveFileName = "AnimalRP-Fabric-${project.mod_version}.jar"
|
||||
}
|
||||
|
||||
tasks.assemble.dependsOn tasks.remappedShadowJar
|
||||
|
||||
artifacts {
|
||||
archives remappedShadowJar
|
||||
shadow shadowJar
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package ovh.sad.animalrp.fabric;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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 net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.util.Identifier;
|
||||
import ovh.sad.animalrp.common.AnimalRP;
|
||||
import ovh.sad.animalrp.common.util.Animal;
|
||||
import ovh.sad.animalrp.common.util.HashmapStore;
|
||||
import ovh.sad.animalrp.fabric.animals.Bee;
|
||||
import ovh.sad.animalrp.fabric.animals.Cat;
|
||||
import ovh.sad.animalrp.fabric.animals.Dog;
|
||||
import ovh.sad.animalrp.fabric.animals.Fox;
|
||||
|
||||
public class AnimalRPFabric implements ModInitializer, AnimalRP {
|
||||
public static ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
|
||||
|
||||
public static HashmapStore hashmapStore = new HashmapStore(
|
||||
FabricLoader.getInstance().getConfigDir().resolve(AnimalRP.MOD_ID).toAbsolutePath());
|
||||
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
LOGGER.info(welcomeMessage);
|
||||
|
||||
animals.put("cat", new Cat());
|
||||
animals.put("dog", new Dog());
|
||||
animals.put("fox", new Fox());
|
||||
animals.put("bee", new Bee());
|
||||
|
||||
hashmapStore.get("users.json").forEach((k, v) -> {
|
||||
users.put(UUID.fromString(k), animals.get(v));
|
||||
});
|
||||
hashmapStore.get("nochat.json").forEach((k, v) -> {
|
||||
noChat.put(UUID.fromString(k), Boolean.valueOf(v));
|
||||
});
|
||||
|
||||
Placeholders.register(Identifier.of("animalrp", "animalcolor"), new PlaceholderHandler() {
|
||||
@Override
|
||||
public PlaceholderResult onPlaceholderRequest(PlaceholderContext ctx, @Nullable String arg) {
|
||||
if (!ctx.hasPlayer())
|
||||
return PlaceholderResult.invalid("No player!");
|
||||
Animal<?, ?> animal = users.get(ctx.player().getUuid());
|
||||
if (animal == null)
|
||||
return PlaceholderResult.value("");
|
||||
if (noChat.get(ctx.player().getUuid()) != null)
|
||||
return PlaceholderResult.value("");
|
||||
return PlaceholderResult.value(animal.color);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
package ovh.sad.animalrp.fabric.animals;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import net.fabricmc.fabric.api.event.player.UseItemCallback;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.component.DataComponentTypes;
|
||||
import net.minecraft.component.type.FoodComponent;
|
||||
import net.minecraft.entity.effect.StatusEffectInstance;
|
||||
import net.minecraft.entity.effect.StatusEffects;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
import ovh.sad.animalrp.common.util.Animal;
|
||||
import ovh.sad.animalrp.common.util.Mood;
|
||||
import ovh.sad.animalrp.common.util.TextDestroyer;
|
||||
import ovh.sad.animalrp.fabric.AnimalRPFabric;
|
||||
|
||||
public class Bee extends Animal<SoundEvent, Item> {
|
||||
class Row {
|
||||
Item mat;
|
||||
Integer times;
|
||||
}
|
||||
|
||||
private static Item[] _allFlowers = { Items.ALLIUM, Items.AZURE_BLUET, Items.BLUE_ORCHID,
|
||||
Items.CORNFLOWER, Items.DANDELION, Items.LILY_OF_THE_VALLEY, Items.OXEYE_DAISY,
|
||||
Items.POPPY, Items.TORCHFLOWER, Items.ORANGE_TULIP, Items.PINK_TULIP, Items.RED_TULIP,
|
||||
Items.WHITE_TULIP };
|
||||
public static List<Item> allFlowers = Arrays.asList(_allFlowers);
|
||||
public static Identifier beeFoodKey = Identifier.of("animalrp", "bee_food");
|
||||
public static HashMap<UUID, Row> inARow = new HashMap<UUID, Row>();
|
||||
TextDestroyer destroyer = new TextDestroyer(new String[] {
|
||||
">_<", "*buzz*",
|
||||
";3", ":3", "εწз", " ≧◠◡◠≦ ", "*stings you*", "*humms*",
|
||||
"*i'm a bee*"
|
||||
}, new String[][] {
|
||||
{ "e", "ee" },
|
||||
{ "b", "bzz" },
|
||||
{ "h", "hh" },
|
||||
{ "ie", "ee" },
|
||||
{ "be", "bee" },
|
||||
{ "E", "EE" },
|
||||
{ "B", "BZZ" },
|
||||
{ "H", "HH" },
|
||||
{ "IE", "EE" },
|
||||
{ "BE", "BEE" }
|
||||
});
|
||||
|
||||
ArrayList<UUID> sneakers = new ArrayList<UUID>();
|
||||
|
||||
public static Boolean isItemARP(ItemStack is) {
|
||||
return (allFlowers.contains(is.getItem()) && is.get(DataComponentTypes.FOOD) != null);
|
||||
}
|
||||
|
||||
public Bee() {
|
||||
super("bee", "Buzz...", "#FFFF00");
|
||||
this.moodSounds.put(Mood.HAPPY, SoundEvents.ENTITY_BEE_LOOP);
|
||||
this.moodSounds.put(Mood.CUTE, SoundEvents.ENTITY_BEE_LOOP);
|
||||
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);
|
||||
UseItemCallback.EVENT.register((player, world, hand) -> {
|
||||
Animal<?,?> animal = AnimalRPFabric.users.get(player.getUuid());
|
||||
|
||||
ItemStack item = player.getStackInHand(hand);
|
||||
|
||||
if (item == null) // air interact
|
||||
return TypedActionResult.pass(item);
|
||||
|
||||
if (!allFlowers.contains(item.getItem())) { // not a flower
|
||||
return TypedActionResult.pass(item);
|
||||
}
|
||||
|
||||
Boolean incorrect = false;
|
||||
|
||||
if (animal == null) {
|
||||
incorrect = true;
|
||||
} else {
|
||||
if (animal.name != this.name) {
|
||||
incorrect = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (incorrect) {
|
||||
if (Bee.isItemARP(item)) {
|
||||
item.remove(DataComponentTypes.FOOD);
|
||||
|
||||
return TypedActionResult.pass(item);
|
||||
}
|
||||
return TypedActionResult.pass(item);
|
||||
}
|
||||
|
||||
if (Bee.isItemARP(item)) { // correct animal, but foodkey already set
|
||||
return TypedActionResult.pass(item);
|
||||
}
|
||||
|
||||
FoodComponent food = new FoodComponent.Builder()
|
||||
.statusEffect(new StatusEffectInstance(StatusEffects.SPEED, 20 * 4, 1, true, true, true), 1)
|
||||
.alwaysEdible()
|
||||
.nutrition(4)
|
||||
.saturationModifier(9.4f)
|
||||
.build();
|
||||
|
||||
item.set(DataComponentTypes.FOOD, food);
|
||||
|
||||
return TypedActionResult.pass(item);
|
||||
});
|
||||
}
|
||||
|
||||
// Called from the FoodEating mixin.
|
||||
// Called only if the player is a animal and a bee.
|
||||
public void onEat(ServerPlayerEntity player, ItemStack item) {
|
||||
if (!allFlowers.contains(item.getItem())) { // not a flower
|
||||
return;
|
||||
}
|
||||
|
||||
Row row = inARow.get(player.getUuid()); // make a new row
|
||||
if (row == null) { // none yet
|
||||
row = new Row();
|
||||
row.mat = item.getItem();
|
||||
row.times = 1;
|
||||
} else {
|
||||
if (row.mat.equals(item.getItem())) { // mat is same as in row, increase time
|
||||
row.times += 1;
|
||||
} else {
|
||||
row.mat = item.getItem(); // mat not same, change mat, reset time
|
||||
row.times = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (row.times > 20) {
|
||||
player.addStatusEffect(new StatusEffectInstance(StatusEffects.NAUSEA, 20 * 10, 1, true, true));
|
||||
}
|
||||
if (row.times > 30) {
|
||||
if (row.times > 40) {
|
||||
player.addStatusEffect(new StatusEffectInstance(StatusEffects.WEAKNESS, 20 * 10, 3, true, true));
|
||||
} else {
|
||||
player.addStatusEffect(new StatusEffectInstance(StatusEffects.WEAKNESS, 20 * 5, 2, true, true));
|
||||
}
|
||||
}
|
||||
|
||||
inARow.put(player.getUuid(), row);
|
||||
}
|
||||
|
||||
// Called from the 'Sneaking' mixin.
|
||||
public void onSneak(ServerPlayerEntity player, boolean status) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Animal<SoundEvent,?> animal = (Animal<SoundEvent, Item>) AnimalRPFabric.users.get(player.getUuid());
|
||||
if (animal == null)
|
||||
return;
|
||||
if (animal.name != this.name)
|
||||
return;
|
||||
|
||||
Block type = player.getWorld().getBlockState(player.getBlockPos().down()).getBlock();
|
||||
|
||||
if (status
|
||||
&& type != Blocks.AIR && type != Blocks.WATER) {
|
||||
if (!sneakers.contains(player.getUuid())) {
|
||||
sneakers.add(player.getUuid());
|
||||
AnimalRPFabric.executor.schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (sneakers.contains(player.getUuid()))
|
||||
sneakers.remove(player.getUuid());
|
||||
}
|
||||
}, 1, TimeUnit.SECONDS);
|
||||
} else {
|
||||
sneakers.remove(player.getUuid());
|
||||
player.addStatusEffect(
|
||||
new StatusEffectInstance(StatusEffects.LEVITATION, 20, 5, true, true, true));
|
||||
player.getWorld().playSound(player, player.getBlockPos(),
|
||||
animal.moodSounds.get(Mood.HAPPY), SoundCategory.PLAYERS, 10F, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String chatTransformations(String message) {
|
||||
return destroyer.destroy(message);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package ovh.sad.animalrp.fabric.animals;
|
||||
|
||||
|
||||
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents;
|
||||
import net.minecraft.entity.damage.DamageTypes;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import ovh.sad.animalrp.common.util.Animal;
|
||||
import ovh.sad.animalrp.common.util.Mood;
|
||||
import ovh.sad.animalrp.common.util.TextDestroyer;
|
||||
import ovh.sad.animalrp.fabric.AnimalRPFabric;
|
||||
|
||||
public class Cat extends Animal<SoundEvent, Item> {
|
||||
TextDestroyer destroyer = new TextDestroyer(new String[]{
|
||||
">_<", ":3", "ʕʘ‿ʘʔ", ":D", "._.",
|
||||
";3", "xD", "ㅇㅅㅇ",
|
||||
">_>", "ÙωÙ", "UwU", "OwO", ":P",
|
||||
"(◠‿◠✿)", "^_^", ";_;",
|
||||
"x3", "(• o •)", "<_<"
|
||||
}, new String[][]{
|
||||
{"l", "w"},
|
||||
{"r", "w"},
|
||||
{"th", "d"},
|
||||
{"L", "W"},
|
||||
{"R", "W"},
|
||||
{"TH", "D"}
|
||||
});
|
||||
|
||||
public Cat() {
|
||||
super("cat", "Nya~", "#F2BDCD");
|
||||
this.moodSounds.put(Mood.HAPPY, SoundEvents.ENTITY_CAT_PURR);
|
||||
this.moodSounds.put(Mood.CUTE, SoundEvents.ENTITY_CAT_PURREOW);
|
||||
this.moodSounds.put(Mood.SAD, SoundEvents.ENTITY_CAT_AMBIENT);
|
||||
this.moodSounds.put(Mood.STRESSED, SoundEvents.ENTITY_CAT_STRAY_AMBIENT);
|
||||
this.moodSounds.put(Mood.ANGRY, SoundEvents.ENTITY_CAT_HISS);
|
||||
|
||||
this.superfoods.add(Items.COOKED_COD);
|
||||
this.superfoods.add(Items.COD);
|
||||
this.superfoods.add(Items.COOKED_SALMON);
|
||||
this.superfoods.add(Items.SALMON);
|
||||
|
||||
ServerLivingEntityEvents.AFTER_DAMAGE.register((entity, source, baseDmg, dmg, blocked) -> {
|
||||
if (entity instanceof ServerPlayerEntity player) {
|
||||
Animal<?,?> animal = AnimalRPFabric.users.get(player.getUuid());
|
||||
|
||||
if (animal == null || !animal.name.equals(this.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (source.isOf(DamageTypes.FALL)) {
|
||||
player.setHealth(Math.max(player.getMaxHealth(), player.getHealth() + 5));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String chatTransformations(String message) {
|
||||
return destroyer.destroy(message);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package ovh.sad.animalrp.fabric.animals;
|
||||
|
||||
import net.fabricmc.fabric.api.event.player.AttackEntityCallback;
|
||||
import net.minecraft.entity.effect.StatusEffectInstance;
|
||||
import net.minecraft.entity.effect.StatusEffects;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import ovh.sad.animalrp.common.util.Animal;
|
||||
import ovh.sad.animalrp.common.util.Mood;
|
||||
import ovh.sad.animalrp.common.util.TextDestroyer;
|
||||
import ovh.sad.animalrp.fabric.AnimalRPFabric;
|
||||
|
||||
public class Dog extends Animal<SoundEvent, Item> {
|
||||
TextDestroyer destroyer = new TextDestroyer(new String[] {
|
||||
"Woof!", "Bark :3",
|
||||
"Arf", "bark bark bark", "arf~"
|
||||
}, new String[][] {
|
||||
});
|
||||
|
||||
public Dog() {
|
||||
super("dog", "Arf!", "#ff8c00");
|
||||
this.moodSounds.put(Mood.HAPPY, SoundEvents.ENTITY_WOLF_AMBIENT);
|
||||
this.moodSounds.put(Mood.CUTE, SoundEvents.ENTITY_WOLF_STEP);
|
||||
this.moodSounds.put(Mood.SAD, SoundEvents.ENTITY_WOLF_WHINE);
|
||||
this.moodSounds.put(Mood.STRESSED, SoundEvents.ENTITY_WOLF_SHAKE);
|
||||
this.moodSounds.put(Mood.ANGRY, SoundEvents.ENTITY_WOLF_GROWL);
|
||||
|
||||
this.superfoods.add(Items.CHICKEN);
|
||||
this.superfoods.add(Items.BEEF);
|
||||
this.superfoods.add(Items.PORKCHOP);
|
||||
|
||||
AttackEntityCallback.EVENT.register((player, world, hand, entity, hitResult) -> {
|
||||
Animal<?,?> animal = AnimalRPFabric.users.get(player.getUuid());
|
||||
|
||||
if (animal == null)
|
||||
return ActionResult.PASS;
|
||||
if (animal.name != this.name)
|
||||
return ActionResult.PASS;
|
||||
player.removeStatusEffect(StatusEffects.SPEED);
|
||||
player.addStatusEffect(
|
||||
new StatusEffectInstance(StatusEffects.SPEED, 20, 2, true, true, true));
|
||||
return ActionResult.PASS;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String chatTransformations(String message) {
|
||||
return destroyer.destroy(message);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package ovh.sad.animalrp.fabric.animals;
|
||||
|
||||
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import ovh.sad.animalrp.common.util.Animal;
|
||||
import ovh.sad.animalrp.common.util.Mood;
|
||||
import ovh.sad.animalrp.common.util.TextDestroyer;
|
||||
import ovh.sad.animalrp.fabric.AnimalRPFabric;
|
||||
|
||||
public class Fox extends Animal<SoundEvent, Item> {
|
||||
TextDestroyer destroyer = new TextDestroyer(new String[] {
|
||||
"yap",
|
||||
"*yap yap*",
|
||||
"*beeps*",
|
||||
"*barks*",
|
||||
"*screeches*",
|
||||
":3"
|
||||
}, new String[][] {
|
||||
{ "you", "u" },
|
||||
{ "o", "yo" },
|
||||
{ "i", "yi" },
|
||||
{ "!", " !" },
|
||||
{ "?", " ?" }
|
||||
});
|
||||
|
||||
public Fox() {
|
||||
super("fox", "Yap!", "#FF8000");
|
||||
this.moodSounds.put(Mood.HAPPY, SoundEvents.ENTITY_FOX_SNIFF);
|
||||
this.moodSounds.put(Mood.CUTE, SoundEvents.ENTITY_FOX_SLEEP);
|
||||
this.moodSounds.put(Mood.SAD, SoundEvents.ENTITY_FOX_SNIFF);
|
||||
this.moodSounds.put(Mood.STRESSED, SoundEvents.ENTITY_FOX_AGGRO);
|
||||
this.moodSounds.put(Mood.ANGRY, SoundEvents.ENTITY_FOX_BITE);
|
||||
|
||||
this.superfoods.add(Items.APPLE);
|
||||
this.superfoods.add(Items.GLOW_BERRIES);
|
||||
|
||||
ServerLivingEntityEvents.AFTER_DAMAGE.register((entity, source, baseDmg, dmg, blocked) -> {
|
||||
if(!(source.getSource() instanceof ServerPlayerEntity)) return;
|
||||
if(entity instanceof PlayerEntity) return;
|
||||
|
||||
Entity victim = entity;
|
||||
ServerPlayerEntity damager = (ServerPlayerEntity) source.getSource();
|
||||
|
||||
Animal<?,?> animal = AnimalRPFabric.users.get(damager.getUuid());
|
||||
|
||||
if (animal == null || !animal.name.equals(this.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
victim.damage(victim.getDamageSources().playerAttack(damager), dmg * 0.25F);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String chatTransformations(String message) {
|
||||
return this.destroyer.destroy(message);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
package ovh.sad.animalrp.fabric.commands;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
|
||||
import eu.pb4.placeholders.api.TextParserUtils;
|
||||
import net.minecraft.command.CommandRegistryAccess;
|
||||
import net.minecraft.command.argument.EntityArgumentType;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.server.command.CommandManager;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.text.Text;
|
||||
import ovh.sad.animalrp.common.util.Animal;
|
||||
import ovh.sad.animalrp.common.util.Messages;
|
||||
import ovh.sad.animalrp.common.util.Mood;
|
||||
import ovh.sad.animalrp.fabric.AnimalRPFabric;
|
||||
|
||||
|
||||
public class InteractionCommand {
|
||||
String command;
|
||||
String toThem;
|
||||
String toYou;
|
||||
Mood mood;
|
||||
|
||||
public InteractionCommand(String command, Mood mood, String toThem, String toYou) {
|
||||
this.command = command;
|
||||
this.toThem = toThem;
|
||||
this.toYou = toYou;
|
||||
this.mood = mood;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void Command(CommandDispatcher<ServerCommandSource> dispatcher, CommandRegistryAccess registryAccess,
|
||||
CommandManager.RegistrationEnvironment environment) {
|
||||
dispatcher.register(CommandManager.literal(this.command)
|
||||
.then(CommandManager.argument("player", EntityArgumentType.player())
|
||||
.executes(context -> {
|
||||
Entity sender = context.getSource().getEntity();
|
||||
|
||||
if (!(sender instanceof ServerPlayerEntity)) {
|
||||
context.getSource().sendFeedback(
|
||||
() -> Text.literal(Messages.get("no_console")).withColor(8421504), false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ServerPlayerEntity player = context.getSource().getPlayer();
|
||||
|
||||
Animal<?,?> aplayer = AnimalRPFabric.users.get(player.getUuid());
|
||||
|
||||
if (aplayer == null) {
|
||||
context.getSource().sendFeedback(
|
||||
() -> Text.literal(Messages.get("only_animals"))
|
||||
.withColor(8421504),
|
||||
false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ServerPlayerEntity splayer = EntityArgumentType.getPlayer(context, "player");
|
||||
|
||||
if (splayer.getName() == player.getName()) {
|
||||
context.getSource().sendFeedback(
|
||||
() -> Text.literal(String.format(Messages.get("no_self_argument"), this.command))
|
||||
.withColor(8421504),
|
||||
false);
|
||||
return 0;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
Animal<SoundEvent,Mood> asplayer = (Animal<SoundEvent, Mood>) AnimalRPFabric.users.get(splayer.getUuid());
|
||||
|
||||
if (asplayer == null) {
|
||||
context.getSource().sendFeedback(
|
||||
() -> Text.literal(String.format(Messages.get("not_animal"), splayer.getName()))
|
||||
.withColor(8421504),
|
||||
false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
splayer.sendMessage(TextParserUtils.formatText(
|
||||
String.format(this.toThem,
|
||||
"<light_purple>" + player.getName().getString() + "</light_purple>",
|
||||
"<italic><gray>" + aplayer.catchphrase)));
|
||||
player.sendMessage(TextParserUtils.formatText(
|
||||
String.format(this.toYou,
|
||||
"<light_purple>" + splayer.getName().getString() + "</light_purple>",
|
||||
"<italic><gray>" + asplayer.catchphrase)));
|
||||
player.getWorld().playSound(splayer, splayer.getBlockPos(),
|
||||
asplayer.moodSounds.get(this.mood), SoundCategory.PLAYERS, 1F,
|
||||
1);
|
||||
return 1;
|
||||
})));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package ovh.sad.animalrp.fabric.commands;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
|
||||
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.common.AnimalRP;
|
||||
import ovh.sad.animalrp.common.util.Messages;
|
||||
import ovh.sad.animalrp.fabric.AnimalRPFabric;
|
||||
|
||||
public class NoChatCommand {
|
||||
public void Command(CommandDispatcher<ServerCommandSource> dispatcher, CommandRegistryAccess registryAccess,
|
||||
CommandManager.RegistrationEnvironment environment) {
|
||||
dispatcher.register(CommandManager.literal("disableanimalchat").executes(context -> {
|
||||
UUID userUuid = context.getSource().getEntity().getUuid();
|
||||
|
||||
Boolean isDisabled = AnimalRP.noChat.get(context.getSource().getEntity().getUuid());
|
||||
if (isDisabled == null)
|
||||
isDisabled = false;
|
||||
if (isDisabled) { //
|
||||
context.getSource().sendFeedback(
|
||||
() -> Text.literal(Messages.get("no_chat_command_enabled")).withColor(65280),
|
||||
false);
|
||||
AnimalRPFabric.noChat.remove(userUuid);
|
||||
} else {
|
||||
context.getSource().sendFeedback(() -> Text
|
||||
.literal(Messages.get("no_chat_command_disabled")).withColor(16711680), false);
|
||||
AnimalRPFabric.noChat.put(userUuid, true);
|
||||
}
|
||||
AnimalRPFabric.hashmapStore.save("nochat.json", AnimalRPFabric.noChat);
|
||||
|
||||
return 0;
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package ovh.sad.animalrp.fabric.commands;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
|
||||
import net.minecraft.command.CommandRegistryAccess;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.server.command.CommandManager;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.text.MutableText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
import ovh.sad.animalrp.common.util.Animal;
|
||||
import ovh.sad.animalrp.common.util.Messages;
|
||||
import ovh.sad.animalrp.fabric.AnimalRPFabric;
|
||||
|
||||
public class TfCommand {
|
||||
public void Command(CommandDispatcher<ServerCommandSource> dispatcher, CommandRegistryAccess registryAccess,
|
||||
CommandManager.RegistrationEnvironment environment) {
|
||||
dispatcher.register(CommandManager.literal("tf")
|
||||
.then(CommandManager.argument("animal", StringArgumentType.string())
|
||||
.executes(context -> {
|
||||
final Entity entity = context.getSource().getEntity();
|
||||
final String animalString = StringArgumentType.getString(context, "animal");
|
||||
|
||||
Animal<?, ?> animal = AnimalRPFabric.animals.get(animalString);
|
||||
|
||||
if (animalString.equals("off")) {
|
||||
if (AnimalRPFabric.users.get(entity.getUuid()) == null) {
|
||||
context.getSource().sendFeedback(
|
||||
() -> Text.literal(Messages.get("animal_not_set")), false);
|
||||
return 0;
|
||||
}
|
||||
AnimalRPFabric.users.remove(entity.getUuid());
|
||||
context.getSource().sendFeedback(
|
||||
() -> Text.literal(Messages.get("animal_removed")), false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (animal == null) {
|
||||
classicError(context.getSource());
|
||||
return 0;
|
||||
}
|
||||
|
||||
AnimalRPFabric.users.put(entity.getUuid(), animal);
|
||||
context.getSource()
|
||||
.sendFeedback(
|
||||
() -> Text.literal(String.format(Messages.get("animal_set"), animalString))
|
||||
.append(Text.literal(animal.catchphrase)
|
||||
.formatted(Formatting.ITALIC).withColor(
|
||||
Integer.parseInt(animal.color.substring(1),
|
||||
16))),
|
||||
false);
|
||||
AnimalRPFabric.hashmapStore.save("users.json", AnimalRPFabric.users);
|
||||
return 1;
|
||||
})));
|
||||
}
|
||||
|
||||
void classicError(ServerCommandSource source) {
|
||||
MutableText options = Text.literal(Messages.get("your_options"));
|
||||
for (Entry<String, Animal<?, ?>> entry : AnimalRPFabric.animals.entrySet()) {
|
||||
options.append(Text.literal(entry.getKey() + " ")
|
||||
.withColor(Integer.parseInt(entry.getValue().color.substring(1), 16)));
|
||||
}
|
||||
source.sendFeedback(() -> Text.literal(Messages.get("invalid_animal")).withColor(16711680), false);
|
||||
source.sendFeedback(() -> options, false);
|
||||
source.sendFeedback(() -> Text.literal(Messages.get("tf_off")), false);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package ovh.sad.animalrp.fabric.mixin;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
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.ModifyVariable;
|
||||
|
||||
import net.minecraft.network.message.SignedMessage;
|
||||
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.text.Text;
|
||||
import ovh.sad.animalrp.common.util.Animal;
|
||||
import ovh.sad.animalrp.common.util.Mood;
|
||||
import ovh.sad.animalrp.fabric.AnimalRPFabric;
|
||||
|
||||
@Mixin(value = ServerPlayNetworkHandler.class, priority = 1) // make sure we run FIRST
|
||||
public abstract class DecoratedMessage {
|
||||
@Shadow
|
||||
public ServerPlayerEntity player;
|
||||
@Unique
|
||||
Random random = new Random();
|
||||
|
||||
@ModifyVariable(method = "handleDecoratedMessage", at = @At(value = "HEAD"), argsOnly = true)
|
||||
public @NotNull SignedMessage modifyChatMessageSentByPlayers(@NotNull SignedMessage original) {
|
||||
if (AnimalRPFabric.noChat.get(player.getUuid()) != null)
|
||||
return original;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Animal<SoundEvent, Mood> animal = (Animal<SoundEvent, Mood>) AnimalRPFabric.users.get(player.getUuid());
|
||||
if (animal == null)
|
||||
return original;
|
||||
if (random.nextDouble() < 0.08) {
|
||||
player.getWorld().playSound(player, player.getBlockPos(),
|
||||
animal.moodSounds.get(Mood.HAPPY), SoundCategory.PLAYERS, 10F, 1);
|
||||
}
|
||||
|
||||
return original
|
||||
.withUnsignedContent(Text.literal(animal.chatTransformations(original.getContent().getString())));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package ovh.sad.animalrp.fabric.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.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.component.type.FoodComponent;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.effect.StatusEffectInstance;
|
||||
import net.minecraft.entity.effect.StatusEffects;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.world.World;
|
||||
import ovh.sad.animalrp.common.util.Animal;
|
||||
import ovh.sad.animalrp.fabric.AnimalRPFabric;
|
||||
import ovh.sad.animalrp.fabric.animals.Bee;
|
||||
|
||||
@Mixin(value = LivingEntity.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;
|
||||
|
||||
Animal<?, ?> animal = AnimalRPFabric.users.get(player.getUuid());
|
||||
|
||||
if (animal != null) {
|
||||
if (animal.name == "bee") {
|
||||
((Bee) animal).onEat(player, stack);
|
||||
}
|
||||
if (animal.superfoods.contains(stack.getItem())) {
|
||||
player.getHungerManager().add(4, 9.4f);
|
||||
|
||||
StatusEffectInstance effect = player.getStatusEffect(StatusEffects.SPEED);
|
||||
int duration = 20 * 4;
|
||||
|
||||
if (effect != null) {
|
||||
duration += effect.getDuration();
|
||||
}
|
||||
player.addStatusEffect(
|
||||
new StatusEffectInstance(StatusEffects.SPEED, duration, 1, true, true, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package ovh.sad.animalrp.fabric.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 net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import ovh.sad.animalrp.fabric.AnimalRPFabric;
|
||||
import ovh.sad.animalrp.fabric.animals.Bee;
|
||||
|
||||
@Mixin(Entity.class)
|
||||
public class Sneaking {
|
||||
@Inject(method = "setSneaking", at = @At("HEAD"))
|
||||
public void setSneaking(boolean sneaking, CallbackInfo info) {
|
||||
Entity entity = (Entity) (Object) this;
|
||||
if (entity.getType() == EntityType.PLAYER) {
|
||||
Bee bee = (Bee) AnimalRPFabric.animals.get("bee");
|
||||
bee.onSneak((ServerPlayerEntity) entity, sneaking);
|
||||
}
|
||||
}
|
||||
}
|
||||
13
animalrp-fabric/src/main/resources/animalrp.mixins.json
Normal file
13
animalrp-fabric/src/main/resources/animalrp.mixins.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"required": true,
|
||||
"package": "ovh.sad.animalrp.fabric.mixin",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"server": [
|
||||
"DecoratedMessage",
|
||||
"FoodEating",
|
||||
"Sneaking"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
||||
32
animalrp-fabric/src/main/resources/fabric.mod.json
Normal file
32
animalrp-fabric/src/main/resources/fabric.mod.json
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "animalrp",
|
||||
"version": "${version}",
|
||||
"name": "AnimalRP",
|
||||
"description": "AnimalRP, an plugin for furry minecraft servers that mangles your text, adds specific types of animals that have different improvements and more!",
|
||||
"authors": [
|
||||
"@fucksophie"
|
||||
],
|
||||
"contact": {
|
||||
"homepage": "https://sad.ovh",
|
||||
"sources": "https://git.sad.ovh/sophie/animalrp2"
|
||||
},
|
||||
"license": "CC0-1.0",
|
||||
"icon": "assets/animal-rp/icon.png",
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"server": [
|
||||
"ovh.sad.animalrp.fabric.AnimalRPFabric"
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
"animal-rp.mixins.json"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.16.4",
|
||||
"minecraft": "~1.21.1",
|
||||
"java": ">=21",
|
||||
"fabric-api": "*",
|
||||
"placeholder-api": "*"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue