/* ====================== UI_MachinegunSpinAngle ====================== */ float UI_MachinegunSpinAngle( uiPlayerInfo_t *pi ) { int delta; float angle; float speed; int torsoAnim; delta = dp_realtime - pi->barrelTime; if ( pi->barrelSpinning ) { angle = pi->barrelAngle + delta * SPIN_SPEED; } else { if ( delta > COAST_TIME ) { delta = COAST_TIME; } speed = 0.5 * ( SPIN_SPEED + (float)( COAST_TIME - delta ) / COAST_TIME ); angle = pi->barrelAngle + delta * speed; } torsoAnim = pi->torsoAnim & ~ANIM_TOGGLEBIT; #ifdef TA_WEAPSYS if (BG_PlayerAttackAnim(torsoAnim)) #else if( torsoAnim == TORSO_ATTACK2 ) #endif { torsoAnim = TORSO_ATTACK; } if ( pi->barrelSpinning == !(torsoAnim == TORSO_ATTACK) ) { pi->barrelTime = dp_realtime; pi->barrelAngle = AngleMod( angle ); pi->barrelSpinning = !!(torsoAnim == TORSO_ATTACK); } return angle; }
/* =============== UI_TorsoSequencing =============== */ static void UI_TorsoSequencing( uiPlayerInfo_t *pi ) { int currentAnim; currentAnim = pi->torsoAnim & ~ANIM_TOGGLEBIT; if ( pi->weapon != pi->currentWeapon ) { if ( currentAnim != TORSO_DROP ) { pi->torsoAnimationTimer = UI_TIMER_WEAPON_SWITCH; UI_ForceTorsoAnim( pi, TORSO_DROP ); } } if ( pi->torsoAnimationTimer > 0 ) { return; } if( currentAnim == TORSO_GESTURE ) { #ifdef TA_WEAPSYS UI_SetTorsoAnim( pi, BG_TorsoStandForWeapon(pi->realWeapon) ); #else UI_SetTorsoAnim( pi, TORSO_STAND ); #endif return; } #ifdef TA_WEAPSYS if (BG_PlayerAttackAnim(currentAnim)) { UI_SetTorsoAnim( pi, BG_TorsoStandForWeapon(pi->realWeapon) ); return; } #else if( currentAnim == TORSO_ATTACK || currentAnim == TORSO_ATTACK2 ) { UI_SetTorsoAnim( pi, TORSO_STAND ); return; } #endif if ( currentAnim == TORSO_DROP ) { UI_PlayerInfo_SetWeapon( pi, pi->weapon ); pi->torsoAnimationTimer = UI_TIMER_WEAPON_SWITCH; UI_ForceTorsoAnim( pi, TORSO_RAISE ); return; } if ( currentAnim == TORSO_RAISE ) { #ifdef TA_WEAPSYS UI_SetTorsoAnim( pi, BG_TorsoStandForWeapon(pi->realWeapon) ); #else UI_SetTorsoAnim( pi, TORSO_STAND ); #endif return; } }
/* =============== UI_ForceTorsoAnim =============== */ static void UI_ForceTorsoAnim( uiPlayerInfo_t *pi, int anim ) { pi->torsoAnim = ( ( pi->torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim; if ( anim == TORSO_GESTURE ) { #ifdef TA_PLAYERSYS // PLAYERCFG_ANIMATION_TIMES pi->torsoAnimationTimer = BG_AnimationTime(&pi->playercfg.animations[anim]); #else pi->torsoAnimationTimer = UI_TIMER_GESTURE; #endif } #ifdef TA_WEAPSYS if (BG_PlayerAttackAnim(anim)) #else if ( anim == TORSO_ATTACK || anim == TORSO_ATTACK2 ) #endif { #ifdef TA_PLAYERSYS // PLAYERCFG_ANIMATION_TIMES pi->torsoAnimationTimer = BG_AnimationTime(&pi->playercfg.animations[anim]); #else pi->torsoAnimationTimer = UI_TIMER_ATTACK; #endif } }
/* =============== UI_PlayerInfo_SetInfo =============== */ void UI_PlayerInfo_SetInfo( uiPlayerInfo_t *pi, int legsAnim, int torsoAnim, vec3_t viewAngles, vec3_t moveAngles, weapon_t weaponNumber, qboolean chat ) { int currentAnim; weapon_t weaponNum; pi->chat = chat; UI_PlayerInfo_UpdateColor( pi ); // view angles VectorCopy( viewAngles, pi->viewAngles ); // move angles VectorCopy( moveAngles, pi->moveAngles ); if ( pi->newModel ) { pi->newModel = qfalse; #ifdef TA_WEAPSYS atkAnim = 0; #endif jumpHeight = 0; pi->pendingLegsAnim = 0; UI_ForceLegsAnim( pi, legsAnim ); pi->legs.yawAngle = viewAngles[YAW]; pi->legs.yawing = qfalse; pi->pendingTorsoAnim = 0; UI_ForceTorsoAnim( pi, torsoAnim ); pi->torso.yawAngle = viewAngles[YAW]; pi->torso.yawing = qfalse; if ( weaponNumber != WP_NUM_WEAPONS ) { pi->weapon = weaponNumber; pi->currentWeapon = weaponNumber; pi->lastWeapon = weaponNumber; pi->pendingWeapon = WP_NUM_WEAPONS; pi->weaponTimer = 0; UI_PlayerInfo_SetWeapon( pi, pi->weapon ); } return; } // weapon if ( weaponNumber == WP_NUM_WEAPONS ) { pi->pendingWeapon = WP_NUM_WEAPONS; pi->weaponTimer = 0; } else if ( weaponNumber != WP_NONE ) { pi->pendingWeapon = weaponNumber; pi->weaponTimer = dp_realtime + UI_TIMER_WEAPON_DELAY; } weaponNum = pi->lastWeapon; pi->weapon = weaponNum; if ( torsoAnim == BOTH_DEATH1 || legsAnim == BOTH_DEATH1 ) { torsoAnim = legsAnim = BOTH_DEATH1; pi->weapon = pi->currentWeapon = WP_NONE; UI_PlayerInfo_SetWeapon( pi, pi->weapon ); jumpHeight = 0; pi->pendingLegsAnim = 0; UI_ForceLegsAnim( pi, legsAnim ); pi->pendingTorsoAnim = 0; UI_ForceTorsoAnim( pi, torsoAnim ); return; } // leg animation #ifdef TA_WEAPSYS if (BG_PlayerAttackAnim(torsoAnim)) { // if torso is attacking, possibly need to animate legs too. currentAnim = BG_LegsAttackForWeapon(&pi->playercfg, weaponNum, atkAnim); if (currentAnim != -1) { legsAnim = currentAnim; } } #endif currentAnim = pi->legsAnim & ~ANIM_TOGGLEBIT; if ( legsAnim != LEGS_JUMP && ( currentAnim == LEGS_JUMP || currentAnim == LEGS_LAND ) ) { pi->pendingLegsAnim = legsAnim; } else if ( legsAnim != currentAnim ) { jumpHeight = 0; pi->pendingLegsAnim = 0; UI_ForceLegsAnim( pi, legsAnim ); } // torso animation #ifdef TA_WEAPSYS if (BG_PlayerStandAnim(&pi->playercfg, AP_TORSO, torsoAnim)) { torsoAnim = BG_TorsoStandForWeapon(weaponNum); } #else if ( torsoAnim == TORSO_STAND || torsoAnim == TORSO_STAND2 ) { if ( weaponNum == WP_NONE || weaponNum == WP_GAUNTLET ) { torsoAnim = TORSO_STAND2; } else { torsoAnim = TORSO_STAND; } } #endif #ifdef TA_WEAPSYS if (BG_PlayerAttackAnim(torsoAnim)) { torsoAnim = BG_TorsoAttackForWeapon(weaponNum, atkAnim); if (!BG_WeaponHasMelee(weaponNum)) { pi->muzzleFlashTime = dp_realtime + UI_TIMER_MUZZLE_FLASH; } //FIXME play firing sound here atkAnim++; } #else if ( torsoAnim == TORSO_ATTACK || torsoAnim == TORSO_ATTACK2 ) { if ( weaponNum == WP_NONE || weaponNum == WP_GAUNTLET ) { torsoAnim = TORSO_ATTACK2; } else { torsoAnim = TORSO_ATTACK; } pi->muzzleFlashTime = dp_realtime + UI_TIMER_MUZZLE_FLASH; //FIXME play firing sound here } #endif currentAnim = pi->torsoAnim & ~ANIM_TOGGLEBIT; if ( weaponNum != pi->currentWeapon || currentAnim == TORSO_RAISE || currentAnim == TORSO_DROP ) { pi->pendingTorsoAnim = torsoAnim; } else if ( ( currentAnim == TORSO_GESTURE || #ifdef TA_WEAPSYS BG_PlayerAttackAnim(currentAnim) #else currentAnim == TORSO_ATTACK #endif ) && ( torsoAnim != currentAnim ) ) { pi->pendingTorsoAnim = torsoAnim; } else if ( torsoAnim != currentAnim ) { pi->pendingTorsoAnim = 0; UI_ForceTorsoAnim( pi, torsoAnim ); } }
/* =============== UI_PlayerAngles =============== */ static void UI_PlayerAngles( uiPlayerInfo_t *pi, vec3_t legs[3], vec3_t torso[3], vec3_t head[3] ) { vec3_t legsAngles, torsoAngles, headAngles; float dest; float adjust; VectorCopy( pi->viewAngles, headAngles ); headAngles[YAW] = AngleMod( headAngles[YAW] ); VectorClear( legsAngles ); VectorClear( torsoAngles ); // --------- yaw ------------- // allow yaw to drift a bit #ifdef TA_WEAPSYS if (!BG_PlayerStandAnim(&pi->playercfg, AP_LEGS, pi->legsAnim) || !BG_PlayerStandAnim(&pi->playercfg, AP_TORSO, pi->torsoAnim)) #else if ( ( pi->legsAnim & ~ANIM_TOGGLEBIT ) != LEGS_IDLE || ( pi->torsoAnim & ~ANIM_TOGGLEBIT ) != TORSO_STAND ) #endif { // if not standing still, always point all in the same direction pi->torso.yawing = qtrue; // always center pi->torso.pitching = qtrue; // always center pi->legs.yawing = qtrue; // always center } // adjust legs for movement dir adjust = UI_MovedirAdjustment( pi ); legsAngles[YAW] = headAngles[YAW] + adjust; torsoAngles[YAW] = headAngles[YAW] + 0.25 * adjust; // torso #ifdef IOQ3ZTM // BG_SWING_ANGLES BG_SwingAngles( torsoAngles[YAW], 25, 90, BG_SWINGSPEED, &pi->torso.yawAngle, &pi->torso.yawing, uis.frametime ); BG_SwingAngles( legsAngles[YAW], 40, 90, BG_SWINGSPEED, &pi->legs.yawAngle, &pi->legs.yawing, uis.frametime ); #else UI_SwingAngles( torsoAngles[YAW], 25, 90, SWINGSPEED, &pi->torso.yawAngle, &pi->torso.yawing ); UI_SwingAngles( legsAngles[YAW], 40, 90, SWINGSPEED, &pi->legs.yawAngle, &pi->legs.yawing ); #endif torsoAngles[YAW] = pi->torso.yawAngle; legsAngles[YAW] = pi->legs.yawAngle; // --------- pitch ------------- // only show a fraction of the pitch angle in the torso if ( headAngles[PITCH] > 180 ) { dest = (-360 + headAngles[PITCH]) * 0.75; } else { dest = headAngles[PITCH] * 0.75; } #ifdef IOQ3ZTM // BG_SWING_ANGLES BG_SwingAngles( dest, 15, 30, 0.1f, &pi->torso.pitchAngle, &pi->torso.pitching, uis.frametime ); #else UI_SwingAngles( dest, 15, 30, 0.1f, &pi->torso.pitchAngle, &pi->torso.pitching ); #endif torsoAngles[PITCH] = pi->torso.pitchAngle; #ifdef TA_PLAYERSYS if ( pi->playercfg.fixedtorso ) { #else if ( pi->fixedtorso ) { #endif torsoAngles[PITCH] = 0.0f; } #ifdef TA_PLAYERSYS if ( pi->playercfg.fixedlegs ) { #else if ( pi->fixedlegs ) { #endif legsAngles[YAW] = torsoAngles[YAW]; legsAngles[PITCH] = 0.0f; legsAngles[ROLL] = 0.0f; } // pull the angles back out of the hierarchial chain AnglesSubtract( headAngles, torsoAngles, headAngles ); AnglesSubtract( torsoAngles, legsAngles, torsoAngles ); AnglesToAxis( legsAngles, legs ); AnglesToAxis( torsoAngles, torso ); AnglesToAxis( headAngles, head ); } /* =============== UI_PlayerFloatSprite =============== */ static void UI_PlayerFloatSprite( uiPlayerInfo_t *pi, vec3_t origin, qhandle_t shader ) { refEntity_t ent; memset( &ent, 0, sizeof( ent ) ); VectorCopy( origin, ent.origin ); ent.origin[2] += 42; ent.reType = RT_SPRITE; ent.customShader = shader; ent.radius = 10; ent.renderfx = 0; trap_R_AddRefEntityToScene( &ent ); } /* ====================== UI_MachinegunSpinAngle ====================== */ float UI_MachinegunSpinAngle( uiPlayerInfo_t *pi ) { int delta; float angle; float speed; int torsoAnim; delta = dp_realtime - pi->barrelTime; if ( pi->barrelSpinning ) { angle = pi->barrelAngle + delta * SPIN_SPEED; } else { if ( delta > COAST_TIME ) { delta = COAST_TIME; } speed = 0.5 * ( SPIN_SPEED + (float)( COAST_TIME - delta ) / COAST_TIME ); angle = pi->barrelAngle + delta * speed; } torsoAnim = pi->torsoAnim & ~ANIM_TOGGLEBIT; #ifdef TA_WEAPSYS if (BG_PlayerAttackAnim(torsoAnim)) #else if( torsoAnim == TORSO_ATTACK2 ) #endif { torsoAnim = TORSO_ATTACK; } if ( pi->barrelSpinning == !(torsoAnim == TORSO_ATTACK) ) { pi->barrelTime = dp_realtime; pi->barrelAngle = AngleMod( angle ); pi->barrelSpinning = !!(torsoAnim == TORSO_ATTACK); } return angle; }