From b3ce59083185823df89fa2d142188f869d40e664 Mon Sep 17 00:00:00 2001 From: Victor Chow Date: Sat, 18 Aug 2001 19:59:25 +0000 Subject: [PATCH] Elder: Code for VM 0-09-00 Server-side --- reaction/game/bg_local.h | 1 + reaction/game/bg_misc.c | 1 + reaction/game/bg_pmove.c | 64 +++++++++++++++++++++++++++++++++++++-- reaction/game/bg_public.h | 9 ++++-- reaction/game/g_combat.c | 54 ++++++++++++++++++++++++++++----- reaction/game/g_items.c | 58 +++++++++++++++++++++++++++++------ reaction/game/g_local.h | 1 + reaction/game/g_misc.c | 2 +- reaction/game/g_weapon.c | 2 +- 9 files changed, 168 insertions(+), 24 deletions(-) diff --git a/reaction/game/bg_local.h b/reaction/game/bg_local.h index a6bb1f21..dd54b0f3 100644 --- a/reaction/game/bg_local.h +++ b/reaction/game/bg_local.h @@ -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; diff --git a/reaction/game/bg_misc.c b/reaction/game/bg_misc.c index d2a944c6..edd2d479 100644 --- a/reaction/game/bg_misc.c +++ b/reaction/game/bg_misc.c @@ -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", diff --git a/reaction/game/bg_pmove.c b/reaction/game/bg_pmove.c index 234ab0cd..c9f68c9e 100644 --- a/reaction/game/bg_pmove.c +++ b/reaction/game/bg_pmove.c @@ -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(); + } diff --git a/reaction/game/bg_public.h b/reaction/game/bg_public.h index a1bad18e..3267a251 100644 --- a/reaction/game/bg_public.h +++ b/reaction/game/bg_public.h @@ -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, diff --git a/reaction/game/g_combat.c b/reaction/game/g_combat.c index f9b75b3a..eb5b7419 100644 --- a/reaction/game/g_combat.c +++ b/reaction/game/g_combat.c @@ -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 { diff --git a/reaction/game/g_items.c b/reaction/game/g_items.c index bd735564..bb5f0a42 100644 --- a/reaction/game/g_items.c +++ b/reaction/game/g_items.c @@ -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; + } +} + + diff --git a/reaction/game/g_local.h b/reaction/game/g_local.h index e2977ec5..207064b4 100644 --- a/reaction/game/g_local.h +++ b/reaction/game/g_local.h @@ -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 ); // diff --git a/reaction/game/g_misc.c b/reaction/game/g_misc.c index efedf3ef..e9a5e5d6 100644 --- a/reaction/game/g_misc.c +++ b/reaction/game/g_misc.c @@ -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 ) { diff --git a/reaction/game/g_weapon.c b/reaction/game/g_weapon.c index fe4f0b2a..563b130d 100644 --- a/reaction/game/g_weapon.c +++ b/reaction/game/g_weapon.c @@ -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; }