That's one heck of a commit you've got there...

I may have got a bit behind with version control. A lot behind, in fact. Maybe I'll go back and split this sometime - then again, I probably won't. But hey, at least it's here!
This commit is contained in:
Electroblob77
2019-08-18 00:04:18 +01:00
parent 2680d02304
commit f37812be3e
1564 changed files with 47652 additions and 12984 deletions
@@ -1,16 +1,19 @@
package electroblob.wizardry.packet;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.data.WizardData;
import electroblob.wizardry.packet.PacketCastContinuousSpell.Message;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.util.SpellModifiers;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
/**
* <b>[Server -> Client]</b> This packet is sent when the /cast command is used with a continuous spell, in order to
* sync the relevant variables in {@link electroblob.wizardry.WizardData WizardData}.
* sync the relevant variables in {@link WizardData WizardData}.
*/
public class PacketCastContinuousSpell implements IMessageHandler<Message, IMessage> {
@@ -21,12 +24,7 @@ public class PacketCastContinuousSpell implements IMessageHandler<Message, IMess
if(ctx.side.isClient()){
// Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy
// methods any more than necessary.
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(new Runnable(){
@Override
public void run(){
Wizardry.proxy.handleCastContinuousSpellPacket(message);
}
});
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> Wizardry.proxy.handleCastContinuousSpellPacket(message));
}
return null;
@@ -34,24 +32,23 @@ public class PacketCastContinuousSpell implements IMessageHandler<Message, IMess
public static class Message implements IMessage {
// Note that range and blast multipliers are the only two that affect particle spawning, so they are the
// only two that need to be sent.
/** EntityID of the caster */
public int casterID;
/** ID of the spell being cast */
public int spellID;
/** SpellModifiers for the spell */
public SpellModifiers modifiers;
/** Number of ticks to cast the spell for, or -1 for non-continuous spells */
public int duration;
// This constructor is required otherwise you'll get errors (used somewhere in fml through reflection)
public Message(){
}
public Message(){}
public Message(int casterID, int spellID, SpellModifiers modifiers){
this.casterID = casterID;
this.spellID = spellID;
public Message(EntityPlayer caster, Spell spell, SpellModifiers modifiers, int duration){
this.casterID = caster.getEntityId();
this.spellID = spell.networkID();
this.modifiers = modifiers;
this.duration = duration;
}
@Override
@@ -61,6 +58,7 @@ public class PacketCastContinuousSpell implements IMessageHandler<Message, IMess
this.spellID = buf.readInt();
this.modifiers = new SpellModifiers();
modifiers.read(buf);
this.duration = buf.readInt();
}
@Override
@@ -68,6 +66,7 @@ public class PacketCastContinuousSpell implements IMessageHandler<Message, IMess
buf.writeInt(casterID);
buf.writeInt(spellID);
this.modifiers.write(buf);
buf.writeInt(duration);
}
}
}
@@ -2,6 +2,7 @@ package electroblob.wizardry.packet;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.packet.PacketCastSpell.Message;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.util.SpellModifiers;
import io.netty.buffer.ByteBuf;
import net.minecraft.item.Item;
@@ -26,12 +27,7 @@ public class PacketCastSpell implements IMessageHandler<Message, IMessage> {
if(ctx.side.isClient()){
// Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy
// methods any more than necessary.
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(new Runnable(){
@Override
public void run(){
Wizardry.proxy.handleCastSpellPacket(message);
}
});
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> Wizardry.proxy.handleCastSpellPacket(message));
}
return null;
@@ -52,10 +48,10 @@ public class PacketCastSpell implements IMessageHandler<Message, IMessage> {
public Message(){
}
public Message(int casterID, EnumHand hand, int spellID, SpellModifiers modifiers){
public Message(int casterID, EnumHand hand, Spell spell, SpellModifiers modifiers){
this.casterID = casterID;
this.spellID = spellID;
this.spellID = spell.networkID();
this.modifiers = modifiers;
this.hand = hand == null ? EnumHand.MAIN_HAND : hand;
}
@@ -0,0 +1,85 @@
package electroblob.wizardry.packet;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.util.SpellModifiers;
import io.netty.buffer.ByteBuf;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
/**
* <b>[Server -> Client]</b> This packet is sent when a spell is cast at a position by commands and returns true, and is
* sent to clients so they can spawn the particles themselves.
*/
// Soooo many spell casting packets...
public class PacketCastSpellAtPos implements IMessageHandler<PacketCastSpellAtPos.Message, IMessage> {
@Override
public IMessage onMessage(Message message, MessageContext ctx){
// Just to make sure that the side is correct
if(ctx.side.isClient()){
// Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy
// methods any more than necessary.
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> Wizardry.proxy.handleCastSpellAtPosPacket(message));
}
return null;
}
public static class Message implements IMessage {
/** Position for the spell */
public Vec3d position;
/** Direction for the spell */
public EnumFacing direction;
/** ID of the spell being cast */
public int spellID;
/** SpellModifiers for the spell */
public SpellModifiers modifiers;
/** Number of ticks to cast the spell for, or -1 for non-continuous spells */
public int duration;
// This constructor is required otherwise you'll get errors (used somewhere in fml through reflection)
public Message(){}
public Message(Vec3d position, EnumFacing direction, Spell spell, SpellModifiers modifiers){
this(position, direction, spell, modifiers, -1);
}
public Message(Vec3d position, EnumFacing direction, Spell spell, SpellModifiers modifiers, int duration){
this.spellID = spell.networkID();
this.modifiers = modifiers;
this.position = position;
this.direction = direction;
this.duration = duration;
}
@Override
public void fromBytes(ByteBuf buf){
// The order is important
position = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble());
direction = EnumFacing.byIndex(buf.readInt());
this.spellID = buf.readInt();
this.modifiers = new SpellModifiers();
this.modifiers.read(buf);
this.duration = buf.readInt();
}
@Override
public void toBytes(ByteBuf buf){
buf.writeDouble(position.x);
buf.writeDouble(position.y);
buf.writeDouble(position.z);
buf.writeInt(direction.getIndex());
buf.writeInt(spellID);
this.modifiers.write(buf);
buf.writeInt(duration);
}
}
}
@@ -1,8 +1,5 @@
package electroblob.wizardry.packet;
import java.util.ArrayList;
import java.util.List;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.packet.PacketClairvoyance.Message;
import io.netty.buffer.ByteBuf;
@@ -12,6 +9,9 @@ import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import java.util.ArrayList;
import java.util.List;
/**
* <b>[Server -> Client]</b> This packet is sent when a player casts the clairvoyance spell to allow pathing to chunks
* outside the render distance.
@@ -0,0 +1,58 @@
package electroblob.wizardry.packet;
import electroblob.wizardry.Wizardry;
import io.netty.buffer.ByteBuf;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
/**
* <b>[Server -> Client]</b> This packet is sent when a shrine is conquered to update nearby clients and spawn particles.
*/
public class PacketConquerShrine implements IMessageHandler<PacketConquerShrine.Message, IMessage> {
@Override
public IMessage onMessage(Message message, MessageContext ctx){
// Just to make sure that the side is correct
if(ctx.side.isClient()){
// Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy
// methods any more than necessary.
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> Wizardry.proxy.handleConquerShrinePacket(message));
}
return null;
}
public static class Message implements IMessage {
public int x;
public int y;
public int z;
// This constructor is required otherwise you'll get errors (used somewhere in fml through reflection)
public Message(){}
public Message(BlockPos pos){
this.x = pos.getX();
this.y = pos.getY();
this.z = pos.getZ();
}
@Override
public void fromBytes(ByteBuf buf){
// The order is important
this.x = buf.readInt();
this.y = buf.readInt();
this.z = buf.readInt();
}
@Override
public void toBytes(ByteBuf buf){
buf.writeInt(x);
buf.writeInt(y);
buf.writeInt(z);
}
}
}
@@ -1,12 +1,18 @@
package electroblob.wizardry.packet;
import electroblob.wizardry.item.ItemWand;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.item.ISpellCastingItem;
import electroblob.wizardry.packet.PacketControlInput.Message;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.spell.Possession;
import electroblob.wizardry.spell.Resurrection;
import electroblob.wizardry.tileentity.ContainerArcaneWorkbench;
import electroblob.wizardry.util.WandHelper;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
@@ -22,45 +28,100 @@ public class PacketControlInput implements IMessageHandler<Message, IMessage> {
final EntityPlayerMP player = ctx.getServerHandler().player;
player.getServerWorld().addScheduledTask(new Runnable(){
player.getServerWorld().addScheduledTask(() -> {
public void run(){
ItemStack wand = player.getHeldItemMainhand();
ItemStack wand = player.getHeldItemMainhand();
if(!(wand.getItem() instanceof ISpellCastingItem)){
wand = player.getHeldItemOffhand();
}
if(!(wand.getItem() instanceof ItemWand)){
wand = player.getHeldItemOffhand();
}
switch(message.controlType){
switch(message.controlType){
case APPLY_BUTTON:
case APPLY_BUTTON:
if(!(player.openContainer instanceof ContainerArcaneWorkbench)){
Wizardry.logger.warn("Received a PacketControlInput, but the player that sent it was not " +
"currently using an arcane workbench. This should not happen!");
}else{
((ContainerArcaneWorkbench)player.openContainer).onApplyButtonPressed(player);
break;
case NEXT_SPELL_KEY:
if(wand.getItem() instanceof ItemWand){
WandHelper.selectNextSpell(wand);
// This line fixes the bug with continuous spells casting when they shouldn't be
player.stopActiveHand();
}
break;
case PREVIOUS_SPELL_KEY:
if(wand.getItem() instanceof ItemWand){
WandHelper.selectPreviousSpell(wand);
// This line fixes the bug with continuous spells casting when they shouldn't be
player.stopActiveHand();
}
break;
}
break;
case NEXT_SPELL_KEY:
if(wand.getItem() instanceof ISpellCastingItem){
((ISpellCastingItem)wand.getItem()).selectNextSpell(wand);
// This line fixes the bug with continuous spells casting when they shouldn't be
player.stopActiveHand();
}
break;
case PREVIOUS_SPELL_KEY:
if(wand.getItem() instanceof ISpellCastingItem){
((ISpellCastingItem)wand.getItem()).selectPreviousSpell(wand);
// This line fixes the bug with continuous spells casting when they shouldn't be
player.stopActiveHand();
}
break;
case RESURRECT_BUTTON:
if(player.isDead && Resurrection.getRemainingWaitTime(player.deathTime) == 0){
ItemStack stack = WizardryUtilities.getHotbar(player).stream()
.filter(s -> Resurrection.canStackResurrect(s, player)).findFirst().orElse(null);
if(stack != null){
// This should suffice, since this is the only way a player can cast resurrection when dead!
((ISpellCastingItem)stack.getItem()).cast(stack, Spells.resurrection, player, EnumHand.MAIN_HAND, 0, new SpellModifiers());
break;
}
}
Wizardry.logger.warn("Received a resurrect button packet, but the player that sent it was not" +
" currently able to resurrect. This should not happen!");
break;
case CANCEL_RESURRECT:
if(player.world.getGameRules().getBoolean("keepInventory")) break; // Shouldn't even receive this
if(player.isDead){
ItemStack stack = WizardryUtilities.getHotbar(player).stream()
.filter(s -> Resurrection.canStackResurrect(s, player)).findFirst().orElse(null);
if(stack != null){
player.dropItem(stack, true, false);
player.inventory.deleteStack(stack); // Might as well
break;
}
Wizardry.logger.warn("Received a cancel resurrect packet, but the player that sent it was not" +
" holding a wand with the resurrection spell. This should not happen!");
}
Wizardry.logger.warn("Received a cancel resurrect packet, but the player that sent it was not" +
" currently dead. This should not happen!");
break;
case POSSESSION_PROJECTILE:
if(!Possession.isPossessing(player)) Wizardry.logger.warn("Received a possession projectile packet, " +
"but the player that sent it is not currently possessing anything!");
Possession.shootProjectile(player);
break;
}
});
}
@@ -68,8 +129,8 @@ public class PacketControlInput implements IMessageHandler<Message, IMessage> {
return null;
}
public static enum ControlType {
APPLY_BUTTON, NEXT_SPELL_KEY, PREVIOUS_SPELL_KEY;
public enum ControlType {
APPLY_BUTTON, NEXT_SPELL_KEY, PREVIOUS_SPELL_KEY, RESURRECT_BUTTON, CANCEL_RESURRECT, POSSESSION_PROJECTILE
}
public static class Message implements IMessage {
@@ -0,0 +1,94 @@
package electroblob.wizardry.packet;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.packet.PacketDispenserCastSpell.Message;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.util.SpellModifiers;
import io.netty.buffer.ByteBuf;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
/**
* <b>[Server -> Client]</b> This packet is sent when a spell is cast by a dispenser and returns true, and is sent to
* clients so they can spawn the particles. Unlike the player packets, this is for both continuous <b>and</b>
* non-continuous spells.
*/
public class PacketDispenserCastSpell implements IMessageHandler<Message, IMessage> {
@Override
public IMessage onMessage(Message message, MessageContext ctx){
// Just to make sure that the side is correct
if(ctx.side.isClient()){
// Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy
// methods any more than necessary.
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> Wizardry.proxy.handleDispenserCastSpellPacket(message));
}
return null;
}
public static class Message implements IMessage {
/** ID of the spell being cast */
public int spellID;
/** Coordinates of the spell origin */
public double x, y, z;
/** Spell casting direction */
public EnumFacing direction;
/** BlockPos of the block that cast this spell. <i>Not necessarily the same as the (x, y, z) coordinates.</i> */
public BlockPos pos;
/** The number of ticks to cast the spell for, or -1 if the spell should be cast until stopped. */
public int duration;
/** SpellModifiers for the spell */
public SpellModifiers modifiers;
// This constructor is required otherwise you'll get errors (used somewhere in fml through reflection)
public Message(){
}
public Message(double x, double y, double z, EnumFacing direction, BlockPos pos, Spell spell, int duration, SpellModifiers modifiers){
this.x = x;
this.y = y;
this.z = z;
this.direction = direction;
this.pos = pos;
this.spellID = spell.networkID();
this.duration = duration;
this.modifiers = modifiers;
}
@Override
public void fromBytes(ByteBuf buf){
// The order is important
this.x = buf.readDouble();
this.y = buf.readDouble();
this.z = buf.readDouble();
this.direction = EnumFacing.values()[buf.readInt()];
this.pos = BlockPos.fromLong(buf.readLong());
this.spellID = buf.readInt();
this.duration = buf.readInt();
this.modifiers = new SpellModifiers();
this.modifiers.read(buf);
}
@Override
public void toBytes(ByteBuf buf){
buf.writeDouble(x);
buf.writeDouble(y);
buf.writeDouble(z);
buf.writeInt(direction.ordinal());
buf.writeLong(pos.toLong());
buf.writeInt(spellID);
buf.writeInt(duration);
this.modifiers.write(buf);
}
}
}
@@ -0,0 +1,55 @@
package electroblob.wizardry.packet;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.command.SpellEmitter;
import io.netty.buffer.ByteBuf;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import java.util.ArrayList;
import java.util.List;
/**
* <b>[Server -> Client]</b> This packet is sent each time a player joins a world to synchronise the client-side spell
* emitters with the server-side ones.
*/
public class PacketEmitterData implements IMessageHandler<PacketEmitterData.Message, IMessage> {
@Override
public IMessage onMessage(Message message, MessageContext ctx){
// Just to make sure that the side is correct
if(ctx.side.isClient()){
// Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy
// methods any more than necessary.
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> Wizardry.proxy.handleEmitterDataPacket(message));
}
return null;
}
public static class Message implements IMessage {
public List<SpellEmitter> emitters;
// This constructor is required otherwise you'll get errors (used somewhere in fml through reflection)
public Message(){}
public Message(List<SpellEmitter> emitters){
this.emitters = emitters;
}
@Override
public void fromBytes(ByteBuf buf){
emitters = new ArrayList<>();
while(buf.isReadable()){
emitters.add(SpellEmitter.read(buf));
}
}
@Override
public void toBytes(ByteBuf buf){
emitters.forEach(s -> s.write(buf));
}
}
}
@@ -0,0 +1,47 @@
package electroblob.wizardry.packet;
import electroblob.wizardry.Wizardry;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.Entity;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
/** <b>[Server -> Client]</b> This packet is sent when the slow time potion effect expires or is removed from an
* entity to unblock all nearby entities' updates. */
public class PacketEndSlowTime implements IMessageHandler<PacketEndSlowTime.Message, IMessage> {
@Override
public IMessage onMessage(Message message, MessageContext ctx){
// Just to make sure that the side is correct
if(ctx.side.isClient()){
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> Wizardry.proxy.handleEndSlowTimePacket(message));
}
return null;
}
public static class Message implements IMessage {
public int hostID;
// This constructor is required otherwise you'll get errors (used somewhere in fml through reflection)
public Message(){
}
public Message(Entity host){
this.hostID = host.getEntityId();
}
@Override
public void fromBytes(ByteBuf buf){
this.hostID = buf.readInt();
}
@Override
public void toBytes(ByteBuf buf){
buf.writeInt(hostID);
}
}
}
@@ -1,8 +1,5 @@
package electroblob.wizardry.packet;
import java.util.ArrayList;
import java.util.List;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.packet.PacketGlyphData.Message;
import io.netty.buffer.ByteBuf;
@@ -11,6 +8,9 @@ import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import java.util.ArrayList;
import java.util.List;
/**
* <b>[Server -> Client]</b> This packet is sent each time a player joins a world to synchronise the client-side spell
* glyph names with the server-side ones.
@@ -23,12 +23,7 @@ public class PacketGlyphData implements IMessageHandler<Message, IMessage> {
if(ctx.side.isClient()){
// Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy
// methods any more than necessary.
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(new Runnable(){
@Override
public void run(){
Wizardry.proxy.handleGlyphDataPacket(message);
}
});
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> Wizardry.proxy.handleGlyphDataPacket(message));
}
return null;
@@ -52,8 +47,8 @@ public class PacketGlyphData implements IMessageHandler<Message, IMessage> {
@Override
public void fromBytes(ByteBuf buf){
names = new ArrayList<String>();
descriptions = new ArrayList<String>();
names = new ArrayList<>();
descriptions = new ArrayList<>();
while(buf.isReadable()){
names.add(ByteBufUtils.readUTF8String(buf));
descriptions.add(ByteBufUtils.readUTF8String(buf));
@@ -3,6 +3,7 @@ package electroblob.wizardry.packet;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.living.ISpellCaster;
import electroblob.wizardry.packet.PacketNPCCastSpell.Message;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.util.SpellModifiers;
import io.netty.buffer.ByteBuf;
import net.minecraft.util.EnumHand;
@@ -52,10 +53,10 @@ public class PacketNPCCastSpell implements IMessageHandler<Message, IMessage> {
public Message(){
}
public Message(int casterID, int targetID, EnumHand hand, int spellID, SpellModifiers modifiers){
public Message(int casterID, int targetID, EnumHand hand, Spell spell, SpellModifiers modifiers){
this.casterID = casterID;
this.targetID = targetID;
this.spellID = spellID;
this.spellID = spell.networkID();
this.modifiers = modifiers;
this.hand = hand == null ? EnumHand.MAIN_HAND : hand;
}
@@ -1,9 +1,8 @@
package electroblob.wizardry.packet;
import java.util.HashSet;
import java.util.Set;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.data.IVariable;
import electroblob.wizardry.data.WizardData;
import electroblob.wizardry.packet.PacketPlayerSync.Message;
import electroblob.wizardry.spell.Spell;
import io.netty.buffer.ByteBuf;
@@ -11,9 +10,11 @@ import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import java.util.*;
/**
* <b>[Server -> Client]</b> This packet is sent to synchronise any fields that need synchronising in
* {@link electroblob.wizardry.WizardData WizardData}. This packet is not sent often enough and is too small to warrant
* {@link WizardData WizardData}. This packet is not sent often enough and is too small to warrant
* having separate packets for each field that needs synchronising.
*/
public class PacketPlayerSync implements IMessageHandler<Message, IMessage> {
@@ -24,12 +25,7 @@ public class PacketPlayerSync implements IMessageHandler<Message, IMessage> {
if(ctx.side.isClient()){
// Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy
// methods any more than necessary.
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(new Runnable(){
@Override
public void run(){
Wizardry.proxy.handlePlayerSyncPacket(message);
}
});
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> Wizardry.proxy.handlePlayerSyncPacket(message));
}
return null;
@@ -37,36 +33,51 @@ public class PacketPlayerSync implements IMessageHandler<Message, IMessage> {
public static class Message implements IMessage {
public long seed;
public Set<Spell> spellsDiscovered;
public int selectedMinionID;
public Map<IVariable, Object> spellData;
// This constructor is required otherwise you'll get errors (used somewhere in fml through reflection)
public Message(){
}
public Message(Set<Spell> spellsDiscovered2, int selectedMinionID){
this.spellsDiscovered = spellsDiscovered2;
public Message(long seed, Set<Spell> spellsDiscovered, int selectedMinionID, Map<IVariable, Object> spellData){
this.seed = seed;
this.spellsDiscovered = spellsDiscovered;
this.selectedMinionID = selectedMinionID;
this.spellData = spellData;
}
@Override
public void fromBytes(ByteBuf buf){
this.seed = buf.readLong();
this.selectedMinionID = buf.readInt();
this.spellsDiscovered = new HashSet<Spell>();
this.spellData = new HashMap<>();
WizardData.getSyncedVariables().forEach(v -> spellData.put(v, v.read(buf)));
// Have to send empty tags to guarantee correct ByteBuf size/order, but no point keeping the resulting nulls
spellData.values().removeIf(Objects::isNull);
this.spellsDiscovered = new HashSet<>();
while(buf.isReadable()){
this.spellsDiscovered.add(Spell.get(buf.readInt()));
this.spellsDiscovered.add(Spell.byNetworkID(buf.readInt()));
}
}
@Override
@SuppressWarnings("unchecked") // We know it's ok
public void toBytes(ByteBuf buf){
buf.writeLong(seed);
buf.writeInt(selectedMinionID);
if(this.spellsDiscovered == null) return;
WizardData.getSyncedVariables().forEach(v -> v.write(buf, spellData.get(v)));
if(this.spellsDiscovered == null) return;
for(Spell spell : this.spellsDiscovered){
buf.writeInt(spell.id());
buf.writeInt(spell.networkID());
}
}
}
@@ -0,0 +1,58 @@
package electroblob.wizardry.packet;
import electroblob.wizardry.Wizardry;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import javax.annotation.Nullable;
/** <b>[Server -> Client]</b> This packet is sent when a player possesses an entity or when a player stops possessing
* to update all clients. */
public class PacketPossession implements IMessageHandler<PacketPossession.Message, IMessage> {
@Override
public IMessage onMessage(Message message, MessageContext ctx){
// Just to make sure that the side is correct
if(ctx.side.isClient()){
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> Wizardry.proxy.handlePossessionPacket(message));
}
return null;
}
public static class Message implements IMessage {
public int playerID;
public int targetID;
public int duration;
// This constructor is required otherwise you'll get errors (used somewhere in fml through reflection)
public Message(){
}
public Message(EntityPlayer host, @Nullable EntityLiving target, int duration){
this.playerID = host.getEntityId();
this.targetID = target == null ? -1 : target.getEntityId();
this.duration = duration;
}
@Override
public void fromBytes(ByteBuf buf){
this.playerID = buf.readInt();
this.targetID = buf.readInt();
this.duration = buf.readInt();
}
@Override
public void toBytes(ByteBuf buf){
buf.writeInt(playerID);
buf.writeInt(targetID);
buf.writeInt(duration);
}
}
}
@@ -0,0 +1,50 @@
package electroblob.wizardry.packet;
import io.netty.buffer.ByteBuf;
import net.minecraft.advancements.Advancement;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import java.util.ArrayList;
/** <b>[Client -> Server]</b> Fired on resource reload to request that the server re-sync the player's advancements. */
public class PacketRequestAdvancementSync implements IMessageHandler<PacketRequestAdvancementSync.Message, PacketSyncAdvancements.Message> {
@Override
public PacketSyncAdvancements.Message onMessage(Message message, MessageContext ctx){
// Just to make sure that the side is correct
if(ctx.side.isServer()){
final EntityPlayerMP player = ctx.getServerHandler().player;
ArrayList<ResourceLocation> advancements = new ArrayList<>();
for(Advancement advancement : player.getServer().getAdvancementManager().getAdvancements()){
if(player.getAdvancements().getProgress(advancement).isDone()) advancements.add(advancement.getId());
}
return new PacketSyncAdvancements.Message(false, advancements.toArray(new ResourceLocation[0]));
}
return null;
}
public static class Message implements IMessage {
// This constructor is required otherwise you'll get errors (used somewhere in fml through reflection)
public Message(){}
// Don't need to put anything in here!
@Override
public void fromBytes(ByteBuf buf){}
@Override
public void toBytes(ByteBuf buf){}
}
}
@@ -0,0 +1,47 @@
package electroblob.wizardry.packet;
import electroblob.wizardry.Wizardry;
import io.netty.buffer.ByteBuf;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
/**
* <b>[Server -> Client]</b> This packet is sent to clients in the same dimension when a player is resurrected.
*/
public class PacketResurrection implements IMessageHandler<PacketResurrection.Message, IMessage> {
@Override
public IMessage onMessage(Message message, MessageContext ctx){
// Just to make sure that the side is correct
if(ctx.side.isClient()){
// Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy
// methods any more than necessary.
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> Wizardry.proxy.handleResurrectionPacket(message));
}
return null;
}
public static class Message implements IMessage {
public int playerID;
// This constructor is required otherwise you'll get errors (used somewhere in fml through reflection)
public Message(){}
public Message(int playerID){
this.playerID = playerID;
}
@Override
public void fromBytes(ByteBuf buf){
this.playerID = buf.readInt();
}
@Override
public void toBytes(ByteBuf buf){
buf.writeInt(playerID);
}
}
}
@@ -0,0 +1,64 @@
package electroblob.wizardry.packet;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.util.SpellProperties;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import java.util.ArrayList;
import java.util.List;
/** <b>[Server -> Client]</b> This packet is sent to sync server-side spell properties with clients on login. */
public class PacketSpellProperties implements IMessageHandler<PacketSpellProperties.Message, IMessage> {
@Override
public IMessage onMessage(Message message, MessageContext ctx){
// Just to make sure that the side is correct
if(ctx.side.isServer()){
final EntityPlayerMP player = ctx.getServerHandler().player;
player.getServerWorld().addScheduledTask(() -> {
for(int i=0; i<message.propertiesArray.length; i++){
Spell.byNetworkID(i).setProperties(message.propertiesArray[i]);
}
});
}
return null;
}
public static class Message implements IMessage {
private SpellProperties[] propertiesArray;
// This constructor is required otherwise you'll get errors (used somewhere in fml through reflection)
public Message(){}
public Message(SpellProperties... properties){
this.propertiesArray = properties;
}
@Override
public void fromBytes(ByteBuf buf){
List<SpellProperties> propertiesList = new ArrayList<>();
int i = 0;
while(buf.isReadable()){
propertiesList.add(new SpellProperties(Spell.byNetworkID(i++), buf));
}
propertiesArray = propertiesList.toArray(new SpellProperties[0]);
}
@Override
public void toBytes(ByteBuf buf){
for(SpellProperties properties : propertiesArray) properties.write(buf);
}
}
}
@@ -0,0 +1,61 @@
package electroblob.wizardry.packet;
import electroblob.wizardry.Wizardry;
import io.netty.buffer.ByteBuf;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import java.util.ArrayList;
/** <b>[Server -> Client]</b> This packet is fired on login and on advancement gain to update the handbook progress. */
public class PacketSyncAdvancements implements IMessageHandler<PacketSyncAdvancements.Message, IMessage> {
@Override
public IMessage onMessage(Message message, MessageContext ctx){
// Just to make sure that the side is correct
if(ctx.side.isClient()){
// Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy
// methods any more than necessary.
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> Wizardry.proxy.handleAdvancementSyncPacket(message));
}
return null;
}
public static class Message implements IMessage {
public boolean showToasts;
public ResourceLocation[] completedAdvancements;
// This constructor is required otherwise you'll get errors (used somewhere in fml through reflection)
public Message(){
}
public Message(boolean showToasts, ResourceLocation... completed){
this.showToasts = showToasts;
this.completedAdvancements = completed;
}
@Override
public void fromBytes(ByteBuf buf){
showToasts = buf.readBoolean();
ArrayList<ResourceLocation> advancements = new ArrayList<>();
while(buf.isReadable()){
advancements.add(new ResourceLocation(ByteBufUtils.readUTF8String(buf)));
}
this.completedAdvancements = advancements.toArray(new ResourceLocation[0]);
}
@Override
public void toBytes(ByteBuf buf){
buf.writeBoolean(showToasts);
for(ResourceLocation advancement : completedAdvancements){
ByteBufUtils.writeUTF8String(buf, advancement.toString());
}
}
}
}
@@ -21,13 +21,7 @@ public class PacketSyncSettings implements IMessageHandler<Message, IMessage> {
if(ctx.side.isClient()){
// Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy
// any more than necessary.
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(new Runnable(){
@Override
public void run(){
copySettings(message);
}
});
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> copySettings(message));
}
return null;
@@ -35,16 +29,14 @@ public class PacketSyncSettings implements IMessageHandler<Message, IMessage> {
private static void copySettings(Message message){
Wizardry.settings.discoveryMode = message.settings.discoveryMode;
// Wizardry.settings.maxSpellCommandMultiplier = message.settings.maxSpellCommandMultiplier;
// Wizardry.settings.castCommandName = message.settings.castCommandName;
// Wizardry.settings.discoverspellCommandName = message.settings.discoverspellCommandName;
// Wizardry.settings.allyCommandName = message.settings.allyCommandName;
// Wizardry.settings.alliesCommandName = message.settings.alliesCommandName;
Wizardry.settings.creativeBypassesArcaneLock = message.settings.creativeBypassesArcaneLock;
Wizardry.settings.slowTimeAffectsPlayers = message.settings.slowTimeAffectsPlayers;
Wizardry.settings.forfeitChance = message.settings.forfeitChance;
}
public static class Message implements IMessage {
/** EntityID of the caster */
/** Instance of wizardry's settings object */
public Settings settings;
// This constructor is required otherwise you'll get errors (used somewhere in fml through reflection)
@@ -62,21 +54,17 @@ public class PacketSyncSettings implements IMessageHandler<Message, IMessage> {
settings = new Settings();
// The order is important
settings.discoveryMode = buf.readBoolean();
// settings.maxSpellCommandMultiplier = buf.readDouble();
// settings.castCommandName = ByteBufUtils.readUTF8String(buf);
// settings.discoverspellCommandName = ByteBufUtils.readUTF8String(buf);
// settings.allyCommandName = ByteBufUtils.readUTF8String(buf);
// settings.alliesCommandName = ByteBufUtils.readUTF8String(buf);
settings.creativeBypassesArcaneLock = buf.readBoolean();
settings.slowTimeAffectsPlayers = buf.readBoolean();
settings.forfeitChance = buf.readFloat();
}
@Override
public void toBytes(ByteBuf buf){
buf.writeBoolean(settings.discoveryMode);
// buf.writeDouble(settings.maxSpellCommandMultiplier);
// ByteBufUtils.writeUTF8String(buf, settings.castCommandName);
// ByteBufUtils.writeUTF8String(buf, settings.discoverspellCommandName);
// ByteBufUtils.writeUTF8String(buf, settings.allyCommandName);
// ByteBufUtils.writeUTF8String(buf, settings.alliesCommandName);
buf.writeBoolean(settings.creativeBypassesArcaneLock);
buf.writeBoolean(settings.slowTimeAffectsPlayers);
buf.writeFloat((float)settings.forfeitChance); // Configs don't have floats but this can only be 0-1 anyway
}
}
}
@@ -19,12 +19,7 @@ public class PacketTransportation implements IMessageHandler<Message, IMessage>
if(ctx.side.isClient()){
// Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy
// methods any more than necessary.
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(new Runnable(){
@Override
public void run(){
Wizardry.proxy.handleTransportationPacket(message);
}
});
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> Wizardry.proxy.handleTransportationPacket(message));
}
return null;
@@ -22,6 +22,16 @@ public class WizardryPacketHandler {
registerMessage(PacketClairvoyance.class, PacketClairvoyance.Message.class);
registerMessage(PacketSyncSettings.class, PacketSyncSettings.Message.class);
registerMessage(PacketNPCCastSpell.class, PacketNPCCastSpell.Message.class);
registerMessage(PacketDispenserCastSpell.class, PacketDispenserCastSpell.Message.class);
registerMessage(PacketSpellProperties.class, PacketSpellProperties.Message.class);
registerMessage(PacketSyncAdvancements.class, PacketSyncAdvancements.Message.class);
registerMessage(PacketRequestAdvancementSync.class, PacketRequestAdvancementSync.Message.class);
registerMessage(PacketEndSlowTime.class, PacketEndSlowTime.Message.class);
registerMessage(PacketResurrection.class, PacketResurrection.Message.class);
registerMessage(PacketCastSpellAtPos.class, PacketCastSpellAtPos.Message.class);
registerMessage(PacketEmitterData.class, PacketEmitterData.Message.class);
registerMessage(PacketPossession.class, PacketPossession.Message.class);
registerMessage(PacketConquerShrine.class, PacketConquerShrine.Message.class);
}
private static int nextPacketId = 0;