mirror of
https://git.code.sf.net/p/quake/game-source
synced 2024-11-22 20:11:49 +00:00
179 lines
4.2 KiB
C++
179 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;
|
|
};
|