untested, but make the client sync code less bad and make trinkets/cyphers actually unable to draw from inventory
This commit is contained in:
parent
8cd849d2db
commit
c15d4cac24
9 changed files with 57 additions and 63 deletions
|
@ -17,7 +17,7 @@ apply plugin: 'maven-publish'
|
|||
apply plugin: 'net.minecraftforge.gradle'
|
||||
apply plugin: 'org.parchmentmc.librarian.forgegradle'
|
||||
|
||||
version = '0.4.1'
|
||||
version = '0.5.0-dev'
|
||||
group = 'at.petra-k.hexcasting' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
archivesBaseName = 'hexcasting'
|
||||
|
||||
|
|
|
@ -41,17 +41,17 @@ class GuiSpellcasting(private val handOpenedWith: InteractionHand) : Screen(Text
|
|||
|
||||
private var stackDescs: List<Component> = emptyList()
|
||||
|
||||
fun recvServerUpdate(info: ControllerInfo, stackDescs: List<Component>) {
|
||||
fun recvServerUpdate(info: ControllerInfo) {
|
||||
this.stackDescs = stackDescs
|
||||
this.patterns.lastOrNull()?.let {
|
||||
it.valid = if (info.status == ControllerInfo.Status.PREV_PATTERN_INVALID)
|
||||
it.valid = if (info.wasPrevPatternInvalid)
|
||||
PatternValidity.ERROR
|
||||
else
|
||||
PatternValidity.OK
|
||||
}
|
||||
|
||||
val sound =
|
||||
if (info.status == ControllerInfo.Status.PREV_PATTERN_INVALID) HexSounds.FAIL_PATTERN.get() else HexSounds.ADD_PATTERN.get()
|
||||
if (info.wasPrevPatternInvalid) HexSounds.FAIL_PATTERN.get() else HexSounds.ADD_PATTERN.get()
|
||||
Minecraft.getInstance().soundManager.play(
|
||||
SimpleSoundInstance.forUI(
|
||||
sound,
|
||||
|
|
|
@ -14,6 +14,7 @@ import at.petrak.hexcasting.hexmath.HexPattern
|
|||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.ListTag
|
||||
import net.minecraft.nbt.Tag
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.InteractionHand
|
||||
|
@ -87,24 +88,27 @@ class CastingHarness private constructor(
|
|||
* Execute the side effects of a cast, and then tell the client what to think about it.
|
||||
*/
|
||||
fun performSideEffects(sideEffects: List<OperatorSideEffect>): ControllerInfo {
|
||||
var status = ControllerInfo.Status.NONE
|
||||
var wasSpellCast = false
|
||||
var wasPrevPatternInvalid = false
|
||||
for (haskellProgrammersShakingandCryingRN in sideEffects) {
|
||||
if (haskellProgrammersShakingandCryingRN is OperatorSideEffect.Mishap)
|
||||
status = ControllerInfo.Status.PREV_PATTERN_INVALID
|
||||
wasPrevPatternInvalid = true
|
||||
|
||||
val mustStop = haskellProgrammersShakingandCryingRN.performEffect(this)
|
||||
if (mustStop)
|
||||
break
|
||||
|
||||
if (haskellProgrammersShakingandCryingRN is OperatorSideEffect.AttemptSpell)
|
||||
status = ControllerInfo.Status.SPELL_CAST
|
||||
wasSpellCast = true
|
||||
}
|
||||
|
||||
if (status == ControllerInfo.Status.SPELL_CAST && this.stack.isEmpty())
|
||||
status = ControllerInfo.Status.SPELL_CAST_AND_DONE
|
||||
val descs: ArrayList<Component> = ArrayList<Component>(this.stack.size)
|
||||
for (datum in this.stack) {
|
||||
descs.add(datum.display())
|
||||
}
|
||||
|
||||
return ControllerInfo(
|
||||
status,
|
||||
wasSpellCast, this.stack.isEmpty(), wasPrevPatternInvalid, descs
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -243,22 +247,22 @@ class CastingHarness private constructor(
|
|||
if (costLeft <= 0)
|
||||
break
|
||||
}
|
||||
|
||||
if (allowOvercast && costLeft > 0) {
|
||||
// Cast from HP!
|
||||
val manaToHealth = HexMod.CONFIG.manaToHealthRate.get()
|
||||
val healthtoRemove = costLeft.toDouble() / manaToHealth
|
||||
val manaAbleToCastFromHP = this.ctx.caster.health * manaToHealth
|
||||
|
||||
val manaToActuallyPayFor = min(manaAbleToCastFromHP.toInt(), costLeft)
|
||||
Advancements.OVERCAST_TRIGGER.trigger(this.ctx.caster, manaToActuallyPayFor)
|
||||
this.ctx.caster.awardStat(HexStatistics.MANA_OVERCASTED, manaCost - costLeft)
|
||||
|
||||
this.ctx.caster.hurt(HexDamageSources.OVERCAST, healthtoRemove.toFloat())
|
||||
costLeft -= manaToActuallyPayFor
|
||||
}
|
||||
}
|
||||
|
||||
if (allowOvercast && costLeft > 0) {
|
||||
// Cast from HP!
|
||||
val manaToHealth = HexMod.CONFIG.manaToHealthRate.get()
|
||||
val healthtoRemove = costLeft.toDouble() / manaToHealth
|
||||
val manaAbleToCastFromHP = this.ctx.caster.health * manaToHealth
|
||||
|
||||
val manaToActuallyPayFor = min(manaAbleToCastFromHP.toInt(), costLeft)
|
||||
Advancements.OVERCAST_TRIGGER.trigger(this.ctx.caster, manaToActuallyPayFor)
|
||||
this.ctx.caster.awardStat(HexStatistics.MANA_OVERCASTED, manaCost - costLeft)
|
||||
|
||||
this.ctx.caster.hurt(HexDamageSources.OVERCAST, healthtoRemove.toFloat())
|
||||
costLeft -= manaToActuallyPayFor
|
||||
}
|
||||
|
||||
|
||||
// this might be more than the mana cost! for example if we waste a lot of mana from an item
|
||||
this.ctx.caster.awardStat(HexStatistics.MANA_USED, manaCost - costLeft)
|
||||
Advancements.SPEND_MANA_TRIGGER.trigger(
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
package at.petrak.hexcasting.common.casting
|
||||
|
||||
import net.minecraft.network.chat.Component
|
||||
|
||||
/**
|
||||
* Information for the sake of the GUI.
|
||||
*/
|
||||
data class ControllerInfo(val status: Status) {
|
||||
enum class Status {
|
||||
NONE,
|
||||
SPELL_CAST,
|
||||
SPELL_CAST_AND_DONE,
|
||||
PREV_PATTERN_INVALID,
|
||||
}
|
||||
|
||||
fun shouldQuit(): Boolean = this.status == Status.SPELL_CAST_AND_DONE
|
||||
fun wasSpellCast(): Boolean = this.status == Status.SPELL_CAST || this.status == Status.SPELL_CAST_AND_DONE
|
||||
}
|
||||
data class ControllerInfo(
|
||||
val wasSpellCast: Boolean,
|
||||
val isStackEmpty: Boolean,
|
||||
val wasPrevPatternInvalid: Boolean,
|
||||
val stackDesc: List<Component>
|
||||
)
|
|
@ -58,7 +58,7 @@ public abstract class ItemPackagedSpell extends Item {
|
|||
List<HexPattern> patterns = getPatterns(tag);
|
||||
for (var pattern : patterns) {
|
||||
var info = harness.executeNewPattern(pattern, sPlayer.getLevel());
|
||||
if (info.shouldQuit()) {
|
||||
if (info.getWasPrevPatternInvalid()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,19 +12,19 @@ import net.minecraftforge.fml.DistExecutor;
|
|||
import net.minecraftforge.network.NetworkEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Sent server->client when the player finishes casting a spell.
|
||||
*/
|
||||
public record MsgNewSpellPatternAck(ControllerInfo info, List<Component> stackDesc) {
|
||||
private static final String TAG_DESC = "desc";
|
||||
public record MsgNewSpellPatternAck(ControllerInfo info) {
|
||||
|
||||
public static MsgNewSpellPatternAck deserialize(ByteBuf buffer) {
|
||||
var buf = new FriendlyByteBuf(buffer);
|
||||
|
||||
var status = ControllerInfo.Status.values()[buf.readInt()];
|
||||
var wasSpellCast = buf.readBoolean();
|
||||
var isStackEmpty = buf.readBoolean();
|
||||
var wasPrevPatternInvalid = buf.readBoolean();
|
||||
var descsLen = buf.readInt();
|
||||
var desc = new ArrayList<Component>(descsLen);
|
||||
for (int i = 0; i < descsLen; i++) {
|
||||
|
@ -32,17 +32,18 @@ public record MsgNewSpellPatternAck(ControllerInfo info, List<Component> stackDe
|
|||
}
|
||||
|
||||
return new MsgNewSpellPatternAck(
|
||||
new ControllerInfo(status),
|
||||
desc
|
||||
new ControllerInfo(wasSpellCast, isStackEmpty, wasPrevPatternInvalid, desc)
|
||||
);
|
||||
}
|
||||
|
||||
public void serialize(ByteBuf buffer) {
|
||||
var buf = new FriendlyByteBuf(buffer);
|
||||
|
||||
buf.writeInt(this.info.getStatus().ordinal());
|
||||
buf.writeInt(this.stackDesc.size());
|
||||
for (var desc : this.stackDesc) {
|
||||
buf.writeBoolean(this.info.getWasSpellCast());
|
||||
buf.writeBoolean(this.info.isStackEmpty());
|
||||
buf.writeBoolean(this.info.getWasPrevPatternInvalid());
|
||||
buf.writeInt(this.info.getStackDesc().size());
|
||||
for (var desc : this.info.getStackDesc()) {
|
||||
buf.writeComponent(desc);
|
||||
}
|
||||
}
|
||||
|
@ -51,16 +52,16 @@ public record MsgNewSpellPatternAck(ControllerInfo info, List<Component> stackDe
|
|||
ctx.get().enqueueWork(() ->
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> {
|
||||
var mc = Minecraft.getInstance();
|
||||
if (this.info.shouldQuit()) {
|
||||
if (this.info.isStackEmpty()) {
|
||||
// don't pay attention to the screen, so it also stops when we die
|
||||
mc.getSoundManager().stop(HexSounds.CASTING_AMBIANCE.getId(), null);
|
||||
}
|
||||
var screen = Minecraft.getInstance().screen;
|
||||
if (screen instanceof GuiSpellcasting spellGui) {
|
||||
if (this.info.shouldQuit()) {
|
||||
if (this.info.isStackEmpty()) {
|
||||
mc.setScreen(null);
|
||||
} else {
|
||||
spellGui.recvServerUpdate(this.info, this.stackDesc);
|
||||
spellGui.recvServerUpdate(this.info);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -7,14 +7,12 @@ import at.petrak.hexcasting.hexmath.HexPattern;
|
|||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
|
@ -47,14 +45,14 @@ public record MsgNewSpellPatternSyn(InteractionHand handUsed, HexPattern pattern
|
|||
|
||||
var clientInfo = harness.executeNewPattern(this.pattern, sender.getLevel());
|
||||
|
||||
if (clientInfo.wasSpellCast()) {
|
||||
if (clientInfo.getWasSpellCast()) {
|
||||
sender.level.playSound(null, sender.getX(), sender.getY(), sender.getZ(),
|
||||
HexSounds.ACTUALLY_CAST.get(), SoundSource.PLAYERS, 1f,
|
||||
1f + ((float) Math.random() - 0.5f) * 0.2f);
|
||||
}
|
||||
|
||||
CompoundTag nextHarnessTag;
|
||||
if (clientInfo.shouldQuit()) {
|
||||
if (clientInfo.isStackEmpty()) {
|
||||
// discard the changes
|
||||
nextHarnessTag = new CompoundTag();
|
||||
} else {
|
||||
|
@ -63,14 +61,8 @@ public record MsgNewSpellPatternSyn(InteractionHand handUsed, HexPattern pattern
|
|||
}
|
||||
tag.put(ItemWand.TAG_HARNESS, nextHarnessTag);
|
||||
|
||||
var descs = new ArrayList<Component>(harness.getStack().size());
|
||||
for (var datum : harness.getStack()) {
|
||||
descs.add(datum.display());
|
||||
}
|
||||
|
||||
HexMessages.getNetwork()
|
||||
.send(PacketDistributor.PLAYER.with(() -> sender),
|
||||
new MsgNewSpellPatternAck(clientInfo, descs));
|
||||
.send(PacketDistributor.PLAYER.with(() -> sender), new MsgNewSpellPatternAck(clientInfo));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -8,11 +8,11 @@
|
|||
"pages": [
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"text": "Although their names were lost to time, the old practitioners of my art were often known for a color, emblematic of them and their spells. It seems a special kind of pigment, offered to Nature in the right way, would \"[...] paint one's thoughts in a manner pleasing to Nature, inducing a miraculous change in color.\""
|
||||
"text": "Although the names of the old practitioners of my art were lost to time, they were often known for a color, emblematic of them and their spells. It seems a special kind of pigment, offered to Nature in the right way, would \"[...] paint one's thoughts in a manner pleasing to Nature, inducing a miraculous change in color.\""
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"text": "I'm not certain on the specifics of how it works, but I believe I have isolated the formulae for many different colors of pigments. To use one, I hold it in my other hand while casting $(l:patterns/spells/colorize)$(action)Internalize Pigment/$, which will consume the pigment and mark my mind with that color.$(br2)The pigments seem to affect the color of the spare media coming out of a staff when I cast a _Hex, as well as my $(l:hexcasting/patterns/sentinels)$(thing)Sentinel/$."
|
||||
"text": "I'm not certain on the specifics of how it works, but I believe I have isolated the formulae for many different colors of pigments. To use one, I hold it in my other hand while casting $(l:patterns/spells/colorize)$(action)Internalize Pigment/$, which will consume the pigment and mark my mind with that color.$(br2)The pigments seem to affect the color of the spare media coming out of a staff when I cast a _Hex, as well as my $(l:patterns/sentinels)$(thing)Sentinel/$."
|
||||
},
|
||||
{
|
||||
"type": "hexcasting:crafting_multi",
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
"pages": [
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
"text": "$(italic)Hence, away! Now all is well,$(br)One aloof stand sentinel./$$(br2)A $(thing)Sentinel/$ is a mysterious force I can summon to assist in the casting of _Hexes, like a familiar or guardian spirit. It appears as a small blob of light to my eyes, but is invisible to everyone else."
|
||||
"text": "$(italic)Hence, away! Now all is well,$(br)One aloof stand sentinel./$$(br2)A $(thing)Sentinel/$ is a mysterious force I can summon to assist in the casting of _Hexes, like a familiar or guardian spirit. It appears as a spinning geometric shape to my eyes, but is invisible to everyone else."
|
||||
},
|
||||
{
|
||||
"type": "patchouli:text",
|
||||
|
|
Loading…
Reference in a new issue