The player's camera now rolls as a pegasus flies

This commit is contained in:
Sollace 2018-09-27 22:12:32 +02:00
parent 1c13c1a867
commit 42f8a3c29b
9 changed files with 154 additions and 44 deletions

View file

@ -3,6 +3,7 @@ package com.minelittlepony.unicopia;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockCrops; import net.minecraft.block.BlockCrops;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.item.EnumAction; import net.minecraft.item.EnumAction;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@ -10,6 +11,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.SoundEvent; import net.minecraft.util.SoundEvent;
import net.minecraftforge.client.event.ColorHandlerEvent; import net.minecraftforge.client.event.ColorHandlerEvent;
import net.minecraftforge.client.event.EntityViewRenderEvent;
import net.minecraftforge.client.event.FOVUpdateEvent; import net.minecraftforge.client.event.FOVUpdateEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType;
@ -153,6 +155,17 @@ public class Unicopia {
} }
} }
@SideOnly(Side.CLIENT)
@SubscribeEvent
public static void setupPlayerCamera(EntityViewRenderEvent.CameraSetup event) {
EntityPlayer player = Minecraft.getMinecraft().player;
if (player != null) {
event.setRoll((float)PlayerSpeciesList.instance().getPlayer(player).getCamera().calculateRoll(player));
}
}
@SubscribeEvent @SubscribeEvent
public static void onBlockHarvested(BlockEvent.HarvestDropsEvent event) { public static void onBlockHarvested(BlockEvent.HarvestDropsEvent event) {
Block block = event.getState().getBlock(); Block block = event.getState().getBlock();

View file

@ -0,0 +1,52 @@
package com.minelittlepony.unicopia.advancements;
import java.util.List;
import java.util.Map;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import net.minecraft.advancements.ICriterionTrigger;
import net.minecraft.advancements.PlayerAdvancements;
import net.minecraft.advancements.critereon.AbstractCriterionInstance;
public abstract class AbstractTrigger<E extends AbstractTrigger.Entry<T>, T extends AbstractCriterionInstance> implements ICriterionTrigger<T> {
protected final Map<PlayerAdvancements, E> listeners = Maps.newHashMap();
@Override
public void addListener(PlayerAdvancements key, Listener<T> listener) {
listeners.computeIfAbsent(key, this::createEntry).listeners.add(listener);;
}
@Override
public void removeListener(PlayerAdvancements key, Listener<T> listener) {
if (listeners.containsKey(key)) {
E entry = listeners.get(key);
entry.listeners.remove(listener);
if (entry.listeners.isEmpty()) {
listeners.remove(key);
}
}
}
@Override
public void removeAllListeners(PlayerAdvancements key) {
if (listeners.containsKey(key)) {
listeners.remove(key);
}
}
protected abstract E createEntry(PlayerAdvancements advancement);
protected static class Entry<T extends AbstractCriterionInstance> {
protected final PlayerAdvancements advancement;
protected final List<Listener<T>> listeners = Lists.newArrayList();
Entry(PlayerAdvancements key) {
advancement = key;
}
}
}

View file

@ -1,15 +1,10 @@
package com.minelittlepony.unicopia.advancements; package com.minelittlepony.unicopia.advancements;
import java.util.List;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import net.minecraft.advancements.ICriterionTrigger;
import net.minecraft.advancements.PlayerAdvancements; import net.minecraft.advancements.PlayerAdvancements;
import net.minecraft.advancements.critereon.AbstractCriterionInstance; import net.minecraft.advancements.critereon.AbstractCriterionInstance;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
@ -19,46 +14,25 @@ import net.minecraft.world.WorldServer;
/** /**
* Advantement trigger for the book of holding. It's an achievement to die so spectacularly! :D * Advantement trigger for the book of holding. It's an achievement to die so spectacularly! :D
*/ */
public class BOHDeathTrigger implements ICriterionTrigger<BOHDeathTrigger.Instance> { public class BOHDeathTrigger extends AbstractTrigger<BOHDeathTrigger.Entry, BOHDeathTrigger.Instance> {
private static final ResourceLocation ID = new ResourceLocation("unicopia", "death_by_bag_of_holding"); private static final ResourceLocation ID = new ResourceLocation("unicopia", "death_by_bag_of_holding");
private final Map<PlayerAdvancements, Entry> listeners = Maps.newHashMap();
@Override @Override
public ResourceLocation getId() { public ResourceLocation getId() {
return ID; return ID;
} }
@Override
public void addListener(PlayerAdvancements key, Listener<Instance> listener) {
listeners.computeIfAbsent(key, Entry::new).listeners.add(listener);;
}
@Override
public void removeListener(PlayerAdvancements key, Listener<Instance> listener) {
if (listeners.containsKey(key)) {
Entry entry = listeners.get(key);
entry.listeners.remove(listener);
if (entry.listeners.isEmpty()) {
listeners.remove(key);
}
}
}
@Override
public void removeAllListeners(PlayerAdvancements key) {
if (listeners.containsKey(key)) {
listeners.remove(key);
}
}
@Override @Override
public Instance deserializeInstance(JsonObject json, JsonDeserializationContext context) { public Instance deserializeInstance(JsonObject json, JsonDeserializationContext context) {
return new Instance(AdvancementPredicate.deserialize(json.get("advancement"))); return new Instance(AdvancementPredicate.deserialize(json.get("advancement")));
} }
@Override
protected Entry createEntry(PlayerAdvancements advancement) {
return new Entry(advancement);
}
public void trigger(EntityPlayerMP player) { public void trigger(EntityPlayerMP player) {
PlayerAdvancements key = player.getAdvancements(); PlayerAdvancements key = player.getAdvancements();
@ -69,12 +43,12 @@ public class BOHDeathTrigger implements ICriterionTrigger<BOHDeathTrigger.Instan
static class Instance extends AbstractCriterionInstance { static class Instance extends AbstractCriterionInstance {
AdvancementPredicate requirement; private final AdvancementPredicate requirement;
public Instance(AdvancementPredicate requirement) { public Instance(AdvancementPredicate key) {
super(ID); super(ID);
this.requirement = requirement; requirement = key;
} }
public boolean test(WorldServer world, PlayerAdvancements playerAdvancements) { public boolean test(WorldServer world, PlayerAdvancements playerAdvancements) {
@ -83,13 +57,10 @@ public class BOHDeathTrigger implements ICriterionTrigger<BOHDeathTrigger.Instan
} }
class Entry { static class Entry extends AbstractTrigger.Entry<BOHDeathTrigger.Instance> {
private final PlayerAdvancements advancement;
private final List<Listener<Instance>> listeners = Lists.newArrayList();
Entry(PlayerAdvancements key) { Entry(PlayerAdvancements key) {
advancement = key; super(key);
} }
public void trigger(WorldServer world, PlayerAdvancements playerAdvancements) { public void trigger(WorldServer world, PlayerAdvancements playerAdvancements) {
@ -98,4 +69,5 @@ public class BOHDeathTrigger implements ICriterionTrigger<BOHDeathTrigger.Instan
.forEach(winner -> winner.grantCriterion(advancement));; .forEach(winner -> winner.grantCriterion(advancement));;
} }
} }
} }

View file

@ -30,7 +30,9 @@ public class MsgRequestCapabilities implements IMessage, IMessageHandler<MsgRequ
System.out.println("[SERVER] Sending capabilities to player id " + senderId); System.out.println("[SERVER] Sending capabilities to player id " + senderId);
IPlayer player = PlayerSpeciesList.instance().getPlayer(senderId); IPlayer player = PlayerSpeciesList.instance().getPlayer(senderId);
player.setPlayerSpecies(message.race); if (player.getPlayerSpecies().isDefault()) {
player.setPlayerSpecies(message.race);
}
channel.respond(new MsgPlayerCapabilities(player), senderId); channel.respond(new MsgPlayerCapabilities(player), senderId);
} }

View file

@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.player;
import java.util.UUID; import java.util.UUID;
import com.minelittlepony.model.anim.IInterpolator;
import com.minelittlepony.unicopia.spell.ICaster; import com.minelittlepony.unicopia.spell.ICaster;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@ -17,6 +18,10 @@ public interface IPlayer extends ICaster<EntityPlayer>, IRaceContainer<EntityPla
IGravity getGravity(); IGravity getGravity();
IView getCamera();
IInterpolator getInterpolator();
float getExertion(); float getExertion();
void setExertion(float exertion); void setExertion(float exertion);

View file

@ -0,0 +1,11 @@
package com.minelittlepony.unicopia.player;
import net.minecraft.entity.player.EntityPlayer;
public interface IView {
double calculateRoll(EntityPlayer player);
double getBaseRoll();
void setBaseRoll(double roll);
}

View file

@ -1,5 +1,7 @@
package com.minelittlepony.unicopia.player; package com.minelittlepony.unicopia.player;
import com.minelittlepony.model.anim.BasicEasingInterpolator;
import com.minelittlepony.model.anim.IInterpolator;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.UClient; import com.minelittlepony.unicopia.UClient;
import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.Unicopia;
@ -39,8 +41,12 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
private final PlayerAttributes attributes = new PlayerAttributes(); private final PlayerAttributes attributes = new PlayerAttributes();
private final PlayerView view = new PlayerView(this);
private final EffectSync<EntityPlayer> effectDelegate = new EffectSync<>(this, EFFECT); private final EffectSync<EntityPlayer> effectDelegate = new EffectSync<>(this, EFFECT);
private final IInterpolator interpolator = new BasicEasingInterpolator();
private float nextStepDistance = 1; private float nextStepDistance = 1;
private EntityPlayer entity; private EntityPlayer entity;
@ -112,6 +118,16 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
return gravity; return gravity;
} }
@Override
public IView getCamera() {
return view;
}
@Override
public IInterpolator getInterpolator() {
return interpolator;
}
@Override @Override
public boolean isClientPlayer() { public boolean isClientPlayer() {
return UClient.isClientSide() && return UClient.isClientSide() &&

View file

@ -48,10 +48,11 @@ class PlayerGravityDelegate implements IUpdatable<EntityPlayer>, IGravity, InbtS
boolean rainboom = Math.sqrt(getHorizontalMotion(entity)) > 0.4F; boolean rainboom = Math.sqrt(getHorizontalMotion(entity)) > 0.4F;
if (isFlying && rainboom) { if (isFlying && rainboom) {
MixinEntity.setSize(entity, entity.width, 0.5F); MixinEntity.setSize(entity, entity.width, player.getInterpolator().interpolate("standingHeight", 0.5F, 10));
entity.eyeHeight = entity.height / 2; entity.eyeHeight = player.getInterpolator().interpolate("eyeHeight", entity.height / 2, 10);
} else { } else {
entity.eyeHeight = entity.getDefaultEyeHeight(); MixinEntity.setSize(entity, entity.width, player.getInterpolator().interpolate("standingHeight", entity.height, 10));
entity.eyeHeight = player.getInterpolator().interpolate("eyeHeight", entity.getDefaultEyeHeight(), 10);
} }
if (!entity.capabilities.isCreativeMode && !entity.isElytraFlying()) { if (!entity.capabilities.isCreativeMode && !entity.isElytraFlying()) {

View file

@ -0,0 +1,38 @@
package com.minelittlepony.unicopia.player;
import com.minelittlepony.transform.MotionCompositor;
import net.minecraft.entity.player.EntityPlayer;
class PlayerView extends MotionCompositor implements IView {
private final IPlayer player;
private double baseRoll = 0;
public PlayerView(IPlayer player) {
this.player = player;
}
@Override
public double calculateRoll(EntityPlayer entity) {
double roll = baseRoll;
if (player.getGravity().isFlying()) {
roll -= super.calculateRoll(entity, entity.motionX, entity.motionY, entity.motionZ);
}
return player.getInterpolator().interpolate("roll", (float)roll, 100);
}
@Override
public double getBaseRoll() {
return baseRoll;
}
@Override
public void setBaseRoll(double roll) {
baseRoll = roll;
}
}