diff options
author | SoniEx2 <endermoneymod@gmail.com> | 2022-08-17 21:21:26 -0300 |
---|---|---|
committer | SoniEx2 <endermoneymod@gmail.com> | 2022-08-17 21:24:57 -0300 |
commit | 2d0b363fe3179087de59d9ef4a2d14af21d89071 (patch) | |
tree | befdb1f281c3abd82c23d9f6855a3237170e47a5 /src | |
parent | 731e568ad487b8f7dfbedf22eaca9b12cb3e754d (diff) |
[Project] ChewStuff
Chew Necklaces for Minecraft!
Diffstat (limited to 'src')
27 files changed, 638 insertions, 51 deletions
diff --git a/src/main/java/ganarchy/chewstuff/ChewComponent.java b/src/main/java/ganarchy/chewstuff/ChewComponent.java new file mode 100644 index 0000000..4b6dcd8 --- /dev/null +++ b/src/main/java/ganarchy/chewstuff/ChewComponent.java @@ -0,0 +1,93 @@ +package ganarchy.chewstuff; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import dev.onyxstudios.cca.api.v3.component.ComponentV3; +import net.minecraft.entity.effect.StatusEffect; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtOps; +import net.minecraft.util.registry.Registry; + +import java.util.*; + +/** + * Component for chews. + */ +public class ChewComponent implements ComponentV3 { + /** + * Codec for encoding/decoding this component. + */ + public static final Codec<ChewComponent> CODEC = RecordCodecBuilder.create( + inst -> inst.group( + Codec.unboundedMap( + Registry.STATUS_EFFECT.getCodec(), Codec.INT + ).fieldOf("effects").forGetter(i -> i.effects), + Codec.list( + Registry.STATUS_EFFECT.getCodec() + ).fieldOf("applied").forGetter(i -> new ArrayList<>(i.applied)), + Codec.BOOL.fieldOf("sendUpdate").forGetter(i -> i.sendUpdate) + ).apply(inst, ChewComponent::new) + ); + /** + * The effects we're currently consuming. + */ + public Map<StatusEffect, Integer> effects; + /** + * The effects which have been applied and should be skipped. + */ + public Set<StatusEffect> applied; + /** + * Whether to send updated effects to the client. + */ + public boolean sendUpdate; + + /** + * Creates a new ChewInfo with no effects. + */ + public ChewComponent() { + this.effects = new HashMap<>(); + this.applied = new HashSet<>(); + } + + /** + * Creates a new ChewInfo with the specified effects. + * + * @param effects The bound effects. + * @param applied The applied effects. + */ + public ChewComponent( + Map<StatusEffect, Integer> effects, + List<StatusEffect> applied, + boolean sendUpdate + ) { + if (effects instanceof HashMap) { + this.effects = effects; + } else { + // ideally we'd just make the HashMap directly but DFU doesn't let + // you set the Map class. + // actually ideally we'd use IdentityHashMap but w/e. + this.effects = new HashMap<>(effects); + } + this.applied = new HashSet<>(applied); + this.sendUpdate = sendUpdate; + } + + @Override + public void readFromNbt(NbtCompound tag) { + var info = ChewComponent.CODEC.parse( + NbtOps.INSTANCE, + tag + ).result().orElseGet(ChewComponent::new); + + this.effects = info.effects; + this.applied = info.applied; + } + + @Override + public void writeToNbt(NbtCompound tag) { + tag.copyFrom((NbtCompound) ChewComponent.CODEC.encodeStart( + NbtOps.INSTANCE, + this + ).result().orElseThrow()); + } +} diff --git a/src/main/java/ganarchy/chewstuff/ChewComponents.java b/src/main/java/ganarchy/chewstuff/ChewComponents.java new file mode 100644 index 0000000..427d86e --- /dev/null +++ b/src/main/java/ganarchy/chewstuff/ChewComponents.java @@ -0,0 +1,28 @@ +package ganarchy.chewstuff; + +import dev.onyxstudios.cca.api.v3.component.ComponentKey; +import dev.onyxstudios.cca.api.v3.component.ComponentRegistry; +import dev.onyxstudios.cca.api.v3.entity.EntityComponentFactoryRegistry; +import dev.onyxstudios.cca.api.v3.entity.EntityComponentInitializer; +import dev.onyxstudios.cca.api.v3.entity.RespawnCopyStrategy; +import net.minecraft.entity.LivingEntity; +import net.minecraft.util.Identifier; + +public class ChewComponents implements EntityComponentInitializer { + public static final ComponentKey<ChewComponent> CHEW = + ComponentRegistry.getOrCreate( + new Identifier("chewstuff", "chew"), ChewComponent.class + ); + + @Override + public void registerEntityComponentFactories( + EntityComponentFactoryRegistry registry + ) { + registry.registerFor( + LivingEntity.class, CHEW, entity -> new ChewComponent() + ); + registry.registerForPlayers( + CHEW, entity -> new ChewComponent(), RespawnCopyStrategy.ALWAYS_COPY + ); + } +} diff --git a/src/main/java/ganarchy/chewstuff/ChewStuff.java b/src/main/java/ganarchy/chewstuff/ChewStuff.java new file mode 100644 index 0000000..7bea0ec --- /dev/null +++ b/src/main/java/ganarchy/chewstuff/ChewStuff.java @@ -0,0 +1,90 @@ +package ganarchy.chewstuff; + +import net.fabricmc.api.ModInitializer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemGroup; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The mod's entry point. + */ +public class ChewStuff implements ModInitializer { + /** + * The ChewStuff Logger. + */ + public static final Logger LOGGER = LoggerFactory.getLogger("chewstuff"); + + /** + * Silicone. Not to be confused with silicon. Crafting material for + * chews. + */ + public static final Item SILICONE = new Item( + new Item.Settings().group(ItemGroup.MISC) + ); + /** + * 1 day, in ticks. + */ + public static final int DAY_MULTIPLIER = 24 * 60 * 60 * 20; + /** + * Soft chew. Lasts 5 days, 1 effect slot. + */ + public static final Item SOFT_CHEW = new ChewableItem( + 1, + new Item.Settings().maxDamage(5 * DAY_MULTIPLIER).group(ItemGroup.TOOLS) + ); + /** + * Medium chew. Lasts 6 days, 2 effect slots. + */ + public static final Item MEDIUM_CHEW = new ChewableItem( + 2, + new Item.Settings().maxDamage(6 * DAY_MULTIPLIER).group(ItemGroup.TOOLS) + ); + /** + * Hard chew. Lasts 7 days, 3 effect slots. + */ + public static final Item HARD_CHEW = new ChewableItem( + 3, + new Item.Settings().maxDamage(7 * DAY_MULTIPLIER).group(ItemGroup.TOOLS) + ); + /** + * The stat for chew effects. + */ + public static final Identifier CHEW_EFFECTS = new Identifier( + "chewstuff", "effects" + ); + + @Override + public void onInitialize() { + // This code runs as soon as Minecraft is in a mod-load-ready state. + // However, some things (like resources) may still be uninitialized. + // Proceed with mild caution. + + LOGGER.info("This software is made with love by a queer trans person."); + + Registry.register( + Registry.ITEM, + new Identifier("chewstuff", "silicone"), + SILICONE + ); + Registry.register( + Registry.ITEM, + new Identifier("chewstuff", "soft_chew"), + SOFT_CHEW + ); + Registry.register( + Registry.ITEM, + new Identifier("chewstuff", "medium_chew"), + MEDIUM_CHEW + ); + Registry.register( + Registry.ITEM, + new Identifier("chewstuff", "hard_chew"), + HARD_CHEW + ); +// Registry.register(Registry.CUSTOM_STAT, CHEW_EFFECTS, CHEW_EFFECTS); +// Stats.CUSTOM.getOrCreateStat(CHEW_EFFECTS, StatFormatter.DEFAULT); + } +} diff --git a/src/main/java/ganarchy/chewstuff/ChewableItem.java b/src/main/java/ganarchy/chewstuff/ChewableItem.java new file mode 100644 index 0000000..e3c8f60 --- /dev/null +++ b/src/main/java/ganarchy/chewstuff/ChewableItem.java @@ -0,0 +1,195 @@ +package ganarchy.chewstuff; + +import dev.emi.trinkets.api.SlotReference; +import dev.emi.trinkets.api.TrinketItem; +import dev.emi.trinkets.api.TrinketsApi; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.effect.StatusEffect; +import net.minecraft.entity.effect.StatusEffectInstance; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Wearable; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.network.packet.s2c.play.EntityStatusEffectS2CPacket; +import net.minecraft.server.network.ServerPlayerEntity; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Collectors; + +/** + * An item that can be chewed. + */ +public class ChewableItem extends TrinketItem implements Wearable { + /** + * The cooldown between activations, in ticks. + */ + private static final int COOLDOWN = 5 * 20; + /** + * Number of effects to bind to. + */ + private final int effects; + + /** + * @param effects Number of effects to bind to. + * @param settings The item settings. + */ + public ChewableItem(int effects, Settings settings) { + super(settings); + this.effects = effects; + } + + @Override + public void onEquip(ItemStack stack, SlotReference slot, LivingEntity entity) { + if (entity.world.isClient) { + return; + } + var maybeInfo = ChewComponents.CHEW.maybeGet(entity); + maybeInfo.ifPresent(info -> { + info.sendUpdate = true; + }); + } + + @Override + public void onUnequip( + ItemStack stack, SlotReference slot, LivingEntity entity + ) { + if (entity.world.isClient) { + return; + } + var maybeInfo = ChewComponents.CHEW.maybeGet(entity); + maybeInfo.ifPresent(info -> { + if (!info.effects.isEmpty()) { + resetEffects(entity, info); + } + }); + } + + @Override + public void tick(ItemStack stack, SlotReference slot, LivingEntity entity) { + if (entity.world.isClient) { + return; + } + if (entity instanceof PlayerEntity player) { + if (player.getItemCooldownManager().isCoolingDown(this)) { + return; + } + } + var maybeInfo = ChewComponents.CHEW.maybeGet(entity); + maybeInfo.ifPresent(info -> { + if (info.effects.isEmpty()) { + var effects = entity.getStatusEffects(); + if (effects.size() >= this.effects) { + effects = new ArrayList<>(effects); + Collections.shuffle((List<?>) effects); + info.effects = effects.stream().filter( + effect -> !effect.isAmbient() + ).limit(this.effects).collect( + Collectors.toMap( + StatusEffectInstance::getEffectType, + StatusEffectInstance::getDuration, + (i1, i2) -> { + // don't crash the game in prod + if ( + FabricLoader.getInstance() + .isDevelopmentEnvironment() + ) { + throw new IllegalStateException(); + } else { + return Integer.min(i1, i2); + } + }, + HashMap::new + ) + ); + info.sendUpdate = true; + } else { + return; + } + } + if (info.effects.size() != this.effects) { + return; + } + if (info.sendUpdate) { + sendEffectUpdate(entity, info); + } + var effects = info.effects.keySet(); + for (StatusEffect effect : effects) { + if (info.effects.get(effect) <= 0) { + continue; + } + var effectInstance = entity.getStatusEffect(effect); + if (effectInstance == null || effectInstance.isAmbient()) { + info.effects.put(effect, 0); + continue; + } + // don't wanna deal with LivingEntity internals. + if (effectInstance.getDuration() == 1) { + continue; + } + if (!effectInstance.update(entity, () -> {})) { + throw new IllegalStateException(); + } + } + if (info.effects.values().stream().allMatch(i -> i == 0)) { + resetEffects(entity, info); + } + stack.damage(1, entity, livingEntity -> { + TrinketsApi.onTrinketBroken(stack, slot, livingEntity); + }); + }); + } + + private void sendEffectUpdate(LivingEntity entity, ChewComponent info) { + if (entity instanceof ServerPlayerEntity player) { + for (StatusEffect effect : info.effects.keySet()) { + var instance = player.getStatusEffect(effect); + if (instance == null) { + continue; + } + NbtCompound nbt = new NbtCompound(); + instance.writeNbt(nbt); + nbt.putInt("Duration", instance.getDuration() / 2); + var toSend = StatusEffectInstance.fromNbt(nbt); + if (toSend != null) { + player.networkHandler.sendPacket( + new EntityStatusEffectS2CPacket( + player.getId(), + toSend + ) + ); + } + } + } + } + + /** + * Stops tracking effects, enables the cooldown, and updates the player, + * as needed. + * + * @param entity The entity. + * @param info The tracked effects. + */ + private void resetEffects(LivingEntity entity, ChewComponent info) { + if (entity instanceof ServerPlayerEntity player) { + for (StatusEffect effect : info.effects.keySet()) { + var instance = player.getStatusEffect(effect); + if (instance == null) { + continue; + } + player.networkHandler.sendPacket( + new EntityStatusEffectS2CPacket( + player.getId(), + instance + ) + ); + } + player.getItemCooldownManager().set(this, COOLDOWN); + } + info.effects.clear(); + info.applied.clear(); + } +} diff --git a/src/main/java/ganarchy/chewstuff/mixin/DesyncFix.java b/src/main/java/ganarchy/chewstuff/mixin/DesyncFix.java new file mode 100644 index 0000000..7a62a41 --- /dev/null +++ b/src/main/java/ganarchy/chewstuff/mixin/DesyncFix.java @@ -0,0 +1,30 @@ +package ganarchy.chewstuff.mixin; + +import ganarchy.chewstuff.ChewComponents; +import net.minecraft.server.network.ServerPlayerEntity; +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; + +/** + * The mixin for server player entities. + */ +@Mixin(ServerPlayerEntity.class) +public class DesyncFix { + /** + * Checks and corrects for desyncs. + */ + @Inject( + at = @At("HEAD"), + method = + "onStatusEffectUpgraded(Lnet/minecraft/entity/effect/StatusEffectInstance;ZLnet/minecraft/entity/Entity;)V" + ) + private void chewstuff_onDesync(CallbackInfo cbinfo) { + var self = (ServerPlayerEntity) (Object) this; + var maybeInfo = ChewComponents.CHEW.maybeGet(self); + maybeInfo.ifPresent(info -> { + info.sendUpdate = true; + }); + } +} diff --git a/src/main/java/ganarchy/chewstuff/mixin/PotionMix.java b/src/main/java/ganarchy/chewstuff/mixin/PotionMix.java new file mode 100644 index 0000000..5ed97ab --- /dev/null +++ b/src/main/java/ganarchy/chewstuff/mixin/PotionMix.java @@ -0,0 +1,67 @@ +package ganarchy.chewstuff.mixin; + +import ganarchy.chewstuff.ChewComponents; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.effect.StatusEffectInstance; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +/** + * The mixin for status effect instances. + */ +@Mixin(StatusEffectInstance.class) +public class PotionMix { + /** + * Checks the apply effect and cancels it when we're force-ticking it. + */ + @Inject( + at = @At("HEAD"), + method = "applyUpdateEffect(Lnet/minecraft/entity/LivingEntity;)V", + cancellable = true + ) + private void chewstuff_checkApplyEffect( + LivingEntity entity, CallbackInfo cbinfo + ) { + StatusEffectInstance self = (StatusEffectInstance) (Object) this; + var maybeInfo = ChewComponents.CHEW.maybeGet(entity); + maybeInfo.ifPresent(info -> { + var effect = self.getEffectType(); + if (info.effects.getOrDefault(effect, 0) <= 0) { + return; + } + if (info.applied.contains(effect)) { + info.applied.remove(effect); + cbinfo.cancel(); + } else { + info.applied.add(effect); + } + }); + } + + /** + * Checks for effect ticks. + */ + @Inject( + at = @At("HEAD"), + method = + "update(Lnet/minecraft/entity/LivingEntity;Ljava/lang/Runnable;)Z" + ) + private void chewstuff_checkUpdate( + LivingEntity entity, + Runnable runnable, + CallbackInfoReturnable<Boolean> cbinfo + ) { + StatusEffectInstance self = (StatusEffectInstance) (Object) this; + var maybeInfo = ChewComponents.CHEW.maybeGet(entity); + maybeInfo.ifPresent(info -> { + var effect = self.getEffectType(); + if (info.effects.getOrDefault(effect, 0) <= 0) { + return; + } + info.effects.computeIfPresent(effect, (k, v) -> v - 1); + }); + } +} diff --git a/src/main/java/net/fabricmc/example/ExampleMod.java b/src/main/java/net/fabricmc/example/ExampleMod.java deleted file mode 100644 index a964189..0000000 --- a/src/main/java/net/fabricmc/example/ExampleMod.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.fabricmc.example; - -import net.fabricmc.api.ModInitializer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ExampleMod implements ModInitializer { - // This logger is used to write text to the console and the log file. - // It is considered best practice to use your mod id as the logger's name. - // That way, it's clear which mod wrote info, warnings, and errors. - public static final Logger LOGGER = LoggerFactory.getLogger("modid"); - - @Override - public void onInitialize() { - // This code runs as soon as Minecraft is in a mod-load-ready state. - // However, some things (like resources) may still be uninitialized. - // Proceed with mild caution. - - LOGGER.info("Hello Fabric world!"); - } -} diff --git a/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java b/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java deleted file mode 100644 index 356cb38..0000000 --- a/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.fabricmc.example.mixin; - -import net.fabricmc.example.ExampleMod; -import net.minecraft.client.gui.screen.TitleScreen; -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; - -@Mixin(TitleScreen.class) -public class ExampleMixin { - @Inject(at = @At("HEAD"), method = "init()V") - private void init(CallbackInfo info) { - ExampleMod.LOGGER.info("This line is printed by an example mod mixin!"); - } -} diff --git a/src/main/resources/assets/chewstuff/icon.png b/src/main/resources/assets/chewstuff/icon.png new file mode 100644 index 0000000..b9d942a --- /dev/null +++ b/src/main/resources/assets/chewstuff/icon.png Binary files differdiff --git a/src/main/resources/assets/chewstuff/lang/en_us.json b/src/main/resources/assets/chewstuff/lang/en_us.json new file mode 100644 index 0000000..47af750 --- /dev/null +++ b/src/main/resources/assets/chewstuff/lang/en_us.json @@ -0,0 +1,6 @@ +{ + "item.chewstuff.silicone": "Silicone", + "item.chewstuff.soft_chew": "Soft Chew Necklace", + "item.chewstuff.medium_chew": "Medium Chew Necklace", + "item.chewstuff.hard_chew": "Hard Chew Necklace" +} \ No newline at end of file diff --git a/src/main/resources/assets/chewstuff/models/item/hard_chew.json b/src/main/resources/assets/chewstuff/models/item/hard_chew.json new file mode 100644 index 0000000..0191e60 --- /dev/null +++ b/src/main/resources/assets/chewstuff/models/item/hard_chew.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "chewstuff:item/hard_chew" + } +} diff --git a/src/main/resources/assets/chewstuff/models/item/medium_chew.json b/src/main/resources/assets/chewstuff/models/item/medium_chew.json new file mode 100644 index 0000000..596291a --- /dev/null +++ b/src/main/resources/assets/chewstuff/models/item/medium_chew.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "chewstuff:item/medium_chew" + } +} diff --git a/src/main/resources/assets/chewstuff/models/item/silicone.json b/src/main/resources/assets/chewstuff/models/item/silicone.json new file mode 100644 index 0000000..36fcd35 --- /dev/null +++ b/src/main/resources/assets/chewstuff/models/item/silicone.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "chewstuff:item/silicone" + } +} diff --git a/src/main/resources/assets/chewstuff/models/item/soft_chew.json b/src/main/resources/assets/chewstuff/models/item/soft_chew.json new file mode 100644 index 0000000..3923e9e --- /dev/null +++ b/src/main/resources/assets/chewstuff/models/item/soft_chew.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "chewstuff:item/soft_chew" + } +} diff --git a/src/main/resources/assets/chewstuff/textures/item/hard_chew.png b/src/main/resources/assets/chewstuff/textures/item/hard_chew.png new file mode 100644 index 0000000..be5712c --- /dev/null +++ b/src/main/resources/assets/chewstuff/textures/item/hard_chew.png Binary files differdiff --git a/src/main/resources/assets/chewstuff/textures/item/medium_chew.png b/src/main/resources/assets/chewstuff/textures/item/medium_chew.png new file mode 100644 index 0000000..871ad3c --- /dev/null +++ b/src/main/resources/assets/chewstuff/textures/item/medium_chew.png Binary files differdiff --git a/src/main/resources/assets/chewstuff/textures/item/silicone.png b/src/main/resources/assets/chewstuff/textures/item/silicone.png new file mode 100644 index 0000000..aad04bb --- /dev/null +++ b/src/main/resources/assets/chewstuff/textures/item/silicone.png Binary files differdiff --git a/src/main/resources/assets/chewstuff/textures/item/soft_chew.png b/src/main/resources/assets/chewstuff/textures/item/soft_chew.png new file mode 100644 index 0000000..2cc2f29 --- /dev/null +++ b/src/main/resources/assets/chewstuff/textures/item/soft_chew.png Binary files differdiff --git a/src/main/resources/assets/modid/icon.png b/src/main/resources/assets/modid/icon.png deleted file mode 100644 index 047b91f..0000000 --- a/src/main/resources/assets/modid/icon.png +++ /dev/null Binary files differdiff --git a/src/main/resources/modid.mixins.json b/src/main/resources/chewstuff.mixins.json index 7c42cb4..ef0b3fa 100644 --- a/src/main/resources/modid.mixins.json +++ b/src/main/resources/chewstuff.mixins.json @@ -1,12 +1,13 @@ { "required": true, "minVersion": "0.8", - "package": "net.fabricmc.example.mixin", + "package": "ganarchy.chewstuff.mixin", "compatibilityLevel": "JAVA_17", "mixins": [ + "PotionMix", + "DesyncFix" ], "client": [ - "ExampleMixin" ], "injectors": { "defaultRequire": 1 diff --git a/src/main/resources/data/chewstuff/recipes/hard_chew.json b/src/main/resources/data/chewstuff/recipes/hard_chew.json new file mode 100644 index 0000000..8cea939 --- /dev/null +++ b/src/main/resources/data/chewstuff/recipes/hard_chew.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shapeless", + "ingredients": [ + { + "item": "chewstuff:silicone" + }, + { + "item": "chewstuff:silicone" + }, + { + "item": "chewstuff:silicone" + }, + { + "item": "minecraft:string" + } + ], + "result": { + "item": "chewstuff:hard_chew" + } +} diff --git a/src/main/resources/data/chewstuff/recipes/medium_chew.json b/src/main/resources/data/chewstuff/recipes/medium_chew.json new file mode 100644 index 0000000..a4b9639 --- /dev/null +++ b/src/main/resources/data/chewstuff/recipes/medium_chew.json @@ -0,0 +1,17 @@ +{ + "type": "minecraft:crafting_shapeless", + "ingredients": [ + { + "item": "chewstuff:silicone" + }, + { + "item": "chewstuff:silicone" + }, + { + "item": "minecraft:string" + } + ], + "result": { + "item": "chewstuff:medium_chew" + } +} diff --git a/src/main/resources/data/chewstuff/recipes/silicone.json b/src/main/resources/data/chewstuff/recipes/silicone.json new file mode 100644 index 0000000..137e5fd --- /dev/null +++ b/src/main/resources/data/chewstuff/recipes/silicone.json @@ -0,0 +1,14 @@ +{ + "type": "minecraft:crafting_shapeless", + "ingredients": [ + { + "tag": "minecraft:coals" + }, + { + "tag": "minecraft:sand" + } + ], + "result": { + "item": "chewstuff:silicone" + } +} diff --git a/src/main/resources/data/chewstuff/recipes/soft_chew.json b/src/main/resources/data/chewstuff/recipes/soft_chew.json new file mode 100644 index 0000000..1e15630 --- /dev/null +++ b/src/main/resources/data/chewstuff/recipes/soft_chew.json @@ -0,0 +1,14 @@ +{ + "type": "minecraft:crafting_shapeless", + "ingredients": [ + { + "item": "chewstuff:silicone" + }, + { + "item": "minecraft:string" + } + ], + "result": { + "item": "chewstuff:soft_chew" + } +} diff --git a/src/main/resources/data/trinkets/entities/chewstuff.json b/src/main/resources/data/trinkets/entities/chewstuff.json new file mode 100644 index 0000000..fd5f0d3 --- /dev/null +++ b/src/main/resources/data/trinkets/entities/chewstuff.json @@ -0,0 +1,8 @@ +{ + "entities": [ + "player" + ], + "slots": [ + "chest/necklace" + ] +} diff --git a/src/main/resources/data/trinkets/tags/items/chest/necklace.json b/src/main/resources/data/trinkets/tags/items/chest/necklace.json new file mode 100644 index 0000000..4d31011 --- /dev/null +++ b/src/main/resources/data/trinkets/tags/items/chest/necklace.json @@ -0,0 +1,8 @@ +{ + "replace": false, + "values": [ + "chewstuff:soft_chew", + "chewstuff:medium_chew", + "chewstuff:hard_chew" + ] +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 730d843..9f07af9 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,38 +1,47 @@ { "schemaVersion": 1, - "id": "modid", + "id": "chewstuff", "version": "${version}", - "name": "Example Mod", - "description": "This is an example description! Tell everyone what your mod is about!", + "name": "Chew Necklaces", + "description": "There once was an Autism Acceptance Mod but it hasn't been updated in forever. This is more or less a complete rewrite, from scratch, of that.", "authors": [ - "Me!" + "SoniEx2" ], + "contributors": { + "torako" + }, "contact": { - "homepage": "https://fabricmc.net/", - "sources": "https://github.com/FabricMC/fabric-example-mod" + "sources": "https://soniex2.autistic.space/git-repos/chewstuff.git" }, - "license": "CC0-1.0", - "icon": "assets/modid/icon.png", + "license": "0BSD", + "icon": "assets/chewstuff/icon.png", "environment": "*", "entrypoints": { "main": [ - "net.fabricmc.example.ExampleMod" + "ganarchy.chewstuff.ChewStuff" + ], + "cardinal-components": [ + "ganarchy.chewstuff.ChewComponents" ] }, "mixins": [ - "modid.mixins.json" + "chewstuff.mixins.json" ], "depends": { + "trinkets": "~3.4", "fabricloader": ">=0.14.6", "fabric": "*", "minecraft": "~1.19", "java": ">=17" }, - "suggests": { - "another-mod": "*" + + "custom": { + "cardinal-components": [ + "chewstuff:chew" + ] } } |