270 lines
8.9 KiB
Java

package org.atriaSoft.gameEngine;
import java.util.ArrayList;
import java.util.List;
import org.atriaSoft.etk.math.Vector3f;
public class Entity {
protected Environement env = null;
protected List<Component> component = new ArrayList<Component>();
/**
* @brief Constructor (when ructer is called just add Entity that did not change.
* The objest will be stored in a pool of Entity and keep a second time if needed == > reduce memory allocation,
* when needed, the system will call the init and un-init function...
*/
public Entity(Environement env) {
this.env = env;
}
public void addComponent(Component ref) {
if (ref == null) {
Log.error("try to add an empty component");
return;
}
// Remove component with the same name.
this.removeComponent(ref.getType());
Log.print("Entity: Add New component ... [START]");
component.add(ref);
env.engineComponentAdd(ref);
for (Component it : component) {
ref.addFriendComponent(it);
it.addFriendComponent(ref);
}
Log.print("Entity: Add New component ... [END]");
}
public void removeComponent(Component ref){
if (ref == null) {
Log.error("try to remove an empty component");
return;
}
if (component.remove(ref) == false) {
Log.error("try to remove an unexisting component");
return;
}
env.engineComponentRemove(ref);
for (Component it : component) {
it.removeFriendComponent(ref);
}
}
public void removeComponent(String type) {
boolean findIt = false;
Component componentRemoved = null;
// check if not exist
for (int iii=0; iii<component.size(); ++iii) {
if (component.get(iii).getType().contentEquals(type)) {
componentRemoved = component.get(iii);
component.remove(iii);
findIt = true;
break;
}
}
if (findIt == false) {
//Log.error("try to remove an unexisting component type : '" + type + "'");
return;
}
env.engineComponentRemove(componentRemoved);
for (Component it : component) {
it.removeFriendComponent(componentRemoved);
}
}
public Component getComponent(String type) {
// check if not exist
for (int iii=0; iii<component.size(); ++iii) {
if (component.get(iii) == null) {
continue;
}
if (component.get(iii).getType().contentEquals(type)) {
return component.get(iii);
}
}
return null;
}
/**
* @brief init the Entity with the defined properties
* @param[in] property Type of the next Entity
* @param[in] value pointer on the value type
* @return true, the Entity is corectly initialized.
*/
public boolean init(){
Log.warning("init() not implemented: uId=" + uID);
return false;
}
public boolean init(Object description){
Log.warning("init(Object) not implemented: uId=" + uID);
return false;
}
public boolean unInit() {
return true;
}
private static int uIDGlobal = 0; //!< This is a reference on a basic Entity ID
private int uID = uIDGlobal++; //!< This is a reference on a basic Entity ID
/**
* @brief get the curent Entity Unique ID in the all Game.
* @return The requested Unique ID.
*/
public int getUID() {
return this.uID;
};
protected float life = 100; //!< Current life of the object
protected float lifeMax = 100; //!< Maximum possible life of the Entity
/**
* @brief get the curent life ratio [0..1]
* @return The proportionnal life
*/
public float getLifeRatio() {
if (0 >= life) {
return 0;
}
return life/lifeMax;
}
/*
* @brief Check if the Entity is dead.
* @return true if the Entity does not exist anymore, false otherwise.
*/
public boolean isDead() {
return (0 >= this.life)?true:false;
};
/**
* @brief Request if the Entity might be removed from the system
* @return true == > the object is removed
*/
public boolean needToRemove() {
return isDead();
}
/**
* @brief apply a fire on the Entity at a current power and a specific power.
* @param[in] groupIdSource Source Id of the group, by default all event arrive at all group, buf some event can not be obviously apply at the ennemy like reparing ....
* @param[in] type Type of event on the life propertied
* @param[in] power Power of the event (can be >0 for adding life).
* @param[in] center Some fire decrease in function of space distance...
*/
public void setFireOn(int groupIdSource, int type, float power, Vector3f center) {
float previousLife = life;
life += power;
life = Math.min(Math.max(0.0f, life), lifeMax);
if (life <= 0) {
Log.debug("[" + getUID() + "] Entity is killed ...");
}
if (life != previousLife) {
onLifeChange();
}
}
/**
* @brief Call when the Entity life change.
*/
public void onLifeChange() { };
// float lifeBorder = 0.1f;
// float lifeHeight = 0.3f;
// float lifeWidth = 2.0f;
// float lifeYPos = 1.7f;
// void Entity::drawLife(ewol::resource::Colored3DObject> draw, Camera> camera) {
// if (draw == null) {
// return;
// }
// float ratio = getLifeRatio();
// if (ratio == 1.0f) {
// return;
// }
// #if 0
// mat4 transformationMatrix = etk::matTranslate(getPosition())
// * etk::matRotate(Vector3f(0,0,1),camera.getAngleZ())
// * etk::matRotate(Vector3f(1,0,0),(MPI/2.0f-camera.getAngleTeta()));
// List<Vector3f> localVertices;
// localVertices.pushBack(Vector3f(-lifeWidth/2.0-lifeBorder,lifeYPos -lifeBorder,0));
// localVertices.pushBack(Vector3f(-lifeWidth/2.0-lifeBorder,lifeYPos+lifeHeight+lifeBorder,0));
// localVertices.pushBack(Vector3f( lifeWidth/2.0+lifeBorder,lifeYPos+lifeHeight+lifeBorder,0));
// localVertices.pushBack(Vector3f(-lifeWidth/2.0-lifeBorder,lifeYPos -lifeBorder,0));
// localVertices.pushBack(Vector3f( lifeWidth/2.0+lifeBorder,lifeYPos+lifeHeight+lifeBorder,0));
// localVertices.pushBack(Vector3f( lifeWidth/2.0+lifeBorder,lifeYPos -lifeBorder,0));
// etk::Color<float> myColor(0x0000FF99);
// draw.draw(localVertices, myColor, transformationMatrix, false, false);
// localVertices.clear();
// /** Bounding box == > model shape **/
// localVertices.pushBack(Vector3f(-lifeWidth/2.0 ,lifeYPos,0));
// localVertices.pushBack(Vector3f(-lifeWidth/2.0 ,lifeYPos + lifeHeight,0));
// localVertices.pushBack(Vector3f(-lifeWidth/2.0+lifeWidth*ratio,lifeYPos + lifeHeight,0));
// localVertices.pushBack(Vector3f(-lifeWidth/2.0 ,lifeYPos,0));
// localVertices.pushBack(Vector3f(-lifeWidth/2.0+lifeWidth*ratio,lifeYPos + lifeHeight,0));
// localVertices.pushBack(Vector3f(-lifeWidth/2.0+lifeWidth*ratio,lifeYPos,0));
// myColor =0x00FF00FF;
// if (ratio < 0.2f) {
// myColor = 0xFF0000FF;
// } else if (ratio < 0.4f) {
// myColor = 0xDA7B00FF;
// }
// draw.draw(localVertices, myColor, transformationMatrix, false, false);
// #endif
// }
private int group = 0; //!< Every Entity has a generic group
/**
* @brief get the Group of the Entity.
* @return The group ID
*/
public int getGroup() {
return this.group;
};
/**
* @brief set the group of the curent Entity
* @param[in] newGroup The new Group ID of the Entity.
*/
public void setGroup(int newGroup) {
this.group = newGroup;
};
/**
* @brief Debug display of the current Entity
* @param[in,out] draw Basic system to draw the debug shape and informations
* @param[in] camera Current camera for display
*/
// public void drawDebug(Colored3DObject draw, Camera camera) {
// /*
// mdebugText.clear();
// mdebugText.setColor(etk::Color<>(0x00, 0xFF, 0x00, 0xFF));
// mdebugText.setPos(Vector3f(-20,32,0));
// mdebugText.print(getType());
// mdebugText.setPos(Vector3f(-20,20,0));
// mdebugText.print("life=("+etk::toString(getLifeRatio()));
// */
// //mdebugText.print(String("Axe=(")+String(mtmpAxe.x())+String(",")+etk::UString(mtmpAxe.y())+etk::UString(",")+etk::UString(m_tmpAxe.z())+etk::UString(")"));
// /*
// // TODO : Keep this it can be usefull to print something in direction of the camera ...
// mdebugText.draw( etk::matTranslate(getPosition())
// * etk::matRotate(Vector3f(0,0,1),camera.getAngleZ())
// * etk::matRotate(Vector3f(1,0,0),(MPI/2.0f-camera.getAngleTeta()))
// * etk::matScale(Vector3f(0.05,0.05,0.05)));
// */
// }
/**
* @brief Event arrive when an Entity has been remove from the system == > this permit to keep pointer of ennemy, and not search them every cycle ...
* @param[in] removedEntity Pointer on the Entity removed.
*/
public void entityIsRemoved(Entity removedEntity) { };
protected float radius = 0; //!< Radius of the Entity (all Entity have a radius, if == 0 ==> then ghost ...
/**
* @brief get the current space needed by the Entity in the workspace
* @return The dimention needed.
*/
public float getRadius() {
return this.radius;
};
/**
* @brief, call when the Entity is removed (call only one time)
*/
public void onDestroy() {};
/**
* @brief set the elment in the physique engine
*/
public void dynamicEnable() {};
/**
* @brief remove this Entity from the physique engine
*/
public void dynamicDisable() {};
}