diff --git a/CHANGELOG.md b/CHANGELOG.md index 53c3c2f..4f585f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ ### Changelog +**1.0.2** +* Add Inward Spell +* Tweak Rebound Mechanic +* Allow Dispensers to Shoot Spells + **1.0.1** * Add Teleport Spell diff --git a/README.md b/README.md index 897a2be..cda8c86 100644 --- a/README.md +++ b/README.md @@ -57,4 +57,5 @@ You can apply Spells to blank or existing Spells in the Casting Table. Doing so | Dissolve | 1 | Removes target's status effects. | | Levitate | 2 | Gives target the Levitation effect. | | Steadfast | 1 | Prevents Spell from rebounding. | -| Teleport | 2 | Teleports target to random location. | \ No newline at end of file +| Teleport | 2 | Teleports target to random location. | +| Inward | 1 | Causes the Spell to target the player. If the Spell fails instead of rebounding, it will just do nothing. | \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index c5134fb..eca3adb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ org.gradle.jvmargs = -Xmx1G loader_version = 0.7.8+build.184 # Mod Properties - mod_version = 1.0.1 + mod_version = 1.0.2 maven_group = com.thebrokenrail archives_base_name = sorcerycraft diff --git a/src/main/java/com/thebrokenrail/sorcerycraft/SorceryCraft.java b/src/main/java/com/thebrokenrail/sorcerycraft/SorceryCraft.java index a310136..8629076 100644 --- a/src/main/java/com/thebrokenrail/sorcerycraft/SorceryCraft.java +++ b/src/main/java/com/thebrokenrail/sorcerycraft/SorceryCraft.java @@ -24,10 +24,14 @@ import net.fabricmc.fabric.api.loot.v1.event.LootTableLoadingCallback; import net.fabricmc.fabric.api.registry.CommandRegistry; import net.fabricmc.fabric.impl.networking.ClientSidePacketRegistryImpl; import net.fabricmc.fabric.impl.networking.ServerSidePacketRegistryImpl; +import net.minecraft.block.DispenserBlock; +import net.minecraft.block.dispenser.ProjectileDispenserBehavior; import net.minecraft.client.MinecraftClient; import net.minecraft.entity.EntityCategory; import net.minecraft.entity.EntityDimensions; import net.minecraft.entity.EntityType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.projectile.Projectile; import net.minecraft.item.BlockItem; import net.minecraft.item.Item; import net.minecraft.item.ItemGroup; @@ -35,9 +39,13 @@ import net.minecraft.item.ItemStack; import net.minecraft.loot.BinomialLootTableRange; import net.minecraft.loot.LootTables; import net.minecraft.loot.entry.ItemEntry; +import net.minecraft.sound.SoundEvent; +import net.minecraft.sound.SoundEvents; import net.minecraft.text.TranslatableText; import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPointer; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Position; import net.minecraft.util.registry.Registry; import net.minecraft.world.World; @@ -61,6 +69,8 @@ public class SorceryCraft implements ModInitializer, ClientModInitializer { LootTables.STRONGHOLD_LIBRARY_CHEST }; + public static final double SPELL_FAILURE_CHANCE = 0.3; + private boolean isSelectedLootTable(Identifier lootTable) { for (Identifier id : LOOT_TABLES) { if (id.equals(lootTable)) { @@ -81,7 +91,7 @@ public class SorceryCraft implements ModInitializer, ClientModInitializer { CASTING_TABLE_BLOCK_ITEM = new BlockItem(CASTING_TABLE_BLOCK, new Item.Settings().group(ITEM_GROUP)); SPELL_ITEM = new SpellItem(); - SPELL_ENTITY = FabricEntityTypeBuilder.create(EntityCategory.MISC, SpellEntity::new).size(EntityDimensions.fixed(0.25f, 0.25f)).build(); + SPELL_ENTITY = FabricEntityTypeBuilder.create(EntityCategory.MISC, (EntityType.EntityFactory) SpellEntity::new).size(EntityDimensions.fixed(0.25f, 0.25f)).build(); Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "spell"), SPELL_ITEM); Registry.register(Registry.BLOCK, new Identifier(NAMESPACE, "casting_table"), CASTING_TABLE_BLOCK); @@ -112,6 +122,21 @@ public class SorceryCraft implements ModInitializer, ClientModInitializer { supplier.withPool(poolBuilder); } }); + + DispenserBlock.registerBehavior(SorceryCraft.SPELL_ITEM, new ProjectileDispenserBehavior() { + @Override + protected Projectile createProjectile(World position, Position stack, ItemStack itemStack) { + SpellEntity entity = new SpellEntity(position, stack.getX(), stack.getY(), stack.getZ()); + entity.setItem(itemStack); + return entity; + } + }); + } + + private static final SoundEvent SPELL_SOUND_EFFECT = SoundEvents.BLOCK_ENCHANTMENT_TABLE_USE; + + public static void playSpellSound(PlayerEntity player) { + player.playSound(SPELL_SOUND_EFFECT, 1.0f, 1.0f); } @Override diff --git a/src/main/java/com/thebrokenrail/sorcerycraft/block/CastingTableContainer.java b/src/main/java/com/thebrokenrail/sorcerycraft/block/CastingTableContainer.java index ccb6128..ce51562 100644 --- a/src/main/java/com/thebrokenrail/sorcerycraft/block/CastingTableContainer.java +++ b/src/main/java/com/thebrokenrail/sorcerycraft/block/CastingTableContainer.java @@ -94,7 +94,7 @@ public class CastingTableContainer extends Container { player.addExperienceLevels(-spells[index].getXPCost()); } - player.playSound(SoundEvents.BLOCK_ENCHANTMENT_TABLE_USE, 1.0f, 1.0f); + SorceryCraft.playSpellSound(player); CastingTableContainer.this.inventory.setInvStack(0, ItemStack.EMPTY); CastingTableContainer.this.inventory.takeInvStack(1, spells[index].getItemCost().getCount()); diff --git a/src/main/java/com/thebrokenrail/sorcerycraft/entity/SpellEntity.java b/src/main/java/com/thebrokenrail/sorcerycraft/entity/SpellEntity.java index 4981a09..89c5fac 100644 --- a/src/main/java/com/thebrokenrail/sorcerycraft/entity/SpellEntity.java +++ b/src/main/java/com/thebrokenrail/sorcerycraft/entity/SpellEntity.java @@ -22,7 +22,7 @@ import net.minecraft.world.World; import java.util.Map; public class SpellEntity extends ThrownItemEntity { - public SpellEntity(EntityType entityType, World world) { + public SpellEntity(EntityType entityType, World world) { super(entityType, world); } @@ -30,10 +30,16 @@ public class SpellEntity extends ThrownItemEntity { super(SorceryCraft.SPELL_ENTITY, owner, world); } + private boolean firstTick = false; + public SpellEntity(World world, double x, double y, double z) { super(SorceryCraft.SPELL_ENTITY, x, y, z, world); } + private boolean didSpellSucceed(Map spells) { + return Math.random() > SorceryCraft.SPELL_FAILURE_CHANCE || spells.containsKey("steadfast_spell"); + } + @Override protected void onCollision(HitResult hitResult) { boolean remove = false; @@ -44,10 +50,11 @@ public class SpellEntity extends ThrownItemEntity { Map spells = SpellTag.getSpells(getItem()); + boolean success = didSpellSucceed(spells); for (Map.Entry entry : spells.entrySet()) { Spell spell = SpellRegistry.getSpell(entry.getKey(), entry.getValue()); if (spell != null) { - if (Math.random() > 0.3 || spells.containsKey("steadfast_spell")) { + if (success) { spell.execute(entity, this, getOwner()); } else if (getOwner() != null) { getOwner().playSound(SoundEvents.ENCHANT_THORNS_HIT, 1.0f, 1.0f); @@ -76,6 +83,20 @@ public class SpellEntity extends ThrownItemEntity { @Override public void tick() { super.tick(); + if (firstTick) { + firstTick = false; + Map spells = SpellTag.getSpells(getItem()); + if (spells.containsKey("inward_spell")) { + boolean success = didSpellSucceed(spells); + for (Map.Entry entry : spells.entrySet()) { + Spell spell = SpellRegistry.getSpell(entry.getKey(), entry.getValue()); + if (spell != null && success) { + spell.execute(getOwner(), this, getOwner()); + } + } + return; + } + } if (!getEntityWorld().isClient()) { getEntityWorld().sendEntityStatus(this, (byte) 0); } diff --git a/src/main/java/com/thebrokenrail/sorcerycraft/item/SpellItem.java b/src/main/java/com/thebrokenrail/sorcerycraft/item/SpellItem.java index 1dde1b0..af88084 100644 --- a/src/main/java/com/thebrokenrail/sorcerycraft/item/SpellItem.java +++ b/src/main/java/com/thebrokenrail/sorcerycraft/item/SpellItem.java @@ -7,6 +7,7 @@ import com.thebrokenrail.sorcerycraft.spell.Spell; import com.thebrokenrail.sorcerycraft.spell.SpellPlayerEntity; import com.thebrokenrail.sorcerycraft.spell.SpellRegistry; import com.thebrokenrail.sorcerycraft.spell.SpellTag; +import net.minecraft.block.dispenser.ProjectileDispenserBehavior; import net.minecraft.client.item.TooltipContext; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; @@ -42,7 +43,7 @@ public class SpellItem extends Item { Map spells = SpellTag.getSpells(itemStack); if (spells.size() > 0) { - playerEntity.playSound(SoundEvents.BLOCK_ENCHANTMENT_TABLE_USE, 1.0f, 1.0f); + SorceryCraft.playSpellSound(playerEntity); if (!world.isClient()) { SpellEntity entity = new SpellEntity(world, playerEntity); diff --git a/src/main/java/com/thebrokenrail/sorcerycraft/packet/LearnedNewSpellS2CPacket.java b/src/main/java/com/thebrokenrail/sorcerycraft/packet/LearnedNewSpellS2CPacket.java index 1c56218..33d8941 100644 --- a/src/main/java/com/thebrokenrail/sorcerycraft/packet/LearnedNewSpellS2CPacket.java +++ b/src/main/java/com/thebrokenrail/sorcerycraft/packet/LearnedNewSpellS2CPacket.java @@ -5,7 +5,6 @@ import io.netty.buffer.Unpooled; import net.fabricmc.fabric.api.network.PacketContext; import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.sound.SoundEvents; import net.minecraft.util.Identifier; import net.minecraft.util.PacketByteBuf; @@ -13,7 +12,7 @@ public class LearnedNewSpellS2CPacket { @SuppressWarnings("unused") public static void handle(PacketContext context, PacketByteBuf bytes) { if (context.getPlayer() != null) { - context.getPlayer().playSound(SoundEvents.BLOCK_ENCHANTMENT_TABLE_USE, 1.0f, 1.0f); + SorceryCraft.playSpellSound(context.getPlayer()); } } diff --git a/src/main/java/com/thebrokenrail/sorcerycraft/spell/InwardSpell.java b/src/main/java/com/thebrokenrail/sorcerycraft/spell/InwardSpell.java new file mode 100644 index 0000000..c3f819f --- /dev/null +++ b/src/main/java/com/thebrokenrail/sorcerycraft/spell/InwardSpell.java @@ -0,0 +1,30 @@ +package com.thebrokenrail.sorcerycraft.spell; + +import net.minecraft.entity.Entity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; + +public class InwardSpell extends Spell { + public InwardSpell(String id, int level) { + super(id, level); + } + + @Override + public void execute(Entity target, Entity source, Entity attacker) { + } + + @Override + public int getXPCost() { + return 16; + } + + @Override + public ItemStack getItemCost() { + return new ItemStack(Items.BLAZE_ROD); + } + + @Override + public int getMaxLevel() { + return 1; + } +} diff --git a/src/main/java/com/thebrokenrail/sorcerycraft/spell/SpellRegistry.java b/src/main/java/com/thebrokenrail/sorcerycraft/spell/SpellRegistry.java index e16c5ae..3a8bfc0 100644 --- a/src/main/java/com/thebrokenrail/sorcerycraft/spell/SpellRegistry.java +++ b/src/main/java/com/thebrokenrail/sorcerycraft/spell/SpellRegistry.java @@ -58,5 +58,6 @@ public class SpellRegistry { SpellRegistry.registerSpell("flame_spell", FlameSpell.class); SpellRegistry.registerSpell("levitate_spell", LevitateSpell.class); SpellRegistry.registerSpell("teleport_spell", TeleportSpell.class); + SpellRegistry.registerSpell("inward_spell", InwardSpell.class); } }