game: add 'trigger_flashlight' support

Based on:
 * https://github.com/id-Software/quake2-rerelease-dll.git
This commit is contained in:
Denis Pauk 2024-11-24 22:54:36 +02:00
parent 42d5958d98
commit 27b41be951
10 changed files with 137 additions and 3 deletions

View file

@ -692,6 +692,7 @@ typedef struct
* it has a zero index model. */
#define EF_ROTATE 0x00000001 /* rotate (bonus items) */
#define EF_GIB 0x00000002 /* leave a trail */
#define EF_FLASHLIGHT 0x00000004 /* project flashlight, only for players */
#define EF_BLASTER 0x00000008 /* redlight + trail */
#define EF_ROCKET 0x00000010 /* redlight + trail */
#define EF_GRENADE 0x00000020

View file

@ -276,6 +276,32 @@ Pickup_Powerup(edict_t *ent, edict_t *other)
return true;
}
qboolean
Pickup_General(edict_t *ent, edict_t *other)
{
if (!ent || !other)
{
return false;
}
if (other->client->pers.inventory[ITEM_INDEX(ent->item)])
{
return false;
}
other->client->pers.inventory[ITEM_INDEX(ent->item)]++;
if (deathmatch->value)
{
if (!(ent->spawnflags & DROPPED_ITEM))
{
SetRespawn(ent, ent->item->quantity);
}
}
return true;
}
void
Drop_General(edict_t *ent, gitem_t *item)
{
@ -2406,6 +2432,29 @@ SpawnItem(edict_t *ent, gitem_t *item)
}
}
void
P_ToggleFlashlight(edict_t *ent, qboolean state)
{
if (!!(ent->flags & FL_FLASHLIGHT) == state)
{
return;
}
ent->flags ^= FL_FLASHLIGHT;
gi.sound(ent, CHAN_AUTO,
gi.soundindex(ent->flags & FL_FLASHLIGHT ?
"items/flashlight_on.wav" : "items/flashlight_off.wav"),
1.f, ATTN_STATIC, 0);
}
void
Use_Flashlight(edict_t *ent, gitem_t *inv)
{
P_ToggleFlashlight(ent, !(ent->flags & FL_FLASHLIGHT));
}
/* ====================================================================== */
static const gitem_t gameitemlist[] = {
@ -4303,6 +4352,27 @@ static const gitem_t gameitemlist[] = {
"ctf/tech4.wav"
},
{
"item_flashlight",
Pickup_General,
Use_Flashlight,
NULL,
NULL,
"items/pkup.wav",
"models/items/flashlight/tris.md2", EF_ROTATE,
NULL,
"p_torch",
"Flashlight",
2,
0,
NULL,
IT_STAY_COOP,
0,
NULL,
0,
"items/flashlight_on.wav items/flashlight_off.wav",
},
/* end of list marker */
{NULL}
};

View file

@ -1125,9 +1125,59 @@ SP_trigger_monsterjump(edict_t *self)
self->movedir[2] = st.height;
}
/* QUAKED trigger_flashlight (.5 .5 .5) ?
* Players moving against this trigger will have their flashlight turned on or off.
* "style" default to 0, set to 1 to always turn flashlight on, 2 to always turn off,
* otherwise "angles" are used to control on/off state
*/
#define SPAWNFLAG_FLASHLIGHT_CLIPPED 1
void
trigger_flashlight_touch(edict_t *self, edict_t *other, cplane_t *plane /* unused */,
csurface_t *surf /* unused */)
{
if (!other->client)
{
return;
}
if (self->style == 1)
{
P_ToggleFlashlight(other, true);
}
else if (self->style == 2)
{
P_ToggleFlashlight(other, false);
}
else if (VectorLength(other->velocity) > 6)
{
vec3_t forward;
VectorNormalize2(other->velocity, forward);
P_ToggleFlashlight(other, _DotProduct(forward, self->movedir) > 0);
}
}
void
SP_trigger_flashlight(edict_t *self)
{
if (self->s.angles[YAW] == 0)
{
self->s.angles[YAW] = 360;
}
InitTrigger(self);
self->touch = trigger_flashlight_touch;
self->movedir[2] = (float) st.height;
gi.linkentity(self);
}
/*
* QUAKED choose_cdtrack (.5 .5 .5) ?
* HEretic 2: Sets CD track
* Heretic 2: Sets CD track
*
* style: CD Track Id
*/

View file

@ -76,7 +76,8 @@
#define FL_TEAMSLAVE 0x00000400 /* not the first on the team */
#define FL_NO_KNOCKBACK 0x00000800
#define FL_POWER_ARMOR 0x00001000 /* power armor (if any) is active */
#define FL_COOP_TAKEN 0x00002000 /* Another client has already taken it */
#define FL_COOP_TAKEN 0x00002000 /* Another client has already taken it */
#define FL_FLASHLIGHT 0x00004000 /* enable flashlight */
#define FL_RESPAWN 0x80000000 /* used for item respawning */
#define FL_MECHANICAL 0x00002000 /* entity is mechanical, use sparks not blood */
@ -1091,6 +1092,7 @@ void fire_doppleganger(edict_t *ent, vec3_t start, vec3_t aimdir);
void ED_CallSpawn(edict_t *ent);
char *ED_NewString(const char *string, qboolean raw);
void SpawnInit(void);
void P_ToggleFlashlight(edict_t *ent, qboolean state);
edict_t *CreateFlyMonster(vec3_t origin, vec3_t angles, vec3_t mins,
vec3_t maxs, char *classname);
edict_t *CreateGroundMonster(vec3_t origin, vec3_t angles, vec3_t mins,

View file

@ -1344,7 +1344,7 @@ SaveClientData(void)
game.clients[i].pers.health = ent->health;
game.clients[i].pers.max_health = ent->max_health;
game.clients[i].pers.savedFlags =
(ent->flags & (FL_GODMODE | FL_NOTARGET | FL_POWER_ARMOR));
(ent->flags & (FL_FLASHLIGHT | FL_GODMODE | FL_NOTARGET | FL_POWER_ARMOR));
if (coop->value)
{

View file

@ -1123,6 +1123,11 @@ G_SetClientEffects(edict_t *ent)
return;
}
if (ent->flags & FL_FLASHLIGHT)
{
ent->s.effects |= EF_FLASHLIGHT;
}
if (ent->flags & FL_DISGUISED)
{
ent->s.renderfx |= RF_USE_DISGUISE;

View file

@ -306,6 +306,7 @@ extern void Use_Defender ( edict_t * ent , gitem_t * item ) ;
extern void Use_Doppleganger ( edict_t * ent , gitem_t * item ) ;
extern void Use_Double ( edict_t * ent , gitem_t * item ) ;
extern void Use_Envirosuit ( edict_t * ent , gitem_t * item ) ;
extern void Use_Flashlight ( edict_t * ent , gitem_t * item ) ;
extern void Use_Hunter ( edict_t * ent , gitem_t * item ) ;
extern void Use_IR ( edict_t * ent , gitem_t * item ) ;
extern void Use_Invulnerability ( edict_t * ent , gitem_t * item ) ;
@ -1400,6 +1401,7 @@ extern void trigger_effect ( edict_t * self ) ;
extern void trigger_elevator_init ( edict_t * self ) ;
extern void trigger_elevator_use ( edict_t * self , edict_t * other , edict_t * activator ) ;
extern void trigger_enable ( edict_t * self , edict_t * other , edict_t * activator ) ;
extern void trigger_flashlight_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ;
extern void trigger_gravity_touch ( edict_t * self , edict_t * other , cplane_t * plane , csurface_t * surf ) ;
extern void trigger_gravity_use ( edict_t * self , edict_t * other , edict_t * activator ) ;
extern void trigger_key_use ( edict_t * self , edict_t * other , edict_t * activator ) ;

View file

@ -257,6 +257,7 @@
{"Use_Doppleganger", (byte *)Use_Doppleganger},
{"Use_Double", (byte *)Use_Double},
{"Use_Envirosuit", (byte *)Use_Envirosuit},
{"Use_Flashlight", (byte *)Use_Flashlight},
{"Use_Hunter", (byte *)Use_Hunter},
{"Use_IR", (byte *)Use_IR},
{"Use_Invulnerability", (byte *)Use_Invulnerability},
@ -1395,6 +1396,7 @@
{"trigger_elevator_init", (byte *)trigger_elevator_init},
{"trigger_elevator_use", (byte *)trigger_elevator_use},
{"trigger_enable", (byte *)trigger_enable},
{"trigger_flashlight_touch", (byte *)trigger_flashlight_touch},
{"trigger_gravity_touch", (byte *)trigger_gravity_touch},
{"trigger_gravity_use", (byte *)trigger_gravity_use},
{"trigger_key_use", (byte *)trigger_key_use},

View file

@ -196,6 +196,7 @@ extern void SP_trigger_always ( edict_t * ent ) ;
extern void SP_trigger_counter(edict_t * self);
extern void SP_trigger_disguise(edict_t * self);
extern void SP_trigger_elevator(edict_t * self);
extern void SP_trigger_flashlight(edict_t * self);
extern void SP_trigger_gravity(edict_t * self);
extern void SP_trigger_hurt(edict_t * self);
extern void SP_trigger_key(edict_t * self);

View file

@ -180,6 +180,7 @@
{"target_crosslevel_trigger", SP_target_crosslevel_trigger},
{"target_earthquake", SP_target_earthquake},
{"target_explosion", SP_target_explosion},
{"trigger_flashlight", SP_trigger_flashlight},
{"target_goal", SP_target_goal},
{"target_gravity", SP_target_gravity},
{"target_help", SP_target_help},