mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Add gem entities, improve networking code
This commit is contained in:
parent
f33b1e37b0
commit
c9e912a378
34 changed files with 1390 additions and 99 deletions
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
78
src/api/java/com/minelittlepony/render/model/ModelGlow.java
Normal file
78
src/api/java/com/minelittlepony/render/model/ModelGlow.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
84
src/api/java/com/minelittlepony/render/model/ModelPlane.java
Normal file
84
src/api/java/com/minelittlepony/render/model/ModelPlane.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
10
src/api/java/com/minelittlepony/render/model/Plane.java
Normal file
10
src/api/java/com/minelittlepony/render/model/Plane.java
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package com.minelittlepony.render.model;
|
||||||
|
|
||||||
|
enum Plane {
|
||||||
|
NORTH,
|
||||||
|
SOUTH,
|
||||||
|
UP,
|
||||||
|
DOWN,
|
||||||
|
EAST,
|
||||||
|
WEST
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
@MethodsReturnNonnullByDefault
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
package com.minelittlepony.render.model;
|
||||||
|
|
||||||
|
import mcp.MethodsReturnNonnullByDefault;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
36
src/api/java/com/minelittlepony/util/render/Box.java
Normal file
36
src/api/java/com/minelittlepony/util/render/Box.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
21
src/api/java/com/minelittlepony/util/render/Color.java
Normal file
21
src/api/java/com/minelittlepony/util/render/Color.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
37
src/api/java/com/minelittlepony/util/render/Quad.java
Normal file
37
src/api/java/com/minelittlepony/util/render/Quad.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
21
src/api/java/com/minelittlepony/util/render/Vertex.java
Normal file
21
src/api/java/com/minelittlepony/util/render/Vertex.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
@MethodsReturnNonnullByDefault
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
package com.minelittlepony.util.render;
|
||||||
|
|
||||||
|
import mcp.MethodsReturnNonnullByDefault;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.minelittlepony.unicopia.entity;
|
||||||
|
|
||||||
|
import net.minecraft.entity.passive.IAnimals;
|
||||||
|
|
||||||
|
public interface IMagicals extends IAnimals {
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
} */
|
}
|
||||||
}
|
}
|
||||||
|
|
126
src/main/java/com/minelittlepony/unicopia/model/ModelGem.java
Normal file
126
src/main/java/com/minelittlepony/unicopia/model/ModelGem.java
Normal 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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
BIN
src/main/resources/assets/unicopia/textures/entity/gem.png
Normal file
BIN
src/main/resources/assets/unicopia/textures/entity/gem.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Loading…
Reference in a new issue