Port To 1.16.1
SorceryCraft/pipeline/head This commit looks good Details

This commit is contained in:
TheBrokenRail 2020-06-24 11:43:53 -04:00
parent 3f06723a1f
commit 162df5c962
14 changed files with 60 additions and 59 deletions

View File

@ -38,12 +38,12 @@ dependencies {
} }
processResources { processResources {
inputs.property 'version', mod_version inputs.property 'version', project.version
inputs.property 'name', rootProject.name inputs.property 'name', rootProject.name
from(sourceSets.main.resources.srcDirs) { from(sourceSets.main.resources.srcDirs) {
include 'fabric.mod.json' include 'fabric.mod.json'
expand 'version': mod_version, 'name': rootProject.name expand 'version': project.version, 'name': rootProject.name
} }
from(sourceSets.main.resources.srcDirs) { from(sourceSets.main.resources.srcDirs) {

View File

@ -3,11 +3,11 @@ org.gradle.jvmargs = -Xmx1G
# Fabric Properties # Fabric Properties
# check these on https://fabricmc.net/use # check these on https://fabricmc.net/use
minecraft_version = 20w18a minecraft_version = 1.16.1
curseforge_id = 365308 curseforge_id = 365308
simple_minecraft_version = 1.16-Snapshot simple_minecraft_version = 1.16.1
yarn_build = 13 yarn_build = 1
fabric_loader_version = 0.8.2+build.194 fabric_loader_version = 0.8.8+build.202
# Mod Properties # Mod Properties
mod_version = 1.2.9 mod_version = 1.2.9
@ -16,7 +16,7 @@ org.gradle.jvmargs = -Xmx1G
# Dependencies # Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
fabric_api_version = 0.10.1+build.336-1.16 fabric_api_version = 0.13.1+build.370-1.16
cloth_config_version = 4.0.8-unstable cloth_config_version = 4.5.6
auto_config_version = 3.0.1-unstable auto_config_version = 3.2.0-unstable
mod_menu_version = 1.11.2+build.6 mod_menu_version = 1.12.2+build.16

View File

@ -22,9 +22,9 @@ import net.fabricmc.fabric.api.registry.CommandRegistry;
import net.fabricmc.fabric.impl.networking.ServerSidePacketRegistryImpl; import net.fabricmc.fabric.impl.networking.ServerSidePacketRegistryImpl;
import net.minecraft.block.DispenserBlock; import net.minecraft.block.DispenserBlock;
import net.minecraft.block.dispenser.ProjectileDispenserBehavior; import net.minecraft.block.dispenser.ProjectileDispenserBehavior;
import net.minecraft.entity.EntityCategory;
import net.minecraft.entity.EntityDimensions; import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnGroup;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
@ -34,7 +34,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.loot.BinomialLootTableRange; import net.minecraft.loot.BinomialLootTableRange;
import net.minecraft.loot.LootTables; import net.minecraft.loot.LootTables;
import net.minecraft.loot.entry.ItemEntry; import net.minecraft.loot.entry.ItemEntry;
import net.minecraft.loot.function.LootFunctions; import net.minecraft.loot.function.LootFunctionType;
import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
@ -111,7 +111,7 @@ public class SorceryCraft implements ModInitializer {
CASTING_TABLE_BLOCK_ITEM = new BlockItem(CASTING_TABLE_BLOCK, new Item.Settings().group(ITEM_GROUP)); CASTING_TABLE_BLOCK_ITEM = new BlockItem(CASTING_TABLE_BLOCK, new Item.Settings().group(ITEM_GROUP));
SPELL_ITEM = new SpellItem(); SPELL_ITEM = new SpellItem();
SPELL_ENTITY = FabricEntityTypeBuilder.create(EntityCategory.MISC, (EntityType.EntityFactory<SpellEntity>) SpellEntity::new).size(EntityDimensions.fixed(0.25f, 0.25f)).build(); SPELL_ENTITY = FabricEntityTypeBuilder.create(SpawnGroup.MISC, (EntityType.EntityFactory<SpellEntity>) SpellEntity::new).size(EntityDimensions.fixed(0.25f, 0.25f)).build();
Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "spell"), SPELL_ITEM); Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "spell"), SPELL_ITEM);
Registry.register(Registry.BLOCK, new Identifier(NAMESPACE, "casting_table"), CASTING_TABLE_BLOCK); Registry.register(Registry.BLOCK, new Identifier(NAMESPACE, "casting_table"), CASTING_TABLE_BLOCK);
@ -131,14 +131,14 @@ public class SorceryCraft implements ModInitializer {
LootTableLoadingCallback.EVENT.register((resourceManager, lootManager, id, supplier, setter) -> { LootTableLoadingCallback.EVENT.register((resourceManager, lootManager, id, supplier, setter) -> {
if (isSelectedLootTable(id)) { if (isSelectedLootTable(id)) {
FabricLootPoolBuilder poolBuilder = FabricLootPoolBuilder.builder() FabricLootPoolBuilder poolBuilder = FabricLootPoolBuilder.builder()
.withRolls(new BinomialLootTableRange(2, 0.5f)) .rolls(new BinomialLootTableRange(2, 0.5f))
.withEntry(ItemEntry.builder(SPELL_ITEM)) .withEntry(ItemEntry.builder(SPELL_ITEM).build())
.withFunction(new RandomSpellLootTableFunction.Builder()); .withFunction(new RandomSpellLootTableFunction.Builder().build());
supplier.withPool(poolBuilder); supplier.withPool(poolBuilder.build());
} }
}); });
LootFunctions.register(new RandomSpellLootTableFunction.Factory()); Registry.register(Registry.LOOT_FUNCTION_TYPE, new Identifier(NAMESPACE, "random_spell"), new LootFunctionType(new RandomSpellLootTableFunction.Factory()));
DispenserBlock.registerBehavior(SorceryCraft.SPELL_ITEM, new ProjectileDispenserBehavior() { DispenserBlock.registerBehavior(SorceryCraft.SPELL_ITEM, new ProjectileDispenserBehavior() {
@Override @Override

View File

@ -32,7 +32,7 @@ public class SorceryCraftClient implements ClientModInitializer {
GuiRegistry guiRegistry = AutoConfig.getGuiRegistry(ModConfig.class); GuiRegistry guiRegistry = AutoConfig.getGuiRegistry(ModConfig.class);
guiRegistry.registerAnnotationProvider((s, field, config, defaults, guiRegistryAccess) -> { guiRegistry.registerAnnotationProvider((s, field, config, defaults, guiRegistryAccess) -> {
ModConfig.UsePercentage bounds = field.getAnnotation(ModConfig.UsePercentage.class); ModConfig.UsePercentage bounds = field.getAnnotation(ModConfig.UsePercentage.class);
return Collections.singletonList(ConfigEntryBuilder.create().startIntSlider(new LiteralText(s), MathHelper.ceil(Utils.getUnsafely(field, config, 0.0) * 100), MathHelper.ceil(bounds.min() * 100), MathHelper.ceil(bounds.max() * 100)).setDefaultValue(() -> MathHelper.ceil((double) Utils.getUnsafely(field, defaults) * 100)).setSaveConsumer((newValue) -> Utils.setUnsafely(field, config, newValue / 100d)).setTextGetter(integer -> new LiteralText(String.format("%d%%", integer))).build()); return Collections.singletonList(ConfigEntryBuilder.create().startIntSlider(new TranslatableText(s), MathHelper.ceil(Utils.getUnsafely(field, config, 0.0) * 100), MathHelper.ceil(bounds.min() * 100), MathHelper.ceil(bounds.max() * 100)).setDefaultValue(() -> MathHelper.ceil((double) Utils.getUnsafely(field, defaults) * 100)).setSaveConsumer((newValue) -> Utils.setUnsafely(field, config, newValue / 100d)).setTextGetter(integer -> new LiteralText(String.format("%d%%", integer))).build());
}, field -> field.getType() == Double.TYPE || field.getType() == Double.class, ModConfig.UsePercentage.class); }, field -> field.getType() == Double.TYPE || field.getType() == Double.class, ModConfig.UsePercentage.class);
EntityRendererRegistry.INSTANCE.register(SorceryCraft.SPELL_ENTITY, (entityRenderDispatcher, context) -> new SpellEntityRenderer(entityRenderDispatcher)); EntityRendererRegistry.INSTANCE.register(SorceryCraft.SPELL_ENTITY, (entityRenderDispatcher, context) -> new SpellEntityRenderer(entityRenderDispatcher));

View File

@ -15,6 +15,7 @@ import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
import net.minecraft.text.StringRenderable;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText; import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@ -35,10 +36,10 @@ public class CastingTableScreen extends HandledScreen<CastingTableScreenHandler>
@Override @Override
protected void drawForeground(MatrixStack matrixStack, int i, int j) { protected void drawForeground(MatrixStack matrixStack, int i, int j) {
int titleY = backgroundHeight - 94; int titleY = backgroundHeight - 94;
textRenderer.draw(matrixStack, title, (float) (49 + this.backgroundWidth / 2 - textRenderer.getStringWidth(title) / 2), 6.0F, 4210752); textRenderer.draw(matrixStack, title, (float) (49 + this.backgroundWidth / 2 - textRenderer.getWidth(title) / 2), 6.0F, 4210752);
textRenderer.draw(matrixStack, playerInventory.getDisplayName(), 107.0F, (float) titleY, 4210752); textRenderer.draw(matrixStack, playerInventory.getDisplayName(), 107.0F, (float) titleY, 4210752);
Text spells = new TranslatableText("container." + SorceryCraft.NAMESPACE + ".spells"); Text spells = new TranslatableText("container." + SorceryCraft.NAMESPACE + ".spells");
textRenderer.draw(matrixStack, spells, (float) (5 - textRenderer.getStringWidth(spells) / 2 + 48), 6.0F, 4210752); textRenderer.draw(matrixStack, spells, (float) (5 - textRenderer.getWidth(spells) / 2 + 48), 6.0F, 4210752);
renderXPCost(matrixStack); renderXPCost(matrixStack);
} }
@ -106,7 +107,7 @@ public class CastingTableScreen extends HandledScreen<CastingTableScreenHandler>
itemRenderer.zOffset = 100.0F; itemRenderer.zOffset = 100.0F;
int y = k + 2; int y = k + 2;
itemRenderer.renderGuiItem(itemStack, i + 5 + 68, y); itemRenderer.renderInGuiWithOverrides(itemStack, i + 5 + 68, y);
itemRenderer.renderGuiItemOverlay(textRenderer, itemStack, i + 5 + 68, y); itemRenderer.renderGuiItemOverlay(textRenderer, itemStack, i + 5 + 68, y);
itemRenderer.zOffset = 0.0F; itemRenderer.zOffset = 0.0F;
k += 20; k += 20;
@ -126,7 +127,7 @@ public class CastingTableScreen extends HandledScreen<CastingTableScreenHandler>
} }
int x2 = backgroundWidth - 8; int x2 = backgroundWidth - 8;
int x1 = x2 - textRenderer.getStringWidth(string); int x1 = x2 - textRenderer.getWidth(string);
fill(matrixStack, x1, 65, x2, 77, 1325400064); fill(matrixStack, x1, 65, x2, 77, 1325400064);
textRenderer.drawWithShadow(matrixStack, string, (float) x1, 67.0F, color); textRenderer.drawWithShadow(matrixStack, string, (float) x1, 67.0F, color);
} }
@ -230,8 +231,8 @@ public class CastingTableScreen extends HandledScreen<CastingTableScreenHandler>
} }
@Override @Override
public void drawCenteredString(MatrixStack matrixStack, TextRenderer textRenderer, String str, int centerX, int y, int color) { public void drawCenteredText(MatrixStack matrices, TextRenderer textRenderer, StringRenderable stringRenderable, int x, int y, int color) {
drawString(matrixStack, textRenderer, str, x + 5, y, color); drawStringWithShadow(matrices, textRenderer, stringRenderable.getString(), this.x + 5, y, color);
} }
} }
} }

View File

@ -7,9 +7,9 @@ import com.thebrokenrail.sorcerycraft.spell.api.registry.SpellRegistry;
import com.thebrokenrail.sorcerycraft.spell.util.SpellHelper; import com.thebrokenrail.sorcerycraft.spell.util.SpellHelper;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.BasicInventory;
import net.minecraft.inventory.CraftingResultInventory; import net.minecraft.inventory.CraftingResultInventory;
import net.minecraft.inventory.Inventory; import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.SimpleInventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.screen.ScreenHandler; import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.ScreenHandlerContext; import net.minecraft.screen.ScreenHandlerContext;
@ -35,7 +35,7 @@ public class CastingTableScreenHandler extends ScreenHandler {
public CastingTableScreenHandler(int syncId, PlayerInventory playerInventory, ScreenHandlerContext blockContext) { public CastingTableScreenHandler(int syncId, PlayerInventory playerInventory, ScreenHandlerContext blockContext) {
super(ScreenHandlerType.STONECUTTER, syncId); super(ScreenHandlerType.STONECUTTER, syncId);
inventory = new BasicInventory(2) { inventory = new SimpleInventory(2) {
public void markDirty() { public void markDirty() {
super.markDirty(); super.markDirty();
CastingTableScreenHandler.this.onContentChanged(this); CastingTableScreenHandler.this.onContentChanged(this);

View File

@ -53,15 +53,15 @@ public class SpellItem extends Item {
} }
@Override @Override
public boolean useOnEntity(ItemStack stack, PlayerEntity user, LivingEntity entity, Hand hand) { public ActionResult useOnEntity(ItemStack stack, PlayerEntity user, LivingEntity entity, Hand hand) {
use(user.getEntityWorld(), user, hand); use(user.getEntityWorld(), user, hand);
return true; return ActionResult.SUCCESS;
} }
@Override @Override
public boolean hasEnchantmentGlint(ItemStack stack) { public boolean hasGlint(ItemStack stack) {
Map<Identifier, Integer> spells = SpellHelper.getSpells(stack); Map<Identifier, Integer> spells = SpellHelper.getSpells(stack);
return spells.size() > 0 || super.hasEnchantmentGlint(stack); return spells.size() > 0 || super.hasGlint(stack);
} }
@Override @Override

View File

@ -18,7 +18,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Map; import java.util.Map;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Environment(EnvType.SERVER)
@Mixin(ServerPlayerEntity.class) @Mixin(ServerPlayerEntity.class)
public abstract class MixinServerPlayerEntity extends MixinPlayerEntity implements SpellServerPlayerEntity { public abstract class MixinServerPlayerEntity extends MixinPlayerEntity implements SpellServerPlayerEntity {
@Inject(at = @At("HEAD"), method = "copyFrom") @Inject(at = @At("HEAD"), method = "copyFrom")

View File

@ -1,18 +1,13 @@
package com.thebrokenrail.sorcerycraft.spell; package com.thebrokenrail.sorcerycraft.spell;
import com.thebrokenrail.sorcerycraft.spell.api.Spell; import com.thebrokenrail.sorcerycraft.spell.api.Spell;
import net.minecraft.block.AbstractFireBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.TntBlock;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.item.FlintAndSteelItem; import net.minecraft.item.AutomaticItemPlacementContext;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.state.property.Properties;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
public class FlameSpell extends Spell { public class FlameSpell extends Spell {
@ -30,20 +25,7 @@ public class FlameSpell extends Spell {
@Override @Override
public void execute(World world, Entity source, Entity attacker, BlockHitResult hitResult) { public void execute(World world, Entity source, Entity attacker, BlockHitResult hitResult) {
BlockPos blockPos = hitResult.getBlockPos(); Items.FLINT_AND_STEEL.useOnBlock(new AutomaticItemPlacementContext(world, hitResult.getBlockPos(), hitResult.getSide().getOpposite(), new ItemStack(Items.FLINT_AND_STEEL), hitResult.getSide()));
BlockState blockState = world.getBlockState(blockPos);
BlockPos sideBlockPos = hitResult.getBlockPos().offset(hitResult.getSide());
BlockState sideBlockState = world.getBlockState(sideBlockPos);
if (blockState.getBlock() instanceof TntBlock) {
TntBlock.primeTnt(world, blockPos);
world.removeBlock(blockPos, false);
} else if (FlintAndSteelItem.canIgnite(sideBlockState, world, sideBlockPos)) {
world.setBlockState(sideBlockPos, AbstractFireBlock.getState(world, sideBlockPos));
} else if (FlintAndSteelItem.isIgnitable(blockState)) {
world.setBlockState(blockPos, blockState.with(Properties.LIT, true));
}
} }
@Override @Override

View File

@ -2,6 +2,7 @@ package com.thebrokenrail.sorcerycraft.spell;
import com.thebrokenrail.sorcerycraft.spell.api.Spell; import com.thebrokenrail.sorcerycraft.spell.api.Spell;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LightningEntity; import net.minecraft.entity.LightningEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.Items; import net.minecraft.item.Items;
@ -29,11 +30,13 @@ public class LightningSpell extends Spell {
private void strike(World world, Vec3d pos, Entity attacker) { private void strike(World world, Vec3d pos, Entity attacker) {
ServerWorld serverWorld = (ServerWorld) world; ServerWorld serverWorld = (ServerWorld) world;
LightningEntity lightningEntity = new LightningEntity(world, pos.getX(), pos.getY(), pos.getZ(), false); LightningEntity lightningEntity = EntityType.LIGHTNING_BOLT.create(world);
assert lightningEntity != null;
lightningEntity.updatePosition(pos.x, pos.y, pos.z);
if (attacker instanceof ServerPlayerEntity) { if (attacker instanceof ServerPlayerEntity) {
lightningEntity.setChanneller((ServerPlayerEntity) attacker); lightningEntity.setChanneller((ServerPlayerEntity) attacker);
} }
serverWorld.addLightning(lightningEntity); serverWorld.spawnEntity(lightningEntity);
} }
@Override @Override

View File

@ -17,7 +17,7 @@ public class TeleportSpell extends Spell {
} }
private int getMaxTeleport(World world) { private int getMaxTeleport(World world) {
return world.getDimension().isNether() ? 128 : 256; return world.getRegistryKey() != World.OVERWORLD ? 128 : 256;
} }
@Override @Override

View File

@ -10,7 +10,9 @@ import net.minecraft.loot.condition.LootCondition;
import net.minecraft.loot.context.LootContext; import net.minecraft.loot.context.LootContext;
import net.minecraft.loot.function.ConditionalLootFunction; import net.minecraft.loot.function.ConditionalLootFunction;
import net.minecraft.loot.function.LootFunction; import net.minecraft.loot.function.LootFunction;
import net.minecraft.loot.function.LootFunctionType;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import java.util.Map; import java.util.Map;
@ -32,14 +34,19 @@ public class RandomSpellLootTableFunction extends ConditionalLootFunction {
return stack; return stack;
} }
public static class Factory extends ConditionalLootFunction.Factory<RandomSpellLootTableFunction> { @Override
public LootFunctionType getType() {
return Registry.LOOT_FUNCTION_TYPE.get(new Identifier(SorceryCraft.NAMESPACE, "random_spell"));
}
public static class Factory extends ConditionalLootFunction.Serializer<RandomSpellLootTableFunction> {
public Factory() { public Factory() {
super(new Identifier(SorceryCraft.NAMESPACE, "random_spell"), RandomSpellLootTableFunction.class); super();
} }
@Override @Override
public RandomSpellLootTableFunction fromJson(JsonObject json, JsonDeserializationContext context, LootCondition[] conditions) { public RandomSpellLootTableFunction fromJson(JsonObject json, JsonDeserializationContext context, LootCondition[] conditions) {
return (RandomSpellLootTableFunction) new Builder().build(); return (RandomSpellLootTableFunction) new com.thebrokenrail.sorcerycraft.spell.util.RandomSpellLootTableFunction.Builder().build();
} }
} }

View File

@ -8,6 +8,8 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag; import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.network.MessageType;
import net.minecraft.network.packet.s2c.play.GameMessageS2CPacket;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
import net.minecraft.text.MutableText; import net.minecraft.text.MutableText;
@ -15,6 +17,7 @@ import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText; import net.minecraft.text.TranslatableText;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
import net.minecraft.world.World; import net.minecraft.world.World;
import java.util.HashMap; import java.util.HashMap;
@ -121,7 +124,7 @@ public class SpellHelper {
playerSpells.put(spell.getID(), spell.getLevel()); playerSpells.put(spell.getID(), spell.getLevel());
assert world.getServer() != null; assert world.getServer() != null;
Text text = getTranslatedSpellChat(spell.getID(), spell.getLevel()); Text text = getTranslatedSpellChat(spell.getID(), spell.getLevel());
world.getServer().getPlayerManager().sendToAll(new TranslatableText("chat." + SorceryCraft.NAMESPACE + ".discovered_spell", player.getDisplayName(), text)); world.getServer().getPlayerManager().sendToAll(new GameMessageS2CPacket(new TranslatableText("chat." + SorceryCraft.NAMESPACE + ".discovered_spell", player.getDisplayName(), text), MessageType.CHAT, Util.NIL_UUID));
} }
} }
} }

View File

@ -33,5 +33,11 @@
"fabricloader": ">=0.7.4", "fabricloader": ">=0.7.4",
"fabric": "*", "fabric": "*",
"minecraft": "1.16.x" "minecraft": "1.16.x"
},
"custom": {
"modupdater": {
"strategy": "curseforge",
"projectID": 365308
}
} }
} }