Code for VM 0-09-00
Server-side
This commit is contained in:
Victor Chow 2001-08-18 19:59:25 +00:00
parent ffaf084371
commit b3ce590831
9 changed files with 168 additions and 24 deletions

View file

@ -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;

View file

@ -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",

View file

@ -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();
}

View file

@ -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,

View file

@ -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
{

View file

@ -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;
}
}

View file

@ -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 );
//

View file

@ -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 )
{

View file

@ -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;
}