forked from mirrors/principia
Cleanups in entity source file
Code cleanups, convert comments into annotations consumable by Doxygen where applicable, renames and splits up the shape extruder object's class into a separate source files, etc...
This commit is contained in:
parent
fac177b9f1
commit
8771027650
7 changed files with 954 additions and 1223 deletions
|
|
@ -7,9 +7,7 @@
|
|||
#include "rack.hh"
|
||||
#include "game.hh"
|
||||
|
||||
void
|
||||
connection::update(void)
|
||||
{
|
||||
void connection::update(void) {
|
||||
this->layer = this->e->get_layer();
|
||||
this->layer_mask = this->e->layer_mask;
|
||||
|
||||
|
|
@ -22,33 +20,23 @@ connection::update(void)
|
|||
this->sublayer_dist = this->e->sublayer_dist(this->o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the relative angle between the bodies
|
||||
**/
|
||||
void
|
||||
connection::update_relative_angle(bool force)
|
||||
{
|
||||
void connection::update_relative_angle(bool force) {
|
||||
if (!force) {
|
||||
b2Joint *j = this->j;
|
||||
if (j) {
|
||||
b2JointType t = j->GetType();
|
||||
|
||||
if (t != e_revoluteJoint && t != e_pivotJoint) {
|
||||
if (t != e_revoluteJoint && t != e_pivotJoint)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tms_infof("update relative angle for connection %p", this);
|
||||
tms_infof("object 1: %p, object 2: %p", this->e, this->o);
|
||||
this->relative_angle = -(this->o->get_angle(this->f[1]) - this->e->get_angle(this->f[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply is called the first time the connection is created
|
||||
**/
|
||||
void
|
||||
connection::apply(void)
|
||||
{
|
||||
//tms_infof("apply joint : %f %f, %p", this->p.x, this->p.y, this);
|
||||
void connection::apply() {
|
||||
this->update_relative_angle(true);
|
||||
|
||||
if (this->type != CONN_GEAR) {
|
||||
|
|
@ -68,7 +56,6 @@ connection::apply(void)
|
|||
this->sublayer_dist = this->e->sublayer_dist(this->o);
|
||||
|
||||
if (!this->fixed) {
|
||||
//tms_infof("adding to bodies");
|
||||
this->e->add_connection(this);
|
||||
this->o->add_connection(this);
|
||||
}
|
||||
|
|
@ -76,88 +63,61 @@ connection::apply(void)
|
|||
this->pending = false;
|
||||
}
|
||||
|
||||
void
|
||||
connection::destroy_joint()
|
||||
{
|
||||
void connection::destroy_joint() {
|
||||
if (this->j) {
|
||||
if (!this->owned || this->e->connection_destroy_joint(this) == false)
|
||||
this->e->get_body(this->f[0])->GetWorld()->DestroyJoint(this->j);
|
||||
|
||||
this->j = 0;
|
||||
|
||||
}
|
||||
|
||||
this->remove_self_ent();
|
||||
}
|
||||
|
||||
void
|
||||
connection::remove_self_ent()
|
||||
{
|
||||
if (this->self_ent) {
|
||||
if (this->self_ent->scene) {
|
||||
G->remove_entity(this->self_ent);
|
||||
}
|
||||
|
||||
delete this->self_ent;
|
||||
this->self_ent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
connection::create_self_ent(bool add)
|
||||
{
|
||||
if (this->render_type == CONN_RENDER_HIDE) {
|
||||
void connection::remove_self_ent() {
|
||||
if (!this->self_ent)
|
||||
return;
|
||||
}
|
||||
|
||||
switch (this->type) {
|
||||
case CONN_PIVOT:
|
||||
case CONN_WELD:
|
||||
case CONN_PLATE:
|
||||
this->self_ent = new connection_entity(this, this->type);
|
||||
break;
|
||||
}
|
||||
if (this->self_ent->scene)
|
||||
G->remove_entity(this->self_ent);
|
||||
|
||||
if (this->self_ent && add) {
|
||||
if (this->self_ent->scene == 0) {
|
||||
G->add_entity(this->self_ent);
|
||||
}
|
||||
}
|
||||
delete this->self_ent;
|
||||
this->self_ent = 0;
|
||||
}
|
||||
|
||||
void
|
||||
connection::update_render_type()
|
||||
{
|
||||
void connection::create_self_ent(bool add) {
|
||||
if (this->render_type == CONN_RENDER_HIDE)
|
||||
return;
|
||||
|
||||
if (this->type == CONN_PIVOT || this->type == CONN_WELD || this->type == CONN_PLATE)
|
||||
this->self_ent = new connection_entity(this, this->type);
|
||||
|
||||
if (this->self_ent && add && this->self_ent->scene == 0)
|
||||
G->add_entity(this->self_ent);
|
||||
}
|
||||
|
||||
void connection::update_render_type() {
|
||||
tms_debugf("Update render type. Self ent: %p", this->self_ent);
|
||||
bool add = (this->self_ent && this->self_ent->scene);
|
||||
|
||||
this->remove_self_ent();
|
||||
|
||||
switch (this->render_type) {
|
||||
case CONN_RENDER_HIDE:
|
||||
break;
|
||||
if (this->render_type == CONN_RENDER_HIDE)
|
||||
return;
|
||||
|
||||
default:
|
||||
if (!this->self_ent) {
|
||||
this->create_self_ent(add);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!this->self_ent)
|
||||
this->create_self_ent(add);
|
||||
}
|
||||
|
||||
void
|
||||
connection::create_joint(bool add)
|
||||
{
|
||||
if (this->type == CONN_GROUP) {
|
||||
void connection::create_joint(bool add) {
|
||||
if (this->type == CONN_GROUP)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this->self_ent) {
|
||||
this->create_self_ent(add);
|
||||
} else {
|
||||
if (this->self_ent->mesh == mesh_factory::get_mesh(MODEL_PLATEJOINT_DAMAGED)) {
|
||||
if (this->self_ent->mesh == mesh_factory::get_mesh(MODEL_PLATEJOINT_DAMAGED))
|
||||
this->self_ent->set_mesh(mesh_factory::get_mesh(MODEL_PLATEJOINT));
|
||||
}
|
||||
}
|
||||
|
||||
//tms_infof("group: %p, body: %p, %d", this->e->group, this->e->body, this->f[0]);
|
||||
|
|
@ -181,7 +141,7 @@ connection::create_joint(bool add)
|
|||
switch (this->type) {
|
||||
case CONN_CUSTOM: this->e->connection_create_joint(this); break;
|
||||
|
||||
case CONN_RACK:{
|
||||
case CONN_RACK: {
|
||||
gear *g = static_cast<gear*>(this->e); /* always this order */
|
||||
rack *r = static_cast<rack*>(this->o);
|
||||
|
||||
|
|
@ -193,10 +153,9 @@ connection::create_joint(bool add)
|
|||
this->j = b2->CreateJoint(&gjd);
|
||||
|
||||
r->update_limits();
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
case CONN_GEAR:{
|
||||
case CONN_GEAR: {
|
||||
gear *g0 = static_cast<gear*>(this->e);
|
||||
gear *g1 = static_cast<gear*>(this->o);
|
||||
float ratio = 1.f;
|
||||
|
|
@ -207,13 +166,6 @@ connection::create_joint(bool add)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (((gear*)this->e)->get_num_gear_conns() < ((gear*)this->o)->get_num_gear_conns()) {
|
||||
((gear*)this->e)->fix_position(this->o);
|
||||
} else
|
||||
((gear*)this->o)->fix_position(this->e);
|
||||
*/
|
||||
|
||||
gjd.bodyA = this->e->get_body(this->f[0]);
|
||||
gjd.bodyB = this->o->get_body(this->f[1]);
|
||||
gjd.joint1 = ((gear*)this->e)->joint;
|
||||
|
|
@ -223,8 +175,7 @@ connection::create_joint(bool add)
|
|||
gjd.ratio = ratio;
|
||||
gjd.collideConnected = true;
|
||||
this->j = b2->CreateJoint(&gjd);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
case CONN_PIVOT:
|
||||
if (this->e->is_wheel() && this->o->is_wheel() && this->e->get_layer() != this->o->get_layer()) {
|
||||
|
|
@ -256,53 +207,47 @@ connection::create_joint(bool add)
|
|||
break;
|
||||
|
||||
case CONN_PLATE:
|
||||
case CONN_WELD:
|
||||
{
|
||||
if (this->e->is_wheel() && this->o->is_wheel() && this->e->get_layer() != this->o->get_layer()) {
|
||||
wjd.localAnchorA = this->e->local_to_body(b2Vec2(0.f, 0.f), this->f[0]);
|
||||
wjd.localAnchorB = this->o->local_to_body(b2Vec2(0.f, 0.f), this->f[1]);
|
||||
} else {
|
||||
wjd.localAnchorA = this->e->local_to_body(this->p, this->f[0]);
|
||||
wjd.localAnchorB = this->o->local_to_body(this->p_s, this->f[1]);
|
||||
}
|
||||
|
||||
wjd.bodyA = this->e->get_body(this->f[0]);
|
||||
wjd.bodyB = this->o->get_body(this->f[1]);
|
||||
|
||||
if (wjd.bodyA->GetType() == b2_staticBody && wjd.bodyB->GetType() == b2_staticBody) {
|
||||
this->j = 0;
|
||||
tms_debugf("skipping joint between static bodies");
|
||||
break;
|
||||
}
|
||||
|
||||
wjd.referenceAngle = this->o->get_body(this->f[1])->GetAngle() - this->e->get_body(this->f[0])->GetAngle()
|
||||
- (this->o->get_angle(this->f[1]) - this->e->get_angle(this->f[0])) - this->relative_angle;
|
||||
|
||||
//wjd.referenceAngle = this->o->get_angle(this->f[1]) - this->e->get_angle(this->f[0]);
|
||||
wjd.collideConnected = false;
|
||||
wjd.frequencyHz = 0.f;
|
||||
|
||||
if (false && this->tolerant && !W->is_paused())
|
||||
wjd.frequencyHz = 40.f;
|
||||
|
||||
this->j = b2->CreateJoint(&wjd);
|
||||
|
||||
b2Vec2 pp = this->e->local_to_world(wjd.localAnchorA, this->f[0]);
|
||||
tms_debugf("applied plate, to world = %f %f, f = %u, id <%u,%u>", pp.x, pp.y, this->f[0], this->e->id, this->o->id);
|
||||
case CONN_WELD: {
|
||||
if (this->e->is_wheel() && this->o->is_wheel() && this->e->get_layer() != this->o->get_layer()) {
|
||||
wjd.localAnchorA = this->e->local_to_body(b2Vec2(0.f, 0.f), this->f[0]);
|
||||
wjd.localAnchorB = this->o->local_to_body(b2Vec2(0.f, 0.f), this->f[1]);
|
||||
} else {
|
||||
wjd.localAnchorA = this->e->local_to_body(this->p, this->f[0]);
|
||||
wjd.localAnchorB = this->o->local_to_body(this->p_s, this->f[1]);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
tms_errorf("invalid joint type %d", this->type);
|
||||
wjd.bodyA = this->e->get_body(this->f[0]);
|
||||
wjd.bodyB = this->o->get_body(this->f[1]);
|
||||
|
||||
if (wjd.bodyA->GetType() == b2_staticBody && wjd.bodyB->GetType() == b2_staticBody) {
|
||||
this->j = 0;
|
||||
tms_debugf("skipping joint between static bodies");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
wjd.referenceAngle = this->o->get_body(this->f[1])->GetAngle() - this->e->get_body(this->f[0])->GetAngle()
|
||||
- (this->o->get_angle(this->f[1]) - this->e->get_angle(this->f[0])) - this->relative_angle;
|
||||
|
||||
//wjd.referenceAngle = this->o->get_angle(this->f[1]) - this->e->get_angle(this->f[0]);
|
||||
wjd.collideConnected = false;
|
||||
wjd.frequencyHz = 0.f;
|
||||
|
||||
if (false && this->tolerant && !W->is_paused())
|
||||
wjd.frequencyHz = 40.f;
|
||||
|
||||
this->j = b2->CreateJoint(&wjd);
|
||||
|
||||
b2Vec2 pp = this->e->local_to_world(wjd.localAnchorA, this->f[0]);
|
||||
tms_debugf("applied plate, to world = %f %f, f = %u, id <%u,%u>", pp.x, pp.y, this->f[0], this->e->id, this->o->id);
|
||||
} break;
|
||||
|
||||
default: {
|
||||
tms_errorf("invalid joint type %d", this->type);
|
||||
} break;
|
||||
}
|
||||
|
||||
if (this->max_force < INFINITY) {
|
||||
//tms_infof("joint is destructable");
|
||||
if (this->max_force < INFINITY) // joint is destructable
|
||||
G->add_destructable_joint(this->j, this->max_force);
|
||||
}
|
||||
} else
|
||||
this->j = 0;
|
||||
|
||||
|
|
@ -314,22 +259,18 @@ connection::create_joint(bool add)
|
|||
}
|
||||
}
|
||||
|
||||
b2Vec2 connection::get_position()
|
||||
{
|
||||
b2Vec2 connection::get_position() {
|
||||
return this->e->local_to_world(this->p, this->f[0]);
|
||||
}
|
||||
|
||||
connection_entity::connection_entity(connection *c, int type)
|
||||
{
|
||||
connection_entity::connection_entity(connection *c, int type) {
|
||||
this->conn = c;
|
||||
this->curr_update_method = this->update_method = ENTITY_UPDATE_JOINT;
|
||||
|
||||
//((struct tms_entity*)this)->update = 0;
|
||||
//
|
||||
this->conn->type = type;
|
||||
|
||||
if ((c->e->layer_mask & c->o->layer_mask) == 0 && c->o->get_layer() == c->e->get_layer()) {
|
||||
/* breadboard, sublayer plank */
|
||||
// special case for e.g. breadboard, sublayer plank
|
||||
type = CONN_PIVOT;
|
||||
}
|
||||
|
||||
|
|
@ -341,31 +282,18 @@ connection_entity::connection_entity(connection *c, int type)
|
|||
tmat4_load_identity(this->M);
|
||||
tmat3_load_identity(this->N);
|
||||
|
||||
|
||||
switch (type) {
|
||||
case CONN_WELD: case CONN_PLATE:
|
||||
if (c->render_type == CONN_RENDER_NAIL || (c->multilayer)) {
|
||||
case CONN_PLATE:
|
||||
if (c->render_type == CONN_RENDER_NAIL || (c->multilayer))
|
||||
this->set_mesh(mesh_factory::get_mesh(MODEL_PIVOTJOINT));
|
||||
} else {
|
||||
else
|
||||
this->set_mesh(mesh_factory::get_mesh(MODEL_PLATEJOINT));
|
||||
}
|
||||
break;
|
||||
/* case CONN_WELD:
|
||||
if (c->multilayer)
|
||||
this->set_mesh(tms_meshfactory_get_cylinder());
|
||||
else
|
||||
this->set_mesh(mesh_factory::weldjoint);
|
||||
break;*/
|
||||
case CONN_PIVOT:
|
||||
this->set_mesh(mesh_factory::get_mesh(MODEL_PIVOTJOINT));
|
||||
this->curr_update_method = this->update_method = ENTITY_UPDATE_JOINT_PIVOT;
|
||||
break;
|
||||
this->curr_update_method = this->update_method = ENTITY_UPDATE_JOINT_PIVOT;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
if (c->render_type == CONN_RENDER_NAIL)
|
||||
this->set_material(&m_conn);
|
||||
else
|
||||
*/
|
||||
this->set_material(&m_conn_no_ao);
|
||||
this->set_material(&m_conn_no_ao);
|
||||
}
|
||||
|
|
|
|||
1232
src/entity.cc
1232
src/entity.cc
File diff suppressed because it is too large
Load diff
523
src/entity.hh
523
src/entity.hh
|
|
@ -17,20 +17,20 @@ class game;
|
|||
class world;
|
||||
class base_prompt;
|
||||
|
||||
struct worth
|
||||
{
|
||||
/// Struct representing the worth of an entity in terms of mineral resources and oil
|
||||
struct worth {
|
||||
uint32_t resources[NUM_RESOURCES];
|
||||
float oil;
|
||||
|
||||
worth();
|
||||
|
||||
/* Add num resources */
|
||||
/// Add num resources
|
||||
struct worth& add(uint8_t resource_type, uint32_t num);
|
||||
|
||||
/* Add oil */
|
||||
/// Add oil
|
||||
struct worth& add_oil(float val);
|
||||
|
||||
/* Add resources and oil from another worth object */
|
||||
/// Add resources and oil from another worth object
|
||||
struct worth& add(const struct worth& worth);
|
||||
};
|
||||
|
||||
|
|
@ -183,27 +183,32 @@ class connection;
|
|||
#define JOINT_TYPE_SCUP 4
|
||||
#define JOINT_TYPE_RAGDOLL 5
|
||||
|
||||
/// Data attached to connection joints
|
||||
class joint_info {
|
||||
public:
|
||||
int type;
|
||||
void *data;
|
||||
bool should_destroy;
|
||||
joint_info(int type, void *data)
|
||||
{
|
||||
joint_info(int type, void *data) {
|
||||
this->type = type;
|
||||
this->data = data;
|
||||
this->should_destroy = true;
|
||||
}
|
||||
joint_info(){this->should_destroy=true;};
|
||||
|
||||
void destroy() const { if (this->should_destroy) delete this; }
|
||||
joint_info() {
|
||||
this->should_destroy = true;
|
||||
}
|
||||
|
||||
void destroy() const {
|
||||
if (this->should_destroy)
|
||||
delete this;
|
||||
}
|
||||
|
||||
protected:
|
||||
~joint_info() {}
|
||||
};
|
||||
|
||||
class connection
|
||||
{
|
||||
class connection {
|
||||
private:
|
||||
void remove_self_ent();
|
||||
void create_self_ent(bool add);
|
||||
|
|
@ -215,38 +220,43 @@ class connection
|
|||
entity *self_ent;
|
||||
b2Joint *j;
|
||||
|
||||
/* if the connection has an owner, e is the owner */
|
||||
/// if the connection has an owner, e is the owner
|
||||
entity *e;
|
||||
entity *o;
|
||||
|
||||
bool fixed; /* can't be removed */
|
||||
bool tolerant; /* if this joint allows slight displacement */
|
||||
/// can't be removed
|
||||
bool fixed;
|
||||
/// if this joint allows slight displacement
|
||||
bool tolerant;
|
||||
/// if this connection has been destroyed during simulation
|
||||
bool destroyed;
|
||||
|
||||
/* layer of the connection, if the connection spans multiple layers,
|
||||
* this is the lowest layer of the two */
|
||||
/// layer of the connection, if the connection spans multiple layers,
|
||||
/// this is the lowest layer of the two
|
||||
int layer;
|
||||
|
||||
/* sublayer mask of the connection, if the connection span multiple sublayers,
|
||||
* this is the lowest sublayer of the two */
|
||||
/// sublayer mask of the connection, if the connection span multiple sublayers,
|
||||
/// this is the lowest sublayer of the two
|
||||
int layer_mask;
|
||||
|
||||
int sublayer_dist;
|
||||
|
||||
/* if this connection is active, the point is in e's local
|
||||
* coordinate frame, otherwise it is a world point */
|
||||
b2Vec2 p, p_s; /* p_s is the secondary local anchor if weld or pivot joint */
|
||||
/// if this connection is active, the point is in e's local
|
||||
/// coordinate frame, otherwise it is a world point.
|
||||
/// p_s is the secondary local anchor if weld or pivot joint
|
||||
b2Vec2 p, p_s;
|
||||
|
||||
/* Coordinate frames for 'e' and 'o' */
|
||||
/// Coordinate frames for 'e' and 'o'
|
||||
uint8_t f[2];
|
||||
|
||||
bool owned;
|
||||
uint8_t o_index;
|
||||
bool pending;
|
||||
bool multilayer; /* true if the connection spans two layers,
|
||||
the rendered nail will not be rotated */
|
||||
/// true if the connection spans two layers, the rendered nail will not be rotated
|
||||
bool multilayer;
|
||||
|
||||
float relative_angle; /* relative angle of the entities level version 22 */
|
||||
/// relative angle of the entities (level revision >= 22)
|
||||
float relative_angle;
|
||||
|
||||
float angle;
|
||||
uint8_t render_type;
|
||||
|
|
@ -254,19 +264,22 @@ class connection
|
|||
uint8_t option;
|
||||
|
||||
float max_force;
|
||||
float damping; /* level VERSION 8, damping for rotary joints */
|
||||
/// damping for rotary joints (level revision >= 8)
|
||||
float damping;
|
||||
|
||||
uint32_t e_data; /* level version 28 (1.5) information about e */
|
||||
uint32_t o_data; /* level version 28 (1.5) information about o */
|
||||
/// information about e (level version >= 28)
|
||||
uint32_t e_data;
|
||||
/// information about o (level version >= 28)
|
||||
uint32_t o_data;
|
||||
|
||||
/* we keep track of where this conn was last written or read */
|
||||
/// we keep track of where this conn was last written or read
|
||||
size_t write_ptr;
|
||||
/// we keep track of where this conn was last written or read
|
||||
size_t write_size;
|
||||
|
||||
connection *next[2];
|
||||
|
||||
connection()
|
||||
{
|
||||
connection() {
|
||||
this->write_ptr = 0;
|
||||
this->write_size = 0;
|
||||
this->reset();
|
||||
|
|
@ -274,35 +287,33 @@ class connection
|
|||
|
||||
b2Vec2 get_position();
|
||||
|
||||
/// Updates the relative angle between the bodies
|
||||
void update_relative_angle(bool force);
|
||||
|
||||
inline void init_owned(int index, entity *e)
|
||||
{
|
||||
/// Initialise connection, being owned by an entity
|
||||
inline void init_owned(int index, entity *e) {
|
||||
this->reset();
|
||||
this->e = e;
|
||||
this->o_index = index;
|
||||
}
|
||||
|
||||
inline entity *get_other(entity *e)
|
||||
{
|
||||
if (e == this->e) {
|
||||
/// Get the other entity in the connection
|
||||
inline entity *get_other(entity *e) {
|
||||
if (e == this->e)
|
||||
return this->o;
|
||||
} else {
|
||||
else
|
||||
return this->e;
|
||||
}
|
||||
}
|
||||
|
||||
inline connection *get_next(entity *e)
|
||||
{
|
||||
if (e == this->e) {
|
||||
/// Get the next connection for the given entity
|
||||
inline connection *get_next(entity *e) {
|
||||
if (e == this->e)
|
||||
return next[0];
|
||||
} else {
|
||||
else
|
||||
return next[1];
|
||||
}
|
||||
}
|
||||
|
||||
inline void reset(void)
|
||||
{
|
||||
inline void reset() {
|
||||
this->ji = 0;
|
||||
this->layer_mask = 0;
|
||||
this->sublayer_dist = 0;
|
||||
|
|
@ -334,21 +345,21 @@ class connection
|
|||
destroyed = false;
|
||||
}
|
||||
|
||||
void update(void);
|
||||
void apply(void);
|
||||
void update();
|
||||
/// Apply is called the first time the connection is created
|
||||
void apply();
|
||||
void create_joint(bool add);
|
||||
void destroy_joint(void);
|
||||
void destroy_joint();
|
||||
|
||||
/// Update how the connection is rendered in-game
|
||||
void update_render_type();
|
||||
|
||||
connection *clone()
|
||||
{
|
||||
connection *clone() {
|
||||
return new connection(*this);
|
||||
}
|
||||
};
|
||||
|
||||
class property
|
||||
{
|
||||
class property {
|
||||
public:
|
||||
uint8_t type;
|
||||
union {
|
||||
|
|
@ -361,53 +372,60 @@ class property
|
|||
} s;
|
||||
} v;
|
||||
|
||||
property()
|
||||
{
|
||||
property() {
|
||||
clear();
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
|
||||
void clear() {
|
||||
type = 0;
|
||||
memset(&this->v, 0, sizeof(this->v));
|
||||
}
|
||||
|
||||
/* The receiving function is responsible for freeing the return value */
|
||||
/// Serialise the property to a string.
|
||||
/// The receiving function is responsible for freeing the return value
|
||||
char* stringify();
|
||||
|
||||
/// Parse serialised property string back
|
||||
void parse(char *buf);
|
||||
};
|
||||
|
||||
struct entity_listener {
|
||||
entity *self;
|
||||
void *userdata;
|
||||
void (*cb)(entity* self,void* userdata);
|
||||
void (*cb)(entity* self, void* userdata);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* entity pointer is stored in UserData of fixtures
|
||||
* uint8 frame ID is stored in the body's UserData
|
||||
**/
|
||||
/// Main class for entities, including but not limited to objects as visible by players in-game.
|
||||
///
|
||||
/// - Entity pointer is stored in UserData of fixtures
|
||||
/// - uint8 frame ID is stored in the body's UserData
|
||||
class entity : public tms::entity
|
||||
{
|
||||
protected:
|
||||
void easy_update();
|
||||
|
||||
/* shape creation functions, should be called from add_to_world */
|
||||
void create_rect(b2BodyType type, float width, float height, m *m){create_rect(type,width,height,m,NULL);};
|
||||
void create_rect(b2BodyType type, float width, float height, m *m) {
|
||||
create_rect(type,width,height,m,NULL);
|
||||
}
|
||||
|
||||
void create_rect(b2BodyType type, float width, float height, m *m, b2Fixture **fixture_out=NULL);
|
||||
void create_circle(b2BodyType type, float radius, m *mat);
|
||||
|
||||
void create_rect(b2BodyType type, float width, float height, struct tms_material *mat){create_rect(type,width,height,static_cast<m*>(mat),NULL);};
|
||||
void create_circle(b2BodyType type, float radius, struct tms_material* mat){ create_circle(type,radius,static_cast<m*>(mat)); };
|
||||
void create_rect(b2BodyType type, float width, float height, struct tms_material *mat) {
|
||||
create_rect(type,width,height,static_cast<m*>(mat),NULL);
|
||||
}
|
||||
|
||||
void create_circle(b2BodyType type, float radius, struct tms_material* mat) {
|
||||
create_circle(type,radius,static_cast<m*>(mat));
|
||||
}
|
||||
|
||||
float m_scale;
|
||||
float width; /* approximate width of the object, used for the menu rendering
|
||||
and for positioning the rotation anchor */
|
||||
/// Approximate width of the object, used for e.g. positioning the rotation anchor
|
||||
float width;
|
||||
|
||||
public:
|
||||
inline void fastbody_update()
|
||||
{
|
||||
inline void fastbody_update() {
|
||||
const b2Transform &t = this->body->GetTransform();
|
||||
|
||||
//tmat4_load_identity(this->M);
|
||||
|
|
@ -428,37 +446,30 @@ class entity : public tms::entity
|
|||
void unsubscribe(entity *target);
|
||||
void signal(int event);
|
||||
|
||||
inline float get_scale() const
|
||||
{
|
||||
inline float get_scale() const {
|
||||
return this->m_scale;
|
||||
}
|
||||
|
||||
void set_scale(float new_scale)
|
||||
{
|
||||
void set_scale(float new_scale) {
|
||||
float old_scale = this->get_scale();
|
||||
|
||||
this->m_scale = new_scale;
|
||||
|
||||
this->scale_changed(old_scale, new_scale);
|
||||
}
|
||||
|
||||
inline float get_width() const
|
||||
{
|
||||
inline float get_width() const {
|
||||
return this->width * this->get_scale();
|
||||
}
|
||||
|
||||
virtual void scale_changed(float old_scale, float new_scale)
|
||||
{
|
||||
virtual void scale_changed(float old_scale, float new_scale) {
|
||||
this->recreate_fixtures(false);
|
||||
}
|
||||
|
||||
virtual void recreate_fixtures(bool initial) { }
|
||||
|
||||
virtual void set_color(tvec4 c) {}
|
||||
virtual tvec4 get_color() {return tvec4f(0.f, 0.f, 0.f, 0.f);}
|
||||
virtual tvec4 get_color() {return tvec4f(0.f, 0.f, 0.f, 0.f); }
|
||||
|
||||
void set_color4(float r, float g, float b, float a=1.0f)
|
||||
{
|
||||
void set_color4(float r, float g, float b, float a=1.0f) {
|
||||
this->set_color(tvec4f(r, g, b, a));
|
||||
}
|
||||
|
||||
|
|
@ -469,11 +480,12 @@ class entity : public tms::entity
|
|||
int curr_update_method;
|
||||
b2Body *body;
|
||||
uint8_t layer_mask;
|
||||
//entity *owner;
|
||||
property *properties;
|
||||
uint8_t num_properties;
|
||||
|
||||
p_gid g_id; /* global object type identifier */
|
||||
/// Global object type identifier
|
||||
p_gid g_id;
|
||||
/// ID of entity it was emitted by, for e.g. weapon projectiles
|
||||
uint32_t emitted_by;
|
||||
uint32_t emit_step;
|
||||
|
||||
|
|
@ -485,7 +497,7 @@ class entity : public tms::entity
|
|||
b2Vec2 menu_pos;
|
||||
b2Vec2 old_pos;
|
||||
|
||||
/* Used as a base for connection-checking */
|
||||
/// Used as a base for connection-checking
|
||||
b2Vec2 query_sides[4];
|
||||
float query_len;
|
||||
|
||||
|
|
@ -493,12 +505,12 @@ class entity : public tms::entity
|
|||
float _angle;
|
||||
int dialog_id;
|
||||
|
||||
/* default state contains velocity and angular velocity of a single body */
|
||||
/// default state contains velocity and angular velocity of a single body
|
||||
float state[3];
|
||||
size_t state_ptr;
|
||||
size_t state_size;
|
||||
|
||||
/* we keep track of where this entity was last written or read */
|
||||
/// we keep track of where this entity was last written or read
|
||||
size_t write_ptr;
|
||||
size_t write_size;
|
||||
|
||||
|
|
@ -510,13 +522,11 @@ class entity : public tms::entity
|
|||
uint8_t protection_status;
|
||||
void update_protection_status();
|
||||
|
||||
virtual void set_moveable(bool moveable)
|
||||
{
|
||||
virtual void set_moveable(bool moveable) {
|
||||
this->set_flag(ENTITY_IS_MOVEABLE, moveable);
|
||||
}
|
||||
|
||||
bool is_moveable()
|
||||
{
|
||||
bool is_moveable() {
|
||||
return this->flag_active(ENTITY_IS_MOVEABLE);
|
||||
}
|
||||
|
||||
|
|
@ -529,87 +539,130 @@ class entity : public tms::entity
|
|||
|
||||
uint64_t flags;
|
||||
|
||||
virtual uint32_t get_fixture_connection_data(b2Fixture *f){return 0;};
|
||||
virtual uint32_t get_fixture_connection_data(b2Fixture *f) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool flag_active(uint64_t flag)
|
||||
{
|
||||
inline bool flag_active(uint64_t flag) {
|
||||
return this->flags & flag;
|
||||
}
|
||||
|
||||
float get_total_mass()
|
||||
{
|
||||
float get_total_mass() {
|
||||
float mass = 0.f;
|
||||
b2Body *b;
|
||||
|
||||
for (int x=0; x<this->get_num_bodies(); x++) {
|
||||
if ((b = this->get_body(x))) {
|
||||
for (int x=0; x<this->get_num_bodies(); x++)
|
||||
if ((b = this->get_body(x)))
|
||||
mass += b->GetMass();
|
||||
}
|
||||
}
|
||||
|
||||
return mass;
|
||||
}
|
||||
|
||||
inline void set_flag(uint64_t flag, bool v)
|
||||
{
|
||||
if (v) {
|
||||
inline void set_flag(uint64_t flag, bool v) {
|
||||
if (v)
|
||||
this->flags |= flag;
|
||||
} else {
|
||||
else
|
||||
this->flags &= ~flag;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns true if the entity has a wireless functionality, meaning it
|
||||
* has at least one property and that first property is used for as
|
||||
* a wireless frequency. */
|
||||
inline bool is_wireless()
|
||||
{
|
||||
/// Returns true if the entity has a wireless functionality, meaning it
|
||||
/// has at least one property and that first property is used for as
|
||||
/// a wireless frequency.
|
||||
inline bool is_wireless() {
|
||||
return (this->g_id == O_RECEIVER || this->g_id == O_TRANSMITTER || this->g_id == O_MINI_TRANSMITTER);
|
||||
}
|
||||
|
||||
inline bool is_item()
|
||||
{
|
||||
return (this->g_id == O_ITEM);
|
||||
inline bool is_item() {
|
||||
return this->g_id == O_ITEM;
|
||||
}
|
||||
|
||||
inline bool is_prompt_compatible()
|
||||
{
|
||||
inline bool is_prompt_compatible() {
|
||||
return this->flag_active(ENTITY_IS_PROMPT);
|
||||
}
|
||||
|
||||
virtual bool is_zappable() { return this->flag_active(ENTITY_IS_ZAPPABLE); }
|
||||
virtual bool is_zappable() {
|
||||
return this->flag_active(ENTITY_IS_ZAPPABLE);
|
||||
}
|
||||
|
||||
inline bool is_explosive() { return this->flag_active(ENTITY_IS_EXPLOSIVE); }
|
||||
inline bool is_compressable() { return this->flag_active(ENTITY_CAN_BE_COMPRESSED); }
|
||||
inline bool is_static() { return this->flag_active(ENTITY_IS_STATIC); }
|
||||
inline bool is_bullet() { return this->flag_active(ENTITY_IS_BULLET); }
|
||||
inline bool is_creature() { return this->flag_active(ENTITY_IS_CREATURE); }
|
||||
inline bool is_robot() { return this->flag_active(ENTITY_IS_ROBOT); }
|
||||
inline bool is_control_panel() { return this->flag_active(ENTITY_IS_CONTROL_PANEL); }
|
||||
inline bool is_rc() { return this->flag_active(ENTITY_IS_CONTROL_PANEL); }
|
||||
inline bool is_edevice() { return this->flag_active(ENTITY_IS_EDEVICE); }
|
||||
inline bool is_interactive() { return this->flag_active(ENTITY_IS_INTERACTIVE); }
|
||||
inline bool is_composable() { return this->flag_active(ENTITY_IS_COMPOSABLE); }
|
||||
inline bool is_wheel() { return (this->type == ENTITY_WHEEL || this->type == ENTITY_GEAR); }
|
||||
inline bool is_gearbox() { return (this->g_id == O_GEARBOX); }
|
||||
inline bool allow_connections() { return this->flag_active(ENTITY_ALLOW_CONNECTIONS); }
|
||||
inline bool has_tracker() { return this->flag_active(ENTITY_HAS_TRACKER); }
|
||||
virtual bool is_locked() { return this->flag_active(ENTITY_IS_LOCKED); }
|
||||
inline bool is_explosive() {
|
||||
return this->flag_active(ENTITY_IS_EXPLOSIVE);
|
||||
}
|
||||
|
||||
/// Can entity be compressed by the compressor item?
|
||||
inline bool is_compressable() {
|
||||
return this->flag_active(ENTITY_CAN_BE_COMPRESSED);
|
||||
}
|
||||
|
||||
inline bool is_static() {
|
||||
return this->flag_active(ENTITY_IS_STATIC);
|
||||
}
|
||||
|
||||
inline bool is_bullet() {
|
||||
return this->flag_active(ENTITY_IS_BULLET);
|
||||
}
|
||||
|
||||
inline bool is_creature() {
|
||||
return this->flag_active(ENTITY_IS_CREATURE);
|
||||
}
|
||||
|
||||
inline bool is_robot() {
|
||||
return this->flag_active(ENTITY_IS_ROBOT);
|
||||
}
|
||||
|
||||
inline bool is_control_panel() {
|
||||
return this->flag_active(ENTITY_IS_CONTROL_PANEL);
|
||||
}
|
||||
|
||||
inline bool is_edevice() {
|
||||
return this->flag_active(ENTITY_IS_EDEVICE);
|
||||
}
|
||||
|
||||
inline bool is_interactive() {
|
||||
return this->flag_active(ENTITY_IS_INTERACTIVE);
|
||||
}
|
||||
|
||||
inline bool is_composable() {
|
||||
return this->flag_active(ENTITY_IS_COMPOSABLE);
|
||||
}
|
||||
|
||||
inline bool is_wheel() {
|
||||
return (this->type == ENTITY_WHEEL || this->type == ENTITY_GEAR);
|
||||
}
|
||||
|
||||
inline bool is_gearbox() {
|
||||
return (this->g_id == O_GEARBOX);
|
||||
}
|
||||
|
||||
inline bool allow_connections() {
|
||||
return this->flag_active(ENTITY_ALLOW_CONNECTIONS);
|
||||
}
|
||||
|
||||
inline bool has_tracker() {
|
||||
return this->flag_active(ENTITY_HAS_TRACKER);
|
||||
}
|
||||
|
||||
virtual bool is_locked() {
|
||||
return this->flag_active(ENTITY_IS_LOCKED);
|
||||
}
|
||||
|
||||
/// If this function returns true, then when the entity is to be deleted by
|
||||
/// pressing Delete or the "remove entity" widget, a confirmation will be shown.
|
||||
virtual bool requires_delete_confirmation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If this function returns true, then when the entity is to be deleted by
|
||||
* pressing Delete or the "remove entity" widget, a confirmation will be shown. */
|
||||
virtual bool requires_delete_confirmation() { return false; }
|
||||
bool is_motor();
|
||||
|
||||
bool is_high_prio();
|
||||
|
||||
bool interacted_with; /* if the player has interacted with this entity
|
||||
allows us to bypass auto protect and platform protect */
|
||||
/// if the player has interacted with this entity.
|
||||
/// allows us to bypass auto protect and platform protect
|
||||
bool interacted_with;
|
||||
|
||||
entity();
|
||||
virtual ~entity();
|
||||
|
||||
inline int sublayer_dist(entity *e)
|
||||
{
|
||||
inline int sublayer_dist(entity *e) {
|
||||
int l0 = this->get_layer()*4;
|
||||
int l1 = e->get_layer()*4;
|
||||
|
||||
|
|
@ -636,25 +689,33 @@ class entity : public tms::entity
|
|||
|
||||
virtual void prepare_fadeout();
|
||||
|
||||
virtual void ghost_update(){update();}
|
||||
virtual void ghost_update() {
|
||||
update();
|
||||
}
|
||||
|
||||
virtual void construct(){}
|
||||
virtual void construct() {}
|
||||
|
||||
virtual edevice *get_edevice(){return 0;}
|
||||
virtual base_prompt *get_base_prompt(){return 0;}
|
||||
virtual edevice *get_edevice() { return 0; }
|
||||
virtual base_prompt *get_base_prompt() { return 0; }
|
||||
virtual activator *get_activator() { return 0; }
|
||||
void sidecheck(connection *c);
|
||||
void sidecheck4(connection *cc);
|
||||
|
||||
/**
|
||||
* Get all chunks that this entity is intersecting with
|
||||
* We can get that info by looping through all bodies and checking their
|
||||
* contacts.
|
||||
*
|
||||
* Static bodies don't collide with the sensors so for static bodies
|
||||
* we instead calculate chunk intersection using width and height
|
||||
*/
|
||||
void get_chunk_intersections(std::set<chunk_pos> *chunks);
|
||||
|
||||
virtual void remove_connection(connection *cr);
|
||||
virtual void destroy_connection(connection *cr);
|
||||
virtual void disconnect_all();
|
||||
|
||||
b2Joint*
|
||||
find_pivot(int dir, bool recursive)
|
||||
{
|
||||
b2Joint* find_pivot(int dir, bool recursive) {
|
||||
if (this->is_wheel()) {
|
||||
connection *c = this->conn_ll;
|
||||
|
||||
|
|
@ -673,20 +734,16 @@ class entity : public tms::entity
|
|||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
inline void
|
||||
add_connection(connection *c)
|
||||
{
|
||||
inline void add_connection(connection *c) {
|
||||
//tms_infof("%p add connection %p", this, c);
|
||||
connection *bkp = this->conn_ll;
|
||||
this->conn_ll = c;
|
||||
c->next[(this == c->e) ? 0:1] = bkp;
|
||||
}
|
||||
|
||||
inline bool
|
||||
connected_to(entity *e)
|
||||
{
|
||||
inline bool connected_to(entity *e) {
|
||||
if (!this->conn_ll) return false;
|
||||
|
||||
connection *c = this->conn_ll;
|
||||
|
|
@ -713,89 +770,81 @@ class entity : public tms::entity
|
|||
int layer=-1
|
||||
);
|
||||
|
||||
inline m* get_material(void)
|
||||
{
|
||||
inline m* get_material(void) {
|
||||
return (m *)this->material;
|
||||
}
|
||||
|
||||
virtual b2PolygonShape* get_resizable_shape(){return 0;};
|
||||
virtual int get_resizable_vertices(int *out){return 0;};
|
||||
virtual int get_resizable_edges(int *out){return 0;};
|
||||
virtual bool on_resize_vertex(int v, b2Vec2 new_pos){return false;};
|
||||
virtual bool on_resize_edge(int e, float movement){return false;};
|
||||
virtual b2PolygonShape* get_resizable_shape() { return 0; }
|
||||
virtual int get_resizable_vertices(int *out) { return 0; }
|
||||
virtual int get_resizable_edges(int *out) { return 0; }
|
||||
virtual bool on_resize_vertex(int v, b2Vec2 new_pos) { return false; }
|
||||
virtual bool on_resize_edge(int e, float movement) { return false; }
|
||||
|
||||
virtual const char *get_slider_label(int s){return 0;};
|
||||
virtual const char *get_slider_tooltip(int s){return 0;};
|
||||
virtual float get_slider_snap(int s){return 0.f;};
|
||||
virtual float get_slider_value(int s){return 0.f;};
|
||||
virtual void on_slider_change(int s, float value){};
|
||||
virtual const char *get_slider_label(int s) { return 0; }
|
||||
virtual const char *get_slider_tooltip(int s) { return 0; }
|
||||
virtual float get_slider_snap(int s) { return 0.f; }
|
||||
virtual float get_slider_value(int s) {return 0.f; }
|
||||
virtual void on_slider_change(int s, float value) {}
|
||||
|
||||
virtual entity *get_property_entity(void){return this;};
|
||||
virtual entity *get_property_entity(void) {return this; }
|
||||
|
||||
virtual void update_effects(){};
|
||||
virtual void update_effects() {}
|
||||
virtual void update();
|
||||
virtual void step(){};
|
||||
virtual void mstep(){};
|
||||
virtual void tick(){};
|
||||
virtual void pre_step(){};
|
||||
virtual void step() {}
|
||||
virtual void mstep() {}
|
||||
virtual void tick() {}
|
||||
virtual void pre_step() {}
|
||||
virtual void set_layer(int z);
|
||||
void set_prio(int z);
|
||||
|
||||
// this is only fired in play-mode
|
||||
virtual int handle_event(uint32_t type, uint64_t pointer_id, tvec2 pos){return EVENT_CONT;};
|
||||
/// this is only fired in play-mode
|
||||
virtual int handle_event(uint32_t type, uint64_t pointer_id, tvec2 pos) { return EVENT_CONT; }
|
||||
|
||||
virtual void set_position(float x, float y, uint8_t frame=0);
|
||||
inline void set_position(b2Vec2 p, uint8_t frame=0) { set_position(p.x, p.y, frame); }
|
||||
|
||||
virtual b2Vec2 get_position();
|
||||
virtual b2Vec2 get_position(uint8_t frame){return local_to_world(b2Vec2(0.f,0.f), frame);};
|
||||
virtual b2Vec2 get_position(uint8_t frame) { return local_to_world(b2Vec2(0.f,0.f), frame); }
|
||||
|
||||
virtual void set_angle(float a);
|
||||
virtual void set_angle(float a,uint8_t frame){set_angle(a);};
|
||||
virtual void set_angle(float a,uint8_t frame) { set_angle(a); }
|
||||
|
||||
virtual float get_angle();
|
||||
virtual float get_angle(uint8_t frame){return get_angle();};
|
||||
virtual float get_angle(uint8_t frame) { return get_angle(); }
|
||||
|
||||
virtual void add_to_world()=0;
|
||||
virtual void remove_from_world();
|
||||
virtual void connection_create_joint(connection *c){};
|
||||
virtual bool connection_destroy_joint(connection *c){return false;};
|
||||
virtual void connection_create_joint(connection *c) { }
|
||||
virtual bool connection_destroy_joint(connection *c) { return false; }
|
||||
|
||||
/* state reading/writing */
|
||||
virtual void restore();
|
||||
virtual void write_state(lvlinfo *lvl, lvlbuf *lb);
|
||||
virtual void read_state(lvlinfo *lvl, lvlbuf *lb);
|
||||
|
||||
virtual void toggle_axis_rot(){};
|
||||
virtual void toggle_axis_rot() {}
|
||||
virtual void set_locked(bool locked, bool immediate=true);
|
||||
virtual void load_flags(uint64_t f);
|
||||
virtual uint64_t save_flags();
|
||||
virtual bool get_axis_rot(){return this->flag_active(ENTITY_AXIS_ROT);};
|
||||
virtual bool get_axis_rot() { return this->flag_active(ENTITY_AXIS_ROT); }
|
||||
virtual const char *get_axis_rot_tooltip() { return "Toggle axis rotation"; }
|
||||
virtual struct tms_sprite * get_axis_rot_sprite(){return 0;};
|
||||
virtual struct tms_sprite * get_axis_rot_sprite() { return 0; }
|
||||
|
||||
/* "editor" events */
|
||||
/* XXX */
|
||||
virtual void on_grab(game *g);
|
||||
virtual void on_release(game *g);
|
||||
|
||||
virtual void on_grab_playing(){};
|
||||
virtual void on_release_playing(){};
|
||||
virtual void on_grab_playing() {}
|
||||
virtual void on_release_playing() {}
|
||||
|
||||
virtual void on_touch(b2Fixture *my, b2Fixture *other);
|
||||
virtual void on_untouch(b2Fixture *my, b2Fixture *other);
|
||||
|
||||
virtual void on_paused_touch(b2Fixture *my, b2Fixture *other){};
|
||||
virtual void on_paused_untouch(b2Fixture *my, b2Fixture *other){};
|
||||
virtual void on_paused_touch(b2Fixture *my, b2Fixture *other) {}
|
||||
virtual void on_paused_untouch(b2Fixture *my, b2Fixture *other) {}
|
||||
|
||||
/*
|
||||
virtual void collision_begin(b2Contact *c, int order) = 0;
|
||||
virtual void collision_presolve(b2Contact *c, int order) = 0;
|
||||
virtual void collision_postsolve(b2Contact *c, int order) = 0;
|
||||
virtual void collision_end(b2Contact *c, int order) = 0;
|
||||
*/
|
||||
|
||||
inline int get_layer(){return this->prio;};
|
||||
inline int get_layer() { return this->prio; }
|
||||
|
||||
virtual bool compatible_with(entity *o);
|
||||
|
||||
|
|
@ -809,12 +858,11 @@ class entity : public tms::entity
|
|||
|
||||
virtual uint32_t get_num_bodies();
|
||||
virtual b2Body *get_body(uint8_t frame);
|
||||
virtual void find_pairs(){};
|
||||
virtual void find_pairs() {}
|
||||
|
||||
virtual const char *get_name(void) = 0;
|
||||
|
||||
virtual const char *get_real_name(void)
|
||||
{
|
||||
virtual const char *get_real_name(void) {
|
||||
return this->get_name();
|
||||
}
|
||||
|
||||
|
|
@ -823,42 +871,36 @@ class entity : public tms::entity
|
|||
virtual void write_object_id(char *out);
|
||||
|
||||
virtual void pre_write(void);
|
||||
virtual void post_write(void){};
|
||||
virtual void on_load(bool created, bool has_state){};
|
||||
virtual connection* load_connection(connection &conn){return 0;};
|
||||
virtual void post_write(void) {}
|
||||
virtual void on_load(bool created, bool has_state) {}
|
||||
virtual connection* load_connection(connection &conn) { return 0; }
|
||||
|
||||
inline void initialize_interactive(void)
|
||||
{
|
||||
inline void initialize_interactive(void) {
|
||||
this->in_dragfield = 0;
|
||||
this->interactive_hp = 1.f;
|
||||
};
|
||||
}
|
||||
|
||||
/* Init is always called, regardless if the entity
|
||||
* has a state to be loaded or not. */
|
||||
virtual void init() {};
|
||||
/// Init is always called, regardless if the entity has a state to be loaded or not.
|
||||
virtual void init() {}
|
||||
|
||||
/* Setup is called after init if the entity has no
|
||||
* state to load from */
|
||||
virtual void setup()
|
||||
{
|
||||
/// Setup is called after init if the entity has no state to load from
|
||||
virtual void setup() {
|
||||
this->listeners.clear();
|
||||
this->subscriptions.clear();
|
||||
};
|
||||
}
|
||||
|
||||
virtual void on_pause()
|
||||
{
|
||||
virtual void on_pause() {
|
||||
this->subscriptions.clear();
|
||||
this->listeners.clear();
|
||||
};
|
||||
}
|
||||
|
||||
virtual void on_absorb() {};
|
||||
virtual void on_absorb() {}
|
||||
|
||||
inline void on_entity_play()
|
||||
{
|
||||
inline void on_entity_play() {
|
||||
this->interacted_with = false;
|
||||
}
|
||||
|
||||
virtual bool allow_connection(entity *asker, uint8_t frame, b2Vec2 p){return true;};
|
||||
virtual bool allow_connection(entity *asker, uint8_t frame, b2Vec2 p) { return true; }
|
||||
virtual bool enjoys_connection(uint32_t g_id) { return false; }
|
||||
|
||||
/* Zappable stuff */
|
||||
|
|
@ -873,16 +915,14 @@ class entity : public tms::entity
|
|||
void set_property(uint8_t id, uint32_t v);
|
||||
void set_property(uint8_t id, const char *v);
|
||||
void set_propertyi8(uint8_t id, uint8_t v);
|
||||
inline void set_property(uint8_t id, uint8_t v){set_property(id, (uint32_t)v);};
|
||||
inline void set_property(uint8_t id, uint16_t v){set_property(id, (uint32_t)v);};
|
||||
inline void set_property(uint8_t id, uint8_t v) { set_property(id, (uint32_t)v); }
|
||||
inline void set_property(uint8_t id, uint16_t v) { set_property(id, (uint32_t)v); }
|
||||
void set_property(uint8_t id, const char *v, uint32_t len);
|
||||
|
||||
void set_num_properties(uint8_t num);
|
||||
void reset_flags(void);
|
||||
|
||||
/* this takes a value between 0.0 and 1.0 and converts it to the proper density scale value */
|
||||
void help_set_density_scale(float value)
|
||||
{
|
||||
/// this takes a value between 0.0 and 1.0 and converts it to the proper density scale value
|
||||
void help_set_density_scale(float value) {
|
||||
this->set_density_scale(ENTITY_DENSITY_SCALE_MIN + value*(ENTITY_DENSITY_SCALE_MAX-ENTITY_DENSITY_SCALE_MIN));
|
||||
}
|
||||
|
||||
|
|
@ -890,7 +930,7 @@ class entity : public tms::entity
|
|||
static tvec2 get_nearest_point(const b2Vec2 &query_point, b2Fixture *fx);
|
||||
|
||||
virtual void set_density_scale(float v) {}
|
||||
virtual float get_density_scale(){return 1.f;};
|
||||
virtual float get_density_scale() { return 1.f; }
|
||||
|
||||
virtual uint32_t get_sub_id() { return 0; }
|
||||
|
||||
|
|
@ -899,19 +939,17 @@ class entity : public tms::entity
|
|||
friend class connection;
|
||||
};
|
||||
|
||||
class entity_simpleconnect : public entity, public b2RayCastCallback
|
||||
{
|
||||
class entity_simpleconnect : public entity, public b2RayCastCallback {
|
||||
public:
|
||||
b2Vec2 query_pt;
|
||||
b2Vec2 query_vec; /* Set in the constructor of the
|
||||
object, direction of raycast */
|
||||
/// Set in the constructor of the object, direction of raycast
|
||||
b2Vec2 query_vec;
|
||||
entity *query_result;
|
||||
b2Fixture *query_result_fx;
|
||||
uint8_t query_frame;
|
||||
connection c;
|
||||
|
||||
entity_simpleconnect()
|
||||
{
|
||||
entity_simpleconnect() {
|
||||
this->c.init_owned(0, this);
|
||||
this->c.type = CONN_GROUP;
|
||||
this->query_vec = b2Vec2(0.f, -.5f);
|
||||
|
|
@ -923,13 +961,11 @@ class entity_simpleconnect : public entity, public b2RayCastCallback
|
|||
void find_pairs();
|
||||
};
|
||||
|
||||
class entity_multiconnect : public entity
|
||||
{
|
||||
class entity_multiconnect : public entity {
|
||||
public:
|
||||
connection c_side[4];
|
||||
|
||||
entity_multiconnect()
|
||||
{
|
||||
entity_multiconnect() {
|
||||
this->c_side[0].init_owned(0, this); this->c_side[0].type = CONN_GROUP;
|
||||
this->c_side[1].init_owned(1, this); this->c_side[1].type = CONN_GROUP;
|
||||
this->c_side[2].init_owned(2, this); this->c_side[2].type = CONN_GROUP;
|
||||
|
|
@ -940,21 +976,4 @@ class entity_multiconnect : public entity
|
|||
void find_pairs();
|
||||
};
|
||||
|
||||
class ghost : public entity, public b2QueryCallback
|
||||
{
|
||||
public:
|
||||
connection c;
|
||||
|
||||
ghost();
|
||||
void update();
|
||||
const char *get_name(){return "Shape Extruder";};
|
||||
void init();
|
||||
bool ReportFixture(b2Fixture *f);
|
||||
void find_pairs();
|
||||
void add_to_world();
|
||||
connection* load_connection(connection &conn);
|
||||
void connection_create_joint(connection *c);
|
||||
bool connection_destroy_joint(connection *c);
|
||||
};
|
||||
|
||||
void entity_fast_update(struct tms_entity *t);
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#include "screenshot_marker.hh"
|
||||
#include "scup.hh"
|
||||
#include "settings.hh"
|
||||
#include "shape_extruder.hh"
|
||||
#include "simplebg.hh"
|
||||
#include "soundman.hh"
|
||||
#include "soundmanager.hh"
|
||||
|
|
@ -3349,7 +3350,7 @@ game::render()
|
|||
case O_SHAPE_EXTRUDER: {
|
||||
// Draw bounding box of Shape extruder
|
||||
|
||||
ghost *g = static_cast<ghost*>(this->selection.e);
|
||||
shape_extruder *g = static_cast<shape_extruder*>(this->selection.e);
|
||||
if (g->conn_ll) {
|
||||
tms_ddraw_set_color(this->dd, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
composable *other = static_cast<composable*>(g->c.o);
|
||||
|
|
@ -4930,7 +4931,7 @@ game::set_control_panel(entity *e)
|
|||
wdg_misc_i = 0;
|
||||
|
||||
if (this->current_panel) {
|
||||
if (this->current_panel->is_rc()) {
|
||||
if (this->current_panel->is_control_panel()) {
|
||||
/* If we are already connected to a panel and it's an RC,
|
||||
* call the panel_disconnected for the RC.
|
||||
*
|
||||
|
|
@ -4968,7 +4969,7 @@ game::set_control_panel(entity *e)
|
|||
return;
|
||||
}
|
||||
|
||||
panel *p = (e && e->is_rc() ? static_cast<panel*>(e) : 0);
|
||||
panel *p = (e && e->is_control_panel() ? static_cast<panel*>(e) : 0);
|
||||
creature *c = (e && e->is_creature() ? static_cast<creature*>(e) : 0);
|
||||
|
||||
this->current_panel = e;
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@
|
|||
#include "seesaw.hh"
|
||||
#include "sequencer.hh"
|
||||
#include "sfxemitter.hh"
|
||||
#include "shape_extruder.hh"
|
||||
#include "shelf.hh"
|
||||
#include "sincos.hh"
|
||||
#include "sinewave.hh"
|
||||
|
|
@ -351,7 +352,7 @@ static entity* new_snap(void){return new snapgate();};
|
|||
static entity* new_var_getter(void){return new var_getter();};
|
||||
static entity* new_var_setter(void){return new var_setter();};
|
||||
static entity* new_sequencer(void){return new sequencer();};
|
||||
static entity* new_ghost(void){return new ghost();};
|
||||
static entity* new_shape_extruder(void){return new shape_extruder();};
|
||||
static entity* new_cursorfield(void){return new cursorfield();};
|
||||
static entity* new_escript(void){return new escript();};
|
||||
static entity* new_ldecay(void){return new ldecay();};
|
||||
|
|
@ -574,7 +575,7 @@ static entity* (*c_creator[])(void) = {
|
|||
&new_var_setter,
|
||||
&new_snap,
|
||||
&new_sequencer,
|
||||
&new_ghost, /* 180 */
|
||||
&new_shape_extruder, /* 180 */
|
||||
&new_ldecay,
|
||||
&new_elimit,
|
||||
&new_cursorfield,
|
||||
|
|
|
|||
171
src/shape_extruder.cc
Normal file
171
src/shape_extruder.cc
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
#include "shape_extruder.hh"
|
||||
#include "entity.hh"
|
||||
#include "game.hh"
|
||||
#include "model.hh"
|
||||
#include "ui.hh"
|
||||
|
||||
shape_extruder::shape_extruder() {
|
||||
this->set_flag(ENTITY_IS_BETA, true);
|
||||
this->set_flag(ENTITY_ALLOW_CONNECTIONS, false);
|
||||
this->set_flag(ENTITY_ALLOW_ROTATION, false);
|
||||
this->set_flag(ENTITY_HAS_CONFIG, true);
|
||||
|
||||
this->dialog_id = DIALOG_SHAPEEXTRUDER;
|
||||
|
||||
this->set_mesh(mesh_factory::get_mesh(MODEL_BOX0));
|
||||
this->set_material(&m_red);
|
||||
this->layer_mask = 1;
|
||||
this->update_method = ENTITY_UPDATE_CUSTOM;
|
||||
|
||||
this->set_num_properties(4);
|
||||
|
||||
this->properties[0].type = P_FLT;
|
||||
this->properties[0].v.f = 0.f; /* extra right */
|
||||
|
||||
this->properties[1].type = P_FLT;
|
||||
this->properties[1].v.f = 0.f; /* extra up */
|
||||
|
||||
this->properties[2].type = P_FLT;
|
||||
this->properties[2].v.f = 0.f; /* extra left */
|
||||
|
||||
this->properties[3].type = P_FLT;
|
||||
this->properties[3].v.f = 1.f; /* extra down */
|
||||
|
||||
this->c.init_owned(0, this);
|
||||
this->c.type = CONN_CUSTOM;
|
||||
}
|
||||
|
||||
connection *shape_extruder::load_connection(connection &conn) {
|
||||
this->c = conn;
|
||||
return &this->c;
|
||||
}
|
||||
|
||||
void shape_extruder::update() {
|
||||
if (G && !W->is_paused()) {
|
||||
// Hide the object when in-game
|
||||
memset(this->M, 0, sizeof(float)*16);
|
||||
return;
|
||||
}
|
||||
|
||||
entity *ths = static_cast<entity*>(this);
|
||||
|
||||
if (ths->body) {
|
||||
b2Transform t;
|
||||
t = ths->body->GetTransform();
|
||||
|
||||
tmat4_load_identity(ths->M);
|
||||
ths->M[0] = t.q.c;
|
||||
ths->M[1] = t.q.s;
|
||||
ths->M[4] = -t.q.s;
|
||||
ths->M[5] = t.q.c;
|
||||
ths->M[12] = t.p.x;
|
||||
ths->M[13] = t.p.y;
|
||||
ths->M[14] = ths->prio * LAYER_DEPTH;
|
||||
|
||||
tmat3_copy_mat4_sub3x3(ths->N, ths->M);
|
||||
} else {
|
||||
//tms_infof("rendering with _pos");
|
||||
tmat4_load_identity(ths->M);
|
||||
tmat4_translate(ths->M, ths->_pos.x, ths->_pos.y, 0);
|
||||
tmat4_rotate(ths->M, ths->_angle * (180.f/M_PI), 0, 0, -1);
|
||||
tmat3_copy_mat4_sub3x3(ths->N, ths->M);
|
||||
/* XXX rotate */
|
||||
}
|
||||
}
|
||||
|
||||
void shape_extruder::connection_create_joint(connection *c) {
|
||||
c->j = (b2Joint*)1;
|
||||
c->max_force = INFINITY;
|
||||
|
||||
if (W->is_paused()) {
|
||||
b2WeldJointDef wjd;
|
||||
wjd.localAnchorA = c->e->local_to_body(b2Vec2(0.f, 0.f), c->f[0]);
|
||||
wjd.localAnchorB = c->o->local_to_body(b2Vec2(0.f, 0.f), c->f[1]);
|
||||
|
||||
wjd.bodyA = c->e->get_body(c->f[0]);
|
||||
wjd.bodyB = c->o->get_body(c->f[1]);
|
||||
wjd.referenceAngle = c->o->get_body(c->f[1])->GetAngle() - c->e->get_body(c->f[0])->GetAngle();
|
||||
wjd.collideConnected = false;
|
||||
wjd.frequencyHz = 0.f;
|
||||
|
||||
c->j = W->b2->CreateJoint(&wjd);
|
||||
}
|
||||
}
|
||||
|
||||
bool shape_extruder::connection_destroy_joint(connection *c) {
|
||||
return !(c->j != (void*)1 && c->j != 0);
|
||||
}
|
||||
|
||||
bool shape_extruder::ReportFixture(b2Fixture *f) {
|
||||
entity *e = static_cast<entity*>(f->GetUserData());
|
||||
|
||||
if (e && e != this) {
|
||||
uint8_t frame = (uint8_t)(uintptr_t)(f->GetBody()->GetUserData());
|
||||
if (this->c.pending && frame == 0 && e->get_body(frame)->GetFixtureList()[0].TestPoint(this->get_position())
|
||||
&& e->flag_active(ENTITY_IS_COMPOSABLE)
|
||||
&& e->get_layer() == this->get_layer()) {
|
||||
this->c.type = CONN_CUSTOM;
|
||||
this->c.o = e;
|
||||
this->c.p = e->get_position();
|
||||
this->c.o_data = e->get_fixture_connection_data(f);
|
||||
G->add_pair(this, e, &this->c);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void shape_extruder::init() {
|
||||
//this->create_rect(w, b2_dynamicBody, .5f, .5, this->material);
|
||||
|
||||
if (this->conn_ll && this->c.o && this->c.o->flag_active(ENTITY_IS_COMPOSABLE)) {
|
||||
composable *other = static_cast<composable*>(this->c.o);
|
||||
|
||||
if (!other)
|
||||
return;
|
||||
|
||||
float w = other->get_width();
|
||||
float h = other->height;
|
||||
|
||||
b2Filter f = other->fx->GetFilterData();
|
||||
f.groupIndex = 1+this->get_layer();
|
||||
other->fx->SetFilterData(f);
|
||||
//other->fx->SetSensor(true);
|
||||
|
||||
b2PolygonShape sh;
|
||||
|
||||
b2Vec2 vertices[4] = {
|
||||
other->local_to_body(b2Vec2(w+this->properties[0].v.f, h+this->properties[1].v.f), 0),
|
||||
other->local_to_body(b2Vec2(-(w+this->properties[2].v.f), h+this->properties[1].v.f), 0),
|
||||
other->local_to_body(b2Vec2(-(w+this->properties[2].v.f), -(h+this->properties[3].v.f)), 0),
|
||||
other->local_to_body(b2Vec2(w+this->properties[0].v.f, -(h+this->properties[3].v.f)), 0)
|
||||
};
|
||||
|
||||
sh.Set(vertices, 4);
|
||||
|
||||
b2FixtureDef fd;
|
||||
fd.shape = &sh;
|
||||
fd.density = 0.00001f;
|
||||
fd.friction = other->fd.friction;
|
||||
fd.restitution = other->fd.restitution;
|
||||
fd.filter = other->fd.filter;
|
||||
fd.filter.groupIndex = -(1+this->get_layer());
|
||||
|
||||
other->get_body(0)->CreateFixture(&fd)->SetUserData(other);
|
||||
}
|
||||
}
|
||||
|
||||
void shape_extruder::find_pairs() {
|
||||
b2AABB aabb;
|
||||
b2Vec2 p = this->get_position();
|
||||
aabb.lowerBound = b2Vec2(p.x-.1f, p.y-.1f);
|
||||
aabb.upperBound = b2Vec2(p.x+.1f, p.y+.1f);
|
||||
W->b2->QueryAABB(this, aabb);
|
||||
}
|
||||
|
||||
void shape_extruder::add_to_world() {
|
||||
if (W->is_paused()) {
|
||||
this->create_rect(b2_dynamicBody, .25f, .25f, this->material);
|
||||
this->body->GetFixtureList()[0].SetSensor(true);
|
||||
}
|
||||
}
|
||||
19
src/shape_extruder.hh
Normal file
19
src/shape_extruder.hh
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include "entity.hh"
|
||||
|
||||
class shape_extruder : public entity, public b2QueryCallback {
|
||||
public:
|
||||
connection c;
|
||||
|
||||
shape_extruder();
|
||||
void update();
|
||||
const char *get_name() { return "Shape Extruder"; }
|
||||
void init();
|
||||
bool ReportFixture(b2Fixture *f);
|
||||
void find_pairs();
|
||||
void add_to_world();
|
||||
connection* load_connection(connection &conn);
|
||||
void connection_create_joint(connection *c);
|
||||
bool connection_destroy_joint(connection *c);
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue