ugh... as I was afraid of... I've tried to extend my Widget class (the base class for the triangles) with the Entity class.
when I try to run the LUA script to add the entities, I get kicked out of my game and everything messes up...
is there an example which adds a raw entity that I can follow??
a few google searches doesn't seem to give me what I need, since the results only list stuff for Entity children classes.
if not, then what can I do to get this working??
if you'd like to see my source, I've actually copied the source with Marcin212's permission for OpenGlasses
so here's my code for the Widget class:
package com.tcll.ochardlight.surface;
import java.util.HashMap;
import com.tcll.ochardlight.lua.LuaReference;
import com.tcll.ochardlight.surface.widgets.core.AttributeRegistry;
import com.tcll.ochardlight.surface.widgets.core.attribute.IAttribute;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
//import net.minecraftforge.fml.relauncher.Side;
//import net.minecraftforge.fml.relauncher.SideOnly;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public abstract class Widget extends Entity implements IAttribute{
boolean isVisable = true;
public Widget(World worldIn) {
super(worldIn);
// TODO Auto-generated constructor stub
}
public abstract void readData(ByteBuf buff);
public abstract void writeData(ByteBuf buff);
public final void read(ByteBuf buff){ isVisable = buff.readBoolean(); readData(buff); }
public final void write(ByteBuf buff){ buff.writeBoolean(isVisable); writeData(buff); }
public Object[] getLuaObject(LuaReference ref) {
HashMap<String, Object> luaObject = new HashMap<String, Object>();
Class<?> current = getClass();
do {
for (Class<?> a : current.getInterfaces()) {
if (IAttribute.class.isAssignableFrom(a)) {
luaObject.putAll(AttributeRegistry.getFunctions(a.asSubclass(IAttribute.class), ref));
}
}
current = current.getSuperclass();
} while (!current.equals(Object.class));
return new Object[] { luaObject };
}
public void setVisable(boolean isVisable) { this.isVisable = isVisable; }
public boolean isVisible() { return isVisable; }
public abstract WidgetType getType();
public RenderType getRenderType() { return RenderType.WorldLocated; }
public boolean shouldWidgetBeRendered() { return isVisible(); }
public void render(EntityPlayer player, double playerX, double playerY, double playerZ) {}
protected void entityInit() {
// TODO Auto-generated method stub
}
protected void readEntityFromNBT(NBTTagCompound nbt){
if(!nbt.hasKey("WidgetData")) return;
byte[] b = nbt.getByteArray("WidgetData");
ByteBuf buff = Unpooled.copiedBuffer(b);
read(buff);
};
protected void writeEntityToNBT(NBTTagCompound nbt) {
ByteBuf buff = Unpooled.buffer();
write(buff);
nbt.setByteArray("WidgetData", buff.array());
};
}
and here's my code for the triangle class:
package com.tcll.ochardlight.surface.widgets.component.world;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.opengl.GL11;
import com.tcll.ochardlight.surface.RenderType;
import com.tcll.ochardlight.surface.Widget;
import com.tcll.ochardlight.surface.WidgetType;
import com.tcll.ochardlight.surface.widgets.core.attribute.I3DVertex;
import com.tcll.ochardlight.surface.widgets.core.attribute.IColorizable;
import com.tcll.ochardlight.surface.widgets.core.attribute.IThroughVisibility;
import com.tcll.ochardlight.utils.Color;
import com.tcll.ochardlight.utils.Vector;
public class Triangle3D extends Widget implements IColorizable, IThroughVisibility, I3DVertex {
Vector[] positions = {new Vector(0,0,0), new Vector(0,0,0), new Vector(0,0,0)};
Color[] colors = {new Color(0,0,0,.5f), new Color(0,0,0,.5f), new Color(0,0,0,.5f)};
boolean isThroughVisibility = false;
public Triangle3D(World worldIn) {
super(worldIn);
// TODO Auto-generated constructor stub
}
//public Triangle3D() {}
@Override
public void writeData(ByteBuf buff) {
buff.writeFloat(positions[0].x);
buff.writeFloat(positions[1].x);
buff.writeFloat(positions[2].x);
buff.writeFloat(positions[0].y);
buff.writeFloat(positions[1].y);
buff.writeFloat(positions[2].y);
buff.writeFloat(positions[0].z);
buff.writeFloat(positions[1].z);
buff.writeFloat(positions[2].z);
buff.writeFloat(colors[0].a);
buff.writeFloat(colors[1].a);
buff.writeFloat(colors[2].a);
buff.writeFloat(colors[0].r);
buff.writeFloat(colors[1].r);
buff.writeFloat(colors[2].r);
buff.writeFloat(colors[0].g);
buff.writeFloat(colors[1].g);
buff.writeFloat(colors[2].g);
buff.writeFloat(colors[0].b);
buff.writeFloat(colors[1].b);
buff.writeFloat(colors[2].b);
buff.writeBoolean(isThroughVisibility);
}
@Override
public void readData(ByteBuf buff) {
positions[0].x = buff.readFloat();
positions[1].x = buff.readFloat();
positions[2].x = buff.readFloat();
positions[0].y = buff.readFloat();
positions[1].y = buff.readFloat();
positions[2].y = buff.readFloat();
positions[0].z = buff.readFloat();
positions[1].z = buff.readFloat();
positions[2].z = buff.readFloat();
colors[0].a = buff.readFloat();
colors[1].a = buff.readFloat();
colors[2].a = buff.readFloat();
colors[0].r = buff.readFloat();
colors[1].r = buff.readFloat();
colors[2].r = buff.readFloat();
colors[0].g = buff.readFloat();
colors[1].g = buff.readFloat();
colors[2].g = buff.readFloat();
colors[0].b = buff.readFloat();
colors[1].b = buff.readFloat();
colors[2].b = buff.readFloat();
isThroughVisibility = buff.readBoolean();
}
@SideOnly(Side.CLIENT)
public void render(EntityPlayer player, double playerX, double playerY, double playerZ) {
GL11.glPushMatrix();
if(isThroughVisibility){
GL11.glDisable(GL11.GL_DEPTH_TEST);
}else{
GL11.glEnable(GL11.GL_DEPTH_TEST);
}
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glBegin(GL11.GL_TRIANGLES);//_STRIP); // pseudo double-sided support
GL11.glColor4f(colors[0].r, colors[0].g, colors[0].b, colors[0].a);
GL11.glVertex3f(positions[0].x, positions[0].y, positions[0].z);
GL11.glColor4f(colors[1].r, colors[1].g, colors[1].b, colors[1].a);
GL11.glVertex3f(positions[1].x, positions[1].y, positions[1].z);
GL11.glColor4f(colors[2].r, colors[2].g, colors[2].b, colors[2].a);
GL11.glVertex3f(positions[2].x, positions[2].y, positions[2].z);
GL11.glColor4f(0,0,0,0);
// pseudo double-sided support:
//GL11.glColor4f(colors[0].r, colors[0].g, colors[0].b, colors[0].a);
//GL11.glVertex3f(positions[0].x, positions[0].y, positions[0].z);
GL11.glEnd();
GL11.glPopMatrix();
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glEnable(GL11.GL_TEXTURE_2D);
}
@Override
public WidgetType getType() { return WidgetType.TRIANGLE3D; }
public RenderType getRenderType() { return RenderType.WorldLocated; }
public boolean shouldWidgetBeRendered() { return isVisible(); }
@Override
public void setColor(int n, double r, double g, double b, double a) {
colors[n].r = (float) r; colors[n].g = (float) g; colors[n].b = (float) b; colors[n].a = (float) a; }
@Override
public double[] getColor(int n) { double[] cl = {
colors[n].r, colors[n].g, colors[n].b, colors[n].a }; return cl; } // Tcll - how can I return the collection w/o `cl`??
@Override
public void setVisibleThroughObjects(boolean visible) { isThroughVisibility = visible; }
@Override
public boolean isVisibleThroughObjects() { return isThroughVisibility; }
@Override
public void setVertex(int n, double x, double y, double z) { positions[n].x = (float) x; positions[n].y = (float) y; positions[n].z = (float) z; }
@Override
public int getVertexCount() { return positions.length; }
}
and also, the code which renders everything:
package com.tcll.ochardlight.surface;
//import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
//import org.lwjgl.opengl.GL30;
//import com.tcll.ochardlight.surface.widgets.component.world.FloatingText;
import com.tcll.ochardlight.utils.Location;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.math.RayTraceResult;
//import net.minecraftforge.client.event.RenderGameOverlayEvent;
//import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ClientSurface {
public static ClientSurface instances = new ClientSurface();
public Map<Integer, Widget> renderables = new ConcurrentHashMap<Integer, Widget>();
public Map<Integer, Widget> renderablesWorld = new ConcurrentHashMap<Integer, Widget>();
boolean isPowered = true;
//public boolean haveGlasses = false;
public Location lastBind;
//IRenderableWidget noPowerRender;
/*
private ClientSurface() {
noPowerRender = getNoPowerRender();
}
*/
// TODO: is this confusion really needed??
public void updateWigets(Set<Entry<Integer, Widget>> widgets){
for(Entry<Integer, Widget> widget : widgets){
Widget w = widget.getValue();
switch(w.getRenderType()){
case GameOverlayLocated: renderables.put(widget.getKey(), w); break; // not used
case WorldLocated: renderablesWorld.put(widget.getKey(), w); break;
}
}
}
public void removeWidgets(List<Integer> ids){
for(Integer id : ids){ renderables.remove(id); renderablesWorld.remove(id); }
}
public void removeAllWidgets(){ renderables.clear(); renderablesWorld.clear(); }
/*
@SubscribeEvent
public void onRenderGameOverlay(RenderGameOverlayEvent evt) {
if (evt instanceof RenderGameOverlayEvent.Post) {
//if(!isPowered || lastBind == null){ noPowerRender.render(null, 0, 0, 0); return;}
if(lastBind == null) {lastBind = new Location();};
if(!isPowered){ noPowerRender.render(null, 0, 0, 0); };
GL11.glPushMatrix();
GL11.glScaled(evt.getResolution().getScaledWidth_double()/512D, evt.getResolution().getScaledHeight_double()/512D*16D/9D, 0);
for(IRenderableWidget renderable : renderables.values()){
if(renderable.shouldWidgetBeRendered())
renderable.render(null, 0, 0, 0);
}
// GL11.glBegin(GL11.GL_QUADS);
// GL11.glColor4f(1, 0, 0, 1);
// GL11.glVertex3f(0, 0, 0);
// GL11.glVertex3f(0, 10, 0);
// GL11.glVertex3f(10, 10, 0);
// GL11.glVertex3f(10, 0, 0);
// GL11.glEnd();
GL11.glColor3f(1.0f,1.0f,1.0f);
GL11.glPopMatrix();
}
}
*/
@SubscribeEvent
public void renderWorldLastEvent(RenderWorldLastEvent event) {
//if(!isPowered || lastBind == null) return;
if(lastBind == null) {lastBind = new Location();};
GL11.glPushMatrix();
EntityPlayer player= Minecraft.getMinecraft().thePlayer;
double playerX = player.prevPosX + (player.posX - player.prevPosX) * event.getPartialTicks();
double playerY = player.prevPosY + (player.posY - player.prevPosY) * event.getPartialTicks();
double playerZ = player.prevPosZ + (player.posZ - player.prevPosZ) * event.getPartialTicks();
GL11.glTranslated(-playerX, -playerY, -playerZ);
GL11.glTranslated(lastBind.x, lastBind.y, lastBind.z);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glPolygonMode( GL11.GL_FRONT_AND_BACK, GL11.GL_FILL );
GL11.glDisable( GL11.GL_CULL_FACE );
GL11.glShadeModel(GL11.GL_SMOOTH);
GL11.glEnable(GL11.GL_NORMALIZE);
GL11.glDepthMask(false);
//int prog = GL20.GL_CURRENT_PROGRAM;
GL20.glUseProgram( 0 );
//Start Drawing In World
for(Widget renderable : renderablesWorld.values()){
if(renderable.shouldWidgetBeRendered()) renderable.render(player, playerX - lastBind.x, playerY - lastBind.y, playerZ - lastBind.z);
}
//Stop Drawing In World
//GL20.glUseProgram( prog );
GL11.glDepthMask(true);
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_BLEND);
GL11.glPopMatrix();
}
public static RayTraceResult getBlockCoordsLookingAt(EntityPlayer player){
RayTraceResult objectMouseOver;
objectMouseOver = player.rayTrace(200, 1);
if(objectMouseOver != null && objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) { return objectMouseOver; }
return null;
}
public void setPowered(boolean isPowered) { this.isPowered = isPowered; }
/*
private IRenderableWidget getNoPowerRender(){
Text t = new Text();
t.setText("NO POWER");
//t.setAlpha(0.5);
t.setScale(1);
t.setColor(1,1, 0.25, 0.25, 0.5);
return t.getRenderable();
}
*/
}
I'm sure plenty of people here will find disgusting implementations in the code, heck, even Marcin212 himself says his code sucks
anyways...
what do I not know I'm doing wrong??
thanks