diff --git a/src/generated/resources/assets/occultism/lang/en_us.json b/src/generated/resources/assets/occultism/lang/en_us.json index 50f9b140f..8b99dc2d7 100644 --- a/src/generated/resources/assets/occultism/lang/en_us.json +++ b/src/generated/resources/assets/occultism/lang/en_us.json @@ -253,6 +253,12 @@ "book.occultism.dictionary_of_spirits.familiar_rituals.overview.ring.title": "Equipping Familiars", "book.occultism.dictionary_of_spirits.familiar_rituals.overview.trading.text": "\"Familiars can be easily traded when in a [Familiar Ring](entry://crafting_rituals/craft_familiar_ring).\n\\\n\\\nWhen released, the spirit will recognize the person releasing them as their new master.\n", "book.occultism.dictionary_of_spirits.familiar_rituals.overview.trading.title": "Equipping Familiars", + "book.occultism.dictionary_of_spirits.familiar_rituals.resurrection.description": "How to bring back a familiar from the dead.", + "book.occultism.dictionary_of_spirits.familiar_rituals.resurrection.description.text": "The resurrection is a relatively simple process. The soul shard is strengthened with [](item://occultism:otherworld_essence) until it is strong enough to allow the familiar to return to the mortal realm and create a new body for itself.\n\\\n\\\nThe essence is obtained by growing (lots of) Demons Dream plants.\n", + "book.occultism.dictionary_of_spirits.familiar_rituals.resurrection.description.title": "Resurrection", + "book.occultism.dictionary_of_spirits.familiar_rituals.resurrection.name": "Resurrecting Familiars", + "book.occultism.dictionary_of_spirits.familiar_rituals.resurrection.soul_shard.text": "If a familiar dies it does not merely return to the Otherworld. Due to the close connection to the summoner a splinter of the familiar's soul remains in the mortal realm.\n\\\n\\\nThis splinter - shard - can be used to re-summon the familiar more easily.\n", + "book.occultism.dictionary_of_spirits.familiar_rituals.resurrection.soul_shard.title": "Soul Shards", "book.occultism.dictionary_of_spirits.familiar_rituals.return_to_rituals.name": "Return to Rituals Category", "book.occultism.dictionary_of_spirits.getting_started.books_of_binding.awakened_feather_recipe.text": "In order to craft [#](ad03fc)Books of Binding[#]() to summon spirits, you also need awakened feather. Simply drop any feather into [](item://occultism:spirit_fire) to awakened it.\n", "book.occultism.dictionary_of_spirits.getting_started.books_of_binding.book_of_binding_bound_foliot_recipe.text": "Add the name of the spirit to summon to your book of binding by crafting it with the Dictionary of Spirits. The Dictionary will not be used up.\n", @@ -303,7 +309,9 @@ "book.occultism.dictionary_of_spirits.getting_started.demons_dream.intro2.text": "These Demons possess a wide variety of powers and useful skills, and for centuries magicians have sought to summon them for their own gain.\nThe first step on the journey to successfully summoning such an Entity is to learn how to interact with the Otherworld.\n", "book.occultism.dictionary_of_spirits.getting_started.demons_dream.name": "Lifting the Veil", "book.occultism.dictionary_of_spirits.getting_started.demons_dream.note_on_spirit_fire.text": "**Hint**: The otherworld materials you obtain by harvesting under the effects of[#](ad03fc)Third Eye[#]() **can be obtained more easily using [](item://occultism:spirit_fire)**. Proceed with the next entry in this book to learn more about spirit fire.\n", - "book.occultism.dictionary_of_spirits.getting_started.demons_dream.spotlight.text": "Demon's Dream is a herb that gives humans the [#](ad03fc)Third Eye[#](),\nallowing them to see where the [#](ad03fc)Otherworld[#]() intersects with our own.\nSeeds can be found **by breaking grass**.\n**Consuming** the grown fruit activates the ability.\n", + "book.occultism.dictionary_of_spirits.getting_started.demons_dream.spotlight.text": "Demon's Dream is a herb that gives humans the [#](ad03fc)Third Eye[#](),\nallowing them to see where the [#](ad03fc)Otherworld[#]() intersects with our own.\nSeeds can be found **by breaking grass**.\n**Consuming** the grown fruit activates the ability *with a certain chance*.\n", + "book.occultism.dictionary_of_spirits.getting_started.demons_dream.spotlight2.text": "Multiple Demon's Dream fruits or seeds can be compressed into an essence that is much more potent. It *guarantees* the [#](ad03fc)Third Eye[#]() and provides it for a longer amount of time, but comes with a lot of (positive and negative) side effects.\n", + "book.occultism.dictionary_of_spirits.getting_started.demons_dream.spotlight3.text": "The essence can be purified in spirit fire (more on that later!) to obtain a version free from all negative side effects, while retaining the positive.\n", "book.occultism.dictionary_of_spirits.getting_started.divination_rod.about_divination_rod.text": "The divination rod uses a spirit attuned gem attached to a wooden rod.\nThe gem resonates with the chosen material, and this movement is amplified by the wooden rod,\nallowing to detect nearby Otherworld materials. \n \n \nThe rod works by detecting resonance between real world and Otherworld materials.\nAttuned the rod to a real world material, and it will find the corresponding Otherworld block.\n", "book.occultism.dictionary_of_spirits.getting_started.divination_rod.description": "Obtaining otherworld materials", "book.occultism.dictionary_of_spirits.getting_started.divination_rod.divination_rod.text": "Otherworld materials play an important role in interacting with spirits.\nAs they are rare and not visible to the naked eye, finding them requires special tools.\nThe divination rod allows to find Otherworld materials based on their similarities to materials common to our world.\n", @@ -351,6 +359,8 @@ "book.occultism.dictionary_of_spirits.getting_started.healing_spirits.description": "Fix up your spirit!", "book.occultism.dictionary_of_spirits.getting_started.healing_spirits.name": "Healing Spirits", "book.occultism.dictionary_of_spirits.getting_started.healing_spirits.spotlight.text": "Right-click a spirit with [](item://occultism:datura) to heal it.\n\\\n\\\nThis will work on **Familiars**, **Summoned Spirits** and also **Possessed Mobs**.\n", + "book.occultism.dictionary_of_spirits.getting_started.healing_spirits.spotlight2.text": "When compressing Demon's Dream fruits or seeds into essence, a much stronger instant healing effect can be achieved. This comes at the cost of efficiency: Feeding 9 fruits to a spirit in succession will heal it more than feeding it 9 fruits worth of essence.\n", + "book.occultism.dictionary_of_spirits.getting_started.healing_spirits.spotlight3.text": "Purifying the Demon's Dream Essence will yield a version that heals even more, negating the efficiency loss.\n", "book.occultism.dictionary_of_spirits.getting_started.iesnium.description": "Myterious metals ...", "book.occultism.dictionary_of_spirits.getting_started.iesnium.how.text": "Iesnium can only be mined with the [Infused Pickaxe](entry://getting_started/infused_pickaxe) or an [](item://occultism:iesnium_pickaxe) (about which you will learn later).\n\\\n\\\nAfter identifying a block that holds Iesnium, you can mine it with the pickaxe you created in the previous step.\n", "book.occultism.dictionary_of_spirits.getting_started.iesnium.how.title": "How to mine it", @@ -535,7 +545,7 @@ "book.occultism.dictionary_of_spirits.pentacles.summon_foliot.intro.text": "**Purpose:** Summon a [#](ad03fc)Foliot[#]()\n\\\n\\\nConsidered by most to be the simplest pentacle, [#](ad03fc)Aviar's Circle[#]() is easy to set up, but provides only a minimum of binding power and protection for the summoner.\n\\\n\\\nOnly the weakest [#](ad03fc)Foliot[#]() can be summoned in rituals using this pentacle.\n", "book.occultism.dictionary_of_spirits.pentacles.summon_foliot.intro.title": "Aviar's Circle", "book.occultism.dictionary_of_spirits.pentacles.summon_foliot.name": "Aviar's Circle", - "book.occultism.dictionary_of_spirits.pentacles.summon_foliot.uses.text": "- [Foliot Crusher](entry://summoning_rituals/summon_crusher_t1)\n- [Foliot Lumberjack](entry://summoning_rituals/summon_lumberjack)\n- [Foliot Transporter](entry://summoning_rituals/summon_transport_items)\n- [Foliot Janitor](entry://summoning_rituals/summon_cleaner)\n- [Otherstone Trader](entry://summoning_rituals/summon_otherstone_trader)\n- [Otherworld Sapling Trader](entry://summoning_rituals/summon_otherworld_sapling_trader)\n", + "book.occultism.dictionary_of_spirits.pentacles.summon_foliot.uses.text": "- [Foliot Crusher](entry://summoning_rituals/summon_crusher_t1)\n- [Foliot Lumberjack](entry://summoning_rituals/summon_lumberjack)\n- [Foliot Transporter](entry://summoning_rituals/summon_transport_items)\n- [Foliot Janitor](entry://summoning_rituals/summon_cleaner)\n- [Otherstone Trader](entry://summoning_rituals/summon_otherstone_trader)\n- [Otherworld Sapling Trader](entry://summoning_rituals/summon_otherworld_sapling_trader)\n- [Resurrect Familiar](entry://familiar_rituals/resurrection)\n", "book.occultism.dictionary_of_spirits.pentacles.summon_foliot.uses.title": "Uses", "book.occultism.dictionary_of_spirits.pentacles.summon_marid.intro.text": "**Purpose:** Summon a [#](ad03fc)Marid[#]()\n\\\n\\\n**Fatma's Incentivized Attraction** is a powerful pentacle, allowing to summon [#](ad03fc)Marid[#]() and bind them to the summoner's will.\n", "book.occultism.dictionary_of_spirits.pentacles.summon_marid.intro.title": "Fatma's Incentivized Attraction", @@ -928,7 +938,9 @@ "item.occultism.copper_dust": "Copper Dust", "item.occultism.crushed_end_stone": "Crushed End Stone", "item.occultism.datura": "Demon's Dream Fruit", + "item.occultism.datura.auto_tooltip": "Consumption may allow to see beyond the veil ... it may also cause general un-wellness.", "item.occultism.datura_seeds": "Demon's Dream Seeds", + "item.occultism.datura_seeds.auto_tooltip": "Plant to grow Demon's Dream Fruit.\nConsumption may allow to see beyond the veil ... it may also cause general un-wellness.", "item.occultism.debug_djinni_manage_machine": "Summon Debug Djinni Manage Machine", "item.occultism.debug_djinni_test": "Summon Debug Djinni Test", "item.occultism.debug_foliot_cleaner": "Summon Debug Foliot Janitor", @@ -936,6 +948,8 @@ "item.occultism.debug_foliot_trader": "Summon Debug Foliot Trader", "item.occultism.debug_foliot_transport_items": "Summon Debug Foliot Transporter", "item.occultism.debug_wand": "Debug Wand", + "item.occultism.demons_dream_essence": "Demon's Dream Essence", + "item.occultism.demons_dream_essence.auto_tooltip": "Consumption allows to see beyond the veil ... and a whole lot of other effects.", "item.occultism.dimensional_matrix": "Dimensional Crystal Matrix", "item.occultism.dimensional_matrix.tooltip": "%s is bound to this dimensional matrix.", "item.occultism.divination_rod": "Divination Rod", @@ -980,6 +994,8 @@ "item.occultism.otherstone_frame": "Otherstone Frame", "item.occultism.otherstone_tablet": "Otherstone Tablet", "item.occultism.otherworld_ashes": "Otherworld Ashes", + "item.occultism.otherworld_essence": "Otherworld Essence", + "item.occultism.otherworld_essence.auto_tooltip": "Purified Demon's Dream Essence, no longer provides any of the negative effects.", "item.occultism.otherworld_goggles": "Otherworld Goggles", "item.occultism.otherworld_sapling": "Otherworld Sapling", "item.occultism.otherworld_sapling_natural": "Unstable Otherworld Sapling", @@ -1077,6 +1093,8 @@ "item.occultism.ritual_dummy.possess_warden.tooltip": "The possessed Warden will always drop a echo shard and can drop anothers ancient stuff (smithing templates and discs) when killed.", "item.occultism.ritual_dummy.possess_weak_shulker": "Ritual: Summon Possessed Weak Shulker", "item.occultism.ritual_dummy.possess_weak_shulker.tooltip": "The possessed Weak Shulker will drop at least one chorus fruit when killed and can drop shulker shell.", + "item.occultism.ritual_dummy.resurrect_familiar": "Ritual: Resurrect Familiar", + "item.occultism.ritual_dummy.resurrect_familiar.tooltip": "Resurrects a Familiar from a Soul Shard.", "item.occultism.ritual_dummy.summon_afrit_crusher": "Ritual: Summon Afrit Crusher", "item.occultism.ritual_dummy.summon_afrit_crusher.tooltip": "The crusher is a spirit summoned to crush ores into dusts, effectively (more than) doubling the metal output. This crusher decays (much) slower than lower tier crushers.\n§7§oNote: Some recipes may require higher tier crushers.", "item.occultism.ritual_dummy.summon_afrit_rain_weather": "Ritual: Rainy Weather", @@ -1129,6 +1147,9 @@ "item.occultism.soul_gem.tooltip_empty": "Use on a creature to capture it.", "item.occultism.soul_gem.tooltip_filled": "Contains a captured %s.", "item.occultism.soul_gem_empty": "Empty Soul Gem", + "item.occultism.soul_shard": "Soul Shard", + "item.occultism.soul_shard.tooltip_empty": "Dropped by a Familiar after their untimely death. Can be used to resurrect it.", + "item.occultism.soul_shard.tooltip_filled": "Contains the soul of a %s.\nCan be used to resurrect it.", "item.occultism.spawn_egg.afrit": "Afrit Spawn Egg", "item.occultism.spawn_egg.afrit_wild": "Unbound Afrit Spawn Egg", "item.occultism.spawn_egg.demonic_husband": "Demonic Husband Spawn Egg", @@ -1484,6 +1505,10 @@ "ritual.occultism.possess_weak_shulker.finished": "Summoned possessed weak_shulker successfully.", "ritual.occultism.possess_weak_shulker.interrupted": "Summoning of possessed weak_shulker interrupted.", "ritual.occultism.possess_weak_shulker.started": "Started summoning possessed weak_shulker.", + "ritual.occultism.resurrect_familiar.conditions": "Not all requirements for this ritual are met.", + "ritual.occultism.resurrect_familiar.finished": "Successfully resurrected familiar.", + "ritual.occultism.resurrect_familiar.interrupted": "Resurrection interrupted.", + "ritual.occultism.resurrect_familiar.started": "Started resurrecting familiar.", "ritual.occultism.ritual_help": "§lInvalid ritual!§r\nWere you trying to perform ritual: \"%s\"? Missing items:\n%s", "ritual.occultism.sacrifice.axolotls": "Axolotl", "ritual.occultism.sacrifice.bats": "Bat", diff --git a/src/generated/resources/assets/occultism/models/item/demons_dream_essence.json b/src/generated/resources/assets/occultism/models/item/demons_dream_essence.json new file mode 100644 index 000000000..f95ad5a58 --- /dev/null +++ b/src/generated/resources/assets/occultism/models/item/demons_dream_essence.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "occultism:item/demons_dream_essence" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/occultism/models/item/otherworld_essence.json b/src/generated/resources/assets/occultism/models/item/otherworld_essence.json new file mode 100644 index 000000000..1ec7c56f4 --- /dev/null +++ b/src/generated/resources/assets/occultism/models/item/otherworld_essence.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "occultism:item/otherworld_essence" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/occultism/models/item/ritual_dummy/resurrect_familiar.json b/src/generated/resources/assets/occultism/models/item/ritual_dummy/resurrect_familiar.json new file mode 100644 index 000000000..1a5442cc2 --- /dev/null +++ b/src/generated/resources/assets/occultism/models/item/ritual_dummy/resurrect_familiar.json @@ -0,0 +1,3 @@ +{ + "parent": "occultism:item/ritual_dummy" +} \ No newline at end of file diff --git a/src/generated/resources/assets/occultism/models/item/soul_shard.json b/src/generated/resources/assets/occultism/models/item/soul_shard.json new file mode 100644 index 000000000..d4b7f6813 --- /dev/null +++ b/src/generated/resources/assets/occultism/models/item/soul_shard.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "occultism:item/soul_shard" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/occultism/modonomicon/books/dictionary_of_spirits/entries/familiar_rituals/resurrection.json b/src/generated/resources/data/occultism/modonomicon/books/dictionary_of_spirits/entries/familiar_rituals/resurrection.json new file mode 100644 index 000000000..3b5cd4885 --- /dev/null +++ b/src/generated/resources/data/occultism/modonomicon/books/dictionary_of_spirits/entries/familiar_rituals/resurrection.json @@ -0,0 +1,66 @@ +{ + "background_u_index": 0, + "background_v_index": 0, + "category": "occultism:familiar_rituals", + "description": "book.occultism.dictionary_of_spirits.familiar_rituals.resurrection.description", + "hide_while_locked": false, + "icon": { + "item": "occultism:soul_shard" + }, + "name": "book.occultism.dictionary_of_spirits.familiar_rituals.resurrection.name", + "pages": [ + { + "type": "modonomicon:spotlight", + "anchor": "", + "item": { + "item": "occultism:soul_shard" + }, + "text": "book.occultism.dictionary_of_spirits.familiar_rituals.resurrection.soul_shard.text", + "title": "book.occultism.dictionary_of_spirits.familiar_rituals.resurrection.soul_shard.title" + }, + { + "type": "modonomicon:text", + "anchor": "", + "show_title_separator": true, + "text": "book.occultism.dictionary_of_spirits.familiar_rituals.resurrection.description.text", + "title": "book.occultism.dictionary_of_spirits.familiar_rituals.resurrection.description.title", + "use_markdown_in_title": false + }, + { + "type": "modonomicon:crafting_recipe", + "anchor": "", + "recipe_id_1": "occultism:crafting/demons_dream_essence_from_fruit", + "recipe_id_2": "occultism:crafting/demons_dream_essence_from_seeds", + "text": "", + "title1": "", + "title2": "" + }, + { + "type": "occultism:spirit_fire_recipe", + "anchor": "", + "recipe_id_1": "occultism:spirit_fire/otherworld_essence", + "text": "", + "title1": "", + "title2": "" + }, + { + "type": "occultism:ritual_recipe", + "anchor": "", + "recipe_id_1": "occultism:ritual/resurrect_familiar", + "text": "", + "title1": "", + "title2": "" + } + ], + "parents": [ + { + "draw_arrow": true, + "entry": "occultism:familiar_rituals/overview", + "line_enabled": true, + "line_reversed": false + } + ], + "show_when_any_parent_unlocked": false, + "x": -8, + "y": -2 +} \ No newline at end of file diff --git a/src/generated/resources/data/occultism/modonomicon/books/dictionary_of_spirits/entries/getting_started/demons_dream.json b/src/generated/resources/data/occultism/modonomicon/books/dictionary_of_spirits/entries/getting_started/demons_dream.json index bae55dbaa..02a506c5a 100644 --- a/src/generated/resources/data/occultism/modonomicon/books/dictionary_of_spirits/entries/getting_started/demons_dream.json +++ b/src/generated/resources/data/occultism/modonomicon/books/dictionary_of_spirits/entries/getting_started/demons_dream.json @@ -59,6 +59,41 @@ "text": "book.occultism.dictionary_of_spirits.getting_started.demons_dream.note_on_spirit_fire.text", "title": "", "use_markdown_in_title": false + }, + { + "type": "modonomicon:spotlight", + "anchor": "", + "item": { + "item": "occultism:demons_dream_essence" + }, + "text": "book.occultism.dictionary_of_spirits.getting_started.demons_dream.spotlight2.text", + "title": "" + }, + { + "type": "modonomicon:crafting_recipe", + "anchor": "", + "recipe_id_1": "occultism:crafting/demons_dream_essence_from_fruit", + "recipe_id_2": "occultism:crafting/demons_dream_essence_from_seeds", + "text": "", + "title1": "", + "title2": "" + }, + { + "type": "modonomicon:spotlight", + "anchor": "", + "item": { + "item": "occultism:demons_dream_essence" + }, + "text": "book.occultism.dictionary_of_spirits.getting_started.demons_dream.spotlight3.text", + "title": "" + }, + { + "type": "occultism:spirit_fire_recipe", + "anchor": "", + "recipe_id_1": "occultism:spirit_fire/otherworld_essence", + "text": "", + "title1": "", + "title2": "" } ], "parents": [ diff --git a/src/generated/resources/data/occultism/modonomicon/books/dictionary_of_spirits/entries/getting_started/healing_spirits.json b/src/generated/resources/data/occultism/modonomicon/books/dictionary_of_spirits/entries/getting_started/healing_spirits.json index a8b0b24bc..6d7157027 100644 --- a/src/generated/resources/data/occultism/modonomicon/books/dictionary_of_spirits/entries/getting_started/healing_spirits.json +++ b/src/generated/resources/data/occultism/modonomicon/books/dictionary_of_spirits/entries/getting_started/healing_spirits.json @@ -17,6 +17,24 @@ }, "text": "book.occultism.dictionary_of_spirits.getting_started.healing_spirits.spotlight.text", "title": "" + }, + { + "type": "modonomicon:spotlight", + "anchor": "", + "item": { + "item": "occultism:demons_dream_essence" + }, + "text": "book.occultism.dictionary_of_spirits.getting_started.healing_spirits.spotlight2.text", + "title": "" + }, + { + "type": "modonomicon:spotlight", + "anchor": "", + "item": { + "item": "occultism:otherworld_essence" + }, + "text": "book.occultism.dictionary_of_spirits.getting_started.healing_spirits.spotlight3.text", + "title": "" } ], "parents": [ diff --git a/src/main/java/com/klikli_dev/occultism/common/entity/familiar/FamiliarEntity.java b/src/main/java/com/klikli_dev/occultism/common/entity/familiar/FamiliarEntity.java index 0a2940c73..b6bb4346c 100644 --- a/src/main/java/com/klikli_dev/occultism/common/entity/familiar/FamiliarEntity.java +++ b/src/main/java/com/klikli_dev/occultism/common/entity/familiar/FamiliarEntity.java @@ -31,17 +31,21 @@ import net.minecraft.util.Mth; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; +import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.*; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.ai.goal.Goal; +import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.pathfinder.BlockPathTypes; import net.minecraft.world.level.pathfinder.WalkNodeEvaluator; +import net.neoforged.neoforge.items.ItemHandlerHelper; + import java.util.EnumSet; import java.util.Optional; import java.util.UUID; @@ -73,6 +77,31 @@ public static AttributeSupplier.Builder createAttributes() { .add(Attributes.MOVEMENT_SPEED, 0.3); } + @Override + protected void dropFromLootTable(DamageSource pDamageSource, boolean pAttackedRecently) { + super.dropFromLootTable(pDamageSource, pAttackedRecently); + + var owner = this.getFamiliarOwner(); + + var shard = new ItemStack(OccultismItems.SOUL_SHARD_ITEM.get()); + + var health = this.getHealth(); + this.setHealth(this.getMaxHealth()); //simulate a healthy familiar to avoid death on respawn + shard.getOrCreateTag().put("entityData", this.serializeNBT()); + this.setHealth(health); + + if(owner instanceof Player player){ + ItemHandlerHelper.giveItemToPlayer(player, shard); + } + else { + ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY() + 0.5, this.getZ(), shard); + entityitem.setPickUpDelay(5); + entityitem.setDeltaMovement(entityitem.getDeltaMovement().multiply(0, 1, 0)); + + this.level().addFreshEntity(entityitem); + } + } + @Override public void setRecordPlayingNearby(BlockPos jukeboxPos, boolean partying) { this.jukeboxPos = jukeboxPos; diff --git a/src/main/java/com/klikli_dev/occultism/common/item/spirit/SpiritHealingItem.java b/src/main/java/com/klikli_dev/occultism/common/item/spirit/SpiritHealingItem.java index 259ff32d8..ddd01e61f 100644 --- a/src/main/java/com/klikli_dev/occultism/common/item/spirit/SpiritHealingItem.java +++ b/src/main/java/com/klikli_dev/occultism/common/item/spirit/SpiritHealingItem.java @@ -22,6 +22,7 @@ package com.klikli_dev.occultism.common.item.spirit; +import com.klikli_dev.occultism.registry.OccultismItems; import com.klikli_dev.occultism.registry.OccultismTags; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; @@ -38,10 +39,22 @@ public SpiritHealingItem(Properties pProperties) { @Override public InteractionResult interactLivingEntity(ItemStack pStack, Player pPlayer, LivingEntity pInteractionTarget, InteractionHand pUsedHand) { if (pInteractionTarget.getType().is(OccultismTags.HEALED_BY_DEMONS_DREAM_FRUIT) && pInteractionTarget.getHealth() < pInteractionTarget.getMaxHealth()) { - pInteractionTarget.heal(2); + pInteractionTarget.heal(this.getHealAmount(pStack)); pStack.shrink(1); return InteractionResult.sidedSuccess(pPlayer.level().isClientSide); } return super.interactLivingEntity(pStack, pPlayer, pInteractionTarget, pUsedHand); } + + protected int getHealAmount(ItemStack pStack) { + if (pStack.is(OccultismItems.DATURA.get())) { + return 2; + } else if (pStack.is(OccultismItems.DEMONS_DREAM_ESSENCE.get())) { + return 10; + } else if (pStack.is(OccultismItems.OTHERWORLD_ESSENCE.get())) { + return 20; + } else { + return 0; + } + } } diff --git a/src/main/java/com/klikli_dev/occultism/common/item/tool/SoulShardItem.java b/src/main/java/com/klikli_dev/occultism/common/item/tool/SoulShardItem.java new file mode 100644 index 000000000..567be831e --- /dev/null +++ b/src/main/java/com/klikli_dev/occultism/common/item/tool/SoulShardItem.java @@ -0,0 +1,64 @@ +/* + * MIT License + * + * Copyright 2020 klikli-dev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.klikli_dev.occultism.common.item.tool; + +import com.klikli_dev.occultism.util.EntityUtil; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.List; + +public class SoulShardItem extends Item { + + public SoulShardItem(Properties properties) { + super(properties); + } + + + @Override + public void appendHoverText(ItemStack stack, @Nullable Level worldIn, List tooltip, + TooltipFlag flagIn) { + super.appendHoverText(stack, worldIn, tooltip, flagIn); + + if (stack.getOrCreateTag().contains("entityData")) { + EntityType type = EntityUtil.entityTypeFromNbt(stack.getTag().getCompound("entityData")); + tooltip.add(Component.translatable(this.getDescriptionId() + ".tooltip_filled", type.getDescription())); + } else { + tooltip.add(Component.translatable(this.getDescriptionId() + ".tooltip_empty")); + } + } +} diff --git a/src/main/java/com/klikli_dev/occultism/common/ritual/ResurrectFamiliarRitual.java b/src/main/java/com/klikli_dev/occultism/common/ritual/ResurrectFamiliarRitual.java new file mode 100644 index 000000000..3fca18af5 --- /dev/null +++ b/src/main/java/com/klikli_dev/occultism/common/ritual/ResurrectFamiliarRitual.java @@ -0,0 +1,88 @@ +/* + * MIT License + * + * Copyright 2020 klikli-dev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.klikli_dev.occultism.common.ritual; + +import com.klikli_dev.occultism.common.blockentity.GoldenSacrificialBowlBlockEntity; +import com.klikli_dev.occultism.common.entity.familiar.FamiliarEntity; +import com.klikli_dev.occultism.crafting.recipe.RitualRecipe; +import com.klikli_dev.occultism.registry.OccultismAdvancements; +import com.klikli_dev.occultism.registry.OccultismSounds; +import com.klikli_dev.occultism.util.EntityUtil; +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; + +public class ResurrectFamiliarRitual extends SummonRitual { + + public ResurrectFamiliarRitual(RitualRecipe recipe) { + super(recipe, true); + } + + @Override + public void finish(Level level, BlockPos goldenBowlPosition, GoldenSacrificialBowlBlockEntity blockEntity, + ServerPlayer castingPlayer, ItemStack activationItem) { + //manually call content of Ritual.finish(), because we cannot access it via super + level.playSound(null, goldenBowlPosition, OccultismSounds.POOF.get(), SoundSource.BLOCKS, 0.7f, + 0.7f); + castingPlayer.displayClientMessage(Component.translatable(this.getFinishedMessage(castingPlayer)), true); + OccultismAdvancements.RITUAL.get().trigger( castingPlayer, this); + + var shard = activationItem.copy(); + activationItem.shrink(1); //remove original activation item. + + ((ServerLevel) level).sendParticles(ParticleTypes.LARGE_SMOKE, goldenBowlPosition.getX() + 0.5, + goldenBowlPosition.getY() + 0.5, goldenBowlPosition.getZ() + 0.5, 1, 0, 0, 0, 0); + + //copied and modified from soul gem item + if (shard.getOrCreateTag().contains("entityData")) { + //whenever we have an entity stored we can do nothing but release it + var entityData = shard.getTag().getCompound("entityData"); + var type = EntityUtil.entityTypeFromNbt(entityData); + + BlockPos spawnPos = goldenBowlPosition; + + //remove position from tag to allow the entity to spawn where it should be + entityData.remove("Pos"); + + //type.spawn uses the sub-tag EntityTag + CompoundTag wrapper = new CompoundTag(); + wrapper.put("EntityTag", entityData); + + Entity entity = type.create(level); + entity.load(entityData); + entity.absMoveTo(spawnPos.getX() + 0.5, spawnPos.getY(), spawnPos.getZ() + 0.5, 0, 0); + level.addFreshEntity(entity); + + if (entity instanceof FamiliarEntity familiar) + familiar.setFamiliarOwner(castingPlayer); + } + } +} diff --git a/src/main/java/com/klikli_dev/occultism/datagen/ItemModelsGenerator.java b/src/main/java/com/klikli_dev/occultism/datagen/ItemModelsGenerator.java index c71bd5712..4d0d85f2a 100644 --- a/src/main/java/com/klikli_dev/occultism/datagen/ItemModelsGenerator.java +++ b/src/main/java/com/klikli_dev/occultism/datagen/ItemModelsGenerator.java @@ -51,11 +51,29 @@ protected void registerModels() { }); this.registerAdvancementItem(); - this.registerSpawnEgg(OccultismItems.SPAWN_EGG_DEMONIC_WIFE); this.registerSpawnEgg(OccultismItems.SPAWN_EGG_DEMONIC_HUSBAND); + + this.registerItemGenerated(this.name(OccultismItems.SOUL_SHARD_ITEM.get())); + this.registerItemGenerated(this.name(OccultismItems.DEMONS_DREAM_ESSENCE.get())); + this.registerItemGenerated(this.name(OccultismItems.OTHERWORLD_ESSENCE.get())); } + protected String name(Item item) { + return BuiltInRegistries.ITEM.getKey(item).getPath(); + } + + private ItemModelBuilder registerItemGenerated(String name) { + return this.registerItemGenerated(name, name); + } + + private ItemModelBuilder registerItemGenerated(String name, String texture) { + return this.getBuilder(name) + .parent(new ModelFile.UncheckedModelFile("item/generated")) + .texture("layer0", this.modLoc("item/" + texture)); + } + + private void registerRitualDummy(String name) { this.getBuilder(name).parent(new ModelFile.UncheckedModelFile("occultism:item/ritual_dummy")); } diff --git a/src/main/java/com/klikli_dev/occultism/datagen/OccultismBookProvider.java b/src/main/java/com/klikli_dev/occultism/datagen/OccultismBookProvider.java index e3202fa31..cd11057e0 100644 --- a/src/main/java/com/klikli_dev/occultism/datagen/OccultismBookProvider.java +++ b/src/main/java/com/klikli_dev/occultism/datagen/OccultismBookProvider.java @@ -323,7 +323,7 @@ private BookEntryModel makeDemonsDreamEntry(CategoryEntryMap entryMap, char icon %1$s is a herb that gives humans the [#](%2$s)Third Eye[#](), allowing them to see where the [#](%2$s)Otherworld[#]() intersects with our own. Seeds can be found **by breaking grass**. - **Consuming** the grown fruit activates the ability. + **Consuming** the grown fruit activates the ability *with a certain chance*. """.formatted(DEMONS_DREAM, COLOR_PURPLE)); this.context().page("harvest_effect"); @@ -349,6 +349,37 @@ private BookEntryModel makeDemonsDreamEntry(CategoryEntryMap entryMap, char icon **Hint**: The otherworld materials you obtain by harvesting under the effects of[#](%2$s)Third Eye[#]() **can be obtained more easily using [](item://occultism:spirit_fire)**. Proceed with the next entry in this book to learn more about spirit fire. """.formatted(DEMONS_DREAM, COLOR_PURPLE)); + this.context().page("spotlight2"); + var spotlight2 = BookSpotlightPageModel.create() + .withItem(Ingredient.of(OccultismItems.DEMONS_DREAM_ESSENCE.get())) + .withText(this.context().pageText()); + this.lang().add(this.context().pageText(), + """ + Multiple Demon's Dream fruits or seeds can be compressed into an essence that is much more potent. It *guarantees* the [#](%2$s)Third Eye[#]() and provides it for a longer amount of time, but comes with a lot of (positive and negative) side effects. + """.formatted(DEMONS_DREAM, COLOR_PURPLE) + ); + + this.context().page("recipe_essence"); + var recipeEssence = BookCraftingRecipePageModel.create() + .withRecipeId1(this.modLoc("crafting/demons_dream_essence_from_fruit")) + .withRecipeId2(this.modLoc("crafting/demons_dream_essence_from_seeds")); + //no text + + this.context().page("spotlight3"); + var spotlight3 = BookSpotlightPageModel.create() + .withItem(Ingredient.of(OccultismItems.DEMONS_DREAM_ESSENCE.get())) + .withText(this.context().pageText()); + this.lang().add(this.context().pageText(), + """ + The essence can be purified in spirit fire (more on that later!) to obtain a version free from all negative side effects, while retaining the positive. + """.formatted(DEMONS_DREAM, COLOR_PURPLE) + ); + + this.context().page("recipe_essence_pure"); + var recipeEssencePure = BookSpiritFireRecipePageModel.create() + .withRecipeId1(this.modLoc("spirit_fire/otherworld_essence")); + //no text + return BookEntryModel.create(this.modLoc(this.context().categoryId() + "/" + this.context().entryId()), this.context().entryName()) .withDescription(this.context().entryDescription()) .withIcon(OccultismItems.DATURA.get()) @@ -359,7 +390,12 @@ private BookEntryModel makeDemonsDreamEntry(CategoryEntryMap entryMap, char icon spotlight, harvestEffect, datureScreenshot, - spiritFire); + spiritFire, + spotlight2, + recipeEssence, + spotlight3, + recipeEssencePure + ); } private BookEntryModel makeSpiritFireEntry(CategoryEntryMap entryMap, char icon) { @@ -458,12 +494,32 @@ private BookEntryModel makeHealingSpiritsEntry(CategoryEntryMap entryMap, char i This will work on **Familiars**, **Summoned Spirits** and also **Possessed Mobs**. """); + this.context().page("spotlight2"); + var spotlight2 = BookSpotlightPageModel.create() + .withItem(Ingredient.of(OccultismItems.DEMONS_DREAM_ESSENCE.get())) + .withText(this.context().pageText()); + this.lang().add(this.context().pageText(), + """ + When compressing Demon's Dream fruits or seeds into essence, a much stronger instant healing effect can be achieved. This comes at the cost of efficiency: Feeding 9 fruits to a spirit in succession will heal it more than feeding it 9 fruits worth of essence. + """); + + this.context().page("spotlight3"); + var spotlight3 = BookSpotlightPageModel.create() + .withItem(Ingredient.of(OccultismItems.OTHERWORLD_ESSENCE.get())) + .withText(this.context().pageText()); + this.lang().add(this.context().pageText(), + """ + Purifying the Demon's Dream Essence will yield a version that heals even more, negating the efficiency loss. + """); + return BookEntryModel.create(this.modLoc(this.context().categoryId() + "/" + this.context().entryId()), this.context().entryName()) .withDescription(this.context().entryDescription()) .withIcon(Items.SPLASH_POTION) .withLocation(entryMap.get(icon)) .withPages( - spotlight + spotlight, + spotlight2, + spotlight3 ); } diff --git a/src/main/java/com/klikli_dev/occultism/datagen/book/FamiliarRitualsCategory.java b/src/main/java/com/klikli_dev/occultism/datagen/book/FamiliarRitualsCategory.java index f97195a5e..2b2ceda43 100644 --- a/src/main/java/com/klikli_dev/occultism/datagen/book/FamiliarRitualsCategory.java +++ b/src/main/java/com/klikli_dev/occultism/datagen/book/FamiliarRitualsCategory.java @@ -10,6 +10,7 @@ import com.klikli_dev.modonomicon.api.datagen.book.page.BookEntityPageModel; import com.klikli_dev.modonomicon.api.datagen.book.page.BookTextPageModel; import com.klikli_dev.occultism.datagen.book.familiarrituals.DemonicPartnerEntry; +import com.klikli_dev.occultism.datagen.book.familiarrituals.ResurrectionEntry; import com.klikli_dev.occultism.integration.modonomicon.pages.BookRitualRecipePageModel; public class FamiliarRitualsCategory extends CategoryProvider { @@ -24,7 +25,7 @@ public String[] generateEntryMap() { return new String[]{ "________R_T_V_X____________", "___________________________", - "_______Q_S_U_W_Z___________", + "_____a_Q_S_U_W_Z___________", "___________________________", "___r_o_____________________", "___________________________", @@ -41,6 +42,9 @@ protected void generateEntries() { returnToRituals.withParent(BookEntryParentModel.create(overview.getId())); returnToRituals.withCondition(BookTrueConditionModel.create()); + var resurrection = new ResurrectionEntry(this).generate('a'); + resurrection.withParent(BookEntryParentModel.create(overview.getId())); + var familiarBat = this.add(this.makeFamiliarBatEntry(entryMap, 'I')); familiarBat.withParent(BookEntryParentModel.create(overview.getId())); var familiarBeaver = this.add(this.makeFamiliarBeaverEntry(entryMap, 'J')); diff --git a/src/main/java/com/klikli_dev/occultism/datagen/book/familiarrituals/ResurrectionEntry.java b/src/main/java/com/klikli_dev/occultism/datagen/book/familiarrituals/ResurrectionEntry.java new file mode 100644 index 000000000..30a72487b --- /dev/null +++ b/src/main/java/com/klikli_dev/occultism/datagen/book/familiarrituals/ResurrectionEntry.java @@ -0,0 +1,95 @@ +package com.klikli_dev.occultism.datagen.book.familiarrituals; + +import com.klikli_dev.modonomicon.api.datagen.CategoryProvider; +import com.klikli_dev.modonomicon.api.datagen.EntryBackground; +import com.klikli_dev.modonomicon.api.datagen.EntryProvider; +import com.klikli_dev.modonomicon.api.datagen.book.BookIconModel; +import com.klikli_dev.modonomicon.api.datagen.book.page.BookCraftingRecipePageModel; +import com.klikli_dev.modonomicon.api.datagen.book.page.BookEntityPageModel; +import com.klikli_dev.modonomicon.api.datagen.book.page.BookSpotlightPageModel; +import com.klikli_dev.modonomicon.api.datagen.book.page.BookTextPageModel; +import com.klikli_dev.occultism.integration.modonomicon.pages.BookRitualRecipePageModel; +import com.klikli_dev.occultism.integration.modonomicon.pages.BookSpiritFireRecipePageModel; +import com.klikli_dev.occultism.registry.OccultismItems; +import com.mojang.datafixers.util.Pair; +import net.minecraft.world.item.crafting.Ingredient; + +public class ResurrectionEntry extends EntryProvider { + + public static final String ENTRY_ID = "resurrection"; + + + public ResurrectionEntry(CategoryProvider parent) { + super(parent); + } + + @Override + protected void generatePages() { + + + this.page("soul_shard", () -> BookSpotlightPageModel.create() + .withItem(Ingredient.of(OccultismItems.SOUL_SHARD_ITEM.get())) + .withTitle(this.context().pageTitle()) + .withText(this.context().pageText())); + this.pageTitle("Soul Shards"); + this.pageText(""" + If a familiar dies it does not merely return to the Otherworld. Due to the close connection to the summoner a splinter of the familiar's soul remains in the mortal realm. + \\ + \\ + This splinter - shard - can be used to re-summon the familiar more easily. + """); + + this.page("description", () -> BookTextPageModel.create() + .withTitle(this.context().pageTitle()) + .withText(this.context().pageText())); + this.pageTitle("Resurrection"); + this.pageText(""" + The resurrection is a relatively simple process. The soul shard is strengthened with {0} until it is strong enough to allow the familiar to return to the mortal realm and create a new body for itself. + \\ + \\ + The essence is obtained by growing (lots of) Demon's Dream plants. + """, + this.itemLink(OccultismItems.OTHERWORLD_ESSENCE.get()) + ); + + this.page("recipe_essence", () ->BookCraftingRecipePageModel.create() + .withRecipeId1(this.modLoc("crafting/demons_dream_essence_from_fruit")) + .withRecipeId2(this.modLoc("crafting/demons_dream_essence_from_seeds"))); + //no text + + this.page("recipe_essence_pure", () -> BookSpiritFireRecipePageModel.create() + .withRecipeId1(this.modLoc("spirit_fire/otherworld_essence"))); + //no text + + + this.page("ritual", () -> BookRitualRecipePageModel.create() + .withRecipeId1(this.modLoc("ritual/resurrect_familiar")) + ); + //no text + } + + @Override + protected String entryName() { + return "Resurrecting Familiars"; + } + + @Override + protected String entryDescription() { + return "How to bring back a familiar from the dead."; + } + + @Override + protected Pair entryBackground() { + return EntryBackground.DEFAULT; + } + + @Override + protected BookIconModel entryIcon() { + return BookIconModel.create(OccultismItems.SOUL_SHARD_ITEM.get()); + } + + @Override + protected String entryId() { + return ENTRY_ID; + } +} diff --git a/src/main/java/com/klikli_dev/occultism/datagen/lang/ENUSProvider.java b/src/main/java/com/klikli_dev/occultism/datagen/lang/ENUSProvider.java index f6ae39fa7..e4c02c301 100644 --- a/src/main/java/com/klikli_dev/occultism/datagen/lang/ENUSProvider.java +++ b/src/main/java/com/klikli_dev/occultism/datagen/lang/ENUSProvider.java @@ -27,17 +27,20 @@ import com.klikli_dev.modonomicon.api.datagen.BookContextHelper; import com.klikli_dev.occultism.Occultism; import com.klikli_dev.occultism.TranslationKeys; +import com.klikli_dev.occultism.common.ritual.RitualFactory; import com.klikli_dev.occultism.datagen.OccultismAdvancementSubProvider; import com.klikli_dev.occultism.integration.modonomicon.OccultismModonomiconConstants.I18n; import com.klikli_dev.occultism.registry.OccultismBlocks; import com.klikli_dev.occultism.registry.OccultismEntities; import com.klikli_dev.occultism.registry.OccultismItems; +import com.klikli_dev.occultism.registry.OccultismRituals; import net.minecraft.ChatFormatting; import net.minecraft.Util; import net.minecraft.data.PackOutput; import net.minecraft.network.chat.contents.TranslatableContents; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.ItemLike; +import net.neoforged.neoforge.registries.DeferredHolder; public class ENUSProvider extends AbstractModonomiconLanguageProvider { @@ -124,6 +127,9 @@ public void addItemTooltips() { this.add(OccultismItems.SOUL_GEM_ITEM.get().getDescriptionId() + ".tooltip_filled", "Contains a captured %s."); this.add(OccultismItems.SOUL_GEM_ITEM.get().getDescriptionId() + ".tooltip_empty", "Use on a creature to capture it."); this.add(OccultismItems.SATCHEL.get().getDescriptionId() + ".tooltip", "%s is bound to this satchel."); + + this.add(OccultismItems.SOUL_SHARD_ITEM.get().getDescriptionId() + ".tooltip_filled", "Contains the soul of a %s.\nCan be used to resurrect it."); + this.add(OccultismItems.SOUL_SHARD_ITEM.get().getDescriptionId() + ".tooltip_empty", "Dropped by a Familiar after their untimely death. Can be used to resurrect it."); } private void addItems() { @@ -173,7 +179,13 @@ private void addItems() { this.addItem(OccultismItems.DIMENSIONAL_MATRIX, "Dimensional Crystal Matrix"); this.addItem(OccultismItems.DIVINATION_ROD, "Divination Rod"); this.addItem(OccultismItems.DATURA_SEEDS, "Demon's Dream Seeds"); + this.addAutoTooltip(OccultismItems.DATURA_SEEDS.get(), "Plant to grow Demon's Dream Fruit.\nConsumption may allow to see beyond the veil ... it may also cause general un-wellness."); this.addItem(OccultismItems.DATURA, "Demon's Dream Fruit"); + this.addAutoTooltip(OccultismItems.DATURA.get(), "Consumption may allow to see beyond the veil ... it may also cause general un-wellness."); + this.addItem(OccultismItems.DEMONS_DREAM_ESSENCE, "Demon's Dream Essence"); + this.addAutoTooltip(OccultismItems.DEMONS_DREAM_ESSENCE.get(), "Consumption allows to see beyond the veil ... and a whole lot of other effects."); + this.addItem(OccultismItems.OTHERWORLD_ESSENCE, "Otherworld Essence"); + this.addAutoTooltip(OccultismItems.OTHERWORLD_ESSENCE.get(), "Purified Demon's Dream Essence, no longer provides any of the negative effects."); this.addItem(OccultismItems.SPIRIT_ATTUNED_GEM, "Spirit Attuned Gem"); this.add("item.occultism.otherworld_sapling", "Otherworld Sapling"); this.add("item.occultism.otherworld_sapling_natural", "Unstable Otherworld Sapling"); @@ -212,6 +224,7 @@ private void addItems() { this.addItem(OccultismItems.MINER_MARID_MASTER, "Master Miner Marid"); this.addItem(OccultismItems.SOUL_GEM_ITEM, "Soul Gem"); this.add(OccultismItems.SOUL_GEM_ITEM.get().getDescriptionId() + "_empty", "Empty Soul Gem"); + this.addItem(OccultismItems.SOUL_SHARD_ITEM, "Soul Shard"); this.addItem(OccultismItems.SATCHEL, "Surprisingly Substantial Satchel"); this.addItem(OccultismItems.FAMILIAR_RING, "Familiar Ring"); this.addItem(OccultismItems.SPAWN_EGG_FOLIOT, "Foliot Spawn Egg"); @@ -750,6 +763,15 @@ private void addRitualMessages() { this.add("ritual.occultism.summon_demonic_husband.started", "Started summoning."); this.add("ritual.occultism.summon_demonic_husband.finished", "Summoned successfully."); this.add("ritual.occultism.summon_demonic_husband.interrupted", "Summoning interrupted."); + + this.addRitualMessage(OccultismRituals.RESURRECT_FAMILIAR_RITUAL, "conditions", "Not all requirements for this ritual are met."); + this.addRitualMessage(OccultismRituals.RESURRECT_FAMILIAR_RITUAL, "started", "Started resurrecting familiar."); + this.addRitualMessage(OccultismRituals.RESURRECT_FAMILIAR_RITUAL, "finished", "Successfully resurrected familiar."); + this.addRitualMessage(OccultismRituals.RESURRECT_FAMILIAR_RITUAL, "interrupted", "Resurrection interrupted."); + } + + public void addRitualMessage(DeferredHolder ritual, String key, String message) { + this.add("ritual.%s.%s".formatted(ritual.getId().getNamespace(), ritual.getId().getPath()) + "." + key, message); } private void addBook() { @@ -1010,8 +1032,10 @@ Now it is time to place the ingredients you see on the next page in the (regular - [Foliot Janitor](entry://summoning_rituals/summon_cleaner) - [Otherstone Trader](entry://summoning_rituals/summon_otherstone_trader) - [Otherworld Sapling Trader](entry://summoning_rituals/summon_otherworld_sapling_trader) + - [Resurrect Familiar](entry://familiar_rituals/resurrection) """); + helper.entry("summon_djinni"); this.add(helper.entryName(), "Ophyx' Calling"); @@ -2999,12 +3023,20 @@ private void addRitualDummies() { this.add(OccultismItems.RITUAL_DUMMY_SUMMON_DEMONIC_HUSBAND.get(), "Ritual: Summon Demonic Husband"); this.addTooltip(OccultismItems.RITUAL_DUMMY_SUMMON_DEMONIC_HUSBAND.get(), "Summons a Demonic Husband to support you: He will fight for you, help with cooking, and extend potion durations."); + + + this.add(OccultismItems.RITUAL_RESURRECT_FAMILIAR.get(), "Ritual: Resurrect Familiar"); + this.addTooltip(OccultismItems.RITUAL_RESURRECT_FAMILIAR.get(), "Resurrects a Familiar from a Soul Shard."); } public void addTooltip(ItemLike key, String value) { this.add(key.asItem().getDescriptionId() + ".tooltip", value); } + public void addAutoTooltip(ItemLike key, String value) { + this.add(key.asItem().getDescriptionId() + ".auto_tooltip", value); + } + private void addDialogs() { this.add("dialog.occultism.dragon.pet", "purrr"); this.add("dialog.occultism.mummy.kapow", "KAPOW!"); diff --git a/src/main/java/com/klikli_dev/occultism/handlers/TooltipHandler.java b/src/main/java/com/klikli_dev/occultism/handlers/TooltipHandler.java index 3d479cfee..508c3151f 100644 --- a/src/main/java/com/klikli_dev/occultism/handlers/TooltipHandler.java +++ b/src/main/java/com/klikli_dev/occultism/handlers/TooltipHandler.java @@ -25,10 +25,12 @@ import com.klikli_dev.occultism.Occultism; import com.klikli_dev.occultism.util.ItemNBTUtil; import com.klikli_dev.occultism.util.TextUtil; +import com.klikli_dev.theurgy.TheurgyConstants; import net.minecraft.ChatFormatting; import net.minecraft.client.resources.language.I18n; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.Style; import net.minecraft.world.item.ItemStack; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; @@ -56,5 +58,15 @@ public static void onAddInformation(ItemTooltipEvent event) { tooltips.add(Component.literal(tag.getFirst().toString()).withStyle(ChatFormatting.DARK_GRAY)); }); } + + var namespace = BuiltInRegistries.ITEM.getKey(stack.getItem()).getNamespace(); + + if(namespace.equals(Occultism.MODID)){ + String tooltipKey = stack.getDescriptionId() + ".auto_tooltip"; + boolean tooltipExists = I18n.exists(tooltipKey); + if (tooltipExists) { + event.getToolTip().add(Component.translatable(tooltipKey).withStyle(Style.EMPTY.withColor(ChatFormatting.GRAY))); + } + } } } diff --git a/src/main/java/com/klikli_dev/occultism/registry/OccultismFoods.java b/src/main/java/com/klikli_dev/occultism/registry/OccultismFoods.java index b7e4d002b..5812e67a4 100644 --- a/src/main/java/com/klikli_dev/occultism/registry/OccultismFoods.java +++ b/src/main/java/com/klikli_dev/occultism/registry/OccultismFoods.java @@ -33,4 +33,23 @@ public class OccultismFoods { .effect(() -> new MobEffectInstance(OccultismEffects.THIRD_EYE.get(), 15 * 20, 1), 0.7f) .effect(() -> new MobEffectInstance(MobEffects.HUNGER, 15 * 20, 1), 1.0f) .build()); + + public static final NonNullLazy DEMONS_DREAM_ESSENCE = NonNullLazy.of( + () -> new FoodProperties.Builder().nutrition(0).saturationMod(0).alwaysEat() + .effect(() -> new MobEffectInstance(OccultismEffects.THIRD_EYE.get(), 60 * 20, 1), 1.0f) + .effect(() -> new MobEffectInstance(MobEffects.HUNGER, 15 * 20, 1), 1.0f) + .effect(() -> new MobEffectInstance(MobEffects.DARKNESS, 15 * 20, 1), 0.2f) + .effect(() -> new MobEffectInstance(MobEffects.GLOWING, 15 * 20, 1), 0.2f) + .effect(() -> new MobEffectInstance(MobEffects.LUCK, 5 * 60 * 20, 1), 0.2f) + .effect(() -> new MobEffectInstance(MobEffects.UNLUCK, 5 * 60 * 20, 1), 0.2f) + .effect(() -> new MobEffectInstance(MobEffects.CONFUSION, 15 * 20, 1), 0.2f) + .effect(() -> new MobEffectInstance(MobEffects.WEAKNESS, 15 * 20, 1), 0.2f) + .effect(() -> new MobEffectInstance(MobEffects.LEVITATION, 15 * 20, 1), 0.2f) + .build()); + + public static final NonNullLazy OTHERWORLD_ESSENCE = NonNullLazy.of( + () -> new FoodProperties.Builder().nutrition(0).saturationMod(0).alwaysEat() + .effect(() -> new MobEffectInstance(OccultismEffects.THIRD_EYE.get(), 60 * 20, 1), 1.0f) + .effect(() -> new MobEffectInstance(MobEffects.LUCK, 5* 60 * 20, 1), 1.0f) + .build()); } diff --git a/src/main/java/com/klikli_dev/occultism/registry/OccultismItems.java b/src/main/java/com/klikli_dev/occultism/registry/OccultismItems.java index f15295a91..69c43d2e8 100644 --- a/src/main/java/com/klikli_dev/occultism/registry/OccultismItems.java +++ b/src/main/java/com/klikli_dev/occultism/registry/OccultismItems.java @@ -187,6 +187,9 @@ public class OccultismItems { public static final DeferredItem SOUL_GEM_ITEM = ITEMS.register("soul_gem", () -> new SoulGemItem(defaultProperties().stacksTo(1))); + public static final DeferredItem SOUL_SHARD_ITEM = ITEMS.register("soul_shard", + () -> new SoulShardItem(defaultProperties().stacksTo(1))); + public static final DeferredItem SATCHEL = ITEMS.register("satchel", () -> new SatchelItem(defaultProperties().stacksTo(1).rarity(Rarity.RARE))); @@ -252,12 +255,18 @@ public class OccultismItems { //Crops public static final DeferredItem DATURA_SEEDS = - ITEMS.register("datura_seeds", () -> new ItemNameBlockItem(OccultismBlocks.DATURA.get(), defaultProperties())); + ITEMS.register("datura_seeds", () -> new ItemNameBlockItem(OccultismBlocks.DATURA.get(), defaultProperties().food(OccultismFoods.DATURA.get()))); //Foods public static final DeferredItem DATURA = ITEMS.register("datura", () -> new SpiritHealingItem(defaultProperties().food(OccultismFoods.DATURA.get()))); + public static final DeferredItem DEMONS_DREAM_ESSENCE = ITEMS.register("demons_dream_essence", + () -> new SpiritHealingItem(defaultProperties().food(OccultismFoods.DEMONS_DREAM_ESSENCE.get()))); + + public static final DeferredItem OTHERWORLD_ESSENCE = ITEMS.register("otherworld_essence", + () -> new SpiritHealingItem(defaultProperties().food(OccultismFoods.OTHERWORLD_ESSENCE.get()))); + //Miner Spirits public static final DeferredItem MAGIC_LAMP_EMPTY = ITEMS.register("magic_lamp_empty", () -> new Item(defaultProperties())); @@ -381,6 +390,8 @@ public class OccultismItems { public static final DeferredItem RITUAL_DUMMY_SUMMON_DEMONIC_WIFE = ITEMS.register("ritual_dummy/summon_demonic_wife", () -> new DummyTooltipItem(defaultProperties())); public static final DeferredItem RITUAL_DUMMY_SUMMON_DEMONIC_HUSBAND = ITEMS.register("ritual_dummy/summon_demonic_husband", () -> new DummyTooltipItem(defaultProperties())); + public static final DeferredItem RITUAL_RESURRECT_FAMILIAR = ITEMS.register("ritual_dummy/resurrect_familiar", () -> new DummyTooltipItem(defaultProperties())); + //Ritual Dummy Items static { ITEMS.register("ritual_dummy/custom_ritual", () -> new DummyTooltipItem(defaultProperties())); diff --git a/src/main/java/com/klikli_dev/occultism/registry/OccultismRituals.java b/src/main/java/com/klikli_dev/occultism/registry/OccultismRituals.java index 567a7fddb..5b29d3aa1 100644 --- a/src/main/java/com/klikli_dev/occultism/registry/OccultismRituals.java +++ b/src/main/java/com/klikli_dev/occultism/registry/OccultismRituals.java @@ -60,10 +60,14 @@ public class OccultismRituals { public static final Supplier SUMMON_WILD_HUNT = RITUAL_FACTORIES.register("summon_wild_hunt", () -> new RitualFactory(SummonWildHuntRitual::new)); - public static final DeferredHolder< RitualFactory,RitualFactory> FAMILIAR_RITUAL = + public static final DeferredHolder FAMILIAR_RITUAL = RITUAL_FACTORIES.register("familiar", () -> new RitualFactory(FamiliarRitual::new)); + public static final DeferredHolder RESURRECT_FAMILIAR_RITUAL = + RITUAL_FACTORIES.register("resurrect_familiar", + () -> new RitualFactory(ResurrectFamiliarRitual::new)); + //Crafting public static final Supplier CRAFT_RITUAL = RITUAL_FACTORIES.register("craft", diff --git a/src/main/resources/assets/occultism/textures/item/demons_dream_essence.png b/src/main/resources/assets/occultism/textures/item/demons_dream_essence.png new file mode 100644 index 000000000..80cb4fc78 Binary files /dev/null and b/src/main/resources/assets/occultism/textures/item/demons_dream_essence.png differ diff --git a/src/main/resources/assets/occultism/textures/item/otherworld_essence.png b/src/main/resources/assets/occultism/textures/item/otherworld_essence.png new file mode 100644 index 000000000..a4d43a4d3 Binary files /dev/null and b/src/main/resources/assets/occultism/textures/item/otherworld_essence.png differ diff --git a/src/main/resources/assets/occultism/textures/item/soul_shard.png b/src/main/resources/assets/occultism/textures/item/soul_shard.png new file mode 100644 index 000000000..0a2d65579 Binary files /dev/null and b/src/main/resources/assets/occultism/textures/item/soul_shard.png differ diff --git a/src/main/resources/data/occultism/recipes/crafting/demons_dream_essence_from_fruit.json b/src/main/resources/data/occultism/recipes/crafting/demons_dream_essence_from_fruit.json new file mode 100644 index 000000000..4bb72f1fc --- /dev/null +++ b/src/main/resources/data/occultism/recipes/crafting/demons_dream_essence_from_fruit.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ppp", + "ppp", + "ppp" + ], + "key": { + "p": { + "item": "occultism:datura" + } + }, + "result": { + "item": "occultism:demons_dream_essence" + } +} \ No newline at end of file diff --git a/src/main/resources/data/occultism/recipes/crafting/demons_dream_essence_from_seeds.json b/src/main/resources/data/occultism/recipes/crafting/demons_dream_essence_from_seeds.json new file mode 100644 index 000000000..bc2e931a8 --- /dev/null +++ b/src/main/resources/data/occultism/recipes/crafting/demons_dream_essence_from_seeds.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ppp", + "ppp", + "ppp" + ], + "key": { + "p": { + "item": "occultism:datura_seeds" + } + }, + "result": { + "item": "occultism:demons_dream_essence" + } +} \ No newline at end of file diff --git a/src/main/resources/data/occultism/recipes/ritual/resurrect_familiar.json b/src/main/resources/data/occultism/recipes/ritual/resurrect_familiar.json new file mode 100644 index 000000000..7975fc32e --- /dev/null +++ b/src/main/resources/data/occultism/recipes/ritual/resurrect_familiar.json @@ -0,0 +1,29 @@ +{ + "type": "occultism:ritual", + "ritual_type": "occultism:resurrect_familiar", + "activation_item": { + "item": "occultism:soul_shard" + }, + "pentacle_id": "occultism:summon_foliot", + "duration": 15, + "ritual_dummy": { + "item": "occultism:ritual_dummy/resurrect_familiar" + }, + "ingredients": [ + { + "item": "occultism:otherworld_essence" + }, + { + "item": "occultism:otherworld_essence" + }, + { + "item": "occultism:otherworld_essence" + }, + { + "item": "occultism:otherworld_essence" + } + ], + "result": { + "item": "occultism:jei_dummy/none" + } +} \ No newline at end of file diff --git a/src/main/resources/data/occultism/recipes/spirit_fire/otherworld_essence.json b/src/main/resources/data/occultism/recipes/spirit_fire/otherworld_essence.json new file mode 100644 index 000000000..c8a234b12 --- /dev/null +++ b/src/main/resources/data/occultism/recipes/spirit_fire/otherworld_essence.json @@ -0,0 +1,9 @@ +{ + "type": "occultism:spirit_fire", + "ingredient": { + "item": "occultism:demons_dream_essence" + }, + "result": { + "item": "occultism:otherworld_essence" + } +} \ No newline at end of file diff --git a/src/main/resources/data/occultism/tags/entity_types/healed_by_demons_dream_fruit.json b/src/main/resources/data/occultism/tags/entity_types/healed_by_demons_dream_fruit.json index 93fa33342..27ffb18b4 100644 --- a/src/main/resources/data/occultism/tags/entity_types/healed_by_demons_dream_fruit.json +++ b/src/main/resources/data/occultism/tags/entity_types/healed_by_demons_dream_fruit.json @@ -29,6 +29,8 @@ "occultism:fairy_familiar", "occultism:mummy_familiar", "occultism:beaver_familiar", - "occultism:shub_niggurath_spawn" + "occultism:shub_niggurath_spawn", + "occultism:demonic_wife", + "occultism:demonic_husband" ] } \ No newline at end of file