mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-24 05:47:59 +01:00
Implement networking, reimplement pega-reach
This commit is contained in:
parent
2536872aad
commit
5708f9c80f
36 changed files with 367 additions and 608 deletions
|
@ -1,23 +0,0 @@
|
|||
package com.minelittlepony.jumpingcastle.api;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.jumpingcastle.api.payload.BinaryPayload;
|
||||
|
||||
/**
|
||||
* Implementor for a Jumping Castle API bus.
|
||||
*/
|
||||
public interface Bus {
|
||||
void sendToServer(String channel, long id, Message message, Target target);
|
||||
|
||||
void sendToClient(String channel, long id, Message message, UUID playerId);
|
||||
|
||||
void sendToClient(UUID playerId, BinaryPayload forwarded);
|
||||
|
||||
@Nullable
|
||||
Object getMinecraftServer();
|
||||
|
||||
Server getServer();
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package com.minelittlepony.jumpingcastle.api;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A channel for sending and recieving messages.
|
||||
*/
|
||||
public interface Channel {
|
||||
/**
|
||||
* Registers a handler for a specific message type transmitted over this channel.
|
||||
*
|
||||
* @param messageType The message type being recieved.
|
||||
* @param handler A handler instance to handle the message.
|
||||
*/
|
||||
<T extends Message> Channel listenFor(Class<T> messageType, Message.Handler<T> handler);
|
||||
|
||||
/**
|
||||
* Registers a handler for a specific message type transmitted over this channel.
|
||||
*
|
||||
* @param messageType The message type being recieved.
|
||||
*/
|
||||
<T extends Message & Message.Handler<T>> Channel listenFor(Class<T> messageType);
|
||||
|
||||
/**
|
||||
* Gets the minecraft server
|
||||
*/
|
||||
<T> T getServer();
|
||||
|
||||
/**
|
||||
* Sends a message over this channel. By default targets all other clients listening on this channel.
|
||||
*
|
||||
* @param message The message to send.
|
||||
*/
|
||||
default Channel send(Message message) {
|
||||
return send(message, Target.CLIENTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message over this channel.
|
||||
*
|
||||
* @param message The message to send.
|
||||
* @param target Recipients that must handle this message (clients, server, or both)
|
||||
*/
|
||||
Channel send(Message message, Target target);
|
||||
|
||||
/**
|
||||
* Sends a message back. Use this if you're a server.
|
||||
*
|
||||
* @param message The message to send.
|
||||
* @param recipient Recipient that must handle this message
|
||||
*/
|
||||
Channel respond(Message message, UUID recipient);
|
||||
|
||||
/**
|
||||
* Sends a message back to all clients. Use this if you're a server.
|
||||
*
|
||||
* @param message The message to send.
|
||||
*/
|
||||
Channel broadcast(Message message);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package com.minelittlepony.jumpingcastle.api;
|
||||
|
||||
/**
|
||||
* Jumping Castle main interface.
|
||||
* <p>
|
||||
*{@code
|
||||
* JumpingCastle.listen("My Channel").consume(MyMessage.class, (msg, channel) -> {
|
||||
* ...
|
||||
* });
|
||||
*
|
||||
*/
|
||||
public interface JumpingCastle {
|
||||
/**
|
||||
* Gets or creates a new channel indexed by the given identifier.
|
||||
*
|
||||
* @param channelName The channel name
|
||||
*
|
||||
* @return An instance of IChannel.
|
||||
*/
|
||||
static Channel subscribeTo(String channelName, Client clientHandler) {
|
||||
return null;// TODO: JumpingFabric
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Client {
|
||||
void connectionEstablished();
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
package com.minelittlepony.jumpingcastle.api;
|
||||
|
||||
import com.minelittlepony.jumpingcastle.api.payload.Serializable;
|
||||
|
||||
/**
|
||||
* A message for communicating over a channel.
|
||||
* Fields marked with @Expose are automatically serialized to the output packet stream
|
||||
* and will be made available on the far end of the pipe.
|
||||
*
|
||||
* Override the read and write methods to customise this behaviour.
|
||||
*
|
||||
*/
|
||||
public interface Message extends Serializable<Message> {
|
||||
|
||||
/**
|
||||
* Gets a unique identifier to represent a packet over channel communications.
|
||||
*/
|
||||
static long identifier(Class<? extends Message> cls) {
|
||||
return cls.getCanonicalName().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a unique identifier to represent this packet over channel communications.
|
||||
*/
|
||||
default long identifier() {
|
||||
return identifier(getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler interface for incoming messages.
|
||||
*
|
||||
* @param <T> The type of message to handle.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface Handler<T extends Message> {
|
||||
/**
|
||||
* Called when a new message is received.
|
||||
*
|
||||
* @param message The message received.
|
||||
*
|
||||
* @param channel The channel used to deliver the message.
|
||||
*/
|
||||
void onPayload(T message, Channel channel);
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package com.minelittlepony.jumpingcastle.api;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface Server {
|
||||
void stopTrackingPlayer(UUID playerId);
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
package com.minelittlepony.jumpingcastle.api;
|
||||
|
||||
/**
|
||||
* Targeting method to control who receives a message when sent.
|
||||
* Senders choose whether a message is received on other clients, just the server, or both.
|
||||
*/
|
||||
public enum Target {
|
||||
/**
|
||||
* Message is ignored by the server and forwarded to connected clients.
|
||||
*/
|
||||
CLIENTS(true, false),
|
||||
/**
|
||||
* Only the server should process this message. Clients ignore it.
|
||||
*/
|
||||
SERVER(false, true),
|
||||
/**
|
||||
* The server should process this message and forward it to all available clients.
|
||||
*/
|
||||
SERVER_AND_CLIENTS(true, true);
|
||||
|
||||
private final boolean clients;
|
||||
|
||||
private final boolean servers;
|
||||
|
||||
Target(boolean clients, boolean servers) {
|
||||
this.clients = clients;
|
||||
this.servers = servers;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if messages with this targeting must be processed by the client.
|
||||
*/
|
||||
public boolean isClients() {
|
||||
return clients;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if messages with this targeting must be processed by the server.
|
||||
*/
|
||||
public boolean isServers() {
|
||||
return servers;
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
package com.minelittlepony.jumpingcastle.api.payload;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
public interface BinaryPayload {
|
||||
|
||||
@Nullable
|
||||
static BinaryPayload of(Object buffer) {
|
||||
if (buffer instanceof ByteBuf) {
|
||||
return ByteBufBinaryPayload.of((ByteBuf)buffer);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static BinaryPayload create() {
|
||||
return of(Unpooled.buffer());
|
||||
}
|
||||
|
||||
<T> T buff();
|
||||
|
||||
byte[] bytes();
|
||||
|
||||
byte[] readToEnd();
|
||||
|
||||
long readLong();
|
||||
|
||||
BinaryPayload writeLong(long l);
|
||||
|
||||
int readInt();
|
||||
|
||||
BinaryPayload writeInt(int b);
|
||||
|
||||
byte readByte();
|
||||
|
||||
BinaryPayload writeByte(byte b);
|
||||
|
||||
String readString();
|
||||
|
||||
BinaryPayload writeString(String s);
|
||||
|
||||
byte[] readBytes(int len);
|
||||
|
||||
BinaryPayload writeBytes(byte[] bytes);
|
||||
|
||||
BinaryPayload reverse();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
default <T extends Serializable<? super T>> T readBinary(Class<T> type) {
|
||||
try {
|
||||
return (T)type.newInstance().read(this);
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
default <T extends Serializable<T>> BinaryPayload writeBinary(T message) {
|
||||
message.write(this);
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
package com.minelittlepony.jumpingcastle.api.payload;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
interface ByteBufBinaryPayload extends BinaryPayload {
|
||||
|
||||
static BinaryPayload of(ByteBuf buff) {
|
||||
return (ByteBufBinaryPayload)(() -> buff);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ByteBuf buff();
|
||||
|
||||
@Override
|
||||
default String readString() {
|
||||
return buff().readCharSequence(readInt(), StandardCharsets.UTF_8).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
default int readInt() {
|
||||
return buff().readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
default BinaryPayload writeInt(int b) {
|
||||
buff().writeInt(b);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
default byte readByte() {
|
||||
return buff().readByte();
|
||||
}
|
||||
|
||||
@Override
|
||||
default BinaryPayload writeByte(byte b) {
|
||||
buff().writeByte(b);
|
||||
return this;
|
||||
}
|
||||
|
||||
default byte[] bytes() {
|
||||
return buff().array();
|
||||
}
|
||||
|
||||
default byte[] readToEnd() {
|
||||
byte[] bytes = new byte[buff().writerIndex() - buff().readerIndex()];
|
||||
buff().readBytes(bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
default long readLong() {
|
||||
return buff().readLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
default BinaryPayload writeLong(long l) {
|
||||
buff().writeLong(l);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
default BinaryPayload reverse() {
|
||||
buff().readerIndex(0);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
default byte[] readBytes(int len) {
|
||||
byte[] data = new byte[len];
|
||||
buff().readBytes(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
default BinaryPayload writeBytes(byte[] bytes) {
|
||||
buff().writeBytes(bytes);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
default BinaryPayload writeString(String s) {
|
||||
buff().writeInt(s.getBytes(StandardCharsets.UTF_8).length);
|
||||
buff().writeCharSequence(s, StandardCharsets.UTF_8);
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package com.minelittlepony.jumpingcastle.api.payload;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
public class JsonSerializer {
|
||||
private static final Gson READER_GSON = new GsonBuilder()
|
||||
.excludeFieldsWithoutExposeAnnotation()
|
||||
.create();
|
||||
|
||||
public static <T> T read(BinaryPayload payload, Class<T> type) {
|
||||
return (T)READER_GSON.fromJson(payload.readString(), type);
|
||||
}
|
||||
|
||||
public static <T> void write(BinaryPayload payload, T object) {
|
||||
payload.writeString(READER_GSON.toJson(object));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package com.minelittlepony.jumpingcastle.api.payload;
|
||||
|
||||
public interface Serializable<T extends Serializable<T>> {
|
||||
/**
|
||||
* Reads the contents of this message from a networking payload.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
default T read(BinaryPayload payload) {
|
||||
return (T)JsonSerializer.read(payload, getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the contents of this message to a networking payload.
|
||||
*/
|
||||
default void write(BinaryPayload payload) {
|
||||
JsonSerializer.write(payload, this);
|
||||
}
|
||||
|
||||
}
|
|
@ -16,7 +16,7 @@ import net.minecraft.world.World;
|
|||
|
||||
@Deprecated
|
||||
public class CustomDrops {
|
||||
// TODO: loot table
|
||||
// XXX: loot table
|
||||
public void addAuxiliaryDrops(World world, BlockState state, BlockPos pos, List<ItemStack> drops, int fortune) {
|
||||
Block block = state.getBlock();
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ import net.minecraft.util.Identifier;
|
|||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public final class TreeType {
|
||||
// TODO: move to datapack
|
||||
// XXX: move to datapack
|
||||
private static final Set<TreeType> REGISTRY = new HashSet<>();
|
||||
|
||||
public static final TreeType NONE = new TreeType("none", new Weighted<Supplier<ItemStack>>());
|
||||
|
|
|
@ -8,8 +8,6 @@ import org.apache.logging.log4j.LogManager;
|
|||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.minelittlepony.common.util.GamePaths;
|
||||
import com.minelittlepony.jumpingcastle.api.Channel;
|
||||
import com.minelittlepony.jumpingcastle.api.JumpingCastle;
|
||||
import com.minelittlepony.unicopia.ability.Abilities;
|
||||
import com.minelittlepony.unicopia.advancement.BOHDeathCriterion;
|
||||
import com.minelittlepony.unicopia.block.UBlocks;
|
||||
|
@ -17,39 +15,28 @@ import com.minelittlepony.unicopia.command.Commands;
|
|||
import com.minelittlepony.unicopia.container.UContainers;
|
||||
import com.minelittlepony.unicopia.enchanting.Pages;
|
||||
import com.minelittlepony.unicopia.enchanting.recipe.AffineIngredients;
|
||||
import com.minelittlepony.unicopia.enchanting.recipe.URecipes;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.mixin.CriterionsRegistry;
|
||||
import com.minelittlepony.unicopia.network.MsgPlayerAbility;
|
||||
import com.minelittlepony.unicopia.network.MsgPlayerCapabilities;
|
||||
import com.minelittlepony.unicopia.network.MsgRequestCapabilities;
|
||||
import com.minelittlepony.unicopia.network.Channel;
|
||||
import com.minelittlepony.unicopia.structure.UStructures;
|
||||
|
||||
public class Unicopia implements ModInitializer {
|
||||
public static final String MODID = "unicopia";
|
||||
|
||||
public static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
private static Channel channel;
|
||||
|
||||
public static Channel getConnection() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
Config.init(GamePaths.getConfigDirectory());
|
||||
|
||||
channel = JumpingCastle.subscribeTo(MODID, () -> {})
|
||||
.listenFor(MsgRequestCapabilities.class)
|
||||
.listenFor(MsgPlayerCapabilities.class)
|
||||
.listenFor(MsgPlayerAbility.class);
|
||||
|
||||
Channel.bootstrap();
|
||||
UTags.bootstrap();
|
||||
Commands.bootstrap();
|
||||
UBlocks.bootstrap();
|
||||
UItems.bootstrap();
|
||||
UContainers.bootstrap();
|
||||
UStructures.bootstrap();
|
||||
URecipes.bootstrap();
|
||||
Abilities.getInstance().init();
|
||||
|
||||
CriterionsRegistry.register(BOHDeathCriterion.INSTANCE);
|
||||
|
|
|
@ -50,7 +50,7 @@ public class UnicornCastingAbility implements Ability<Ability.Hit> {
|
|||
|
||||
@Override
|
||||
public void apply(Pony player, Hit data) {
|
||||
// TODO: A way for the player to select which effect they want
|
||||
// XXX: A way for the player to select which effect they want
|
||||
if (player.getEffect() instanceof ShieldSpell) {
|
||||
player.setEffect(null);
|
||||
} else {
|
||||
|
|
|
@ -6,11 +6,9 @@ import javax.annotation.Nonnull;
|
|||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.common.event.ClientReadyCallback;
|
||||
import com.minelittlepony.jumpingcastle.api.Target;
|
||||
import com.minelittlepony.unicopia.Config;
|
||||
import com.minelittlepony.unicopia.InteractionManager;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.ability.Abilities;
|
||||
import com.minelittlepony.unicopia.block.UBlocks;
|
||||
import com.minelittlepony.unicopia.container.SpellbookResultSlot;
|
||||
|
@ -19,6 +17,7 @@ import com.minelittlepony.unicopia.entity.player.Pony;
|
|||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.magic.spell.SpellRegistry;
|
||||
import com.minelittlepony.unicopia.mixin.client.DefaultTexturesRegistry;
|
||||
import com.minelittlepony.unicopia.network.Channel;
|
||||
import com.minelittlepony.unicopia.network.MsgRequestCapabilities;
|
||||
import com.minelittlepony.unicopia.util.dummy.DummyClientPlayerEntity;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
@ -84,7 +83,7 @@ public class UnicopiaClient extends InteractionManager implements ClientModIniti
|
|||
if (newRace != clientPlayerRace) {
|
||||
clientPlayerRace = newRace;
|
||||
|
||||
Unicopia.getConnection().send(new MsgRequestCapabilities(player, clientPlayerRace), Target.SERVER);
|
||||
Channel.REQUEST_CAPABILITIES.send(new MsgRequestCapabilities(player, clientPlayerRace));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import com.minelittlepony.unicopia.entity.player.Pony;
|
|||
import net.minecraft.client.MinecraftClient;
|
||||
|
||||
@Deprecated
|
||||
// TODO: forge events
|
||||
// XXX: hud render events
|
||||
class HudHooks {
|
||||
public static void beforePreRenderHud() {
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
|
|
|
@ -5,6 +5,7 @@ import javax.annotation.Nonnull;
|
|||
import com.minelittlepony.unicopia.AwaitTickQueue;
|
||||
import com.minelittlepony.unicopia.EquinePredicates;
|
||||
import com.minelittlepony.unicopia.enchanting.IPageUnlockListener;
|
||||
import com.minelittlepony.unicopia.enchanting.recipe.URecipes;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.magic.spell.SpellRegistry;
|
||||
|
||||
|
@ -16,7 +17,6 @@ import net.minecraft.inventory.Inventory;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
import net.minecraft.recipe.Recipe;
|
||||
import net.minecraft.recipe.RecipeType;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
|
@ -73,8 +73,7 @@ public class SpellBookContainer extends Container {
|
|||
ItemStack current = craftResult.getInvStack(0);
|
||||
|
||||
if (!current.isEmpty()) {
|
||||
// TODO: URecipeType.SPELL_BOOK
|
||||
ItemStack crafted = player.world.getRecipeManager().getFirstMatch(RecipeType.CRAFTING, craftMatrix, worldObj)
|
||||
ItemStack crafted = player.world.getRecipeManager().getFirstMatch(URecipes.SPELL_BOOK, craftMatrix, worldObj)
|
||||
.map(Recipe::getOutput)
|
||||
.orElse(ItemStack.EMPTY);
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.container;
|
|||
|
||||
import com.minelittlepony.unicopia.enchanting.IPageUnlockListener;
|
||||
import com.minelittlepony.unicopia.enchanting.SpellCraftingEvent;
|
||||
import com.minelittlepony.unicopia.enchanting.recipe.URecipes;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.MagicGemItem;
|
||||
import com.minelittlepony.unicopia.magic.spell.SpellRegistry;
|
||||
|
@ -12,7 +13,6 @@ import net.minecraft.entity.player.PlayerEntity;
|
|||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.MusicDiscItem;
|
||||
import net.minecraft.recipe.RecipeType;
|
||||
import net.minecraft.util.DefaultedList;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
|
@ -49,8 +49,7 @@ public class SpellbookResultSlot extends SpellBookContainer.SpellbookSlot {
|
|||
ItemStack current = craftMatrix.getCraftResultMatrix().getInvStack(0);
|
||||
craftMatrix.getCraftResultMatrix().setInvStack(0, stack);
|
||||
|
||||
// TODO: URecipeType.SPELL_BOOK
|
||||
DefaultedList<ItemStack> remaining = player.world.getRecipeManager().getRemainingStacks(RecipeType.CRAFTING, craftMatrix, player.world);
|
||||
DefaultedList<ItemStack> remaining = player.world.getRecipeManager().getRemainingStacks(URecipes.SPELL_BOOK, craftMatrix, player.world);
|
||||
|
||||
craftMatrix.getCraftResultMatrix().setInvStack(0, current);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.minelittlepony.unicopia.ducks;
|
||||
|
||||
@Deprecated
|
||||
// TODO: 1.16 Use the vanilla BlockTag once mojang adds it
|
||||
// XXX: 1.16 Use the vanilla BlockTag once mojang adds it
|
||||
public interface Climbable {
|
||||
|
||||
}
|
||||
|
|
|
@ -2,29 +2,18 @@ package com.minelittlepony.unicopia.enchanting.recipe;
|
|||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.minecraft.inventory.CraftingInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.recipe.Recipe;
|
||||
import net.minecraft.recipe.RecipeSerializer;
|
||||
import net.minecraft.recipe.RecipeType;
|
||||
import net.minecraft.util.DefaultedList;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
|
||||
public class SpecialRecipe extends AbstractSpecialRecipe {
|
||||
|
||||
private final SpellIngredient output;
|
||||
|
||||
public static Recipe<CraftingInventory> deserialize(JsonObject json) {
|
||||
return new SpecialRecipe(null,
|
||||
SpellIngredient.single(json.get("input").getAsJsonObject()),
|
||||
SpellIngredient.single(json.get("output").getAsJsonObject()),
|
||||
SpellIngredient.multiple(json)
|
||||
);
|
||||
}
|
||||
|
||||
public SpecialRecipe(Identifier id, SpellIngredient input, SpellIngredient output, DefaultedList<SpellIngredient> ingredients) {
|
||||
super(id, input, ingredients);
|
||||
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
|
@ -35,13 +24,45 @@ public class SpecialRecipe extends AbstractSpecialRecipe {
|
|||
|
||||
@Override
|
||||
public RecipeSerializer<?> getSerializer() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return URecipes.SPECIAL_SERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType<?> getType() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return URecipes.SPELL_BOOK;
|
||||
}
|
||||
|
||||
public static class Serializer implements RecipeSerializer<SpecialRecipe> {
|
||||
@Override
|
||||
public SpecialRecipe read(Identifier id, JsonObject json) {
|
||||
return new SpecialRecipe(id,
|
||||
SpellIngredient.single(json.get("input").getAsJsonObject()),
|
||||
SpellIngredient.single(json.get("output").getAsJsonObject()),
|
||||
SpellIngredient.multiple(json)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpecialRecipe read(Identifier id, PacketByteBuf buf) {
|
||||
SpellIngredient input = SpellIngredient.SERIALIZER.read(buf);
|
||||
SpellIngredient output = SpellIngredient.SERIALIZER.read(buf);
|
||||
int length = buf.readInt();
|
||||
DefaultedList<SpellIngredient> ingredients = DefaultedList.copyOf(SpellIngredient.EMPTY);
|
||||
while (ingredients.size() < length) {
|
||||
ingredients.add(SpellIngredient.SERIALIZER.read(buf));
|
||||
}
|
||||
|
||||
return new SpecialRecipe(id, input, output, ingredients);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketByteBuf buf, SpecialRecipe recipe) {
|
||||
recipe.getSpellItem().write(buf);
|
||||
recipe.output.write(buf);
|
||||
DefaultedList<SpellIngredient> ingredients = recipe.getSpellIngredients();
|
||||
buf.writeInt(ingredients.size());
|
||||
ingredients.forEach(i -> i.write(buf));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.enchanting.recipe;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
|
@ -20,6 +21,7 @@ public interface SpellIngredient {
|
|||
map.put("single", SingleSpellIngredient.SERIALIZER);
|
||||
map.put("affine", AffineIngredient.SERIALIZER);
|
||||
});
|
||||
Map<Serializer<? extends SpellIngredient>, String> IDS = SERIALIZERS.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
|
||||
|
||||
Serializer<SpellIngredient> SERIALIZER = new Serializer<SpellIngredient>() {
|
||||
@Override
|
||||
|
@ -40,7 +42,7 @@ public interface SpellIngredient {
|
|||
|
||||
@Override
|
||||
public void write(PacketByteBuf buff, SpellIngredient recipe) {
|
||||
buff.writeByte(recipe instanceof SingleSpellIngredient ? 0 : 1);
|
||||
buff.writeString(IDS.get(recipe.getSerializer()));
|
||||
recipe.write(buff);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -45,16 +45,15 @@ public class SpellRecipe extends AbstractSpecialRecipe {
|
|||
|
||||
@Override
|
||||
public RecipeSerializer<?> getSerializer() {
|
||||
return null;
|
||||
return URecipes.SPELL_SERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType<?> getType() {
|
||||
return null;
|
||||
return URecipes.SPELL_BOOK;
|
||||
}
|
||||
|
||||
public static class Serializer implements RecipeSerializer<SpellRecipe> {
|
||||
|
||||
@Override
|
||||
public SpellRecipe read(Identifier id, JsonObject json) {
|
||||
JsonObject resultJson = json.get("result").getAsJsonObject();
|
||||
|
@ -93,4 +92,5 @@ public class SpellRecipe extends AbstractSpecialRecipe {
|
|||
ingredients.forEach(i -> i.write(buff));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package com.minelittlepony.unicopia.enchanting.recipe;
|
||||
|
||||
import net.minecraft.recipe.Recipe;
|
||||
import net.minecraft.recipe.RecipeSerializer;
|
||||
import net.minecraft.recipe.RecipeType;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public interface URecipes {
|
||||
|
||||
RecipeType<SpellRecipe> SPELL_BOOK = register("spell_book");
|
||||
|
||||
RecipeSerializer<SpecialRecipe> SPECIAL_SERIALIZER = register("special_spell", new SpecialRecipe.Serializer());
|
||||
RecipeSerializer<SpellRecipe> SPELL_SERIALIZER = register("spell", new SpellRecipe.Serializer());
|
||||
|
||||
static <T extends Recipe<?>> RecipeType<T> register(final String id) {
|
||||
return Registry.register(Registry.RECIPE_TYPE, new Identifier("unicopia", id), new RecipeType<T>() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return id;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static <S extends RecipeSerializer<T>, T extends Recipe<?>> S register(String id, S serializer) {
|
||||
return Registry.register(Registry.RECIPE_SERIALIZER, new Identifier("unicopia", id), serializer);
|
||||
}
|
||||
|
||||
static void bootstrap() {}
|
||||
}
|
|
@ -1,18 +1,17 @@
|
|||
package com.minelittlepony.unicopia.entity;
|
||||
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.network.Channel;
|
||||
import com.minelittlepony.unicopia.network.MsgSpawnRainbow;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.packet.EntitySpawnGlobalS2CPacket;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityDimensions;
|
||||
import net.minecraft.entity.EntityPose;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LightningEntity;
|
||||
import net.minecraft.entity.SpawnType;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.NetworkThreadUtils;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.listener.ClientPlayPacketListener;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
@ -26,7 +25,7 @@ public class RainbowEntity extends Entity implements InAnimate {
|
|||
|
||||
private int ticksAlive;
|
||||
|
||||
private double radius;
|
||||
private final double radius;
|
||||
|
||||
public static final int RAINBOW_MAX_SIZE = 180;
|
||||
public static final int RAINBOW_MIN_SIZE = 50;
|
||||
|
@ -49,8 +48,7 @@ public class RainbowEntity extends Entity implements InAnimate {
|
|||
|
||||
ignoreCameraFrustum = true;
|
||||
|
||||
//width = (float)radius;
|
||||
//height = width;
|
||||
calculateDimensions();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -69,6 +67,11 @@ public class RainbowEntity extends Entity implements InAnimate {
|
|||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityDimensions getDimensions(EntityPose pose) {
|
||||
return EntityDimensions.changing((float)getRadius(), (float)getRadius());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundCategory getSoundCategory() {
|
||||
return SoundCategory.WEATHER;
|
||||
|
@ -119,7 +122,7 @@ public class RainbowEntity extends Entity implements InAnimate {
|
|||
|
||||
@Override
|
||||
public Packet<?> createSpawnPacket() {
|
||||
return new SpawnPacket(this);
|
||||
return Channel.SPAWN_RAINBOW.toPacket(new MsgSpawnRainbow(this));
|
||||
}
|
||||
|
||||
public static class Spawner extends MobEntity {
|
||||
|
@ -159,27 +162,4 @@ public class RainbowEntity extends Entity implements InAnimate {
|
|||
world.spawnEntity(rainbow);
|
||||
}
|
||||
}
|
||||
|
||||
static class SpawnPacket extends EntitySpawnGlobalS2CPacket {
|
||||
public SpawnPacket(RainbowEntity entity) {
|
||||
super(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(ClientPlayPacketListener listener) {
|
||||
// TODO: Packet needs to be registered, and handling separated
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
|
||||
NetworkThreadUtils.forceMainThread(this, listener, client);
|
||||
double x = getX();
|
||||
double y = getY();
|
||||
double z = getZ();
|
||||
LightningEntity entity = new LightningEntity(client.world, x, y, z, false);
|
||||
entity.updateTrackedPosition(x, y, z);
|
||||
entity.yaw = 0;
|
||||
entity.pitch = 0;
|
||||
entity.setEntityId(getId());
|
||||
client.world.addLightning(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
package com.minelittlepony.unicopia.entity.player;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.jumpingcastle.api.Target;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.ability.AbilityReceiver;
|
||||
import com.minelittlepony.unicopia.ability.Ability;
|
||||
import com.minelittlepony.unicopia.ability.Abilities;
|
||||
import com.minelittlepony.unicopia.entity.Updatable;
|
||||
import com.minelittlepony.unicopia.network.MsgPlayerAbility;
|
||||
import com.minelittlepony.unicopia.network.Channel;
|
||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
@ -112,7 +110,11 @@ class AbilityDelegate implements AbilityReceiver, Updatable, NbtSerialisable {
|
|||
cooldown = ability.getCooldownTime(player);
|
||||
|
||||
if (player.isClientPlayer()) {
|
||||
if (!activateAbility(ability)) {
|
||||
Ability.IData data = ability.tryActivate(player);
|
||||
|
||||
if (data != null) {
|
||||
Channel.PLAYER_ABILITY.send(new MsgPlayerAbility(ability, data));
|
||||
} else {
|
||||
cooldown = 0;
|
||||
}
|
||||
}
|
||||
|
@ -150,18 +152,4 @@ class AbilityDelegate implements AbilityReceiver, Updatable, NbtSerialisable {
|
|||
.ifPresent(p -> activeAbility = p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to activate the current stored ability.
|
||||
* Returns true if the ability suceeded, otherwise false.
|
||||
*/
|
||||
protected boolean activateAbility(@Nonnull Ability<?> ability) {
|
||||
Ability.IData data = ability.tryActivate(player);
|
||||
|
||||
if (data != null) {
|
||||
Unicopia.getConnection().send(new MsgPlayerAbility(player.getOwner(), ability, data), Target.SERVER);
|
||||
}
|
||||
|
||||
return data != null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import com.minelittlepony.unicopia.util.NbtSerialisable;
|
|||
import com.minelittlepony.unicopia.util.MutableVector;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityPose;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
|
@ -41,6 +42,8 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl
|
|||
|
||||
private float gravity = 0;
|
||||
|
||||
private float eyeHeight;
|
||||
|
||||
public GravityDelegate(Pony player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
@ -65,6 +68,10 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl
|
|||
return Math.sqrt(getHorizontalMotion(player.getOwner())) > 0.4F;
|
||||
}
|
||||
|
||||
public float getEyeHeight() {
|
||||
return eyeHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTargetEyeHeight(Pony player) {
|
||||
if (player.hasEffect()) {
|
||||
|
@ -81,7 +88,8 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl
|
|||
return 0.5F;
|
||||
}
|
||||
|
||||
return player.getOwner().getStandingEyeHeight();
|
||||
EntityPose pose = player.getOwner().getPose();
|
||||
return player.getOwner().getActiveEyeHeight(pose, player.getOwner().getDimensions(pose));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -163,7 +171,8 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl
|
|||
}
|
||||
|
||||
float bodyHeight = getTargetBodyHeight(player);
|
||||
float eyeHeight = getTargetEyeHeight(player);
|
||||
eyeHeight = 0;
|
||||
eyeHeight = getTargetEyeHeight(player);
|
||||
|
||||
if (gravity < 0) {
|
||||
eyeHeight = bodyHeight - eyeHeight;
|
||||
|
@ -176,8 +185,6 @@ public class GravityDelegate implements Updatable, FlightControl, NbtSerialisabl
|
|||
|
||||
|
||||
((MixinEntity)entity).setSize(entity.getWidth(), bodyHeight);
|
||||
// TODO: Change eye height
|
||||
//entity.eyeHeight = eyeHeight;
|
||||
|
||||
if (gravity < 0) {
|
||||
if (entity.isSneaking()) {
|
||||
|
|
|
@ -6,6 +6,7 @@ import com.minelittlepony.unicopia.Race;
|
|||
import com.minelittlepony.unicopia.container.HeavyInventory;
|
||||
import com.minelittlepony.unicopia.mixin.Walker;
|
||||
|
||||
import net.minecraft.entity.attribute.ClampedEntityAttribute;
|
||||
import net.minecraft.entity.attribute.EntityAttribute;
|
||||
import net.minecraft.entity.attribute.EntityAttributeInstance;
|
||||
import net.minecraft.entity.attribute.EntityAttributeModifier;
|
||||
|
@ -13,14 +14,16 @@ import net.minecraft.entity.attribute.EntityAttributeModifier.Operation;
|
|||
import net.minecraft.entity.attribute.EntityAttributes;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
||||
public class PlayerAttributes {
|
||||
class PlayerAttributes {
|
||||
|
||||
static final EntityAttribute EXTENDED_REACH_DISTANCE = new ClampedEntityAttribute(null, "player.reachDistance", 0, 0, 10);
|
||||
|
||||
private static final EntityAttributeModifier EARTH_PONY_STRENGTH =
|
||||
new EntityAttributeModifier(UUID.fromString("777a5505-521e-480b-b9d5-6ea54f259564"), "Earth Pony Strength", 0.6, Operation.MULTIPLY_TOTAL);
|
||||
private static final EntityAttributeModifier PEGASUS_SPEED =
|
||||
new EntityAttributeModifier(UUID.fromString("9e2699fc-3b8d-4f71-9d2d-fb92ee19b4f7"), "Pegasus Speed", 0.2, Operation.MULTIPLY_TOTAL);
|
||||
//private static final EntityAttributeModifier PEGASUS_REACH =
|
||||
// new EntityAttributeModifier(UUID.fromString("707b50a8-03e8-40f4-8553-ecf67025fd6d"), "Pegasus Reach", 1.5, Operation.ADDITION);
|
||||
private static final EntityAttributeModifier PEGASUS_REACH =
|
||||
new EntityAttributeModifier(UUID.fromString("707b50a8-03e8-40f4-8553-ecf67025fd6d"), "Pegasus Reach", 1.5, Operation.ADDITION);
|
||||
|
||||
private double loadStrength = 0;
|
||||
|
||||
|
@ -29,14 +32,15 @@ public class PlayerAttributes {
|
|||
|
||||
((Walker)entity.abilities).setWalkSpeed(0.1F - (float)(loadStrength / 100000));
|
||||
|
||||
applyAttribute(entity, EntityAttributes.ATTACK_DAMAGE, EARTH_PONY_STRENGTH, race.canUseEarth());
|
||||
applyAttribute(entity, EntityAttributes.KNOCKBACK_RESISTANCE, EARTH_PONY_STRENGTH, race.canUseEarth());
|
||||
applyAttribute(entity, EntityAttributes.MOVEMENT_SPEED, PEGASUS_SPEED, race.canFly());
|
||||
applyAttribute(entity, EntityAttributes.ATTACK_SPEED, PEGASUS_SPEED, race.canFly());
|
||||
// applyAttribute(entity, PlayerEntity.REACH_DISTANCE, PEGASUS_REACH, race.canFly());
|
||||
toggleAttribute(entity, EntityAttributes.ATTACK_DAMAGE, EARTH_PONY_STRENGTH, race.canUseEarth());
|
||||
toggleAttribute(entity, EntityAttributes.KNOCKBACK_RESISTANCE, EARTH_PONY_STRENGTH, race.canUseEarth());
|
||||
toggleAttribute(entity, EntityAttributes.MOVEMENT_SPEED, PEGASUS_SPEED, race.canFly());
|
||||
toggleAttribute(entity, EntityAttributes.ATTACK_SPEED, PEGASUS_SPEED, race.canFly());
|
||||
toggleAttribute(entity, EXTENDED_REACH_DISTANCE, PEGASUS_REACH, race.canFly());
|
||||
}
|
||||
|
||||
private void applyAttribute(PlayerEntity entity, EntityAttribute attribute, EntityAttributeModifier modifier, boolean enable) {
|
||||
private void toggleAttribute(PlayerEntity entity, EntityAttribute attribute, EntityAttributeModifier modifier, boolean enable) {
|
||||
|
||||
EntityAttributeInstance instance = entity.getAttributeInstance(attribute);
|
||||
|
||||
if (enable) {
|
||||
|
|
|
@ -4,7 +4,6 @@ import javax.annotation.Nullable;
|
|||
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.UTags;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.ability.AbilityReceiver;
|
||||
import com.minelittlepony.unicopia.enchanting.PageOwner;
|
||||
import com.minelittlepony.unicopia.entity.FlightControl;
|
||||
|
@ -16,6 +15,7 @@ import com.minelittlepony.unicopia.magic.HeldMagicEffect;
|
|||
import com.minelittlepony.unicopia.magic.MagicEffect;
|
||||
import com.minelittlepony.unicopia.magic.MagicalItem;
|
||||
import com.minelittlepony.unicopia.magic.spell.SpellRegistry;
|
||||
import com.minelittlepony.unicopia.network.Channel;
|
||||
import com.minelittlepony.unicopia.network.EffectSync;
|
||||
import com.minelittlepony.unicopia.network.MsgPlayerCapabilities;
|
||||
import com.minelittlepony.unicopia.util.BasicEasingInterpolator;
|
||||
|
@ -85,6 +85,8 @@ public class PlayerImpl implements Pony {
|
|||
player.getDataTracker().startTracking(ENERGY, 0F);
|
||||
player.getDataTracker().startTracking(EFFECT, new CompoundTag());
|
||||
player.getDataTracker().startTracking(HELD_EFFECT, new CompoundTag());
|
||||
|
||||
player.getAttributes().register(PlayerAttributes.EXTENDED_REACH_DISTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -169,11 +171,7 @@ public class PlayerImpl implements Pony {
|
|||
dirty = false;
|
||||
|
||||
if (!getWorld().isClient()) {
|
||||
if (full) {
|
||||
Unicopia.getConnection().broadcast(new MsgPlayerCapabilities(this));
|
||||
} else {
|
||||
Unicopia.getConnection().broadcast(new MsgPlayerCapabilities(getSpecies(), getOwner()));
|
||||
}
|
||||
Channel.BROADCAST_CAPABILITIES.send(new MsgPlayerCapabilities(full, this));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,6 +197,11 @@ public class PlayerImpl implements Pony {
|
|||
return gravity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getExtendedReach() {
|
||||
return (float)entity.getAttributeInstance(PlayerAttributes.EXTENDED_REACH_DISTANCE).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlightControl getFlight() {
|
||||
return gravity;
|
||||
|
|
|
@ -70,6 +70,12 @@ public interface Pony extends Caster<PlayerEntity>, RaceContainer<PlayerEntity>,
|
|||
*/
|
||||
void setExertion(float exertion);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
float getExtendedReach();
|
||||
|
||||
/**
|
||||
* Adds player tiredness.
|
||||
*/
|
||||
|
|
|
@ -55,7 +55,7 @@ public class ShieldSpell extends AbstractSpell.RangedAreaSpell implements Attach
|
|||
particlEffect
|
||||
.ifMissing(source, () -> {
|
||||
source.addParticle(UParticles.SPHERE, source.getOriginVector(), Vec3d.ZERO);
|
||||
return null; // TODO: Attachables
|
||||
return null; // XXX: Attachables
|
||||
}) // 1, getTint(), 10
|
||||
.ifPresent(p -> p.setAttribute(0, radius));
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ import com.minelittlepony.unicopia.entity.player.Pony;
|
|||
import com.minelittlepony.unicopia.entity.player.PlayerImpl;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
|
||||
import net.minecraft.entity.EntityDimensions;
|
||||
import net.minecraft.entity.EntityPose;
|
||||
import net.minecraft.entity.ItemEntity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
@ -58,7 +60,17 @@ public abstract class MixinPlayerEntity extends LivingEntity implements PonyCont
|
|||
|
||||
@Inject(method = "setGameMode(Lnet/minecraft/world/GameMode;)V",
|
||||
at = @At("RETURN"))
|
||||
public void setGameMode(GameMode mode, CallbackInfo info) {
|
||||
private void onSetGameMode(GameMode mode, CallbackInfo info) {
|
||||
get().setSpecies(get().getSpecies());
|
||||
}
|
||||
|
||||
@Inject(method = "getActiveEyeHeight(Lnet/minecraft/entity/EntityPose;Lnet/minecraft/entity/EntityDimensions;)F",
|
||||
at = @At("RETURN"),
|
||||
cancellable = true)
|
||||
private void onGetActiveEyeHeight(EntityPose pose, EntityDimensions dimensions, CallbackInfoReturnable<Float> info) {
|
||||
float h = get().getGravity().getEyeHeight();
|
||||
if (h != 0) {
|
||||
info.setReturnValue(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
package com.minelittlepony.unicopia.network;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
|
||||
import net.fabricmc.fabric.api.network.PacketContext;
|
||||
import net.fabricmc.fabric.api.network.ServerSidePacketRegistry;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
|
||||
public interface Channel {
|
||||
|
||||
SPacketType<MsgPlayerAbility> PLAYER_ABILITY = clientToServer(new Identifier("unicopia", "player_ability"), MsgPlayerAbility::new);
|
||||
|
||||
SPacketType<MsgRequestCapabilities> REQUEST_CAPABILITIES = clientToServer(new Identifier("unicopia", "request_capabilities"), MsgRequestCapabilities::new);
|
||||
CPacketType<MsgPlayerCapabilities> PLAYER_CAPABILITIES = serverToClient(new Identifier("unicopia", "player_capabilities"), MsgPlayerCapabilities::new);
|
||||
|
||||
SPacketType<MsgPlayerCapabilities> BROADCAST_CAPABILITIES = broadcast(PLAYER_CAPABILITIES, MsgPlayerCapabilities::new);
|
||||
|
||||
CPacketType<MsgSpawnRainbow> SPAWN_RAINBOW = serverToClient(new Identifier("unicopia", "rainbow_entity"), MsgSpawnRainbow::new);
|
||||
|
||||
static void bootstrap() { }
|
||||
|
||||
static <T extends Packet> SPacketType<T> clientToServer(Identifier id, Function<PacketByteBuf, T> factory) {
|
||||
ServerSidePacketRegistry.INSTANCE.register(id, (context, buffer) -> factory.apply(buffer).handle(context));
|
||||
return () -> id;
|
||||
}
|
||||
|
||||
static <T extends Packet> SPacketType<T> broadcast(CPacketType<T> redirect, Function<PacketByteBuf, T> factory) {
|
||||
Identifier id = new Identifier(redirect.getId().getNamespace(), "broadcast_" + redirect.getId().getPath());
|
||||
ServerSidePacketRegistry.INSTANCE.register(id, (context, buffer) -> {
|
||||
PlayerEntity sender = context.getPlayer();
|
||||
T p = factory.apply(buffer);
|
||||
p.handle(context);
|
||||
sender.world.getPlayers().forEach(player -> {
|
||||
if (player != null && player != sender) {
|
||||
redirect.send(player, p);
|
||||
}
|
||||
});
|
||||
});
|
||||
return () -> id;
|
||||
}
|
||||
|
||||
static <T extends Packet> CPacketType<T> serverToClient(Identifier id, Function<PacketByteBuf, T> factory) {
|
||||
ClientSidePacketRegistry.INSTANCE.register(id, (context, buffer) -> factory.apply(buffer).handle(context));
|
||||
return () -> id;
|
||||
}
|
||||
|
||||
interface CPacketType<T extends Packet> {
|
||||
Identifier getId();
|
||||
|
||||
default void send(PlayerEntity recipient, T packet) {
|
||||
ServerSidePacketRegistry.INSTANCE.sendToPlayer(recipient, getId(), packet.toBuffer());
|
||||
}
|
||||
|
||||
default net.minecraft.network.Packet<?> toPacket(T packet) {
|
||||
return ServerSidePacketRegistry.INSTANCE.toPacket(getId(), packet.toBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
interface SPacketType<T extends Packet> {
|
||||
Identifier getId();
|
||||
|
||||
default void send(T packet) {
|
||||
ClientSidePacketRegistry.INSTANCE.sendToServer(getId(), packet.toBuffer());
|
||||
}
|
||||
|
||||
default net.minecraft.network.Packet<?> toPacket(T packet) {
|
||||
return ClientSidePacketRegistry.INSTANCE.toPacket(getId(), packet.toBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
interface Packet {
|
||||
void handle(PacketContext context);
|
||||
|
||||
void toBuffer(PacketByteBuf buffer);
|
||||
|
||||
default PacketByteBuf toBuffer() {
|
||||
PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer());
|
||||
toBuffer(buf);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,43 +1,36 @@
|
|||
package com.minelittlepony.unicopia.network;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.minelittlepony.jumpingcastle.api.Channel;
|
||||
import com.minelittlepony.jumpingcastle.api.Message;
|
||||
import com.minelittlepony.unicopia.ability.Ability;
|
||||
import com.minelittlepony.unicopia.ability.Abilities;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.fabricmc.fabric.api.network.PacketContext;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
|
||||
public class MsgPlayerAbility implements Message, Message.Handler<MsgPlayerAbility> {
|
||||
public class MsgPlayerAbility implements Channel.Packet {
|
||||
|
||||
private static final Gson gson = new GsonBuilder()
|
||||
.excludeFieldsWithoutExposeAnnotation()
|
||||
.create();
|
||||
|
||||
@Expose
|
||||
private UUID senderId;
|
||||
private final String powerIdentifier;
|
||||
|
||||
@Expose
|
||||
private String powerIdentifier;
|
||||
private final String abilityJson;
|
||||
|
||||
@Expose
|
||||
private String abilityJson;
|
||||
|
||||
public MsgPlayerAbility(PlayerEntity player, Ability<?> power, Ability.IData data) {
|
||||
senderId = player.getUuid();
|
||||
public MsgPlayerAbility(Ability<?> power, Ability.IData data) {
|
||||
powerIdentifier = power.getKeyName();
|
||||
abilityJson = gson.toJson(data, power.getPackageType());
|
||||
}
|
||||
|
||||
private <T extends Ability.IData> void apply(Ability<T> power, Channel channel) {
|
||||
MinecraftServer server = channel.getServer();
|
||||
Pony player = Pony.of(server.getPlayerManager().getPlayer(senderId));
|
||||
public MsgPlayerAbility(PacketByteBuf buffer) {
|
||||
powerIdentifier = buffer.readString();
|
||||
abilityJson = buffer.readString();
|
||||
}
|
||||
|
||||
private <T extends Ability.IData> void apply(Ability<T> power, PacketContext context) {
|
||||
Pony player = Pony.of(context.getPlayer());
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -48,7 +41,13 @@ public class MsgPlayerAbility implements Message, Message.Handler<MsgPlayerAbili
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onPayload(MsgPlayerAbility message, Channel channel) {
|
||||
Abilities.getInstance().getPowerFromName(powerIdentifier).ifPresent(power -> apply(power, channel));
|
||||
public void toBuffer(PacketByteBuf buffer) {
|
||||
buffer.writeString(powerIdentifier);
|
||||
buffer.writeString(abilityJson);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PacketContext context) {
|
||||
Abilities.getInstance().getPowerFromName(powerIdentifier).ifPresent(power -> apply(power, context));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,77 +1,60 @@
|
|||
package com.minelittlepony.unicopia.network;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.minelittlepony.jumpingcastle.api.Channel;
|
||||
import com.minelittlepony.jumpingcastle.api.Message;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
import io.netty.buffer.ByteBufInputStream;
|
||||
import io.netty.buffer.ByteBufOutputStream;
|
||||
import net.fabricmc.fabric.api.network.PacketContext;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
|
||||
public class MsgPlayerCapabilities implements Message, Message.Handler<MsgPlayerCapabilities> {
|
||||
@Expose
|
||||
Race newRace;
|
||||
public class MsgPlayerCapabilities implements Channel.Packet {
|
||||
|
||||
@Expose
|
||||
UUID senderId;
|
||||
private final Race newRace;
|
||||
|
||||
@Expose
|
||||
byte[] compoundTag;
|
||||
private final CompoundTag compoundTag;
|
||||
|
||||
public MsgPlayerCapabilities(PacketByteBuf buffer) {
|
||||
newRace = Race.values()[buffer.readInt()];
|
||||
try (InputStream in = new ByteBufInputStream(buffer)) {
|
||||
compoundTag = NbtIo.readCompressed(in);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public MsgPlayerCapabilities(Race race, PlayerEntity player) {
|
||||
newRace = race;
|
||||
senderId = player.getUuid();
|
||||
compoundTag = new byte[0];
|
||||
compoundTag = new CompoundTag();
|
||||
}
|
||||
|
||||
public MsgPlayerCapabilities(Pony player) {
|
||||
public MsgPlayerCapabilities(boolean full, Pony player) {
|
||||
newRace = player.getSpecies();
|
||||
senderId = player.getOwner().getUuid();
|
||||
compoundTag = full ? player.toNBT() : new CompoundTag();
|
||||
}
|
||||
|
||||
try (ByteArrayOutputStream bytes = new ByteArrayOutputStream()) {
|
||||
CompoundTag nbt = player.toNBT();
|
||||
|
||||
NbtIo.write(nbt, new DataOutputStream(bytes));
|
||||
|
||||
compoundTag = bytes.toByteArray();
|
||||
@Override
|
||||
public void toBuffer(PacketByteBuf buffer) {
|
||||
buffer.writeInt(newRace.ordinal());
|
||||
try (OutputStream out = new ByteBufOutputStream(buffer)) {
|
||||
NbtIo.writeCompressed(compoundTag, out);
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPayload(MsgPlayerCapabilities message, Channel channel) {
|
||||
|
||||
MinecraftServer server = channel.getServer();
|
||||
|
||||
PlayerEntity self = server.getPlayerManager().getPlayer(senderId);
|
||||
|
||||
if (self == null) {
|
||||
Unicopia.LOGGER.warn("[Unicopia] [CLIENT] [MsgPlayerCapabilities] Player with id %s was not found!\n", senderId.toString());
|
||||
public void handle(PacketContext context) {
|
||||
Pony player = Pony.of(context.getPlayer());
|
||||
if (compoundTag.isEmpty()) {
|
||||
player.setSpecies(newRace);
|
||||
} else {
|
||||
Pony player = Pony.of(self);
|
||||
|
||||
if (compoundTag.length > 0) {
|
||||
try (ByteArrayInputStream input = new ByteArrayInputStream(compoundTag)) {
|
||||
CompoundTag nbt = NbtIo.read(new DataInputStream(input));
|
||||
|
||||
player.fromNBT(nbt);
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
} else {
|
||||
player.setSpecies(newRace);
|
||||
}
|
||||
player.fromNBT(compoundTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,40 +1,38 @@
|
|||
package com.minelittlepony.unicopia.network;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.minelittlepony.jumpingcastle.api.Channel;
|
||||
import com.minelittlepony.jumpingcastle.api.Message;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
import net.fabricmc.fabric.api.network.PacketContext;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
|
||||
public class MsgRequestCapabilities implements Message, Message.Handler<MsgRequestCapabilities> {
|
||||
@Expose
|
||||
public UUID senderId;
|
||||
public class MsgRequestCapabilities implements Channel.Packet {
|
||||
|
||||
@Expose
|
||||
public Race race;
|
||||
private final Race race;
|
||||
|
||||
public MsgRequestCapabilities(PacketByteBuf buffer) {
|
||||
race = Race.values()[buffer.readInt()];
|
||||
}
|
||||
|
||||
public MsgRequestCapabilities(PlayerEntity player, Race preferredRace) {
|
||||
senderId = player.getGameProfile().getId();
|
||||
race = preferredRace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPayload(MsgRequestCapabilities message, Channel channel) {
|
||||
MinecraftServer server = channel.getServer();
|
||||
public void toBuffer(PacketByteBuf buffer) {
|
||||
buffer.writeInt(race.ordinal());
|
||||
}
|
||||
|
||||
Unicopia.LOGGER.warn("[Unicopia] [SERVER] [MsgRequestCapabilities] Sending capabilities to player %s\n", senderId.toString());
|
||||
Pony player = Pony.of(server.getPlayerManager().getPlayer(senderId));
|
||||
@Override
|
||||
public void handle(PacketContext context) {
|
||||
Pony player = Pony.of(context.getPlayer());
|
||||
|
||||
if (player.getSpecies().isDefault()) {
|
||||
player.setSpecies(message.race);
|
||||
player.setSpecies(race);
|
||||
}
|
||||
|
||||
channel.respond(new MsgPlayerCapabilities(player), senderId);
|
||||
Channel.PLAYER_CAPABILITIES.send(context.getPlayer(), new MsgPlayerCapabilities(true, player));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package com.minelittlepony.unicopia.network;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.RainbowEntity;
|
||||
import com.minelittlepony.unicopia.entity.UEntities;
|
||||
import net.fabricmc.fabric.api.network.PacketContext;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.PacketByteBuf;
|
||||
|
||||
public class MsgSpawnRainbow implements Channel.Packet {
|
||||
|
||||
private final int id;
|
||||
|
||||
private final double x;
|
||||
private final double y;
|
||||
private final double z;
|
||||
|
||||
public MsgSpawnRainbow(Entity entity) {
|
||||
id = entity.getEntityId();
|
||||
x = entity.getX();
|
||||
y = entity.getY();
|
||||
z = entity.getZ();
|
||||
}
|
||||
|
||||
public MsgSpawnRainbow(PacketByteBuf buffer) {
|
||||
id = buffer.readVarInt();
|
||||
x = buffer.readDouble();
|
||||
y = buffer.readDouble();
|
||||
z = buffer.readDouble();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBuffer(PacketByteBuf buffer) {
|
||||
buffer.writeVarInt(id);
|
||||
buffer.writeDouble(x);
|
||||
buffer.writeDouble(y);
|
||||
buffer.writeDouble(z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PacketContext context) {
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
|
||||
RainbowEntity entity = UEntities.RAINBOW.create(client.world);
|
||||
entity.setPos(x, y, z);
|
||||
entity.updateTrackedPosition(x, y, z);
|
||||
entity.yaw = 0;
|
||||
entity.pitch = 0;
|
||||
entity.setEntityId(id);
|
||||
client.world.addEntity(id, entity);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue