quake2-action/cgf_sfx_glass.h

282 lines
10 KiB
C

/****************************************************************************/
/* */
/* project : CGF (c) 1999 William van der Sterren */
/* parts (c) 1998 id software */
/* */
/* file : cgf_sfx_glass.h "special effects for glass entities" */
/* author(s): William van der Sterren */
/* version : 0.5 */
/* */
/* date (last revision): Jun 12, 99 */
/* date (creation) : Jun 04, 99 */
/* */
/* */
/* revision history */
/* -- date ---- | -- revision ---------------------- | -- revisor -- */
/* Jun 12, 1999 | fixed knife slash breaks glass | William */
/* */
/******* http://www.botepidemic.com/aid/cgf for CGF for Action Quake2 *******/
#ifndef __CGF_SFX_GLASS_H_
#define __CGF_SFX_GLASS_H_
// defines (should be consistent with other weapon defs in g_local.h)
#define MOD_BREAKINGGLASS 46
/*
// forward definitions
typedef struct edict_s edict_t;
*/
// export a number of functions to g_func.c:
//
//
void CGF_SFX_InstallGlassSupport();
// registers cvar breakableglass (default 0)
// registers cvar glassfragmentlimit (default 30)
void CGF_SFX_RebuildAllBrokenGlass();
// upon starting a new team play game, reconstruct any
// broken glass because we like to break it again
int CGF_SFX_IsBreakableGlassEnabled();
// returns whether breakable glass is enabled (cvar breakableglass)
void CGF_SFX_TestBreakableGlassAndRemoveIfNot_Think(edict_t* aPossibleGlassEntity);
// initial think function for all func_explosives
// because we cannot verify the contents of the entity unless the entity
// has been spawned, we need to first introduce the entity, and remove
// it later (level.time == 0.1) if required
void CGF_SFX_ShootBreakableGlass(edict_t* aGlassPane,
edict_t* anAttacker,
/*trace_t*/ void* tr,
int mod
);
// shoot thru glass - depending on bullet types and
// random effects, glass just emits fragments, or breaks
void CGF_SFX_AttachDecalToGlass(edict_t* aGlassPane, edict_t* aDecal);
// a glass that breaks will remove all decals (blood splashes, bullet
// holes) if they are attached
#endif
/*
further documentation:
cgf_sfx_glass.cpp can be compiled with ordinary c compilers as
well - just change the extension from .cpp to .c
to install breakable glass in the ActionQuake2 1.51 code base,
do the following:
@ file a_game.h
+ modify
#define ACTION_VERSION "1.51"
to something that tells users breakable glass is supported
@ file a_team.c
+ add #include "cgf_sfx_glass.h"
+ in void CleanLevel()
add
CGF_SFX_RebuildAllBrokenGlass();
as the last statement (thus after CleanBodies();)
@ file g_misc.c
+ add #include "cgf_sfx_glass.h"
+ in void SP_func_explosive (edict_t *self)
disable the statements (put them within comments):
if (deathmatch->value)
{ // auto-remove for deathmatch
G_FreeEdict (self);
return;
}
+ in void SP_func_explosive (edict_t *self)
add
self->think = CGF_SFX_TestBreakableGlassAndRemoveIfNot_Think;
self->nextthink = level.time + FRAMETIME;
as the last statement (thus after gi.linkentity (self);)
@ file g_save.c
+ add #include "cgf_sfx_glass.h"
+ in void InitGame (void)
add
CGF_SFX_InstallGlassSupport();
under (splatlimit = gi.cvar ("splatlimit", "0", 0);)
@ file g_local.h
+ replace
void AddDecal (edict_t *self, vec3_t point, vec3_t direct);
void AddSplat (edict_t *self, vec3_t point, vec3_t direct);
by
void AddDecal (edict_t *self, trace_t* tr);
void AddSplat (edict_t *self, vec3_t point, trace_t* tr);
@ file a_game.c
+ add #include "cgf_sfx_glass.h"
+ replace
void AddDecal (edict_t *self, vec3_t point, vec3_t direct)
by
void AddDecal (edict_t *self, trace_t* tr)
+ replace
void AddSplat (edict_t *self, vec3_t point, vec3_t direct);
by
void AddSplat (edict_t *self, vec3_t point, trace_t* tr);
+ in void AddDecal (edict_t *self, trace_t* tr)
replace each occurrence of 'point' by tr->endpos
+ in void AddDecal (edict_t *self, trace_t* tr)
replace each occurrence of 'direct' by tr->plane.normal
+ in void AddDecal (edict_t *self, trace_t* tr)
add (as the last line, thus under gi.linkentity (decal);)
if ((tr->ent) && (0 == Q_stricmp("func_explosive", tr->ent->classname)))
{
CGF_SFX_AttachDecalToGlass(tr->ent, decal);
}
+ in void AddSplat (edict_t *self, vec3_t point, trace_t* tr)
replace each occurrence of 'direct' by tr->plane.normal
+ in void AddSplat (edict_t *self, vec3_t point, trace_t* tr)
add (as the last line, thus under gi.linkentity (decal);)
if ((tr->ent) && (0 == Q_stricmp("func_explosive", tr->ent->classname)))
{
CGF_SFX_AttachDecalToGlass(tr->ent, splat);
}
@ file g_weapon.c
+ add #include "cgf_sfx_glass.h"
+ in static void fire_lead (edict_t *self, ...)
replace
AddDecal (self, tr.endpos, tr.plane.normal);
by
AddDecal (self, &tr);
+ in void fire_lead_ap (edict_t *self, ...)
replace
AddDecal (self, tr.endpos, tr.plane.normal);
by
AddDecal (self, &tr);
+ in static void fire_lead (edict_t *self, ...)
add
between
tr = do_trace (start, NULL, NULL, end, self, content_mask);
and
// see if we hit water
the following
// catch case of firing thru one or breakable glasses
while ( (tr.fraction < 1.0)
&& (tr.surface->flags & (SURF_TRANS33 | SURF_TRANS66))
&& (tr.ent)
&& (0 == Q_stricmp(tr.ent->classname, "func_explosive"))
)
{
// break glass
CGF_SFX_ShootBreakableGlass(tr.ent, self, &tr, mod);
// continue trace from current endpos to start
tr = do_trace (tr.endpos, NULL, NULL, end, tr.ent, content_mask);
}
+ in static void fire_lead_ap (edict_t *self, ...)
add
between
tr = do_trace (start, NULL, NULL, end, self, content_mask);
and
// see if we hit water
the following
// catch case of firing thru one or breakable glasses
while ( (tr.fraction < 1.0)
&& (tr.surface->flags & (SURF_TRANS33 | SURF_TRANS66))
&& (tr.ent)
&& (0 == Q_stricmp(tr.ent->classname, "func_explosive"))
)
{
// break glass
CGF_SFX_ShootBreakableGlass(tr.ent, self, &tr, mod);
// continue trace from current endpos to start
tr = do_trace (tr.endpos, NULL, NULL, end, tr.ent, content_mask);
}
+ in void knife_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
replace
if (other->takedamage)
by
if (0 == Q_stricmp(other->classname, "func_explosive"))
{
// ignore it, so it can bounce
return;
}
else
if (other->takedamage)
+ in void kick_attack (edict_t * ent )
between
// zucc stop powerful upwards kicking
forward[2] = 0;
and
T_Damage (tr.ent, ent, ent, forward, tr.endpos, tr.plane.normal, damage, kick, 0, MOD_KICK );
add
if (0 == Q_stricmp(tr.ent->classname, "func_explosive"))
{
CGF_SFX_ShootBreakableGlass(tr.ent, ent, &tr, MOD_KICK);
}
+ in int knife_attack ( edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick)
replace
if (tr.ent->takedamage)
by
if (0 == Q_stricmp(tr.ent->classname, "func_explosive"))
{
CGF_SFX_ShootBreakableGlass(tr.ent, self, &tr, MOD_KNIFE);
}
else
if (tr.ent->takedamage)
@ file g_phys.c
+ add #include "cgf_sfx_glass.h"
+ in void SV_Physics_Toss (edict_t *ent)
replace
AddSplat (self, tr.endpos, tr.plane.normal);
by
AddSplat (self, &tr);
@ file g_combat.c
+ add #include "cgf_sfx_glass.h"
+ in void T_Damage (edict_t *targ, ...)
replace
if ( (mod == MOD_M3) || (mod == MOD_HC) || (mod == MOD_HELD_GRENADE) ||
(mod == MOD_HG_SPLASH) || (mod == MOD_G_SPLASH) )
by
if ( (mod == MOD_M3)
|| (mod == MOD_HC)
|| (mod == MOD_HELD_GRENADE)
|| (mod == MOD_HG_SPLASH)
|| (mod == MOD_G_SPLASH)
|| (mod == MOD_BREAKINGGLASS)
)
+ in void T_RadiusDamage (...)
add before if (CanDamage (ent, inflictor))
if (0 == Q_stricmp(ent->classname, "func_explosive"))
{
CGF_SFX_ShootBreakableGlass(ent, inflictor, 0, mod);
}
else
@ file p_client.c
+ add #include "cgf_sfx_glass.h"
+ in void ClientObituary (edict_t *self, edict_t *inflictor, edict_t *attacker)
between
switch (mod)
{
and
case MOD_SUICIDE:
add
case MOD_BREAKINGGLASS:
message = "ate too much glass";
break;
*/