game-source/klik/override.qc
2004-02-08 07:34:17 +00:00

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;
};