From 56fb8eaf7a4f8c966a5e47f57fa5ffda07b43cc4 Mon Sep 17 00:00:00 2001 From: LelouBil Date: Mon, 14 Jul 2025 16:18:02 -0400 Subject: [PATCH] Gifting code --- build.gradle | 16 +- client/build.gradle | 5 + gradle.properties | 5 +- .../aprandomizer/gift_traits/ancient.json | 4 + .../aprandomizer/gift_traits/animal.json | 4 + .../gift_traits/animal_product.json | 13 + .../aprandomizer/gift_traits/aquamarine.json | 13 + .../aprandomizer/gift_traits/armor.json | 16 + .../gift_traits/armor_toughness.json | 4 + .../aprandomizer/gift_traits/artifact.json | 4 + .../gift_traits/attack_speed.json | 12 + .../aprandomizer/gift_traits/axe.json | 4 + .../aprandomizer/gift_traits/bamboo.json | 4 + .../aprandomizer/gift_traits/beach.json | 4 + .../aprandomizer/gift_traits/beef.json | 4 + .../aprandomizer/gift_traits/berry.json | 4 + .../aprandomizer/gift_traits/black.json | 4 + .../aprandomizer/gift_traits/blindness.json | 4 + .../aprandomizer/gift_traits/blue.json | 4 + .../aprandomizer/gift_traits/bomb.json | 8 + .../aprandomizer/gift_traits/bone.json | 13 + .../aprandomizer/gift_traits/book.json | 11 + .../aprandomizer/gift_traits/boulder.json | 4 + .../aprandomizer/gift_traits/bow.json | 8 + .../aprandomizer/gift_traits/broken.json | 4 + .../aprandomizer/gift_traits/brown.json | 4 + .../aprandomizer/gift_traits/buff.json | 12 + .../aprandomizer/gift_traits/bush.json | 4 + .../aprandomizer/gift_traits/ceramic.json | 13 + .../aprandomizer/gift_traits/chicken.json | 4 + .../aprandomizer/gift_traits/clay.json | 13 + .../aprandomizer/gift_traits/coal.json | 15 + .../aprandomizer/gift_traits/coffee.json | 4 + .../aprandomizer/gift_traits/consumable.json | 8 + .../aprandomizer/gift_traits/container.json | 13 + .../aprandomizer/gift_traits/cooking.json | 4 + .../aprandomizer/gift_traits/copper.json | 15 + .../aprandomizer/gift_traits/cow.json | 4 + .../aprandomizer/gift_traits/crafting.json | 4 + .../aprandomizer/gift_traits/crystal.json | 15 + .../aprandomizer/gift_traits/cure.json | 12 + .../aprandomizer/gift_traits/currency.json | 4 + .../aprandomizer/gift_traits/cyan.json | 4 + .../aprandomizer/gift_traits/damage.json | 12 + .../aprandomizer/gift_traits/defense.json | 4 + .../aprandomizer/gift_traits/desert.json | 4 + .../aprandomizer/gift_traits/diamond.json | 15 + .../aprandomizer/gift_traits/drink.json | 4 + .../aprandomizer/gift_traits/dry.json | 4 + .../aprandomizer/gift_traits/dye.json | 4 + .../aprandomizer/gift_traits/egg.json | 13 + .../aprandomizer/gift_traits/electronics.json | 13 + .../aprandomizer/gift_traits/energy.json | 13 + .../aprandomizer/gift_traits/explosive.json | 13 + .../aprandomizer/gift_traits/fertilizer.json | 12 + .../aprandomizer/gift_traits/fiber.json | 4 + .../aprandomizer/gift_traits/fire.json | 13 + .../aprandomizer/gift_traits/firework.json | 4 + .../aprandomizer/gift_traits/fish.json | 13 + .../aprandomizer/gift_traits/flight.json | 4 + .../aprandomizer/gift_traits/flower.json | 4 + .../aprandomizer/gift_traits/food.json | 4 + .../aprandomizer/gift_traits/fossil.json | 4 + .../aprandomizer/gift_traits/fruit.json | 13 + .../aprandomizer/gift_traits/fuel.json | 4 + .../aprandomizer/gift_traits/furnace.json | 4 + .../aprandomizer/gift_traits/gem.json | 15 + .../aprandomizer/gift_traits/goat.json | 4 + .../aprandomizer/gift_traits/gold.json | 15 + .../aprandomizer/gift_traits/goo.json | 7 + .../aprandomizer/gift_traits/grain.json | 4 + .../aprandomizer/gift_traits/grass.json | 4 + .../aprandomizer/gift_traits/gray.json | 4 + .../aprandomizer/gift_traits/green.json | 4 + .../aprandomizer/gift_traits/haste.json | 4 + .../aprandomizer/gift_traits/head.json | 4 + .../aprandomizer/gift_traits/heal.json | 12 + .../aprandomizer/gift_traits/hoe.json | 4 + .../aprandomizer/gift_traits/hunger.json | 4 + .../aprandomizer/gift_traits/ice.json | 13 + .../aprandomizer/gift_traits/insect.json | 4 + .../aprandomizer/gift_traits/instrument.json | 4 + .../aprandomizer/gift_traits/invincible.json | 4 + .../gift_traits/invisibility.json | 4 + .../aprandomizer/gift_traits/iq.json | 4 + .../aprandomizer/gift_traits/iron.json | 13 + .../aprandomizer/gift_traits/juice.json | 4 + .../aprandomizer/gift_traits/jump_boost.json | 4 + .../aprandomizer/gift_traits/key.json | 4 + .../aprandomizer/gift_traits/lava.json | 4 + .../aprandomizer/gift_traits/leather.json | 13 + .../aprandomizer/gift_traits/legendary.json | 4 + .../aprandomizer/gift_traits/life.json | 4 + .../aprandomizer/gift_traits/light.json | 13 + .../aprandomizer/gift_traits/light_blue.json | 4 + .../aprandomizer/gift_traits/light_gray.json | 4 + .../aprandomizer/gift_traits/lime.json | 4 + .../gift_traits/liquid_container.json | 13 + .../aprandomizer/gift_traits/luck.json | 4 + .../aprandomizer/gift_traits/lumber.json | 4 + .../aprandomizer/gift_traits/luxury.json | 4 + .../aprandomizer/gift_traits/machine.json | 4 + .../aprandomizer/gift_traits/magenta.json | 4 + .../aprandomizer/gift_traits/mana.json | 12 + .../aprandomizer/gift_traits/material.json | 4 + .../aprandomizer/gift_traits/meat.json | 13 + .../gift_traits/melee_weapon.json | 16 + .../aprandomizer/gift_traits/metal.json | 13 + .../aprandomizer/gift_traits/milk.json | 4 + .../aprandomizer/gift_traits/mineral.json | 13 + .../gift_traits/mining_fatigue.json | 4 + .../aprandomizer/gift_traits/monster.json | 4 + .../aprandomizer/gift_traits/mushroom.json | 13 + .../aprandomizer/gift_traits/nausea.json | 4 + .../gift_traits/night_vision.json | 4 + .../aprandomizer/gift_traits/ocean.json | 4 + .../aprandomizer/gift_traits/oil.json | 4 + .../aprandomizer/gift_traits/ominous.json | 12 + .../aprandomizer/gift_traits/orange.json | 4 + .../aprandomizer/gift_traits/ore.json | 8 + .../aprandomizer/gift_traits/paper.json | 13 + .../aprandomizer/gift_traits/pickaxe.json | 4 + .../aprandomizer/gift_traits/pink.json | 4 + .../aprandomizer/gift_traits/platinum.json | 15 + .../aprandomizer/gift_traits/poison.json | 4 + .../aprandomizer/gift_traits/potion.json | 4 + .../aprandomizer/gift_traits/powder.json | 7 + .../aprandomizer/gift_traits/prismarine.json | 13 + .../aprandomizer/gift_traits/purple.json | 4 + .../aprandomizer/gift_traits/random.json | 4 + .../gift_traits/ranged_weapon.json | 16 + .../aprandomizer/gift_traits/red.json | 4 + .../aprandomizer/gift_traits/resource.json | 8 + .../aprandomizer/gift_traits/rock.json | 13 + .../aprandomizer/gift_traits/rocket.json | 4 + .../aprandomizer/gift_traits/saddle.json | 13 + .../aprandomizer/gift_traits/salted.json | 4 + .../aprandomizer/gift_traits/sand.json | 13 + .../aprandomizer/gift_traits/scroll.json | 4 + .../aprandomizer/gift_traits/seed.json | 4 + .../aprandomizer/gift_traits/shovel.json | 4 + .../aprandomizer/gift_traits/silver.json | 15 + .../gift_traits/slow_falling.json | 4 + .../aprandomizer/gift_traits/slowness.json | 12 + .../aprandomizer/gift_traits/speed.json | 4 + .../aprandomizer/gift_traits/statue.json | 4 + .../aprandomizer/gift_traits/stone.json | 13 + .../aprandomizer/gift_traits/strength.json | 4 + .../aprandomizer/gift_traits/suspicious.json | 12 + .../aprandomizer/gift_traits/sword.json | 8 + .../aprandomizer/gift_traits/teleport.json | 4 + .../aprandomizer/gift_traits/throwing.json | 8 + .../aprandomizer/gift_traits/tool.json | 16 + .../aprandomizer/gift_traits/trap.json | 12 + .../aprandomizer/gift_traits/tree.json | 4 + .../aprandomizer/gift_traits/tree_seed.json | 4 + .../aprandomizer/gift_traits/trident.json | 4 + .../aprandomizer/gift_traits/unluck.json | 4 + .../aprandomizer/gift_traits/vegetable.json | 13 + .../aprandomizer/gift_traits/vine.json | 4 + .../aprandomizer/gift_traits/water.json | 4 + .../gift_traits/water_breathing.json | 4 + .../aprandomizer/gift_traits/weakness.json | 4 + .../aprandomizer/gift_traits/weapon.json | 16 + .../aprandomizer/gift_traits/white.json | 4 + .../aprandomizer/gift_traits/wither.json | 4 + .../aprandomizer/gift_traits/wood.json | 13 + .../aprandomizer/gift_traits/yellow.json | 4 + .../data_maps/fluid/gifts/traits.json | 14 + .../data_maps/item/gifts/traits/base.json | 611 ++++++++++++++ .../aprandomizer/gift_traits/containers.json | 7 + .../aprandomizer/gift_traits/effects.json | 17 + .../aprandomizer/gift_traits/equipment.json | 7 + .../aprandomizer/gift_traits/materials.json | 39 + .../tags/aprandomizer/gift_traits/ores.json | 13 + .../gift_traits/physical_states.json | 6 + .../tags/aprandomizer/gift_traits/usages.json | 10 + .../aprandomizer/gift_traits/weapons.json | 9 + .../aprandomizer/APRandomizer.java | 51 ++ .../aprandomizer/APRegistries.java | 2 + .../aprandomizer/ap/events/ConnectResult.java | 5 + .../common/commands/GiftCommand.java | 140 +++ .../aprandomizer/common/events/OnJoin.java | 1 + .../aprandomizer/common/events/OnLeave.java | 20 + .../aprandomizer/data/APDataGenerator.java | 7 +- .../data/datamaps/APDataMapProvider.java | 3 + .../aprandomizer/datamaps/APDataMaps.java | 30 + .../aprandomizer/gifting/BaseTraits.kt | 297 +++++++ .../gifting/CraftingTraitsHolder.kt | 156 ++++ .../aprandomizer/gifting/GiftHandler.kt | 166 ++++ .../aprandomizer/gifting/GiftTraits.kt | 658 +++++++++++++++ .../aprandomizer/gifting/MatchingUtils.kt | 165 ++++ .../gifting/MinecraftGiftMatcher.kt | 795 ++++++++++++++++++ .../aprandomizer/gifting/TraitsDataMap.kt | 447 ++++++++++ .../aprandomizer/utils/RegistriesUtils.kt | 25 + .../templates/META-INF/neoforge.mods.toml | 2 +- 196 files changed, 4931 insertions(+), 5 deletions(-) create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ancient.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/animal.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/animal_product.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/aquamarine.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/armor.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/armor_toughness.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/artifact.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/attack_speed.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/axe.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bamboo.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/beach.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/beef.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/berry.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/black.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/blindness.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/blue.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bomb.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bone.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/book.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/boulder.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bow.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/broken.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/brown.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/buff.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bush.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ceramic.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/chicken.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/clay.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/coal.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/coffee.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/consumable.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/container.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/cooking.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/copper.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/cow.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/crafting.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/crystal.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/cure.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/currency.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/cyan.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/damage.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/defense.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/desert.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/diamond.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/drink.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/dry.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/dye.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/egg.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/electronics.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/energy.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/explosive.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fertilizer.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fiber.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fire.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/firework.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fish.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/flight.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/flower.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/food.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fossil.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fruit.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fuel.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/furnace.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/gem.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/goat.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/gold.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/goo.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/grain.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/grass.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/gray.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/green.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/haste.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/head.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/heal.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/hoe.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/hunger.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ice.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/insect.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/instrument.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/invincible.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/invisibility.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/iq.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/iron.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/juice.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/jump_boost.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/key.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/lava.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/leather.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/legendary.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/life.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/light.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/light_blue.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/light_gray.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/lime.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/liquid_container.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/luck.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/lumber.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/luxury.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/machine.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/magenta.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/mana.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/material.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/meat.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/melee_weapon.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/metal.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/milk.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/mineral.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/mining_fatigue.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/monster.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/mushroom.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/nausea.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/night_vision.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ocean.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/oil.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ominous.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/orange.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ore.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/paper.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/pickaxe.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/pink.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/platinum.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/poison.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/potion.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/powder.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/prismarine.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/purple.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/random.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ranged_weapon.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/red.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/resource.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/rock.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/rocket.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/saddle.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/salted.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/sand.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/scroll.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/seed.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/shovel.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/silver.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/slow_falling.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/slowness.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/speed.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/statue.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/stone.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/strength.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/suspicious.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/sword.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/teleport.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/throwing.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/tool.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/trap.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/tree.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/tree_seed.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/trident.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/unluck.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/vegetable.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/vine.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/water.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/water_breathing.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/weakness.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/weapon.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/white.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/wither.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/wood.json create mode 100644 src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/yellow.json create mode 100644 src/generated/resources/data/aprandomizer/data_maps/fluid/gifts/traits.json create mode 100644 src/generated/resources/data/aprandomizer/data_maps/item/gifts/traits/base.json create mode 100644 src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/containers.json create mode 100644 src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/effects.json create mode 100644 src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/equipment.json create mode 100644 src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/materials.json create mode 100644 src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/ores.json create mode 100644 src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/physical_states.json create mode 100644 src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/usages.json create mode 100644 src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/weapons.json create mode 100644 src/main/java/gg/archipelago/aprandomizer/common/commands/GiftCommand.java create mode 100644 src/main/java/gg/archipelago/aprandomizer/common/events/OnLeave.java create mode 100644 src/main/kotlin/gg/archipelago/aprandomizer/gifting/BaseTraits.kt create mode 100644 src/main/kotlin/gg/archipelago/aprandomizer/gifting/CraftingTraitsHolder.kt create mode 100644 src/main/kotlin/gg/archipelago/aprandomizer/gifting/GiftHandler.kt create mode 100644 src/main/kotlin/gg/archipelago/aprandomizer/gifting/GiftTraits.kt create mode 100644 src/main/kotlin/gg/archipelago/aprandomizer/gifting/MatchingUtils.kt create mode 100644 src/main/kotlin/gg/archipelago/aprandomizer/gifting/MinecraftGiftMatcher.kt create mode 100644 src/main/kotlin/gg/archipelago/aprandomizer/gifting/TraitsDataMap.kt create mode 100644 src/main/kotlin/gg/archipelago/aprandomizer/utils/RegistriesUtils.kt diff --git a/build.gradle b/build.gradle index 13a8b97..60408de 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ plugins { id 'idea' id 'java-library' + id 'org.jetbrains.kotlin.jvm' version '2.2.0' id 'maven-publish' id 'net.neoforged.moddev' version '2.0.95' } @@ -13,6 +14,12 @@ tasks.named('wrapper', Wrapper).configure { distributionType = Wrapper.DistributionType.BIN } +kotlin { + compilerOptions{ + freeCompilerArgs.add("-Xcontext-parameters") + } +} + version = mod_version group = mod_group_id @@ -28,6 +35,11 @@ allprojects { } } mavenCentral() + maven { + name = 'Kotlin for Forge' + url = 'https://thedarkcolour.github.io/KotlinForForge/' + content { includeGroup "thedarkcolour" } + } } } @@ -142,6 +154,7 @@ dependencies { // http://www.gradle.org/docs/current/userguide/dependency_management.html // Archipelago Client Java Library jarJar project(path: ':client', configuration: 'shadow') + library 'thedarkcolour:kotlinforforge-neoforge:5.9.0' library project(path: ':client') } @@ -153,6 +166,7 @@ var generateModMetadata = tasks.register("generateModMetadata", ProcessResources minecraft_version_range: minecraft_version_range, neo_version : neo_version, neo_version_range : neo_version_range, + loader : loader, loader_version_range : loader_version_range, mod_id : mod_id, mod_name : mod_name, @@ -197,4 +211,4 @@ idea { downloadSources = true downloadJavadoc = true } -} \ No newline at end of file +} diff --git a/client/build.gradle b/client/build.gradle index 86b048f..abd6111 100644 --- a/client/build.gradle +++ b/client/build.gradle @@ -8,6 +8,11 @@ dependencies { exclude group: "com.google.code.gson" exclude group: "org.slf4j" } + api(group: "net.leloubil", name: "archipelago-gifting-jvm", version: "1.3.0") { + transitive = false + exclude group: "com.google.code.gson" + } + } tasks.shadowJar { diff --git a/gradle.properties b/gradle.properties index 8c81657..f5022ea 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,7 +22,8 @@ neo_version=21.5.77 # The Neo version range can use any version of Neo as bounds neo_version_range=[21.5.77,) # The loader version range can only use the major version of FML as bounds -loader_version_range=[4,) +loader=kotlinforforge +loader_version_range=[5.9,) ## Mod Properties @@ -42,4 +43,4 @@ mod_group_id=gg.archipelago.aprandomizer # The authors of the mod. This is a simple text string that is used for display purposes in the mod list. mod_authors=coehlrich, lexikiq, Red # The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list. -mod_description=A randomizer mod meant for the Archipelago multiworld randomizer\n\ncheck it out at http://archipelago.gg \ No newline at end of file +mod_description=A randomizer mod meant for the Archipelago multiworld randomizer\n\ncheck it out at http://archipelago.gg diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ancient.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ancient.json new file mode 100644 index 0000000..a0132d6 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ancient.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Ancient" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/animal.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/animal.json new file mode 100644 index 0000000..b029a66 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/animal.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Animal" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/animal_product.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/animal_product.json new file mode 100644 index 0000000..992b6a0 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/animal_product.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "AnimalProduct" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/aquamarine.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/aquamarine.json new file mode 100644 index 0000000..c2af34d --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/aquamarine.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Aquamarine" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/armor.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/armor.json new file mode 100644 index 0000000..87498a4 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/armor.json @@ -0,0 +1,16 @@ +{ + "craft_inheritance": {}, + "duration": { + "type": "item_durability", + "multiplier": 1.0 + }, + "matching": { + "distance_weight": 2.0, + "is_required": true + }, + "name": "Armor", + "quality": { + "type": "armor", + "multiplier": 1.0 + } +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/armor_toughness.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/armor_toughness.json new file mode 100644 index 0000000..4d06016 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/armor_toughness.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "ArmorToughness" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/artifact.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/artifact.json new file mode 100644 index 0000000..53fa1ad --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/artifact.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Artifact" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/attack_speed.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/attack_speed.json new file mode 100644 index 0000000..f13ab2b --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/attack_speed.json @@ -0,0 +1,12 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "duration_kept_multiplier": 0.0, + "quality_kept_multiplier": 0.2 + } + }, + "matching": { + "distance_weight": 1.6 + }, + "name": "AttackSpeed" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/axe.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/axe.json new file mode 100644 index 0000000..758d17a --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/axe.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Axe" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bamboo.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bamboo.json new file mode 100644 index 0000000..db94417 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bamboo.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Bamboo" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/beach.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/beach.json new file mode 100644 index 0000000..9412029 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/beach.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Beach" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/beef.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/beef.json new file mode 100644 index 0000000..78e7dab --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/beef.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Beef" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/berry.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/berry.json new file mode 100644 index 0000000..efb9a97 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/berry.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Berry" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/black.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/black.json new file mode 100644 index 0000000..05f4b68 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/black.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Black" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/blindness.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/blindness.json new file mode 100644 index 0000000..2ad729d --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/blindness.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Blindness" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/blue.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/blue.json new file mode 100644 index 0000000..d44006e --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/blue.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Blue" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bomb.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bomb.json new file mode 100644 index 0000000..05c1382 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bomb.json @@ -0,0 +1,8 @@ +{ + "craft_inheritance": {}, + "matching": { + "distance_weight": 1.8, + "is_required": true + }, + "name": "Bomb" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bone.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bone.json new file mode 100644 index 0000000..da10c4d --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bone.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Bone" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/book.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/book.json new file mode 100644 index 0000000..8609274 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/book.json @@ -0,0 +1,11 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + } + }, + "matching": { + "is_required": true + }, + "name": "Book" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/boulder.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/boulder.json new file mode 100644 index 0000000..33cc9c1 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/boulder.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Boulder" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bow.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bow.json new file mode 100644 index 0000000..89e4037 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bow.json @@ -0,0 +1,8 @@ +{ + "craft_inheritance": {}, + "matching": { + "distance_weight": 2.0, + "is_required": true + }, + "name": "Bow" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/broken.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/broken.json new file mode 100644 index 0000000..e671f9a --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/broken.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Broken" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/brown.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/brown.json new file mode 100644 index 0000000..ade159c --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/brown.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Brown" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/buff.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/buff.json new file mode 100644 index 0000000..53f5622 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/buff.json @@ -0,0 +1,12 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "duration_kept_multiplier": 0.0, + "quality_kept_multiplier": 0.2 + } + }, + "matching": { + "distance_weight": 1.6 + }, + "name": "Buff" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bush.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bush.json new file mode 100644 index 0000000..02bdbb6 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/bush.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Bush" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ceramic.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ceramic.json new file mode 100644 index 0000000..54ac5ef --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ceramic.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Ceramic" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/chicken.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/chicken.json new file mode 100644 index 0000000..e289573 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/chicken.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Chicken" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/clay.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/clay.json new file mode 100644 index 0000000..a1d6c4b --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/clay.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Clay" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/coal.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/coal.json new file mode 100644 index 0000000..2146e2b --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/coal.json @@ -0,0 +1,15 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": { + "quality_kept_multiplier": 1.2 + } + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Coal" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/coffee.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/coffee.json new file mode 100644 index 0000000..ede9667 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/coffee.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Coffee" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/consumable.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/consumable.json new file mode 100644 index 0000000..f75736e --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/consumable.json @@ -0,0 +1,8 @@ +{ + "craft_inheritance": {}, + "matching": { + "distance_weight": 1.8, + "is_required": true + }, + "name": "Consumable" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/container.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/container.json new file mode 100644 index 0000000..0813cc4 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/container.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "duration_kept_multiplier": 0.0, + "quality_kept_multiplier": 0.5 + } + }, + "matching": { + "distance_weight": 1.8, + "is_required": true + }, + "name": "Container" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/cooking.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/cooking.json new file mode 100644 index 0000000..421cdcf --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/cooking.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Cooking" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/copper.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/copper.json new file mode 100644 index 0000000..44472b5 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/copper.json @@ -0,0 +1,15 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": { + "quality_kept_multiplier": 1.2 + } + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Copper" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/cow.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/cow.json new file mode 100644 index 0000000..3a7519f --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/cow.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Cow" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/crafting.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/crafting.json new file mode 100644 index 0000000..316d5ea --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/crafting.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Crafting" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/crystal.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/crystal.json new file mode 100644 index 0000000..a4d9135 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/crystal.json @@ -0,0 +1,15 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": { + "quality_kept_multiplier": 1.2 + } + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Crystal" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/cure.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/cure.json new file mode 100644 index 0000000..279485e --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/cure.json @@ -0,0 +1,12 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "duration_kept_multiplier": 0.0, + "quality_kept_multiplier": 0.2 + } + }, + "matching": { + "distance_weight": 1.6 + }, + "name": "Cure" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/currency.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/currency.json new file mode 100644 index 0000000..860de8b --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/currency.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Currency" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/cyan.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/cyan.json new file mode 100644 index 0000000..5323f89 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/cyan.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Cyan" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/damage.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/damage.json new file mode 100644 index 0000000..dfe8085 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/damage.json @@ -0,0 +1,12 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "duration_kept_multiplier": 0.0, + "quality_kept_multiplier": 0.2 + } + }, + "matching": { + "distance_weight": 1.6 + }, + "name": "Damage" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/defense.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/defense.json new file mode 100644 index 0000000..3f189a8 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/defense.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Defense" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/desert.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/desert.json new file mode 100644 index 0000000..d164e3f --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/desert.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Desert" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/diamond.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/diamond.json new file mode 100644 index 0000000..5ec2582 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/diamond.json @@ -0,0 +1,15 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": { + "quality_kept_multiplier": 1.2 + } + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Diamond" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/drink.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/drink.json new file mode 100644 index 0000000..4808ab8 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/drink.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Drink" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/dry.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/dry.json new file mode 100644 index 0000000..0309b7d --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/dry.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Dry" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/dye.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/dye.json new file mode 100644 index 0000000..3675bcc --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/dye.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Dye" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/egg.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/egg.json new file mode 100644 index 0000000..cd359c5 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/egg.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Egg" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/electronics.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/electronics.json new file mode 100644 index 0000000..b25e205 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/electronics.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Electronics" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/energy.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/energy.json new file mode 100644 index 0000000..252669a --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/energy.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Energy" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/explosive.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/explosive.json new file mode 100644 index 0000000..8ce1f26 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/explosive.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Explosive" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fertilizer.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fertilizer.json new file mode 100644 index 0000000..d5af322 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fertilizer.json @@ -0,0 +1,12 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "duration_kept_multiplier": 0.0, + "quality_kept_multiplier": 0.2 + } + }, + "matching": { + "distance_weight": 1.6 + }, + "name": "Fertilizer" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fiber.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fiber.json new file mode 100644 index 0000000..6beda66 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fiber.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Fiber" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fire.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fire.json new file mode 100644 index 0000000..e879171 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fire.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.6, + "is_required": true + }, + "name": "Fire" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/firework.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/firework.json new file mode 100644 index 0000000..c105f2f --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/firework.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Firework" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fish.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fish.json new file mode 100644 index 0000000..6d68f7a --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fish.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Fish" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/flight.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/flight.json new file mode 100644 index 0000000..aff6899 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/flight.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Flight" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/flower.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/flower.json new file mode 100644 index 0000000..0efc56b --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/flower.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Flower" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/food.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/food.json new file mode 100644 index 0000000..8eaf5eb --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/food.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Food" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fossil.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fossil.json new file mode 100644 index 0000000..e7b7b88 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fossil.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Fossil" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fruit.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fruit.json new file mode 100644 index 0000000..33a3b5e --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fruit.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Fruit" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fuel.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fuel.json new file mode 100644 index 0000000..a215c9e --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/fuel.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Fuel" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/furnace.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/furnace.json new file mode 100644 index 0000000..c5e6ae1 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/furnace.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Furnace" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/gem.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/gem.json new file mode 100644 index 0000000..e67a2b2 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/gem.json @@ -0,0 +1,15 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": { + "quality_kept_multiplier": 1.2 + } + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Gem" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/goat.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/goat.json new file mode 100644 index 0000000..cc5f941 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/goat.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Goat" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/gold.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/gold.json new file mode 100644 index 0000000..3b67da4 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/gold.json @@ -0,0 +1,15 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": { + "quality_kept_multiplier": 1.2 + } + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Gold" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/goo.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/goo.json new file mode 100644 index 0000000..61957ae --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/goo.json @@ -0,0 +1,7 @@ +{ + "craft_inheritance": {}, + "matching": { + "distance_weight": 1.3 + }, + "name": "Goo" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/grain.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/grain.json new file mode 100644 index 0000000..a3ca864 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/grain.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Grain" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/grass.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/grass.json new file mode 100644 index 0000000..e8614c8 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/grass.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Grass" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/gray.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/gray.json new file mode 100644 index 0000000..99da84f --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/gray.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Gray" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/green.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/green.json new file mode 100644 index 0000000..7bc3371 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/green.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Green" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/haste.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/haste.json new file mode 100644 index 0000000..950dfad --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/haste.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Haste" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/head.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/head.json new file mode 100644 index 0000000..0052583 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/head.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Head" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/heal.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/heal.json new file mode 100644 index 0000000..2043dd1 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/heal.json @@ -0,0 +1,12 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "duration_kept_multiplier": 0.0, + "quality_kept_multiplier": 0.2 + } + }, + "matching": { + "distance_weight": 1.6 + }, + "name": "Heal" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/hoe.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/hoe.json new file mode 100644 index 0000000..ea53448 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/hoe.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Hoe" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/hunger.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/hunger.json new file mode 100644 index 0000000..99d8ddb --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/hunger.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Hunger" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ice.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ice.json new file mode 100644 index 0000000..c0c943e --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ice.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.6, + "is_required": true + }, + "name": "Ice" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/insect.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/insect.json new file mode 100644 index 0000000..b911771 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/insect.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Insect" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/instrument.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/instrument.json new file mode 100644 index 0000000..cdeddf9 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/instrument.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Instrument" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/invincible.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/invincible.json new file mode 100644 index 0000000..3a8b4f4 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/invincible.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Invincible" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/invisibility.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/invisibility.json new file mode 100644 index 0000000..2f22ca7 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/invisibility.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Invisibility" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/iq.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/iq.json new file mode 100644 index 0000000..66e9566 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/iq.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "IQ" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/iron.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/iron.json new file mode 100644 index 0000000..d4cd004 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/iron.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Iron" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/juice.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/juice.json new file mode 100644 index 0000000..5cb1e78 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/juice.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Juice" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/jump_boost.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/jump_boost.json new file mode 100644 index 0000000..474ea2f --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/jump_boost.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "JumpBoost" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/key.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/key.json new file mode 100644 index 0000000..be7bb34 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/key.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Key" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/lava.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/lava.json new file mode 100644 index 0000000..855c784 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/lava.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Lava" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/leather.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/leather.json new file mode 100644 index 0000000..269f3f2 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/leather.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Leather" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/legendary.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/legendary.json new file mode 100644 index 0000000..a0e4ae3 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/legendary.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Legendary" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/life.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/life.json new file mode 100644 index 0000000..66ece23 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/life.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Life" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/light.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/light.json new file mode 100644 index 0000000..4c76087 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/light.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Light" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/light_blue.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/light_blue.json new file mode 100644 index 0000000..74fb309 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/light_blue.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "LightBlue" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/light_gray.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/light_gray.json new file mode 100644 index 0000000..a7bfd28 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/light_gray.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "LightGray" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/lime.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/lime.json new file mode 100644 index 0000000..4db662f --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/lime.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Lime" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/liquid_container.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/liquid_container.json new file mode 100644 index 0000000..3cda803 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/liquid_container.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "duration_kept_multiplier": 0.0, + "quality_kept_multiplier": 0.5 + } + }, + "matching": { + "distance_weight": 1.8, + "is_required": true + }, + "name": "LiquidContainer" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/luck.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/luck.json new file mode 100644 index 0000000..70f39bb --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/luck.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Luck" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/lumber.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/lumber.json new file mode 100644 index 0000000..7b7e275 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/lumber.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Lumber" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/luxury.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/luxury.json new file mode 100644 index 0000000..fc88ab9 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/luxury.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Luxury" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/machine.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/machine.json new file mode 100644 index 0000000..b4ee060 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/machine.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Machine" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/magenta.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/magenta.json new file mode 100644 index 0000000..57d9633 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/magenta.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Magenta" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/mana.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/mana.json new file mode 100644 index 0000000..5623729 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/mana.json @@ -0,0 +1,12 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "duration_kept_multiplier": 0.0, + "quality_kept_multiplier": 0.2 + } + }, + "matching": { + "distance_weight": 1.6 + }, + "name": "Mana" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/material.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/material.json new file mode 100644 index 0000000..20db649 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/material.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Material" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/meat.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/meat.json new file mode 100644 index 0000000..2bc58a1 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/meat.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Meat" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/melee_weapon.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/melee_weapon.json new file mode 100644 index 0000000..e2a79ea --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/melee_weapon.json @@ -0,0 +1,16 @@ +{ + "craft_inheritance": {}, + "duration": { + "type": "item_durability", + "multiplier": 1.0 + }, + "matching": { + "distance_weight": 2.0, + "is_required": true + }, + "name": "MeleeWeapon", + "quality": { + "type": "damage", + "multiplier": 1.0 + } +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/metal.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/metal.json new file mode 100644 index 0000000..deafd9b --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/metal.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Metal" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/milk.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/milk.json new file mode 100644 index 0000000..cd91e1e --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/milk.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Milk" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/mineral.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/mineral.json new file mode 100644 index 0000000..323c36b --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/mineral.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Mineral" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/mining_fatigue.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/mining_fatigue.json new file mode 100644 index 0000000..5399e85 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/mining_fatigue.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "MiningFatigue" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/monster.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/monster.json new file mode 100644 index 0000000..9f77275 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/monster.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Monster" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/mushroom.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/mushroom.json new file mode 100644 index 0000000..21ee306 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/mushroom.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Mushroom" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/nausea.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/nausea.json new file mode 100644 index 0000000..07dc58d --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/nausea.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Nausea" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/night_vision.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/night_vision.json new file mode 100644 index 0000000..1da90b3 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/night_vision.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "NightVision" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ocean.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ocean.json new file mode 100644 index 0000000..1754f5d --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ocean.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Ocean" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/oil.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/oil.json new file mode 100644 index 0000000..d386152 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/oil.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Oil" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ominous.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ominous.json new file mode 100644 index 0000000..6e732d2 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ominous.json @@ -0,0 +1,12 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "duration_kept_multiplier": 0.0, + "quality_kept_multiplier": 0.2 + } + }, + "matching": { + "distance_weight": 1.6 + }, + "name": "Ominous" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/orange.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/orange.json new file mode 100644 index 0000000..40639fd --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/orange.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Orange" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ore.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ore.json new file mode 100644 index 0000000..dff964b --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ore.json @@ -0,0 +1,8 @@ +{ + "craft_inheritance": { + "minecraft:smelting": { + "quality_kept_multiplier": 1.2 + } + }, + "name": "Ore" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/paper.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/paper.json new file mode 100644 index 0000000..8cb302e --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/paper.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Paper" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/pickaxe.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/pickaxe.json new file mode 100644 index 0000000..abb47a9 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/pickaxe.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Pickaxe" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/pink.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/pink.json new file mode 100644 index 0000000..3d1c33c --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/pink.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Pink" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/platinum.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/platinum.json new file mode 100644 index 0000000..4ae5f23 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/platinum.json @@ -0,0 +1,15 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": { + "quality_kept_multiplier": 1.2 + } + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Platinum" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/poison.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/poison.json new file mode 100644 index 0000000..475366d --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/poison.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Poison" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/potion.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/potion.json new file mode 100644 index 0000000..1832471 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/potion.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Potion" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/powder.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/powder.json new file mode 100644 index 0000000..69e627f --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/powder.json @@ -0,0 +1,7 @@ +{ + "craft_inheritance": {}, + "matching": { + "distance_weight": 1.3 + }, + "name": "Powder" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/prismarine.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/prismarine.json new file mode 100644 index 0000000..02e7b9f --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/prismarine.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Prismarine" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/purple.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/purple.json new file mode 100644 index 0000000..614c814 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/purple.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Purple" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/random.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/random.json new file mode 100644 index 0000000..3cc53fe --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/random.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Random" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ranged_weapon.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ranged_weapon.json new file mode 100644 index 0000000..b16272c --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/ranged_weapon.json @@ -0,0 +1,16 @@ +{ + "craft_inheritance": {}, + "duration": { + "type": "item_durability", + "multiplier": 1.0 + }, + "matching": { + "distance_weight": 2.0, + "is_required": true + }, + "name": "RangedWeapon", + "quality": { + "type": "damage", + "multiplier": 1.0 + } +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/red.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/red.json new file mode 100644 index 0000000..7f23240 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/red.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Red" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/resource.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/resource.json new file mode 100644 index 0000000..2b87aa3 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/resource.json @@ -0,0 +1,8 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + } + }, + "name": "Resource" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/rock.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/rock.json new file mode 100644 index 0000000..e13a502 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/rock.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Rock" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/rocket.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/rocket.json new file mode 100644 index 0000000..56f4e9d --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/rocket.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Rocket" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/saddle.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/saddle.json new file mode 100644 index 0000000..9fbc734 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/saddle.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "duration_kept_multiplier": 0.0, + "quality_kept_multiplier": 0.5 + } + }, + "matching": { + "distance_weight": 1.8, + "is_required": true + }, + "name": "Saddle" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/salted.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/salted.json new file mode 100644 index 0000000..046e8e0 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/salted.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Salted" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/sand.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/sand.json new file mode 100644 index 0000000..b22fe93 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/sand.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Sand" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/scroll.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/scroll.json new file mode 100644 index 0000000..10ac6d4 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/scroll.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Scroll" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/seed.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/seed.json new file mode 100644 index 0000000..a7a7e03 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/seed.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Seed" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/shovel.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/shovel.json new file mode 100644 index 0000000..61515fa --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/shovel.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Shovel" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/silver.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/silver.json new file mode 100644 index 0000000..67fcfb0 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/silver.json @@ -0,0 +1,15 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": { + "quality_kept_multiplier": 1.2 + } + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Silver" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/slow_falling.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/slow_falling.json new file mode 100644 index 0000000..459ce43 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/slow_falling.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "SlowFalling" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/slowness.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/slowness.json new file mode 100644 index 0000000..a5d2c7d --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/slowness.json @@ -0,0 +1,12 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "duration_kept_multiplier": 0.0, + "quality_kept_multiplier": 0.2 + } + }, + "matching": { + "distance_weight": 1.6 + }, + "name": "Slowness" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/speed.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/speed.json new file mode 100644 index 0000000..eed9f00 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/speed.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Speed" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/statue.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/statue.json new file mode 100644 index 0000000..37f9214 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/statue.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Statue" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/stone.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/stone.json new file mode 100644 index 0000000..56a6939 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/stone.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Stone" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/strength.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/strength.json new file mode 100644 index 0000000..0c6b2b8 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/strength.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Strength" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/suspicious.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/suspicious.json new file mode 100644 index 0000000..e2f26fa --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/suspicious.json @@ -0,0 +1,12 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "duration_kept_multiplier": 0.0, + "quality_kept_multiplier": 0.2 + } + }, + "matching": { + "distance_weight": 1.6 + }, + "name": "Suspicious" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/sword.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/sword.json new file mode 100644 index 0000000..87ffaf0 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/sword.json @@ -0,0 +1,8 @@ +{ + "craft_inheritance": {}, + "matching": { + "distance_weight": 2.0, + "is_required": true + }, + "name": "Sword" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/teleport.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/teleport.json new file mode 100644 index 0000000..6854018 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/teleport.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Teleport" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/throwing.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/throwing.json new file mode 100644 index 0000000..024c170 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/throwing.json @@ -0,0 +1,8 @@ +{ + "craft_inheritance": {}, + "matching": { + "distance_weight": 1.8, + "is_required": true + }, + "name": "Throwing" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/tool.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/tool.json new file mode 100644 index 0000000..aa2f18a --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/tool.json @@ -0,0 +1,16 @@ +{ + "craft_inheritance": {}, + "duration": { + "type": "item_durability", + "multiplier": 1.0 + }, + "matching": { + "distance_weight": 2.0, + "is_required": true + }, + "name": "Tool", + "quality": { + "type": "tool_efficiency", + "multiplier": 1.0 + } +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/trap.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/trap.json new file mode 100644 index 0000000..c0a0a95 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/trap.json @@ -0,0 +1,12 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "duration_kept_multiplier": 0.0, + "quality_kept_multiplier": 0.2 + } + }, + "matching": { + "distance_weight": 1.6 + }, + "name": "Trap" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/tree.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/tree.json new file mode 100644 index 0000000..9e505aa --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/tree.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Tree" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/tree_seed.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/tree_seed.json new file mode 100644 index 0000000..63cd876 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/tree_seed.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "TreeSeed" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/trident.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/trident.json new file mode 100644 index 0000000..889c415 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/trident.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Trident" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/unluck.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/unluck.json new file mode 100644 index 0000000..969089a --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/unluck.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Unluck" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/vegetable.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/vegetable.json new file mode 100644 index 0000000..61c9e2c --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/vegetable.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Vegetable" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/vine.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/vine.json new file mode 100644 index 0000000..4a0e0a9 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/vine.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Vine" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/water.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/water.json new file mode 100644 index 0000000..a6e05b1 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/water.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Water" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/water_breathing.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/water_breathing.json new file mode 100644 index 0000000..f32615c --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/water_breathing.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "WaterBreathing" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/weakness.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/weakness.json new file mode 100644 index 0000000..6a248c2 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/weakness.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Weakness" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/weapon.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/weapon.json new file mode 100644 index 0000000..1daf155 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/weapon.json @@ -0,0 +1,16 @@ +{ + "craft_inheritance": {}, + "duration": { + "type": "item_durability", + "multiplier": 1.0 + }, + "matching": { + "distance_weight": 2.0, + "is_required": true + }, + "name": "Weapon", + "quality": { + "type": "damage", + "multiplier": 1.0 + } +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/white.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/white.json new file mode 100644 index 0000000..e8ea037 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/white.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "White" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/wither.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/wither.json new file mode 100644 index 0000000..3cca50f --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/wither.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Wither" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/wood.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/wood.json new file mode 100644 index 0000000..53c0a07 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/wood.json @@ -0,0 +1,13 @@ +{ + "craft_inheritance": { + "minecraft:crafting": { + "min_quality": 0.01 + }, + "minecraft:smelting": {} + }, + "matching": { + "distance_weight": 1.4, + "is_required": true + }, + "name": "Wood" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/yellow.json b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/yellow.json new file mode 100644 index 0000000..39cb94c --- /dev/null +++ b/src/generated/resources/data/aprandomizer/aprandomizer/gift_traits/yellow.json @@ -0,0 +1,4 @@ +{ + "craft_inheritance": {}, + "name": "Yellow" +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/data_maps/fluid/gifts/traits.json b/src/generated/resources/data/aprandomizer/data_maps/fluid/gifts/traits.json new file mode 100644 index 0000000..551c3e7 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/data_maps/fluid/gifts/traits.json @@ -0,0 +1,14 @@ +{ + "values": { + "#c:lava": { + "aprandomizer:fire": {}, + "aprandomizer:lava": {} + }, + "#c:milk": { + "aprandomizer:milk": {} + }, + "#c:water": { + "aprandomizer:water": {} + } + } +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/data_maps/item/gifts/traits/base.json b/src/generated/resources/data/aprandomizer/data_maps/item/gifts/traits/base.json new file mode 100644 index 0000000..6398bfb --- /dev/null +++ b/src/generated/resources/data/aprandomizer/data_maps/item/gifts/traits/base.json @@ -0,0 +1,611 @@ +{ + "values": { + "#c:armors": { + "aprandomizer:armor": {} + }, + "#c:barrels": { + "aprandomizer:container": {} + }, + "#c:bones": { + "aprandomizer:bone": {} + }, + "#c:bookshelves": { + "aprandomizer:book": {}, + "aprandomizer:paper": {} + }, + "#c:buckets/entity_water": { + "aprandomizer:animal": {}, + "aprandomizer:water": {} + }, + "#c:buds": { + "aprandomizer:crystal": {} + }, + "#c:chests": { + "aprandomizer:container": {} + }, + "#c:clusters": { + "aprandomizer:crystal": {} + }, + "#c:cobblestones": { + "aprandomizer:stone": { + "quality": 0.8 + } + }, + "#c:crops": { + "aprandomizer:grass": {} + }, + "#c:crops/cactus": { + "aprandomizer:desert": {} + }, + "#c:drinks": { + "aprandomizer:drink": {} + }, + "#c:drinks/juice": { + "aprandomizer:juice": {} + }, + "#c:drinks/milk": { + "aprandomizer:animal_product": {}, + "aprandomizer:milk": {} + }, + "#c:drinks/watery": { + "aprandomizer:water": {} + }, + "#c:dusts": { + "aprandomizer:powder": {} + }, + "#c:dyed/black": { + "aprandomizer:black": {} + }, + "#c:dyed/blue": { + "aprandomizer:blue": {} + }, + "#c:dyed/brown": { + "aprandomizer:brown": {} + }, + "#c:dyed/cyan": { + "aprandomizer:cyan": {} + }, + "#c:dyed/gray": { + "aprandomizer:gray": {} + }, + "#c:dyed/green": { + "aprandomizer:green": {} + }, + "#c:dyed/light_blue": { + "aprandomizer:light_blue": {} + }, + "#c:dyed/light_gray": { + "aprandomizer:light_gray": {} + }, + "#c:dyed/lime": { + "aprandomizer:lime": {} + }, + "#c:dyed/magenta": { + "aprandomizer:magenta": {} + }, + "#c:dyed/orange": { + "aprandomizer:orange": {} + }, + "#c:dyed/pink": { + "aprandomizer:pink": {} + }, + "#c:dyed/purple": { + "aprandomizer:purple": {} + }, + "#c:dyed/red": { + "aprandomizer:red": {} + }, + "#c:dyed/white": { + "aprandomizer:white": {} + }, + "#c:dyed/yellow": { + "aprandomizer:yellow": {} + }, + "#c:dyes": { + "aprandomizer:dye": {} + }, + "#c:dyes/black": { + "aprandomizer:black": {} + }, + "#c:dyes/blue": { + "aprandomizer:blue": {} + }, + "#c:dyes/brown": { + "aprandomizer:brown": {} + }, + "#c:dyes/cyan": { + "aprandomizer:cyan": {} + }, + "#c:dyes/gray": { + "aprandomizer:gray": {} + }, + "#c:dyes/green": { + "aprandomizer:green": {} + }, + "#c:dyes/light_blue": { + "aprandomizer:light_blue": {} + }, + "#c:dyes/light_gray": { + "aprandomizer:light_gray": {} + }, + "#c:dyes/lime": { + "aprandomizer:lime": {} + }, + "#c:dyes/magenta": { + "aprandomizer:magenta": {} + }, + "#c:dyes/orange": { + "aprandomizer:orange": {} + }, + "#c:dyes/pink": { + "aprandomizer:pink": {} + }, + "#c:dyes/purple": { + "aprandomizer:purple": {} + }, + "#c:dyes/red": { + "aprandomizer:red": {} + }, + "#c:dyes/white": { + "aprandomizer:white": {} + }, + "#c:dyes/yellow": { + "aprandomizer:yellow": {} + }, + "#c:eggs": { + "aprandomizer:egg": {} + }, + "#c:fertilizers": { + "aprandomizer:fertilizer": {} + }, + "#c:flowers": { + "aprandomizer:flower": {} + }, + "#c:foods": { + "aprandomizer:food": {} + }, + "#c:foods/berry": { + "aprandomizer:berry": {} + }, + "#c:foods/cooked_fish": { + "aprandomizer:fish": {} + }, + "#c:foods/cooked_meat": { + "aprandomizer:meat": {} + }, + "#c:foods/cookie": { + "aprandomizer:cooking": {} + }, + "#c:foods/fruit": { + "aprandomizer:fruit": {} + }, + "#c:foods/raw_fish": { + "aprandomizer:fish": {} + }, + "#c:foods/raw_meat": { + "aprandomizer:meat": {} + }, + "#c:foods/soup": { + "aprandomizer:cooking": {} + }, + "#c:foods/vegetable": { + "aprandomizer:vegetable": {} + }, + "#c:gems": { + "aprandomizer:gem": {} + }, + "#c:gems/amethyst": { + "aprandomizer:crystal": { + "quality": 0.8 + } + }, + "#c:gems/diamond": { + "aprandomizer:diamond": {} + }, + "#c:gems/emerald": { + "aprandomizer:currency": {} + }, + "#c:gems/quartz": { + "aprandomizer:crystal": { + "quality": 1.0 + } + }, + "#c:gunpowders": { + "aprandomizer:explosive": {}, + "aprandomizer:powder": {} + }, + "#c:ingots": { + "aprandomizer:metal": { + "quality": 1.0 + } + }, + "#c:ingots/copper": { + "aprandomizer:copper": { + "quality": 1.0 + } + }, + "#c:ingots/gold": { + "aprandomizer:gold": { + "quality": 1.0 + } + }, + "#c:ingots/iron": { + "aprandomizer:iron": { + "quality": 1.0 + } + }, + "#c:ingots/netherite": { + "aprandomizer:metal": { + "quality": 5.0 + } + }, + "#c:leathers": { + "aprandomizer:leather": {} + }, + "#c:mushrooms": { + "aprandomizer:mushroom": {} + }, + "#c:netherracks": { + "aprandomizer:fire": { + "quality": 0.2 + }, + "aprandomizer:stone": {} + }, + "#c:obsidians": { + "aprandomizer:gem": {}, + "aprandomizer:mineral": {} + }, + "#c:ores": { + "aprandomizer:ore": {} + }, + "#c:ores/coal": { + "aprandomizer:coal": { + "quality": 1.0 + } + }, + "#c:ores/copper": { + "aprandomizer:copper": {} + }, + "#c:ores/gold": { + "aprandomizer:gold": {} + }, + "#c:ores/netherite_scrap": { + "aprandomizer:metal": { + "quality": 4.0 + } + }, + "#c:player_workstations/crafting_tables": { + "aprandomizer:crafting": {}, + "aprandomizer:machine": {} + }, + "#c:player_workstations/furnaces": { + "aprandomizer:furnace": {}, + "aprandomizer:machine": {} + }, + "#c:potions": { + "aprandomizer:potion": {} + }, + "#c:raw_materials": { + "aprandomizer:material": {} + }, + "#c:rods/blaze": { + "aprandomizer:fire": {} + }, + "#c:sands": { + "aprandomizer:desert": {} + }, + "#c:seeds": { + "aprandomizer:seed": {} + }, + "#c:shulker_boxes": { + "aprandomizer:container": {} + }, + "#c:slime_balls": { + "aprandomizer:goo": {} + }, + "#c:stones": { + "aprandomizer:rock": {} + }, + "#c:storage_blocks/coal": { + "aprandomizer:coal": {} + }, + "#c:storage_blocks/slime": { + "aprandomizer:goo": {} + }, + "#c:stripped_logs": { + "aprandomizer:lumber": {}, + "aprandomizer:wood": { + "quality": 4.0 + } + }, + "#c:tools": { + "aprandomizer:tool": {} + }, + "#c:tools/melee_weapon": { + "aprandomizer:melee_weapon": {}, + "aprandomizer:weapon": {} + }, + "#c:tools/mining_tool": { + "aprandomizer:ore": { + "quality": 0.5 + }, + "aprandomizer:stone": { + "quality": 0.5 + } + }, + "#c:tools/ranged_weapon": { + "aprandomizer:ranged_weapon": {}, + "aprandomizer:weapon": {} + }, + "#minecraft:axes": { + "aprandomizer:axe": {}, + "aprandomizer:lumber": { + "quality": 0.5 + }, + "aprandomizer:wood": { + "quality": 0.5 + } + }, + "#minecraft:bookshelf_books": { + "aprandomizer:book": {}, + "aprandomizer:paper": {} + }, + "#minecraft:decorated_pot_sherds": { + "aprandomizer:ceramic": {} + }, + "#minecraft:dirt": { + "aprandomizer:grass": { + "quality": 0.5 + } + }, + "#minecraft:flowers": { + "aprandomizer:flower": {}, + "aprandomizer:grass": {} + }, + "#minecraft:hoes": { + "aprandomizer:grain": { + "quality": 0.5 + }, + "aprandomizer:grass": { + "quality": 0.5 + }, + "aprandomizer:hoe": {} + }, + "#minecraft:leaves": { + "aprandomizer:grass": { + "quality": 0.8 + }, + "aprandomizer:tree": { + "quality": 0.8 + } + }, + "#minecraft:logs": { + "aprandomizer:tree": {}, + "aprandomizer:wood": { + "quality": 4.0 + } + }, + "#minecraft:pickaxes": { + "aprandomizer:pickaxe": {} + }, + "#minecraft:planks": { + "aprandomizer:lumber": {}, + "aprandomizer:wood": { + "quality": 1.0 + } + }, + "#minecraft:saplings": { + "aprandomizer:tree_seed": {} + }, + "#minecraft:shovels": { + "aprandomizer:grass": { + "quality": 0.5 + }, + "aprandomizer:sand": { + "quality": 0.5 + }, + "aprandomizer:shovel": {} + }, + "minecraft:armor_stand": { + "aprandomizer:luxury": { + "quality": 0.1 + } + }, + "minecraft:bamboo": { + "aprandomizer:bamboo": {}, + "aprandomizer:grass": {} + }, + "minecraft:beef": { + "aprandomizer:beef": {}, + "aprandomizer:cow": {} + }, + "minecraft:blue_ice": { + "aprandomizer:ice": { + "quality": 0.5 + } + }, + "minecraft:bone": { + "aprandomizer:bone": {} + }, + "minecraft:bone_block": { + "aprandomizer:bone": {}, + "aprandomizer:fossil": {} + }, + "minecraft:bone_meal": { + "aprandomizer:bone": {} + }, + "minecraft:chicken": { + "aprandomizer:chicken": {} + }, + "minecraft:clay": { + "aprandomizer:beach": {}, + "aprandomizer:clay": {} + }, + "minecraft:comparator": { + "aprandomizer:electronics": { + "quality": 0.5 + } + }, + "minecraft:cooked_beef": { + "aprandomizer:beef": {}, + "aprandomizer:cow": {} + }, + "minecraft:cooked_chicken": { + "aprandomizer:chicken": {} + }, + "minecraft:dark_prismarine": { + "aprandomizer:aquamarine": {}, + "aprandomizer:ocean": {}, + "aprandomizer:prismarine": {}, + "aprandomizer:water": {} + }, + "minecraft:dead_bush": { + "aprandomizer:bush": {}, + "aprandomizer:dry": {} + }, + "minecraft:decorated_pot": { + "aprandomizer:ceramic": {} + }, + "minecraft:enchanted_book": { + "aprandomizer:buff": {}, + "aprandomizer:iq": {}, + "aprandomizer:scroll": {} + }, + "minecraft:ender_pearl": { + "aprandomizer:teleport": {}, + "aprandomizer:throwing": {} + }, + "minecraft:firework_rocket": { + "aprandomizer:firework": {}, + "aprandomizer:rocket": {} + }, + "minecraft:flower_pot": { + "aprandomizer:ceramic": {} + }, + "minecraft:glowstone": { + "aprandomizer:light": { + "quality": 0.5 + } + }, + "minecraft:glowstone_dust": { + "aprandomizer:light": { + "quality": 0.1 + } + }, + "minecraft:goat_horn": { + "aprandomizer:goat": {}, + "aprandomizer:instrument": {} + }, + "minecraft:heart_of_the_sea": { + "aprandomizer:ancient": {}, + "aprandomizer:artifact": {}, + "aprandomizer:ocean": {} + }, + "minecraft:ice": { + "aprandomizer:ice": {} + }, + "minecraft:item_frame": { + "aprandomizer:luxury": { + "quality": 0.5 + } + }, + "minecraft:jukebox": { + "aprandomizer:instrument": { + "quality": 0.5 + } + }, + "minecraft:lingering_potion": { + "aprandomizer:throwing": {} + }, + "minecraft:nautilus_shell": { + "aprandomizer:ancient": {}, + "aprandomizer:ocean": {} + }, + "minecraft:note_block": { + "aprandomizer:instrument": {} + }, + "minecraft:packed_ice": { + "aprandomizer:ice": {} + }, + "minecraft:painting": { + "aprandomizer:luxury": {} + }, + "minecraft:paper": { + "aprandomizer:paper": {} + }, + "minecraft:prismarine": { + "aprandomizer:aquamarine": {}, + "aprandomizer:ocean": {}, + "aprandomizer:prismarine": {}, + "aprandomizer:water": {} + }, + "minecraft:redstone": { + "aprandomizer:energy": { + "quality": 0.1 + } + }, + "minecraft:redstone_block": { + "aprandomizer:energy": { + "quality": 0.5 + } + }, + "minecraft:redstone_torch": { + "aprandomizer:light": {} + }, + "minecraft:repeater": { + "aprandomizer:electronics": { + "quality": 0.1 + } + }, + "minecraft:snow": { + "aprandomizer:ice": { + "quality": 0.05 + } + }, + "minecraft:snow_block": { + "aprandomizer:ice": { + "quality": 0.1 + } + }, + "minecraft:snowball": { + "aprandomizer:ice": {}, + "aprandomizer:throwing": {} + }, + "minecraft:soul_torch": { + "aprandomizer:light": {} + }, + "minecraft:splash_potion": { + "aprandomizer:throwing": {} + }, + "minecraft:tnt": { + "aprandomizer:bomb": {} + }, + "minecraft:torch": { + "aprandomizer:light": {} + }, + "minecraft:totem_of_undying": { + "aprandomizer:ancient": {}, + "aprandomizer:artifact": {} + }, + "minecraft:trident": { + "aprandomizer:ancient": {}, + "aprandomizer:ocean": {}, + "aprandomizer:trident": {} + }, + "minecraft:twisting_vines": { + "aprandomizer:grass": {}, + "aprandomizer:vine": {} + }, + "minecraft:vine": { + "aprandomizer:grass": {}, + "aprandomizer:vine": {} + }, + "minecraft:weeping_vines": { + "aprandomizer:grass": {}, + "aprandomizer:vine": {} + }, + "minecraft:wheat": { + "aprandomizer:grain": {} + } + } +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/containers.json b/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/containers.json new file mode 100644 index 0000000..4efe8d9 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/containers.json @@ -0,0 +1,7 @@ +{ + "values": [ + "aprandomizer:container", + "aprandomizer:liquid_container", + "aprandomizer:saddle" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/effects.json b/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/effects.json new file mode 100644 index 0000000..0df558e --- /dev/null +++ b/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/effects.json @@ -0,0 +1,17 @@ +{ + "values": [ + "aprandomizer:buff", + "aprandomizer:trap", + "aprandomizer:heal", + "aprandomizer:mana", + "aprandomizer:cure", + "aprandomizer:slowness", + "aprandomizer:damage", + "aprandomizer:fire", + "aprandomizer:ice", + "aprandomizer:attack_speed", + "aprandomizer:suspicious", + "aprandomizer:ominous", + "aprandomizer:fertilizer" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/equipment.json b/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/equipment.json new file mode 100644 index 0000000..e9aa70a --- /dev/null +++ b/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/equipment.json @@ -0,0 +1,7 @@ +{ + "values": [ + "aprandomizer:tool", + "aprandomizer:armor", + "#aprandomizer:weapons" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/materials.json b/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/materials.json new file mode 100644 index 0000000..de838a9 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/materials.json @@ -0,0 +1,39 @@ +{ + "values": [ + "aprandomizer:wood", + "aprandomizer:stone", + "aprandomizer:meat", + "aprandomizer:vegetable", + "aprandomizer:fruit", + "aprandomizer:egg", + "aprandomizer:metal", + "aprandomizer:mineral", + "aprandomizer:gem", + "aprandomizer:crystal", + "aprandomizer:rock", + "aprandomizer:paper", + "aprandomizer:fish", + "aprandomizer:mushroom", + "aprandomizer:copper", + "aprandomizer:coal", + "aprandomizer:gold", + "aprandomizer:silver", + "aprandomizer:platinum", + "aprandomizer:diamond", + "aprandomizer:prismarine", + "aprandomizer:aquamarine", + "aprandomizer:sand", + "aprandomizer:bone", + "aprandomizer:clay", + "aprandomizer:iron", + "aprandomizer:light", + "aprandomizer:ceramic", + "aprandomizer:fire", + "aprandomizer:ice", + "aprandomizer:energy", + "aprandomizer:electronics", + "aprandomizer:leather", + "aprandomizer:animal_product", + "aprandomizer:explosive" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/ores.json b/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/ores.json new file mode 100644 index 0000000..a69116b --- /dev/null +++ b/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/ores.json @@ -0,0 +1,13 @@ +{ + "values": [ + "aprandomizer:ore", + "aprandomizer:copper", + "aprandomizer:coal", + "aprandomizer:gold", + "aprandomizer:silver", + "aprandomizer:platinum", + "aprandomizer:diamond", + "aprandomizer:gem", + "aprandomizer:crystal" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/physical_states.json b/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/physical_states.json new file mode 100644 index 0000000..f933815 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/physical_states.json @@ -0,0 +1,6 @@ +{ + "values": [ + "aprandomizer:goo", + "aprandomizer:powder" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/usages.json b/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/usages.json new file mode 100644 index 0000000..9cdde32 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/usages.json @@ -0,0 +1,10 @@ +{ + "values": [ + "aprandomizer:bomb", + "aprandomizer:consumable", + "aprandomizer:saddle", + "aprandomizer:throwing", + "#aprandomizer:equipment", + "#aprandomizer:containers" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/weapons.json b/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/weapons.json new file mode 100644 index 0000000..f038472 --- /dev/null +++ b/src/generated/resources/data/aprandomizer/tags/aprandomizer/gift_traits/weapons.json @@ -0,0 +1,9 @@ +{ + "values": [ + "aprandomizer:weapon", + "aprandomizer:melee_weapon", + "aprandomizer:ranged_weapon", + "aprandomizer:sword", + "aprandomizer:bow" + ] +} \ No newline at end of file diff --git a/src/main/java/gg/archipelago/aprandomizer/APRandomizer.java b/src/main/java/gg/archipelago/aprandomizer/APRandomizer.java index 0a023cb..8867752 100644 --- a/src/main/java/gg/archipelago/aprandomizer/APRandomizer.java +++ b/src/main/java/gg/archipelago/aprandomizer/APRandomizer.java @@ -10,6 +10,9 @@ import gg.archipelago.aprandomizer.data.WorldData; import gg.archipelago.aprandomizer.data.loot.APLootModifierTypes; import gg.archipelago.aprandomizer.datamaps.APDataMaps; +import gg.archipelago.aprandomizer.gifting.GiftHandler; +import gg.archipelago.aprandomizer.gifting.GiftTraitDefinition; +import gg.archipelago.aprandomizer.gifting.MinecraftGiftMatcher; import gg.archipelago.aprandomizer.items.APItem; import gg.archipelago.aprandomizer.items.APRewardTypes; import gg.archipelago.aprandomizer.locations.APLocation; @@ -34,6 +37,7 @@ import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.Mod; import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.AddServerReloadListenersEvent; import net.neoforged.neoforge.event.server.ServerAboutToStartEvent; import net.neoforged.neoforge.event.server.ServerStartingEvent; import net.neoforged.neoforge.event.server.ServerStoppedEvent; @@ -81,6 +85,8 @@ public class APRandomizer { static private BlockPos jailCenter = BlockPos.ZERO; @Nullable static private WorldData worldData; + static private GiftHandler giftHandler; + static private final MinecraftGiftMatcher giftMatcher; static { Gson gson = new Gson(); @@ -111,6 +117,7 @@ public class APRandomizer { } } apmcData = data; + giftMatcher = new MinecraftGiftMatcher(apmcData.world_seed); } public APRandomizer(IEventBus modEventBus) { @@ -119,6 +126,7 @@ public APRandomizer(IEventBus modEventBus) { // Register ourselves for server and other game events we are interested in IEventBus forgeBus = NeoForge.EVENT_BUS; forgeBus.register(this); + forgeBus.addListener(APRandomizer::addReloadListeners); // For registration and init stuff. APStructures.DEFERRED_REGISTRY_STRUCTURE.register(modEventBus); @@ -136,11 +144,20 @@ public APRandomizer(IEventBus modEventBus) { public static void registerDataPackRegistries(DataPackRegistryEvent.NewRegistry event) { event.dataPackRegistry(APRegistries.ARCHIPELAGO_ITEM, APItem.CODEC); event.dataPackRegistry(APRegistries.ARCHIPELAGO_LOCATION, APLocation.CODEC); + event.dataPackRegistry(APRegistries.GIFT_TRAITS, GiftTraitDefinition.CODEC); } public static void registerDataMapTypes(RegisterDataMapTypesEvent event) { event.register(APDataMaps.DEFAULT_STRUCTURE_BIOMES); + event.register(APDataMaps.ITEMS_GIFTS_BASE_TRAITS); + event.register(APDataMaps.ITEMS_GIFTS_FINAL_TRAITS); + event.register(APDataMaps.FLUIDS_GIFTS_TRAITS); } + + public static void addReloadListeners(AddServerReloadListenersEvent event) { + giftMatcher.registerReloadListeners(event); + } + @Nullable public static APClient getAP() { return APClient; @@ -207,12 +224,42 @@ public static WorldData getWorldData() { return worldData; } + public static GiftHandler getGiftHandler() { + return giftHandler; + } + + public static void tryEnableGifting() { + if (APClient == null || !APClient.isConnected() || giftHandler != null) { + return; + } + giftHandler = new GiftHandler(APClient,giftMatcher); + } + + public static void tryEnableGiftReception() { + if (giftHandler == null) return; + assert server != null; + boolean anyPlayerConnected = !server.getPlayerList().getPlayers().isEmpty(); + if (anyPlayerConnected) { + LOGGER.info("Enabling gift reception"); + giftHandler.startReception(server.registryAccess(),server.getRecipeManager()); + giftHandler.openGiftBox(); + } else { + giftHandler.closeGiftBox(); + } + } + @SubscribeEvent public void onServerAboutToStart(ServerAboutToStartEvent event) { if (apmcData.state != APMCData.State.VALID) { LOGGER.error("invalid APMC file"); } server = event.getServer(); + //todo try to move in reload listener, but tags are not available there yet. + giftMatcher.registerAllMinecraftGifts( + server.getWorldData().enabledFeatures(), + server.registryAccess(), + server.getRecipeManager() + ); } @SubscribeEvent @@ -309,12 +356,16 @@ public void onServerStarting(ServerStartingEvent event) { @SubscribeEvent public void onServerStopping(ServerStoppingEvent event) { + if (giftHandler != null) + giftHandler.closeGiftBox(); if (APClient != null) APClient.close(); } @SubscribeEvent public void onServerStopped(ServerStoppedEvent event) { + if (giftHandler != null) + giftHandler.closeGiftBox(); if (APClient != null) APClient.close(); } diff --git a/src/main/java/gg/archipelago/aprandomizer/APRegistries.java b/src/main/java/gg/archipelago/aprandomizer/APRegistries.java index 5b059ae..dd28e25 100644 --- a/src/main/java/gg/archipelago/aprandomizer/APRegistries.java +++ b/src/main/java/gg/archipelago/aprandomizer/APRegistries.java @@ -1,6 +1,7 @@ package gg.archipelago.aprandomizer; import com.mojang.serialization.MapCodec; +import gg.archipelago.aprandomizer.gifting.GiftTraitDefinition; import gg.archipelago.aprandomizer.items.APItem; import gg.archipelago.aprandomizer.items.APReward; import gg.archipelago.aprandomizer.locations.APLocation; @@ -15,4 +16,5 @@ public class APRegistries { public static final ResourceKey>> ARCHIPELAGO_REWARD_TYPE = ResourceKey.createRegistryKey(ResourceLocation.fromNamespaceAndPath(APRandomizer.MODID, "archipelago_item_type")); public static final ResourceKey>> ARCHIPELAGO_LOCATION_TYPE = ResourceKey.createRegistryKey(ResourceLocation.fromNamespaceAndPath(APRandomizer.MODID, "archipelago_location_type")); public static final ResourceKey>> STRUCTURE_LEVEL_REFERENCE = ResourceKey.createRegistryKey(ResourceLocation.fromNamespaceAndPath(APRandomizer.MODID, "structure_level_reference")); + public static final ResourceKey> GIFT_TRAITS = ResourceKey.createRegistryKey(ResourceLocation.fromNamespaceAndPath(APRandomizer.MODID, "gift_traits")); } diff --git a/src/main/java/gg/archipelago/aprandomizer/ap/events/ConnectResult.java b/src/main/java/gg/archipelago/aprandomizer/ap/events/ConnectResult.java index ffb0591..f9724fb 100644 --- a/src/main/java/gg/archipelago/aprandomizer/ap/events/ConnectResult.java +++ b/src/main/java/gg/archipelago/aprandomizer/ap/events/ConnectResult.java @@ -3,6 +3,7 @@ import dev.koifysh.archipelago.events.ArchipelagoEventListener; import dev.koifysh.archipelago.events.ConnectionResultEvent; import dev.koifysh.archipelago.network.ConnectionResult; +import gg.archipelago.aprandomizer.APRandomizer; import gg.archipelago.aprandomizer.SlotData; import gg.archipelago.aprandomizer.ap.APClient; import gg.archipelago.aprandomizer.common.Utils.Utils; @@ -54,6 +55,10 @@ public void onConnectResult(ConnectionResultEvent event) { APClient.setDeathLinkEnabled(true); } + + APRandomizer.tryEnableGifting(); + APRandomizer.tryEnableGiftReception(); + advancementManager.setCheckedAdvancements(new LongOpenHashSet(APClient.getLocationManager().getCheckedLocations())); // ensure server is synced diff --git a/src/main/java/gg/archipelago/aprandomizer/common/commands/GiftCommand.java b/src/main/java/gg/archipelago/aprandomizer/common/commands/GiftCommand.java new file mode 100644 index 0000000..4b1cd43 --- /dev/null +++ b/src/main/java/gg/archipelago/aprandomizer/common/commands/GiftCommand.java @@ -0,0 +1,140 @@ +package gg.archipelago.aprandomizer.common.commands; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.suggestion.SuggestionProvider; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import dev.koifysh.archipelago.network.server.RoomInfoPacket; +import dev.koifysh.archipelago.parts.NetworkPlayer; +import gg.archipelago.aprandomizer.APRandomizer; +import gg.archipelago.aprandomizer.gifting.GiftHandler; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.RecipeManager; +import net.minecraft.world.level.Level; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.RegisterCommandsEvent; + +import java.util.Optional; +import java.util.concurrent.CompletableFuture; + +@EventBusSubscriber +public final class GiftCommand { + + private GiftCommand() { + } + + // Register the command + public static void Register(CommandDispatcher dispatcher) { + dispatcher.register( + Commands.literal("gift") + .then( + Commands.argument("recipient", StringArgumentType.string()) + .suggests(new APPlayersSuggestionProvider()) + .executes(GiftCommand::gift) + ) + ); + } + + public static int gift(CommandContext context) throws CommandSyntaxException { + if (!APRandomizer.isConnected()) { + context.getSource().sendFailure(Component.literal("Please connect to the Archipelago server before gifting.")); + return 1; + } + if (APRandomizer.isJailPlayers()) { + context.getSource().sendFailure(Component.literal("You cannot gift items before the game starts.")); + return 1; + } + + var server = APRandomizer.getServer(); + if (server == null) return 0; + var overworld = server.getLevel(Level.OVERWORLD); + if (overworld == null) return 0; + var apClient = APRandomizer.getAP(); + if (apClient == null) { + context.getSource().sendFailure(Component.literal("Archipelago client is not initialized.")); + return 0; + } + var player = context.getSource().getPlayerOrException(); + var heldItem = player.getMainHandItem(); + if (heldItem.isEmpty()) { + context.getSource().sendFailure(Component.literal("You must hold an item in your hand to gift it.")); + return 0; + } + + String recipientName = StringArgumentType.getString(context, "recipient"); + Optional recipientOpt = apClient.getRoomInfo().networkPlayers.stream() + .filter(p -> p != null && p.name.equals(recipientName)) + .findFirst(); + if (recipientOpt.isEmpty()) { + context.getSource().sendFailure(Component.literal("No player found with the name: " + recipientName)); + return 0; + } + NetworkPlayer recipient = recipientOpt.get(); + + GiftHandler giftHandler = APRandomizer.getGiftHandler(); + if (giftHandler == null) { + context.getSource().sendFailure(Component.literal("Gifting is not enabled")); + return 0; + } + + RecipeManager recipeManager = context.getSource().getServer().getRecipeManager(); + context.getSource().sendSystemMessage( + Component.literal("Item traits : " + giftHandler.getGiftItem( + context.getSource() + .registryAccess(),heldItem, + recipeManager)) + ); + giftHandler.giftItem(context.getSource().registryAccess(),heldItem,recipient, recipeManager).whenComplete((giftingError, v) -> { + if (giftingError != null) { + context.getSource().sendFailure(Component.literal("Error while gifting item: " + giftingError)); + } else { + player.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY); + } + }); + + return 1; + } + + @SubscribeEvent + public static void onRegisterCommandsEvent(RegisterCommandsEvent event) { + Register(event.getDispatcher()); + } + + public static class APPlayersSuggestionProvider implements SuggestionProvider { + @Override + public CompletableFuture getSuggestions( + CommandContext context, + SuggestionsBuilder builder) throws CommandSyntaxException { + String recipientName = ""; + try { + recipientName = context.getArgument("recipient", String.class); + } catch (IllegalArgumentException ignored) { + } + + if (APRandomizer.getAP() == null) { + return Suggestions.empty(); + } + String finalRecipientName = recipientName; + RoomInfoPacket roomInfo = APRandomizer.getAP().getRoomInfo(); + if (roomInfo == null || roomInfo.networkPlayers == null) { + return Suggestions.empty(); + } + roomInfo.networkPlayers.stream() + .filter(player -> player.slot != 0) + .forEach(player -> { + if (finalRecipientName.isBlank() || player.name.startsWith(finalRecipientName)) { + builder.suggest(player.name); + } + }); + return builder.buildFuture(); + } + } +} diff --git a/src/main/java/gg/archipelago/aprandomizer/common/events/OnJoin.java b/src/main/java/gg/archipelago/aprandomizer/common/events/OnJoin.java index 9de88ca..f675789 100644 --- a/src/main/java/gg/archipelago/aprandomizer/common/events/OnJoin.java +++ b/src/main/java/gg/archipelago/aprandomizer/common/events/OnJoin.java @@ -53,6 +53,7 @@ else if (data.state == APMCData.State.INVALID_SEED) { advancementManager.syncAllAdvancements(); goalManager.updateInfoBar(); itemManager.catchUpPlayer(player); + APRandomizer.tryEnableGiftReception(); if (APRandomizer.isJailPlayers()) { BlockPos jail = APRandomizer.getJailPosition(); diff --git a/src/main/java/gg/archipelago/aprandomizer/common/events/OnLeave.java b/src/main/java/gg/archipelago/aprandomizer/common/events/OnLeave.java new file mode 100644 index 0000000..425f390 --- /dev/null +++ b/src/main/java/gg/archipelago/aprandomizer/common/events/OnLeave.java @@ -0,0 +1,20 @@ +package gg.archipelago.aprandomizer.common.events; + +import gg.archipelago.aprandomizer.APRandomizer; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.entity.player.PlayerEvent; + +@EventBusSubscriber +public class OnLeave { + + @SubscribeEvent + static void onPlayerLeave(PlayerEvent.PlayerLoggedOutEvent event) { + if (APRandomizer.getServer() != null) + if (APRandomizer.getServer() + .getPlayerList().getPlayers() + .stream().allMatch(e -> e.equals(event.getEntity()))) { + APRandomizer.getGiftHandler().stopReception(); + } + } +} diff --git a/src/main/java/gg/archipelago/aprandomizer/data/APDataGenerator.java b/src/main/java/gg/archipelago/aprandomizer/data/APDataGenerator.java index 1854ff2..8d6589f 100644 --- a/src/main/java/gg/archipelago/aprandomizer/data/APDataGenerator.java +++ b/src/main/java/gg/archipelago/aprandomizer/data/APDataGenerator.java @@ -15,6 +15,8 @@ import gg.archipelago.aprandomizer.data.tags.APDamageTypeTagsProvider; import gg.archipelago.aprandomizer.data.tags.APStructureTagsProvider; import gg.archipelago.aprandomizer.dimensions.APDimensionTypes; +import gg.archipelago.aprandomizer.gifting.DefaultTags; +import gg.archipelago.aprandomizer.gifting.GiftTraitDefinition; import gg.archipelago.aprandomizer.items.APItems; import gg.archipelago.aprandomizer.locations.APLocations; import gg.archipelago.aprandomizer.modifiers.APStructureModifiers; @@ -28,6 +30,7 @@ import net.minecraft.data.loot.LootTableProvider; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +import net.neoforged.bus.api.EventPriority; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber.Bus; @@ -42,7 +45,7 @@ @EventBusSubscriber(bus = Bus.MOD, modid = APRandomizer.MODID) public class APDataGenerator { - @SubscribeEvent + @SubscribeEvent(priority = EventPriority.LOW) public static void onDataGen(GatherDataEvent.Client event) { CompletableFuture registries = event.addProvider(new DatapackBuiltinEntriesProvider(event.getGenerator().getPackOutput(), event.getLookupProvider(), new RegistrySetBuilder() @@ -52,6 +55,7 @@ public static void onDataGen(GatherDataEvent.Client event) { .add(Registries.STRUCTURE_SET, APStructureSets::bootstrap) .add(APRegistries.ARCHIPELAGO_LOCATION, APLocations::bootstrap) .add(APRegistries.ARCHIPELAGO_ITEM, APItems::bootstrap) + .add(APRegistries.GIFT_TRAITS, GiftTraitDefinition::bootstrap) .add(Registries.DIMENSION_TYPE, APDimensionTypes::bootstrap), Set.of(APRandomizer.MODID, "minecraft"))).getRegistryProvider(); event.addProvider(new AdvancementProvider(event.getGenerator().getPackOutput(), registries, List.of( @@ -66,6 +70,7 @@ public static void onDataGen(GatherDataEvent.Client event) { id -> ResourceLocation.fromNamespaceAndPath(APRandomizer.MODID, "vanilla/" + id.getPath() + "_after")), new VanillaOverrideAdvancementProvider()))); event.addProvider(new APDamageTypeTagsProvider(event.getGenerator().getPackOutput(), registries)); + event.addProvider(new DefaultTags.GiftTagsProvider(event.getGenerator().getPackOutput(), registries)); event.addProvider(new APRecipeProvider.Runner(event.getGenerator().getPackOutput(), registries)); event.addProvider(new APDataMapProvider(event.getGenerator().getPackOutput(), registries)); event.addProvider(new APBiomeTagsProvider(event.getGenerator().getPackOutput(), registries)); diff --git a/src/main/java/gg/archipelago/aprandomizer/data/datamaps/APDataMapProvider.java b/src/main/java/gg/archipelago/aprandomizer/data/datamaps/APDataMapProvider.java index 6452d76..a927b81 100644 --- a/src/main/java/gg/archipelago/aprandomizer/data/datamaps/APDataMapProvider.java +++ b/src/main/java/gg/archipelago/aprandomizer/data/datamaps/APDataMapProvider.java @@ -1,6 +1,7 @@ package gg.archipelago.aprandomizer.data.datamaps; import gg.archipelago.aprandomizer.datamaps.APDataMaps; +import gg.archipelago.aprandomizer.gifting.BaseTraitsKt; import gg.archipelago.aprandomizer.tags.APBiomeTags; import net.minecraft.core.HolderGetter; import net.minecraft.core.HolderLookup.Provider; @@ -25,6 +26,8 @@ protected void gather(Provider provider) { .add(Level.OVERWORLD, biomes.getOrThrow(APBiomeTags.OVERWORLD_STRUCTURE), false) .add(Level.NETHER, biomes.getOrThrow(APBiomeTags.NETHER_STRUCTURE), false) .add(Level.END, biomes.getOrThrow(APBiomeTags.END_STRUCTURE), false); + BaseTraitsKt.baseItemTraits(builder(APDataMaps.ITEMS_GIFTS_BASE_TRAITS),provider); + BaseTraitsKt.baseFluidTraits(builder(APDataMaps.FLUIDS_GIFTS_TRAITS),provider); } } diff --git a/src/main/java/gg/archipelago/aprandomizer/datamaps/APDataMaps.java b/src/main/java/gg/archipelago/aprandomizer/datamaps/APDataMaps.java index 8609312..1bef29e 100644 --- a/src/main/java/gg/archipelago/aprandomizer/datamaps/APDataMaps.java +++ b/src/main/java/gg/archipelago/aprandomizer/datamaps/APDataMaps.java @@ -1,16 +1,46 @@ package gg.archipelago.aprandomizer.datamaps; import gg.archipelago.aprandomizer.APRandomizer; +import gg.archipelago.aprandomizer.gifting.*; import net.minecraft.core.HolderSet; import net.minecraft.core.RegistryCodecs; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; import net.minecraft.world.level.Level; import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.material.Fluid; +import net.neoforged.neoforge.registries.datamaps.AdvancedDataMapType; import net.neoforged.neoforge.registries.datamaps.DataMapType; public class APDataMaps { public static final DataMapType> DEFAULT_STRUCTURE_BIOMES = DataMapType.builder( ResourceLocation.fromNamespaceAndPath(APRandomizer.MODID, "default_structure_biomes"), Registries.DIMENSION, RegistryCodecs.homogeneousList(Registries.BIOME)) .build(); + + public static final DataMapType ITEMS_GIFTS_BASE_TRAITS = AdvancedDataMapType.builder( + ResourceLocation.fromNamespaceAndPath(APRandomizer.MODID, "gifts/traits/base"), + Registries.ITEM, + TraitData.CODEC + ) + .merger(new DataGiftTraitsMerger<>()) + .remover(DataGiftTraitsRemover.codec()) + .build(); + + public static final DataMapType ITEMS_GIFTS_FINAL_TRAITS = AdvancedDataMapType.builder( + ResourceLocation.fromNamespaceAndPath(APRandomizer.MODID, "gifts/traits/final"), + Registries.ITEM, + FinalTraitData.CODEC + ) + .merger(new FinalDataGiftTraitsMerger<>()) + .remover(FinalDataGiftTraitsRemover.codec()) + .build(); + public static final DataMapType FLUIDS_GIFTS_TRAITS = AdvancedDataMapType.builder( + ResourceLocation.fromNamespaceAndPath(APRandomizer.MODID, "gifts/traits"), + Registries.FLUID, + TraitData.CODEC + ) + .merger(new DataGiftTraitsMerger<>()) + .remover(DataGiftTraitsRemover.codec()) + .build(); } diff --git a/src/main/kotlin/gg/archipelago/aprandomizer/gifting/BaseTraits.kt b/src/main/kotlin/gg/archipelago/aprandomizer/gifting/BaseTraits.kt new file mode 100644 index 0000000..442089d --- /dev/null +++ b/src/main/kotlin/gg/archipelago/aprandomizer/gifting/BaseTraits.kt @@ -0,0 +1,297 @@ +package gg.archipelago.aprandomizer.gifting + +import gg.archipelago.aprandomizer.APRegistries +import gg.archipelago.aprandomizer.utils.asHolder +import gg.archipelago.aprandomizer.utils.holder +import gg.archipelago.aprandomizer.utils.holderSet +import net.minecraft.core.Holder +import net.minecraft.core.HolderLookup +import net.minecraft.core.Registry +import net.minecraft.core.registries.BuiltInRegistries +import net.minecraft.resources.ResourceKey +import net.minecraft.tags.ItemTags +import net.minecraft.tags.TagKey +import net.minecraft.world.item.Item +import net.minecraft.world.item.Items +import net.minecraft.world.level.block.Block +import net.minecraft.world.level.material.Fluid +import net.neoforged.neoforge.common.Tags +import net.neoforged.neoforge.common.data.DataMapProvider + +context(builder: DataMapProvider.Builder, _: Registry, _: HolderLookup.RegistryLookup) +private fun add(item: T, vararg traits: ResourceKey) = + builder.add(item.asHolder, TraitData(*traits.map { it.holder }.toTypedArray()), false) + +context(builder: DataMapProvider.Builder, _: Registry) +private fun add(item: T, vararg traits: Pair, GiftTraitData>) = + builder.add(item.asHolder, TraitData(*traits), false) + + +context(builder: DataMapProvider.Builder, _: Registry) +private fun add(items: TagKey, vararg traits: Pair, GiftTraitData>) = + builder.add(items, TraitData(*traits), false) + +context(builder: DataMapProvider.Builder, _: Registry, _: HolderLookup.RegistryLookup) +private fun add(items: TagKey, vararg traits: ResourceKey) = + builder.add(items, TraitData(*traits.map { it.holder }.toTypedArray()), false) + + + +context(_: HolderLookup.RegistryLookup) +private fun ResourceKey.with(quality: Float? = null, duration: Float? = null) = + this.holder to GiftTraitData(quality, duration) + +fun baseFluidTraits(builder: DataMapProvider.Builder, provider: HolderLookup.Provider): Unit = + context( + builder, provider.lookupOrThrow(APRegistries.GIFT_TRAITS), + BuiltInRegistries.FLUID + ) { + add(Tags.Fluids.WATER, KnownTraits.Water) + add(Tags.Fluids.LAVA, KnownTraits.Fire,ExtraTraits.Lava) + add(Tags.Fluids.MILK, KnownTraits.Milk) + } + +fun baseItemTraits(builder: DataMapProvider.Builder, provider: HolderLookup.Provider): Unit = + context( + builder, + provider.lookupOrThrow(APRegistries.GIFT_TRAITS), + BuiltInRegistries.ITEM, + BuiltInRegistries.BLOCK + ) { + + + add(Items.TNT, KnownTraits.Bomb) + add( + Items.TOTEM_OF_UNDYING, + KnownTraits.Artifact, KnownTraits.Ancient + ) + add(Items.SNOWBALL, KnownTraits.Ice, KnownTraits.Throwing) + add(Items.ICE, KnownTraits.Ice) + add(Items.PACKED_ICE, KnownTraits.Ice) + add(Items.BLUE_ICE, KnownTraits.Ice.with(quality = 0.5f)) + add(Items.SNOW_BLOCK, KnownTraits.Ice.with(quality = 0.1f)) + add(Items.SNOW, KnownTraits.Ice.with(quality = 0.05f)) + add(Items.BAMBOO, KnownTraits.Grass, ExtraTraits.Bamboo) + add(Items.DECORATED_POT, KnownTraits.Ceramic) + add(Items.ENCHANTED_BOOK, KnownTraits.Scroll, KnownTraits.IQ, KnownTraits.Buff) + add(Items.BONE, KnownTraits.Bone) + add(Items.BONE_BLOCK, KnownTraits.Fossil, KnownTraits.Bone) + add(Items.BONE_MEAL, KnownTraits.Bone) + add(Items.REDSTONE, KnownTraits.Energy.with(quality = 0.1f)) + add(Items.REDSTONE_BLOCK, KnownTraits.Energy.with(quality = 0.5f)) + add(Items.GLOWSTONE_DUST, KnownTraits.Light.with(quality = 0.1f)) + add(Items.GLOWSTONE, KnownTraits.Light.with(quality = 0.5f)) + add(Items.NOTE_BLOCK, KnownTraits.Instrument) + add(Items.JUKEBOX, KnownTraits.Instrument.with(quality = 0.5f)) + add(Items.REPEATER, KnownTraits.Electronics.with(quality = 0.1f)) + add(Items.COMPARATOR, KnownTraits.Electronics.with(quality = 0.5f)) + add(Items.PAINTING, KnownTraits.Luxury) + add(Items.ITEM_FRAME, KnownTraits.Luxury.with(quality = 0.5f)) + add(Items.ARMOR_STAND, KnownTraits.Luxury.with(quality = 0.1f)) + add(Items.GOAT_HORN, KnownTraits.Instrument, KnownTraits.Goat) + add(Items.CLAY, KnownTraits.Beach, KnownTraits.Clay) + add(Items.DEAD_BUSH, KnownTraits.Bush, KnownTraits.Dry) + add(Items.HEART_OF_THE_SEA, KnownTraits.Artifact, KnownTraits.Ocean, KnownTraits.Ancient) + add(Items.NAUTILUS_SHELL, KnownTraits.Ocean, KnownTraits.Ancient) + add(Items.TRIDENT, KnownTraits.Trident, KnownTraits.Ocean, KnownTraits.Ancient) + add(Items.PAPER, KnownTraits.Paper) + add(Items.FIREWORK_ROCKET, KnownTraits.Firework, KnownTraits.Rocket) + add(Items.SPLASH_POTION, KnownTraits.Throwing) + add(Items.LINGERING_POTION, KnownTraits.Throwing) + add(Items.ENDER_PEARL, KnownTraits.Teleport, KnownTraits.Throwing) + add(Items.VINE, KnownTraits.Vine, KnownTraits.Grass) + add(Items.TWISTING_VINES, KnownTraits.Vine, KnownTraits.Grass) + add(Items.WEEPING_VINES, KnownTraits.Vine, KnownTraits.Grass) + add(Items.FLOWER_POT, KnownTraits.Ceramic) + add(Items.COOKED_CHICKEN, KnownTraits.Chicken) + add(Items.CHICKEN, KnownTraits.Chicken) + add(Items.WHEAT, KnownTraits.Grain) + + listOf( + Items.PRISMARINE, + Items.DARK_PRISMARINE, + ).forEach { add(it, KnownTraits.Prismarine, KnownTraits.Aquamarine, KnownTraits.Water, KnownTraits.Ocean) } + + listOf( + Items.COOKED_BEEF, + Items.BEEF, + ).forEach { + add(it, KnownTraits.Cow, KnownTraits.Beef) + } + + listOf( + Items.TORCH, + Items.REDSTONE_TORCH, + Items.SOUL_TORCH, + ).forEach { + add(it, KnownTraits.Light) + } + + + //todo wood types + + // dies + tags() + } + +context(builder: DataMapProvider.Builder, _: Registry, _: HolderLookup.RegistryLookup) +private fun dyes() { + add(Tags.Items.DYES_BLACK, KnownTraits.Black) + add(Tags.Items.DYED_BLACK, KnownTraits.Black) + add(Tags.Items.DYES_BLUE, KnownTraits.Blue) + add(Tags.Items.DYED_BLUE, KnownTraits.Blue) + add(Tags.Items.DYES_BROWN, KnownTraits.Brown) + add(Tags.Items.DYED_BROWN, KnownTraits.Brown) + add(Tags.Items.DYES_CYAN, KnownTraits.Cyan) + add(Tags.Items.DYED_CYAN, KnownTraits.Cyan) + add(Tags.Items.DYES_GRAY, KnownTraits.Gray) + add(Tags.Items.DYED_GRAY, KnownTraits.Gray) + add(Tags.Items.DYES_GREEN, KnownTraits.Green) + add(Tags.Items.DYED_GREEN, KnownTraits.Green) + add(Tags.Items.DYES_LIGHT_BLUE, KnownTraits.LightBlue) + add(Tags.Items.DYED_LIGHT_BLUE, KnownTraits.LightBlue) + add(Tags.Items.DYES_LIGHT_GRAY, KnownTraits.LightGray) + add(Tags.Items.DYED_LIGHT_GRAY, KnownTraits.LightGray) + add(Tags.Items.DYES_LIME, KnownTraits.Lime) + add(Tags.Items.DYED_LIME, KnownTraits.Lime) + add(Tags.Items.DYES_MAGENTA, KnownTraits.Magenta) + add(Tags.Items.DYED_MAGENTA, KnownTraits.Magenta) + add(Tags.Items.DYES_ORANGE, KnownTraits.Orange) + add(Tags.Items.DYED_ORANGE, KnownTraits.Orange) + add(Tags.Items.DYES_PINK, KnownTraits.Pink) + add(Tags.Items.DYED_PINK, KnownTraits.Pink) + add(Tags.Items.DYES_PURPLE, KnownTraits.Purple) + add(Tags.Items.DYED_PURPLE, KnownTraits.Purple) + add(Tags.Items.DYES_RED, KnownTraits.Red) + add(Tags.Items.DYED_RED, KnownTraits.Red) + add(Tags.Items.DYES_WHITE, KnownTraits.White) + add(Tags.Items.DYED_WHITE, KnownTraits.White) + add(Tags.Items.DYES_YELLOW, KnownTraits.Yellow) + add(Tags.Items.DYED_YELLOW, KnownTraits.Yellow) + add(Tags.Items.DYES, KnownTraits.Dye) +} + +context(builder: DataMapProvider.Builder, + _: Registry, + _: HolderLookup.RegistryLookup, + _: HolderLookup.RegistryLookup +) +private fun tags() { + dyes() + // c: are in Tags.Items + add(ItemTags.PICKAXES, ExtraTraits.Pickaxe) + add( + Tags.Items.MINING_TOOL_TOOLS, KnownTraits.Stone.with(quality = 0.5f), + KnownTraits.Ore.with(quality = 0.5f) + ) + add( + ItemTags.AXES, + ExtraTraits.Axe.with(), + KnownTraits.Wood.with(quality = 0.5f), + KnownTraits.Lumber.with(quality = 0.5f) + ) + add( + ItemTags.SHOVELS, + ExtraTraits.Shovel.with(), + KnownTraits.Grass.with(quality = 0.5f), + KnownTraits.Sand.with(quality = 0.5f) + ) + add( + ItemTags.HOES, + ExtraTraits.Hoe.with(), + KnownTraits.Grass.with(quality = 0.5f), + KnownTraits.Grain.with(quality = 0.5f) + ) + add(Tags.Items.STONES, KnownTraits.Stone.with(quality = 1f),KnownTraits.Mineral.with(quality = 0.2f)) + add(Tags.Items.COBBLESTONES, KnownTraits.Stone.with(quality = 0.8f)) + add(Tags.Items.FOODS_VEGETABLE, KnownTraits.Vegetable) + add(Tags.Items.FOODS, KnownTraits.Food) + add(Tags.Items.RAW_MATERIALS, KnownTraits.Material) + add(Tags.Items.DRINKS, KnownTraits.Drink) + add( + ItemTags.DIRT, + KnownTraits.Grass.with(quality = 0.5f), + ) + add( + ItemTags.FLOWERS, + KnownTraits.Grass, + KnownTraits.Flower + ) + add( + ItemTags.LEAVES, + KnownTraits.Grass.with(quality = 0.8f), + KnownTraits.Tree.with(quality = 0.8f), + ) + add(Tags.Items.CROPS, KnownTraits.Grass) + add(Tags.Items.SEEDS, KnownTraits.Grass, KnownTraits.Seed) + add(Tags.Items.ORES, KnownTraits.Ore) + add(Tags.Items.EGGS, KnownTraits.Egg) + add(Tags.Items.FOODS_RAW_FISH, KnownTraits.Fish) + add(Tags.Items.FOODS_COOKED_FISH, KnownTraits.Fish) + add(Tags.Items.TOOLS, KnownTraits.Tool) + add(Tags.Items.MELEE_WEAPON_TOOLS, KnownTraits.Weapon, KnownTraits.MeleeWeapon) + add(Tags.Items.RANGED_WEAPON_TOOLS, KnownTraits.Weapon, KnownTraits.RangedWeapon) + add(Tags.Items.BUCKETS_ENTITY_WATER, KnownTraits.Water, KnownTraits.Animal) + add(Tags.Items.FOODS_RAW_MEAT, KnownTraits.Meat) + add(Tags.Items.FOODS_COOKED_MEAT, KnownTraits.Meat) + add(Tags.Items.ARMORS, KnownTraits.Armor) + add(Tags.Items.FOODS_FRUIT, KnownTraits.Fruit) + add(Tags.Items.INGOTS_COPPER, KnownTraits.Copper.with(quality = 1f)) + add(Tags.Items.INGOTS_IRON, KnownTraits.Iron.with(quality = 1f)) + add(Tags.Items.ORES_COPPER, KnownTraits.Copper) + add(Tags.Items.ORES_COAL, KnownTraits.Coal.with(quality = 1f)) + add(Tags.Items.INGOTS_NETHERITE, KnownTraits.Metal.with(quality = 5f)) + add(Tags.Items.ORES_NETHERITE_SCRAP, KnownTraits.Metal.with(quality = 4f)) + add(Tags.Items.STORAGE_BLOCKS_COAL, KnownTraits.Coal) + add(Tags.Items.INGOTS, KnownTraits.Metal.with(quality = 1f)) + add(Tags.Items.FOODS_RAW_MEAT, KnownTraits.Meat) + add(Tags.Items.FOODS_COOKED_MEAT, KnownTraits.Meat) + add(Tags.Items.INGOTS_GOLD, KnownTraits.Gold.with(quality = 1f)) + add(Tags.Items.ORES_GOLD, KnownTraits.Gold) + add(Tags.Items.FOODS_COOKIE, KnownTraits.Cooking) + add(Tags.Items.FOODS_SOUP, KnownTraits.Cooking) + add(Tags.Items.NETHERRACKS, KnownTraits.Fire.with(quality = 0.2f), KnownTraits.Stone.with()) + add(Tags.Items.RODS_BLAZE, KnownTraits.Fire) + add(Tags.Items.FLOWERS, KnownTraits.Flower) + add(ItemTags.PLANKS, KnownTraits.Lumber.with(), KnownTraits.Wood.with(quality = 1f)) + add(Tags.Items.STRIPPED_LOGS, KnownTraits.Wood.with(quality = 4f), KnownTraits.Lumber.with()) + add(ItemTags.LOGS, KnownTraits.Wood.with(quality = 4f), KnownTraits.Tree.with()) + add(Tags.Items.GEMS, KnownTraits.Gem) + add(Tags.Items.OBSIDIANS, KnownTraits.Mineral, KnownTraits.Gem) + add(Tags.Items.DRINKS_WATERY, KnownTraits.Water) + add(Tags.Items.SHULKER_BOXES, KnownTraits.Container) + add(Tags.Items.CHESTS, KnownTraits.Container) + add(Tags.Items.BARRELS, KnownTraits.Container) + add(Tags.Items.STONES, KnownTraits.Rock) + add(Tags.Items.BOOKSHELVES, KnownTraits.Book, KnownTraits.Paper) + add(ItemTags.BOOKSHELF_BOOKS, KnownTraits.Book, KnownTraits.Paper) + add(Tags.Items.SEEDS, KnownTraits.Seed) + add(ItemTags.DECORATED_POT_SHERDS, KnownTraits.Ceramic) + add(Tags.Items.GEMS_EMERALD, KnownTraits.Currency) + add(Tags.Items.GEMS_DIAMOND, KnownTraits.Diamond) + add(Tags.Items.MUSHROOMS, KnownTraits.Mushroom) + add(Tags.Items.LEATHERS, KnownTraits.Leather) + add(Tags.Items.BONES, KnownTraits.Bone) + add(Tags.Items.FOODS_BERRY, KnownTraits.Berry) + add(Tags.Items.PLAYER_WORKSTATIONS_FURNACES, KnownTraits.Machine, KnownTraits.Furnace) + add(Tags.Items.PLAYER_WORKSTATIONS_CRAFTING_TABLES, KnownTraits.Machine, KnownTraits.Crafting) + add(Tags.Items.SLIME_BALLS, KnownTraits.Goo) + add(Tags.Items.STORAGE_BLOCKS_SLIME, KnownTraits.Goo) + add(Tags.Items.CLUSTERS, KnownTraits.Crystal) + add(Tags.Items.BUDS, KnownTraits.Crystal) + add(Tags.Items.GEMS_AMETHYST, KnownTraits.Crystal.with(quality = 0.8f)) + add(Tags.Items.GEMS_QUARTZ, KnownTraits.Crystal.with(quality = 1f)) + add(Tags.Items.DRINKS_JUICE, KnownTraits.Juice) + add(Tags.Items.DRINKS_MILK, KnownTraits.Milk, KnownTraits.AnimalProduct) + add(Tags.Items.POTIONS, KnownTraits.Potion) + add(Tags.Items.SANDS, KnownTraits.Sand, KnownTraits.Beach) + add(Tags.Items.FERTILIZERS, KnownTraits.Fertilizer) + add(ItemTags.SAPLINGS, KnownTraits.TreeSeed) + add(Tags.Items.SANDS, KnownTraits.Desert) + add(Tags.Items.CROPS_CACTUS, KnownTraits.Desert) + add(Tags.Items.GUNPOWDERS, KnownTraits.Explosive, KnownTraits.Powder) + add(Tags.Items.DUSTS, KnownTraits.Powder) + + +} + diff --git a/src/main/kotlin/gg/archipelago/aprandomizer/gifting/CraftingTraitsHolder.kt b/src/main/kotlin/gg/archipelago/aprandomizer/gifting/CraftingTraitsHolder.kt new file mode 100644 index 0000000..87484fe --- /dev/null +++ b/src/main/kotlin/gg/archipelago/aprandomizer/gifting/CraftingTraitsHolder.kt @@ -0,0 +1,156 @@ +package gg.archipelago.aprandomizer.gifting + +import net.minecraft.core.Holder +import net.minecraft.core.HolderLookup +import net.minecraft.util.context.ContextMap +import net.minecraft.world.item.Item +import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.crafting.Recipe +import net.minecraft.world.item.crafting.RecipeHolder +import net.minecraft.world.item.crafting.RecipeInput +import net.minecraft.world.item.crafting.RecipeManager +import net.minecraft.world.item.crafting.RecipeType + +class CraftingTraitsHolder( + private val itemTraits: context(HolderLookup.RegistryLookup) + (Holder, RecipeManager) -> Collection, + private val materialTraitMinimumRecipes: Int = 3, + private val materialTraitQualityPerRecipe: Float = 0.1f, + private val materialTraitMaxValue: Float = 3f, +) { + private val cache: MutableMap> = mutableMapOf() + + + //todo figure out proper ordering + context(_: HolderLookup.RegistryLookup) + fun resolveTraits(item: Item, recipeManager: RecipeManager): List { + if (cache.containsKey(item)) { + return cache[item]!! + } + cache[item] = emptyList() // todo find better way to avoid infinite recursion + val recipeMap = recipeManager.recipeMap() + // find recipes outputting the item + val recipesMaking = recipeMap.byType(RecipeType.CRAFTING).mapNotNull { recipe -> + recipe.value.display().flatMap { + it.result().resolveForStacks(ContextMap.EMPTY) + }.find { it.item == item }?.let { recipe to it } + } + recipeMap.byType(RecipeType.SMELTING).mapNotNull { recipe -> + recipe.value.display().flatMap { + it.result().resolveForStacks(ContextMap.EMPTY) + }.find { it.item == item }?.let { recipe to it } + } + + //find recipes which use the item as an ingredient + val recipesUsing = recipeMap.byType(RecipeType.CRAFTING).filter { recipe -> + recipe.value.placementInfo().ingredients().any { ing -> + if (ing.isCustom) { + ing.customIngredient!!.items().anyMatch { it.value() == item } + } else { + ing.values.any { it.value() == item } + } + } + } + recipeMap.byType(RecipeType.SMELTING).filter { recipe -> + recipe.value.placementInfo().ingredients().any { ing -> + if (ing.isCustom) { + ing.customIngredient!!.items().anyMatch { it.value() == item } + } else { + ing.values.any { it.value() == item } + } + } + } + + + val materialTrait = if (recipesUsing.count() > materialTraitMinimumRecipes) { + val quality = (recipesUsing.count() * materialTraitQualityPerRecipe).coerceAtMost(materialTraitMaxValue) + listOf( + KnownTraits.Material.with( + quality = quality, source = GiftTraitSource.CRAFTING + ) + ) + } else emptyList() + val recipeTraits = recipesMaking.map { (r, o) -> r to recipeTraits(r, o,recipeManager) } + val finalInheritedTraits = recipeTraits.map { (recipe, traits) -> + // keep traits that are inheritable and above a certain quality threshold + traits.filter { t -> + val inheritance = t.definition.value().craftingInheritance[recipe.value.type] + inheritance != null && (t.quality == null || t.quality >= inheritance.qualityThreshold) + }.map { t -> + val inheritance = t.definition.value().craftingInheritance[recipe.value.type]!! + t.copy( + quality = (t.quality ?: inheritance.inheritanceDefaultQuality) + .coerceIn(inheritance.minQuality, inheritance.maxQuality), + duration = (t.duration ?: inheritance.inheritanceDefaultDuration) + .coerceIn(inheritance.minDuration, inheritance.maxDuration) + ) + } + }.reduceOrNull { acc, tl -> + // only keep traits that are common to all recipes + val commonDefs = acc.map { it.definition }.intersect(tl.map { it.definition }) + (acc + tl).filter { it.definition in commonDefs } + }.orEmpty() + .groupBy { it.definition } + .map { (def, traits) -> // keep lowest values for each trait + GiftTraitWrapper( + definition = def, + quality = traits.mapNotNull { it.quality }.minOrNull(), + duration = traits.mapNotNull { it.duration }.minOrNull(), + source = GiftTraitSource.CRAFTING + ) + } + return (finalInheritedTraits + materialTrait).also { cache[item] = it } + } + + context(traitLookup: HolderLookup.RegistryLookup) private fun recipeTraits( + recipe: RecipeHolder>, output: ItemStack, recipeManager: RecipeManager + ): List { + val ingredients = + recipe.value.placementInfo().ingredients().map { ing -> // list of "actual" ingredient in each slot + if (ing.isCustom) { + ing.customIngredient!!.items().toList() + } else ing.values.toList() + } + + val ingredientTraitsPerSlot = ingredients.map { possibleIngredientsInSlot -> // for each slot + possibleIngredientsInSlot.map { itemTraits(it, recipeManager) } // turn each ingredient into its traits + .reduceOrNull { acc, traits -> // only take traits that are common to alternative possible ingredients in this slot + val commonDefs = acc.map { it.definition }.intersect(traits.map { it.definition }) + (acc + traits).filter { it.definition in commonDefs } + }.orEmpty() + } + val traitsFromAllIngredients = ingredientTraitsPerSlot.map { slotTraits -> + slotTraits.groupBy { it.definition }.mapNotNull { (traitDef, traitList) -> + val inheritance = + traitDef.value().craftingInheritance[recipe.value.type] ?: return@mapNotNull null + val quality = traitList.mapNotNull { it.quality }.minOrNull() + val duration = traitList.mapNotNull { it.duration }.minOrNull() + + GiftTraitWrapper( + definition = traitDef, + quality = quality?.times(inheritance.qualityKeptMultiplier), + duration = duration?.times(inheritance.durationKeptMultiplier), + source = GiftTraitSource.CRAFTING + ) + } + }.map { slotTraits -> + slotTraits.map { trait -> // divide quality and duration by the recipe result amount + GiftTraitWrapper( + definition = trait.definition, + source = GiftTraitSource.CRAFTING, + quality = trait.quality?.div(output.count), + duration = trait.duration?.div(output.count) + ) + } + }.flatten() + .groupBy { it.definition } + .mapNotNull { (d, t) -> + val inheritance = d.value().craftingInheritance[recipe.value.type] ?: return@mapNotNull null + GiftTraitWrapper( + definition = d, + quality = t.map { it.quality ?: inheritance.inheritanceDefaultQuality }.sum(), + duration = t.map { it.duration ?: inheritance.inheritanceDefaultDuration }.sum(), + source = GiftTraitSource.CRAFTING + ) + } + return traitsFromAllIngredients + } +} diff --git a/src/main/kotlin/gg/archipelago/aprandomizer/gifting/GiftHandler.kt b/src/main/kotlin/gg/archipelago/aprandomizer/gifting/GiftHandler.kt new file mode 100644 index 0000000..30f5b9f --- /dev/null +++ b/src/main/kotlin/gg/archipelago/aprandomizer/gifting/GiftHandler.kt @@ -0,0 +1,166 @@ +package gg.archipelago.aprandomizer.gifting + +import dev.koifysh.archipelago.parts.NetworkPlayer +import gg.archipelago.aprandomizer.APRandomizer +import gg.archipelago.aprandomizer.APRegistries +import gg.archipelago.aprandomizer.ap.APClient +import kotlinx.coroutines.* +import kotlinx.coroutines.future.asCompletableFuture +import net.leloubil.archipelago.gifting.api.CanGiftResult +import net.leloubil.archipelago.gifting.api.GiftItem +import net.leloubil.archipelago.gifting.api.GiftingService +import net.leloubil.archipelago.gifting.api.SendGiftResult +import net.minecraft.core.RegistryAccess +import net.minecraft.core.registries.BuiltInRegistries +import net.minecraft.resources.ResourceLocation +import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.crafting.RecipeManager +import java.util.concurrent.CompletableFuture +import kotlin.jvm.optionals.getOrNull + +private val CanGiftResult.CanGiftError.playerFacingMessage + get() = when (this) { + CanGiftResult.CanGiftError.DataStorageWriteError -> "Failed to write to data storage." + is CanGiftResult.CanGiftError.DataVersionTooLow -> "The recipient's data version is too low to receive gifts. Minimum required: ${this.recipientMinimumVersion}." + + CanGiftResult.CanGiftError.GiftBoxClosed -> "The recipient's gift box is closed." + is CanGiftResult.CanGiftError.NoMatchingTraits -> "The recipient does not accept any of the traits of this gift. Accepted traits: ${ + this.recipientAcceptedTraits.joinToString( + ", " + ) + }." + + is CanGiftResult.CanGiftError.NoGiftBox -> "The player doesn't accept gifts." + } + +@OptIn(DelicateCoroutinesApi::class) +class GiftHandler(client: APClient,val matcher: MinecraftGiftMatcher) { + fun openGiftBox(): CompletableFuture { + return GlobalScope.async { giftingService.openGiftBox(true, emptyList()) }.asCompletableFuture() + } + + private val giftingService = GiftingService(client) + + var recepTask: Job? = null + + fun startReception(registryAccess: RegistryAccess, recipeManager: RecipeManager) { + if (recepTask != null) return + recepTask = GlobalScope.launch { + println("Starting gift reception") + giftingService.receivedGifts.collect { gift -> + println("Received gift: $gift") + val removed = giftingService.removeGiftsFromBox(gift) + if (!(removed?.contains(gift.id) ?: false)){ + println("Failed to remove gift from box: $gift") + return@collect + } + val recipient = APRandomizer.server!!.playerList.players.random() //todo + println("Received gift $gift") + if (gift.isRefund) { + val item = BuiltInRegistries.ITEM.get(ResourceLocation.parse(gift.item.name)).getOrNull() + if (item == null) { + println("Dropping refund : $gift") + } else { + //todo handle complex refunds (like potions) by saving sent gift ids and itemstacks maybe ? + recipient.addItem(ItemStack(item, gift.amount)) + } + } + else { + val itemStack: ItemStack? = context(registryAccess.lookupOrThrow(APRegistries.GIFT_TRAITS)) { + matcher.resolveGift(gift.item.traits, recipeManager)?.copyWithCount(gift.amount) + } + if (itemStack == null) { + println("Failed to resolve item for gift: $gift") + giftingService.refundGift(gift) + return@collect + } + val displayStack = itemStack.copy() + val res = recipient.addItem(itemStack) + if (!res) { + println("Failed to add gift item to player ${recipient.name}. Item: $displayStack, Amount: ${gift.amount}") + giftingService.refundGift(gift) + } else { + println("Gift item added to player ${recipient.name}. Item: $displayStack, Amount: ${gift.amount}") + } + } + + } + } + } + + fun stopReception() { + recepTask?.cancel() + } + + fun closeGiftBox(): CompletableFuture { + return GlobalScope.async { + giftingService.closeGiftBox(); + }.asCompletableFuture() + } + + /** + * Checks if the item can be sent to the recipient. + * + * @param stack The item + * @param recipient The player receiving the item. + * @return A user-facing string indicating the reason if it cannot be sent, or null if it can be sent. + */ + context(registryAccess: RegistryAccess) + fun canSendItem(stack: ItemStack, recipient: NetworkPlayer, recipeManager: RecipeManager): CompletableFuture { + return GlobalScope.async { + val res = giftingService.canGiftToPlayer( + recipient.slot, recipient.team, getGiftItem(stack, recipeManager).traits.map { it.name }) + + + when (res) { + is CanGiftResult.CanGiftError -> res.playerFacingMessage + is CanGiftResult.CanGiftSuccess -> null + } + }.asCompletableFuture() + } + + /** + * Gifts the item to the recipient. + * + * @param stack The item to be gifted. + * @param recipient The player receiving the item. + * @return A user-facing string indicating the result of the gifting operation, or null if successful. + */ + context(registryAccess: RegistryAccess) + fun giftItem(stack: ItemStack, recipient: NetworkPlayer, recipeManager: RecipeManager): CompletableFuture { + return GlobalScope.async { + val item = getGiftItem(stack, recipeManager) + println("Gifting item: $item to recipient: ${recipient.name} (slot: ${recipient.slot}, team: ${recipient.team})") + val res = giftingService.sendGift( + item = item, + amount = stack.count, + recipientPlayerSlot = recipient.slot, + recipientPlayerTeam = recipient.team + ) + + when (res) { + SendGiftResult.SendGiftFailure.DataStorageWriteError -> "Failed to write to data storage." + is SendGiftResult.SendGiftFailure.CannotGift -> "Cannot gift: ${res.reason.playerFacingMessage}" + SendGiftResult.SendGiftSuccess -> null + } + }.asCompletableFuture() + } + + context(registryAccess: RegistryAccess) + fun getGiftItem(itemStack: ItemStack, recipeManager: RecipeManager): GiftItem { + val item = itemStack.item + val orThrow = registryAccess.lookupOrThrow(APRegistries.GIFT_TRAITS) + val traits = context(orThrow) { + matcher.getItemStackTraits(itemStack, recipeManager) + } + return GiftItem( + name = BuiltInRegistries.ITEM.getKey(item).toString(), + traits = traits + ) + } + + +} + + + diff --git a/src/main/kotlin/gg/archipelago/aprandomizer/gifting/GiftTraits.kt b/src/main/kotlin/gg/archipelago/aprandomizer/gifting/GiftTraits.kt new file mode 100644 index 0000000..2b5767f --- /dev/null +++ b/src/main/kotlin/gg/archipelago/aprandomizer/gifting/GiftTraits.kt @@ -0,0 +1,658 @@ +package gg.archipelago.aprandomizer.gifting + +import gg.archipelago.aprandomizer.APRandomizer +import gg.archipelago.aprandomizer.APRegistries +import net.minecraft.core.HolderLookup +import net.minecraft.data.PackOutput +import net.minecraft.data.tags.TagsProvider +import net.minecraft.data.worldgen.BootstrapContext +import net.minecraft.resources.ResourceKey +import net.minecraft.resources.ResourceLocation +import net.minecraft.tags.TagKey +import net.minecraft.world.item.crafting.RecipeType +import java.util.concurrent.CompletableFuture + + +object DefaultTags { + // Things that are weapons + val WEAPON_TRAITS = createTagKey("weapons") + private val baseWeaponTraits = arrayOf( + KnownTraits.Weapon, + KnownTraits.MeleeWeapon, + KnownTraits.RangedWeapon, + ExtraTraits.Sword, + ExtraTraits.Bow, + ) + + + // Things that are meant to be used multiple times and usually have a durability + val EQUIPMENT_TRAITS = createTagKey("equipment") + private val baseEquipmentTraits = arrayOf( + KnownTraits.Tool, + KnownTraits.Armor, + + ) + + val CONTAINER_TRAITS = createTagKey("containers") + private val baseContainerTraits = arrayOf( + KnownTraits.Container, + KnownTraits.LiquidContainer, + ExtraTraits.Saddle + ) + + val ORE_TRAITS = createTagKey("ores") + private val baseOreTraits = arrayOf( + KnownTraits.Ore, + KnownTraits.Copper, + KnownTraits.Coal, + KnownTraits.Gold, + KnownTraits.Silver, + KnownTraits.Platinum, + KnownTraits.Diamond, + KnownTraits.Gem, + KnownTraits.Crystal, + ) + + // Things that affect the usage of the item + val USAGE_TRAITS = createTagKey("usages") + private val baseUsageTraits = arrayOf( + KnownTraits.Bomb, KnownTraits.Consumable, ExtraTraits.Saddle, KnownTraits.Throwing + ) + + // Traits relating to effects the item can apply + val EFFECT_TRAITS = createTagKey("effects") + private val baseEffectTraits = arrayOf( + KnownTraits.Buff, + KnownTraits.Trap, + KnownTraits.Heal, + KnownTraits.Mana, + KnownTraits.Cure, + KnownTraits.Slowness, + KnownTraits.Damage, + KnownTraits.Fire, + KnownTraits.Ice, + ExtraTraits.AttackSpeed, + ExtraTraits.Suspicious, + ExtraTraits.Ominous, + KnownTraits.Fertilizer + ) + + + // Traits relating to the physical form of the item + val PHYSICAL_STATE_TRAITS = createTagKey("physical_states") + private val basePhysicalStateTraits = arrayOf( + KnownTraits.Goo, + KnownTraits.Powder, + ) + + val MATERIAL_TRAITS = createTagKey("materials") + private val baseMaterialTraits = arrayOf( + KnownTraits.Wood, + KnownTraits.Lumber, + KnownTraits.Stone, + KnownTraits.Meat, + KnownTraits.Vegetable, + KnownTraits.Fruit, + KnownTraits.Egg, + KnownTraits.Metal, + KnownTraits.Mineral, + KnownTraits.Gem, + KnownTraits.Crystal, + KnownTraits.Rock, + KnownTraits.Paper, + KnownTraits.Fish, + KnownTraits.Mushroom, + KnownTraits.Copper, + KnownTraits.Coal, + KnownTraits.Gold, + KnownTraits.Silver, + KnownTraits.Platinum, + KnownTraits.Diamond, + KnownTraits.Prismarine, + KnownTraits.Aquamarine, + KnownTraits.Sand, + KnownTraits.Bone, + KnownTraits.Clay, + KnownTraits.Iron, + KnownTraits.Light, + KnownTraits.Ceramic, + KnownTraits.Fire, + KnownTraits.Ice, + KnownTraits.Energy, + KnownTraits.Electronics, + KnownTraits.Leather, + KnownTraits.AnimalProduct, + KnownTraits.Explosive, + ) + + fun defaultMatchInfo(key: ResourceKey): MatchInfo { + val distanceWeight = when (key) { + in baseEquipmentTraits, in baseWeaponTraits -> 2f + in baseUsageTraits, in baseContainerTraits -> 1.8f + in baseEffectTraits -> 1.6f + in baseMaterialTraits -> 1.4f + in basePhysicalStateTraits -> 1.3f + else -> 1f + } + + val isRequired = when (key) { + in baseMaterialTraits, + in baseUsageTraits, + in baseWeaponTraits, + in baseContainerTraits, + in baseEquipmentTraits, + KnownTraits.Book -> true + + else -> false + } + + return MatchInfo(distanceWeight, isRequired) + } + + fun defaultCraftingInheritance(key: ResourceKey): Map, CraftingInheritance> { + val shapedInheritance = when (key) { + in baseMaterialTraits, KnownTraits.Book, KnownTraits.Resource -> CraftingInheritance( + minQuality = 0.01f, + qualityKeptMultiplier = 1f, + durationKeptMultiplier = 1f, + ) + + in baseEffectTraits -> CraftingInheritance( + qualityKeptMultiplier = 0.2f, + durationKeptMultiplier = 0f + ) + + in baseContainerTraits -> CraftingInheritance( + qualityKeptMultiplier = 0.5f, + durationKeptMultiplier = 0f + ) + + else -> null + } + val smeltingInheritance = when (key) { + in baseOreTraits -> CraftingInheritance( + qualityKeptMultiplier = 1.2f, + durationKeptMultiplier = 1f + ) + + in baseMaterialTraits -> CraftingInheritance( + qualityKeptMultiplier = 1f, + durationKeptMultiplier = 1f + ) + + else -> null + } + return listOfNotNull( + shapedInheritance?.let { RecipeType.CRAFTING to it }, + smeltingInheritance?.let { RecipeType.SMELTING to it } + ).toMap() + } + + class GiftTagsProvider(output: PackOutput, lookupProvider: CompletableFuture) : + GiftTraitsTagProvider(output, lookupProvider, APRandomizer.MODID) { + override fun addTags(lookupProvider: HolderLookup.Provider) { + this.tag(MATERIAL_TRAITS) + .add(*baseMaterialTraits) + tag(PHYSICAL_STATE_TRAITS) + .add( + *basePhysicalStateTraits + ) + tag(ORE_TRAITS) + .add(*baseOreTraits) + tag(EFFECT_TRAITS) + .add(*baseEffectTraits) + tag(CONTAINER_TRAITS) + .add( + *baseContainerTraits + ) + tag(WEAPON_TRAITS) + .add( + *baseWeaponTraits + ) + tag(EQUIPMENT_TRAITS) + .add( + *baseEquipmentTraits + ).addTag(WEAPON_TRAITS) + tag(USAGE_TRAITS) + .add( + *baseUsageTraits + ) + .addTags( + EQUIPMENT_TRAITS, + CONTAINER_TRAITS + ) + } + } +} + + +abstract class GiftTraitsTagProvider( + output: PackOutput, + lookupProvider: CompletableFuture, + modId: String +) : + TagsProvider(output, APRegistries.GIFT_TRAITS, lookupProvider, modId) { +} + + +private fun createKey(path: String): ResourceKey = ResourceKey.create( + APRegistries.GIFT_TRAITS, + ResourceLocation.fromNamespaceAndPath( + APRandomizer.MODID, + path + ) +) + + +private fun createTagKey(path: String): TagKey = TagKey.create( + APRegistries.GIFT_TRAITS, + ResourceLocation.fromNamespaceAndPath( + APRandomizer.MODID, + path + ) +) + +// region Trait definitions +object ExtraTraits { + val Bamboo = createKey("bamboo") + val Pickaxe = createKey("pickaxe") + val Axe = createKey("axe") + val Shovel = createKey("shovel") + val Hoe = createKey("hoe") + val Sword = createKey("sword") + val Bow = createKey("bow") + val ArmorToughness = createKey("armor_toughness") + val AttackSpeed = createKey("attack_speed") + val Saddle = createKey("saddle") + val Suspicious = createKey("suspicious") + val Ominous = createKey("ominous") + val Lava = createKey("lava") + + + val Haste = createKey("haste") + val MiningFatigue = createKey("mining_fatigue") + val Strength = createKey("strength") + val JumpBoost = createKey("jump_boost") + val Nausea = createKey("nausea") + val WaterBreathing = createKey("water_breathing") + val NightVision = createKey("night_vision") + val Hunger = createKey("hunger") + val Weakness = createKey("weakness") + val Wither = createKey("wither") + val SlowFalling = createKey("slow_falling") + val Invisibility = createKey("invisibility") + val Blindness = createKey("blindness") + + fun bootstrap(context: BootstrapContext) { + fun register(key: ResourceKey, name: String) { + context.register( + key, defaultTrait(key, name) + ) + } + register(Bamboo, "Bamboo") + register(Pickaxe, "Pickaxe") + register(Axe, "Axe") + register(Shovel, "Shovel") + register(Hoe, "Hoe") + register(Sword, "Sword") + register(Bow, "Bow") + register(ArmorToughness, "ArmorToughness") + register(AttackSpeed, "AttackSpeed") + register(Saddle, "Saddle") + register(Suspicious, "Suspicious") + register(Ominous, "Ominous") + register(Lava, "Lava") + + register(Haste, "Haste") + register(MiningFatigue, "MiningFatigue") + register(Strength, "Strength") + register(JumpBoost, "JumpBoost") + register(Nausea, "Nausea") + register(WaterBreathing, "WaterBreathing") + register(NightVision, "NightVision") + register(Hunger, "Hunger") + register(Weakness, "Weakness") + register(Wither, "Wither") + register(SlowFalling, "SlowFalling") + register(Invisibility, "Invisibility") + register(Blindness, "Blindness") + } +} + +object KnownTraits { + + val Defense = createKey("defense") + val Speed = createKey("speed") + val Consumable = createKey("consumable") + val Food = createKey("food") + val Drink = createKey("drink") + val Heal = createKey("heal") + val Mana = createKey("mana") + val Key = createKey("key") + val Trap = createKey("trap") + val Buff = createKey("buff") + val Life = createKey("life") + val Weapon = createKey("weapon") + val Armor = createKey("armor") + val Tool = createKey("tool") + val Fish = createKey("fish") + val Animal = createKey("animal") + val Cure = createKey("cure") + val Seed = createKey("seed") + val Metal = createKey("metal") + val Bomb = createKey("bomb") + val Monster = createKey("monster") + val Resource = createKey("resource") + val Material = createKey("material") + val Wood = createKey("wood") + val Stone = createKey("stone") + val Ore = createKey("ore") + val Grass = createKey("grass") + val Meat = createKey("meat") + val Vegetable = createKey("vegetable") + val Fruit = createKey("fruit") + val Egg = createKey("egg") + val Slowness = createKey("slowness") + val Damage = createKey("damage") + val Fire = createKey("fire") + val Ice = createKey("ice") + val Currency = createKey("currency") + val Energy = createKey("energy") + val Light = createKey("light") + + val Copper = createKey("copper") + val Coal = createKey("coal") + val Gold = createKey("gold") + val Silver = createKey("silver") + val Platinum = createKey("platinum") + val Diamond = createKey("diamond") + val Gem = createKey("gem") + val Crystal = createKey("crystal") + val Rock = createKey("rock") + val Boulder = createKey("boulder") + val Book = createKey("book") + val Paper = createKey("paper") + val Dye = createKey("dye") + val Potion = createKey("potion") + val MeleeWeapon = createKey("melee_weapon") + val RangedWeapon = createKey("ranged_weapon") + val Container = createKey("container") + val LiquidContainer = createKey("liquid_container") + val Electronics = createKey("electronics") + val Furnace = createKey("furnace") + val Crafting = createKey("crafting") + val Machine = createKey("machine") + val Luxury = createKey("luxury") + val Statue = createKey("statue") + val Goat = createKey("goat") + val Clay = createKey("clay") + val Cooking = createKey("cooking") + val Bush = createKey("bush") + val Dry = createKey("dry") + val Ocean = createKey("ocean") + val Trident = createKey("trident") + val Artifact = createKey("artifact") + val Ancient = createKey("ancient") + val Water = createKey("water") + val Aquamarine = createKey("aquamarine") + val Prismarine = createKey("prismarine") + val Insect = createKey("insect") + val Sand = createKey("sand") + val Desert = createKey("desert") + val Fertilizer = createKey("fertilizer") + val Fiber = createKey("fiber") + val Explosive = createKey("explosive") + val Powder = createKey("powder") + val Broken = createKey("broken") + val Goo = createKey("goo") + val Salted = createKey("salted") + val Leather = createKey("leather") + val Milk = createKey("milk") + val Chicken = createKey("chicken") + val Cow = createKey("cow") + val Beef = createKey("beef") + val Tree = createKey("tree") + val TreeSeed = createKey("tree_seed") + val Oil = createKey("oil") + val Juice = createKey("juice") + val AnimalProduct = createKey("animal_product") + val Beach = createKey("beach") + val Grain = createKey("grain") + val Mushroom = createKey("mushroom") + val Bone = createKey("bone") + val Iron = createKey("iron") + val Unluck = createKey("unluck") + val Luck = createKey("luck") + val Vine = createKey("vine") + val Ceramic = createKey("ceramic") + val Berry = createKey("berry") + val Coffee = createKey("coffee") + val Flower = createKey("flower") + val Lumber = createKey("lumber") + val Mineral = createKey("mineral") + val Poison = createKey("poison") + val Flight = createKey("flight") + val Head = createKey("head") + val Invincible = createKey("invincible") + val Random = createKey("random") + val Legendary = createKey("legendary") + val Instrument = createKey("instrument") + val Firework = createKey("firework") + val Rocket = createKey("rocket") + val Fuel = createKey("fuel") + val Throwing = createKey("throwing") + val Scroll = createKey("scroll") + val IQ = createKey("iq") + val Fossil = createKey("fossil") + val Teleport = createKey("teleport") + + val Black = createKey("black") + val Blue = createKey("blue") + val Brown = createKey("brown") + val Cyan = createKey("cyan") + val Gray = createKey("gray") + val Green = createKey("green") + val LightBlue = createKey("light_blue") + val LightGray = createKey("light_gray") + val Lime = createKey("lime") + val Magenta = createKey("magenta") + val Orange = createKey("orange") + val Pink = createKey("pink") + val Purple = createKey("purple") + val Red = createKey("red") + val White = createKey("white") + val Yellow = createKey("yellow") + + + fun bootstrap(context: BootstrapContext) { + + fun register(key: ResourceKey, name: String) { + context.register( + key, defaultTrait(key, name) + ) + } + + register(Defense, "Defense") + register(Speed, "Speed") + register(Consumable, "Consumable") + register(Food, "Food") + register(Drink, "Drink") + register(Heal, "Heal") + register(Mana, "Mana") + register(Key, "Key") + register(Trap, "Trap") + register(Buff, "Buff") + register(Life, "Life") + context.register( + Weapon, + defaultTrait(Weapon, "Weapon").copy( + duration = Duration.ItemDurability(), + quality = Quality.WeaponValue(), + ) + ) + context.register( + Armor, + defaultTrait(Armor, "Armor").copy( + duration = Duration.ItemDurability(), + quality = Quality.ArmorQuality(), + ) + ) + context.register( + Tool, defaultTrait( + Tool, + "Tool" + ).copy( + duration = Duration.ItemDurability(), + quality = Quality.ToolEfficiency(), + ) + ) + register(Fish, "Fish") + register(Animal, "Animal") + register(Cure, "Cure") + register(Seed, "Seed") + register(Metal, "Metal") + register(Bomb, "Bomb") + register(Monster, "Monster") + register(Resource, "Resource") + register(Material, "Material") + register(Wood, "Wood") + register(Stone, "Stone") + register(Ore, "Ore") + register(Grass, "Grass") + register(Meat, "Meat") + register(Vegetable, "Vegetable") + register(Fruit, "Fruit") + register(Egg, "Egg") + register(Slowness, "Slowness") + register(Damage, "Damage") + register(Fire, "Fire") + register(Ice, "Ice") + register(Currency, "Currency") + register(Energy, "Energy") + register(Light, "Light") + register(Copper, "Copper") + register(Coal, "Coal") + register(Gold, "Gold") + register(Silver, "Silver") + register(Platinum, "Platinum") + register(Diamond, "Diamond") + register(Gem, "Gem") + register(Crystal, "Crystal") + register(Rock, "Rock") + register(Boulder, "Boulder") + register(Book, "Book") + register(Paper, "Paper") + register(Dye, "Dye") + register(Potion, "Potion") + context.register( + MeleeWeapon, + defaultTrait(MeleeWeapon, "MeleeWeapon").copy( + duration = Duration.ItemDurability(), + quality = Quality.WeaponValue(), + ) + ) + context.register( + RangedWeapon, + defaultTrait(RangedWeapon, "RangedWeapon").copy( + duration = Duration.ItemDurability(), + quality = Quality.WeaponValue(), + ) + ) + register(Container, "Container") + register(LiquidContainer, "LiquidContainer") + register(Electronics, "Electronics") + register(Furnace, "Furnace") + register(Crafting, "Crafting") + register(Machine, "Machine") + register(Luxury, "Luxury") + register(Statue, "Statue") + register(Goat, "Goat") + register(Clay, "Clay") + register(Cooking, "Cooking") + register(Bush, "Bush") + register(Dry, "Dry") + register(Ocean, "Ocean") + register(Trident, "Trident") + register(Artifact, "Artifact") + register(Ancient, "Ancient") + register(Water, "Water") + register(Aquamarine, "Aquamarine") + register(Prismarine, "Prismarine") + register(Insect, "Insect") + register(Sand, "Sand") + register(Desert, "Desert") + register(Fertilizer, "Fertilizer") + register(Fiber, "Fiber") + register(Explosive, "Explosive") + register(Powder, "Powder") + register(Broken, "Broken") + register(Goo, "Goo") + register(Salted, "Salted") + register(Leather, "Leather") + register(Milk, "Milk") + register(Chicken, "Chicken") + register(Cow, "Cow") + register(Beef, "Beef") + register(Tree, "Tree") + register(TreeSeed, "TreeSeed") + register(Oil, "Oil") + register(Juice, "Juice") + register(AnimalProduct, "AnimalProduct") + register(Beach, "Beach") + register(Grain, "Grain") + register(Mushroom, "Mushroom") + register(Bone, "Bone") + register(Iron, "Iron") + register(Unluck, "Unluck") + register(Luck, "Luck") + register(Vine, "Vine") + register(Ceramic, "Ceramic") + register(Berry, "Berry") + register(Coffee, "Coffee") + register(Flower, "Flower") + register(Lumber, "Lumber") + register(Mineral, "Mineral") + register(Poison, "Poison") + register(Flight, "Flight") + register(Head, "Head") + register(Invincible, "Invincible") + register(Random, "Random") + register(Legendary, "Legendary") + register(Instrument, "Instrument") + register(Firework, "Firework") + register(Rocket, "Rocket") + register(Fuel, "Fuel") + register(Throwing, "Throwing") + register(Scroll, "Scroll") + register(IQ, "IQ") + register(Fossil, "Fossil") + register(Teleport, "Teleport") + register(Black, "Black") + register(Blue, "Blue") + register(Brown, "Brown") + register(Cyan, "Cyan") + register(Gray, "Gray") + register(Green, "Green") + register(LightBlue, "LightBlue") + register(LightGray, "LightGray") + register(Lime, "Lime") + register(Magenta, "Magenta") + register(Orange, "Orange") + register(Pink, "Pink") + register(Purple, "Purple") + register(Red, "Red") + register(White, "White") + register(Yellow, "Yellow") + } +} + +fun defaultTrait( + key: ResourceKey, + name: String +) = GiftTraitDefinition( + name, + craftingInheritance = DefaultTags.defaultCraftingInheritance(key), + matchInfo = DefaultTags.defaultMatchInfo(key) +) + + diff --git a/src/main/kotlin/gg/archipelago/aprandomizer/gifting/MatchingUtils.kt b/src/main/kotlin/gg/archipelago/aprandomizer/gifting/MatchingUtils.kt new file mode 100644 index 0000000..08fb0c4 --- /dev/null +++ b/src/main/kotlin/gg/archipelago/aprandomizer/gifting/MatchingUtils.kt @@ -0,0 +1,165 @@ +package gg.archipelago.aprandomizer.gifting + +import gg.archipelago.aprandomizer.utils.holder +import net.minecraft.core.Holder +import net.minecraft.core.HolderLookup +import net.minecraft.resources.ResourceKey + +enum class GiftTraitSource(val priority: Int) { + ATTRIBUTE_MODIFIERS(8), + ITEM_COMPONENTS(7), + FLUID_COMPONENTS(6), + //dynamic + CAPABILITIES(5), + + //calculated + CRAFTING(4), + DERIVED_TRAITS(3), + //static + ITEM_SPECIFIC(2), + FLUID_SPECIFIC(1), + MERGED(0); + +} + +data class GiftTraitWrapper( + val definition: Holder, + val quality: Float? = null, + val duration: Float? = null, + val source: GiftTraitSource, +) { + + fun copy( + source: GiftTraitSource, + quality: Float? = this.quality, + duration: Float? = this.duration + ): GiftTraitWrapper { + return GiftTraitWrapper(definition, quality, duration, source) + } +} + +fun Holder.with( + source: GiftTraitSource, + quality: Float? = null, + duration: Float? = null +): GiftTraitWrapper { + return GiftTraitWrapper(this, quality, duration, source) +} + +fun TraitData.wrapped(source: GiftTraitSource): List = + this.traits.map { (k, v) -> GiftTraitWrapper(k, v.quality, v.duration, source) } + + +interface TraitSourceScope { + + fun Holder.with( + quality: Float? = null, + duration: Float? = null + ): GiftTraitWrapper + + context(lookup: HolderLookup.RegistryLookup) + fun ResourceKey.with( + quality: Float? = null, + duration: Float? = null + ): GiftTraitWrapper + + val Holder.default + get() = this.with() + +} + +inline fun traitSourceScope(source: GiftTraitSource, block: TraitSourceScope.() -> T): T { + val obj = object : TraitSourceScope { + + override fun Holder.with( + quality: Float?, + duration: Float? + ): GiftTraitWrapper { + return GiftTraitWrapper(this, quality, duration, source) + } + + context(lookup: HolderLookup.RegistryLookup) + override fun ResourceKey.with( + quality: Float?, + duration: Float? + ): GiftTraitWrapper = this.with(source, quality, duration) + } + return obj.block() +} + + +//fun splitResourceLocationToElements(location: ResourceLocation): List { +// return location.path.split('/', '_', '-') +//} +// +//interface ResourceLocationMatchScope { +// infix fun String.locationMeans(trait: GiftTrait) +// fun String.locationMeans(vararg traits: GiftTrait) +// +// infix fun String.stringInLocationMeans(trait: GiftTrait) +// +// infix fun List.locationMeans(trait: GiftTrait) { +// this.forEach { t -> +// t locationMeans trait +// } +// } +// +// infix fun String.elementInLocationMeans(trait: GiftTrait) +// infix fun List.elementInLocationMeans(trait: GiftTrait) { +// this.forEach { t -> +// t elementInLocationMeans trait +// } +// } +// +// fun String.elementInLocationMeans(vararg traits: GiftTrait) +//} +// +//inline fun TraitSourceScope.matchResourceLocation( +// location: ResourceLocation, +// block: ResourceLocationMatchScope.() -> Unit +//): List { +// val res = mutableListOf() +// val obj = object : ResourceLocationMatchScope { +// override fun String.locationMeans(trait: GiftTrait) { +// assert(this.contains(':')) +// if (this@locationMeans == location.toString()) { +// res.add(trait.withSource()) +// } +// } +// +// override fun String.locationMeans(vararg traits: GiftTrait) { +// assert(this.contains(':')) +// if (this@locationMeans == location.toString()) { +// res.addAll(traits.toList().withSource()) +// } +// } +// +// override fun String.stringInLocationMeans(trait: GiftTrait) { +// assert(!this.contains(':')) +// if (splitResourceLocationToElements(location).contains(this)) { +// res.add(trait.withSource()) +// } +// } +// +// override fun String.elementInLocationMeans(trait: GiftTrait) { +// assert(!this.contains(':')) +// if (splitResourceLocationToElements(location).contains(this@elementInLocationMeans)) { +// res.add(trait.withSource()) +// } +// } +// +// override fun String.elementInLocationMeans(vararg traits: GiftTrait) { +// assert(!this.contains(':')) +// if (splitResourceLocationToElements(location).contains(this@elementInLocationMeans)) { +// res.addAll(traits.toList().withSource()) +// } +// } +// } +// block.invoke(obj) +// return res +//} +context(_: HolderLookup.RegistryLookup) +fun ResourceKey.with(source: GiftTraitSource, quality: Float? = null, duration: Float? = null) = + GiftTraitWrapper( + this.holder, quality, duration, source + ) diff --git a/src/main/kotlin/gg/archipelago/aprandomizer/gifting/MinecraftGiftMatcher.kt b/src/main/kotlin/gg/archipelago/aprandomizer/gifting/MinecraftGiftMatcher.kt new file mode 100644 index 0000000..ea4337d --- /dev/null +++ b/src/main/kotlin/gg/archipelago/aprandomizer/gifting/MinecraftGiftMatcher.kt @@ -0,0 +1,795 @@ +package gg.archipelago.aprandomizer.gifting + +import gg.archipelago.aprandomizer.APRandomizer +import gg.archipelago.aprandomizer.APRegistries +import gg.archipelago.aprandomizer.datamaps.APDataMaps +import gg.archipelago.aprandomizer.gifting.DefaultTags.EQUIPMENT_TRAITS +import net.leloubil.archipelago.gifting.api.GiftTrait +import net.leloubil.archipelago.gifting.remote.GiftTraitName +import net.leloubil.archipelago.gifting.utils.BKTreeCloseTraitParser +import net.minecraft.core.Holder +import net.minecraft.core.HolderLookup +import net.minecraft.core.RegistryAccess +import net.minecraft.core.component.DataComponents +import net.minecraft.core.component.TypedDataComponent +import net.minecraft.core.registries.BuiltInRegistries +import net.minecraft.resources.ResourceKey +import net.minecraft.resources.ResourceLocation +import net.minecraft.server.packs.resources.ResourceManager +import net.minecraft.server.packs.resources.SimplePreparableReloadListener +import net.minecraft.util.profiling.ProfilerFiller +import net.minecraft.world.effect.MobEffect +import net.minecraft.world.effect.MobEffectCategory +import net.minecraft.world.effect.MobEffectInstance +import net.minecraft.world.effect.MobEffects +import net.minecraft.world.entity.EquipmentSlot +import net.minecraft.world.entity.ai.attributes.Attribute +import net.minecraft.world.entity.ai.attributes.AttributeModifier +import net.minecraft.world.entity.ai.attributes.Attributes +import net.minecraft.world.entity.ai.attributes.RangedAttribute +import net.minecraft.world.flag.FeatureFlagSet +import net.minecraft.world.food.FoodProperties +import net.minecraft.world.item.* +import net.minecraft.world.item.alchemy.PotionContents +import net.minecraft.world.item.component.Consumable +import net.minecraft.world.item.component.ItemAttributeModifiers +import net.minecraft.world.item.component.Tool +import net.minecraft.world.item.consume_effects.* +import net.minecraft.world.item.crafting.RecipeManager +import net.minecraft.world.item.enchantment.Enchantments +import net.minecraft.world.item.enchantment.ItemEnchantments +import net.minecraft.world.item.equipment.Equippable +import net.minecraft.world.level.material.Fluids +import net.neoforged.neoforge.capabilities.Capabilities +import net.neoforged.neoforge.common.BooleanAttribute +import net.neoforged.neoforge.common.CreativeModeTabRegistry +import net.neoforged.neoforge.common.NeoForgeMod +import net.neoforged.neoforge.common.PercentageAttribute +import net.neoforged.neoforge.event.AddServerReloadListenersEvent +import net.neoforged.neoforge.fluids.FluidStack +import net.neoforged.neoforge.fluids.capability.IFluidHandler +import net.neoforged.neoforge.registries.datamaps.builtin.FurnaceFuel +import net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps +import kotlin.jvm.optionals.getOrNull +import kotlin.math.abs +import kotlin.random.Random + +class MinecraftGiftMatcher( + val randomSeed: Long, +) { + private var treeParser = BKTreeCloseTraitParser(::distance) + private val craftingTraitsHolder: CraftingTraitsHolder = + CraftingTraitsHolder({ it, re -> + itemTraits(it.value(), craftingTraitsHolder, re) + } + ) + + + private fun distance( + originalTraits: List, + other: MutableMap>, + isCompatible: BKTreeCloseTraitParser.BooleanWrapper + ): Float { + val traits = originalTraits.groupBy { + it.name + }.map { (k, v) -> + GiftTrait( + k, + quality = v.map { it.quality }.average().toFloat(), + duration = v.map { it.duration }.average().toFloat(), + ) + } + + isCompatible.value = true + val traitsCopy = other.toMutableMap() + var distance = 0.0f + traits.forEach { giftTrait -> + val (distanceWeight, isRequired) = matchInfo.getOrDefault(giftTrait.name, MatchInfo(1f, false)) + traitsCopy.remove(giftTrait.name.name)?.let { values -> + val traitDist = abs(values.first - giftTrait.quality) + abs(values.second - giftTrait.duration) + + distance += traitDist * (1/ distanceWeight) + } ?: run { + distance += 10.0f * distanceWeight + if (isRequired) { + isCompatible.value = false + } + } + } + distance += abs(traits.size - traitsCopy.size) / 2f + return distance + } + + + fun registerAllMinecraftGifts( + featureFlagSet: FeatureFlagSet, + access: RegistryAccess, + recipeManager: RecipeManager + ) { + treeParser = BKTreeCloseTraitParser(::distance) + println("Registering items as gifts") + val excluded: List = CreativeModeTabRegistry.getDefaultTabs() + listOf( + CreativeModeTabs.OP_BLOCKS, // should already be exluded by setting permission to false, but just in case + CreativeModeTabs.SPAWN_EGGS + ).map { BuiltInRegistries.CREATIVE_MODE_TAB.get(it) }.mapNotNull { it.getOrNull()?.value() } + BuiltInRegistries.CREATIVE_MODE_TAB.subtract(excluded).flatMap { + it.buildContents( + CreativeModeTab.ItemDisplayParameters( + featureFlagSet, + false, + access, + ) + ) + it.displayItems.asSequence() + }.distinct() + .forEach { + val traits = with(access.lookupOrThrow(APRegistries.GIFT_TRAITS)) { + getItemStackTraits(it, recipeManager) + } + if (traits.size < 3) { + println("Item $it has few traits : $traits") + } + treeParser.registerAvailableGift(it, traits) + } + println("Finished") + } + + context(traitLookup: HolderLookup.RegistryLookup) fun getItemStackTraits( + itemStack: ItemStack, + recipeManager: RecipeManager + ): List { + return itemStackTraits(itemStack, craftingTraitsHolder, recipeManager).map { + GiftTrait( + it.definition.value().name, + quality = it.quality ?: 1f, + duration = it.duration ?: 1f, + ) + } + } + + private lateinit var durabilityTraits: List + private lateinit var matchInfo: Map + + private val RELOAD_LISTENER_TRAITS_CONFIG = ResourceLocation.fromNamespaceAndPath( + APRandomizer.MODID, "traits_config" + ) + + private val traitsConfigReloadListener = object : SimplePreparableReloadListener, Map>>() { + override fun prepare( + resourceManager: ResourceManager, + profiler: ProfilerFiller + ): Pair, Map> { + val reg = this.context.registryAccess().lookupOrThrow(APRegistries.GIFT_TRAITS) + val durabilityTraits = reg.mapNotNull { + if (it.duration !is Duration.ItemDurability) return@mapNotNull null + return@mapNotNull it.name + } + val matchInfo = reg.groupBy { it.name }.map { (n, t) -> + n to t + .map { + it.matchInfo + } + .reduce { acc, info -> + MatchInfo( + distanceWeight = listOf(acc.distanceWeight, info.distanceWeight).average().toFloat(), + isRequired = acc.isRequired || info.isRequired + ) + } + }.toMap() + return durabilityTraits to matchInfo + } + + override fun apply( + res: Pair, Map>, + resourceManager: ResourceManager, + profiler: ProfilerFiller + ) { + durabilityTraits = res.first + matchInfo = res.second + } + } + + private val RELOAD_LISTENER_REGISTER_ITEMS = ResourceLocation.fromNamespaceAndPath( + APRandomizer.MODID, "register_items" + ) + + private fun getRegisterItemsReloadListener(recipeManager: RecipeManager) = + object : SimplePreparableReloadListener() { + override fun prepare( + resourceManager: ResourceManager, + profiler: ProfilerFiller + ) { + + } + + override fun apply( + res: Unit, + resourceManager: ResourceManager, + profiler: ProfilerFiller + ) { + registerAllMinecraftGifts( + this.context.enabledFeatures(), + this.context.registryAccess(), + recipeManager + ) + } + } + + fun registerReloadListeners( + manager: AddServerReloadListenersEvent + ) { + manager.addListener(RELOAD_LISTENER_TRAITS_CONFIG, traitsConfigReloadListener) +// manager.addListener(RELOAD_LISTENER_REGISTER_ITEMS, +// getRegisterItemsReloadListener(manager.serverResources.recipeManager) +// ) +// manager.addDependency(RELOAD_LISTENER_TRAITS_CONFIG, RELOAD_LISTENER_REGISTER_ITEMS) +// manager.addDependency(VanillaServerListeners.LAST, RELOAD_LISTENER_REGISTER_ITEMS) +// manager.addDependency(NeoForgeReloadListeners.RECIPE_PRIORITIES, RELOAD_LISTENER_REGISTER_ITEMS) + } + + + context(traitLookup: HolderLookup.RegistryLookup) + fun resolveGift(traits: List, recipeManager: RecipeManager): ItemStack? { + val closest: List = treeParser.findClosestAvailableGift(traits) + closest.random( + Random( + closest.hashCode() + randomSeed + ) + ) + val item = closest.getOrNull(0) ?: return null + println("Closest item found: $closest: ${getItemStackTraits(item, recipeManager)}") + val durableTraits = traits.filter { durabilityTraits.contains(it.name) } + if (durableTraits.isNotEmpty() && item.isDamageableItem) { + // set the damage value based on the average duration of the durability traits + val averageDurability = durableTraits.map { it.duration }.average().toInt() + item.damageValue = averageDurability - (averageDurability * item.maxDamage) + } + return item + } + +} + + +private const val averageDurability = 250f + + +fun potionDurationToTraitDuration(duration: Int): Float { + return if (duration < 0) -1f else (duration.toFloat() / 20f) / 180f // 3 min is standard potion duration +} + +context(traitLookup: HolderLookup.RegistryLookup) private fun modifierToTraits(modifier: ItemAttributeModifiers.Entry): Pair, ComponentValues> = + traitSourceScope(GiftTraitSource.ATTRIBUTE_MODIFIERS) { + return when (modifier.attribute) { + Attributes.ATTACK_DAMAGE -> KnownTraits.Damage.with( + quality = scaleQuality( + modifier.attribute.value(), + modifier.modifier, + 6.0, + ).toFloat() + ).let { + listOf(it) to ComponentValues( + attackDamage = it.quality, + ) + } + + Attributes.ATTACK_SPEED -> { + ExtraTraits.AttackSpeed.with( + quality = scaleQuality( + modifier.attribute.value(), + modifier.modifier, + 4.0, + ).toFloat() + ).let { + listOf(it) to ComponentValues( + attackSpeed = it.quality, + ) + } + } + + Attributes.MOVEMENT_SPEED -> listOf( + KnownTraits.Speed.with( + quality = scaleQuality(modifier.attribute.value(), modifier.modifier).toFloat() + ), + ) to ComponentValues() + + Attributes.MAX_HEALTH, Attributes.MAX_ABSORPTION -> listOf( + KnownTraits.Life.with( + quality = scaleQuality(modifier.attribute.value(), modifier.modifier).toFloat() + ), + ) to ComponentValues() + + Attributes.ARMOR -> KnownTraits.Armor.with( + quality = scaleQuality( + modifier.attribute.value(), modifier.modifier + ).toFloat() + ).let { + listOf(it) to ComponentValues( + armor = it.quality, + ) + } + + Attributes.ARMOR_TOUGHNESS -> ExtraTraits.ArmorToughness.with( + quality = scaleQuality( + modifier.attribute.value(), modifier.modifier + ).toFloat() + ).let { + listOf(it) to ComponentValues( + armorToughness = it.quality, + ) + } + + else -> emptyList() to ComponentValues() + } + } + + +private fun effectTraits(effect: Holder): List> { + return when (effect) { + MobEffects.SPEED -> listOf(KnownTraits.Speed) + MobEffects.SLOWNESS -> listOf(KnownTraits.Slowness) + MobEffects.HASTE -> listOf(ExtraTraits.Haste) + MobEffects.MINING_FATIGUE -> listOf(ExtraTraits.MiningFatigue) + MobEffects.STRENGTH -> listOf(ExtraTraits.Strength) + MobEffects.INSTANT_HEALTH -> listOf(KnownTraits.Heal) + MobEffects.INSTANT_DAMAGE -> listOf(KnownTraits.Damage) + MobEffects.JUMP_BOOST -> listOf(ExtraTraits.JumpBoost) + MobEffects.NAUSEA -> listOf(ExtraTraits.Nausea) + MobEffects.REGENERATION -> listOf(KnownTraits.Heal) + MobEffects.RESISTANCE -> listOf(KnownTraits.Defense) + MobEffects.FIRE_RESISTANCE -> listOf(KnownTraits.Defense, KnownTraits.Fire) + MobEffects.WATER_BREATHING -> listOf(ExtraTraits.WaterBreathing, KnownTraits.Water) + MobEffects.INVISIBILITY -> listOf(ExtraTraits.Invisibility) + MobEffects.BLINDNESS -> listOf(ExtraTraits.Blindness) + MobEffects.NIGHT_VISION -> listOf(ExtraTraits.NightVision) + MobEffects.HUNGER -> listOf(ExtraTraits.Hunger) + MobEffects.WEAKNESS -> listOf(ExtraTraits.Weakness) + MobEffects.POISON -> listOf(KnownTraits.Poison) + MobEffects.WITHER -> listOf(KnownTraits.Poison, ExtraTraits.Wither) + MobEffects.HEALTH_BOOST -> listOf(KnownTraits.Life) + MobEffects.ABSORPTION -> listOf(KnownTraits.Life) + MobEffects.SATURATION -> listOf(KnownTraits.Food) + MobEffects.GLOWING -> listOf(KnownTraits.Light) + MobEffects.LEVITATION -> listOf(KnownTraits.Flight) + MobEffects.LUCK -> listOf(KnownTraits.Luck) + MobEffects.UNLUCK -> listOf(KnownTraits.Unluck) + MobEffects.SLOW_FALLING -> listOf(ExtraTraits.SlowFalling, KnownTraits.Flight) + MobEffects.CONDUIT_POWER -> listOf( + KnownTraits.Ocean, KnownTraits.Water, ExtraTraits.NightVision, ExtraTraits.WaterBreathing + ) + + MobEffects.DOLPHINS_GRACE -> listOf( + KnownTraits.Ocean, KnownTraits.Water, KnownTraits.Speed + ) + + MobEffects.BAD_OMEN -> listOf(ExtraTraits.Ominous, KnownTraits.Trap) + MobEffects.HERO_OF_THE_VILLAGE -> listOf(KnownTraits.Currency) + else -> emptyList() + } +} + +//todo datamap +context(_: HolderLookup.RegistryLookup) private fun mobEffectsTraits( + effects: Iterable, source: GiftTraitSource +): List = traitSourceScope(source) { + return effects.flatMap { + effectTraits(it.effect).map { n -> + n.with(quality = it.amplifier.toFloat() + 1, duration = potionDurationToTraitDuration(it.duration)) + + } + when (it.effect.value().category) { + MobEffectCategory.BENEFICIAL -> listOf( + KnownTraits.Buff.with( + quality = it.amplifier.toFloat(), duration = potionDurationToTraitDuration(it.duration) + ) + ) + + MobEffectCategory.HARMFUL -> listOf( + KnownTraits.Trap.with( + quality = it.amplifier.toFloat(), duration = potionDurationToTraitDuration(it.duration) + ) + ) + + MobEffectCategory.NEUTRAL -> emptyList() + } + } +} + +private fun applyOperation(attribute: Double, value: AttributeModifier): Double { + return when (value.operation) { + AttributeModifier.Operation.ADD_VALUE -> attribute + value.amount + AttributeModifier.Operation.ADD_MULTIPLIED_TOTAL -> attribute * (1 + value.amount) + AttributeModifier.Operation.ADD_MULTIPLIED_BASE -> attribute * (1 + value.amount) + } +} + +private fun scaleQuality( + attribute: Attribute, value: AttributeModifier, base: Double = attribute.defaultValue +): Double { + return when (attribute) { + is PercentageAttribute -> (applyOperation(attribute.defaultValue, value) / base) + is RangedAttribute -> (applyOperation(attribute.defaultValue, value) / base) + is BooleanAttribute -> value.amount + else -> error("unreachable") + } +} + +context(lookup: HolderLookup.RegistryLookup) private fun componentTraits(component: TypedDataComponent<*>): Pair, ComponentValues> = + traitSourceScope(GiftTraitSource.ITEM_COMPONENTS) { + return when (component.type) { + // enchantment are handled in updateEquipmentTraitValues + DataComponents.CONSUMABLE -> { + val data = component.value as Consumable + return listOf(KnownTraits.Consumable.with()) + data.onConsumeEffects.flatMap { + when (it) { + is ApplyStatusEffectsConsumeEffect -> mobEffectsTraits( + it.effects, GiftTraitSource.ITEM_COMPONENTS + ) + + is ClearAllStatusEffectsConsumeEffect -> listOf(KnownTraits.Cure.with()) + is TeleportRandomlyConsumeEffect -> listOf(KnownTraits.Teleport.with()) + is RemoveStatusEffectsConsumeEffect -> listOf() //todo ? + is PlaySoundConsumeEffect -> listOf() //todo ? + else -> error("unreachable") + } + } + when (data.animation) { + ItemUseAnimation.EAT -> listOf(KnownTraits.Food.with()) + ItemUseAnimation.DRINK -> listOf(KnownTraits.Drink.with()) + else -> emptyList() + } to ComponentValues() + } + + DataComponents.RARITY -> when (component.value as Rarity) { + Rarity.COMMON -> emptyList() + Rarity.UNCOMMON -> emptyList() + Rarity.RARE -> emptyList() + Rarity.EPIC -> listOf(KnownTraits.Legendary.with()) + } to ComponentValues() + + DataComponents.SUSPICIOUS_STEW_EFFECTS -> listOf( + ExtraTraits.Suspicious.with(), + KnownTraits.Random.with(), + KnownTraits.Food.with(quality = 0.1f), + KnownTraits.Buff.with(quality = 0.5f), + KnownTraits.Trap.with(quality = 0.5f) + ) to ComponentValues() + + DataComponents.TOOL -> { + val data = component.value as Tool + val qual = (listOf(data.defaultMiningSpeed) + data.rules.map { + it.speed.orElse( + 0f + ) + }).maxOrNull() ?: 0f + listOf(KnownTraits.Tool.with(quality = qual)) to ComponentValues() + } + + DataComponents.WEAPON -> listOf(KnownTraits.Weapon.with()) to ComponentValues() + DataComponents.FOOD -> listOf(KnownTraits.Food.with(quality = (component.value as FoodProperties).nutrition() / 3f)) to ComponentValues() + + DataComponents.EQUIPPABLE -> { + val slot = (component.value as Equippable).slot + when (slot) { + EquipmentSlot.FEET, EquipmentSlot.LEGS, EquipmentSlot.CHEST, EquipmentSlot.BODY, EquipmentSlot.HEAD -> listOf( + KnownTraits.Armor.with() + ) + + EquipmentSlot.SADDLE -> listOf(ExtraTraits.Saddle.with()) + else -> emptyList() + } + if (slot == EquipmentSlot.HEAD) { + listOf(KnownTraits.Head.with()) + } else { + emptyList() + } to ComponentValues() + } + + DataComponents.POTION_CONTENTS -> mobEffectsTraits( + (component.value as PotionContents).allEffects, GiftTraitSource.ITEM_COMPONENTS + ) to ComponentValues() + + DataComponents.DEATH_PROTECTION -> listOf( + KnownTraits.Life.with(quality = 10f), + KnownTraits.Buff.with(quality = 10f), + KnownTraits.Invincible.with(duration = 0.1f), + ) to ComponentValues() + + DataComponents.BUNDLE_CONTENTS -> listOf(KnownTraits.Container.with()) to ComponentValues() + DataComponents.CONTAINER -> listOf(KnownTraits.Container.with()) to ComponentValues() + + DataComponents.ATTRIBUTE_MODIFIERS -> (component.value as ItemAttributeModifiers).modifiers.map { + modifierToTraits(it) + } + .ifEmpty { + listOf(emptyList() to ComponentValues()) + } + .reduce { (acct, accv), (t, v) -> + (acct + t) to ComponentValues( + attackDamage = listOfNotNull(accv.attackDamage, v.attackDamage).maxOrNull(), + attackSpeed = listOfNotNull(accv.attackSpeed, v.attackSpeed).maxOrNull(), + armor = listOfNotNull(accv.armor, v.armor).maxOrNull(), + armorToughness = listOfNotNull(accv.armorToughness, v.armorToughness).maxOrNull(), + ) + } + + else -> return emptyList() to ComponentValues() + } + } + + +context(_: HolderLookup.RegistryLookup) private fun derivedTraits(traits: List): List = + traitSourceScope(GiftTraitSource.DERIVED_TRAITS) { + val derived = mutableListOf() + if (traits.none { it.definition.`is`(EQUIPMENT_TRAITS) }) { + // if no traits are from object with usage, add a resource trait + //todo configurable + derived.add(KnownTraits.Resource.with(quality = 0.1f)) + } + + return derived + } + +data class ComponentValues( + val attackDamage: Float? = null, + val attackSpeed: Float? = null, + val armor: Float? = null, + val armorToughness: Float? = null, +) + +context(_: HolderLookup.RegistryLookup) private fun updateEquipmentTraitValues( + itemStack: ItemStack, traits: List, componentValues: ComponentValues + +): List { + fun Map.getScaled(vararg scalePairs: Pair): List = + scalePairs.map { (k, v) -> this[k]?.toFloat()?.times(v) ?: 1f } + + + val enchantments = itemStack.components.find { it.type == DataComponents.ENCHANTMENTS } + ?.let { (it.value as ItemEnchantments).entrySet() }?.associate { (h, l) -> h.key to l }.orEmpty() + + val attackDamage = componentValues.attackDamage + //todo datamap for enchantment values + val damageEnchantmentValue = enchantments.getScaled( + Enchantments.SHARPNESS to 0.8f, + Enchantments.POWER to 0.8f, + Enchantments.FIRE_ASPECT to 0.5f, + Enchantments.FLAME to 0.5f, + Enchantments.IMPALING to 0.4f, + Enchantments.PIERCING to 0.4f, + Enchantments.KNOCKBACK to 0.2f, + Enchantments.PUNCH to 0.2f, + Enchantments.BANE_OF_ARTHROPODS to 0.2f, + Enchantments.SMITE to 0.2f, + ).sum() + val attackSpeed = componentValues.attackSpeed + val armor = componentValues.armor + val armorToughness = componentValues.armorToughness + val armorEnchantValue = enchantments.getScaled( + Enchantments.PROTECTION to 1f, + Enchantments.PROJECTILE_PROTECTION to 0.8f, + Enchantments.BLAST_PROTECTION to 0.5f, + Enchantments.FIRE_PROTECTION to 0.5f, + Enchantments.FEATHER_FALLING to 0.65f + ).sum() + val toolValue = enchantments.getScaled( + Enchantments.EFFICIENCY to 1f, + Enchantments.FORTUNE to 0.8f, + Enchantments.LOOTING to 0.8f, + Enchantments.LURE to 0.5f, + ).sum() + val mendingMultiplier = if (enchantments.containsKey(Enchantments.MENDING)) 1.5f else 1f + val infinityMultiplier = if (enchantments.containsKey(Enchantments.INFINITY)) 1.2f else 1f + val thornsValue = enchantments[Enchantments.THORNS]?.times(0.5f) + + val normalizedItemStackDurability = + (averageDurability - itemStack.damageValue) / (averageDurability) * mendingMultiplier * infinityMultiplier + val weaponValue = (attackSpeed ?: 1f) * (attackDamage ?: 1f) * (1 + damageEnchantmentValue) + val toughnessBonus = armorToughness?.div(20f) ?: 0f + val armorValue = armor?.times(toughnessBonus.plus(1))?.times((1 + armorEnchantValue)) ?: 0f + + val maybeDura = + if (traits.none { it.definition.value().duration is Duration.ItemDurability } && itemStack.isDamageableItem) { + listOf( + KnownTraits.Tool.with( + duration = normalizedItemStackDurability, quality = 0.1f, source = GiftTraitSource.ITEM_COMPONENTS + ) + ) + } else emptyList() + + val mapped = traits.flatMap { trait -> + when (val d = trait.definition.value().duration) { + is Duration.ItemDurability -> listOf( + trait.copy( + source = GiftTraitSource.ITEM_COMPONENTS, + duration = normalizedItemStackDurability * d.multiplier, + ) + ) + + null -> listOf(trait) + } + }.flatMap { trait -> + if (trait.definition.key == KnownTraits.Armor && thornsValue != null) { + //todo config option + listOf(trait, KnownTraits.Damage.with(quality = thornsValue, source = GiftTraitSource.ITEM_COMPONENTS)) + } else listOf(trait) + }.map { trait -> + when (val q = trait.definition.value().quality) { + is Quality.ArmorQuality -> trait.copy(quality = armorValue * q.multiplier) + is Quality.WeaponValue -> trait.copy(quality = weaponValue * q.multiplier) + is Quality.ToolEfficiency -> trait.copy(quality = (trait.quality ?: 0f) * ((1 + toolValue)) * q.multiplier) + null -> trait + } + } + return mapped + maybeDura +} + +private fun mergeDuplicateTraits(traits: List): List { + + fun reduceValue(values: List>): Float? { + return values.groupBy { it.first }.map { (s, v) -> s to v.map { it.second } }.map { (source, vals) -> + val min = vals.filterNotNull().minOrNull() + val max = vals.filterNotNull().maxOrNull() + val avg = vals.filterNotNull().average().toFloat().takeUnless { it.isNaN() } + source to when (source) { + GiftTraitSource.CRAFTING -> min + GiftTraitSource.ITEM_COMPONENTS -> max + GiftTraitSource.ITEM_SPECIFIC -> max + GiftTraitSource.CAPABILITIES -> min + GiftTraitSource.DERIVED_TRAITS -> avg + GiftTraitSource.ATTRIBUTE_MODIFIERS -> max + GiftTraitSource.FLUID_COMPONENTS -> max + GiftTraitSource.FLUID_SPECIFIC -> max + GiftTraitSource.MERGED -> max + } + }.reduce { left, right -> + if (left.first.priority > right.first.priority) { + left + } else if (left.first.priority < right.first.priority) { + right + } else { + // if both sources have the same priority, take the average value + left.first to listOfNotNull(left.second, right.second) + .average() + .toFloat() + .takeIf { !it.isNaN() } + } + }.second + } + + return traits.groupBy { it.definition }.map { (def, traits) -> + GiftTraitWrapper( + definition = def, + source = GiftTraitSource.MERGED, + quality = reduceValue(traits.map { it.source to it.quality }), + duration = reduceValue(traits.map { it.source to it.duration }) + ) + } +} + + +const val COAL_BURN_TIME = 16000 + +context(lookup: HolderLookup.RegistryLookup) private fun itemTraits( + item: Item, craftingTraitsHolder: CraftingTraitsHolder, recipeManager: RecipeManager +): List = traitSourceScope(GiftTraitSource.ITEM_SPECIFIC) { + val baseTraits = BuiltInRegistries.ITEM.getDataMap(APDataMaps.ITEMS_GIFTS_BASE_TRAITS).getOrDefault( + BuiltInRegistries.ITEM.wrapAsHolder(item).key!!, TraitData.EMPTY + ) + val fuelValue: FurnaceFuel? = BuiltInRegistries.ITEM.getDataMap(NeoForgeDataMaps.FURNACE_FUELS) + .getOrDefault(BuiltInRegistries.ITEM.wrapAsHolder(item).key!!, null) + + + baseTraits.wrapped(GiftTraitSource.ITEM_SPECIFIC) + fuelValue?.let { listOf(KnownTraits.Fuel.with(it.burnTime.toFloat() / COAL_BURN_TIME)) } + .orEmpty() + craftingTraitsHolder.resolveTraits(item, recipeManager) +} + +context(lookup: HolderLookup.RegistryLookup) private fun itemStackTraits( + stack: ItemStack, craftingTraitsHolder: CraftingTraitsHolder, recipeManager: RecipeManager +): List { + val item = stack.item + val (componentTraits, componentValues) = stack.components.map { componentTraits(it) }.ifEmpty { + listOf(emptyList() to ComponentValues()) + } + .reduce { (acct, accv), (t, v) -> + Pair( + acct + t, ComponentValues( + attackDamage = listOfNotNull(accv.attackDamage, v.attackDamage).maxOrNull(), + attackSpeed = listOfNotNull(accv.attackSpeed, v.attackSpeed).maxOrNull(), + armor = listOfNotNull(accv.armor, v.armor).maxOrNull(), + armorToughness = listOfNotNull(accv.armorToughness, v.armorToughness).maxOrNull(), + ) + ) + } + val baseTraits = listOf( + componentTraits, + itemTraits(item, craftingTraitsHolder, recipeManager), + capabilitiesTraits(stack, craftingTraitsHolder, recipeManager), + stack.takeIf { it.nextDamageWillBreak() || it.isBroken }?.let { + listOf(KnownTraits.Broken.with(GiftTraitSource.ITEM_COMPONENTS)) + }.orEmpty(), + ).flatten() + + + val traits = updateEquipmentTraitValues(stack, baseTraits, componentValues) + derivedTraits(baseTraits) + val merged = mergeDuplicateTraits( + traits + ) + val finalTraitInfo = BuiltInRegistries.ITEM.wrapAsHolder(item) + .getData(APDataMaps.ITEMS_GIFTS_FINAL_TRAITS) ?: FinalTraitData.EMPTY + + + val withFinal = merged.filterNot { + finalTraitInfo.removed.contains(it.definition) + } + finalTraitInfo.traits.map { (k, v) -> + GiftTraitWrapper( + source = GiftTraitSource.ITEM_SPECIFIC, + definition = k, + quality = v.quality, + duration = v.duration + ) + } + + return withFinal +} + + +context(_: HolderLookup.RegistryLookup) private fun fluidTraits(stack: FluidStack) = + stack.components.flatMap { componentTraits(it).first.map { it.copy(source = GiftTraitSource.FLUID_COMPONENTS) } } + (stack.fluidHolder.getData( + APDataMaps.FLUIDS_GIFTS_TRAITS + ) ?: TraitData.EMPTY).wrapped(GiftTraitSource.FLUID_SPECIFIC) + + +context(_: HolderLookup.RegistryLookup) private fun capabilitiesTraits( + item: ItemStack, craftingTraitsHolder: CraftingTraitsHolder, recipeManager: RecipeManager +): List = traitSourceScope(GiftTraitSource.CAPABILITIES) { + val traits = mutableListOf() + if (item.getCapability(Capabilities.ItemHandler.ITEM) != null) { + traits.add(KnownTraits.Container.with()) + } + val fluidcap = item.getCapability(Capabilities.FluidHandler.ITEM) + if (fluidcap != null) { + traits.add(KnownTraits.Container.with()) + traits.add(KnownTraits.LiquidContainer.with()) + val fls = (0..fluidcap.tanks).map { fluidcap.getFluidInTank(it) } + fls.filter { it.fluid != Fluids.EMPTY }.forEach { fluid -> + traits.addAll(fluidTraits(fluid).map { trait -> + if (trait.quality != null) trait.copy(quality = trait.quality * (fluid.amount / 1000f)) + else trait + }) + } + + val copied = item.copy() + val capability = copied.getCapability(Capabilities.FluidHandler.ITEM) + for (i in 0 until capability!!.tanks) { + val fluidInTank = capability.getFluidInTank(i) + if (fluidInTank.isEmpty) continue + capability.drain(fluidInTank.copyWithAmount(Int.MAX_VALUE), IFluidHandler.FluidAction.EXECUTE); + } + val itemWithoutFluid = capability.container + if (itemWithoutFluid.item != item.item) { + // add all traits that weren't already present + val resolveItemTraits: List = itemStackTraits( + itemWithoutFluid, craftingTraitsHolder, + recipeManager + ) + traits.addAll(resolveItemTraits) + } + } else if (item.item == Items.MILK_BUCKET && !NeoForgeMod.MILK.isBound) { + // if no mods adds a milk fluid + itemStackTraits(ItemStack(Items.BUCKET, 1), craftingTraitsHolder, recipeManager).forEach { trait -> + traits.add(trait) + } + traits.add(KnownTraits.Milk.with()) + } else if (item.item == Items.POWDER_SNOW_BUCKET) { + // if no mods have powder snow fluid + itemStackTraits(ItemStack(Items.BUCKET, 1), craftingTraitsHolder, recipeManager).forEach { trait -> + traits.add(trait) + } + traits.add(KnownTraits.Ice.with()) + } + val energyCap = item.getCapability(Capabilities.EnergyStorage.ITEM) + if (energyCap != null) { + traits.add(KnownTraits.Energy.with(quality = energyCap.energyStored / 1000f)) + } + return traits +} + + diff --git a/src/main/kotlin/gg/archipelago/aprandomizer/gifting/TraitsDataMap.kt b/src/main/kotlin/gg/archipelago/aprandomizer/gifting/TraitsDataMap.kt new file mode 100644 index 0000000..4edd0f0 --- /dev/null +++ b/src/main/kotlin/gg/archipelago/aprandomizer/gifting/TraitsDataMap.kt @@ -0,0 +1,447 @@ +package gg.archipelago.aprandomizer.gifting + +import com.mojang.datafixers.util.Either +import com.mojang.serialization.Codec +import com.mojang.serialization.DataResult +import com.mojang.serialization.MapCodec +import com.mojang.serialization.codecs.RecordCodecBuilder +import gg.archipelago.aprandomizer.APRegistries +import net.leloubil.archipelago.gifting.remote.GiftTraitName +import net.minecraft.core.Holder +import net.minecraft.core.HolderSet +import net.minecraft.core.Registry +import net.minecraft.core.RegistryCodecs +import net.minecraft.core.registries.BuiltInRegistries +import net.minecraft.core.registries.Registries.RECIPE_TYPE +import net.minecraft.data.worldgen.BootstrapContext +import net.minecraft.resources.RegistryFixedCodec +import net.minecraft.resources.ResourceKey +import net.minecraft.tags.TagKey +import net.minecraft.util.StringRepresentable +import net.minecraft.world.item.crafting.RecipeType +import net.neoforged.neoforge.registries.datamaps.DataMapValueMerger +import net.neoforged.neoforge.registries.datamaps.DataMapValueRemover +import java.util.* +import kotlin.jvm.optionals.getOrNull + + +data class GiftTraitData( + val quality: Float?, val duration: Float? +) { + + companion object { + val CODEC: Codec = RecordCodecBuilder.create { instance -> + instance.group( + Codec.FLOAT.optionalFieldOf("quality").forGetter { Optional.ofNullable(it.quality) }, + Codec.FLOAT.optionalFieldOf("duration").forGetter { Optional.ofNullable(it.duration) }, + ).apply(instance) { a, b -> GiftTraitData(a.getOrNull(), b.getOrNull()) } + } + } +} + + +sealed interface Duration { + enum class DurationType(val id: String) : StringRepresentable { + ITEM_DURABILITY("item_durability"); + + override fun getSerializedName(): String = id + + companion object { + val CODEC: Codec = StringRepresentable.fromEnum(DurationType::values) + } + + } + + val type: DurationType + + data class ItemDurability(val multiplier: Float = 1f) : Duration { + companion object { + val CODEC: MapCodec = RecordCodecBuilder.mapCodec { + it.group( + Codec.FLOAT.fieldOf("multiplier").forGetter(ItemDurability::multiplier) + ).apply(it, ::ItemDurability) + } + } + + override val type = DurationType.ITEM_DURABILITY + } + + companion object { + val CODEC: Codec = DurationType.CODEC.dispatch(Duration::type) { + when (it) { + DurationType.ITEM_DURABILITY -> ItemDurability.CODEC + } + } + } + +} + +sealed interface Quality { + enum class QualityType(val id: String) : StringRepresentable { + TOOL_EFFICIENCY("tool_efficiency"), DAMAGE("damage"), + ARMOR("armor"); + + override fun getSerializedName(): String = id + + companion object { + val CODEC: Codec = StringRepresentable.fromEnum(QualityType::values) + } + } + + val type: QualityType + + data class ToolEfficiency(val multiplier: Float = 1f) : Quality { + companion object { + val CODEC: MapCodec = RecordCodecBuilder.mapCodec { + it.group( + Codec.FLOAT.fieldOf("multiplier").forGetter(ToolEfficiency::multiplier) + ).apply(it, ::ToolEfficiency) + } + } + + override val type = QualityType.TOOL_EFFICIENCY + } + + data class WeaponValue(val multiplier: Float = 1f) : Quality { + companion object { + val CODEC: MapCodec = RecordCodecBuilder.mapCodec { + it.group( + Codec.FLOAT.fieldOf("multiplier").forGetter(WeaponValue::multiplier) + ).apply(it, ::WeaponValue) + } + } + + override val type = QualityType.DAMAGE + } + + data class ArmorQuality( + val multiplier: Float = 1f, + ) : Quality { + companion object { + val CODEC: MapCodec = RecordCodecBuilder.mapCodec { + it.group( + Codec.FLOAT.fieldOf("multiplier").forGetter(ArmorQuality::multiplier) + ).apply(it, ::ArmorQuality) + } + } + + override val type = QualityType.ARMOR + } + + companion object { + val CODEC: Codec = QualityType.CODEC.dispatch(Quality::type) { + when (it) { + QualityType.TOOL_EFFICIENCY -> ToolEfficiency.CODEC + QualityType.DAMAGE -> WeaponValue.CODEC + QualityType.ARMOR -> ArmorQuality.CODEC + } + } + } +} + +data class CraftingInheritance( + val maxQuality: Float? = null, + val minQuality: Float? = null, + val maxDuration: Float? = null, + val minDuration: Float? = null, + val qualityKeptMultiplier: Float = DEFAULT_QUALITY_KEPT_MULTIPLIER, + val durationKeptMultiplier: Float = DEFAULT_DURATION_KEPT_MULTIPLIER, + val qualityThreshold: Float = DEFAULT_QUALITY_THRESHOLD, + val inheritanceDefaultQuality: Float = DEFAULT_INHERITANCE_DEFAULT_QUALITY, + val inheritanceDefaultDuration: Float = DEFAULT_INHERITANCE_DEFAULT_DURATION +) { + + companion object { + private const val DEFAULT_QUALITY_KEPT_MULTIPLIER: Float = 1f + private const val DEFAULT_DURATION_KEPT_MULTIPLIER: Float = 1f + private const val DEFAULT_QUALITY_THRESHOLD: Float = 0.01f + private const val DEFAULT_INHERITANCE_DEFAULT_QUALITY: Float = 0.01f + private const val DEFAULT_INHERITANCE_DEFAULT_DURATION: Float = 0f + val CODEC: Codec = RecordCodecBuilder.create { instance -> + instance.group( + Codec.FLOAT.optionalFieldOf("max_quality") + .forGetter { Optional.ofNullable(it.maxQuality) }, + Codec.FLOAT.optionalFieldOf("min_quality") + .forGetter { Optional.ofNullable(it.minQuality) }, + Codec.FLOAT.optionalFieldOf("max_duration") + .forGetter { Optional.ofNullable(it.maxDuration) }, + Codec.FLOAT.optionalFieldOf("min_duration") + .forGetter { Optional.ofNullable(it.minDuration) }, + Codec.FLOAT.optionalFieldOf("quality_kept_multiplier", DEFAULT_QUALITY_KEPT_MULTIPLIER) + .forGetter { it.qualityKeptMultiplier }, + Codec.FLOAT.optionalFieldOf("duration_kept_multiplier", DEFAULT_DURATION_KEPT_MULTIPLIER) + .forGetter { it.durationKeptMultiplier }, + Codec.FLOAT.optionalFieldOf("quality_threshold", DEFAULT_QUALITY_THRESHOLD) + .forGetter { it.qualityThreshold }, + Codec.FLOAT.optionalFieldOf("inheritance_default_value", DEFAULT_INHERITANCE_DEFAULT_QUALITY) + .forGetter { it.inheritanceDefaultQuality }, + Codec.FLOAT.optionalFieldOf("inheritance_default_duration", DEFAULT_INHERITANCE_DEFAULT_DURATION) + .forGetter { it.inheritanceDefaultDuration } + ).apply(instance) { maxQ, minQ, maxD, minD, qKept, dKept, qTreshold, idf, idfd -> + CraftingInheritance( + maxQuality = maxQ.getOrNull(), + minQuality = minQ.getOrNull(), + maxDuration = maxD.getOrNull(), + minDuration = minD.getOrNull(), + qualityKeptMultiplier = qKept, + durationKeptMultiplier = dKept, + qualityThreshold = qTreshold, + inheritanceDefaultQuality = idf, + inheritanceDefaultDuration = idfd + ) + } + + } + } +} + +data class MatchInfo( + val distanceWeight: Float, + val isRequired: Boolean, +) { + companion object { + val CODEC: Codec = RecordCodecBuilder.create { instance -> + instance.group( + Codec.FLOAT.optionalFieldOf("distance_weight", 1f) + .forGetter { it.distanceWeight }, + Codec.BOOL.optionalFieldOf("is_required", false) + .forGetter { it.isRequired } + ).apply(instance) { d, r -> + MatchInfo( + distanceWeight = d, + isRequired = r + ) + } + } + } +} + +// Not a data class since instances are meant to be unique, even if they have the same data +class GiftTraitDefinition( + val name: GiftTraitName, + val craftingInheritance: Map, CraftingInheritance>, + val matchInfo: MatchInfo, + val quality: Quality? = null, + val duration: Duration? = null, +) { + + + fun copy( + strName: String = name.name, + craftingInheritance: Map, CraftingInheritance>? = this.craftingInheritance, + matchInfo: MatchInfo = this.matchInfo, + quality: Quality? = this.quality, + duration: Duration? = this.duration + ): GiftTraitDefinition { + return GiftTraitDefinition( + strName, matchInfo, craftingInheritance, quality, duration + ) + } + + + companion object { + + @JvmStatic + @JvmName("create") + operator fun invoke( + name: String, + matchInfo: MatchInfo, + craftingInheritance: Map, CraftingInheritance>? = null, + quality: Quality? = null, + duration: Duration? = null + ): GiftTraitDefinition = GiftTraitDefinition( + GiftTraitName(name), craftingInheritance ?: emptyMap(), + matchInfo, + quality, + duration + ) + + @JvmField + val CODEC: Codec = RecordCodecBuilder.create { builder -> + builder.group( + GIFT_TRAIT_NAME_CODEC.fieldOf("name") + .forGetter { it.name }, + Codec.simpleMap( + ResourceKey.codec(RECIPE_TYPE), + CraftingInheritance.CODEC, + BuiltInRegistries.RECIPE_TYPE + ).xmap({ + it.mapKeys { (k, _) -> BuiltInRegistries.RECIPE_TYPE.getValueOrThrow(k) } + }, { + it.mapKeys { (k, _) -> BuiltInRegistries.RECIPE_TYPE.wrapAsHolder(k).key } + }) + .codec().optionalFieldOf("craft_inheritance") + .forGetter { Optional.ofNullable(it.craftingInheritance) }, + MatchInfo.CODEC.optionalFieldOf("matching", MatchInfo(1f, false)) + .forGetter { it.matchInfo }, + Quality.CODEC.optionalFieldOf("quality") + .forGetter { Optional.ofNullable(it.quality) }, + Duration.CODEC.optionalFieldOf("duration") + .forGetter { Optional.ofNullable(it.duration) }) + .apply(builder) { n, c, di, q, d -> + GiftTraitDefinition( + n.name, + di, + c.getOrNull(), + q.getOrNull(), + d.getOrNull() + ) + } + } + + @JvmStatic + fun bootstrap(context: BootstrapContext) { + KnownTraits.bootstrap(context) + ExtraTraits.bootstrap(context) + } + } + +} + +val GIFT_TRAIT_NAME_CODEC: Codec = Codec.STRING.validate { + if (it.contains(' ')) { + return@validate DataResult.error { "Trait name should not contain spaces" } + } + if (!(it.first().isUpperCase())) { + return@validate DataResult.error { "Trait name should be in PascalCase" } + } + return@validate DataResult.success(it) +}.xmap({ GiftTraitName(it) }) { it.name } + +data class TraitData(val traits: Map, GiftTraitData>) { + constructor(vararg traits: Pair, GiftTraitData>) : + this(traits.toMap()) + + constructor(vararg traits: Holder) + : this(traits.associateWith { GiftTraitData(null, null) }) + + companion object { + val EMPTY: TraitData = TraitData(emptyMap()) + + @JvmField + val CODEC: Codec = Codec.unboundedMap( + RegistryFixedCodec.create(APRegistries.GIFT_TRAITS), GiftTraitData.CODEC + ).xmap({ TraitData(it) }) { it.traits } + } +} + +data class FinalGiftTraitData( + val quality: Float, val duration: Float +) { + companion object { + val CODEC: Codec = RecordCodecBuilder.create { instance -> + instance.group( + Codec.FLOAT.optionalFieldOf("quality", 1f).forGetter { it.quality }, + Codec.FLOAT.optionalFieldOf("duration", 1f).forGetter { it.duration }, + ).apply(instance) { a, b -> FinalGiftTraitData(a, b) } + } + } +} + +data class FinalTraitData( + val traits: Map, FinalGiftTraitData>, + val removed: List> = emptyList() +) { + + companion object { + val EMPTY: FinalTraitData = FinalTraitData(emptyMap()) + + @JvmField + val CODEC: Codec = Codec.unboundedMap( + RegistryFixedCodec.create(APRegistries.GIFT_TRAITS), FinalGiftTraitData.CODEC + ).xmap({ FinalTraitData(it) }) { it.traits } + } +} + +class FinalDataGiftTraitsMerger : DataMapValueMerger { + override fun merge( + registry: Registry, + first: Either, ResourceKey>, + firstData: FinalTraitData, + second: Either, ResourceKey>, + secondData: FinalTraitData + ): FinalTraitData { + val added = firstData.traits.keys.union(secondData.traits.keys).associateWith { k -> + val secondTrait = secondData.traits[k] + val firstTrait = firstData.traits[k] + FinalGiftTraitData( + quality = secondTrait?.quality ?: firstTrait?.quality ?: 1f, + duration = secondTrait?.duration ?: firstTrait?.duration ?: 1f + ) + } + return FinalTraitData( + added, + removed = (firstData.removed.filter { !secondData.traits.keys.contains(it) }) + + (secondData.removed) + ) + } + +} + + +class FinalDataGiftTraitsRemover(private val names: HolderSet) : + DataMapValueRemover { + override fun remove( + data: FinalTraitData, registry: Registry, key: Either, ResourceKey>, item: T + ): Optional { + return Optional.of( + data.copy( + traits = data.traits.filterKeys { !names.contains(it) }, + removed = data.removed + names.toList() + ) + ) + } + + companion object { + @JvmStatic + fun codec(): Codec> = + RegistryCodecs.homogeneousList(APRegistries.GIFT_TRAITS) + .xmap(::FinalDataGiftTraitsRemover, FinalDataGiftTraitsRemover::names) + + } +} + + +class DataGiftTraitsMerger : DataMapValueMerger { + override fun merge( + registry: Registry, + first: Either, ResourceKey>, + firstData: TraitData, + second: Either, ResourceKey>, + secondData: TraitData + ): TraitData = TraitData( + firstData.traits.keys.union(secondData.traits.keys).associateWith { k -> + val secondTrait = secondData.traits[k] + val firstTrait = firstData.traits[k] + GiftTraitData( + quality = secondTrait?.quality ?: firstTrait?.quality, + duration = secondTrait?.duration ?: firstTrait?.duration + ) + }, + ) + +} + + +class DataGiftTraitsRemover(private val names: HolderSet) : + DataMapValueRemover { + override fun remove( + data: TraitData, registry: Registry, key: Either, ResourceKey>, item: T + ): Optional { + return Optional.of( + TraitData( + data.traits.filterKeys { !names.contains(it) }) + ) + } + + companion object { + @JvmStatic + fun codec(): Codec> = + RegistryCodecs.homogeneousList(APRegistries.GIFT_TRAITS) + .xmap(::DataGiftTraitsRemover, DataGiftTraitsRemover::names) + + } +} + + + diff --git a/src/main/kotlin/gg/archipelago/aprandomizer/utils/RegistriesUtils.kt b/src/main/kotlin/gg/archipelago/aprandomizer/utils/RegistriesUtils.kt new file mode 100644 index 0000000..0a2be97 --- /dev/null +++ b/src/main/kotlin/gg/archipelago/aprandomizer/utils/RegistriesUtils.kt @@ -0,0 +1,25 @@ +package gg.archipelago.aprandomizer.utils + +import net.minecraft.core.Holder +import net.minecraft.core.HolderLookup +import net.minecraft.core.HolderSet +import net.minecraft.core.Registry +import net.minecraft.resources.ResourceKey +import net.minecraft.tags.TagKey + +context(lookup: HolderLookup.RegistryLookup) +val ResourceKey.holder: Holder.Reference + get() = lookup.getOrThrow(this) + + +context(lookup: HolderLookup.RegistryLookup) +val TagKey.holderSet: HolderSet.Named + get() = lookup.getOrThrow(this) + +context(registry: Registry) +val T.asHolder: Holder + get() { + val value: T = this@asHolder + return registry.wrapAsHolder(value) + } + diff --git a/src/main/templates/META-INF/neoforge.mods.toml b/src/main/templates/META-INF/neoforge.mods.toml index ce34e54..5094112 100644 --- a/src/main/templates/META-INF/neoforge.mods.toml +++ b/src/main/templates/META-INF/neoforge.mods.toml @@ -4,7 +4,7 @@ # 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 +modLoader = "${loader}" #mandatory # A version range to match for said mod loader - for regular FML @Mod it will be the the FML version. This is currently 47. loaderVersion = "${loader_version_range}" #mandatory # The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties.