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
Date | Commit Message | Author | + | - |
---|---|---|---|---|
2025-03-30 | Big commit. Entity networking, etc. | cev | +102 | -152 |
2024-11-20 | pmove refactor into prepoc macros, view bobbing | cev | +3 | |
2024-07-03 | pmove changes and fixes, improved climbing | cev | +1 | -1 |
2024-06-15 | Major update, committing as-is, will have bugs | cev | +182 | -4 |
2024-03-24 | 2nd pass refactor, rework QC class structure | cev | +107 | -70 |
2024-02-18 | Client/player, projectiles, entrypoints refactor | cev | +7 | |
2024-01-31 | Class based monster refactor & start projectiles | cev | +10 | -6 |
2024-01-09 | Continue OO / Class-based refactor | cev | +133 |
Return to the top of this page or return to the overview of this repo.