mirror of
https://git.code.sf.net/p/quake/game-source
synced 2024-11-22 20:11:49 +00:00
194 lines
4.2 KiB
C++
194 lines
4.2 KiB
C++
#include "act.qh"
|
|
|
|
#include "common.qh"
|
|
|
|
#include "items.qh"
|
|
#include "damage.qh"
|
|
#include "misc.qh"
|
|
#include "teleport.qh"
|
|
|
|
#include "override.qh"
|
|
|
|
.entity overrider, overrider_self;
|
|
.float overrider_priority;
|
|
|
|
// ===================================================================== //
|
|
|
|
/* Let's make my life simpler when I add new ones, mmmkay? */
|
|
#define all_funcs() \
|
|
one_func(float (), f_v, th_takeitem, (), return, FALSE); \
|
|
\
|
|
one_func(void (entity missile), v_e, th_attack, (missile), , ); \
|
|
\
|
|
one_func(float (float dmg), f_f, th_takedamage, (dmg), return, FALSE); \
|
|
one_func(float (float dmg), f_f, th_dealdamage, (dmg), return, dmg); \
|
|
\
|
|
one_func(void (), v_v, th_die, (), , ); \
|
|
one_func(void (), v_v, th_kill, (), , ); \
|
|
\
|
|
one_func(void (), v_v, prethink, (), , ); \
|
|
one_func(void (), v_v, actthink, (), , ); \
|
|
one_func(void (), v_v, postthink, (), , ); \
|
|
\
|
|
one_func(float (vector org), f_c, th_teleport, (org), return, TRUE); \
|
|
\
|
|
one_func(float (entity missile), f_e, th_projectile, (missile), return, TRUE)
|
|
|
|
|
|
#define all_types() \
|
|
one_type (void (), v_v); \
|
|
one_type (float (), f_v); \
|
|
one_type (void (entity ent), v_e); \
|
|
one_type (float (float flt), f_f); \
|
|
one_type (float (vector vec), f_c); \
|
|
one_type (float (entity ent), f_e)
|
|
|
|
// ===================================================================== //
|
|
|
|
/* default passthru functions */
|
|
#define one_func(type1,type2,func,args,return,val) \
|
|
type1 _passthru_##func = { \
|
|
local entity ovr; \
|
|
ovr = override_findself (); \
|
|
if (ovr.func) \
|
|
return ovr.func args; \
|
|
return val; \
|
|
}
|
|
|
|
all_funcs();
|
|
|
|
#undef one_func
|
|
|
|
/* for the override_set_FUNCTION macros in override.qh */
|
|
#define one_type(type1,type2) \
|
|
void(entity e, .type1 fld, type1 func) override_set_##type2 = { \
|
|
if (e.overrider) \
|
|
e.overrider.fld = func; \
|
|
else \
|
|
e.fld = func; \
|
|
}
|
|
|
|
all_types ();
|
|
|
|
#undef one_type
|
|
|
|
// ===================================================================== //
|
|
|
|
void (entity e1, entity e2)
|
|
_override_swap =
|
|
{
|
|
#define one_type(type1,type2) local type1 t_##type2
|
|
all_types();
|
|
#undef one_type
|
|
|
|
/* Swap all the functions */
|
|
#define one_func(type1,type2,func,args,return,val) \
|
|
t_##type2 = e1.func; \
|
|
e1.func = e2.func; \
|
|
e2.func = t_##type2
|
|
|
|
all_funcs();
|
|
#undef one_func
|
|
};
|
|
|
|
// ===================================================================== //
|
|
|
|
entity (entity e, string override_class, float priority)
|
|
override_create =
|
|
{
|
|
local entity ovr, ovr2;
|
|
|
|
for (ovr = e.overrider; ovr; ovr = ovr.overrider) {
|
|
if (ovr.classname == override_class) {
|
|
ovr2 = ovr.overrider;
|
|
if (!ovr2)
|
|
ovr2 = e;
|
|
_override_swap (ovr, ovr2);
|
|
return ovr;
|
|
}
|
|
}
|
|
|
|
/* Move to the tail.. */
|
|
for (ovr = e; ovr.overrider; ovr = ovr.overrider) {
|
|
if (ovr.overrider.overrider_priority > priority)
|
|
break;
|
|
}
|
|
|
|
ovr2 = ovr.overrider;
|
|
ovr.overrider = spawn(override_class);
|
|
ovr.overrider.owner = ovr;
|
|
ovr.overrider.overrider = ovr2;
|
|
|
|
if (ovr2)
|
|
ovr2.owner = ovr.overrider;
|
|
if (!ovr2)
|
|
ovr2 = e;
|
|
|
|
ovr = ovr.overrider;
|
|
ovr.overrider_priority = priority;
|
|
ovr.goalentity = ovr2;
|
|
|
|
/* Set default passthru funcs for ovr */
|
|
#define one_func(type1,type2,func,args,return,val) \
|
|
ovr.func = _passthru_##func
|
|
|
|
all_funcs ();
|
|
#undef one_func
|
|
|
|
return ovr;
|
|
};
|
|
|
|
void (entity ovr)
|
|
override_finalize =
|
|
{
|
|
_override_swap (ovr, ovr.goalentity);
|
|
};
|
|
|
|
entity ()
|
|
override_findself =
|
|
{
|
|
local entity ovrself;
|
|
|
|
ovrself = self.overrider_self;
|
|
if (!ovrself) {
|
|
/* Move to the end of the list */
|
|
for (ovrself = self.overrider; ovrself.overrider;
|
|
ovrself = ovrself.overrider);
|
|
}
|
|
|
|
self.overrider_self = ovrself.owner;
|
|
if (self.overrider_self == self)
|
|
self.overrider_self = world;
|
|
|
|
return ovrself;
|
|
};
|
|
|
|
void ()
|
|
override_halt =
|
|
{
|
|
self.overrider_self = world;
|
|
};
|
|
|
|
void (entity e, entity ovr)
|
|
override_destroy =
|
|
{
|
|
local entity ovr2;
|
|
|
|
ovr2 = ovr.overrider;
|
|
if (!ovr2)
|
|
ovr2 = e;
|
|
|
|
/* Copy the funcs from ovr to ovr2 */
|
|
#define one_func(type1,type2,func,args,return,val) \
|
|
ovr2.func = ovr.func
|
|
|
|
all_funcs();
|
|
#undef one_func
|
|
|
|
if (ovr.overrider)
|
|
ovr.overrider.owner = ovr.owner;
|
|
ovr.owner.overrider = ovr.overrider;
|
|
|
|
ovr.think = SUB_remove;
|
|
ovr.nextthink = time;
|
|
};
|