/* ===================== RE_AddRefEntityToScene ===================== */ void RE_AddRefEntityToScene( const refEntity_t *ent ) { if ( !tr.registered ) { return; } if ( r_numentities >= MAX_REFENTITIES ) { ri.Printf(PRINT_DEVELOPER, "RE_AddRefEntityToScene: Dropping refEntity, reached MAX_REFENTITIES\n"); return; } if ( Q_isnan(ent->origin[0]) || Q_isnan(ent->origin[1]) || Q_isnan(ent->origin[2]) ) { static qboolean firstTime = qtrue; if (firstTime) { firstTime = qfalse; ri.Printf( PRINT_WARNING, "RE_AddRefEntityToScene passed a refEntity which has an origin with a NaN component\n"); } return; } if ( (int)ent->reType < 0 || ent->reType >= RT_MAX_REF_ENTITY_TYPE ) { ri.Error( ERR_DROP, "RE_AddRefEntityToScene: bad reType %i", ent->reType ); } backEndData->entities[r_numentities].e = *ent; backEndData->entities[r_numentities].lightingCalculated = qfalse; r_numentities++; }
void AddSightEvent( gentity_t *owner, vec3_t position, float radius, alertEventLevel_e alertLevel, float addLight ) { //FIXME: Handle this in another manner? if ( level.numAlertEvents >= MAX_ALERT_EVENTS ) { if ( !RemoveOldestAlert() ) {//how could that fail? return; } } if ( owner == NULL && alertLevel < AEL_DANGER ) //allows un-owned danger alerts return; //FIXME: if owner is not a player or player ally, and there are no player allies present, // perhaps we don't need to store the alert... unless we want the player to // react to enemy alert events in some way? #ifdef _DEBUG assert( !Q_isnan(position[0]) && !Q_isnan(position[1]) && !Q_isnan(position[2]) ); #endif VectorCopy( position, level.alertEvents[ level.numAlertEvents ].position ); level.alertEvents[ level.numAlertEvents ].radius = radius; level.alertEvents[ level.numAlertEvents ].level = alertLevel; level.alertEvents[ level.numAlertEvents ].type = AET_SIGHT; level.alertEvents[ level.numAlertEvents ].owner = owner; level.alertEvents[ level.numAlertEvents ].addLight = addLight; //will get added to actual light at that point when it's checked level.alertEvents[ level.numAlertEvents ].ID = level.curAlertID++; level.alertEvents[ level.numAlertEvents ].timestamp = level.time; level.numAlertEvents++; }
static void _S_AL_SanitiseVector( vec3_t v, int line ) { if( Q_isnan( v[ 0 ] ) || Q_isnan( v[ 1 ] ) || Q_isnan( v[ 2 ] ) ) { Com_DPrintf( S_COLOR_YELLOW "WARNING: vector with one or more NaN components " "being passed to OpenAL at %s:%d -- zeroing\n", __FILE__, line ); VectorClear( v ); } }
void AddSoundEvent( gentity_t *owner, vec3_t position, float radius, alertEventLevel_e alertLevel, qboolean needLOS, qboolean onGround ) { //FIXME: Handle this in another manner? if ( level.numAlertEvents >= MAX_ALERT_EVENTS ) { if ( !RemoveOldestAlert() ) {//how could that fail? return; } } if ( owner == NULL && alertLevel < AEL_DANGER ) //allows un-owned danger alerts return; //FIXME: why are Sand creatures suddenly crashlanding? if ( owner && owner->client && owner->client->NPC_class == CLASS_SAND_CREATURE ) { return; } //FIXME: if owner is not a player or player ally, and there are no player allies present, // perhaps we don't need to store the alert... unless we want the player to // react to enemy alert events in some way? #ifdef _DEBUG assert( !Q_isnan(position[0]) && !Q_isnan(position[1]) && !Q_isnan(position[2]) ); #endif VectorCopy( position, level.alertEvents[ level.numAlertEvents ].position ); level.alertEvents[ level.numAlertEvents ].radius = radius; level.alertEvents[ level.numAlertEvents ].level = alertLevel; level.alertEvents[ level.numAlertEvents ].type = AET_SOUND; level.alertEvents[ level.numAlertEvents ].owner = owner; if ( needLOS ) {//a very low-level sound, when check this sound event, check for LOS level.alertEvents[ level.numAlertEvents ].addLight = 1; //will force an LOS trace on this sound } else { level.alertEvents[ level.numAlertEvents ].addLight = 0; //will force an LOS trace on this sound } level.alertEvents[ level.numAlertEvents ].onGround = onGround; level.alertEvents[ level.numAlertEvents ].ID = ++level.curAlertID; level.alertEvents[ level.numAlertEvents ].timestamp = level.time; level.numAlertEvents++; }
/* ===================== RE_AddRefEntityToScene ===================== */ void RE_AddRefEntityToScene( const refEntity_t *ent, int entBufSize, int numVerts, const polyVert_t *verts, int numPolys ) { if ( !tr.registered ) { return; } if ( r_numentities >= MAX_REFENTITIES ) { ri.Printf(PRINT_DEVELOPER, "RE_AddRefEntityToScene: Dropping refEntity, reached MAX_REFENTITIES\n"); return; } if ( Q_isnan(ent->origin[0]) || Q_isnan(ent->origin[1]) || Q_isnan(ent->origin[2]) ) { static qboolean firstTime = qtrue; if (firstTime) { firstTime = qfalse; ri.Printf( PRINT_WARNING, "RE_AddRefEntityToScene passed a refEntity which has an origin with a NaN component\n"); } return; } if ( (int)ent->reType < 0 || ent->reType >= RT_MAX_REF_ENTITY_TYPE ) { ri.Error( ERR_DROP, "RE_AddRefEntityToScene: bad reType %i", ent->reType ); } if ( ent->reType == RT_POLY_GLOBAL || ent->reType == RT_POLY_LOCAL ) { int totalVerts = numVerts * numPolys; if ( !verts || numVerts <= 0 || numPolys <= 0 ) { ri.Printf( PRINT_WARNING, "WARNING: RE_AddRefEntityToScene: RT_POLY without poly info\n"); return; } if ( r_numpolyverts + totalVerts > max_polyverts ) { ri.Printf( PRINT_DEVELOPER, "WARNING: RE_AddRefEntityToScene: r_max_polyverts reached\n"); return; } backEndData->entities[r_numentities].numPolys = numPolys; backEndData->entities[r_numentities].numVerts = numVerts; backEndData->entities[r_numentities].verts = &backEndData->polyVerts[r_numpolyverts]; Com_Memcpy( backEndData->entities[r_numentities].verts, verts, totalVerts * sizeof( *verts ) ); r_numpolyverts += totalVerts; } Com_Memcpy2( &backEndData->entities[r_numentities].e, sizeof ( refEntity_t ), ent, entBufSize ); backEndData->entities[r_numentities].lightingCalculated = qfalse; r_numentities++; }
/* ===================== RE_AddRefEntityToScene ===================== */ void RE_AddRefEntityToScene( const refEntity_t *ent ) { if ( !tr.registered ) { return; } if ( r_numentities >= MAX_ENTITIES ) { return; } if ( Q_isnan(ent->origin[0]) || Q_isnan(ent->origin[1]) || Q_isnan(ent->origin[2]) ) { return; } if ( ent->reType < 0 || ent->reType >= RT_MAX_REF_ENTITY_TYPE ) { ri.Error( ERR_DROP, "RE_AddRefEntityToScene: bad reType %i", ent->reType ); } backEndData[tr.smpFrame]->entities[r_numentities].e = *ent; backEndData[tr.smpFrame]->entities[r_numentities].lightingCalculated = qfalse; r_numentities++; }
/* ===================== RE_AddRefEntityToScene ===================== */ void RE_AddRefEntityToScene(const refEntity_t *ent) { if (!tr.registered) { return; } // fixed was ENTITYNUM_WORLD if (r_numentities >= MAX_REFENTITIES) { // we may change this to developer print Ren_Print("WARNING RE_AddRefEntityToScene: Dropping refEntity, reached MAX_REFENTITIES\n"); return; } if (Q_isnan(ent->origin[0]) || Q_isnan(ent->origin[1]) || Q_isnan(ent->origin[2])) { static qboolean firstTime = qtrue; if (firstTime) { firstTime = qfalse; Ren_Print("WARNING RE_AddRefEntityToScene passed a refEntity which has an origin with a NaN component\n"); } return; } if ((int)ent->reType < 0 || ent->reType >= RT_MAX_REF_ENTITY_TYPE) { Ren_Drop("RE_AddRefEntityToScene: bad reType %i", ent->reType); } backEndData->entities[r_numentities].e = *ent; backEndData->entities[r_numentities].lightingCalculated = qfalse; r_numentities++; // add projected shadows for this model // - casting const away R_AddModelShadow((refEntity_t *) ent); }
/* ===================== RE_AddRefEntityToScene ===================== */ void RE_AddRefEntityToScene( const refEntity_t *ent ) { if ( !tr.registered ) { return; } if ( r_numentities >= MAX_ENTITIES ) { return; } if ( Q_isnan(ent->origin[0]) || Q_isnan(ent->origin[1]) || Q_isnan(ent->origin[2]) ) { static qboolean firstTime = qtrue; if (firstTime) { firstTime = qfalse; Com_DPrintf(S_COLOR_YELLOW "WARNING: RE_AddRefEntityToScene passed a refEntity which has an origin with a NaN component\n"); } return; } if ( ent->reType < 0 || ent->reType >= RT_MAX_REF_ENTITY_TYPE ) { ri.Error( ERR_DROP, "RE_AddRefEntityToScene: bad reType %i", ent->reType ); } backEndData[tr.smpFrame]->entities[r_numentities].e = *ent; backEndData[tr.smpFrame]->entities[r_numentities].lightingCalculated = qfalse; r_numentities++; }
void G_ReflectMissile( gentity_t *ent, gentity_t *missile, vec3_t forward ) { vec3_t bounce_dir; int i; float speed; qboolean reflected = qfalse; gentity_t *owner = ent; if ( ent->owner ) { owner = ent->owner; } //save the original speed speed = VectorNormalize( missile->s.pos.trDelta ); if ( ent && owner && owner->client && !owner->client->ps.saberInFlight && (owner->client->ps.forcePowerLevel[FP_SABER_DEFENSE] > FORCE_LEVEL_2 || (owner->client->ps.forcePowerLevel[FP_SABER_DEFENSE]>FORCE_LEVEL_1&&!Q_irand( 0, 3 )) ) ) {//if high enough defense skill and saber in-hand (100% at level 3, 25% at level 2, 0% at level 1), reflections are perfectly deflected toward an enemy gentity_t *enemy; if ( owner->enemy && Q_irand( 0, 3 ) ) {//toward current enemy 75% of the time enemy = owner->enemy; } else {//find another enemy enemy = Jedi_FindEnemyInCone( owner, owner->enemy, 0.3f ); } if ( enemy ) { vec3_t bullseye; CalcEntitySpot( enemy, SPOT_HEAD, bullseye ); bullseye[0] += Q_irand( -4, 4 ); bullseye[1] += Q_irand( -4, 4 ); bullseye[2] += Q_irand( -16, 4 ); VectorSubtract( bullseye, missile->currentOrigin, bounce_dir ); VectorNormalize( bounce_dir ); if ( !PM_SaberInParry( owner->client->ps.saberMove ) && !PM_SaberInReflect( owner->client->ps.saberMove ) && !PM_SaberInIdle( owner->client->ps.saberMove ) ) {//a bit more wild if ( PM_SaberInAttack( owner->client->ps.saberMove ) || PM_SaberInTransitionAny( owner->client->ps.saberMove ) || PM_SaberInSpecialAttack( owner->client->ps.torsoAnim ) ) {//moderately more wild for ( i = 0; i < 3; i++ ) { bounce_dir[i] += Q_flrand( -0.2f, 0.2f ); } } else {//mildly more wild for ( i = 0; i < 3; i++ ) { bounce_dir[i] += Q_flrand( -0.1f, 0.1f ); } } } VectorNormalize( bounce_dir ); reflected = qtrue; } } if ( !reflected ) { if ( missile->owner && missile->s.weapon != WP_SABER ) {//bounce back at them if you can VectorSubtract( missile->owner->currentOrigin, missile->currentOrigin, bounce_dir ); VectorNormalize( bounce_dir ); } else { vec3_t missile_dir; VectorSubtract( ent->currentOrigin, missile->currentOrigin, missile_dir ); VectorCopy( missile->s.pos.trDelta, bounce_dir ); VectorScale( bounce_dir, DotProduct( forward, missile_dir ), bounce_dir ); VectorNormalize( bounce_dir ); } if ( owner->s.weapon == WP_SABER && owner->client ) {//saber if ( owner->client->ps.saberInFlight ) {//reflecting off a thrown saber is totally wild for ( i = 0; i < 3; i++ ) { bounce_dir[i] += Q_flrand( -0.8f, 0.8f ); } } else if ( owner->client->ps.forcePowerLevel[FP_SABER_DEFENSE] <= FORCE_LEVEL_1 ) {// at level 1 for ( i = 0; i < 3; i++ ) { bounce_dir[i] += Q_flrand( -0.4f, 0.4f ); } } else {// at level 2 for ( i = 0; i < 3; i++ ) { bounce_dir[i] += Q_flrand( -0.2f, 0.2f ); } } if ( !PM_SaberInParry( owner->client->ps.saberMove ) && !PM_SaberInReflect( owner->client->ps.saberMove ) && !PM_SaberInIdle( owner->client->ps.saberMove ) ) {//a bit more wild if ( PM_SaberInAttack( owner->client->ps.saberMove ) || PM_SaberInTransitionAny( owner->client->ps.saberMove ) || PM_SaberInSpecialAttack( owner->client->ps.torsoAnim ) ) {//really wild for ( i = 0; i < 3; i++ ) { bounce_dir[i] += Q_flrand( -0.3f, 0.3f ); } } else {//mildly more wild for ( i = 0; i < 3; i++ ) { bounce_dir[i] += Q_flrand( -0.1f, 0.1f ); } } } } else {//some other kind of reflection for ( i = 0; i < 3; i++ ) { bounce_dir[i] += Q_flrand( -0.2f, 0.2f ); } } } VectorNormalize( bounce_dir ); VectorScale( bounce_dir, speed, missile->s.pos.trDelta ); #ifdef _DEBUG assert( !Q_isnan(missile->s.pos.trDelta[0])&&!Q_isnan(missile->s.pos.trDelta[1])&&!Q_isnan(missile->s.pos.trDelta[2])); #endif// _DEBUG missile->s.pos.trTime = level.time - 10; // move a bit on the very first frame VectorCopy( missile->currentOrigin, missile->s.pos.trBase ); if ( missile->s.weapon != WP_SABER ) {//you are mine, now! if ( !missile->lastEnemy ) {//remember who originally shot this missile missile->lastEnemy = missile->owner; } missile->owner = owner; } if ( missile->s.weapon == WP_ROCKET_LAUNCHER ) {//stop homing missile->e_ThinkFunc = thinkF_NULL; } }
void G_ReflectMissile(gentity_t *ent, gentity_t *missile, vec3_t forward, forcePowers_t powerToUse) { vec3_t bounce_dir; int i; float speed; qboolean perfectReflection = qfalse; qboolean reflected = qfalse; gentity_t *owner = ent; if (ent->owner) { owner = ent->owner; } //save the original speed speed = VectorNormalize(missile->s.pos.trDelta); if (ent && owner && owner->client && (owner->client->ps.forcePowerLevel[powerToUse] > FORCE_LEVEL_2 || (owner->client->ps.forcePowerLevel[powerToUse]>FORCE_LEVEL_1&&!Q_irand(0, 3)))) //if high enough force skill (100% at level 3, 25% at level 2, 0% at level 1), reflections are perfectly deflected toward an enemy { perfectReflection = qtrue; } if (powerToUse == FP_SABER_DEFENSE) { if (owner->client->ps.saberInFlight) {//but need saber in-hand for perfect reflection perfectReflection = qfalse; } if (g_spskill->integer >= 2 && !g_saberAutoBlocking->integer && owner->client->ps.saberBlockingTime < level.time) {//but need to be blocking for perfect reflection on higher difficulties perfectReflection = qfalse; } /* if (!PM_WalkingOrIdle(owner) || !PM_SaberInParry(owner->client->ps.saberMove)) {//but need to be blocking for perfect reflection on higher difficulties perfectReflection = qfalse; } */ } if (perfectReflection) { if (g_saberDeflectAutoAim->integer || owner->s.clientNum >= MAX_CLIENTS) //either by autoaim (lower difficulties) { gentity_t *enemy; if (owner->enemy && Q_irand(0, 3)) {//toward current enemy 75% of the time enemy = owner->enemy; } else {//find another enemy enemy = Jedi_FindEnemyInCone(owner, owner->enemy, 0.3f); } if (enemy) { vec3_t bullseye; CalcEntitySpot(enemy, SPOT_HEAD, bullseye); bullseye[0] += Q_irand(-4, 4); bullseye[1] += Q_irand(-4, 4); bullseye[2] += Q_irand(-16, 4); VectorSubtract(bullseye, missile->currentOrigin, bounce_dir); VectorNormalize(bounce_dir); if (!PM_SaberInParry(owner->client->ps.saberMove) && !PM_SaberInReflect(owner->client->ps.saberMove) && !PM_SaberInIdle(owner->client->ps.saberMove)) {//a bit more wild if (PM_SaberInAttack(owner->client->ps.saberMove) || PM_SaberInTransitionAny(owner->client->ps.saberMove) || PM_SaberInSpecialAttack(owner->client->ps.torsoAnim)) {//moderately more wild for (i = 0; i < 3; i++) { bounce_dir[i] += Q_flrand(-0.2f, 0.2f); } } else {//mildly more wild for (i = 0; i < 3; i++) { bounce_dir[i] += Q_flrand(-0.1f, 0.1f); } } } VectorNormalize(bounce_dir); reflected = qtrue; } } else //or by where the crosshair is (higher difficulties) { VectorSubtract(g_crosshairWorldCoord, missile->currentOrigin, bounce_dir); VectorNormalize(bounce_dir); if (!PM_SaberInParry(owner->client->ps.saberMove) && !PM_SaberInReflect(owner->client->ps.saberMove) && !PM_SaberInIdle(owner->client->ps.saberMove)) {//a bit more wild if (PM_SaberInAttack(owner->client->ps.saberMove) || PM_SaberInTransitionAny(owner->client->ps.saberMove) || PM_SaberInSpecialAttack(owner->client->ps.torsoAnim)) {//moderately more wild for (i = 0; i < 3; i++) { bounce_dir[i] += Q_flrand(-0.2f, 0.2f); } } else {//mildly more wild for (i = 0; i < 3; i++) { bounce_dir[i] += Q_flrand(-0.1f, 0.1f); } } } VectorNormalize(bounce_dir); reflected = qtrue; } } if (!reflected) { if (g_saberDeflectAutoAim->integer || owner->s.clientNum >= MAX_CLIENTS) { if (missile->owner && missile->s.weapon != WP_SABER) {//bounce back at them if you can VectorSubtract(missile->owner->currentOrigin, missile->currentOrigin, bounce_dir); VectorNormalize(bounce_dir); } else { vec3_t missile_dir; VectorSubtract(ent->currentOrigin, missile->currentOrigin, missile_dir); VectorCopy(missile->s.pos.trDelta, bounce_dir); VectorScale(bounce_dir, DotProduct(forward, missile_dir), bounce_dir); VectorNormalize(bounce_dir); } } else //deflect off at an angle. { vec3_t deflect_dir, missile_dir; float forceFactor; VectorSubtract(g_crosshairWorldCoord, missile->currentOrigin, deflect_dir); VectorCopy(missile->s.pos.trDelta, missile_dir); VectorNormalize(missile_dir); VectorNormalize(deflect_dir); //bigger forceFactors make the reflected shots go closer to the crosshair switch (owner->client->ps.forcePowerLevel[powerToUse]) { case FORCE_LEVEL_1: forceFactor = 2.0f; break; case FORCE_LEVEL_2: forceFactor = 3.0f; break; default: forceFactor = 10.0f; break; } VectorMA(missile_dir, forceFactor, deflect_dir, bounce_dir); VectorNormalize(bounce_dir); } if (owner->s.weapon == WP_SABER && owner->client && powerToUse == FP_SABER_DEFENSE) {//saber if (owner->client->ps.saberInFlight) {//reflecting off a thrown saber is totally wild for (i = 0; i < 3; i++) { bounce_dir[i] += Q_flrand(-0.8f, 0.8f); } } else if (owner->client->ps.forcePowerLevel[FP_SABER_DEFENSE] <= FORCE_LEVEL_1) {// at level 1 or below for (i = 0; i < 3; i++) { bounce_dir[i] += Q_flrand(-0.4f, 0.4f); } } else {// at level 2 for (i = 0; i < 3; i++) { bounce_dir[i] += Q_flrand(-0.2f, 0.2f); } } if (!PM_SaberInParry(owner->client->ps.saberMove) && !PM_SaberInReflect(owner->client->ps.saberMove) && !PM_SaberInIdle(owner->client->ps.saberMove)) {//a bit more wild if (PM_SaberInAttack(owner->client->ps.saberMove) || PM_SaberInTransitionAny(owner->client->ps.saberMove) || PM_SaberInSpecialAttack(owner->client->ps.torsoAnim)) {//really wild for (i = 0; i < 3; i++) { bounce_dir[i] += Q_flrand(-0.3f, 0.3f); } } else {//mildly more wild for (i = 0; i < 3; i++) { bounce_dir[i] += Q_flrand(-0.1f, 0.1f); } } } } else {//some other kind of reflection for (i = 0; i < 3; i++) { bounce_dir[i] += Q_flrand(-0.2f, 0.2f); } } } VectorNormalize(bounce_dir); VectorScale(bounce_dir, speed, missile->s.pos.trDelta); #ifdef _DEBUG assert(!Q_isnan(missile->s.pos.trDelta[0]) && !Q_isnan(missile->s.pos.trDelta[1]) && !Q_isnan(missile->s.pos.trDelta[2])); #endif// _DEBUG missile->s.pos.trTime = level.time - 10; // move a bit on the very first frame VectorCopy(missile->currentOrigin, missile->s.pos.trBase); if (missile->s.weapon != WP_SABER) {//you are mine, now! if (!missile->lastEnemy) {//remember who originally shot this missile missile->lastEnemy = missile->owner; } missile->owner = owner; } if (missile->s.weapon == WP_ROCKET_LAUNCHER) {//stop homing missile->e_ThinkFunc = thinkF_NULL; } }