Add gem entities, improve networking code

This commit is contained in:
Sollace 2018-09-21 17:53:33 +02:00
parent f33b1e37b0
commit c9e912a378
34 changed files with 1390 additions and 99 deletions

View file

@ -0,0 +1,53 @@
package com.minelittlepony.render.model;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.ModelBase;
import org.lwjgl.opengl.GL11;
import com.minelittlepony.util.render.AbstractBoxRenderer;
import com.minelittlepony.util.render.Color;
public class GlowRenderer extends AbstractBoxRenderer<GlowRenderer> {
int tint;
float alpha = 1;
public GlowRenderer(ModelBase model, int x, int y) {
super(model, x, y);
}
public GlowRenderer setAlpha(float alpha) {
this.alpha = alpha;
return this;
}
public GlowRenderer setTint(int tint) {
this.tint = tint;
return this;
}
public void applyTint(float alpha) {
Color.glColor(tint, alpha);
}
@Override
public void createBox(float offX, float offY, float offZ, int width, int height, int depth, float scaleFactor, boolean mirrored) {
cubeList.add(new ModelGlow(this, textureOffsetX, textureOffsetY, offX, offY, offZ, width, height, depth, scaleFactor, alpha));
}
@Override
public void render(float scale) {
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
Minecraft.getMinecraft().entityRenderer.disableLightmap();
super.render(scale);
GL11.glPopAttrib();
}
@Override
protected GlowRenderer copySelf() {
return new GlowRenderer(baseModel, textureOffsetX, textureOffsetY);
}
}

View file

@ -0,0 +1,78 @@
package com.minelittlepony.render.model;
import net.minecraft.client.renderer.BufferBuilder;
import com.minelittlepony.util.render.Box;
import com.minelittlepony.util.render.Quad;
import com.minelittlepony.util.render.Vertex;
/**
* Like a normal box, but with the top narrowed a bit.
*/
public class ModelGlow extends Box<GlowRenderer> {
private final float alpha;
private Quad[] quadList;
public ModelGlow(GlowRenderer renderer, int texX, int texY, float xMin, float yMin, float zMin, int w, int h, int d, float scale, float alpha) {
super(renderer, texX, texY, xMin, yMin, zMin, w, h, d, scale);
this.alpha = alpha;
float xMax = xMin + w + scale;
float yMax = yMin + h + scale;
float zMax = zMin + d + scale;
xMin -= scale;
yMin -= scale;
zMin -= scale;
if (renderer.mirror) {
float v = xMax;
xMax = xMin;
xMin = v;
}
float tipInset = 0.4f;
float tipXmin = xMin + w * tipInset;
float tipZmin = zMin + d * tipInset;
float tipXMax = xMax - w * tipInset;
float tipZMax = zMax - d * tipInset;
// w:west e:east d:down u:up s:south n:north
Vertex wds = vert(tipXmin, yMin, tipZmin, 0, 0);
Vertex eds = vert(tipXMax, yMin, tipZmin, 0, 8);
Vertex eus = vert(xMax, yMax, zMin, 8, 8);
Vertex wus = vert(xMin, yMax, zMin, 8, 0);
Vertex wdn = vert(tipXmin, yMin, tipZMax, 0, 0);
Vertex edn = vert(tipXMax, yMin, tipZMax, 0, 8);
Vertex eun = vert(xMax, yMax, zMax, 8, 8);
Vertex wun = vert(xMin, yMax, zMax, 8, 0);
quadList = new Quad[] {
quad(texX + d + w, d, texY + d, h, edn, eds, eus, eun),
quad(texX, d, texY + d, h, wds, wdn, wun, wus),
quad(texX + d, w, texY, d, edn, wdn, wds, eds),
quad(texX + d + w, w, texY + d, -d, eus, wus, wun, eun),
quad(texX + d, w, texY + d, h, eds, wds, wus, eus),
quad(texX + d + w + d, w, texY + d, h, wdn, edn, eun, wun)
};
if (renderer.mirror) {
for (Quad i : quadList) {
i.flipFace();
}
}
}
@Override
public void render(BufferBuilder buffer, float scale) {
parent.applyTint(alpha);
for (Quad i : quadList) {
i.draw(buffer, scale);
}
}
}

View file

@ -0,0 +1,84 @@
package com.minelittlepony.render.model;
import net.minecraft.client.renderer.BufferBuilder;
import com.minelittlepony.util.render.Box;
import com.minelittlepony.util.render.Quad;
import com.minelittlepony.util.render.Vertex;
import javax.annotation.Nonnull;
public class ModelPlane extends Box<PlaneRenderer> {
private Quad quad;
public boolean hidden = false;
public ModelPlane(PlaneRenderer renderer, int textureX, int textureY, float xMin, float yMin, float zMin, int w, int h, int d, float scale, Plane face) {
super(renderer, textureX, textureY, xMin, yMin, zMin, w, h, d, scale, false);
float xMax = xMin + w + scale;
float yMax = yMin + h + scale;
float zMax = zMin + d + scale;
xMin -= scale;
yMin -= scale;
zMin -= scale;
if (renderer.mirror) {
float v = xMax;
xMax = xMin;
xMin = v;
}
if (renderer.mirrory) {
float v = yMax;
yMax = yMin;
yMin = v;
}
if (renderer.mirrorz) {
float v = zMax;
zMax = zMin;
zMin = v;
}
// w:west e:east d:down u:up s:south n:north
Vertex wds = vert(xMin, yMin, zMin, 0, 0);
Vertex eds = vert(xMax, yMin, zMin, 0, 8);
Vertex eus = vert(xMax, yMax, zMin, 8, 8);
Vertex wus = vert(xMin, yMax, zMin, 8, 0);
Vertex wdn = vert(xMin, yMin, zMax, 0, 0);
Vertex edn = vert(xMax, yMin, zMax, 0, 8);
Vertex eun = vert(xMax, yMax, zMax, 8, 8);
Vertex wun = vert(xMin, yMax, zMax, 8, 0);
if (face == Plane.EAST) {
quad = quad(textureX, d, textureY, h, edn, eds, eus, eun);
}
if (face == Plane.WEST) {
quad = quad(textureX, d, textureY, h, wds, wdn, wun, wus);
}
if (face == Plane.UP) {
quad = quad(textureX, w, textureY, d, edn, wdn, wds, eds);
}
if (face == Plane.DOWN) {
quad = quad(textureX, w, textureY, d, eus, wus, wun, eun);
}
if (face == Plane.SOUTH) {
quad = quad(textureX, w, textureY, h, eds, wds, wus, eus);
}
if (face == Plane.NORTH) {
quad = quad(textureX, w, textureY, h, wdn, edn, eun, wun);
}
if (renderer.mirror || renderer.mirrory || renderer.mirrorz) {
quad.flipFace();
}
}
@Override
public void render(@Nonnull BufferBuilder buffer, float scale) {
if (!hidden) quad.draw(buffer, scale);
}
}

View file

@ -0,0 +1,10 @@
package com.minelittlepony.render.model;
enum Plane {
NORTH,
SOUTH,
UP,
DOWN,
EAST,
WEST
}

View file

@ -0,0 +1,69 @@
package com.minelittlepony.render.model;
import net.minecraft.client.model.ModelBase;
import com.minelittlepony.util.render.AbstractBoxRenderer;
public class PlaneRenderer extends AbstractBoxRenderer<PlaneRenderer> {
public boolean mirrory, mirrorz;
public PlaneRenderer(ModelBase model) {
super(model);
}
public PlaneRenderer(ModelBase model, int x, int y) {
super(model, x, y);
}
/**
* Flips the Z bit. Any calls to add a plane will be mirrored until this is called again.
*/
public PlaneRenderer flipZ() {
mirrorz = !mirrorz;
return this;
}
/**
* Flips the Y bit. Any calls to add a plane will be mirrored until this is called again.
*/
public PlaneRenderer flipY() {
mirrory = !mirrory;
return this;
}
@Override
protected PlaneRenderer copySelf() {
return new PlaneRenderer(baseModel, textureOffsetX, textureOffsetY);
}
private PlaneRenderer addPlane(float offX, float offY, float offZ, int width, int height, int depth, float scale, Plane face) {
cubeList.add(new ModelPlane(this, textureOffsetX, textureOffsetY, modelOffsetX + offX, modelOffsetY + offY, modelOffsetZ + offZ, width, height, depth, scale, face));
return this;
}
public PlaneRenderer top(float offX, float offY, float offZ, int width, int depth, float scale) {
return addPlane(offX, offY, offZ, width, 0, depth, scale, Plane.UP);
}
public PlaneRenderer bottom(float offX, float offY, float offZ, int width, int depth, float scale) {
return addPlane(offX, offY, offZ, width, 0, depth, scale, Plane.DOWN);
}
public PlaneRenderer west(float offX, float offY, float offZ, int height, int depth, float scale) {
return addPlane(offX, offY, offZ, 0, height, depth, scale, Plane.WEST);
}
public PlaneRenderer east(float offX, float offY, float offZ, int height, int depth, float scale) {
return addPlane(offX, offY, offZ, 0, height, depth, scale, Plane.EAST);
}
public PlaneRenderer north(float offX, float offY, float offZ, int width, int height, float scale) {
return addPlane(offX, offY, offZ - scale * 2, width, height, 0, scale, Plane.NORTH);
}
public PlaneRenderer south(float offX, float offY, float offZ, int width, int height, float scale) {
return addPlane(offX, offY, offZ + scale * 2, width, height, 0, scale, Plane.SOUTH);
}
}

View file

@ -0,0 +1,21 @@
package com.minelittlepony.render.model;
import net.minecraft.client.model.ModelBase;
import com.minelittlepony.util.render.AbstractBoxRenderer;
public class PonyRenderer extends AbstractBoxRenderer<PonyRenderer> {
public PonyRenderer(ModelBase model) {
super(model);
}
public PonyRenderer(ModelBase model, int texX, int texY) {
super(model, texX, texY);
}
@Override
protected PonyRenderer copySelf() {
return new PonyRenderer(baseModel, textureOffsetX, textureOffsetY);
}
}

View file

@ -0,0 +1,7 @@
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
package com.minelittlepony.render.model;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View file

@ -0,0 +1,212 @@
package com.minelittlepony.util.render;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelBox;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.client.model.TextureOffset;
@SuppressWarnings("unchecked")
public abstract class AbstractBoxRenderer<T extends AbstractBoxRenderer<T>> extends ModelRenderer {
protected final ModelBase baseModel;
protected int textureOffsetX;
protected int textureOffsetY;
protected float modelOffsetX;
protected float modelOffsetY;
protected float modelOffsetZ;
public AbstractBoxRenderer(ModelBase model) {
super(model);
baseModel = model;
}
public AbstractBoxRenderer(ModelBase model, int texX, int texY) {
super(model, texX, texY);
baseModel = model;
}
/**
* Called to create a new instance of this renderer (used for child renderers)
*/
protected abstract T copySelf();
@Override
public T setTextureOffset(int x, int y) {
this.textureOffsetX = x;
this.textureOffsetY = y;
super.setTextureOffset(x, y);
return (T) this;
}
/**
* Flips the mirror flag. All faces are mirrored until this is called again.
*/
public T flip() {
return mirror(!mirror);
}
public T mirror(boolean m) {
mirror = m;
return (T) this;
}
/**
* Sets the texture offset
*/
public T tex(int x, int y) {
return setTextureOffset(x, y);
}
/**
* Sets the texture size for this renderer.
*/
public T size(int w, int h) {
return (T) setTextureSize(w, h);
}
/**
* Positions this model in space.
*/
public T at(float x, float y, float z) {
return (T)at(this, x, y, z);
}
/**
* Sets an offset to be used on all shapes and children created through this renderer.
*/
public T offset(float x, float y, float z) {
modelOffsetX = x;
modelOffsetY = y;
modelOffsetZ = z;
return (T) this;
}
/**
* Adjusts the rotation center of the given renderer by the given amounts in each direction.
*/
public static void shiftRotationPoint(ModelRenderer renderer, float x, float y, float z) {
renderer.rotationPointX += x;
renderer.rotationPointY += y;
renderer.rotationPointZ += z;
}
/**
* Sets this renderer's rotation angles.
*/
public T rotate(float x, float y, float z) {
rotateAngleX = x;
rotateAngleY = y;
rotateAngleZ = z;
return (T) this;
}
/**
* Positions a given model in space by setting its offset values divided
* by 16 to account for scaling applied inside the model.
*/
public static <T extends ModelRenderer> T at(T renderer, float x, float y, float z) {
renderer.offsetX = x / 16;
renderer.offsetY = y / 16;
renderer.offsetZ = z / 16;
return renderer;
}
/**
* Rotates this model to align itself with the angles of another.
*/
public void rotateTo(ModelRenderer other) {
rotate(other.rotateAngleX, other.rotateAngleY, other.rotateAngleZ);
}
/**
* Shifts this model to align its center with the center of another.
*/
public T rotateAt(ModelRenderer other) {
return around(other.rotationPointX, other.rotationPointY, other.rotationPointZ);
}
/**
* Sets the rotation point.
*/
public T around(float x, float y, float z) {
setRotationPoint(x, y, z);
return (T) this;
}
/**
* Gets or creates a new child model based on its unique index.
* New children will be of the same type and inherit the same textures and offsets of the original.
*/
public T child(int index) {
if (childModels == null || index >= childModels.size()) {
return child();
}
return (T)childModels.get(index);
}
/**
* Returns a brand new child under this renderer.
*/
public T child() {
T copy = copySelf();
child(copy.offset(modelOffsetX, modelOffsetY, modelOffsetZ));
copy.textureHeight = textureHeight;
copy.textureWidth = textureWidth;
return copy;
}
/**
* Adds a new child renderer and returns itself for chaining.
*/
public <K extends ModelRenderer> T child(K child) {
addChild(child);
return (T)this;
}
@Override
public T addBox(String partName, float offX, float offY, float offZ, int width, int height, int depth) {
partName = boxName + "." + partName;
TextureOffset tex = baseModel.getTextureOffset(partName);
setTextureOffset(tex.textureOffsetX, tex.textureOffsetY).addBox(offX, offY, offZ, width, height, depth);
cubeList.get(cubeList.size() - 1).setBoxName(partName);
return (T) this;
}
@Override
public T addBox(float offX, float offY, float offZ, int width, int height, int depth) {
addBox(offX, offY, offZ, width, height, depth, 0);
return (T) this;
}
@Override
public T addBox(float offX, float offY, float offZ, int width, int height, int depth, boolean mirrored) {
addBox(offX, offY, offZ, width, height, depth, 0, mirrored);
return (T)this;
}
@Override
public void addBox(float offX, float offY, float offZ, int width, int height, int depth, float scaleFactor) {
addBox(offX, offY, offZ, width, height, depth, scaleFactor, mirror);
}
/**
* Creates a textured box.
*/
public T box(float offX, float offY, float offZ, int width, int height, int depth, float scaleFactor) {
return addBox(offX, offY, offZ, width, height, depth, scaleFactor, mirror);
}
private T addBox(float offX, float offY, float offZ, int width, int height, int depth, float scaleFactor, boolean mirrored) {
createBox(modelOffsetX + offX, modelOffsetY + offY, modelOffsetZ + offZ, width, height, depth, scaleFactor, mirrored);
return (T)this;
}
protected void createBox(float offX, float offY, float offZ, int width, int height, int depth, float scaleFactor, boolean mirrored) {
cubeList.add(new ModelBox(this, textureOffsetX, textureOffsetY, offX, offY, offZ, width, height, depth, scaleFactor, mirrored));
}
}

View file

@ -0,0 +1,36 @@
package com.minelittlepony.util.render;
import net.minecraft.client.model.ModelBox;
import net.minecraft.client.model.ModelRenderer;
public abstract class Box<T extends ModelRenderer> extends ModelBox {
protected final T parent;
public Box(T renderer, int texU, int texV, float x, float y, float z, int dx, int dy, int dz, float delta) {
super(renderer, texU, texV, x, y, z, dx, dy, dz, delta);
parent = renderer;
}
public Box(T renderer, int texU, int texV, float x, float y, float z, int dx, int dy, int dz, float delta, boolean mirror) {
super(renderer, texU, texV, x, y, z, dx, dy, dz, delta, mirror);
parent = renderer;
}
/**
* Creates a new vertex mapping the given (x, y, z) coordinates to a texture offset.
*/
protected Vertex vert(float x, float y, float z, int texX, int texY) {
return new Vertex(x, y, z, texX, texY);
}
/**
* Creates a new quad with the given spacial vertices.
*/
protected Quad quad(int startX, int width, int startY, int height, Vertex ...verts) {
return new Quad(verts,
startX, startY,
startX + width, startY + height,
parent.textureWidth, parent.textureHeight);
}
}

View file

@ -0,0 +1,21 @@
package com.minelittlepony.util.render;
import net.minecraft.client.renderer.GlStateManager;
public interface Color {
static float r(int color) {
return (color >> 16 & 255) / 255F;
}
static float g(int color) {
return (color >> 8 & 255) / 255F;
}
static float b(int color) {
return (color & 255) / 255F;
}
static void glColor(int color, float alpha) {
GlStateManager.color(Color.r(color), Color.g(color), Color.b(color), alpha);
}
}

View file

@ -0,0 +1,11 @@
package com.minelittlepony.util.render;
import net.minecraft.util.ResourceLocation;
/**
* A texture pool for generating multiple associated textures.
*/
@FunctionalInterface
public interface ITextureSupplier<T> {
ResourceLocation supplyTexture(T key);
}

View file

@ -0,0 +1,37 @@
package com.minelittlepony.util.render;
import net.minecraft.client.model.TexturedQuad;
public class Quad extends TexturedQuad {
Quad(Vertex[] vertices, int texcoordU1, int texcoordV1, int texcoordU2, int texcoordV2, float textureWidth, float textureHeight) {
super(vertices, texcoordU1, texcoordV1, texcoordU2, texcoordV2, textureWidth, textureHeight);
}
/**
* Reverses the order of the vertices belonging to this quad.
* Positions of the vertices stay the same but the order of rendering is reversed to go counter-clockwise.
*
* Reversal also affects the cross-product used to calculate texture orientation.
* <pre>
* Normal:
* 0-----1
* |\ |
* | \ |
* | \|
* 3-----2
*
* After flipFace:
*
* 3-----2
* | /|
* | / |
* |/ |
* 0-----1
* </pre>
*/
@Override
public void flipFace() {
super.flipFace();
}
}

View file

@ -0,0 +1,21 @@
package com.minelittlepony.util.render;
import net.minecraft.client.model.PositionTextureVertex;
public class Vertex extends PositionTextureVertex {
public Vertex(float x, float y, float z, float texX, float texY) {
super(x, y, z, texX, texY);
}
private Vertex(Vertex old, float texX, float texY) {
super(old, texX, texY);
}
// The MCP name is misleading.
// This is meant to return a COPY with the given texture position
@Override
public Vertex setTexturePosition(float texX, float texY) {
return new Vertex(this, texX, texY);
}
}

View file

@ -0,0 +1,7 @@
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
package com.minelittlepony.util.render;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View file

@ -0,0 +1,32 @@
package com.minelittlepony.render.model;
import java.util.ArrayList;
import java.util.List;
import com.minelittlepony.util.render.Box;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.client.model.PositionTextureVertex;
import net.minecraft.client.model.TexturedQuad;
import net.minecraft.client.renderer.BufferBuilder;
public class ModelQuads extends Box<ModelRenderer> {
public ModelQuads(ModelRenderer renderer) {
super(renderer, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}
protected List<TexturedQuad> quadList = new ArrayList<TexturedQuad>();
public ModelQuads addFace(PositionTextureVertex... vertices) {
quadList.add(new TexturedShape2d(vertices));
return this;
}
public void render(BufferBuilder renderer, float scale) {
for (TexturedQuad i : quadList) {
i.draw(renderer, scale);
}
}
}

View file

@ -0,0 +1,50 @@
package com.minelittlepony.render.model;
import net.minecraft.client.model.PositionTextureVertex;
import net.minecraft.client.model.TexturedQuad;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.math.Vec3d;
public class TexturedShape2d extends TexturedQuad {
protected boolean invertNormal;
public TexturedShape2d(PositionTextureVertex... vertices) {
super(vertices);
}
public TexturedShape2d(PositionTextureVertex[] vertices, int texcoordU1, int texcoordV1, int texcoordU2, int texcoordV2, float textureWidth, float textureHeight) {
super(vertices, texcoordU1, texcoordV1, texcoordU2, texcoordV2, textureWidth, textureHeight);
}
public TexturedShape2d setInvertNormal() {
invertNormal = true;
return this;
}
public void drawQuad(BufferBuilder renderer, float scale) {
Vec3d vec3d = vertexPositions[1].vector3D.subtractReverse(vertexPositions[0].vector3D);
Vec3d vec3d1 = vertexPositions[1].vector3D.subtractReverse(vertexPositions[2].vector3D);
Vec3d vec3d2 = vec3d1.crossProduct(vec3d).normalize();
float f = (float)vec3d2.x;
float f1 = (float)vec3d2.y;
float f2 = (float)vec3d2.z;
if (invertNormal) {
f = -f;
f1 = -f1;
f2 = -f2;
}
renderer.begin(7, DefaultVertexFormats.OLDMODEL_POSITION_TEX_NORMAL);
for (int i = 0; i < nVertices; ++i) {
PositionTextureVertex positiontexturevertex = vertexPositions[i];
renderer.pos(positiontexturevertex.vector3D.x * (double)scale, positiontexturevertex.vector3D.y * (double)scale, positiontexturevertex.vector3D.z * (double)scale).tex((double)positiontexturevertex.texturePositionX, (double)positiontexturevertex.texturePositionY).normal(f, f1, f2).endVertex();
}
Tessellator.getInstance().draw();
}
}

View file

@ -3,9 +3,12 @@ package com.minelittlepony.unicopia;
import com.minelittlepony.unicopia.entity.EntityCloud; import com.minelittlepony.unicopia.entity.EntityCloud;
import com.minelittlepony.unicopia.entity.EntityConstructionCloud; import com.minelittlepony.unicopia.entity.EntityConstructionCloud;
import com.minelittlepony.unicopia.entity.EntityRacingCloud; import com.minelittlepony.unicopia.entity.EntityRacingCloud;
import com.minelittlepony.unicopia.entity.EntitySpell;
import com.minelittlepony.unicopia.entity.EntityWildCloud; import com.minelittlepony.unicopia.entity.EntityWildCloud;
import com.minelittlepony.unicopia.render.RenderCloud; import com.minelittlepony.unicopia.render.RenderCloud;
import com.minelittlepony.unicopia.render.RenderGem;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList.EntityEggInfo; import net.minecraft.entity.EntityList.EntityEggInfo;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.client.registry.RenderingRegistry; import net.minecraftforge.fml.client.registry.RenderingRegistry;
@ -13,22 +16,29 @@ import net.minecraftforge.fml.common.registry.EntityEntry;
import net.minecraftforge.registries.IForgeRegistry; import net.minecraftforge.registries.IForgeRegistry;
public class UEntities { public class UEntities {
private static final int BRUSHES_ROYALBLUE = 4286945; private static final int BRUSHES_ROYALBLUE = 0x4169E1;
private static final int BRUSHES_CHARTREUSE = 8388352; private static final int BRUSHES_CHARTREUSE = 0x7FFF00;
static void init(IForgeRegistry<EntityEntry> registry) { static void init(IForgeRegistry<EntityEntry> registry) {
EntityEntry entry = new EntityEntry(EntityCloud.class, "cloud").setRegistryName(Unicopia.MODID, "cloud"); addEntity(registry, EntityCloud.class, "cloud", true, BRUSHES_ROYALBLUE, BRUSHES_CHARTREUSE);
addEntity(registry, EntityWildCloud.class, "wild_cloud", false, 0, 0);
addEntity(registry, EntityRacingCloud.class, "racing_cloud", false, 0, 0);
addEntity(registry, EntityConstructionCloud.class, "construction_cloud", false, 0, 0);
addEntity(registry, EntitySpell.class, "magic_spell", false, 0, 0);
}
entry.setEgg(new EntityEggInfo(new ResourceLocation("unicopia", "cloud"), BRUSHES_ROYALBLUE, BRUSHES_CHARTREUSE)); static <T extends Entity> void addEntity(IForgeRegistry<EntityEntry> registry, Class<T> type, String name, boolean egg, int a, int b) {
EntityEntry entry = new EntityEntry(type, name).setRegistryName(Unicopia.MODID, name);
if (egg) {
entry.setEgg(new EntityEggInfo(new ResourceLocation("unicopia", "cloud"), a, a));
}
registry.register(entry); registry.register(entry);
registry.register(new EntityEntry(EntityWildCloud.class, "wild_cloud").setRegistryName(Unicopia.MODID, "wild_cloud"));
registry.register(new EntityEntry(EntityRacingCloud.class, "racing_cloud").setRegistryName(Unicopia.MODID, "racing_cloud"));
registry.register(new EntityEntry(EntityConstructionCloud.class, "construction_cloud").setRegistryName(Unicopia.MODID, "construction_cloud"));
} }
static void preInit() { static void preInit() {
RenderingRegistry.registerEntityRenderingHandler(EntityCloud.class, manager -> new RenderCloud(manager)); RenderingRegistry.registerEntityRenderingHandler(EntityCloud.class, manager -> new RenderCloud(manager));
RenderingRegistry.registerEntityRenderingHandler(EntitySpell.class, manager -> new RenderGem(manager));
} }
} }

View file

@ -0,0 +1,308 @@
package com.minelittlepony.unicopia.entity;
import com.minelittlepony.unicopia.Predicates;
import com.minelittlepony.unicopia.UItems;
import com.minelittlepony.unicopia.item.ItemSpell;
import com.minelittlepony.unicopia.network.EffectSync;
import com.minelittlepony.unicopia.spell.ICaster;
import com.minelittlepony.unicopia.spell.IMagicEffect;
import com.minelittlepony.unicopia.spell.SpellRegistry;
import net.minecraft.block.SoundType;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.ItemStack;
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.util.math.BlockPos;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class EntitySpell extends EntityLiving implements IMagicals, ICaster<EntityLivingBase> {
private EntityLivingBase owner = null;
public float hoverStart;
private static final DataParameter<Integer> LEVEL = EntityDataManager
.createKey(EntitySpell.class, DataSerializers.VARINT);
private static final DataParameter<String> OWNER = EntityDataManager
.createKey(EntitySpell.class, DataSerializers.STRING);
private static final DataParameter<NBTTagCompound> EFFECT = EntityDataManager
.createKey(EntitySpell.class, DataSerializers.COMPOUND_TAG);
private final EffectSync<EntityLivingBase> effectDelegate = new EffectSync<>(this, EFFECT);
public EntitySpell(World w) {
super(w);
setSize(0.6f, 0.25f);
hoverStart = (float)(Math.random() * Math.PI * 2.0D);
setRenderDistanceWeight(getRenderDistanceWeight() + 1);
preventEntitySpawning = false;
enablePersistence();
}
public boolean isInRangeToRenderDist(double distance) {
return super.isInRangeToRenderDist(distance);
}
public void setEffect(IMagicEffect effect) {
effectDelegate.set(effect);
}
public IMagicEffect getEffect() {
return effectDelegate.get();
}
@Override
protected void entityInit() {
super.entityInit();
dataManager.register(LEVEL, 0);
dataManager.register(EFFECT, new NBTTagCompound());
dataManager.register(OWNER, "");
}
public ItemStack onPlayerMiddleClick(EntityPlayer player) {
ItemStack stack = new ItemStack(UItems.spell, 1);
SpellRegistry.instance().enchantStack(stack, getEffect().getName());
return stack;
}
@Override
protected boolean canTriggerWalking() {
return false;
}
@Override
public boolean isPushedByWater() {
return false;
}
@Override
public boolean canRenderOnFire() {
return false;
}
@Override
public void setOwner(EntityLivingBase owner) {
this.owner = owner;
setOwner(owner.getName());
}
protected void setOwner(String ownerName) {
if (ownerName != null && ownerName.length() != 0) {
dataManager.set(OWNER, ownerName);
}
}
protected String getOwnerName() {
String ownerName = dataManager.get(OWNER);
if (ownerName == null || ownerName.length() == 0) {
if (owner instanceof EntityPlayer) {
return owner.getName();
}
return "";
}
return ownerName;
}
@Override
public EntityLivingBase getOwner() {
if (owner == null) {
String ownerName = dataManager.get(OWNER);
if (ownerName != null && ownerName.length() > 0) {
owner = world.getPlayerEntityByName(ownerName);
}
}
return owner;
}
protected void displayTick() {
if (hasEffect()) {
getEffect().renderAt(this, world, posX, posY, posZ, getLevel());
}
}
@Override
public void onUpdate() {
if (world.isRemote) {
displayTick();
}
if (getEffect() == null) {
setDead();
} else {
if (getEffect().getDead()) {
setDead();
onDeath();
} else {
getEffect().updateAt(this, world, posX, posY, posZ, getLevel());
}
if (getEffect().allowAI()) {
super.onUpdate();
}
}
}
@Override
public void fall(float distance, float damageMultiplier) {
}
@Override
protected void updateFallState(double y, boolean onGround, IBlockState state, BlockPos pos) {
this.onGround = true;
//super.updateFallState(y, onGround = this.onGround = true, state, pos);
}
public boolean attackEntityFrom(DamageSource source, float amount) {
if (!world.isRemote) {
setDead();
onDeath();
}
return false;
}
protected void onDeath() {
SoundType sound = SoundType.STONE;
world.playSound(posX, posY, posZ, sound.getBreakSound(), SoundCategory.NEUTRAL, sound.getVolume(), sound.getPitch(), true);
if (world.getGameRules().getBoolean("doTileDrops")) {
int level = getLevel();
ItemStack stack = new ItemStack(UItems.spell, level + 1);
if (hasEffect()) {
SpellRegistry.instance().enchantStack(stack, getEffect().getName());
}
entityDropItem(stack, 0);
}
}
public void setDead() {
if (hasEffect()) {
getEffect().setDead();
}
super.setDead();
}
public int getLevel() {
return dataManager.get(LEVEL);
}
public void setLevel(int radius) {
dataManager.set(LEVEL, radius);
}
public boolean tryLevelUp(ItemStack stack) {
if (SpellRegistry.stackHasEnchantment(stack)) {
if (!getEffect().getName().equals(SpellRegistry.getKeyFromStack(stack))) {
return false;
}
increaseLevel();
if (!world.isRemote) {
if ((rand.nextFloat() * getLevel()) > 10 || overLevelCap()) {
world.createExplosion(this, posX, posY, posZ, getLevel()/2, true);
setDead();
return false;
}
}
playSound(SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, 0.1f, 1);
return true;
}
return false;
}
public EnumActionResult applyPlayerInteraction(EntityPlayer player, Vec3d vec, EnumHand hand) {
if (Predicates.MAGI.test(player)) {
ItemStack currentItem = player.getHeldItem(EnumHand.MAIN_HAND);
if (currentItem != null && currentItem.getItem() instanceof ItemSpell) {
tryLevelUp(currentItem);
if (!player.capabilities.isCreativeMode) {
currentItem.shrink(1);
if (currentItem.isEmpty()) {
player.renderBrokenItemStack(currentItem);
}
}
return EnumActionResult.SUCCESS;
}
}
return EnumActionResult.FAIL;
}
public void increaseLevel() {
setLevel(getLevel() + 1);
}
public boolean canLevelUp() {
int max = getEffect().getMaxLevel();
return max < 0 || getLevel() < max;
}
public boolean overLevelCap() {
int max = getEffect().getMaxLevel();
return max > 0 && getLevel() >= (max * 1.1);
}
public void decreaseLevel() {
int level = getLevel() - 1;
if (level < 0) level = 0;
setLevel(level);
}
@Override
public Entity getEntity() {
return this;
}
@Override
public void readEntityFromNBT(NBTTagCompound compound) {
super.readEntityFromNBT(compound);
setOwner(compound.getString("ownerName"));
setLevel(compound.getInteger("level"));
if (compound.hasKey("effect")) {
setEffect(SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect")));
}
}
@Override
public void writeEntityToNBT(NBTTagCompound compound) {
super.writeEntityToNBT(compound);
compound.setString("ownerName", getOwnerName());
compound.setInteger("level", getLevel());
if (hasEffect()) {
compound.setTag("effect", SpellRegistry.instance().serializeEffectToNBT(getEffect()));
}
}
}

View file

@ -0,0 +1,7 @@
package com.minelittlepony.unicopia.entity;
import net.minecraft.entity.passive.IAnimals;
public interface IMagicals extends IAnimals {
}

View file

@ -1,6 +1,7 @@
package com.minelittlepony.unicopia.item; package com.minelittlepony.unicopia.item;
import com.minelittlepony.unicopia.Predicates; import com.minelittlepony.unicopia.Predicates;
import com.minelittlepony.unicopia.entity.EntitySpell;
import com.minelittlepony.unicopia.spell.IMagicEffect; import com.minelittlepony.unicopia.spell.IMagicEffect;
import com.minelittlepony.unicopia.spell.IUseAction; import com.minelittlepony.unicopia.spell.IUseAction;
import com.minelittlepony.unicopia.spell.SpellCastResult; import com.minelittlepony.unicopia.spell.SpellCastResult;
@ -43,8 +44,9 @@ public class ItemSpell extends Item implements ICastable {
} }
if (dispenceResult == SpellCastResult.PLACE) { if (dispenceResult == SpellCastResult.PLACE) {
BlockPos pos = source.getBlockPos();
// castContainedSpell(source.getWorld(), pos.getX(), pos.getY(), pos.getZ(), stack, effect); castContainedSpell(source.getWorld(), pos, stack, effect);
stack.shrink(1); stack.shrink(1);
} }
@ -114,7 +116,7 @@ public class ItemSpell extends Item implements ICastable {
pos = pos.offset(side); pos = pos.offset(side);
if (result == SpellCastResult.PLACE) { if (result == SpellCastResult.PLACE) {
// castContainedSpell(world, pos.getX(), pos.getY(), pos.getZ(), stack, effect).setOwner(player); castContainedSpell(world, pos, stack, effect).setOwner(player);
} }
} }
@ -169,11 +171,13 @@ public class ItemSpell extends Item implements ICastable {
return result; return result;
} }
/* protected static EntitySpell castContainedSpell(World world, int x, int y, int z, ItemStack stack, IMagicEffect effect) { protected static EntitySpell castContainedSpell(World world, BlockPos pos, ItemStack stack, IMagicEffect effect) {
EntitySpell spell = new EntitySpell(world); EntitySpell spell = new EntitySpell(world);
spell.setEffect(effect); spell.setEffect(effect);
spell.setLocationAndAngles(x + 0.5, y + 0.5, z + 0.5, 0, 0); spell.setLocationAndAngles(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 0, 0);
world.spawnEntity(spell); world.spawnEntity(spell);
return spell; return spell;
} */ }
} }

View file

@ -0,0 +1,126 @@
package com.minelittlepony.unicopia.model;
import com.minelittlepony.render.model.ModelQuads;
import com.minelittlepony.unicopia.entity.EntitySpell;
import com.minelittlepony.unicopia.spell.SpellRegistry;
import com.minelittlepony.util.render.Color;
import com.minelittlepony.util.render.Vertex;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.MathHelper;
public class ModelGem extends ModelBase {
private ModelRenderer body;
public ModelGem() {
textureWidth = 256;
textureHeight = 256;
body = new ModelRenderer(this);
body.offsetY = 1.2f;
int size = 1;
body.cubeList.add(new ModelQuads(body).addFace(
new Vertex( size, 0, size, 0, 0.5f),
new Vertex(-size, 0, size, 0.25f, 0.25f),
new Vertex( 0, size * 2, 0, 0, 0.25f),
new Vertex( 0, size * 2, 0, 0, 0.25f)
).addFace(
new Vertex( size, 0, size, 0, 0.25f),
new Vertex(-size, 0, size, 0.25f, 0),
new Vertex( 0, -size * 2, 0, 0.25f, 0.25f),
new Vertex( 0, -size * 2, 0, 0.25f, 0.25f)
).addFace(
new Vertex(size, 0, -size, 0.25f, 0.5f),
new Vertex(size, 0, size, 0.5f, 0.25f),
new Vertex(0, size * 2, 0, 0.25f, 0.25f),
new Vertex(0, size * 2, 0, 0.25f, 0.25f)
).addFace(
new Vertex(size, 0, -size, 0.25f, 0.25f),
new Vertex(size, 0, size, 0.5f, 0),
new Vertex(0, -size * 2, 0, 0.5f, 0.25f),
new Vertex(0, -size * 2, 0, 0.5f, 0.25f)
).addFace(
new Vertex(-size, 0, -size, 0.5f, 0.5f),
new Vertex( size, 0, -size, 0.75f, 0.25f),
new Vertex( 0, size * 2, 0, 0.5f, 0.25f),
new Vertex( 0, size * 2, 0, 0.5f, 0.25f)
).addFace(
new Vertex(-size, 0, -size, 0.5f, 0.25f),
new Vertex( size, 0, -size, 0.75f, 0),
new Vertex( 0, -size * 2, 0, 0.75f, 0.25f),
new Vertex( 0, -size * 2, 0, 0.75f, 0.25f)
).addFace(
new Vertex(-size, 0, size, 0.75f, 0.5f),
new Vertex(-size, 0, -size, 1, 0.25f),
new Vertex( 0, size * 2, 0, 0.75f, 0.25f),
new Vertex( 0, size * 2, 0, 0.75f, 0.25f)
).addFace(
new Vertex(-size, 0, size, 0.75f, 0.25f),
new Vertex(-size, 0, -size, 1, 0),
new Vertex( 0, -size * 2, 0, 1, 0.25f),
new Vertex( 0, -size * 2, 0, 1, 0.25f)
));
}
@Override
public void render(Entity entity, float time, float walkSpeed, float stutter, float yaw, float pitch, float scale) {
GlStateManager.pushMatrix();
EntitySpell spell = (EntitySpell)entity;
float floatOffset = MathHelper.sin((spell.ticksExisted + stutter) / 10 + spell.hoverStart) / 10 + 0.1F;
GlStateManager.translate(0, floatOffset, 0);
floatOffset = (spell.ticksExisted + stutter) / 20;
if (spell.getLevel() > 0) {
floatOffset *= spell.getLevel() + 1;
}
floatOffset += spell.hoverStart;
floatOffset *= 180 / (float)Math.PI;
GlStateManager.rotate(floatOffset, 0, 1, 0);
body.render(scale);
GlStateManager.enableBlend();
GlStateManager.disableAlpha();
GlStateManager.blendFunc(1, 1);
setLightingConditionsBrightness(0xF0F0);
Color.glColor(SpellRegistry.instance().getSpellTint(spell.getEffect().getName()), 1);
GlStateManager.scale(1.2F, 1.2F, 1.2F);
GlStateManager.translate(0, -0.2F, 0);
body.render(scale);
setLightingConditionsBrightness(entity.getBrightnessForRender());
GlStateManager.disableBlend();
GlStateManager.enableAlpha();
GlStateManager.popMatrix();
}
private void setLightingConditionsBrightness(int brightness) {
int texX = brightness % 0x10000;
int texY = brightness / 0x10000;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, texX, texY);
}
@Override
public void setRotationAngles(float time, float walkSpeed, float stutter, float yaw, float pitch, float increment, Entity entity) {
}
}

View file

@ -0,0 +1,53 @@
package com.minelittlepony.unicopia.network;
import com.minelittlepony.unicopia.spell.ICaster;
import com.minelittlepony.unicopia.spell.IMagicEffect;
import com.minelittlepony.unicopia.spell.SpellRegistry;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
public class EffectSync<T extends EntityLivingBase> {
private IMagicEffect effect;
private final ICaster<T> owned;
private final DataParameter<NBTTagCompound> param;
public EffectSync(ICaster<T> owned, DataParameter<NBTTagCompound> param) {
this.owned = owned;
this.param = param;
}
public boolean has() {
return get() != null;
}
public IMagicEffect get() {
NBTTagCompound comp = owned.getEntity().getDataManager().get(param);
if (comp == null || !comp.hasKey("effect_id")) {
effect = null;
} else {
String id = comp.getString("effect_id");
if (effect == null || id != effect.getName()) {
effect = SpellRegistry.instance().createEffectFromNBT(comp);
} else {
effect.readFromNBT(comp);
}
}
return effect;
}
public void set(IMagicEffect effect) {
this.effect = effect;
if (effect == null) {
owned.getEntity().getDataManager().set(param, new NBTTagCompound());
} else {
owned.getEntity().getDataManager().set(param, SpellRegistry.instance().serializeEffectToNBT(effect));
}
}
}

View file

@ -32,13 +32,13 @@ public class MsgPlayerAbility implements IMessage, IMessageHandler<MsgPlayerAbil
private String abilityJson; private String abilityJson;
public MsgPlayerAbility(EntityPlayer player, IPower<?> power, IData data) { public MsgPlayerAbility(EntityPlayer player, IPower<?> power, IData data) {
senderId = player.getGameProfile().getId(); senderId = player.getUniqueID();
powerIdentifier = power.getKeyName(); powerIdentifier = power.getKeyName();
abilityJson = gson.toJson(data, power.getPackageType()); abilityJson = gson.toJson(data, power.getPackageType());
} }
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.getPlayerFromServer(senderId);
if (player == null) { if (player == null) {
return; return;
} }

View file

@ -15,7 +15,6 @@ import com.minelittlepony.unicopia.Race;
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.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
@ -32,12 +31,14 @@ public class MsgPlayerCapabilities implements IMessage, IMessageHandler<MsgPlaye
byte[] compoundTag; byte[] compoundTag;
public MsgPlayerCapabilities(Race race, EntityPlayer player) { public MsgPlayerCapabilities(Race race, EntityPlayer player) {
this(race, player.getGameProfile().getId()); newRace = race;
senderId = player.getUniqueID();
compoundTag = new byte[0];
} }
public MsgPlayerCapabilities(IPlayer player) { public MsgPlayerCapabilities(IPlayer player) {
newRace = player.getPlayerSpecies(); newRace = player.getPlayerSpecies();
senderId = player.getOwner().getGameProfile().getId(); senderId = player.getOwner().getUniqueID();
try (ByteArrayOutputStream bytes = new ByteArrayOutputStream()) { try (ByteArrayOutputStream bytes = new ByteArrayOutputStream()) {
NBTTagCompound nbt = player.toNBT(); NBTTagCompound nbt = player.toNBT();
@ -49,40 +50,27 @@ public class MsgPlayerCapabilities implements IMessage, IMessageHandler<MsgPlaye
} }
} }
public MsgPlayerCapabilities(Race race, UUID playerId) {
newRace = race;
senderId = playerId;
compoundTag = new byte[0];
}
@Override @Override
public void onPayload(MsgPlayerCapabilities message, IChannel channel) { public void onPayload(MsgPlayerCapabilities message, IChannel channel) {
EntityPlayer self = Minecraft.getMinecraft().player; EntityPlayer self = IPlayer.getPlayerFromClient(senderId);
UUID myid = self.getGameProfile().getId();
IPlayer player; if (self == null) {
if (senderId.equals(myid)) { System.out.println("[CLIENT] Player with id " + senderId + " was not found!");
player = PlayerSpeciesList.instance().getPlayer(self);
} else { } else {
EntityPlayer found = Minecraft.getMinecraft().world.getPlayerEntityByUUID(senderId); System.out.println("[CLIENT] Got capabilities for " + senderId);
IPlayer player = PlayerSpeciesList.instance().getPlayer(self);
if (found == null) { if (compoundTag.length > 0) {
System.out.println("Player with id " + senderId + " was not found!"); try (ByteArrayInputStream input = new ByteArrayInputStream(compoundTag)) {
return; NBTTagCompound nbt = CompressedStreamTools.read(new DataInputStream(input));
player.readFromNBT(nbt);
} catch (IOException e) {
}
} else {
player.setPlayerSpecies(newRace);
} }
player = PlayerSpeciesList.instance().getPlayer(found);
}
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

@ -25,6 +25,6 @@ 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);
channel.respond(new MsgPlayerCapabilities(player.getPlayerSpecies(), senderId), senderId); channel.respond(new MsgPlayerCapabilities(player), senderId);
} }
} }

View file

@ -4,6 +4,7 @@ import java.util.UUID;
import com.minelittlepony.unicopia.spell.ICaster; import com.minelittlepony.unicopia.spell.ICaster;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.FMLCommonHandler;
@ -34,16 +35,23 @@ public interface IPlayer extends ICaster<EntityPlayer>, IRaceContainer<EntityPla
void beforeUpdate(EntityPlayer entity); void beforeUpdate(EntityPlayer entity);
static EntityPlayer getPlayerEntity(UUID playerId) { static EntityPlayer getPlayerFromServer(UUID playerId) {
EntityPlayer player = FMLCommonHandler.instance().getMinecraftServerInstance().getPlayerList().getPlayerByUUID(playerId); Entity e = FMLCommonHandler.instance().getMinecraftServerInstance().getEntityFromUuid(playerId);
if (player == null) { if (e instanceof EntityPlayer) {
Entity e = FMLCommonHandler.instance().getMinecraftServerInstance().getEntityFromUuid(playerId); return (EntityPlayer)e;
if (e instanceof EntityPlayer) {
return (EntityPlayer)e;
}
} }
return player; return null;
}
static EntityPlayer getPlayerFromClient(UUID playerId) {
Minecraft mc = Minecraft.getMinecraft();
if (mc.player.getUniqueID().equals(playerId)) {
return mc.player;
}
return mc.world.getPlayerEntityByUUID(playerId);
} }
} }

View file

@ -1,13 +1,9 @@
package com.minelittlepony.unicopia.player; package com.minelittlepony.unicopia.player;
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.Unicopia;
import com.minelittlepony.unicopia.network.EffectSync;
import com.minelittlepony.unicopia.network.MsgPlayerCapabilities; 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;
@ -28,31 +24,33 @@ import net.minecraft.stats.StatList;
class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> { class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
private static final Logger logger = LogManager.getLogger();
private static final DataParameter<Integer> PLAYER_RACE = EntityDataManager private static final DataParameter<Integer> PLAYER_RACE = EntityDataManager
.createKey(EntityPlayer.class, DataSerializers.VARINT); .createKey(EntityPlayer.class, DataSerializers.VARINT);
private static final DataParameter<Float> EXERTION = EntityDataManager private static final DataParameter<Float> EXERTION = EntityDataManager
.createKey(EntityPlayer.class, DataSerializers.FLOAT); .createKey(EntityPlayer.class, DataSerializers.FLOAT);
private static final DataParameter<NBTTagCompound> EFFECT = EntityDataManager
.createKey(EntityPlayer.class, DataSerializers.COMPOUND_TAG);
private final PlayerAbilityDelegate powers = new PlayerAbilityDelegate(this); private final PlayerAbilityDelegate powers = new PlayerAbilityDelegate(this);
private final PlayerGravityDelegate gravity = new PlayerGravityDelegate(this); private final PlayerGravityDelegate gravity = new PlayerGravityDelegate(this);
private final PlayerAttributes attributes = new PlayerAttributes(); private final PlayerAttributes attributes = new PlayerAttributes();
private final EffectSync<EntityPlayer> effectDelegate = new EffectSync<>(this, EFFECT);
private float nextStepDistance = 1; private float nextStepDistance = 1;
private IMagicEffect effect;
private EntityPlayer entity; private EntityPlayer entity;
private UUID playerId;
PlayerCapabilities(EntityPlayer player) { PlayerCapabilities(EntityPlayer player) {
setOwner(player); setOwner(player);
player.getDataManager().register(PLAYER_RACE, Race.HUMAN.ordinal()); player.getDataManager().register(PLAYER_RACE, Race.HUMAN.ordinal());
player.getDataManager().register(EXERTION, 0F); player.getDataManager().register(EXERTION, 0F);
player.getDataManager().register(EFFECT, new NBTTagCompound());
} }
@Override @Override
@ -66,21 +64,19 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
@Override @Override
public void setPlayerSpecies(Race race) { public void setPlayerSpecies(Race race) {
EntityPlayer self = getOwner(); EntityPlayer player = getOwner();
if (!PlayerSpeciesList.instance().speciesPermitted(race, getOwner())) { if (!PlayerSpeciesList.instance().speciesPermitted(race, player)) {
race = Race.HUMAN; race = Race.HUMAN;
} }
if (self != null) { player.getDataManager().set(PLAYER_RACE, race.ordinal());
getOwner().getDataManager().set(PLAYER_RACE, race.ordinal());
self.capabilities.allowFlying = race.canFly(); player.capabilities.allowFlying = race.canFly();
gravity.updateFlightStat(self, self.capabilities.isFlying); gravity.updateFlightStat(player, player.capabilities.isFlying);
self.sendPlayerAbilities(); player.sendPlayerAbilities();
sendCapabilities(false); sendCapabilities(false);
}
} }
@Override @Override
@ -96,10 +92,12 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
@Override @Override
public void sendCapabilities(boolean full) { public void sendCapabilities(boolean full) {
if (!getOwner().getEntityWorld().isRemote) { if (!getOwner().getEntityWorld().isRemote) {
System.out.println("[SERVER] Sending player capabilities.");
if (full) { if (full) {
Unicopia.channel.broadcast(new MsgPlayerCapabilities(this)); Unicopia.channel.broadcast(new MsgPlayerCapabilities(this));
} else { } else {
Unicopia.channel.broadcast(new MsgPlayerCapabilities(getPlayerSpecies(), getOwner().getGameProfile().getId())); Unicopia.channel.broadcast(new MsgPlayerCapabilities(getPlayerSpecies(), getOwner()));
} }
} }
} }
@ -136,15 +134,15 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
powers.onUpdate(entity); powers.onUpdate(entity);
gravity.onUpdate(entity); gravity.onUpdate(entity);
if (effect != null) { if (hasEffect()) {
if (!getPlayerSpecies().canCast()) { if (!getPlayerSpecies().canCast()) {
setEffect(null); setEffect(null);
} else { } else {
if (entity.getEntityWorld().isRemote) { // && entity.getEntityWorld().getWorldTime() % 10 == 0 if (entity.getEntityWorld().isRemote) { // && entity.getEntityWorld().getWorldTime() % 10 == 0
effect.render(entity); getEffect().render(entity);
} }
if (!effect.update(entity)) { if (!getEffect().update(entity)) {
setEffect(null); setEffect(null);
} }
} }
@ -196,21 +194,27 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
@Override @Override
public void writeToNBT(NBTTagCompound compound) { public void writeToNBT(NBTTagCompound compound) {
compound.setString("playerSpecies", getPlayerSpecies().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());
IMagicEffect effect = getEffect();
if (effect != null) { if (effect != null) {
compound.setString("effect_id", effect.getName()); compound.setTag("effect", SpellRegistry.instance().serializeEffectToNBT(effect));
compound.setTag("effect", effect.toNBT());
} }
} }
@Override @Override
public void readFromNBT(NBTTagCompound compound) { public void readFromNBT(NBTTagCompound compound) {
setPlayerSpecies(Race.fromName(compound.getString("playerSpecies"), Race.HUMAN)); setPlayerSpecies(Race.fromName(compound.getString("playerSpecies"), Race.HUMAN));
powers.readFromNBT(compound.getCompoundTag("powers")); powers.readFromNBT(compound.getCompoundTag("powers"));
gravity.readFromNBT(compound.getCompoundTag("gravity")); gravity.readFromNBT(compound.getCompoundTag("gravity"));
effect = SpellRegistry.instance().createEffectFroNBT(compound);
if (compound.hasKey("effect")) {
setEffect(SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect")));
}
} }
@Override @Override
@ -221,30 +225,23 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
@Override @Override
public void setEffect(IMagicEffect effect) { public void setEffect(IMagicEffect effect) {
this.effect = effect; effectDelegate.set(effect);
sendCapabilities(true); sendCapabilities(true);
} }
@Override @Override
public IMagicEffect getEffect() { public IMagicEffect getEffect() {
return effect; return effectDelegate.get();
} }
@Override @Override
public void setOwner(EntityPlayer owner) { public void setOwner(EntityPlayer owner) {
entity = 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

@ -46,7 +46,7 @@ public class PlayerSpeciesList {
} }
public IPlayer getPlayer(UUID playerId) { public IPlayer getPlayer(UUID playerId) {
return getPlayer(IPlayer.getPlayerEntity(playerId)); return getPlayer(IPlayer.getPlayerFromServer(playerId));
} }
public <T extends Entity> IRaceContainer<T> getEntity(T entity) { public <T extends Entity> IRaceContainer<T> getEntity(T entity) {

View file

@ -0,0 +1,30 @@
package com.minelittlepony.unicopia.render;
import com.minelittlepony.unicopia.entity.EntitySpell;
import com.minelittlepony.unicopia.model.ModelGem;
import net.minecraft.client.renderer.entity.RenderLiving;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.util.ResourceLocation;
public class RenderGem extends RenderLiving<EntitySpell> {
private static final ResourceLocation gem = new ResourceLocation("unicopia", "textures/entity/gem.png");
public RenderGem(RenderManager rendermanagerIn) {
super(rendermanagerIn, new ModelGem(), 0);
}
protected ResourceLocation getEntityTexture(EntitySpell entity) {
return gem;
}
protected float getDeathMaxRotation(EntitySpell entity) {
return 0;
}
protected boolean canRenderName(EntitySpell targetEntity) {
return super.canRenderName(targetEntity) && (targetEntity.getAlwaysRenderNameTagForRender()
|| targetEntity.hasCustomName() && targetEntity == renderManager.pointedEntity);
}
}

View file

@ -14,6 +14,9 @@ public interface ICaster<E extends EntityLivingBase> extends IOwned<E> {
return getEffect() != null; return getEffect() != null;
} }
/**
* Gets the entity directly responsible for casting.
*/
default Entity getEntity() { default Entity getEntity() {
return getOwner(); return getOwner();
} }

View file

@ -6,13 +6,13 @@ import net.minecraft.util.EnumFacing;
/** /**
* Represents an object with an action to perform when dispensed from a dispenser. * Represents an object with an action to perform when dispensed from a dispenser.
* *
*/ */
public interface IDispenceable { public interface IDispenceable extends IMagicEffect {
/** /**
* Called when dispensed. * Called when dispensed.
* *
* @param pos Block position in front of the dispenser * @param pos Block position in front of the dispenser
* @param facing Direction of the dispenser * @param facing Direction of the dispenser
* @param source The dispenser currently dispensing * @param source The dispenser currently dispensing

View file

@ -34,8 +34,8 @@ public class SpellRegistry {
return null; return null;
} }
public IMagicEffect createEffectFroNBT(NBTTagCompound compound) { public IMagicEffect createEffectFromNBT(NBTTagCompound compound) {
if (compound.hasKey("effect_id") && compound.hasKey("effect")) { if (compound.hasKey("effect_id")) {
IMagicEffect effect = getSpellFromName(compound.getString("effect_id")); IMagicEffect effect = getSpellFromName(compound.getString("effect_id"));
if (effect != null) { if (effect != null) {
@ -48,6 +48,14 @@ public class SpellRegistry {
return null; return null;
} }
public NBTTagCompound serializeEffectToNBT(IMagicEffect effect) {
NBTTagCompound compound = effect.toNBT();
compound.setString("effect_id", effect.getName());
return compound;
}
public IDispenceable getDispenseActionFrom(ItemStack stack) { public IDispenceable getDispenseActionFrom(ItemStack stack) {
String key = getKeyFromStack(stack); String key = getKeyFromStack(stack);
@ -80,7 +88,7 @@ public class SpellRegistry {
return stack; return stack;
} }
private String getKeyFromStack(ItemStack stack) { public static String getKeyFromStack(ItemStack stack) {
if (stack.isEmpty() || !stack.hasTagCompound() || !stack.getTagCompound().hasKey("spell")) { if (stack.isEmpty() || !stack.hasTagCompound() || !stack.getTagCompound().hasKey("spell")) {
return ""; return "";
} }

View file

@ -57,7 +57,7 @@ public class SpellShield extends AbstractSpell {
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);
for (int i = 0; i < strength; i++) { for (int i = 0; i < strength * 6; i++) {
Vec3d pos = sphere.computePoint(w.rand); Vec3d pos = sphere.computePoint(w.rand);
Particles.instance().spawnParticle(Unicopia.MAGIC_PARTICLE, false, Particles.instance().spawnParticle(Unicopia.MAGIC_PARTICLE, false,
pos.x + x, pos.y + y, pos.z + z, pos.x + x, pos.y + y, pos.z + z,

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB