djcev.com

//

Git Repos / fte_dogmode / qc / base_func.qc

Last update to this file was on 2025-03-30 at 19:29.

Show base_func.qc

//==============================================================================
// base_func.qc -- func base class
//==============================================================================

//======================================================================
// Constants
//======================================================================

#if defined(CSQC) || defined(SSQC)
//----------------------------------------------------------------------
// func_ entity states, used for buttons & doors & plats -- CEV
//----------------------------------------------------------------------
typedef enum
{
FUNC_STATE_TOP = 0,
FUNC_STATE_BOTTOM = 1,
FUNC_STATE_UP = 2,
FUNC_STATE_DOWN = 3
} base_func_states;
#endif

//======================================================================
// fields
//======================================================================

#ifdef SSQC
.float lip; //
.vector finaldest, finalangle;

.void() think1; // called by calcmove_done
#endif

//======================================================================
// forward declarations
//======================================================================

// base_func
#ifdef CSQC
// BASE_FUNC_NETRECEIVE(initfn)
float() base_func_predraw;
#endif
#ifdef SSQC
void() base_func_neteval;
#endif
#ifdef SSQC
void() base_func_calcmove_done;
void(entity e, vector tdest, float tspeed, void() newthink) base_func_calcmove;
void() sub_calcanglemovecontroller_done;
void(entity e, vector destangle, float tspeed, void() func, entity c)
sub_calcanglemovecontroller;
#endif
#if defined(CSQC) || defined(SSQC)
void(entity e) base_func_init;
#endif
#ifdef SSQC
strip void() base_func;
#endif

//------------------------------------------------------------------------------

//----------------------------------------------------------------------
// class base_func: base_mapentity
// {
//==============================================================
// Drawing & Networking
//==============================================================

#ifdef CSQC
//--------------------------------------------------------------
#define BASE_FUNC_NETRECEIVE(initfn) \
/* { */ \
local float netflags = base_entity_netreceive (isnew); \
if (NETFLAG_BASE_ENTITY_FRAME) \
self.frame = self.frame_net; \
if (isnew && !(self.predraw)) \
{ \
initfn (self); \
} \
else \
{ \
if (netflags & NETFLAG_BASE_ENTITY_MODEL) { \
if (self.modelindex) \
{ \
setmodelindex (self, self.modelindex); \
} } \
if (netflags & NETFLAG_BASE_ENTITY_SIZE) \
{ \
setsize (self, self.mins, self.maxs); \
} \
/*
else if (netflags & NETFLAG_BASE_ENTITY_SOLID) \
{ \
if (self.solid) \
setsize (self, self.mins, self.maxs); \
else \
setsize (self, '0 0 0', '0 0 0'); \
if (!(netflags & NETFLAG_BASE_ENTITY_ORIGIN)) \
setorigin (self, self.origin); \
} \
*/ \
if (netflags & NETFLAG_BASE_ENTITY_ORIGIN) \
setorigin (self, self.origin); \
} \
/* } */

//--------------------------------------------------------------
float() base_func_predraw =
{
// func_ entities are (I hope) not changing frame often
// enough to need interpolation -- CEV

// interpolate angles -- see base_entities.qc -- CEV
BASE_ENTITY_LERP_ANGLES (self,
self.angles_net, self.angles_prev, time,
self.angles_net_time, self.angles_prev_time)

// interpolate origin -- see base_entities.qc -- CEV
BASE_ENTITY_LERP_ORIGIN (self,
self.origin_net, self.origin_prev, time,
self.origin_net_time, self.origin_prev_time)

// draw this entity -- CEV
addentity (self);

// rewind to last sent server position -- CEV
setorigin (self, self.origin_net);

// go to next without auto-drawing this entity -- CEV
return PREDRAW_NEXT;
};
#endif

#ifdef SSQC
//--------------------------------------------------------------
// flag moving func_ entities to transmit origin -- CEV
//--------------------------------------------------------------
void() base_func_neteval =
{
if (!(self.SendFlags & NETFLAG_BASE_ENTITY_ORIGIN)) {
if (self.origin != self.origin_net)
{
// flag this entity to transmit origin -- CEV
self.SendFlags |= NETFLAG_BASE_ENTITY_ORIGIN;
} }
};
#endif

//==============================================================
// Subs
//==============================================================

#ifdef SSQC
//--------------------------------------------------------------
void() base_func_calcmove_done =
{
setorigin (self, self.finaldest);
self.velocity = '0 0 0';
self.nextthink = -1;

#if 0
dprint (sprintf("base_func_calcmove_done: %s completed "
"at %g\n", self.classname, time));
#endif

// don't need custom physics anymore -- CEV
if (self.customphysics == base_entity_movetype_push)
self.customphysics = __NULL__;

if (self.think1)
self.think1 ();
};

//--------------------------------------------------------------
// SUB_CalcMove
//--------------------------------------------------------------
void(entity e, vector tdest, float tspeed, void() newthink)
base_func_calcmove =
{
local vector vdestdelta;
local float len, traveltime, localtime;

if (!tspeed)
objerror ("base_func_calcmove: No speed is defined!");

if (e.movetype == MOVETYPE_PUSH)
{
localtime = e.ltime;

// use a custom movetype_push that will update
// SendFlags on this and nearby entities -- CEV
e.customphysics = base_entity_movetype_push;
}
else
{
localtime = time;
}

e.think1 = newthink;
e.finaldest = tdest;
e.think = base_func_calcmove_done;

if (tdest == e.origin)
{
e.velocity = '0 0 0';
e.nextthink = localtime + 0.1;
return;
}

// set destdelta to the vector needed to move
vdestdelta = tdest - e.origin;

// calculate length of vector
len = vlen (vdestdelta);

// divide by speed to get time to reach tdest
traveltime = len / tspeed;

if (traveltime < 0.1)
{
e.velocity = '0 0 0';
e.nextthink = localtime + 0.1;
return;
}

// set nextthink to trigger a think when d is reached
e.nextthink = localtime + traveltime;

// scale the destdelta vector by the time spent traveling
// to get velocity
// qcc won't take vec/float
e.velocity = vdestdelta * (1 / traveltime);
};

//--------------------------------------------------------------
// SUB_CalcAngleMoveDoneController
// After rotating, set angle to exact final angle
//--------------------------------------------------------------
void() sub_calcanglemovecontroller_done =
{
self.owner.angles = self.finalangle;
self.owner.avelocity = '0 0 0';
self.nextthink = -1;
if (self.think1)
sub_runvoidas (self.owner, self.think1);
};

//--------------------------------------------------------------
// SUB_CalcAngleMoveController -- Same as SUB_CalcAngleMove, but
// using a separate controller entity to not lose track of current
// think functions.
//--------------------------------------------------------------
void(entity e, vector destangle, float tspeed, void() func,
entity c) sub_calcanglemovecontroller =
{
local vector destdelta;
local float len, traveltime;

if (!tspeed)
objerror("sub_calcanglemove: No speed is defined!\n");

// set destdelta to the vector needed to move
destdelta = normalize_angles180 (destangle - e.angles);

/*
dprint (sprintf("destangle: %v\n", destangle));
dprint (sprintf("self.angles: %v\n", self.angles));
dprint (sprintf("destdelta: %v\n", destdelta));
*/

// calculate length of vector
len = vlen (destdelta);

// divide by speed to get time to reach dest
traveltime = len / tspeed;

// set nextthink to trigger a think when dest is reached
c.nextthink = time + traveltime;

// scale the destdelta vector by the time spent traveling to
// get velocity
e.avelocity = destdelta * (1 / traveltime);

// Makes sure controller.owner points to self so it can be
// referenced later in the think function
c.owner = e;
c.think1 = func;
c.finalangle = destangle;
c.think = sub_calcanglemovecontroller_done;
};
#endif

//==============================================================
// Constructor & Spawn Functions
//==============================================================

#if defined(CSQC) || defined(SSQC)
//--------------------------------------------------------------
void(entity e) base_func_init =
{
base_mapentity_init (e);
e.classgroup |= CG_FUNC;
};
#endif

#ifdef SSQC
//--------------------------------------------------------------
strip void() base_func =
{
base_func_init (self);
};
#endif
// };

Return to the top of this page or return to the overview of this repo.

Log base_func.qc

Return to the top of this page or return to the overview of this repo.