mirror of
https://github.com/ReactionQuake3/reaction.git
synced 2024-11-22 20:31:11 +00:00
Elder:
Code for VM 0-09-00 Server-side
This commit is contained in:
parent
ffaf084371
commit
b3ce590831
9 changed files with 168 additions and 24 deletions
|
@ -26,6 +26,7 @@ typedef struct {
|
|||
qboolean groundPlane;
|
||||
trace_t groundTrace;
|
||||
qboolean ladder; // We'll use this to tell when the player is on a ladder (c3a tut)
|
||||
qboolean previous_ladder; // Elder: need this to see if player was on ladder
|
||||
qboolean opendoor;
|
||||
|
||||
float impactSpeed;
|
||||
|
|
|
@ -1353,6 +1353,7 @@ char *eventnames[] = {
|
|||
"EV_MISSILE_HIT",
|
||||
"EV_MISSILE_MISS",
|
||||
"EV_MISSILE_MISS_METAL",
|
||||
"EV_KNIFE_MISS", // Elder: knife slash stuff
|
||||
"EV_RAILTRAIL",
|
||||
"EV_SHOTGUN",
|
||||
"EV_HANDCANNON",
|
||||
|
|
|
@ -443,8 +443,17 @@ static qboolean PM_CheckJump( void ) {
|
|||
|
||||
if (pm->ps->stats[STAT_JUMPTIME] > 0) {
|
||||
pm->ps->velocity[2] += JUMP_VELOCITY;
|
||||
pm->ps->velocity[2] += 100; // More velocity
|
||||
// if (pm->debugLevel)
|
||||
// Elder: ladder jump boost
|
||||
if (pml.ladder == qtrue)
|
||||
{
|
||||
if (pm->debugLevel)
|
||||
Com_Printf("^3Ladder jump boost^7\n");
|
||||
pm->ps->velocity[2] += 135;
|
||||
}
|
||||
else
|
||||
pm->ps->velocity[2] += 100; // More velocity
|
||||
if (pm->debugLevel)
|
||||
Com_Printf("^4Hit a double jump^7\n");
|
||||
// Com_Printf("%i:CPM->Double Jump, after %ims\n", c_pmove, (pm->jumpTime - pm->ps->stats[STAT_JUMPTIME]));
|
||||
} else {
|
||||
pm->ps->velocity[2] = JUMP_VELOCITY;
|
||||
|
@ -2517,6 +2526,12 @@ static void PM_LadderMove( void ) {
|
|||
float scale;
|
||||
float vel;
|
||||
|
||||
// Elder: ladder jump crap
|
||||
trace_t tr;
|
||||
vec3_t lookAhead;
|
||||
vec3_t trEndTest;
|
||||
|
||||
|
||||
PM_Friction ();
|
||||
|
||||
scale = PM_CmdScale( &pm->cmd );
|
||||
|
@ -2544,6 +2559,34 @@ static void PM_LadderMove( void ) {
|
|||
wishspeed = pm->ps->speed * pm_ladderScale;
|
||||
}
|
||||
|
||||
// Elder: ladder jump crap
|
||||
lookAhead[0] = pml.forward[0];
|
||||
lookAhead[1] = pml.forward[1];
|
||||
lookAhead[2] = 0;
|
||||
VectorNormalize (lookAhead);
|
||||
// Calculate end point
|
||||
VectorMA (pm->ps->origin, 1, lookAhead, trEndTest);
|
||||
trEndTest[2] += 20;
|
||||
// Calculate start point
|
||||
VectorCopy(pm->ps->origin, lookAhead);
|
||||
lookAhead[2] += 16;
|
||||
|
||||
pm->trace (&tr, lookAhead, pm->mins, pm->maxs, trEndTest,
|
||||
pm->ps->clientNum, MASK_PLAYERSOLID);
|
||||
|
||||
if (tr.fraction == 1 || !(tr.surfaceFlags & SURF_LADDER))
|
||||
{
|
||||
// good conditions -- now we can set up a double jump on the ladder
|
||||
if (pm->debugLevel)
|
||||
Com_Printf("Ladder jump conditions met...\n");
|
||||
if (PM_CheckJump())
|
||||
{
|
||||
if (pm->debugLevel)
|
||||
Com_Printf("Trying airmove ladder jump...\n");
|
||||
}
|
||||
}
|
||||
// End ladder jump crap
|
||||
|
||||
PM_Accelerate (wishdir, wishspeed, pm_ladderAccelerate);
|
||||
|
||||
// This SHOULD help us with sloped ladders, but it remains untested.
|
||||
|
@ -2559,6 +2602,8 @@ static void PM_LadderMove( void ) {
|
|||
}
|
||||
|
||||
PM_SlideMove( qfalse ); // move without gravity
|
||||
// Elder: stop legs from animating
|
||||
PM_ForceLegsAnim( LEGS_IDLE );
|
||||
}
|
||||
|
||||
|
||||
|
@ -2571,12 +2616,23 @@ void CheckLadder( void )
|
|||
{
|
||||
vec3_t flatforward,spot;
|
||||
trace_t trace;
|
||||
|
||||
pml.ladder = qfalse;
|
||||
pml.previous_ladder = qfalse;
|
||||
// check for ladder
|
||||
flatforward[0] = pml.forward[0];
|
||||
flatforward[1] = pml.forward[1];
|
||||
flatforward[2] = 0;
|
||||
VectorNormalize (flatforward);
|
||||
|
||||
// Elder: Previously on ladder? Does this work?
|
||||
VectorMA (pml.previous_origin, 1, flatforward, spot);
|
||||
pm->trace (&trace, pml.previous_origin, pm->mins, pm->maxs, spot,
|
||||
pm->ps->clientNum, MASK_PLAYERSOLID);
|
||||
|
||||
if ((trace.fraction < 1) && (trace.surfaceFlags & SURF_LADDER))
|
||||
pml.previous_ladder = qtrue;
|
||||
|
||||
VectorMA (pm->ps->origin, 1, flatforward, spot);
|
||||
pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, spot,
|
||||
pm->ps->clientNum, MASK_PLAYERSOLID);
|
||||
|
@ -2584,6 +2640,10 @@ void CheckLadder( void )
|
|||
if ((trace.fraction < 1) && (trace.surfaceFlags & SURF_LADDER))
|
||||
pml.ladder = qtrue;
|
||||
|
||||
// Elder: does this work?
|
||||
if (pml.ladder && pml.previous_ladder)
|
||||
PM_CrashLand();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -41,9 +41,10 @@
|
|||
#define VOTE_TIME 30000 // 30 seconds before vote times out
|
||||
|
||||
#define MINS_Z -24
|
||||
#define DEFAULT_VIEWHEIGHT 26
|
||||
#define DEFAULT_VIEWHEIGHT 22
|
||||
//#define DEFAULT_VIEWHEIGHT 26
|
||||
//Elder: changed to 8 like AQ2 source BUT is it sync-ed?
|
||||
#define CROUCH_VIEWHEIGHT 8
|
||||
#define CROUCH_VIEWHEIGHT 8
|
||||
//#define CROUCH_VIEWHEIGHT 12
|
||||
#define DEAD_VIEWHEIGHT -16
|
||||
|
||||
|
@ -284,8 +285,9 @@ typedef enum {
|
|||
//Elder: special flag needed in both games
|
||||
#define FL_THROWN_KNIFE 0x00040000 // Elder: thrown knife special case
|
||||
|
||||
//Elder: weapon modifications -- right now only silencer
|
||||
//Elder: weapon modifications
|
||||
#define RQ3_WPMOD_SILENCER 1
|
||||
#define RQ3_WPMOD_KNIFESLASH 2
|
||||
|
||||
//
|
||||
// config strings are a general means of communicating variable length strings
|
||||
|
@ -735,6 +737,7 @@ typedef enum {
|
|||
EV_MISSILE_HIT,
|
||||
EV_MISSILE_MISS,
|
||||
EV_MISSILE_MISS_METAL,
|
||||
EV_KNIFE_MISS, // Elder: knife slash stuff
|
||||
EV_RAILTRAIL,
|
||||
EV_SHOTGUN,
|
||||
EV_HANDCANNON,
|
||||
|
|
|
@ -734,8 +734,43 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
|
|||
}
|
||||
else if ( self->client->ps.powerups[PW_BLUEFLAG] ) { // only happens in standard CTF
|
||||
Team_ReturnFlag(TEAM_BLUE);
|
||||
//Elder: include immediate item and weapon return here
|
||||
}
|
||||
// Elder: include immediate item and weapon return here -- but handled in G_RunItem?
|
||||
//if ( self->client->ps.stats[STAT_HOLDABLE_ITEM] )
|
||||
//{
|
||||
//RQ3_ResetItem(bg_itemlist[self->client->ps.stats[STAT_HOLDABLE_ITEM]].giTag);
|
||||
//self->client->ps.stats[STAT_HOLDABLE_ITEM] = 0;
|
||||
//}
|
||||
// Elder: weapons are smart enough to return themselves
|
||||
/*
|
||||
// Elder: obviously we don't worry about the pistol or knives here
|
||||
weaponInventory = self->client->ps.stat[STAT_WEAPONS];
|
||||
if ( (weaponInventory & (1 << WP_M3) ) == (1 << WP_M3) ) {
|
||||
RQ3_ResetWeapon( WP_M3 );
|
||||
self->client->pers.hadUniqueWeapon[ WP_M3 ] = qfalse;
|
||||
}
|
||||
|
||||
if ( (weaponInventory & (1 << WP_M4) ) == (1 << WP_M4) ) {
|
||||
RQ3_ResetWeapon( WP_M4 );
|
||||
self->client->pers.hadUniqueWeapon[ WP_M4 ] = qfalse;
|
||||
}
|
||||
|
||||
if ( (weaponInventory & (1 << WP_MP5) ) == (1 << WP_MP5) ) {
|
||||
RQ3_ResetWeapon( WP_MP5 );
|
||||
self->client->pers.hadUniqueWeapon[ WP_MP5 ] = qfalse;
|
||||
}
|
||||
|
||||
if ( (weaponInventory & (1 << WP_HANDCANNON) ) == (1 << WP_HANDCANNON) ) {
|
||||
RQ3_ResetWeapon( WP_HANDCANNON );
|
||||
self->client->pers.hadUniqueWeapon[ WP_HANDCANNON ] = qfalse;
|
||||
}
|
||||
|
||||
if ( (weaponInventory & (1 << WP_SSG3000) ) == (1 << WP_SSG3000) ) {
|
||||
RQ3_ResetWeapon( WP_SSG3000 );
|
||||
self->client->pers.hadUniqueWeapon[ WP_SSG3000 ] = qfalse;
|
||||
}
|
||||
self->client->uniqueWeapons = 0;
|
||||
*/
|
||||
}
|
||||
#ifdef MISSIONPACK
|
||||
TossClientPersistantPowerups( self );
|
||||
|
@ -1527,7 +1562,8 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
tookShellHit[playernum] = 1;
|
||||
}
|
||||
else {
|
||||
//Grenade stuff - don't print if you hurt yourself
|
||||
// Grenade stuff - don't print if you hurt yourself
|
||||
// We could re-use the shotgun report for grenades
|
||||
if (targ != attacker)
|
||||
trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7\n\"", targ->client->pers.netname));
|
||||
}
|
||||
|
@ -1664,20 +1700,24 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
|
|||
//if ((attacker->client->ps.stats[STAT_WEAPONS] & (1 << WP_SSG3000)) == (1 << WP_SSG3000))
|
||||
if (attacker->client->ps.weapon == WP_SSG3000)
|
||||
{
|
||||
trap_SendServerCommand(attacker-g_entities, va("print \"%s has a Kevlar Vest, too bad you have AP rounds...\n\"",targ->client->pers.netname));
|
||||
trap_SendServerCommand(targ-g_entities, va("print \"Kevlar Vest absorbed some of %s's AP sniper round\n\"",attacker->client->pers.netname));
|
||||
trap_SendServerCommand(attacker-g_entities, va("print \"%s ^7has a Kevlar Vest, too bad you have AP rounds...\n\"",targ->client->pers.netname));
|
||||
trap_SendServerCommand(targ-g_entities, va("print \"Kevlar Vest absorbed some of %s^7's AP sniper round\n\"",attacker->client->pers.netname));
|
||||
take = take * 0.325;
|
||||
}
|
||||
else
|
||||
{
|
||||
trap_SendServerCommand( attacker-g_entities, va("print \"%s^7 has a Kevlar Vest - AIM FOR THE HEAD!\n\"", targ->client->pers.netname));
|
||||
trap_SendServerCommand( targ-g_entities, va("print \"Kevlar Vest absorbed most of %s shot\n\"", attacker->client->pers.netname ));
|
||||
if (mod != MOD_KNIFE && mod != MOD_KNIFE_THROWN)
|
||||
trap_SendServerCommand( attacker-g_entities, va("print \"%s^7 has a Kevlar Vest - AIM FOR THE HEAD!\n\"", targ->client->pers.netname));
|
||||
else
|
||||
trap_SendServerCommand( attacker-g_entities, va("print \"You hit %s^7 in the chest.\n\"", targ->client->pers.netname));
|
||||
trap_SendServerCommand( targ-g_entities, va("print \"Kevlar Vest absorbed most of %s ^7shot\n\"", attacker->client->pers.netname ));
|
||||
take = take/10;
|
||||
instant_dam = 1;
|
||||
bleeding = 0;
|
||||
}
|
||||
//Kevlar sound
|
||||
tent = G_TempEntity2(targ->s.pos.trBase, EV_RQ3_SOUND, RQ3_SOUND_KEVLARHIT);
|
||||
if (mod != MOD_KNIFE && mod != MOD_KNIFE_THROWN)
|
||||
tent = G_TempEntity2(targ->s.pos.trBase, EV_RQ3_SOUND, RQ3_SOUND_KEVLARHIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1429,6 +1429,9 @@ void G_RunItem( gentity_t *ent ) {
|
|||
//Elder: force-call the weaponthink function
|
||||
RQ3_DroppedWeaponThink(ent);
|
||||
}
|
||||
else if (ent->item && ent->item->giType == IT_HOLDABLE) {
|
||||
RQ3_DroppedItemThink(ent);
|
||||
}
|
||||
else {
|
||||
G_FreeEntity( ent );
|
||||
}
|
||||
|
@ -1558,11 +1561,11 @@ void RQ3_ResetWeapon( int weapon ) {
|
|||
|
||||
/*
|
||||
==============
|
||||
Added by Elder
|
||||
|
||||
RQ3_DroppedItemThink
|
||||
Items respawn themselves after a period of time
|
||||
Based on the AQ2 item code which was based off Q2 CTF techs
|
||||
|
||||
|
||||
Added by Elder
|
||||
Support function for RQ3_ResetItem
|
||||
==============
|
||||
*/
|
||||
void RQ3_DroppedItemThink(gentity_t *ent) {
|
||||
|
@ -1577,13 +1580,8 @@ void RQ3_DroppedItemThink(gentity_t *ent) {
|
|||
case HI_SILENCER:
|
||||
case HI_BANDOLIER:
|
||||
case HI_SLIPPERS:
|
||||
//Free entity and reset position in unique item array
|
||||
//level.uniqueItemsUsed &= ~(1 << ent->item->giTag);
|
||||
rq3_item = BG_FindItemForHoldable( ent->item->giTag );
|
||||
rq3_temp = (gentity_t*)SelectRandomDeathmatchSpawnPoint();
|
||||
RQ3_ResetItem( ent->item->giTag );
|
||||
G_FreeEntity(ent);
|
||||
Drop_Item (rq3_temp, rq3_item, angle);
|
||||
//G_Printf("RQ3_DroppedItemThink: Freeing item entity + respawning\n");
|
||||
break;
|
||||
default:
|
||||
//Elder: shouldn't have to come here
|
||||
|
@ -1592,3 +1590,43 @@ void RQ3_DroppedItemThink(gentity_t *ent) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
RQ3_ResetItem
|
||||
|
||||
|
||||
Added by Elder
|
||||
Items respawn themselves after a period of time
|
||||
Based on the AQ2 item code which was based off Q2 CTF techs
|
||||
This can be called directly when a player dies in a CONTENTS_NODROP area
|
||||
==============
|
||||
*/
|
||||
void RQ3_ResetItem ( int itemTag )
|
||||
{
|
||||
gitem_t *rq3_item;
|
||||
gentity_t *rq3_temp;
|
||||
float angle = rand() % 360;
|
||||
|
||||
switch ( itemTag )
|
||||
{
|
||||
case HI_KEVLAR:
|
||||
case HI_LASER:
|
||||
case HI_SILENCER:
|
||||
case HI_BANDOLIER:
|
||||
case HI_SLIPPERS:
|
||||
//Free entity and reset position in unique item array
|
||||
//level.uniqueItemsUsed &= ~(1 << ent->item->giTag);
|
||||
rq3_item = BG_FindItemForHoldable( itemTag );
|
||||
rq3_temp = (gentity_t*)SelectRandomDeathmatchSpawnPoint();
|
||||
Drop_Item (rq3_temp, rq3_item, angle);
|
||||
//G_Printf("RQ3_DroppedItemThink: Freeing item entity + respawning\n");
|
||||
break;
|
||||
default:
|
||||
//Elder: shouldn't have to come here
|
||||
G_Printf ("RQ3_ResetItem: Out of range or invalid item %d\n", itemTag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -597,6 +597,7 @@ void SaveRegisteredItems( void );
|
|||
void RQ3_DroppedItemThink(gentity_t *ent);
|
||||
void RQ3_DroppedWeaponThink(gentity_t *ent);
|
||||
void RQ3_ResetWeapon( int weapon );
|
||||
void RQ3_ResetItem ( int itemTag );
|
||||
|
||||
|
||||
//
|
||||
|
|
|
@ -513,7 +513,7 @@ void G_BreakGlass( gentity_t *ent, vec3_t point, int mod )
|
|||
break;
|
||||
|
||||
}
|
||||
G_Printf("(%d) (%d) (%d)\n", impactPoint[0], impactPoint[1], impactPoint[2]);
|
||||
G_Printf("(%f) (%f) (%f)\n", impactPoint[0], impactPoint[1], impactPoint[2]);
|
||||
G_FreeEntity( ent );
|
||||
switch ( shiftCount )
|
||||
{
|
||||
|
|
|
@ -1056,7 +1056,7 @@ void Knife_Attack ( gentity_t *self, int damage)
|
|||
else
|
||||
{
|
||||
//Elder TODO: take into account surface flags for clank
|
||||
tent = G_TempEntity(tr.endpos, EV_MISSILE_MISS);
|
||||
tent = G_TempEntity(tr.endpos, EV_KNIFE_MISS);
|
||||
tent->s.eventParm = DirToByte(tr.plane.normal);
|
||||
tent->s.weapon = WP_KNIFE;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue