/* ============= SV_CheckWaterTransition ============= */ void SV_CheckWaterTransition (edict_t *ent) { int cont; cont = SV_PointContents (ent->v.origin); if (!ent->v.watertype) { // just spawned here ent->v.watertype = cont; ent->v.waterlevel = 1; return; } if (cont <= CONTENTS_WATER) { if (ent->v.watertype == CONTENTS_EMPTY) { // just crossed into water SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); } ent->v.watertype = cont; ent->v.waterlevel = 1; } else { if (ent->v.watertype != CONTENTS_EMPTY) { // just crossed into water SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); } ent->v.watertype = CONTENTS_EMPTY; ent->v.waterlevel = cont; } }
/* ============= SV_CheckWaterTransition ============= */ void SV_CheckWaterTransition (edict_t *ent) { int cont; cont = SV_PointContents (ent->v.origin); if (cont == CONTENTS_WATER || cont == CONTENTS_SLIME || cont == CONTENTS_LAVA) { if (ent->v.watertype == CONTENTS_EMPTY) { // just crossed into water SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); } ent->v.watertype = cont; ent->v.waterlevel = 1; } else { if (ent->v.watertype == CONTENTS_WATER || ent->v.watertype == CONTENTS_SLIME || ent->v.watertype == CONTENTS_LAVA) { // just crossed out of water SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); } ent->v.watertype = CONTENTS_EMPTY; ent->v.waterlevel = 0; // EER1 fix } }
void SV_Physics_Step (edict_t *ent) { qboolean hitsound; // freefall if not onground if ( ! ((int)ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM) ) ) { if (ent->v.velocity[2] < sv_gravity.value*-0.1) hitsound = true; else hitsound = false; SV_AddGravity (ent); SV_CheckVelocity (ent); SV_FlyMove (ent, host_frametime, NULL); SV_LinkEdict (ent, true); if ( (int)ent->v.flags & FL_ONGROUND ) // just hit ground { if (hitsound) SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1); } } // regular thinking SV_RunThink (ent); SV_CheckWaterTransition (ent); }
/* ============= SV_Physics_Step Monsters freefall when they don't have a ground entity, otherwise all movement is done with discrete steps. This is also used for objects that have become still on the ground, but will fall if the floor is pulled out from under them. FIXME: is this true? ============= */ void SV_Physics_Step (edict_t *ent) { qbool hitsound; // frefall if not onground if ( ! ((int)ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM) ) ) { if (ent->v.velocity[2] < sv.movevars.gravity*-0.1) hitsound = true; else hitsound = false; SV_AddGravity (ent, 1.0); SV_CheckVelocity (ent); // Tonik: the check for SOLID_NOT is to fix the way dead bodies and // gibs behave (should not be blocked by players & monsters); // The SOLID_TRIGGER check is disabled lest we break frikbots if (ent->v.solid == SOLID_NOT /* || ent->v.solid == SOLID_TRIGGER*/) SV_FlyMove (ent, sv_frametime, NULL, MOVE_NOMONSTERS); else SV_FlyMove (ent, sv_frametime, NULL, MOVE_NORMAL); SV_LinkEdict (ent, true); if ( (int)ent->v.flags & FL_ONGROUND ) // just hit ground { if (hitsound) SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1, NULL); } } // regular thinking SV_RunThink (ent); SV_CheckWaterTransition (ent); }
/* ================= Host_RestartAmbientSounds Write ambient sounds into demo ================= */ void Host_RestartAmbientSounds( void ) { soundlist_t soundInfo[64]; string curtrack, looptrack; int i, nSounds; fs_offset_t position; if( !SV_Active( )) { return; } nSounds = S_GetCurrentStaticSounds( soundInfo, 64 ); for( i = 0; i < nSounds; i++ ) { if( !soundInfo[i].looping || soundInfo[i].entnum == -1 ) continue; MsgDev( D_NOTE, "Restarting sound %s...\n", soundInfo[i].name ); S_StopSound( soundInfo[i].entnum, soundInfo[i].channel, soundInfo[i].name ); SV_StartSound( pfnPEntityOfEntIndex( soundInfo[i].entnum ), CHAN_STATIC, soundInfo[i].name, soundInfo[i].volume, soundInfo[i].attenuation, 0, soundInfo[i].pitch ); } // restart soundtrack if( S_StreamGetCurrentState( curtrack, looptrack, &position )) { SV_StartMusic( curtrack, looptrack, position ); } }
/* ============= SV_CheckWaterTransition ============= */ void SV_CheckWaterTransition (edict_t *ent) { int cont; vec3_t point; point[0] = ent->v.origin[0]; point[1] = ent->v.origin[1]; point[2] = ent->v.origin[2] + ent->v.mins[2] + 1; cont = SV_PointContents (ent->v.origin); if (!ent->v.watertype) { // just spawned here ent->v.watertype = cont; ent->v.waterlevel = 1; return; } if (cont <= CONTENTS_WATER) { if (ent->v.watertype == CONTENTS_EMPTY) { // just crossed into water SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); } ent->v.watertype = cont; ent->v.waterlevel = 1; } else { if (ent->v.watertype != CONTENTS_EMPTY) { // just crossed into water // vec3_t nothin; // nothin[0] = ent->v.velocity[0] * -0.1; // nothin[1] = ent->v.velocity[1] * -0.1; // nothin[2] = ent->v.velocity[2] * -0.5; // R_ParticleBloodSplash(point, nothin, 44); SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); //R_Splash(point, ent->v.velocity, 85, 36, ent->v.velocity[2]); } ent->v.watertype = CONTENTS_EMPTY; ent->v.waterlevel = cont; } }
static void pfnPlaySound( int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch ) { edict_t *ent; ent = EDICT_NUM( svgame.pmove->player_index + 1 ); if( !SV_IsValidEdict( ent )) return; SV_StartSound( ent, channel, sample, volume, attenuation, fFlags, pitch ); }
/* ============= SV_CheckWaterTransition ============= */ void SV_CheckWaterTransition (edict_t *ent) { int cont; #ifdef QUAKE2 vec3_t point; point[0] = ent->v.origin[0]; point[1] = ent->v.origin[1]; point[2] = ent->v.origin[2] + ent->v.mins[2] + 1; cont = SV_PointContents (point); #else cont = SV_PointContents (ent->v.origin); #endif if (!ent->v.watertype) { // just spawned here ent->v.watertype = cont; ent->v.waterlevel = 1; return; } if (cont <= CONTENTS_WATER) { if (ent->v.watertype == CONTENTS_EMPTY) { // just crossed into water SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); } ent->v.watertype = cont; ent->v.waterlevel = 1; } else { if ((ent->v.watertype != CONTENTS_EMPTY)&&(ent->v.watertype != CONTENTS_SOLID)) //Added extra check to stop splashing bug (thx to DrLabMan for tip) - Eradicator { // just crossed into water SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); } ent->v.watertype = CONTENTS_EMPTY; ent->v.waterlevel = cont; } }
/* ============= SV_CheckWaterTransition ============= */ void SV_CheckWaterTransition (edict_t *ent) { int cont; #ifdef QUAKE2 vec3_t point; point[0] = ent->v.origin[0]; point[1] = ent->v.origin[1]; point[2] = ent->v.origin[2] + ent->v.mins[2] + 1; cont = SV_PointContents (point); #else cont = SV_PointContents (ent->v.origin); #endif if (!ent->v.watertype) { // just spawned here ent->v.watertype = cont; ent->v.waterlevel = 1; return; } if (cont <= CONTENTS_WATER) { if (ent->v.watertype == CONTENTS_EMPTY) { // just crossed into water SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); } ent->v.watertype = cont; ent->v.waterlevel = 1; } else { if (ent->v.watertype != CONTENTS_EMPTY) { // just crossed into water SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); } ent->v.watertype = CONTENTS_EMPTY; ent->v.waterlevel = cont; } }
/* ============= SV_Physics_Step Monsters freefall when they don't have a ground entity, otherwise all movement is done with discrete steps. This is also used for objects that have become still on the ground, but will fall if the floor is pulled out from under them. ============= */ void SV_Physics_Step (edict_t *ent) { qboolean hitsound; char *snd; // freefall if not onground if (!((int)ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM))) { if (ent->v.velocity[2] < sv_gravity.value*-0.1) hitsound = true; else hitsound = false; SV_AddGravity (ent); SV_CheckVelocity (ent); SV_FlyMove (ent, host_frametime, NULL); SV_LinkEdict (ent, true); if ((int)ent->v.flags & FL_ONGROUND) // just hit ground #ifdef HEXEN2_SUPPORT if (!hexen2 || (!ent->v.flags & FL_MONSTER)) #endif { if (hitsound) { #ifdef HEXEN2_SUPPORT if (hexen2) snd = "fx/thngland.wav"; else #endif snd = "demon/dland2.wav"; SV_StartSound (ent, 0, snd, 255, 1); } } } // regular thinking SV_RunThink (ent); SV_CheckWaterTransition (ent); }
void SV_Physics_Step (edict_t *ent) { qboolean wasonground; qboolean inwater; qboolean hitsound = false; float *vel; float speed, newspeed, control; float friction; edict_t *groundentity; groundentity = PROG_TO_EDICT(ent->v.groundentity); if ((int)groundentity->v.flags & FL_CONVEYOR) VectorScale(groundentity->v.movedir, groundentity->v.speed, ent->v.basevelocity); else VectorCopy(vec_origin, ent->v.basevelocity); //@@ pr_global_struct->time = sv.time; pr_global_struct->self = EDICT_TO_PROG(ent); PF_WaterMove(); SV_CheckVelocity (ent); wasonground = (int)ent->v.flags & FL_ONGROUND; // ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; // add gravity except: // flying monsters // swimming monsters who are in the water inwater = SV_CheckWater(ent); if (! wasonground) if (!((int)ent->v.flags & FL_FLY)) if (!(((int)ent->v.flags & FL_SWIM) && (ent->v.waterlevel > 0))) { if (ent->v.velocity[2] < sv_gravity.value*-0.1) hitsound = true; if (!inwater) SV_AddGravity (ent); } if (!VectorCompare(ent->v.velocity, vec_origin) || !VectorCompare(ent->v.basevelocity, vec_origin)) { ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; // apply friction // let dead monsters who aren't completely onground slide if (wasonground) if (!(ent->v.health <= 0.0 && !SV_CheckBottom(ent))) { vel = ent->v.velocity; speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1]); if (speed) { friction = sv_friction.value; control = speed < sv_stopspeed.value ? sv_stopspeed.value : speed; newspeed = speed - host_frametime*control*friction; if (newspeed < 0) newspeed = 0; newspeed /= speed; vel[0] = vel[0] * newspeed; vel[1] = vel[1] * newspeed; } } VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); SV_FlyMove (ent, host_frametime, NULL); VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); // determine if it's on solid ground at all { vec3_t mins, maxs, point; int x, y; VectorAdd (ent->v.origin, ent->v.mins, mins); VectorAdd (ent->v.origin, ent->v.maxs, maxs); point[2] = mins[2] - 1; for (x=0 ; x<=1 ; x++) for (y=0 ; y<=1 ; y++) { point[0] = x ? maxs[0] : mins[0]; point[1] = y ? maxs[1] : mins[1]; if (SV_PointContents (point) == CONTENTS_SOLID) { ent->v.flags = (int)ent->v.flags | FL_ONGROUND; break; } } } SV_LinkEdict (ent, true); if ((int)ent->v.flags & FL_ONGROUND) if (!wasonground) if (hitsound) SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1); } // regular thinking SV_RunThink (ent); SV_CheckWaterTransition (ent); }
void EXT_FUNC SV_StartSound_api(int recipients, edict_t *entity, int channel, const char *sample, int volume, float attenuation, int flags, int pitch) { SV_StartSound(recipients, entity, channel, sample, volume, attenuation, flags, pitch); }
/* ============= SV_CheckWaterTransition ============= */ void SV_CheckWaterTransition( edict_t *ent ) { int cont; vec3_t halfmax; halfmax[0] = (ent->v.absmax[0] + ent->v.absmin[0]) * 0.5f; halfmax[1] = (ent->v.absmax[1] + ent->v.absmin[1]) * 0.5f; halfmax[2] = (ent->v.absmin[2] + 1.0f); svs.groupmask = ent->v.groupinfo; cont = SV_PointContents( halfmax ); if( !ent->v.watertype ) { // just spawned here ent->v.watertype = cont; ent->v.waterlevel = 1; return; } if( cont > CONTENTS_WATER || cont <= CONTENTS_TRANSLUCENT ) { if( ent->v.watertype != CONTENTS_EMPTY ) { SV_StartSound( ent, CHAN_AUTO, "player/pl_wade2.wav", 1.0f, ATTN_NORM, 0, 100 ); } ent->v.watertype = CONTENTS_EMPTY; ent->v.waterlevel = 0; return; } if( ent->v.watertype == CONTENTS_EMPTY ) { SV_StartSound( ent, CHAN_AUTO, "player/pl_wade1.wav", 1.0f, ATTN_NORM, 0, 100 ); ent->v.velocity[2] *= 0.5f; } ent->v.watertype = cont; ent->v.waterlevel = 1; if( ent->v.absmin[2] == ent->v.absmax[2] ) { // a point entity ent->v.waterlevel = 3; } halfmax[2] = (ent->v.absmin[2] + ent->v.absmax[2]) * 0.5f; svs.groupmask = ent->v.groupinfo; cont = SV_PointContents( halfmax ); if( cont > CONTENTS_WATER || cont <= CONTENTS_TRANSLUCENT ) return; ent->v.waterlevel = 2; VectorAdd( halfmax, ent->v.view_ofs, halfmax ); svs.groupmask = ent->v.groupinfo; cont = SV_PointContents( halfmax ); if( cont > CONTENTS_WATER || cont <= CONTENTS_TRANSLUCENT ) return; ent->v.waterlevel = 3; }
void PF_WaterMove(edict_t * ent) { double var_10; int var_4_flags; int var_8_waterlevel; int var_c_watertype; // double var_14; //some sort of damage counter, but it keeps not being used... if(ent->v.movetype == MOVETYPE_NOCLIP) { ent->v.air_finished = 12 + global_sv.time0c; return; } if(ent->v.health <= 0) { return; } if(ent->v.deadflag == 0) { var_10 = 3; } else { var_10 = 1; } var_4_flags = ent->v.flags; var_8_waterlevel = ent->v.waterlevel; var_c_watertype = ent->v.watertype; //This area is almost but not quite entirely unlike the drowning code in the SDK. if((var_4_flags & (FL_IMMUNE_WATER | FL_GODMODE)) == 0) { //Gods don't drown, unless they're Bruce Willis if(((var_4_flags & FL_SWIM) && var_8_waterlevel > var_10) || var_8_waterlevel <= var_10) { if(ent->v.air_finished > global_sv.time0c && ent->v.pain_finished > global_sv.time0c) { ent->v.dmg += 2; if(ent->v.dmg < 15) { ent->v.dmg = 10; //wha? } //var_14 = ent->v.dmg; ent->v.pain_finished = 1 + global_sv.time0c; } } else { // if(ent->v.air_finished <= global_sv.time0c) { // if(ent->v.air_finished <= 0 + global_sv.time0c) { } // } ent->v.air_finished = 12 + global_sv.time0c; ent->v.dmg = 2; } } //This is asmess if(var_8_waterlevel == 0) { if((var_4_flags & FL_INWATER) != 0) { //Leave the water. switch(RandomLong(0, 3)) { case 0: SV_StartSound(0, ent, 4, "player/pl_wade1.wav", 255, 0.8, 0, 100); break; case 1: SV_StartSound(0, ent, 4, "player/pl_wade2.wav", 255, 0.8, 0, 100); break; case 2: SV_StartSound(0, ent, 4, "player/pl_wade3.wav", 255, 0.8, 0, 100); break; case 3: SV_StartSound(0, ent, 4, "player/pl_wade4.wav", 255, 0.8, 0, 100); break; } ent->v.flags = var_4_flags & ~FL_INWATER; } ent->v.air_finished = 12 + global_sv.time0c; return; } if(var_c_watertype == Q1CONTENTS_LAVA) { //aah, it stings and burns if(((var_4_flags & (FL_IMMUNE_LAVA | FL_GODMODE)) == 0) && ent->v.dmgtime < global_sv.time0c) { if(ent->v.radsuit_finished < global_sv.time0c) { ent->v.dmgtime = global_sv.time0c + 0.2; } else { ent->v.dmgtime = global_sv.time0c + 1.0; } // var_14 = var_8_waterlevel * 10; } } else if(var_c_watertype == Q1CONTENTS_SLIME) { if(((var_4_flags & (FL_IMMUNE_SLIME | FL_GODMODE)) == 0) && ent->v.dmgtime < global_sv.time0c && ent->v.radsuit_finished < global_sv.time0c) { ent->v.dmgtime = global_sv.time0c + 1.0; // var_14 = var_8_waterlevel * 4; } } if((var_4_flags & FL_INWATER) == 0) { if(var_c_watertype == Q1CONTENTS_WATER) { switch(RandomLong(0, 3)) { case 0: SV_StartSound(0, ent, 4, "player/pl_wade1.wav", 255, 0.8, 0, 100); break; case 1: SV_StartSound(0, ent, 4, "player/pl_wade2.wav", 255, 0.8, 0, 100); break; case 2: SV_StartSound(0, ent, 4, "player/pl_wade3.wav", 255, 0.8, 0, 100); break; case 3: SV_StartSound(0, ent, 4, "player/pl_wade4.wav", 255, 0.8, 0, 100); break; } } ent->v.flags = var_4_flags | FL_INWATER; ent->v.dmgtime = 0; } if((var_4_flags & FL_WATERJUMP) == 0) { VectorMA(ent->v.velocity, (ent->v.waterlevel * -0.8 * host_frametime), ent->v.velocity, ent->v.velocity); } }
void SV_WaterMove( edict_t *ent ) { float drownlevel; int waterlevel; int watertype; int flags; if( ent->v.movetype == MOVETYPE_NOCLIP ) { ent->v.air_finished = sv.time + 12.0f; return; } // no watermove for monsters but pushables if(( ent->v.flags & FL_MONSTER ) && ent->v.health <= 0.0f ) return; drownlevel = (ent->v.deadflag == DEAD_NO) ? 3.0 : 1.0; waterlevel = ent->v.waterlevel; watertype = ent->v.watertype; flags = ent->v.flags; if( !( flags & ( FL_IMMUNE_WATER|FL_GODMODE ))) { if((( flags & FL_SWIM ) && waterlevel > drownlevel ) || waterlevel <= drownlevel ) { if( ent->v.air_finished > sv.time && ent->v.pain_finished > sv.time ) { ent->v.dmg += 2; if( ent->v.dmg < 15 ) ent->v.dmg = 10; // quake1 original code ent->v.pain_finished = sv.time + 1.0f; } } else { ent->v.air_finished = sv.time + 12.0f; ent->v.dmg = 2; } } if( !waterlevel ) { if( flags & FL_INWATER ) { // leave the water. switch( Com_RandomLong( 0, 3 )) { case 0: SV_StartSound( ent, CHAN_BODY, "player/pl_wade1.wav", 1.0f, ATTN_NORM, 0, 100 ); break; case 1: SV_StartSound( ent, CHAN_BODY, "player/pl_wade2.wav", 1.0f, ATTN_NORM, 0, 100 ); break; case 2: SV_StartSound( ent, CHAN_BODY, "player/pl_wade3.wav", 1.0f, ATTN_NORM, 0, 100 ); break; case 3: SV_StartSound( ent, CHAN_BODY, "player/pl_wade4.wav", 1.0f, ATTN_NORM, 0, 100 ); break; } ent->v.flags = flags & ~FL_INWATER; } ent->v.air_finished = sv.time + 12.0f; return; } if( watertype == CONTENTS_LAVA ) { if((!( flags & ( FL_IMMUNE_LAVA|FL_GODMODE ))) && ent->v.dmgtime < sv.time ) { if( ent->v.radsuit_finished < sv.time ) ent->v.dmgtime = sv.time + 0.2f; else ent->v.dmgtime = sv.time + 1.0f; } } else if( watertype == CONTENTS_SLIME ) { if((!( flags & ( FL_IMMUNE_SLIME|FL_GODMODE ))) && ent->v.dmgtime < sv.time ) { if( ent->v.radsuit_finished < sv.time ) ent->v.dmgtime = sv.time + 1.0; // otherwise radsuit is fully protect entity from slime } } if( !( flags & FL_INWATER )) { if( watertype == CONTENTS_WATER ) { // entering the water switch( Com_RandomLong( 0, 3 )) { case 0: SV_StartSound( ent, CHAN_BODY, "player/pl_wade1.wav", 1.0f, ATTN_NORM, 0, 100 ); break; case 1: SV_StartSound( ent, CHAN_BODY, "player/pl_wade2.wav", 1.0f, ATTN_NORM, 0, 100 ); break; case 2: SV_StartSound( ent, CHAN_BODY, "player/pl_wade3.wav", 1.0f, ATTN_NORM, 0, 100 ); break; case 3: SV_StartSound( ent, CHAN_BODY, "player/pl_wade4.wav", 1.0f, ATTN_NORM, 0, 100 ); break; } } ent->v.flags = flags | FL_INWATER; ent->v.dmgtime = 0.0f; } if( !( flags & FL_WATERJUMP )) { VectorMA( ent->v.velocity, ( ent->v.waterlevel * -0.8f * host.frametime ), ent->v.velocity, ent->v.velocity ); } }