Fixed networking, npe when ticking players, fixed various abilities, fixed values not being syncronised between the client and server, re-added the various apples

This commit is contained in:
Sollace 2018-09-12 22:37:06 +02:00
parent c36402b4d9
commit 5ce8d4a492
51 changed files with 490 additions and 392 deletions

View file

@ -1,5 +1,8 @@
package com.minelittlepony.unicopia; package com.minelittlepony.unicopia;
import java.util.HashMap;
import java.util.Map;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.I18n;
@ -16,6 +19,13 @@ public enum Race {
private final boolean flight; private final boolean flight;
private final boolean earth; private final boolean earth;
private final static Map<Integer, Race> raceIdMap = new HashMap<>();
static {
for (Race race : values()) {
raceIdMap.put(race.ordinal(), race);
}
}
Race(boolean magic, boolean flight, boolean earth) { Race(boolean magic, boolean flight, boolean earth) {
this.magic = magic; this.magic = magic;
this.flight = flight; this.flight = flight;
@ -43,7 +53,7 @@ public enum Race {
} }
public String getTranslationString() { public String getTranslationString() {
return String.format("unicopia.race.%s", name()); return String.format("unicopia.race.%s", name().toLowerCase());
} }
public boolean isSameAs(String s) { public boolean isSameAs(String s) {
@ -59,19 +69,14 @@ public enum Race {
} }
} }
return fromId(s);
}
public static Race fromId(String s) {
try { try {
int id = Integer.parseInt(s); return fromId(Integer.parseInt(s));
Race[] values = values();
if (id >= 0 || id < values.length) {
return values[id];
}
} catch (NumberFormatException e) { } } catch (NumberFormatException e) { }
return HUMAN; return HUMAN;
} }
public static Race fromId(int id) {
return raceIdMap.getOrDefault(id, HUMAN);
}
} }

View file

@ -4,6 +4,6 @@ import net.minecraftforge.fml.common.FMLCommonHandler;
public interface UClient { public interface UClient {
static boolean isClientSide() { static boolean isClientSide() {
return FMLCommonHandler.instance().getSide().isServer(); return FMLCommonHandler.instance().getSide().isClient();
} }
} }

View file

@ -4,6 +4,7 @@ import com.minelittlepony.unicopia.item.ItemApple;
import come.minelittlepony.unicopia.forgebullshit.RegistryLockSpinner; import come.minelittlepony.unicopia.forgebullshit.RegistryLockSpinner;
import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.init.Items;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.FurnaceRecipes; import net.minecraft.item.crafting.FurnaceRecipes;
@ -18,16 +19,17 @@ public class UItems {
static void registerItems() { static void registerItems() {
RegistryLockSpinner.unlock(Item.REGISTRY); RegistryLockSpinner.unlock(Item.REGISTRY);
Item.REGISTRY.register(260, new ResourceLocation("minecraft", "apple"), apple); ResourceLocation res = new ResourceLocation("apple");
Item.REGISTRY.register(Item.getIdFromItem(Items.APPLE), res, apple);
if (UClient.isClientSide()) { if (UClient.isClientSide()) {
String[] variants = apple.getVariants(); String[] variants = apple.getVariants();
ResourceLocation app = new ResourceLocation("minecraft", "apple");
for (int i = 0; i < variants.length; i++) { for (int i = 0; i < variants.length; i++) {
ModelLoader.setCustomModelResourceLocation(apple, i, new ModelResourceLocation(app, variants[i])); ModelLoader.setCustomModelResourceLocation(apple, i, new ModelResourceLocation("unicopia:" + variants[i]));
} }
// ModelBakery.registerItemVariants(apple, NoNameSpacedResource.ofAllDomained("unicopia", apple.getVariants()));
} }
RegistryLockSpinner.lock(Item.REGISTRY); RegistryLockSpinner.lock(Item.REGISTRY);

View file

@ -1,11 +1,13 @@
package com.minelittlepony.unicopia; package com.minelittlepony.unicopia;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.item.EnumAction; import net.minecraft.item.EnumAction;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraftforge.event.AttachCapabilitiesEvent; import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.entity.player.PlayerFlyableFallEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@ -14,7 +16,6 @@ import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.event.FMLServerStartingEvent; import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent; import net.minecraftforge.fml.common.gameevent.TickEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent.Phase; import net.minecraftforge.fml.common.gameevent.TickEvent.Phase;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
@ -22,12 +23,14 @@ import net.minecraftforge.fml.relauncher.SideOnly;
import com.minelittlepony.jumpingcastle.api.IChannel; import com.minelittlepony.jumpingcastle.api.IChannel;
import com.minelittlepony.jumpingcastle.api.JumpingCastle; import com.minelittlepony.jumpingcastle.api.JumpingCastle;
import com.minelittlepony.jumpingcastle.api.Target;
import com.minelittlepony.unicopia.client.particle.EntityMagicFX; import com.minelittlepony.unicopia.client.particle.EntityMagicFX;
import com.minelittlepony.unicopia.client.particle.Particles; import com.minelittlepony.unicopia.client.particle.Particles;
import com.minelittlepony.unicopia.command.Commands; import com.minelittlepony.unicopia.command.Commands;
import com.minelittlepony.unicopia.input.Keyboard; import com.minelittlepony.unicopia.input.Keyboard;
import com.minelittlepony.unicopia.network.MsgPlayerAbility; import com.minelittlepony.unicopia.network.MsgPlayerAbility;
import com.minelittlepony.unicopia.network.MsgPlayerCapabilities; import com.minelittlepony.unicopia.network.MsgPlayerCapabilities;
import com.minelittlepony.unicopia.network.MsgRequestCapabilities;
import com.minelittlepony.unicopia.player.PlayerSpeciesList; import com.minelittlepony.unicopia.player.PlayerSpeciesList;
import com.minelittlepony.unicopia.power.PowersRegistry; import com.minelittlepony.unicopia.power.PowersRegistry;
@ -51,13 +54,17 @@ public class Unicopia {
@EventHandler @EventHandler
public void init(FMLInitializationEvent event) { public void init(FMLInitializationEvent event) {
channel = JumpingCastle.listen(MODID) channel = JumpingCastle.listen(MODID, () -> {
.consume(MsgPlayerCapabilities.class, (msg, channel) -> { channel.send(new MsgRequestCapabilities(Minecraft.getMinecraft().player), Target.SERVER);
PlayerSpeciesList.instance().handleSpeciesChange(msg.senderId, msg.newRace);
}) })
.consume(MsgPlayerAbility.class, (msg, channel) -> { // client ------> server
msg.applyServerAbility(); .consume(MsgRequestCapabilities.class)
});
// client <------ server
.consume(MsgPlayerCapabilities.class)
// client ------> server
.consume(MsgPlayerAbility.class);
MAGIC_PARTICLE = Particles.instance().registerParticle(new EntityMagicFX.Factory()); MAGIC_PARTICLE = Particles.instance().registerParticle(new EntityMagicFX.Factory());
@ -68,15 +75,9 @@ public class Unicopia {
@SubscribeEvent @SubscribeEvent
public static void registerItemsStatic(RegistryEvent.Register<Item> event) { public static void registerItemsStatic(RegistryEvent.Register<Item> event) {
// Why won't you run!?
UItems.registerItems(); UItems.registerItems();
} }
@SubscribeEvent
public static void onPlayerJoin(PlayerLoggedInEvent event) {
PlayerSpeciesList.instance().sendCapabilities(event.player.getGameProfile().getId());
}
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@SubscribeEvent @SubscribeEvent
public static void onGameTick(TickEvent.ClientTickEvent event) { public static void onGameTick(TickEvent.ClientTickEvent event) {
@ -86,29 +87,38 @@ public class Unicopia {
} }
@SubscribeEvent @SubscribeEvent
public static void onPlyerTick(TickEvent.PlayerTickEvent event) { public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
if (event.phase == Phase.END) { if (event.phase == Phase.END) {
PlayerSpeciesList.instance().getPlayer(event.player).onUpdate(event.player); PlayerSpeciesList.instance()
.getPlayer(event.player)
.onUpdate(event.player);
} }
} }
@SubscribeEvent
public static void onPlayerFall(PlayerFlyableFallEvent event) {
PlayerSpeciesList.instance()
.getPlayer(event.getEntityPlayer())
.onFall(event.getDistance(), event.getMultiplier());
}
@EventHandler @EventHandler
public void onServerStarted(FMLServerStartingEvent event) { public void onServerStarted(FMLServerStartingEvent event) {
Commands.init(event); Commands.init(event);
} }
@EventHandler @SubscribeEvent
public void onPlayerRightClick(PlayerInteractEvent.RightClickItem event) { public static void onPlayerRightClick(PlayerInteractEvent.RightClickItem event) {
// Why won't you run!? // Why won't you run!?
if (!event.isCanceled() if (!event.isCanceled() && event.getItemStack().getItemUseAction() == EnumAction.EAT) {
&& event.getItemStack().getItemUseAction() == EnumAction.EAT) { PlayerSpeciesList.instance()
PlayerSpeciesList.instance().getPlayer(event.getEntityPlayer()).onEntityEat(); .getPlayer(event.getEntityPlayer())
.onEntityEat();
} }
} }
@SubscribeEvent @SubscribeEvent
public static void attachCapabilities(AttachCapabilitiesEvent<Entity> event) { public static void attachCapabilities(AttachCapabilitiesEvent<Entity> event) {
// Why won't you run!?
FBS.attach(event); FBS.attach(event);
} }

View file

@ -23,7 +23,7 @@ public class Particles {
public int registerParticle(IParticleFactory factory) { public int registerParticle(IParticleFactory factory) {
int id = registeredParticles.size(); int id = registeredParticles.size();
registeredParticles.add(factory); registeredParticles.add(factory);
return -id; return -id - 1;
} }
public Particle spawnParticle(int particleId, boolean ignoreDistance, double posX, double posY, double posZ, double speedX, double speedY, double speedZ, int ...pars) { public Particle spawnParticle(int particleId, boolean ignoreDistance, double posX, double posY, double posZ, double speedX, double speedY, double speedZ, int ...pars) {
@ -51,6 +51,7 @@ public class Particles {
return mc.effectRenderer.spawnEffectParticle(particleId, posX, posY, posZ, speedX, speedY, speedZ, pars); return mc.effectRenderer.spawnEffectParticle(particleId, posX, posY, posZ, speedX, speedY, speedZ, pars);
} }
particleId ++;
IParticleFactory iparticlefactory = registeredParticles.get(-particleId); IParticleFactory iparticlefactory = registeredParticles.get(-particleId);

View file

@ -4,7 +4,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.player.IPlayer;
import com.minelittlepony.unicopia.player.PlayerSpeciesList; import com.minelittlepony.unicopia.player.PlayerSpeciesList;
import net.minecraft.command.CommandBase; import net.minecraft.command.CommandBase;
@ -72,10 +71,7 @@ class CommandSpecies extends CommandBase {
player.sendMessage(new TextComponentTranslation("commands.race.fail", args[1].toUpperCase())); player.sendMessage(new TextComponentTranslation("commands.race.fail", args[1].toUpperCase()));
} else { } else {
if (PlayerSpeciesList.instance().speciesPermitted(species)) { if (PlayerSpeciesList.instance().speciesPermitted(species)) {
IPlayer iplayer = PlayerSpeciesList.instance().getPlayer(player); PlayerSpeciesList.instance().getPlayer(player).setPlayerSpecies(species);
iplayer.setPlayerSpecies(species);
iplayer.sendCapabilities();
TextComponentTranslation formattedName = new TextComponentTranslation(species.name().toLowerCase()); TextComponentTranslation formattedName = new TextComponentTranslation(species.name().toLowerCase());
@ -96,7 +92,7 @@ class CommandSpecies extends CommandBase {
String name = "commands.race.tell."; String name = "commands.race.tell.";
name += player == sender ? "self" : "other"; name += player == sender ? "self" : "other";
ITextComponent race = new TextComponentString(spec.getTranslationString()); ITextComponent race = new TextComponentTranslation(spec.getTranslationString());
TextComponentTranslation message = new TextComponentTranslation(name); TextComponentTranslation message = new TextComponentTranslation(name);

View file

@ -5,7 +5,9 @@ import java.util.UUID;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.annotations.Expose; import com.google.gson.annotations.Expose;
import com.minelittlepony.jumpingcastle.api.IChannel;
import com.minelittlepony.jumpingcastle.api.IMessage; import com.minelittlepony.jumpingcastle.api.IMessage;
import com.minelittlepony.jumpingcastle.api.IMessageHandler;
import com.minelittlepony.unicopia.player.IPlayer; import com.minelittlepony.unicopia.player.IPlayer;
import com.minelittlepony.unicopia.power.IData; import com.minelittlepony.unicopia.power.IData;
import com.minelittlepony.unicopia.power.IPower; import com.minelittlepony.unicopia.power.IPower;
@ -14,7 +16,7 @@ import com.minelittlepony.unicopia.power.PowersRegistry;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
@IMessage.Id(2) @IMessage.Id(2)
public class MsgPlayerAbility implements IMessage { public class MsgPlayerAbility implements IMessage, IMessageHandler<MsgPlayerAbility> {
private static final Gson gson = new GsonBuilder() private static final Gson gson = new GsonBuilder()
.excludeFieldsWithoutExposeAnnotation() .excludeFieldsWithoutExposeAnnotation()
@ -29,15 +31,12 @@ public class MsgPlayerAbility implements IMessage {
@Expose @Expose
private String abilityJson; private String abilityJson;
public MsgPlayerAbility(IPower<?> power, IData data) { public MsgPlayerAbility(EntityPlayer player, IPower<?> power, IData data) {
senderId = player.getGameProfile().getId();
powerIdentifier = power.getKeyName(); powerIdentifier = power.getKeyName();
abilityJson = gson.toJson(data, power.getPackageType()); abilityJson = gson.toJson(data, power.getPackageType());
} }
public void applyServerAbility() {
PowersRegistry.instance().getPowerFromName(powerIdentifier).ifPresent(this::apply);
}
private <T extends IData> void apply(IPower<T> power) { private <T extends IData> void apply(IPower<T> power) {
EntityPlayer player = IPlayer.getPlayerEntity(senderId); EntityPlayer player = IPlayer.getPlayerEntity(senderId);
if (player == null) { if (player == null) {
@ -48,4 +47,9 @@ public class MsgPlayerAbility implements IMessage {
power.apply(player, data); power.apply(player, data);
} }
@Override
public void onPayload(MsgPlayerAbility message, IChannel channel) {
PowersRegistry.instance().getPowerFromName(powerIdentifier).ifPresent(this::apply);
}
} }

View file

@ -1,28 +1,75 @@
package com.minelittlepony.unicopia.network; 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 java.util.UUID;
import com.google.gson.annotations.Expose; import com.google.gson.annotations.Expose;
import com.minelittlepony.jumpingcastle.api.IChannel;
import com.minelittlepony.jumpingcastle.api.IMessage; import com.minelittlepony.jumpingcastle.api.IMessage;
import com.minelittlepony.jumpingcastle.api.IMessageHandler;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.player.IPlayer;
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
@IMessage.Id(1) @IMessage.Id(1)
public class MsgPlayerCapabilities implements IMessage { public class MsgPlayerCapabilities implements IMessage, IMessageHandler<MsgPlayerCapabilities> {
@Expose @Expose
public Race newRace; public Race newRace;
@Expose @Expose
public UUID senderId; UUID senderId;
@Expose
byte[] compoundTag;
public MsgPlayerCapabilities(Race race, EntityPlayer player) { public MsgPlayerCapabilities(Race race, EntityPlayer player) {
newRace = race; this(race, player.getGameProfile().getId());
senderId = player.getGameProfile().getId(); }
public MsgPlayerCapabilities(IPlayer player) {
newRace = player.getPlayerSpecies();
senderId = player.getOwner().getGameProfile().getId();
try (ByteArrayOutputStream bytes = new ByteArrayOutputStream()) {
NBTTagCompound nbt = player.toNBT();
CompressedStreamTools.write(nbt, new DataOutputStream(bytes));
compoundTag = bytes.toByteArray();
} catch (IOException e) {
}
} }
public MsgPlayerCapabilities(Race race, UUID playerId) { public MsgPlayerCapabilities(Race race, UUID playerId) {
newRace = race; newRace = race;
senderId = playerId; senderId = playerId;
compoundTag = new byte[0];
}
@Override
public void onPayload(MsgPlayerCapabilities message, IChannel channel) {
System.out.println("[CLIENT] Got capabilities for player id " + senderId + " I am "
+ Minecraft.getMinecraft().player.getGameProfile().getId());
IPlayer player = PlayerSpeciesList.instance().getPlayer(Minecraft.getMinecraft().player);
if (compoundTag.length > 0) {
try (ByteArrayInputStream input = new ByteArrayInputStream(compoundTag)) {
NBTTagCompound nbt = CompressedStreamTools.read(new DataInputStream(input));
player.readFromNBT(nbt);
} catch (IOException e) {
}
} else {
player.setPlayerSpecies(newRace);
}
} }
} }

View file

@ -0,0 +1,30 @@
package com.minelittlepony.unicopia.network;
import java.util.UUID;
import com.google.gson.annotations.Expose;
import com.minelittlepony.jumpingcastle.api.IChannel;
import com.minelittlepony.jumpingcastle.api.IMessage;
import com.minelittlepony.jumpingcastle.api.IMessageHandler;
import com.minelittlepony.unicopia.player.IPlayer;
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
import net.minecraft.entity.player.EntityPlayer;
@IMessage.Id(0)
public class MsgRequestCapabilities implements IMessage, IMessageHandler<MsgRequestCapabilities> {
@Expose
public UUID senderId;
public MsgRequestCapabilities(EntityPlayer player) {
senderId = player.getGameProfile().getId();
}
@Override
public void onPayload(MsgRequestCapabilities message, IChannel channel) {
System.out.println("[SERVER] Sending capabilities to player id " + senderId);
IPlayer player = PlayerSpeciesList.instance().getPlayer(senderId);
channel.respond(new MsgPlayerCapabilities(player.getPlayerSpecies(), senderId), senderId);
}
}

View file

@ -23,7 +23,7 @@ final class DefaultPlayerSpecies implements IPlayer, IAbilityReceiver {
} }
@Override @Override
public void sendCapabilities() { public void sendCapabilities(boolean full) {
} }
@ -71,4 +71,9 @@ final class DefaultPlayerSpecies implements IPlayer, IAbilityReceiver {
public EntityPlayer getOwner() { public EntityPlayer getOwner() {
return null; return null;
} }
@Override
public void copyFrom(IPlayer oldPlayer) {
}
} }

View file

@ -15,16 +15,22 @@ public interface IPlayer extends ICaster<EntityPlayer>, InbtSerialisable, IUpdat
void setPlayerSpecies(Race race); void setPlayerSpecies(Race race);
void sendCapabilities(); void sendCapabilities(boolean full);
IAbilityReceiver getAbilities(); IAbilityReceiver getAbilities();
boolean isClientPlayer(); boolean isClientPlayer();
void copyFrom(IPlayer oldPlayer);
default void onEntityEat() { default void onEntityEat() {
} }
default void onFall(float distance, float damageMultiplier) {
}
static EntityPlayer getPlayerEntity(UUID playerId) { static EntityPlayer getPlayerEntity(UUID playerId) {
EntityPlayer player = FMLCommonHandler.instance().getMinecraftServerInstance().getPlayerList().getPlayerByUUID(playerId); EntityPlayer player = FMLCommonHandler.instance().getMinecraftServerInstance().getPlayerList().getPlayerByUUID(playerId);

View file

@ -111,7 +111,7 @@ class PlayerAbilityDelegate implements IAbilityReceiver, IUpdatable, InbtSeriali
IData data = activeAbility.tryActivate(entity, entity.getEntityWorld()); IData data = activeAbility.tryActivate(entity, entity.getEntityWorld());
if (data != null) { if (data != null) {
Unicopia.channel.send(new MsgPlayerAbility(activeAbility, data), Target.SERVER); Unicopia.channel.send(new MsgPlayerAbility(entity, activeAbility, data), Target.SERVER);
} }
return data != null; return data != null;

View file

@ -2,8 +2,13 @@ package com.minelittlepony.unicopia.player;
import java.util.UUID; import java.util.UUID;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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.network.MsgPlayerCapabilities;
import com.minelittlepony.unicopia.spell.ICaster; import com.minelittlepony.unicopia.spell.ICaster;
import com.minelittlepony.unicopia.spell.IMagicEffect; import com.minelittlepony.unicopia.spell.IMagicEffect;
import com.minelittlepony.unicopia.spell.SpellRegistry; import com.minelittlepony.unicopia.spell.SpellRegistry;
@ -12,11 +17,18 @@ import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects; import net.minecraft.init.MobEffects;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.potion.PotionEffect; import net.minecraft.potion.PotionEffect;
import net.minecraft.stats.StatList;
class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> { class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
private Race playerSpecies = Race.HUMAN; private static final Logger logger = LogManager.getLogger();
private static final DataParameter<Integer> PLAYER_RACE = EntityDataManager
.createKey(EntityPlayer.class, DataSerializers.VARINT);
private final PlayerAbilityDelegate powers = new PlayerAbilityDelegate(this); private final PlayerAbilityDelegate powers = new PlayerAbilityDelegate(this);
@ -25,31 +37,46 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
private IMagicEffect effect; private IMagicEffect effect;
private EntityPlayer entity; private EntityPlayer entity;
private UUID playerId;
PlayerCapabilities(UUID playerId) { PlayerCapabilities(EntityPlayer player) {
setOwner(player);
player.getDataManager().register(PLAYER_RACE, Race.HUMAN.ordinal());
} }
@Override @Override
public Race getPlayerSpecies() { public Race getPlayerSpecies() {
return playerSpecies; if (getOwner() == null) {
return Race.HUMAN;
}
return Race.fromId(getOwner().getDataManager().get(PLAYER_RACE));
} }
@Override @Override
public void setPlayerSpecies(Race race) { public void setPlayerSpecies(Race race) {
playerSpecies = race;
EntityPlayer self = getOwner(); EntityPlayer self = getOwner();
self.capabilities.allowFlying = race.canFly(); if (self != null) {
gravity.updateFlightStat(self, self.capabilities.isFlying); getOwner().getDataManager().set(PLAYER_RACE, race.ordinal());
self.sendPlayerAbilities(); self.capabilities.allowFlying = race.canFly();
gravity.updateFlightStat(self, self.capabilities.isFlying);
self.sendPlayerAbilities();
sendCapabilities(false);
}
} }
@Override @Override
public void sendCapabilities() { public void sendCapabilities(boolean full) {
PlayerSpeciesList.instance().sendCapabilities(getOwner().getGameProfile().getId()); if (!getOwner().getEntityWorld().isRemote) {
if (full) {
Unicopia.channel.broadcast(new MsgPlayerCapabilities(this));
} else {
Unicopia.channel.broadcast(new MsgPlayerCapabilities(getPlayerSpecies(), getOwner().getGameProfile().getId()));
}
}
} }
@Override @Override
@ -65,22 +92,33 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
@Override @Override
public void onUpdate(EntityPlayer entity) { public void onUpdate(EntityPlayer entity) {
this.entity = entity;
powers.onUpdate(entity); powers.onUpdate(entity);
gravity.onUpdate(entity); gravity.onUpdate(entity);
if (!getPlayerSpecies().canCast()) {
effect = null;
}
if (effect != null) { if (effect != null) {
if (entity.getEntityWorld().isRemote && entity.getEntityWorld().getWorldTime() % 10 == 0) { if (!getPlayerSpecies().canCast()) {
effect.render(entity); setEffect(null);
} } else {
if (entity.getEntityWorld().isRemote) { // && entity.getEntityWorld().getWorldTime() % 10 == 0
effect.render(entity);
}
if (!effect.update(entity)) { if (!effect.update(entity)) {
effect = null; setEffect(null);
}
}
}
}
@Override
public void onFall(float distance, float damageMultiplier) {
if (!entity.getEntityWorld().isRemote) {
if (getPlayerSpecies().canFly()) {
if (entity.fallDistance > 2) {
entity.addStat(StatList.FALL_ONE_CM, (int)Math.round(distance * 100));
}
gravity.landHard(entity, distance, damageMultiplier);
} }
} }
} }
@ -96,7 +134,7 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
@Override @Override
public void writeToNBT(NBTTagCompound compound) { public void writeToNBT(NBTTagCompound compound) {
compound.setString("playerSpecies", playerSpecies.name()); compound.setString("playerSpecies", getPlayerSpecies().name());
compound.setTag("powers", powers.toNBT()); compound.setTag("powers", powers.toNBT());
compound.setTag("gravity", gravity.toNBT()); compound.setTag("gravity", gravity.toNBT());
@ -108,12 +146,13 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
@Override @Override
public void readFromNBT(NBTTagCompound compound) { public void readFromNBT(NBTTagCompound compound) {
playerSpecies = Race.fromName(compound.getString("playerSpecies")); setPlayerSpecies(Race.fromName(compound.getString("playerSpecies")));
powers.readFromNBT(compound.getCompoundTag("powers")); powers.readFromNBT(compound.getCompoundTag("powers"));
gravity.readFromNBT(compound.getCompoundTag("gravity")); gravity.readFromNBT(compound.getCompoundTag("gravity"));
effect = null;
if (compound.hasKey("effect_id") && compound.hasKey("effect")) { if (compound.hasKey("effect_id") && compound.hasKey("effect")) {
effect = null;
SpellRegistry.instance().getSpellFromName(compound.getString("effect_id")).ifPresent(f -> { SpellRegistry.instance().getSpellFromName(compound.getString("effect_id")).ifPresent(f -> {
effect = f; effect = f;
effect.readFromNBT(compound.getCompoundTag("effect")); effect.readFromNBT(compound.getCompoundTag("effect"));
@ -121,9 +160,17 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
} }
} }
@Override
public void copyFrom(IPlayer oldPlayer) {
setEffect(oldPlayer.getEffect());
setPlayerSpecies(oldPlayer.getPlayerSpecies());
}
@Override @Override
public void setEffect(IMagicEffect effect) { public void setEffect(IMagicEffect effect) {
this.effect = effect; this.effect = effect;
sendCapabilities(true);
} }
@Override @Override
@ -131,8 +178,20 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
return effect; return effect;
} }
@Override
public void setOwner(EntityPlayer owner) {
entity = owner;
playerId = owner.getGameProfile().getId();
}
@Override @Override
public EntityPlayer getOwner() { public EntityPlayer getOwner() {
if (entity == null) {
entity = IPlayer.getPlayerEntity(playerId);
if (entity == null) {
logger.error("Capabilities without player! Mismatched id was" + playerId);
}
}
return entity; return entity;
} }
} }

View file

@ -2,14 +2,28 @@ package com.minelittlepony.unicopia.player;
import com.minelittlepony.unicopia.InbtSerialisable; import com.minelittlepony.unicopia.InbtSerialisable;
import net.minecraft.block.Block;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.init.SoundEvents;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.DamageSource;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
class PlayerGravityDelegate implements IUpdatable, InbtSerialisable { class PlayerGravityDelegate implements IUpdatable, InbtSerialisable {
private final IPlayer player; private final IPlayer player;
private int ticksSinceLanding = 0; private static final float MAXIMUM_FLIGHT_EXPERIENCE = 100;
private int ticksInAir = 0;
private float flightExperience = 0;
public boolean isFlying = false; public boolean isFlying = false;
@ -19,20 +33,69 @@ class PlayerGravityDelegate implements IUpdatable, InbtSerialisable {
@Override @Override
public void onUpdate(EntityPlayer entity) { public void onUpdate(EntityPlayer entity) {
if (!entity.capabilities.isCreativeMode) { entity.capabilities.allowFlying = entity.capabilities.isCreativeMode || player.getPlayerSpecies().canFly();
if (player.getPlayerSpecies().canFly()) { entity.capabilities.isFlying |= entity.capabilities.allowFlying && isFlying;
if (ticksSinceLanding < 2) {
ticksSinceLanding++; if (!entity.capabilities.isCreativeMode && !entity.isElytraFlying()) {
if (entity.capabilities.isFlying && !entity.isRiding()) {
entity.fallDistance = 0;
float exhaustion = (0.2F * ticksInAir++) / 100;
if (entity.isSprinting()) {
exhaustion *= 3.11F;
} }
entity.capabilities.allowFlying = player.getPlayerSpecies().canFly(); entity.addExhaustion(exhaustion * (1 - flightExperience));
entity.capabilities.isFlying = false;
if (entity.ticksExisted % 20000 == 0) {
addFlightExperience(entity);
}
} else {
ticksInAir = 0;
} }
} }
}
if (entity.capabilities.isFlying) { public void landHard(EntityPlayer player, float distance, float damageMultiplier) {
entity.fallDistance = 0; if (distance <= 0) {
return;
} }
PotionEffect potioneffect = player.getActivePotionEffect(MobEffects.JUMP_BOOST);
float potion = potioneffect != null ? potioneffect.getAmplifier() + 1 : 0;
int i = MathHelper.ceil((distance - 8.0F - potion) * damageMultiplier);
if (i > 0) {
int j = MathHelper.floor(player.posX);
int k = MathHelper.floor(player.posY - 0.20000000298023224D);
int l = MathHelper.floor(player.posZ);
BlockPos pos = new BlockPos(j, k, l);
IBlockState state = player.world.getBlockState(pos);
Block block = state.getBlock();
if (state.getMaterial() != Material.AIR) {
player.playSound(getFallSound(i), 1, 1);
player.attackEntityFrom(DamageSource.FALL, i);
SoundType soundtype = block.getSoundType(state, player.getEntityWorld(), pos, player);
player.playSound(soundtype.getStepSound(), soundtype.getVolume() * 0.5f, soundtype.getPitch() * 0.75f);
}
}
}
protected SoundEvent getFallSound(int distance) {
return distance > 4 ? SoundEvents.ENTITY_PLAYER_BIG_FALL : SoundEvents.ENTITY_PLAYER_SMALL_FALL;
}
private void addFlightExperience(EntityPlayer entity) {
entity.addExperience(1);
flightExperience += (flightExperience - MAXIMUM_FLIGHT_EXPERIENCE) / 20;
} }
public void updateFlightStat(EntityPlayer entity, boolean flying) { public void updateFlightStat(EntityPlayer entity, boolean flying) {
@ -45,7 +108,7 @@ class PlayerGravityDelegate implements IUpdatable, InbtSerialisable {
isFlying = entity.capabilities.isFlying; isFlying = entity.capabilities.isFlying;
if (isFlying) { if (isFlying) {
ticksSinceLanding = 0; ticksInAir = 0;
} }
} else { } else {
@ -57,13 +120,15 @@ class PlayerGravityDelegate implements IUpdatable, InbtSerialisable {
@Override @Override
public void writeToNBT(NBTTagCompound compound) { public void writeToNBT(NBTTagCompound compound) {
compound.setInteger("ticksOnGround", ticksSinceLanding); compound.setInteger("flightDuration", ticksInAir);
compound.setFloat("flightExperience", flightExperience);
compound.setBoolean("isFlying", isFlying); compound.setBoolean("isFlying", isFlying);
} }
@Override @Override
public void readFromNBT(NBTTagCompound compound) { public void readFromNBT(NBTTagCompound compound) {
ticksSinceLanding = compound.getInteger("ticksOnGround"); ticksInAir = compound.getInteger("flightDuration");
flightExperience = compound.getFloat("flightExperience");
isFlying = compound.getBoolean("isFlying"); isFlying = compound.getBoolean("isFlying");
} }
} }

View file

@ -4,13 +4,9 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import com.minelittlepony.jumpingcastle.api.Target;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.network.MsgPlayerCapabilities;
import come.minelittlepony.unicopia.forgebullshit.FBS; import come.minelittlepony.unicopia.forgebullshit.FBS;
import come.minelittlepony.unicopia.forgebullshit.IPlayerCapabilitiesProxyContainer;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
public class PlayerSpeciesList { public class PlayerSpeciesList {
@ -27,16 +23,8 @@ public class PlayerSpeciesList {
return race.isDefault() || serverPermittedRaces.isEmpty() || serverPermittedRaces.contains(race); return race.isDefault() || serverPermittedRaces.isEmpty() || serverPermittedRaces.contains(race);
} }
public void sendCapabilities(UUID playerId) { public IPlayer emptyPlayer(EntityPlayer player) {
Unicopia.channel.send(new MsgPlayerCapabilities(getPlayer(playerId).getPlayerSpecies(), playerId), playerId); return new PlayerCapabilities(player);
}
public void handleSpeciesChange(UUID playerId, Race race) {
getPlayer(playerId).setPlayerSpecies(race);
}
public IPlayer emptyPlayer(UUID playerId) {
return new PlayerCapabilities(playerId);
} }
public IPlayer getPlayer(EntityPlayer player) { public IPlayer getPlayer(EntityPlayer player) {
@ -44,16 +32,7 @@ public class PlayerSpeciesList {
return DefaultPlayerSpecies.INSTANCE; return DefaultPlayerSpecies.INSTANCE;
} }
IPlayerCapabilitiesProxyContainer container = FBS.of(player); return FBS.of(player).getPlayer();
IPlayer ply = container.getPlayer();
if (ply == null) {
ply = emptyPlayer(player.getGameProfile().getId());
container.setPlayer(ply);
}
return ply;
} }
public IPlayer getPlayer(UUID playerId) { public IPlayer getPlayer(UUID playerId) {

View file

@ -1,17 +1,16 @@
package com.minelittlepony.unicopia.power; package com.minelittlepony.unicopia.power;
import java.util.Random;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.client.particle.Particles; import com.minelittlepony.unicopia.client.particle.Particles;
import com.minelittlepony.unicopia.input.IKeyBind; import com.minelittlepony.unicopia.input.IKeyBind;
import com.minelittlepony.unicopia.player.IPlayer; import com.minelittlepony.unicopia.player.IPlayer;
import com.minelittlepony.util.shape.IShape;
import com.minelittlepony.util.shape.Sphere;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.DamageSource; import net.minecraft.util.DamageSource;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public interface IPower<T extends IData> extends IKeyBind { public interface IPower<T extends IData> extends IKeyBind {
@ -41,20 +40,20 @@ public interface IPower<T extends IData> extends IKeyBind {
} }
static void spawnParticles(int particleId, EntityPlayer player, int count) { static void spawnParticles(int particleId, EntityPlayer player, int count) {
double halfDist = player.getEyeHeight() / 1.5; double halfDist = player.getEyeHeight() / 1.5;
double middle = player.getEntityBoundingBox().minY + halfDist; double middle = player.getEntityBoundingBox().minY + halfDist;
Random rand = player.getEntityWorld().rand; IShape shape = new Sphere(false, (float)halfDist);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
double x = (rand.nextFloat() * halfDist) - halfDist; Vec3d point = shape.computePoint(player.world.rand);
double y = (rand.nextFloat() * halfDist) - halfDist;
double z = (rand.nextFloat() * halfDist) - halfDist;
Particles.instance().spawnParticle(particleId, false, Particles.instance().spawnParticle(particleId, false,
player.posX + x, player.posX + point.x,
middle + y, middle + point.y,
player.posZ + z, player.posZ + point.z,
0, 0, 0); 0, 0, 0);
} }
} }
@ -109,21 +108,18 @@ public interface IPower<T extends IData> extends IKeyBind {
* @param player The player that triggered the ability * @param player The player that triggered the ability
* @param data Data previously sent from the client * @param data Data previously sent from the client
*/ */
@SideOnly(Side.SERVER)
void apply(EntityPlayer player, T data); void apply(EntityPlayer player, T data);
/** /**
* Called just before the ability is activated. * Called just before the ability is activated.
* @param player The current player * @param player The current player
*/ */
@SideOnly(Side.CLIENT)
void preApply(EntityPlayer player); void preApply(EntityPlayer player);
/** /**
* Called every tick until the cooldown timer runs out. * Called every tick until the cooldown timer runs out.
* @param player The current player * @param player The current player
*/ */
@SideOnly(Side.CLIENT)
void postApply(EntityPlayer player); void postApply(EntityPlayer player);
} }

View file

@ -15,6 +15,7 @@ import com.minelittlepony.util.vector.VecHelper;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.passive.EntityCow; import net.minecraft.entity.passive.EntityCow;
import net.minecraft.entity.passive.EntitySheep;
import net.minecraft.entity.passive.EntityVillager; import net.minecraft.entity.passive.EntityVillager;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects; import net.minecraft.init.MobEffects;
@ -66,6 +67,7 @@ public class PowerFeed implements IPower<Hit> {
return e instanceof EntityCow return e instanceof EntityCow
|| e instanceof EntityVillager || e instanceof EntityVillager
|| e instanceof EntityPlayer || e instanceof EntityPlayer
|| e instanceof EntitySheep
|| EnumCreatureType.MONSTER.getCreatureClass().isAssignableFrom(e.getClass()); || EnumCreatureType.MONSTER.getCreatureClass().isAssignableFrom(e.getClass());
} }

View file

@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.power;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.player.IPlayer; import com.minelittlepony.unicopia.player.IPlayer;
import com.minelittlepony.unicopia.power.data.Location; import com.minelittlepony.unicopia.power.data.Location;
import com.minelittlepony.util.vector.VecHelper; import com.minelittlepony.util.vector.VecHelper;
@ -84,18 +85,13 @@ public class PowerGrow implements IPower<Location> {
IGrowable g = ((IGrowable)state.getBlock()); IGrowable g = ((IGrowable)state.getBlock());
if (g.canGrow(w, pos, state, w.isRemote) && g.canUseBonemeal(w, w.rand, pos, state)) { if (g.canGrow(w, pos, state, w.isRemote) && g.canUseBonemeal(w, w.rand, pos, state)) {
do { if (ItemDye.applyBonemeal(new ItemStack(Items.DYE, 1), w, pos)) {
if (ItemDye.applyBonemeal(new ItemStack(Items.DYE, 1), w, pos)) { w.playEvent(2005, pos, 0);
w.playEvent(2005, pos, 0);
if (g instanceof BlockDoublePlant) { if (g instanceof BlockDoublePlant) {
w.playEvent(2005, pos.up(), 0); w.playEvent(2005, pos.up(), 0);
}
} }
}
state = w.getBlockState(pos);
g = ((IGrowable)state.getBlock());
} while (g.canGrow(w, pos, state, w.isRemote));
return 1; return 1;
} }
@ -105,7 +101,7 @@ public class PowerGrow implements IPower<Location> {
@Override @Override
public void preApply(EntityPlayer player) { public void preApply(EntityPlayer player) {
IPower.spawnParticles(com.minelittlepony.unicopia.Unicopia.MAGIC_PARTICLE, player, 1); IPower.spawnParticles(Unicopia.MAGIC_PARTICLE, player, 1);
} }
@Override @Override

View file

@ -25,9 +25,9 @@ public class PowerMagic implements IPower<PowerMagic.Magic> {
@Override @Override
public int getWarmupTime(IPlayer player) { public int getWarmupTime(IPlayer player) {
if (player.hasEffect() && "shield".contentEquals(player.getEffect().getName())) { // if (player.hasEffect() && "shield".contentEquals(player.getEffect().getName())) {
return 0; // return 0;
} // }
return 20; return 20;
} }

View file

@ -6,6 +6,7 @@ import java.util.Map.Entry;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
import com.google.gson.annotations.Expose;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.UItems; import com.minelittlepony.unicopia.UItems;
import com.minelittlepony.unicopia.client.particle.Particles; import com.minelittlepony.unicopia.client.particle.Particles;
@ -95,7 +96,11 @@ public class PowerStomp implements IPower<PowerStomp.Data> {
@Override @Override
public void apply(EntityPlayer player, Data data) { public void apply(EntityPlayer player, Data data) {
double rad = 4; double rad = 4;
data.hitType = 1;
if (data.hitType == 0) { if (data.hitType == 0) {
player.addVelocity(0, -6, 0); player.addVelocity(0, -6, 0);
BlockPos pos = player.getPosition(); BlockPos pos = player.getPosition();
@ -115,22 +120,28 @@ public class PowerStomp implements IPower<PowerStomp.Data> {
i.attackEntityFrom(damage, amount); i.attackEntityFrom(damage, amount);
} }
} }
Iterable<BlockPos> area = BlockPos.getAllInBox(pos.add(-rad, -rad, -rad), pos.add(rad, rad, rad)); Iterable<BlockPos> area = BlockPos.getAllInBox(pos.add(-rad, -rad, -rad), pos.add(rad, rad, rad));
for (BlockPos i : area) { for (BlockPos i : area) {
if (i.distanceSqToCenter(player.posX, player.posY, player.posZ) <= rad*rad) { if (i.distanceSqToCenter(player.posX, player.posY, player.posZ) <= rad*rad) {
spawnEffect(player.world, i); spawnEffect(player.world, i);
} }
} }
for (int i = 1; i < 202; i+= 2) { for (int i = 1; i < 202; i+= 2) {
spawnParticleRing(player, i); spawnParticleRing(player, i);
} }
IPower.takeFromPlayer(player, 4); IPower.takeFromPlayer(player, 4);
} else if (data.hitType == 1) { } else if (data.hitType == 1) {
if (player.world.rand.nextInt(30) == 0) { if (player.world.rand.nextInt(30) == 0) {
removeTree(player.world, new BlockPos(data.x, data.y, data.z)); removeTree(player.world, new BlockPos(data.x, data.y, data.z));
} else { } else {
dropApples(player.world, new BlockPos(data.x, data.y, data.z)); dropApples(player.world, new BlockPos(data.x, data.y, data.z));
} }
IPower.takeFromPlayer(player, 1); IPower.takeFromPlayer(player, 1);
} }
} }
@ -394,7 +405,7 @@ public class PowerStomp implements IPower<PowerStomp.Data> {
} }
protected static class Data extends Location { protected static class Data extends Location {
@Expose
public int hitType; public int hitType;
public Data(int x, int y, int z, int hit) { public Data(int x, int y, int z, int hit) {

View file

@ -107,15 +107,17 @@ public class PowerTeleport implements IPower<Location> {
@Override @Override
public void apply(EntityPlayer player, Location data) { public void apply(EntityPlayer player, Location data) {
player.world.playSound(player.posX, player.posY, player.posZ, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, 1, 1, true); player.world.playSound(null, player.posX, player.posY, player.posZ, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, 1, 1);
double distance = player.getDistance(data.x, data.y, data.z) / 10; double distance = player.getDistance(data.x, data.y, data.z) / 10;
player.dismountRidingEntity(); player.dismountRidingEntity();
player.setPositionAndUpdate(data.x + (player.posX - Math.floor(player.posX)), data.y, data.z + (player.posZ - Math.floor(player.posZ))); player.setPositionAndUpdate(data.x + (player.posX - Math.floor(player.posX)), data.y, data.z + (player.posZ - Math.floor(player.posZ)));
IPower.takeFromPlayer(player, distance); IPower.takeFromPlayer(player, distance);
player.fallDistance /= distance; player.fallDistance /= distance;
player.world.playSound(data.x, data.y, data.z, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, 1, 1, true);
player.world.playSound(null, data.x, data.y, data.z, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, 1, 1);
} }
private boolean enterable(World w, BlockPos pos) { private boolean enterable(World w, BlockPos pos) {
@ -141,12 +143,11 @@ public class PowerTeleport implements IPower<Location> {
@Override @Override
public void preApply(EntityPlayer player) { public void preApply(EntityPlayer player) {
postApply(player); IPower.spawnParticles(Unicopia.MAGIC_PARTICLE, player, 5);
} }
@Override @Override
public void postApply(EntityPlayer player) { public void postApply(EntityPlayer player) {
IPower.spawnParticles(Unicopia.MAGIC_PARTICLE, player, 1); IPower.spawnParticles(Unicopia.MAGIC_PARTICLE, player, 5);
} }
} }

View file

@ -12,7 +12,7 @@ public interface ICaster<E extends EntityLivingBase> {
return getEffect() != null; return getEffect() != null;
} }
default void setOwner(EntityLivingBase owner) { default void setOwner(E owner) {
} }

View file

@ -16,9 +16,6 @@ public class SpellRegistry {
private final Map<String, Callable<IMagicEffect>> factories = new HashMap<>(); private final Map<String, Callable<IMagicEffect>> factories = new HashMap<>();
private SpellRegistry() { private SpellRegistry() {
}
public void init() {
registerSpell("shield", SpellShield::new); registerSpell("shield", SpellShield::new);
} }

View file

@ -1,7 +1,6 @@
package com.minelittlepony.unicopia.spell; package com.minelittlepony.unicopia.spell;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.UClient;
import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.client.particle.Particles; import com.minelittlepony.unicopia.client.particle.Particles;
import com.minelittlepony.unicopia.player.PlayerSpeciesList; import com.minelittlepony.unicopia.player.PlayerSpeciesList;
@ -46,37 +45,37 @@ public class SpellShield extends AbstractSpell {
@Override @Override
public void render(Entity source) { public void render(Entity source) {
if (UClient.isClientSide()) { spawnParticles(source.getEntityWorld(), source.posX, source.posY, source.posZ, 4 + (strength * 2));
spawnParticles(source.getEntityWorld(), source.posX, source.posY, source.posZ, 4 + (strength * 2));
}
} }
public void renderAt(ICaster<?> source, World w, double x, double y, double z, int level) { public void renderAt(ICaster<?> source, World w, double x, double y, double z, int level) {
if (UClient.isClientSide()) { if (w.rand.nextInt(4 + level * 4) == 0) {
if (w.rand.nextInt(4 + level * 4) == 0) { spawnParticles(w, x, y, z, 4 + (level * 2));
spawnParticles(w, x, y, z, 4 + (level * 2));
}
} }
} }
protected void spawnParticles(World w, double x, double y, double z, int strength) { protected void spawnParticles(World w, double x, double y, double z, int strength) {
IShape sphere = new Sphere(true, strength); IShape sphere = new Sphere(true, strength);
Vec3d pos = sphere.computePoint(w.rand); for (int i = 0; i < strength; i++) {
Particles.instance().spawnParticle(Unicopia.MAGIC_PARTICLE, false, Vec3d pos = sphere.computePoint(w.rand);
pos.x + x, pos.y + y, pos.z + z, Particles.instance().spawnParticle(Unicopia.MAGIC_PARTICLE, false,
0, 0, 0); pos.x + x, pos.y + y, pos.z + z,
0, 0, 0);
}
} }
@Override @Override
public boolean update(Entity source) { public boolean update(Entity source) {
applyEntities(null, source, source.getEntityWorld(), source.posX, source.posY, source.posZ, strength); applyEntities(null, source, source.getEntityWorld(), source.posX, source.posY, source.posZ, strength);
if (source.getEntityWorld().getWorldTime() % 50 == 0) { if (source.getEntityWorld().getWorldTime() % 50 == 0) {
double radius = 4 + (strength * 2); double radius = 4 + (strength * 2);
if (!IPower.takeFromPlayer((EntityPlayer)source, radius/4)) { if (!IPower.takeFromPlayer((EntityPlayer)source, radius/4)) {
setDead(); setDead();
} }
} }
return !isDead; return !isDead;
} }
@ -90,7 +89,7 @@ public class SpellShield extends AbstractSpell {
AxisAlignedBB bb = new AxisAlignedBB(x - radius, y - radius, z - radius, x + radius, y + radius, z + radius); AxisAlignedBB bb = new AxisAlignedBB(x - radius, y - radius, z - radius, x + radius, y + radius, z + radius);
for (Entity i : w.getEntitiesWithinAABBExcludingEntity(source.getEntity(), bb)) { for (Entity i : w.getEntitiesWithinAABBExcludingEntity(source == null ? null : source.getEntity(), bb)) {
if ((!i.equals(owner) if ((!i.equals(owner)
|| (owner instanceof EntityPlayer || (owner instanceof EntityPlayer
&& !PlayerSpeciesList.instance().getPlayer((EntityPlayer)owner).getPlayerSpecies().canCast()))) { && !PlayerSpeciesList.instance().getPlayer((EntityPlayer)owner).getPlayerSpecies().canCast()))) {

View file

@ -3,6 +3,7 @@ package come.minelittlepony.unicopia.forgebullshit;
import com.minelittlepony.unicopia.player.IPlayer; import com.minelittlepony.unicopia.player.IPlayer;
import com.minelittlepony.unicopia.player.PlayerSpeciesList; import com.minelittlepony.unicopia.player.PlayerSpeciesList;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.CapabilityInject;
@ -16,6 +17,10 @@ class DefaultPlayerCapabilitiesProxyContainer implements IPlayerCapabilitiesProx
@Override @Override
public IPlayer getPlayer() { public IPlayer getPlayer() {
if (player == null) {
player = PlayerSpeciesList.instance().emptyPlayer(null);
}
return player; return player;
} }
@ -25,18 +30,20 @@ class DefaultPlayerCapabilitiesProxyContainer implements IPlayerCapabilitiesProx
} }
public void writeToNBT(NBTTagCompound compound) { public void writeToNBT(NBTTagCompound compound) {
if (player == null) { getPlayer().writeToNBT(compound);
return;
}
player.writeToNBT(compound);
} }
public void readFromNBT(NBTTagCompound compound) { public void readFromNBT(NBTTagCompound compound) {
if (player == null) { getPlayer().readFromNBT(compound);
player = PlayerSpeciesList.instance().emptyPlayer(null); }
public IPlayerCapabilitiesProxyContainer withEntity(EntityPlayer player) {
if (this.player == null) {
this.player = PlayerSpeciesList.instance().emptyPlayer(player);
} else {
getPlayer().setOwner(player);
} }
player.readFromNBT(compound); return this;
} }
} }

View file

@ -17,7 +17,7 @@ public class FBS {
public static void attach(AttachCapabilitiesEvent<Entity> event) { public static void attach(AttachCapabilitiesEvent<Entity> event) {
if (event.getObject() instanceof EntityPlayer) { if (event.getObject() instanceof EntityPlayer) {
event.addCapability(new ResourceLocation("unicopia", "race"), new Provider()); event.addCapability(new ResourceLocation("unicopia", "race"), new Provider((EntityPlayer)event.getObject()));
} }
} }
@ -30,12 +30,12 @@ public class FBS {
final IPlayerCapabilitiesProxyContainer clone = of(event.getEntity()); final IPlayerCapabilitiesProxyContainer clone = of(event.getEntity());
clone.setPlayer(original.getPlayer()); clone.getPlayer().copyFrom(original.getPlayer());
} }
public static IPlayerCapabilitiesProxyContainer of(Entity entity) { public static IPlayerCapabilitiesProxyContainer of(Entity entity) {
if (entity.hasCapability(DefaultPlayerCapabilitiesProxyContainer.CAPABILITY, EnumFacing.DOWN)) { if (entity.hasCapability(DefaultPlayerCapabilitiesProxyContainer.CAPABILITY, EnumFacing.DOWN)) {
return entity.getCapability(DefaultPlayerCapabilitiesProxyContainer.CAPABILITY, EnumFacing.DOWN); return entity.getCapability(DefaultPlayerCapabilitiesProxyContainer.CAPABILITY, EnumFacing.DOWN).withEntity((EntityPlayer)entity);
} }
return null; return null;

View file

@ -3,8 +3,12 @@ package come.minelittlepony.unicopia.forgebullshit;
import com.minelittlepony.unicopia.InbtSerialisable; import com.minelittlepony.unicopia.InbtSerialisable;
import com.minelittlepony.unicopia.player.IPlayer; import com.minelittlepony.unicopia.player.IPlayer;
import net.minecraft.entity.player.EntityPlayer;
public interface IPlayerCapabilitiesProxyContainer extends InbtSerialisable { public interface IPlayerCapabilitiesProxyContainer extends InbtSerialisable {
IPlayer getPlayer(); IPlayer getPlayer();
void setPlayer(IPlayer player); void setPlayer(IPlayer player);
IPlayerCapabilitiesProxyContainer withEntity(EntityPlayer player);
} }

View file

@ -0,0 +1,35 @@
package come.minelittlepony.unicopia.forgebullshit;
import net.minecraft.util.ResourceLocation;
public class NoNameSpacedResource extends ResourceLocation {
public static ResourceLocation[] ofAll(String...strings) {
ResourceLocation[] resources = new ResourceLocation[strings.length];
for (int i = 0; i < strings.length; i++) {
resources[i] = new NoNameSpacedResource(strings[i]);
}
return resources;
}
public static ResourceLocation[] ofAllDomained(String domain, String...strings) {
ResourceLocation[] resources = new ResourceLocation[strings.length];
for (int i = 0; i < strings.length; i++) {
resources[i] = new ResourceLocation(domain, strings[i]);
}
return resources;
}
public NoNameSpacedResource(String path) {
super(path);
}
@Override
public String toString() {
return getPath();
}
}

View file

@ -1,5 +1,6 @@
package come.minelittlepony.unicopia.forgebullshit; package come.minelittlepony.unicopia.forgebullshit;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
@ -8,6 +9,12 @@ import net.minecraftforge.common.capabilities.ICapabilitySerializable;
class Provider implements ICapabilitySerializable<NBTTagCompound> { class Provider implements ICapabilitySerializable<NBTTagCompound> {
DefaultPlayerCapabilitiesProxyContainer instance = (DefaultPlayerCapabilitiesProxyContainer) DefaultPlayerCapabilitiesProxyContainer.CAPABILITY.getDefaultInstance(); DefaultPlayerCapabilitiesProxyContainer instance = (DefaultPlayerCapabilitiesProxyContainer) DefaultPlayerCapabilitiesProxyContainer.CAPABILITY.getDefaultInstance();
private final EntityPlayer entity;
Provider(EntityPlayer entity) {
this.entity = entity;
}
@Override @Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing) { public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
return capability == DefaultPlayerCapabilitiesProxyContainer.CAPABILITY; return capability == DefaultPlayerCapabilitiesProxyContainer.CAPABILITY;
@ -16,7 +23,7 @@ class Provider implements ICapabilitySerializable<NBTTagCompound> {
@Override @Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing) { public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
if (hasCapability(capability, facing)) { if (hasCapability(capability, facing)) {
return DefaultPlayerCapabilitiesProxyContainer.CAPABILITY.<T>cast(instance); return DefaultPlayerCapabilitiesProxyContainer.CAPABILITY.<T>cast(instance.withEntity(entity));
} }
return null; return null;
@ -25,12 +32,12 @@ class Provider implements ICapabilitySerializable<NBTTagCompound> {
@Override @Override
public NBTTagCompound serializeNBT() { public NBTTagCompound serializeNBT() {
return (NBTTagCompound) DefaultPlayerCapabilitiesProxyContainer.CAPABILITY.getStorage() return (NBTTagCompound) DefaultPlayerCapabilitiesProxyContainer.CAPABILITY.getStorage()
.writeNBT(DefaultPlayerCapabilitiesProxyContainer.CAPABILITY, instance, null); .writeNBT(DefaultPlayerCapabilitiesProxyContainer.CAPABILITY, instance.withEntity(entity), null);
} }
@Override @Override
public void deserializeNBT(NBTTagCompound nbt) { public void deserializeNBT(NBTTagCompound nbt) {
DefaultPlayerCapabilitiesProxyContainer.CAPABILITY.getStorage() DefaultPlayerCapabilitiesProxyContainer.CAPABILITY.getStorage()
.readNBT(DefaultPlayerCapabilitiesProxyContainer.CAPABILITY, instance, null, nbt); .readNBT(DefaultPlayerCapabilitiesProxyContainer.CAPABILITY, instance.withEntity(entity), null, nbt);
} }
} }

View file

@ -10,11 +10,7 @@ class Storage implements IStorage<IPlayerCapabilitiesProxyContainer> {
@Override @Override
public NBTBase writeNBT(Capability<IPlayerCapabilitiesProxyContainer> capability, IPlayerCapabilitiesProxyContainer instance, EnumFacing side) { public NBTBase writeNBT(Capability<IPlayerCapabilitiesProxyContainer> capability, IPlayerCapabilitiesProxyContainer instance, EnumFacing side) {
NBTTagCompound compound = new NBTTagCompound(); return instance.toNBT();
instance.writeToNBT(compound);
return compound;
} }
@Override @Override

View file

@ -50,6 +50,13 @@ commands.race.tell.other.alt=%s is an
commands.decloud.success=%s clouds removed commands.decloud.success=%s clouds removed
commands.decloud.usage=/decloud <all> commands.decloud.usage=/decloud <all>
unicopia.race.human=Human
unicopia.race.earth=Earth Pony
unicopia.race.unicorn=Unicorn
unicopia.race.pegasus=Pegasus
unicopia.race.alicorn=Alicorn
unicopia.race.changeling=Changeling
unicopia.category.name=Pony Abilities unicopia.category.name=Pony Abilities
unicopia.power.grow=Earth Pony (Primary) unicopia.power.grow=Earth Pony (Primary)

View file

@ -0,0 +1,6 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "minecraft:items/apple"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "unicopia:items/apple_green"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "unicopia:items/apple_rotten"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "unicopia:items/apple_sweet"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "unicopia:items/apple_zap"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "unicopia:items/apple_zap_cooked"
}
}

View file

@ -1,18 +0,0 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "unicopia:items/cloud"
},
"display": {
"thirdperson": {
"rotation": [ -90, 0, 0 ],
"translation": [ 0, 1, -3 ],
"scale": [ 0.55, 0.55, 0.55 ]
},
"firstperson": {
"rotation": [ 0, -135, 25 ],
"translation": [ 0, 4, 2 ],
"scale": [ 1.7, 1.7, 1.7 ]
}
}
}

View file

@ -1,27 +0,0 @@
{
"textures": {
"top": "unicopia:blocks/cloud_normal",
"bottom": "unicopia:blocks/cloud_normal",
"side": "unicopia:blocks/cloud_normal"
},
"elements": [
{ "from": [ 0, 0, 0 ],
"to": [ 16, 8, 16 ],
"faces": {
"down": { "uv": [ 1, 1, 15, 15 ], "texture": "#bottom", "cullface": "down" },
"up": { "uv": [ 1, 1, 15, 15 ], "texture": "#top" },
"north": { "uv": [ 0, 4, 16, 12 ], "texture": "#side", "cullface": "north" },
"south": { "uv": [ 0, 4, 16, 12 ], "texture": "#side", "cullface": "south" },
"west": { "uv": [ 0, 4, 16, 12 ], "texture": "#side", "cullface": "west" },
"east": { "uv": [ 0, 4, 16, 12 ], "texture": "#side", "cullface": "east" }
}
}
],
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
}
}
}

View file

@ -1,18 +0,0 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "unicopia:items/cloud_matter"
},
"display": {
"thirdperson": {
"rotation": [ -90, 0, 0 ],
"translation": [ 0, 1, -3 ],
"scale": [ 0.55, 0.55, 0.55 ]
},
"firstperson": {
"rotation": [ 0, -135, 25 ],
"translation": [ 0, 4, 2 ],
"scale": [ 1.7, 1.7, 1.7 ]
}
}
}

View file

@ -1,16 +0,0 @@
{
"parent": "unicopia:item/cloud_large",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.25, 0.25, 0.25 ]
},
"firstperson": {
"scale": [ 0.7, 0.7, 0.7 ]
},
"gui": {
"scale": [ 0.7, 0.7, 0.7 ]
}
}
}

View file

@ -1,16 +0,0 @@
{
"parent": "unicopia:item/cloud_large",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.15, 0.15, 0.15 ]
},
"firstperson": {
"scale": [ 0.5, 0.5, 0.5 ]
},
"gui": {
"scale": [ 0.5, 0.5, 0.5 ]
}
}
}

View file

@ -1,13 +0,0 @@
{
"parent": "unicopia:block/cloud_stairs",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
},
"gui": {
"rotation": [ 0, 180, 0 ]
}
}
}

View file

@ -1,10 +0,0 @@
{
"parent": "unicopia:block/enchanted_cloud",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
}
}
}

View file

@ -1,10 +0,0 @@
{
"parent": "unicopia:block/half_slab_enchanted_cloud",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
}
}
}

View file

@ -1,10 +0,0 @@
{
"parent": "unicopia:block/normal_cloud",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
}
}
}

View file

@ -1,10 +0,0 @@
{
"parent": "unicopia:block/half_slab_normal_cloud",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
}
}
}

View file

@ -1,10 +0,0 @@
{
"parent": "unicopia:block/packed_cloud",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
}
}
}

View file

@ -1,10 +0,0 @@
{
"parent": "unicopia:block/half_slab_packed_cloud",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
}
}
}

View file

@ -1,19 +0,0 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "unicopia:items/gem",
"layer1": "unicopia:items/gem_overlay"
},
"display": {
"thirdperson": {
"rotation": [ -90, 0, 0 ],
"translation": [ 0, 1, -3 ],
"scale": [ 0.55, 0.55, 0.55 ]
},
"firstperson": {
"rotation": [ 0, -135, 25 ],
"translation": [ 0, 4, 2 ],
"scale": [ 1.7, 1.7, 1.7 ]
}
}
}

View file

@ -1,18 +0,0 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "unicopia:items/spellbook"
},
"display": {
"thirdperson": {
"rotation": [ -90, 0, 0 ],
"translation": [ 0, 1, -3 ],
"scale": [ 0.55, 0.55, 0.55 ]
},
"firstperson": {
"rotation": [ 0, -135, 25 ],
"translation": [ 0, 4, 2 ],
"scale": [ 1.7, 1.7, 1.7 ]
}
}
}