Skip to content

Commit

Permalink
cgame - game: Implement Short-Range Teleport
Browse files Browse the repository at this point in the history
  • Loading branch information
LegendaryGuard committed Jun 5, 2024
1 parent cf2e8f0 commit 3bab185
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ A legendary 90s era Quake 3 Arena mod.
- [x] ~~Hit Stun (makes player can't use ki, melee, block and charge)~~
- [ ] Power Struggles (when two beam attacks collide)
- [x] ~~Blocking (consumes ki energy, transfers all damage to ki instead of health, deflect missile attacks, more info on old docs)~~
- [ ] Short-Range Teleport (when pressing 2 times left or right)
- [x] ~~Short-Range Teleport - Zanzoken (when pressing 2 times left or right)~~
- [ ] Transformations (related to Power Tiers)
- [ ] Attacksets (configurable for cfgs)
- [ ] Skin Config File (explosionModel, explosionShader, missileRotation, missileShader, ... look old docs about that. "Custom plugin models")
Expand Down
6 changes: 6 additions & 0 deletions source/cgame/cg_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,12 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
break;
}

// BFP - Short-Range Teleport (Zanzoken)
case EV_ZANZOKEN:
DEBUGNAME("EV_ZANZOKEN");
trap_S_StartSound (NULL, es->number, CHAN_BODY, CG_CustomSound( es->number, "sound/bfp/srteleport.wav" ) );
break;

// BFP - TODO: Implement EV_TIER_0-4 (Tiers)
case EV_TIER_0:
DEBUGNAME("EV_TIER_0");
Expand Down
2 changes: 2 additions & 0 deletions source/game/bg_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,8 @@ typedef enum {
EV_MELEE_READY, // BFP - EV_MELEE_READY (10), preparing melee
EV_MELEE, // BFP - EV_MELEE (11), melee attack

EV_ZANZOKEN, // BFP - EV_ZANZOKEN (maybe 12?), ki teleport

// EV_TIER_RESET, // EV_TIER_RESET (13), reset tier when the player respawns and changes to the default or a bit less ki energy?

// BFP - EV_TIER_0-4 (14-18), when the player frags, increases their PL and obtains a new skill (in the last tier, transforms)
Expand Down
146 changes: 146 additions & 0 deletions source/game/g_active.c
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,148 @@ void FlyingThink( gentity_t *ent, usercmd_t *ucmd ) { // BFP - Flight
}
}

/*
============
Zanzoken
============
*/
qboolean Zanzoken( gentity_t *ent, int range ) { // BFP - Short-Range Teleport (Zanzoken)
trace_t tr;
vec3_t right, up, start, direction;
int startRightRange = ( range < 0 ) ? -10 : 10;

// set diagonal direction, included the up vector for upward detection
AngleVectors( ent->client->ps.viewangles, NULL, right, up );

// upward detection, avoid if the player is touching the surface above
VectorMA( ent->client->ps.origin, 10, up, start );
VectorMA( start, 100, up, direction );

trap_Trace( &tr, start, ent->r.mins, ent->r.maxs, direction, ent->s.number, MASK_PLAYERSOLID );
if ( tr.startsolid || tr.allsolid ) {
return qfalse;
}

// if there's something solid diagonally, then avoid the teleportation
VectorMA( ent->client->ps.origin, startRightRange, right, start );
VectorMA( ent->client->ps.origin, range, right, direction );

trap_Trace( &tr, start, ent->r.mins, ent->r.maxs, direction, ent->s.number, MASK_PLAYERSOLID );
if ( tr.startsolid || tr.allsolid ) {
return qfalse;
}

// TELEPORT!
VectorCopy( tr.endpos, ent->client->ps.origin );

// sound event
G_AddEvent( ent, EV_ZANZOKEN, 0 );

return qtrue;
}

/*
=================
ZanzokenHandling
=================
*/
#define ZANZOKEN_NUMBER_TIMES_ALLOWED 20
#define ZANZOKEN_ABUSE_DELAY 2000
static void ZanzokenHandling( gentity_t *ent, usercmd_t *ucmd ) { // BFP - Handling short-range teleport
// zanzoken cannot be used with ki charging status
if ( !( ent->client->ps.pm_flags & PMF_KI_CHARGE ) ) {
// restriction: stop abusing zanzoken technique all time
if ( ent->client->zanzokenNumberTimesAllowed >= ZANZOKEN_NUMBER_TIMES_ALLOWED ) {
ent->client->zanzokenNumberTimesAllowed = 0;
ent->client->zanzokenDelay = level.time;
return;
}
if ( ent->client->zanzokenDelay > 0
&& level.time - ent->client->zanzokenDelay <= ZANZOKEN_ABUSE_DELAY ) {
return;
}

if ( ucmd->rightmove && ent->client->zanzokenPressTime <= 0 ) {
ent->client->zanzokenPressTime = level.time;
ent->client->zanzokenNow = qfalse;
// handle directions to avoid pressing the opposite
if ( ucmd->rightmove > 0 ) {
ent->client->zanzokenLeft = qfalse;
ent->client->zanzokenRight = qtrue;
} else {
ent->client->zanzokenLeft = qtrue;
ent->client->zanzokenRight = qfalse;
}
}

// once pressed and having one moment to press again, zanzoken will be possible at these milliseconds
if ( !ucmd->rightmove
&& level.time - ent->client->zanzokenPressTime > 100
&& level.time - ent->client->zanzokenPressTime <= 250
&& !ent->client->zanzokenNow ) {
ent->client->zanzokenNow = qtrue;
ent->client->zanzokenNumberTimesAllowed++;
}

if ( !ucmd->rightmove
&& level.time - ent->client->zanzokenPressTime > 250 ) {
ent->client->zanzokenNumberTimesAllowed = 0;
ent->client->zanzokenPressTime = 0;
ent->client->zanzokenNow = qfalse;
ent->client->zanzokenLeft = qfalse;
ent->client->zanzokenRight = qfalse;
return;
}

// BFP - TODO: Zanzoken ki consume looks relative to powerlevel and the maximum ki quantity
// (so, if it's 8160 as ki max quantity, then consumes 408)
if ( ent->client->ps.stats[STAT_KI] > 408
&& ucmd->rightmove
&& ent->client->zanzokenNow ) {
int range = ( ucmd->rightmove > 0 ) ? 500 : -500;

// handle the directions correctly
if ( ucmd->rightmove > 0 && !ent->client->zanzokenRight ) {
ent->client->zanzokenLeft = qfalse;
ent->client->zanzokenRight = qfalse;
return;
}
if ( ucmd->rightmove < 0 && !ent->client->zanzokenLeft ) {
ent->client->zanzokenLeft = qfalse;
ent->client->zanzokenRight = qfalse;
return;
}

// put in 1 second delay before the player can 'zanzoken' out of stun
if ( ( ent->client->ps.pm_flags & PMF_HITSTUN )
&& ent->client->ps.pm_time > 2000 ) {
ent->client->zanzokenPressTime = 0;
ent->client->zanzokenNow = qfalse;
ent->client->zanzokenLeft = qfalse;
ent->client->zanzokenRight = qfalse;
return;
}

if ( Zanzoken( ent, range ) ) {
// block and stun statuses are removed when using zanzoken
if ( ( ent->client->ps.pm_flags & PMF_HITSTUN )
&& ent->client->ps.pm_time <= 2000 ) {
ent->client->ps.pm_flags &= ~PMF_HITSTUN;
ent->client->ps.pm_time = 0;
}
ent->client->ps.pm_flags &= ~PMF_BLOCK;
ent->client->ps.stats[STAT_KI] -= 408;
ent->client->zanzokenPressTime = 0;
ent->client->zanzokenNow = qfalse;
ent->client->zanzokenLeft = qfalse;
ent->client->zanzokenRight = qfalse;
}
}
}
}
#undef ZANZOKEN_NUMBER_TIMES_ALLOWED
#undef ZANZOKEN_ABUSE_DELAY

/*
==============
ClientThink
Expand Down Expand Up @@ -732,6 +874,10 @@ void ClientThink_real( gentity_t *ent ) {
client->ps.speed = g_speed.value;

if ( client->ps.pm_type != PM_DEAD && client->ps.pm_type != PM_SPECTATOR ) {

// BFP - Short-Range Teleport (Zanzoken)
ZanzokenHandling( ent, ucmd );

// BFP - Hit stun melee delay time
if ( client->hitStunMeleeDelayTime > 0
&& level.time >= client->hitStunMeleeDelayTime ) {
Expand Down
6 changes: 6 additions & 0 deletions source/game/g_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,12 @@ struct gclient_s {
int blockTime;
int blockDelayTime;

// BFP - Zanzoken handlers
int zanzokenPressTime;
qboolean zanzokenNow;
qboolean zanzokenLeft, zanzokenRight;
int zanzokenNumberTimesAllowed;
int zanzokenDelay;

char *areabits;
};
Expand Down

0 comments on commit 3bab185

Please sign in to comment.