Compare commits

...

19 Commits

Author SHA1 Message Date
TheBrokenRail 5381263113 Auto-Publish
SorceryCraft/pipeline/head This commit looks good Details
2020-12-15 14:04:06 -05:00
TheBrokenRail 263466eed3 1.16.4
SorceryCraft/pipeline/head This commit looks good Details
2020-12-15 14:00:42 -05:00
TheBrokenRail 10bfbdb53d Update Loom
SorceryCraft/pipeline/head This commit looks good Details
2020-06-24 18:09:42 -04:00
TheBrokenRail 162df5c962 Port To 1.16.1
SorceryCraft/pipeline/head This commit looks good Details
2020-06-24 11:43:53 -04:00
TheBrokenRail 3f06723a1f 1.2.9
SorceryCraft/pipeline/head This commit looks good Details
Fix Dedicated Server Crash
2020-05-24 16:55:23 -04:00
TheBrokenRail 700b970a04 Fix Config
SorceryCraft/pipeline/head This commit looks good Details
2020-05-02 15:21:29 -04:00
TheBrokenRail 3bfe235d97 Fix HTML Publish
SorceryCraft/pipeline/head This commit looks good Details
2020-05-02 14:54:43 -04:00
TheBrokenRail 48fef73096 20w18a
SorceryCraft/pipeline/head There was a failure building this commit Details
2020-05-02 14:42:16 -04:00
TheBrokenRail 504a52597d 1.2.8
SorceryCraft/pipeline/head This commit looks good Details
Register Loot Table Function
2020-04-11 13:49:08 -04:00
TheBrokenRail 55808ca049 Fix Gradle
SorceryCraft/pipeline/head This commit looks good Details
2020-04-03 11:47:55 -04:00
TheBrokenRail e5aa71f751 20w14a
SorceryCraft/pipeline/head This commit looks good Details
2020-04-03 11:45:44 -04:00
TheBrokenRail 0664de5de5 Use @Unique
SorceryCraft/pipeline/head This commit looks good Details
2020-03-27 14:07:47 -04:00
TheBrokenRail 4d0e4b6411 20w13b
SorceryCraft/pipeline/head This commit looks good Details
2020-03-26 11:48:22 -04:00
TheBrokenRail 114c3a03d2 1.2.7
SorceryCraft/pipeline/head This commit looks good Details
Fix Cooling Spell Bug
2020-03-25 16:19:41 -04:00
TheBrokenRail 6b3445e1f6 Update Fabric API
SorceryCraft/pipeline/head This commit looks good Details
2020-03-25 15:04:33 -04:00
TheBrokenRail 14f254af3d Update Cloth Config
SorceryCraft/pipeline/head This commit looks good Details
2020-03-25 14:02:03 -04:00
TheBrokenRail 8a23afeed0 20w13a
SorceryCraft/pipeline/head This commit looks good Details
2020-03-25 13:58:00 -04:00
TheBrokenRail 8ca4986714 1.2.6
SorceryCraft/pipeline/head This commit looks good Details
Fix Potential Client-Server De-sync Bug
2020-03-24 15:31:35 -04:00
TheBrokenRail fb3ba1411f Remove Unused Import
SorceryCraft/pipeline/head This commit looks good Details
2020-03-24 13:12:12 -04:00
30 changed files with 289 additions and 145 deletions

4
API.md
View File

@ -4,7 +4,7 @@
1. Add Dependency to Gradle
```gradle
repositories {
maven { url 'https://jitpack.io' }
maven { url 'https://maven.thebrokenrail.com' }
}
dependencies {
modImplementation 'com.thebrokenrail:sorcerycraft:VERSION'
@ -112,4 +112,4 @@ APIs are only guaranteed to be stable in the ```com.thebrokenrail.sorcerycraft.a
Spell levels are 0-indexed, if you have a level 1 Example Spell, ```Spell.getLevel()``` wil return 0, and if it is level 2 ```Spell.getLevel()``` wil return 1, ```Spell.getMaxSpell()``` should be the maximum-acceptable value of ```Spell.getLevel() + 1```, so if Example Spell has levels 1-2, ```Spell.getMaxLevel()``` should return 2.
## JavaDoc
[View JavaDoc](https://javadoc.jitpack.io/com/thebrokenrail/sorcerycraft/latest/javadoc/index.html)
[View JavaDoc](https://jenkins.thebrokenrail.com/job/SorceryCraft/job/master/JavaDoc/)

View File

@ -1,5 +1,17 @@
# Changelog
**1.2.9**
* Fix Dedicated Server Crash
**1.2.8**
* Register Loot Table Function
**1.2.7**
* Fix Cooling Spell Bug
**1.2.6**
* Fix Potential Client-Server De-sync Bug
**1.2.5**
* Fix Casting Table Bug

23
Jenkinsfile vendored
View File

@ -7,11 +7,32 @@ pipeline {
stages {
stage('Build') {
steps {
sh './gradlew build'
sh './gradlew build javadoc'
}
post {
success {
archiveArtifacts artifacts: 'build/libs/*', fingerprint: true
publishHTML target: [
allowMissing: false,
alwaysLinkToLastBuild: false,
keepAll: false,
reportDir: 'build/docs/javadoc',
reportFiles: 'index.html',
reportName: 'JavaDoc'
]
}
}
}
stage('Publish') {
when {
expression {
return sh(returnStdout: true, script: 'git tag --contains').trim().length() > 0
}
}
steps {
withCredentials([string(credentialsId: 'curseforge_key', variable: 'CURSEFORGE_KEY')]) {
sh './gradlew -Pcurseforge.api_key="${CURSEFORGE_KEY}" curseforge publish'
}
}
}

View File

@ -1,6 +1,7 @@
plugins {
id 'fabric-loom' version '0.2.7-SNAPSHOT'
id 'fabric-loom' version '0.4-SNAPSHOT'
id 'com.matthewprenger.cursegradle' version '1.4.0'
id 'maven-publish'
}
compileJava {
@ -37,12 +38,12 @@ dependencies {
}
processResources {
inputs.property 'version', mod_version
inputs.property 'version', project.version
inputs.property 'name', rootProject.name
from(sourceSets.main.resources.srcDirs) {
include 'fabric.mod.json'
expand 'version': mod_version, 'name': rootProject.name
expand 'version': project.version, 'name': rootProject.name
}
from(sourceSets.main.resources.srcDirs) {
@ -79,6 +80,23 @@ jar {
from "LICENSE"
}
publishing {
publications {
mavenJava(MavenPublication) {
artifactId archivesBaseName
artifact(remapJar) {
builtBy remapJar
}
}
}
repositories {
maven {
url '/data/maven'
}
}
}
if (project.hasProperty('curseforge.api_key')) {
curseforge {
apiKey = project.getProperty('curseforge.api_key')

View File

@ -3,20 +3,20 @@ org.gradle.jvmargs = -Xmx1G
# Fabric Properties
# check these on https://fabricmc.net/use
minecraft_version = 20w12a
minecraft_version = 1.16.4
curseforge_id = 365308
simple_minecraft_version = 1.16-Snapshot
yarn_build = 18
fabric_loader_version = 0.7.8+build.189
simple_minecraft_version = 1.16.4
yarn_build = 7
fabric_loader_version = 0.10.8
# Mod Properties
mod_version = 1.2.5
mod_version = 1.2.9
maven_group = com.thebrokenrail
archives_base_name = sorcerycraft
# Dependencies
# 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.5.5+build.311-1.16
cloth_config_version = 3.1.0-unstable
auto_config_version = 1.2.4
mod_menu_version = 1.11.0+build.2
fabric_api_version = 0.28.1+1.16
cloth_config_version = 4.8.3
auto_config_version = 3.3.1
mod_menu_version = 1.14.13+build.19

View File

@ -6,7 +6,7 @@ import com.thebrokenrail.sorcerycraft.block.CastingTableBlock;
import com.thebrokenrail.sorcerycraft.command.SpellCommand;
import com.thebrokenrail.sorcerycraft.entity.SpellEntity;
import com.thebrokenrail.sorcerycraft.item.SpellItem;
import com.thebrokenrail.sorcerycraft.mixin.CriterionRegistryHook;
import com.thebrokenrail.sorcerycraft.mixin.CriteriaRegistryHook;
import com.thebrokenrail.sorcerycraft.packet.SelectSpellC2SPacket;
import com.thebrokenrail.sorcerycraft.spell.util.RandomSpellLootTableFunction;
import com.thebrokenrail.sorcerycraft.spell.api.registry.Spells;
@ -22,9 +22,9 @@ import net.fabricmc.fabric.api.registry.CommandRegistry;
import net.fabricmc.fabric.impl.networking.ServerSidePacketRegistryImpl;
import net.minecraft.block.DispenserBlock;
import net.minecraft.block.dispenser.ProjectileDispenserBehavior;
import net.minecraft.entity.EntityCategory;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnGroup;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.item.BlockItem;
@ -34,6 +34,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.loot.BinomialLootTableRange;
import net.minecraft.loot.LootTables;
import net.minecraft.loot.entry.ItemEntry;
import net.minecraft.loot.function.LootFunctionType;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents;
@ -96,6 +97,7 @@ public class SorceryCraft implements ModInitializer {
@Override
public void onInitialize() {
//noinspection InstantiationOfUtilityClass
new Spells();
AutoConfig.register(ModConfig.class, GsonConfigSerializer::new);
@ -109,7 +111,7 @@ public class SorceryCraft implements ModInitializer {
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, (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.BLOCK, new Identifier(NAMESPACE, "casting_table"), CASTING_TABLE_BLOCK);
@ -129,13 +131,14 @@ public class SorceryCraft implements ModInitializer {
LootTableLoadingCallback.EVENT.register((resourceManager, lootManager, id, supplier, setter) -> {
if (isSelectedLootTable(id)) {
FabricLootPoolBuilder poolBuilder = FabricLootPoolBuilder.builder()
.withRolls(new BinomialLootTableRange(2, 0.5f))
.withEntry(ItemEntry.builder(SPELL_ITEM))
.withFunction(new RandomSpellLootTableFunction.Builder());
.rolls(new BinomialLootTableRange(2, 0.5f))
.withEntry(ItemEntry.builder(SPELL_ITEM).build())
.withFunction(new RandomSpellLootTableFunction.Builder().build());
supplier.withPool(poolBuilder);
supplier.withPool(poolBuilder.build());
}
});
Registry.register(Registry.LOOT_FUNCTION_TYPE, new Identifier(NAMESPACE, "random_spell"), new LootFunctionType(new RandomSpellLootTableFunction.Factory()));
DispenserBlock.registerBehavior(SorceryCraft.SPELL_ITEM, new ProjectileDispenserBehavior() {
@Override
@ -154,8 +157,8 @@ public class SorceryCraft implements ModInitializer {
INTERACT_WITH_CASTING_TABLE_STAT = registerStat("interact_with_casting_table");
CAST_SPELL_STAT = registerStat("cast_spell");
DISCOVER_ALL_SPELLS_CRITERION = CriterionRegistryHook.callRegister(new DiscoverAllSpellsCriterion());
CREATE_SPELL_CRITERION = CriterionRegistryHook.callRegister(new CreateSpellCriterion());
DISCOVER_ALL_SPELLS_CRITERION = CriteriaRegistryHook.callRegister(new DiscoverAllSpellsCriterion());
CREATE_SPELL_CRITERION = CriteriaRegistryHook.callRegister(new CreateSpellCriterion());
}
private Identifier registerStat(String name) {

View File

@ -1,10 +1,11 @@
package com.thebrokenrail.sorcerycraft.advancement;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import com.thebrokenrail.sorcerycraft.SorceryCraft;
import net.minecraft.advancement.criterion.AbstractCriterion;
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer;
import net.minecraft.predicate.entity.EntityPredicate;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
@ -14,21 +15,23 @@ public class CreateSpellCriterion extends AbstractCriterion<CreateSpellCriterion
public CreateSpellCriterion() {
}
@Override
protected Conditions conditionsFromJson(JsonObject obj, EntityPredicate.Extended playerPredicate, AdvancementEntityPredicateDeserializer predicateDeserializer) {
return new CreateSpellCriterion.Conditions(playerPredicate);
}
@Override
public Identifier getId() {
return ID;
}
public CreateSpellCriterion.Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) {
return new CreateSpellCriterion.Conditions();
}
public void trigger(ServerPlayerEntity player) {
test(player.getAdvancementTracker(), (conditions) -> true);
test(player, (conditions) -> true);
}
public static class Conditions extends AbstractCriterionConditions {
public Conditions() {
super(ID);
public Conditions(EntityPredicate.Extended player) {
super(ID, player);
}
}
}

View File

@ -1,6 +1,5 @@
package com.thebrokenrail.sorcerycraft.advancement;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import com.thebrokenrail.sorcerycraft.SorceryCraft;
import com.thebrokenrail.sorcerycraft.spell.api.Spell;
@ -8,6 +7,8 @@ import com.thebrokenrail.sorcerycraft.spell.api.registry.SpellRegistry;
import com.thebrokenrail.sorcerycraft.spell.util.SpellPlayerEntity;
import net.minecraft.advancement.criterion.AbstractCriterion;
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer;
import net.minecraft.predicate.entity.EntityPredicate;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
@ -19,16 +20,18 @@ public class DiscoverAllSpellsCriterion extends AbstractCriterion<DiscoverAllSpe
public DiscoverAllSpellsCriterion() {
}
@Override
public Identifier getId() {
return ID;
}
public DiscoverAllSpellsCriterion.Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) {
return new DiscoverAllSpellsCriterion.Conditions();
@Override
protected DiscoverAllSpellsCriterion.Conditions conditionsFromJson(JsonObject obj, EntityPredicate.Extended playerPredicate, AdvancementEntityPredicateDeserializer predicateDeserializer) {
return new DiscoverAllSpellsCriterion.Conditions(playerPredicate);
}
public void trigger(ServerPlayerEntity player) {
test(player.getAdvancementTracker(), (conditions) -> {
test(player, (conditions) -> {
SpellPlayerEntity spellPlayer = (SpellPlayerEntity) player;
Map<Identifier, Integer> spells = spellPlayer.getDiscoveredSpells();
Spell[] maxSpells = SpellRegistry.getMaxSpells();
@ -44,8 +47,8 @@ public class DiscoverAllSpellsCriterion extends AbstractCriterion<DiscoverAllSpe
}
public static class Conditions extends AbstractCriterionConditions {
public Conditions() {
super(ID);
public Conditions(EntityPredicate.Extended player) {
super(ID, player);
}
}
}

View File

@ -17,6 +17,7 @@ import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry;
import net.fabricmc.fabric.api.client.screen.ScreenProviderRegistry;
import net.fabricmc.fabric.impl.networking.ClientSidePacketRegistryImpl;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.LiteralText;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper;
@ -31,7 +32,7 @@ public class SorceryCraftClient implements ClientModInitializer {
GuiRegistry guiRegistry = AutoConfig.getGuiRegistry(ModConfig.class);
guiRegistry.registerAnnotationProvider((s, field, config, defaults, guiRegistryAccess) -> {
ModConfig.UsePercentage bounds = field.getAnnotation(ModConfig.UsePercentage.class);
return Collections.singletonList(ConfigEntryBuilder.create().startIntSlider(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 -> 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);
EntityRendererRegistry.INSTANCE.register(SorceryCraft.SPELL_ENTITY, (entityRenderDispatcher, context) -> new SpellEntityRenderer(entityRenderDispatcher));

View File

@ -8,11 +8,12 @@ import com.thebrokenrail.sorcerycraft.spell.api.Spell;
import com.thebrokenrail.sorcerycraft.spell.util.SpellHelper;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier;
@ -21,9 +22,9 @@ import net.minecraft.util.math.MathHelper;
@Environment(EnvType.CLIENT)
public class CastingTableScreen extends HandledScreen<CastingTableScreenHandler> {
private static final Identifier TEXTURE = new Identifier("textures/gui/container/villager2.png");
private int selectedIndex;
private int indexStartOffset;
private boolean scrolling;
private int selectedIndex = 0;
private int indexStartOffset = 0;
private boolean scrolling = false;
public CastingTableScreen(CastingTableScreenHandler container, PlayerInventory inventory, Text title) {
super(container, inventory, title);
@ -31,47 +32,52 @@ public class CastingTableScreen extends HandledScreen<CastingTableScreenHandler>
}
@Override
protected void drawForeground(int mouseX, int mouseY) {
protected void drawForeground(MatrixStack matrixStack, int i, int j) {
int titleY = backgroundHeight - 94;
textRenderer.draw(title.asFormattedString(), (float) (49 + this.backgroundWidth / 2 - textRenderer.getStringWidth(title.asFormattedString()) / 2), 6.0F, 4210752);
textRenderer.draw(playerInventory.getDisplayName().asFormattedString(), 107.0F, (float) titleY, 4210752);
String spells = new TranslatableText("container." + SorceryCraft.NAMESPACE + ".spells").getString();
textRenderer.draw(spells, (float) (5 - textRenderer.getStringWidth(spells) / 2 + 48), 6.0F, 4210752);
renderXPCost();
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);
Text spells = new TranslatableText("container." + SorceryCraft.NAMESPACE + ".spells");
textRenderer.draw(matrixStack, spells, (float) (5 - textRenderer.getWidth(spells) / 2 + 48), 6.0F, 4210752);
renderXPCost(matrixStack);
}
public void resetIndex() {
selectedIndex = 0;
indexStartOffset = 0;
}
@Override
protected void drawBackground(float delta, int mouseX, int mouseY) {
protected void drawBackground(MatrixStack matrixStack, float delta, int mouseX, int mouseY) {
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
assert client != null;
client.getTextureManager().bindTexture(TEXTURE);
int i = (width - backgroundWidth) / 2;
int j = (height - backgroundHeight) / 2;
drawTexture(i, j, getZOffset(), 0.0F, 0.0F, backgroundWidth, backgroundHeight, 256, 512);
drawTexture(matrixStack, i, j, getZOffset(), 0.0F, 0.0F, backgroundWidth, backgroundHeight, 256, 512);
}
@Override
public void render(int mouseX, int mouseY, float delta) {
renderBackground();
super.render(mouseX, mouseY, delta);
drawMouseoverTooltip(mouseX, mouseY);
public void render(MatrixStack matrixStack, int mouseX, int mouseY, float delta) {
renderBackground(matrixStack);
super.render(matrixStack, mouseX, mouseY, delta);
drawMouseoverTooltip(matrixStack, mouseX, mouseY);
renderScrollbar();
renderScrollbar(matrixStack);
renderItems();
for (WidgetButtonPage button : buttons) {
if (button.isHovered()) {
button.renderToolTip(mouseX, mouseY);
button.renderToolTip(matrixStack, mouseX, mouseY);
}
button.visible = button.index < handler.getRecipes().length;
if (button.visible) {
Spell spell = handler.getRecipes()[button.getIndex() + indexStartOffset];
button.setMessage(SpellHelper.getTranslatedSpell(spell.getID(), spell.getLevel()).getString());
button.setMessage(SpellHelper.getTranslatedSpell(spell.getID(), spell.getLevel()));
}
}
}
private void renderScrollbar() {
private void renderScrollbar(MatrixStack matrixStack) {
Spell[] spells = handler.getRecipes();
assert client != null;
client.getTextureManager().bindTexture(TEXTURE);
@ -81,9 +87,9 @@ public class CastingTableScreen extends HandledScreen<CastingTableScreenHandler>
if (k > 0) {
int modifier = (int) (((float) indexStartOffset / k) * (1 + 139 - 27));
drawTexture(i + 94, j + 18 + modifier, getZOffset(), 0.0F, 199.0F, 6, 27, 256, 512);
drawTexture(matrixStack, i + 94, j + 18 + modifier, getZOffset(), 0.0F, 199.0F, 6, 27, 256, 512);
} else {
drawTexture(i + 94, j + 18, getZOffset(), 6.0F, 199.0F, 6, 27, 256, 512);
drawTexture(matrixStack, i + 94, j + 18, getZOffset(), 6.0F, 199.0F, 6, 27, 256, 512);
}
}
@ -99,7 +105,7 @@ public class CastingTableScreen extends HandledScreen<CastingTableScreenHandler>
itemRenderer.zOffset = 100.0F;
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.zOffset = 0.0F;
k += 20;
@ -107,21 +113,21 @@ public class CastingTableScreen extends HandledScreen<CastingTableScreenHandler>
}
}
private void renderXPCost() {
private void renderXPCost(MatrixStack matrixStack) {
if (handler.getRecipes().length > 0) {
int cost = handler.getRecipes()[selectedIndex].getXPCost();
int color = 8453920;
assert client != null;
assert client.player != null;
String string = new TranslatableText("container.repair.cost", cost).getString();
Text string = new TranslatableText("container.repair.cost", cost);
if (!handler.canTakeResult(playerInventory.player)) {
color = 16736352;
}
int x2 = backgroundWidth - 8;
int x1 = x2 - textRenderer.getStringWidth(string);
fill(x1, 65, x2, 77, 1325400064);
textRenderer.drawWithShadow(string, (float) x1, 67.0F, color);
int x1 = x2 - textRenderer.getWidth(string);
fill(matrixStack, x1, 65, x2, 77, 1325400064);
textRenderer.drawWithShadow(matrixStack, string, (float) x1, 67.0F, color);
}
}
@ -194,37 +200,32 @@ public class CastingTableScreen extends HandledScreen<CastingTableScreenHandler>
}
@Environment(EnvType.CLIENT)
private class WidgetButtonPage extends ButtonWidget {
public class WidgetButtonPage extends ButtonWidget {
final int index;
public WidgetButtonPage(int i, int j, int k, PressAction pressAction) {
super(i, j, 89, 20, "", pressAction);
super(i, j, 89, 20, new LiteralText(""), pressAction);
index = k;
visible = false;
}
@Override
public void render(int mouseX, int mouseY, float delta) {
public void render(MatrixStack matrixStack, int mouseX, int mouseY, float delta) {
active = (index + CastingTableScreen.this.indexStartOffset) != CastingTableScreen.this.selectedIndex;
super.render(mouseX, mouseY, delta);
super.render(matrixStack, mouseX, mouseY, delta);
}
public int getIndex() {
return this.index;
}
public void renderToolTip(int mouseX, int mouseY) {
public void renderToolTip(MatrixStack matrixStack, int mouseX, int mouseY) {
if (hovered && handler.getRecipes().length > index + indexStartOffset && mouseX > this.x + 65) {
ItemStack itemStack = handler.getRecipes()[index + indexStartOffset].getItemCost();
if (!itemStack.isEmpty()) {
renderTooltip(itemStack, mouseX, mouseY);
renderTooltip(matrixStack, itemStack, mouseX, mouseY);
}
}
}
@Override
public void drawCenteredString(TextRenderer textRenderer, String str, int centerX, int y, int color) {
drawString(textRenderer, str, x + 5, y, color);
}
}
}

View File

@ -14,7 +14,7 @@ import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import com.thebrokenrail.sorcerycraft.SorceryCraft;
import com.thebrokenrail.sorcerycraft.spell.api.Spell;
import com.thebrokenrail.sorcerycraft.spell.api.registry.SpellRegistry;
import net.minecraft.server.command.CommandSource;
import net.minecraft.command.CommandSource;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier;

View File

@ -8,7 +8,7 @@ import com.thebrokenrail.sorcerycraft.spell.api.Spell;
import com.thebrokenrail.sorcerycraft.spell.api.registry.SpellRegistry;
import com.thebrokenrail.sorcerycraft.spell.util.SpellHelper;
import com.thebrokenrail.sorcerycraft.spell.util.SpellPlayerEntity;
import net.minecraft.command.arguments.EntityArgumentType;
import net.minecraft.command.argument.EntityArgumentType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.server.command.CommandManager;

View File

@ -7,9 +7,9 @@ import com.thebrokenrail.sorcerycraft.spell.api.registry.SpellRegistry;
import com.thebrokenrail.sorcerycraft.spell.util.SpellHelper;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.BasicInventory;
import net.minecraft.inventory.CraftingResultInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.SimpleInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.ScreenHandlerContext;
@ -35,7 +35,7 @@ public class CastingTableScreenHandler extends ScreenHandler {
public CastingTableScreenHandler(int syncId, PlayerInventory playerInventory, ScreenHandlerContext blockContext) {
super(ScreenHandlerType.STONECUTTER, syncId);
inventory = new BasicInventory(2) {
inventory = new SimpleInventory(2) {
public void markDirty() {
super.markDirty();
CastingTableScreenHandler.this.onContentChanged(this);
@ -53,7 +53,7 @@ public class CastingTableScreenHandler extends ScreenHandler {
}
@Override
public int getMaxStackAmount() {
public int getMaxItemCount() {
return 1;
}
@ -91,8 +91,8 @@ public class CastingTableScreenHandler extends ScreenHandler {
}
});
CastingTableScreenHandler.this.inventory.setInvStack(0, ItemStack.EMPTY);
CastingTableScreenHandler.this.inventory.takeInvStack(1, spells[index].getItemCost().getCount());
CastingTableScreenHandler.this.inventory.setStack(0, ItemStack.EMPTY);
CastingTableScreenHandler.this.inventory.removeStack(1, spells[index].getItemCost().getCount());
return stack;
}
});
@ -109,6 +109,11 @@ public class CastingTableScreenHandler extends ScreenHandler {
}
}
private void resetIndex() {
index = 0;
onContentChanged(inventory);
}
public void setSpells(PlayerEntity player) {
if (player.isCreative() ? SorceryCraft.getConfig().limitCastingTable.creative : SorceryCraft.getConfig().limitCastingTable.survival) {
SpellPlayerEntity spellPlayer = (SpellPlayerEntity) player;
@ -125,8 +130,7 @@ public class CastingTableScreenHandler extends ScreenHandler {
} else {
spells = SpellRegistry.getSpells();
}
index = 0;
onContentChanged(inventory);
resetIndex();
}
public boolean canTakeResult(PlayerEntity playerEntity) {
@ -137,7 +141,7 @@ public class CastingTableScreenHandler extends ScreenHandler {
this.index = index;
onContentChanged(inventory);
if (inventory.getInvStack(0).isEmpty() && inventory.getInvStack(1).isEmpty()) {
if (inventory.getStack(0).isEmpty() && inventory.getStack(1).isEmpty()) {
ItemStack spellItem = new ItemStack(SorceryCraft.SPELL_ITEM);
autoFill(0, spellItem, true);
ItemStack paymentItem = getRecipes()[index].getItemCost();
@ -194,8 +198,8 @@ public class CastingTableScreenHandler extends ScreenHandler {
@Override
public void onContentChanged(Inventory inventory) {
super.onContentChanged(inventory);
ItemStack item = inventory.getInvStack(0);
ItemStack cost = inventory.getInvStack(1);
ItemStack item = inventory.getStack(0);
ItemStack cost = inventory.getStack(1);
if (inventory == this.inventory) {
if (spells.length > 0 &&
!item.isEmpty() &&
@ -207,9 +211,9 @@ public class CastingTableScreenHandler extends ScreenHandler {
resultSpells.put(spells[index].getID(), spells[index].getLevel());
}
SpellHelper.setSpells(resultItem, resultSpells);
result.setInvStack(2, resultItem);
result.setStack(2, resultItem);
} else {
result.setInvStack(2, ItemStack.EMPTY);
result.setStack(2, ItemStack.EMPTY);
}
}
}
@ -219,14 +223,14 @@ public class CastingTableScreenHandler extends ScreenHandler {
for (int i = 3; i < 39; ++i) {
ItemStack itemStack = slots.get(i).getStack();
if (!itemStack.isEmpty() && itemCompatible(stack, itemStack)) {
ItemStack invSlot = inventory.getInvStack(slot);
ItemStack invSlot = inventory.getStack(slot);
int count = invSlot.isEmpty() ? 0 : invSlot.getCount();
int requiredCount = Math.min((onlyOne ? 1 : stack.getMaxCount()) - count, itemStack.getCount());
ItemStack modifiedItem = itemStack.copy();
int totalCount = count + requiredCount;
itemStack.decrement(requiredCount);
modifiedItem.setCount(totalCount);
inventory.setInvStack(slot, modifiedItem);
inventory.setStack(slot, modifiedItem);
if (totalCount >= stack.getMaxCount() || onlyOne) {
break;
}

View File

@ -53,15 +53,15 @@ public class SpellItem extends Item {
}
@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);
return true;
return ActionResult.SUCCESS;
}
@Override
public boolean hasEnchantmentGlint(ItemStack stack) {
public boolean hasGlint(ItemStack stack) {
Map<Identifier, Integer> spells = SpellHelper.getSpells(stack);
return spells.size() > 0 || super.hasEnchantmentGlint(stack);
return spells.size() > 0 || super.hasGlint(stack);
}
@Override
@ -97,7 +97,7 @@ public class SpellItem extends Item {
super.inventoryTick(stack, world, entity, slot, selected);
if (!world.isClient() && entity instanceof PlayerEntity) {
PlayerEntity player = (PlayerEntity) entity;
Map<Identifier, Integer> itemSpells = SpellHelper.getSpells(player.inventory.getInvStack(slot));
Map<Identifier, Integer> itemSpells = SpellHelper.getSpells(player.inventory.getStack(slot));
SpellHelper.learnSpells(player, itemSpells);
}

View File

@ -1,12 +1,12 @@
package com.thebrokenrail.sorcerycraft.mixin;
import net.minecraft.advancement.criterion.Criteria;
import net.minecraft.advancement.criterion.Criterion;
import net.minecraft.advancement.criterion.Criterions;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(Criterions.class)
public interface CriterionRegistryHook {
@Mixin(Criteria.class)
public interface CriteriaRegistryHook {
@Invoker("register")
static <T extends Criterion<?>> T callRegister(T criterion) {
return criterion;

View File

@ -0,0 +1,24 @@
package com.thebrokenrail.sorcerycraft.mixin;
import com.thebrokenrail.sorcerycraft.client.gui.CastingTableScreen;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@SuppressWarnings("ConstantConditions")
@Mixin(AbstractButtonWidget.class)
public class MixinAbstractButtonWidget {
@Redirect(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/AbstractButtonWidget;drawCenteredText(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/text/Text;III)V"), method = "renderButton")
public void drawCenteredText(MatrixStack matrices, TextRenderer textRenderer, Text text, int centerX, int y, int color) {
if ((Object) this instanceof CastingTableScreen.WidgetButtonPage) {
DrawableHelper.drawStringWithShadow(matrices, textRenderer, text.getString(), ((CastingTableScreen.WidgetButtonPage) (Object) this).x + 5, y, color);
} else {
DrawableHelper.drawCenteredText(matrices, textRenderer, text, centerX, y, color);
}
}
}

View File

@ -16,12 +16,12 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@SuppressWarnings("unused")
@Environment(EnvType.CLIENT)
@Mixin(ClientPlayNetworkHandler.class)
public class MixinClientPlayNetworkHandler {
@Shadow
private ClientWorld world;
@Environment(EnvType.CLIENT)
@Inject(method = "onEntitySpawn", at = @At(value = "TAIL"))
public void onEntitySpawn(EntitySpawnS2CPacket packet, CallbackInfo info) {
EntityType<?> entityType = packet.getEntityTypeId();

View File

@ -0,0 +1,30 @@
package com.thebrokenrail.sorcerycraft.mixin;
import com.thebrokenrail.sorcerycraft.client.gui.CastingTableScreen;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import java.util.Map;
@SuppressWarnings("unused")
@Mixin(ClientPlayerEntity.class)
@Environment(EnvType.CLIENT)
public class MixinClientPlayerEntity extends MixinPlayerEntity {
@Shadow
@Final
protected MinecraftClient client;
@Override
public void setDiscoveredSpells(Map<Identifier, Integer> spells) {
super.setDiscoveredSpells(spells);
if (client.currentScreen instanceof CastingTableScreen) {
((CastingTableScreen) client.currentScreen).resetIndex();
}
}
}

View File

@ -9,6 +9,7 @@ import net.minecraft.screen.ScreenHandler;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@ -19,23 +20,24 @@ import java.util.Map;
@SuppressWarnings("unused")
@Mixin(PlayerEntity.class)
public class MixinPlayerEntity implements SpellPlayerEntity {
@Shadow public ScreenHandler currentScreenHandler;
// Namespace Fields
private Map<Identifier, Integer> sorceryCraftDiscoveredSpells = new HashMap<>();
@Shadow
public ScreenHandler currentScreenHandler;
@Unique
private Map<Identifier, Integer> discoveredSpells = new HashMap<>();
@Inject(at = @At("HEAD"), method = "readCustomDataFromTag")
public void readCustomDataFromTag(CompoundTag tag, CallbackInfo info) {
sorceryCraftDiscoveredSpells = SpellHelper.getSpells(tag);
discoveredSpells = SpellHelper.getSpells(tag);
}
@Inject(at = @At("HEAD"), method = "writeCustomDataToTag")
public void writeCustomDataToTag(CompoundTag tag, CallbackInfo info) {
tag.put(SpellHelper.SPELL_TAG, SpellHelper.createSpellsTag(sorceryCraftDiscoveredSpells));
tag.put(SpellHelper.SPELL_TAG, SpellHelper.createSpellsTag(discoveredSpells));
}
@Override
public void setDiscoveredSpells(Map<Identifier, Integer> spells) {
this.sorceryCraftDiscoveredSpells = spells;
discoveredSpells = spells;
if (currentScreenHandler instanceof CastingTableScreenHandler) {
//noinspection ConstantConditions
((CastingTableScreenHandler) currentScreenHandler).setSpells((PlayerEntity) (Object) this);
@ -44,6 +46,6 @@ public class MixinPlayerEntity implements SpellPlayerEntity {
@Override
public Map<Identifier, Integer> getDiscoveredSpells() {
return sorceryCraftDiscoveredSpells;
return discoveredSpells;
}
}

View File

@ -5,7 +5,8 @@ import com.thebrokenrail.sorcerycraft.packet.UpdateKnownSpellsS2CPacket;
import com.thebrokenrail.sorcerycraft.spell.util.SpellHelper;
import com.thebrokenrail.sorcerycraft.spell.util.SpellPlayerEntity;
import com.thebrokenrail.sorcerycraft.spell.util.SpellServerPlayerEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;

View File

@ -4,6 +4,8 @@ import com.thebrokenrail.sorcerycraft.SorceryCraft;
import com.thebrokenrail.sorcerycraft.spell.util.SpellPlayerEntity;
import com.thebrokenrail.sorcerycraft.spell.util.SpellHelper;
import io.netty.buffer.Unpooled;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.network.PacketContext;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.PacketByteBuf;
@ -12,6 +14,7 @@ import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
public class UpdateKnownSpellsS2CPacket {
@Environment(EnvType.CLIENT)
public static void handle(PacketContext context, PacketByteBuf bytes) {
CompoundTag tag = bytes.readCompoundTag();
if (context.getPlayer() != null) {

View File

@ -27,7 +27,7 @@ public class CoolingSpell extends Spell {
if (world.getBlockState(blockPos).isIn(BlockTags.FIRE)) {
world.removeBlock(blockPos, false);
}
if (world.getBlockState(blockPos).get(Properties.LIT)) {
if (world.getBlockState(blockPos).contains(Properties.LIT) && world.getBlockState(blockPos).get(Properties.LIT)) {
world.setBlockState(blockPos, world.getBlockState(blockPos).with(Properties.LIT, false));
}

View File

@ -1,18 +1,13 @@
package com.thebrokenrail.sorcerycraft.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.LivingEntity;
import net.minecraft.item.FlintAndSteelItem;
import net.minecraft.item.AutomaticItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.state.property.Properties;
import net.minecraft.util.Identifier;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class FlameSpell extends Spell {
@ -30,20 +25,7 @@ public class FlameSpell extends Spell {
@Override
public void execute(World world, Entity source, Entity attacker, BlockHitResult hitResult) {
BlockPos blockPos = hitResult.getBlockPos();
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));
}
Items.FLINT_AND_STEEL.useOnBlock(new AutomaticItemPlacementContext(world, hitResult.getBlockPos(), hitResult.getSide().getOpposite(), new ItemStack(Items.FLINT_AND_STEEL), hitResult.getSide()));
}
@Override

View File

@ -2,6 +2,7 @@ package com.thebrokenrail.sorcerycraft.spell;
import com.thebrokenrail.sorcerycraft.spell.api.Spell;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LightningEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
@ -29,11 +30,13 @@ public class LightningSpell extends Spell {
private void strike(World world, Vec3d pos, Entity attacker) {
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) {
lightningEntity.setChanneller((ServerPlayerEntity) attacker);
lightningEntity.setChanneler((ServerPlayerEntity) attacker);
}
serverWorld.addLightning(lightningEntity);
serverWorld.spawnEntity(lightningEntity);
}
@Override

View File

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

View File

@ -3,7 +3,7 @@ package com.thebrokenrail.sorcerycraft.spell.api;
import com.thebrokenrail.sorcerycraft.spell.api.registry.SpellRegistry;
import net.minecraft.entity.Entity;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import net.minecraft.text.MutableText;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier;
import net.minecraft.util.hit.BlockHitResult;
@ -83,8 +83,8 @@ public abstract class Spell {
* @param level Spell Level
* @return Translated Display Name
*/
public static Text getDefaultTranslation(Identifier id, int level) {
Text text = new TranslatableText("spell." + id.getNamespace() + '.' + id.getPath());
public static MutableText getDefaultTranslation(Identifier id, int level) {
MutableText text = new TranslatableText("spell." + id.getNamespace() + '.' + id.getPath());
if (level != 0 || SpellRegistry.getMaxLevel(id) != 1) {
text.append(" ").append(new TranslatableText("enchantment.level." + (level + 1)));
}
@ -95,7 +95,7 @@ public abstract class Spell {
* Get Translated Display Name
* @return Translated Display Name
*/
public Text getTranslation() {
public MutableText getTranslation() {
return getDefaultTranslation(getID(), getLevel());
}
}

View File

@ -1,5 +1,8 @@
package com.thebrokenrail.sorcerycraft.spell.util;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import com.thebrokenrail.sorcerycraft.SorceryCraft;
import com.thebrokenrail.sorcerycraft.spell.api.Spell;
import com.thebrokenrail.sorcerycraft.spell.api.registry.SpellRegistry;
import net.minecraft.item.ItemStack;
@ -7,7 +10,9 @@ import net.minecraft.loot.condition.LootCondition;
import net.minecraft.loot.context.LootContext;
import net.minecraft.loot.function.ConditionalLootFunction;
import net.minecraft.loot.function.LootFunction;
import net.minecraft.loot.function.LootFunctionType;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import java.util.Map;
@ -29,6 +34,22 @@ public class RandomSpellLootTableFunction extends ConditionalLootFunction {
return stack;
}
@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() {
super();
}
@Override
public RandomSpellLootTableFunction fromJson(JsonObject json, JsonDeserializationContext context, LootCondition[] conditions) {
return (RandomSpellLootTableFunction) new com.thebrokenrail.sorcerycraft.spell.util.RandomSpellLootTableFunction.Builder().build();
}
}
public static class Builder extends ConditionalLootFunction.Builder<RandomSpellLootTableFunction.Builder> {
@Override
protected RandomSpellLootTableFunction.Builder getThisBuilder() {

View File

@ -8,12 +8,16 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
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.text.LiteralText;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
import net.minecraft.world.World;
import java.util.HashMap;
@ -85,7 +89,7 @@ public class SpellHelper {
public static Text getTranslatedSpell(Identifier id, int level) {
Spell spell = SpellRegistry.getSpell(id, level);
Text text;
MutableText text;
if (spell != null) {
text = spell.getTranslation();
} else {
@ -120,7 +124,7 @@ public class SpellHelper {
playerSpells.put(spell.getID(), spell.getLevel());
assert world.getServer() != null;
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",
"fabric": "*",
"minecraft": "1.16.x"
},
"custom": {
"modupdater": {
"strategy": "curseforge",
"projectID": 365308
}
}
}

View File

@ -3,12 +3,14 @@
"package": "com.thebrokenrail.sorcerycraft.mixin",
"compatibilityLevel": "JAVA_8",
"client": [
"MixinClientPlayNetworkHandler"
"MixinClientPlayerEntity",
"MixinClientPlayNetworkHandler",
"MixinAbstractButtonWidget"
],
"mixins": [
"CriteriaRegistryHook",
"MixinPlayerEntity",
"MixinServerPlayerEntity",
"CriterionRegistryHook"
"MixinServerPlayerEntity"
],
"injectors": {
"defaultRequire": 1