mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-01 19:46:42 +01:00
Store the default race with the world and properly sync with the client upon joining
This commit is contained in:
parent
77f0915d82
commit
2fd270131f
13 changed files with 170 additions and 69 deletions
|
@ -18,18 +18,21 @@ public class InteractionManager {
|
|||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true on the client if the passed in player entity is the client's player.
|
||||
* Always returns false on the server.
|
||||
*/
|
||||
public boolean isClientPlayer(@Nullable PlayerEntity player) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The player's camera mode. Always 0 on the server.
|
||||
*/
|
||||
public int getViewMode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Race getPreferredRace() {
|
||||
return Unicopia.getConfig().getPrefferedRace();
|
||||
}
|
||||
|
||||
/**
|
||||
* Side-independent method to create a new player.
|
||||
*
|
||||
|
|
|
@ -7,9 +7,12 @@ import java.util.function.Function;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.minelittlepony.common.client.gui.sprite.TextureSprite;
|
||||
import com.minelittlepony.common.client.gui.style.Style;
|
||||
import com.minelittlepony.unicopia.ability.magic.Affine;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public enum Race implements Affine {
|
||||
/**
|
||||
|
@ -101,6 +104,16 @@ public enum Race implements Affine {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Style getStyle() {
|
||||
return new Style()
|
||||
.setIcon(new TextureSprite()
|
||||
.setPosition(2, 2)
|
||||
.setSize(16, 16)
|
||||
.setTexture(new Identifier("unicopia", "textures/gui/icons.png"))
|
||||
.setTextureOffset((16 * ordinal()) % 256, (ordinal() / 256) * 16)
|
||||
)
|
||||
.setTooltip(getTranslationKey(), 0, 10);
|
||||
}
|
||||
|
||||
public boolean equals(String s) {
|
||||
return name().equalsIgnoreCase(s)
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package com.minelittlepony.unicopia;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.world.PersistentState;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
|
||||
public class WorldTribeManager extends PersistentState {
|
||||
|
||||
private Race defaultRace = Unicopia.getConfig().getPrefferedRace();
|
||||
|
||||
public WorldTribeManager(ServerWorld world) {
|
||||
super("unicopia:tribes" + world.getDimension().getSuffix());
|
||||
}
|
||||
|
||||
public Race getDefaultRace() {
|
||||
return defaultRace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromTag(CompoundTag tag) {
|
||||
defaultRace = Race.fromName(tag.getString("defaultRace"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
tag.putString("defaultRace", defaultRace.name());
|
||||
return tag;
|
||||
}
|
||||
|
||||
public static String nameFor(DimensionType dimension) {
|
||||
return "unicopia:tribes" + dimension.getSuffix();
|
||||
}
|
||||
|
||||
public static WorldTribeManager forWorld(ServerWorld world) {
|
||||
return world.getPersistentStateManager().getOrCreate(() -> new WorldTribeManager(world), nameFor(world.getDimension()));
|
||||
}
|
||||
}
|
|
@ -164,7 +164,7 @@ public class AbilityDispatcher implements Tickable, NbtSerialisable {
|
|||
T data = ability.tryActivate(player);
|
||||
|
||||
if (data != null) {
|
||||
Channel.PLAYER_ABILITY.send(new MsgPlayerAbility<>(ability, data));
|
||||
Channel.CLIENT_PLAYER_ABILITY.send(new MsgPlayerAbility<>(ability, data));
|
||||
} else {
|
||||
setCooldown(0);
|
||||
}
|
||||
|
|
|
@ -4,8 +4,6 @@ import javax.annotation.Nonnull;
|
|||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.InteractionManager;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.entity.player.dummy.DummyClientPlayerEntity;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
@ -16,7 +14,6 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
||||
public class ClientInteractionManager extends InteractionManager {
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public PlayerEntity createPlayer(Entity observer, GameProfile profile) {
|
||||
|
@ -28,29 +25,9 @@ public class ClientInteractionManager extends InteractionManager {
|
|||
|
||||
@Override
|
||||
public boolean isClientPlayer(@Nullable PlayerEntity player) {
|
||||
if (MinecraftClient.getInstance().player == player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (MinecraftClient.getInstance().player == null || player == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Pony.equal(MinecraftClient.getInstance().player, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Race getPreferredRace() {
|
||||
if (!Unicopia.getConfig().ignoresMineLittlePony()
|
||||
&& MinecraftClient.getInstance().player != null) {
|
||||
Race race = MineLPConnector.getPlayerPonyRace();
|
||||
|
||||
if (!race.isDefault()) {
|
||||
return race;
|
||||
}
|
||||
}
|
||||
|
||||
return Unicopia.getConfig().getPrefferedRace();
|
||||
return (MinecraftClient.getInstance().player != null && player != null)
|
||||
&& (MinecraftClient.getInstance().player == player
|
||||
|| Pony.equal(MinecraftClient.getInstance().player, player));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -24,13 +24,14 @@ public final class MineLPConnector {
|
|||
case GRYPHON:
|
||||
case HIPPOGRIFF:
|
||||
case PEGASUS:
|
||||
case BATPONY:
|
||||
return Race.PEGASUS;
|
||||
case BATPONY:
|
||||
return Race.BAT;
|
||||
case SEAPONY:
|
||||
case UNICORN:
|
||||
return Race.UNICORN;
|
||||
default:
|
||||
return Race.EARTH;
|
||||
return Race.HUMAN;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,38 +1,70 @@
|
|||
package com.minelittlepony.unicopia.client;
|
||||
|
||||
import com.minelittlepony.common.client.gui.element.Cycler;
|
||||
import com.minelittlepony.common.event.ScreenInitCallback;
|
||||
import com.minelittlepony.common.event.ScreenInitCallback.ButtonList;
|
||||
import com.minelittlepony.unicopia.InteractionManager;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.network.Channel;
|
||||
import com.minelittlepony.unicopia.network.MsgRequestCapabilities;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.world.CreateWorldScreen;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class UnicopiaClient implements ClientModInitializer {
|
||||
|
||||
private Race lastPreferredRace = InteractionManager.instance().getPreferredRace();
|
||||
public static Race getPreferredRace() {
|
||||
if (!Unicopia.getConfig().ignoresMineLittlePony()
|
||||
&& MinecraftClient.getInstance().player != null) {
|
||||
Race race = MineLPConnector.getPlayerPonyRace();
|
||||
|
||||
if (!race.isDefault()) {
|
||||
return race;
|
||||
}
|
||||
}
|
||||
|
||||
return Unicopia.getConfig().getPrefferedRace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
lastPreferredRace = InteractionManager.instance().getPreferredRace();
|
||||
InteractionManager.INSTANCE = new ClientInteractionManager();
|
||||
|
||||
URenderers.bootstrap();
|
||||
|
||||
ClientTickEvents.END_CLIENT_TICK.register(client -> {
|
||||
PlayerEntity player = client.player;
|
||||
ClientTickEvents.END_CLIENT_TICK.register(this::onTick);
|
||||
ScreenInitCallback.EVENT.register(this::onScreenInit);
|
||||
}
|
||||
|
||||
if (player != null && !player.removed) {
|
||||
Race newRace = InteractionManager.instance().getPreferredRace();
|
||||
private void onTick(MinecraftClient client) {
|
||||
KeyBindingsHandler.INSTANCE.tick(client);
|
||||
}
|
||||
|
||||
if (newRace != lastPreferredRace) {
|
||||
lastPreferredRace = newRace;
|
||||
|
||||
Channel.REQUEST_CAPABILITIES.send(new MsgRequestCapabilities(lastPreferredRace));
|
||||
private void onScreenInit(Screen screen, ButtonList buttons) {
|
||||
if (screen instanceof CreateWorldScreen) {
|
||||
buttons.add(new Cycler(screen.width / 2 + 110, 60, 20, 20) {
|
||||
@Override
|
||||
protected void renderForground(MatrixStack matrices, MinecraftClient mc, int mouseX, int mouseY, int foreColor) {
|
||||
super.renderForground(matrices, mc, mouseX, mouseY, foreColor);
|
||||
if (isMouseOver(mouseX, mouseY)) {
|
||||
renderToolTip(matrices, screen, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}).setStyles(
|
||||
Race.EARTH.getStyle(),
|
||||
Race.UNICORN.getStyle(),
|
||||
Race.PEGASUS.getStyle(),
|
||||
Race.BAT.getStyle(),
|
||||
Race.ALICORN.getStyle(),
|
||||
Race.CHANGELING.getStyle()
|
||||
).onChange(i -> {
|
||||
Unicopia.getConfig().setPreferredRace(Race.fromId(i + 1));
|
||||
|
||||
KeyBindingsHandler.INSTANCE.tick(client);
|
||||
});
|
||||
return i;
|
||||
}).setValue(MathHelper.clamp(Unicopia.getConfig().getPrefferedRace().ordinal() - 1, 0, 5));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,10 @@ import java.util.Optional;
|
|||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.Affinity;
|
||||
import com.minelittlepony.unicopia.client.UnicopiaClient;
|
||||
import com.minelittlepony.unicopia.InteractionManager;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.WorldTribeManager;
|
||||
import com.minelittlepony.unicopia.ability.AbilityDispatcher;
|
||||
import com.minelittlepony.unicopia.ability.magic.AttachableSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
|
@ -21,11 +23,13 @@ import com.minelittlepony.unicopia.item.toxin.Toxin;
|
|||
import com.minelittlepony.unicopia.network.Channel;
|
||||
import com.minelittlepony.unicopia.network.EffectSync;
|
||||
import com.minelittlepony.unicopia.network.MsgPlayerCapabilities;
|
||||
import com.minelittlepony.unicopia.network.MsgRequestCapabilities;
|
||||
import com.minelittlepony.unicopia.network.Transmittable;
|
||||
import com.minelittlepony.unicopia.util.Copieable;
|
||||
import com.minelittlepony.common.util.animation.LinearInterpolator;
|
||||
import com.minelittlepony.common.util.animation.Interpolator;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.attribute.DefaultAttributeContainer;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
|
@ -38,6 +42,7 @@ import net.minecraft.item.ItemStack;
|
|||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.packet.s2c.play.EntityPassengersSetS2CPacket;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -65,7 +70,12 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
|
|||
|
||||
private final PlayerEntity entity;
|
||||
|
||||
private boolean dirty = false;
|
||||
private boolean dirty;
|
||||
private boolean speciesSet;
|
||||
private boolean speciesPersisted;
|
||||
|
||||
@Nullable
|
||||
private Race clientPreferredRace;
|
||||
|
||||
private boolean invisible = false;
|
||||
|
||||
|
@ -73,7 +83,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
|
|||
this.entity = player;
|
||||
this.mana = new ManaContainer(this);
|
||||
|
||||
player.getDataTracker().startTracking(RACE, Race.EARTH.ordinal());
|
||||
player.getDataTracker().startTracking(RACE, Race.HUMAN.ordinal());
|
||||
player.getDataTracker().startTracking(EFFECT, new CompoundTag());
|
||||
player.getDataTracker().startTracking(HELD_EFFECT, new CompoundTag());
|
||||
}
|
||||
|
@ -94,6 +104,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
|
|||
@Override
|
||||
public void setSpecies(Race race) {
|
||||
race = race.validate(entity);
|
||||
speciesSet = true;
|
||||
|
||||
entity.getDataTracker().set(RACE, race.ordinal());
|
||||
|
||||
|
@ -110,6 +121,10 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
|
|||
return invisible && hasSpell();
|
||||
}
|
||||
|
||||
public boolean isSpeciesPersisted() {
|
||||
return speciesPersisted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInvisible(boolean invisible) {
|
||||
this.invisible = invisible;
|
||||
|
@ -129,7 +144,6 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
|
|||
dirty = false;
|
||||
|
||||
if (entity instanceof ServerPlayerEntity) {
|
||||
System.out.println("Sending capabilities for player");
|
||||
Channel.BROADCAST_CAPABILITIES.send(new MsgPlayerCapabilities(full, this));
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +175,25 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
|
|||
|
||||
@Override
|
||||
public boolean beforeUpdate() {
|
||||
if (entity.world.isClient()) {
|
||||
|
||||
if (!speciesSet && getWorld() instanceof ServerWorld) {
|
||||
setSpecies(WorldTribeManager.forWorld((ServerWorld)getWorld()).getDefaultRace());
|
||||
setDirty();
|
||||
}
|
||||
|
||||
if (isClientPlayer() && !speciesSet) {
|
||||
Race race = UnicopiaClient.getPreferredRace();
|
||||
|
||||
if (race != clientPreferredRace) {
|
||||
clientPreferredRace = race;
|
||||
|
||||
if (race != getSpecies()) {
|
||||
Channel.CLIENT_REQUEST_CAPABILITIES.send(new MsgRequestCapabilities(race));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isClient()) {
|
||||
if (entity.hasVehicle() && entity.isSneaking()) {
|
||||
|
||||
Entity ridee = entity.getVehicle();
|
||||
|
@ -300,6 +332,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
|
|||
|
||||
@Override
|
||||
public void fromNBT(CompoundTag compound) {
|
||||
speciesPersisted = true;
|
||||
setSpecies(Race.fromName(compound.getString("playerSpecies")));
|
||||
|
||||
powers.fromNBT(compound.getCompound("powers"));
|
||||
|
@ -312,6 +345,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
|
|||
|
||||
@Override
|
||||
public void copyFrom(Pony oldPlayer) {
|
||||
speciesPersisted = oldPlayer.speciesPersisted;
|
||||
setSpell(oldPlayer.getSpell());
|
||||
setSpecies(oldPlayer.getSpecies());
|
||||
setDirty();
|
||||
|
|
|
@ -12,14 +12,15 @@ import net.minecraft.network.PacketByteBuf;
|
|||
|
||||
public interface Channel {
|
||||
|
||||
SPacketType<MsgPlayerAbility<?>> PLAYER_ABILITY = clientToServer(new Identifier("unicopia", "player_ability"), MsgPlayerAbility::new);
|
||||
SPacketType<MsgPlayerAbility<?>> CLIENT_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<MsgRequestCapabilities> CLIENT_REQUEST_CAPABILITIES = clientToServer(new Identifier("unicopia", "request_capabilities"), MsgRequestCapabilities::new);
|
||||
|
||||
SPacketType<MsgPlayerCapabilities> BROADCAST_CAPABILITIES = broadcast(PLAYER_CAPABILITIES, MsgPlayerCapabilities::new);
|
||||
CPacketType<MsgPlayerCapabilities> SERVER_PLAYER_CAPABILITIES = serverToClient(new Identifier("unicopia", "player_capabilities"), MsgPlayerCapabilities::new);
|
||||
|
||||
CPacketType<MsgSpawnProjectile> SPAWN_PROJECTILE = serverToClient(new Identifier("unicopia", "projectile_entity"), MsgSpawnProjectile::new);
|
||||
SPacketType<MsgPlayerCapabilities> BROADCAST_CAPABILITIES = broadcast(SERVER_PLAYER_CAPABILITIES, MsgPlayerCapabilities::new);
|
||||
|
||||
CPacketType<MsgSpawnProjectile> SERVER_SPAWN_PROJECTILE = serverToClient(new Identifier("unicopia", "projectile_entity"), MsgSpawnProjectile::new);
|
||||
|
||||
static void bootstrap() { }
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@ public class MsgPlayerCapabilities implements Channel.Packet {
|
|||
|
||||
@Override
|
||||
public void handle(PacketContext context) {
|
||||
System.out.println("Got capabilities for player " + newRace + " " + context.getPacketEnvironment());
|
||||
Pony player = Pony.of(context.getPlayer());
|
||||
if (compoundTag.isEmpty()) {
|
||||
player.setSpecies(newRace);
|
||||
|
|
|
@ -1,37 +1,40 @@
|
|||
package com.minelittlepony.unicopia.network;
|
||||
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.WorldTribeManager;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
import net.fabricmc.fabric.api.network.PacketContext;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
|
||||
public class MsgRequestCapabilities implements Channel.Packet {
|
||||
|
||||
private final Race race;
|
||||
private final Race clientPreferredRace;
|
||||
|
||||
MsgRequestCapabilities(PacketByteBuf buffer) {
|
||||
race = Race.values()[buffer.readInt()];
|
||||
clientPreferredRace = Race.values()[buffer.readInt()];
|
||||
}
|
||||
|
||||
public MsgRequestCapabilities(Race preferredRace) {
|
||||
race = preferredRace;
|
||||
clientPreferredRace = preferredRace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBuffer(PacketByteBuf buffer) {
|
||||
buffer.writeInt(race.ordinal());
|
||||
buffer.writeInt(clientPreferredRace.ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PacketContext context) {
|
||||
System.out.println("Requesting player capabilities " + context.getPacketEnvironment());
|
||||
Pony player = Pony.of(context.getPlayer());
|
||||
|
||||
if (player.getSpecies().isDefault()) {
|
||||
player.setSpecies(race);
|
||||
Race worldDefaultRace = WorldTribeManager.forWorld((ServerWorld)player.getWorld()).getDefaultRace();
|
||||
|
||||
if (player.getSpecies().isDefault() || (player.getSpecies() == worldDefaultRace && !player.isSpeciesPersisted())) {
|
||||
player.setSpecies(clientPreferredRace.isPermitted(context.getPlayer()) ? clientPreferredRace : worldDefaultRace);
|
||||
}
|
||||
|
||||
Channel.PLAYER_CAPABILITIES.send(context.getPlayer(), new MsgPlayerCapabilities(true, player));
|
||||
Channel.SERVER_PLAYER_CAPABILITIES.send(context.getPlayer(), new MsgPlayerCapabilities(true, player));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -293,6 +293,6 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
|
|||
|
||||
@Override
|
||||
public Packet<?> createSpawnPacket() {
|
||||
return Channel.SPAWN_PROJECTILE.toPacket(new MsgSpawnProjectile(this));
|
||||
return Channel.SERVER_SPAWN_PROJECTILE.toPacket(new MsgSpawnProjectile(this));
|
||||
}
|
||||
}
|
||||
|
|
BIN
src/main/resources/assets/unicopia/textures/gui/icons.png
Normal file
BIN
src/main/resources/assets/unicopia/textures/gui/icons.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
Loading…
Reference in a new issue