mirror of
https://github.com/DrBeef/RTCWQuest.git
synced 2025-04-22 23:11:02 +00:00
Real dual-wield for akimbo
This commit is contained in:
parent
86a6a87903
commit
0f6d6386e8
14 changed files with 317 additions and 144 deletions
|
@ -1514,8 +1514,7 @@ void RTCWVR_Init()
|
|||
//Set up vr client info
|
||||
vr.backpackitemactive = 0;
|
||||
vr.visible_hud = qtrue;
|
||||
vr.dualwield = qfalse;
|
||||
vr.weapon_recoil = 0.0f;
|
||||
vr.weapon_recoil = 0.0f;
|
||||
|
||||
//Clear teleport stuff
|
||||
vr.teleportexecute = qfalse;
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
#define NUM_WEAPON_SAMPLES 10
|
||||
#define WEAPON_RECOIL 15.0f;
|
||||
|
||||
#define USE_GESTURE_OFF_HAND 1
|
||||
#define USE_GESTURE_WEAPON_HAND 2
|
||||
#define ACTIVE_OFF_HAND 1
|
||||
#define ACTIVE_WEAPON_HAND 2
|
||||
|
||||
typedef struct {
|
||||
qboolean screen;
|
||||
|
@ -15,7 +15,6 @@ typedef struct {
|
|||
qboolean menu_right_handed;
|
||||
qboolean player_moving;
|
||||
qboolean visible_hud;
|
||||
qboolean dualwield;
|
||||
int weaponid;
|
||||
int lastweaponid;
|
||||
int backpackitemactive; //0 - nothing, 1 - grenades, 2 - knife, 3 - Binoculars
|
||||
|
@ -55,6 +54,7 @@ typedef struct {
|
|||
|
||||
qboolean velocitytriggered; // Weapon attack triggered by velocity (knife)
|
||||
|
||||
vec3_t offhandweaponangles;
|
||||
vec3_t offhandangles;
|
||||
vec3_t offhandangles_last; // Don't use this, it is just for calculating delta!
|
||||
vec3_t offhandangles_delta;
|
||||
|
@ -79,6 +79,8 @@ typedef struct {
|
|||
qboolean binocularsActive;
|
||||
qboolean useHoldableItem;
|
||||
qboolean toggleMainMenu;
|
||||
int akimboTriggerState;
|
||||
qboolean akimboFire;
|
||||
|
||||
//////////////////////////////////////
|
||||
// Test stuff for weapon alignment
|
||||
|
|
|
@ -52,14 +52,6 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
|
|||
//Need this for the touch screen
|
||||
ovrTracking * pWeapon = pDominantTracking;
|
||||
ovrTracking * pOff = pOffTracking;
|
||||
if (vr.weaponid == WP_AKIMBO &&
|
||||
!vr.right_handed &&
|
||||
!RTCWVR_useScreenLayer())
|
||||
{
|
||||
//Revert to same weapon controls as right-handed if using akimbo
|
||||
pWeapon = pOffTracking;
|
||||
pOff = pDominantTracking;
|
||||
}
|
||||
|
||||
//All this to allow stick and button switching!
|
||||
ovrVector2f *pPrimaryJoystick;
|
||||
|
@ -111,24 +103,27 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
|
|||
QuatToYawPitchRoll(pDominantTracking->HeadPose.Pose.Orientation, rotation, vr.dominanthandangles);
|
||||
rotation[PITCH] = 30;
|
||||
QuatToYawPitchRoll(pWeapon->HeadPose.Pose.Orientation, rotation, vr.weaponangles_knife);
|
||||
rotation[PITCH] = vr_weapon_pitchadjust->value +
|
||||
(vr.pistol ? vr.weapon_recoil : 0.0f); // Our hacked recoil effect
|
||||
vr.weapon_recoil *= 0.8f; // quick reduction on synthetic recoil
|
||||
qboolean addRecoil = vr.pistol && (vr.weaponid != WP_AKIMBO || vr.akimboFire);
|
||||
rotation[PITCH] = vr_weapon_pitchadjust->value + (addRecoil ? vr.weapon_recoil : 0.0f); // Our hacked recoil effect
|
||||
QuatToYawPitchRoll(pWeapon->HeadPose.Pose.Orientation, rotation, vr.weaponangles);
|
||||
|
||||
VectorSubtract(vr.weaponangles_last, vr.weaponangles, vr.weaponangles_delta);
|
||||
VectorCopy(vr.weaponangles, vr.weaponangles_last);
|
||||
|
||||
ALOGV(" weaponangles_last: %f, %f, %f",
|
||||
vr.weaponangles_last[0], vr.weaponangles_last[1], vr.weaponangles_last[2]);
|
||||
ALOGV(" weaponangles_last: %f, %f, %f", vr.weaponangles_last[0], vr.weaponangles_last[1], vr.weaponangles_last[2]);
|
||||
|
||||
//GB Also set offhand angles just in case we want to use those.
|
||||
vec3_t rotation_off = {0};
|
||||
rotation_off[PITCH] = -25;
|
||||
QuatToYawPitchRoll(pOff->HeadPose.Pose.Orientation, rotation_off, vr.offhandangles);
|
||||
qboolean addRecoil_off = vr.pistol && (vr.weaponid != WP_AKIMBO || !vr.akimboFire);
|
||||
rotation_off[PITCH] = vr_weapon_pitchadjust->value + (addRecoil_off ? vr.weapon_recoil : 0.0f); // Our hacked recoil effect
|
||||
QuatToYawPitchRoll(pOff->HeadPose.Pose.Orientation, rotation_off, vr.offhandweaponangles);
|
||||
|
||||
VectorSubtract(vr.offhandangles_last, vr.offhandangles, vr.offhandangles_delta);
|
||||
VectorCopy(vr.offhandangles, vr.offhandangles_last);
|
||||
|
||||
vr.weapon_recoil *= 0.8f; // quick reduction on synthetic recoil
|
||||
}
|
||||
|
||||
//Menu button
|
||||
|
@ -279,10 +274,9 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
|
|||
sendButtonAction("+attack", velocityTriggeredAttack);
|
||||
}
|
||||
|
||||
if (vr.weapon_stabilised || vr.dualwield)
|
||||
if (vr.weapon_stabilised)
|
||||
{
|
||||
if (vr.scopeengaged || (vr_virtual_stock->integer == 1 && // Classic Virtual Stock
|
||||
!vr.dualwield))
|
||||
if (vr.scopeengaged || vr_virtual_stock->integer == 1)
|
||||
{
|
||||
//offset to the appropriate eye a little bit
|
||||
vec2_t xy;
|
||||
|
@ -305,16 +299,8 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
|
|||
float zxDist = length(x, z);
|
||||
|
||||
if (zxDist != 0.0f && z != 0.0f) {
|
||||
if (vr.dualwield) {
|
||||
//SUPER FUDGE
|
||||
VectorSet(vr.weaponangles, vr.weaponangles[PITCH],
|
||||
-90.0f-degrees(atan2f(x, -z)), degrees(atanf(y / zxDist)));
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorSet(vr.weaponangles, -degrees(atanf(y / zxDist)),
|
||||
-degrees(atan2f(x, -z)), vr.weaponangles[ROLL] / 2.0f); //Dampen roll on stabilised weapon
|
||||
}
|
||||
VectorSet(vr.weaponangles, -degrees(atanf(y / zxDist)),
|
||||
-degrees(atan2f(x, -z)), vr.weaponangles[ROLL] / 2.0f); //Dampen roll on stabilised weapon
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -583,6 +569,7 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
|
|||
else if (firing)
|
||||
{
|
||||
//no longer firing
|
||||
vr.akimboTriggerState = 0;
|
||||
firing = qfalse;
|
||||
ALOGV("**WEAPON EVENT** Grip Pushed %sattack", (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) ? "+" : "-");
|
||||
sendButtonAction("+attack", firing);
|
||||
|
@ -599,9 +586,22 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
|
|||
else
|
||||
{
|
||||
//Just ignore grip and fire
|
||||
firing = (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger);
|
||||
ALOGV("**WEAPON EVENT** Grip Pushed %sattack", (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) ? "+" : "-");
|
||||
sendButtonAction("+attack", firing);
|
||||
firing = (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger);
|
||||
if (vr.weaponid == WP_AKIMBO) {
|
||||
if (firing) {
|
||||
vr.akimboTriggerState |= ACTIVE_WEAPON_HAND;
|
||||
sendButtonAction("+attack", firing);
|
||||
} else {
|
||||
vr.akimboTriggerState &= ~ACTIVE_WEAPON_HAND;
|
||||
if (!vr.akimboTriggerState) { // Stop firing only if we are not firing with off-hand weapon
|
||||
sendButtonAction("+attack", firing);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
vr.akimboTriggerState = 0;
|
||||
sendButtonAction("+attack", firing);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -615,7 +615,20 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
|
|||
|
||||
ALOGV("**WEAPON EVENT** Not Grip Pushed %sattack", (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) ? "+" : "-");
|
||||
firing = (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger);
|
||||
sendButtonAction("+attack", firing);
|
||||
if (vr.weaponid == WP_AKIMBO) {
|
||||
if (firing) {
|
||||
vr.akimboTriggerState |= ACTIVE_WEAPON_HAND;
|
||||
sendButtonAction("+attack", firing);
|
||||
} else {
|
||||
vr.akimboTriggerState &= ~ACTIVE_WEAPON_HAND;
|
||||
if (!vr.akimboTriggerState) { // Stop firing only if we are not still firing with off-hand weapon
|
||||
sendButtonAction("+attack", firing);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
vr.akimboTriggerState = 0;
|
||||
sendButtonAction("+attack", firing);
|
||||
}
|
||||
}
|
||||
else if (binocularsactive) // trigger can zoom-in binoculars, remove from face to reset
|
||||
{
|
||||
|
@ -748,11 +761,30 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
|
|||
//in meantime, then it wouldn't stop the gun firing and it would get stuck
|
||||
if (!vr.teleportenabled)
|
||||
{
|
||||
//Run
|
||||
handleTrackedControllerButton(pOffTrackedRemoteNew,
|
||||
pOffTrackedRemoteOld,
|
||||
ovrButton_Trigger, K_SHIFT);
|
||||
|
||||
if (vr.weaponid == WP_AKIMBO && vr.backpackitemactive != 3 && !vr.binocularsActive) {
|
||||
// Fire off-hand weapon
|
||||
if ((pOffTrackedRemoteNew->Buttons & ovrButton_Trigger) != (pOffTrackedRemoteOld->Buttons & ovrButton_Trigger)) {
|
||||
ALOGV("**WEAPON EVENT** Off-hand trigger %sattack", (pOffTrackedRemoteNew->Buttons & ovrButton_Trigger) ? "+" : "-");
|
||||
qboolean firing = (pOffTrackedRemoteNew->Buttons & ovrButton_Trigger);
|
||||
if (firing) {
|
||||
vr.akimboTriggerState |= ACTIVE_OFF_HAND;
|
||||
sendButtonAction("+attack", firing);
|
||||
} else {
|
||||
vr.akimboTriggerState &= ~ACTIVE_OFF_HAND;
|
||||
if (!vr.akimboTriggerState) { // Stop firing only if we are not still firing with main weapon
|
||||
sendButtonAction("+attack", firing);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (vr.akimboTriggerState) {
|
||||
// Akimbo no longer active, stop attacking
|
||||
vr.akimboTriggerState = 0;
|
||||
sendButtonAction("+attack", qfalse);
|
||||
}
|
||||
// Run
|
||||
handleTrackedControllerButton(pOffTrackedRemoteNew, pOffTrackedRemoteOld, ovrButton_Trigger, K_SHIFT);
|
||||
}
|
||||
} else {
|
||||
if (pOffTrackedRemoteNew->Buttons & ovrButton_Trigger)
|
||||
{
|
||||
|
@ -861,34 +893,34 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
|
|||
// Off-hand gesture
|
||||
float distanceToBody = sqrt(vr.offhandoffset[0]*vr.offhandoffset[0] + vr.offhandoffset[2]*vr.offhandoffset[2]);
|
||||
if (gestureUseAllowed && (distanceToBody > vr_use_gesture_boundary->value)) {
|
||||
if (!(vr.useGestureState & USE_GESTURE_OFF_HAND)) {
|
||||
if (!(vr.useGestureState & ACTIVE_OFF_HAND)) {
|
||||
sendButtonAction("+activate2", true);
|
||||
}
|
||||
vr.useGestureState |= USE_GESTURE_OFF_HAND;
|
||||
vr.useGestureState |= ACTIVE_OFF_HAND;
|
||||
} else {
|
||||
if (vr.useGestureState & USE_GESTURE_OFF_HAND) {
|
||||
if (vr.useGestureState & ACTIVE_OFF_HAND) {
|
||||
sendButtonAction("+activate2", false);
|
||||
}
|
||||
vr.useGestureState &= ~USE_GESTURE_OFF_HAND;
|
||||
vr.useGestureState &= ~ACTIVE_OFF_HAND;
|
||||
}
|
||||
// Weapon-hand gesture
|
||||
distanceToBody = sqrt(vr.current_weaponoffset[0]*vr.current_weaponoffset[0] + vr.current_weaponoffset[2]*vr.current_weaponoffset[2]);
|
||||
if (gestureUseAllowed && (distanceToBody > vr_use_gesture_boundary->value)) {
|
||||
if (!(vr.useGestureState & USE_GESTURE_WEAPON_HAND)) {
|
||||
if (!(vr.useGestureState & ACTIVE_WEAPON_HAND)) {
|
||||
sendButtonAction("+activate", true);
|
||||
}
|
||||
vr.useGestureState |= USE_GESTURE_WEAPON_HAND;
|
||||
vr.useGestureState |= ACTIVE_WEAPON_HAND;
|
||||
} else {
|
||||
if (vr.useGestureState & USE_GESTURE_WEAPON_HAND) {
|
||||
if (vr.useGestureState & ACTIVE_WEAPON_HAND) {
|
||||
sendButtonAction("+activate", false);
|
||||
}
|
||||
vr.useGestureState &= ~USE_GESTURE_WEAPON_HAND;
|
||||
vr.useGestureState &= ~ACTIVE_WEAPON_HAND;
|
||||
}
|
||||
} else {
|
||||
if (vr.useGestureState & USE_GESTURE_OFF_HAND) {
|
||||
if (vr.useGestureState & ACTIVE_OFF_HAND) {
|
||||
sendButtonAction("+activate2", false);
|
||||
}
|
||||
if (vr.useGestureState & USE_GESTURE_WEAPON_HAND) {
|
||||
if (vr.useGestureState & ACTIVE_WEAPON_HAND) {
|
||||
sendButtonAction("+activate", false);
|
||||
}
|
||||
vr.useGestureState = 0;
|
||||
|
|
|
@ -1947,6 +1947,9 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
|
|||
|
||||
case EV_EMPTYCLIP:
|
||||
DEBUGNAME( "EV_EMPTYCLIP" );
|
||||
if ( ( es->weapon != WP_GRENADE_LAUNCHER ) && ( es->weapon != WP_GRENADE_PINEAPPLE ) && ( es->weapon != WP_DYNAMITE ) ) {
|
||||
trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.noAmmoSound );
|
||||
}
|
||||
break;
|
||||
|
||||
case EV_FILL_CLIP:
|
||||
|
@ -2022,8 +2025,10 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
|
|||
CG_FireWeapon( cent );
|
||||
if ( event == EV_FIRE_WEAPONB ) { // akimbo firing colt
|
||||
cent->akimboFire = qtrue;
|
||||
cgVR->akimboFire = qtrue;
|
||||
} else {
|
||||
cent->akimboFire = qfalse;
|
||||
cgVR->akimboFire = qfalse;
|
||||
}
|
||||
break;
|
||||
case EV_FIRE_WEAPON_LASTSHOT:
|
||||
|
|
|
@ -2097,7 +2097,7 @@ void CG_Bullet( vec3_t origin, int sourceEntityNum, vec3_t normal, qboolean fles
|
|||
void CG_RailTrail( clientInfo_t *ci, vec3_t start, vec3_t end, int type ); //----(SA) added 'type'
|
||||
void CG_GrappleTrail( centity_t *ent, const weaponInfo_t *wi );
|
||||
void CG_AddViewWeapon( playerState_t *ps );
|
||||
void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent );
|
||||
void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent, qboolean akimbo );
|
||||
void CG_DrawWeaponSelect( void );
|
||||
void CG_DrawHoldableSelect( void );
|
||||
void CG_AddViewHand( playerState_t *ps );
|
||||
|
|
|
@ -1436,7 +1436,11 @@ float CG_GetValue( int ownerDraw, int type ) {
|
|||
case CG_PLAYER_AMMOCLIP_VALUE:
|
||||
if ( cent->currentState.weapon ) {
|
||||
if ( type == RANGETYPE_RELATIVE ) {
|
||||
return (float)ps->ammoclip[BG_FindClipForWeapon( cent->currentState.weapon )] / (float)ammoTable[cent->currentState.weapon].maxclip;
|
||||
if (cent->currentState.weapon == WP_AKIMBO) {
|
||||
return (float)(ps->ammoclip[WP_AKIMBO] + ps->ammoclip[WP_COLT]) / (float)(ammoTable[WP_AKIMBO].maxclip * 4);
|
||||
} else {
|
||||
return (float)ps->ammoclip[BG_FindClipForWeapon( cent->currentState.weapon )] / (float)ammoTable[cent->currentState.weapon].maxclip;
|
||||
}
|
||||
} else {
|
||||
return ps->ammoclip[BG_FindClipForWeapon( cent->currentState.weapon )];
|
||||
}
|
||||
|
|
|
@ -5021,7 +5021,7 @@ void CG_Player( centity_t *cent ) {
|
|||
//
|
||||
// add the gun / barrel / flash
|
||||
//
|
||||
CG_AddPlayerWeapon( &torso, NULL, cent );
|
||||
CG_AddPlayerWeapon( &torso, NULL, cent, qfalse );
|
||||
|
||||
cent->lastWeaponClientFrame = cg.clientFrame;
|
||||
|
||||
|
|
|
@ -1607,7 +1607,8 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
|
|||
CG_DrawWheelSelector();
|
||||
} else if (!cgVR->screen){
|
||||
CG_AddViewWeapon( &cg.predictedPlayerState );
|
||||
if (trap_Cvar_VariableIntegerValue("vr_gesture_triggered_use") && !cgVR->weapon_stabilised && !cg.renderingThirdPerson) {
|
||||
qboolean usingAkimbo = cg.predictedPlayerState.weapon == WP_AKIMBO;
|
||||
if (!usingAkimbo && !cgVR->weapon_stabilised && !cg.renderingThirdPerson && trap_Cvar_VariableIntegerValue("vr_gesture_triggered_use")) {
|
||||
CG_AddViewHand( &cg.predictedPlayerState);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1977,17 +1977,9 @@ void convertFromVR(vec3_t in, vec3_t offset, vec3_t out)
|
|||
}
|
||||
|
||||
void CG_CalculateVRWeaponPosition( int weaponNum, vec3_t origin, vec3_t angles ) {
|
||||
|
||||
if (weaponNum != WP_AKIMBO || BG_AkimboFireSequence(weaponNum, cg.predictedPlayerState.ammoclip[WP_AKIMBO], cg.predictedPlayerState.ammoclip[WP_COLT] ))
|
||||
{
|
||||
convertFromVR(cgVR->calculated_weaponoffset, cg.refdef.vieworg, origin);
|
||||
} else{
|
||||
convertFromVR(cgVR->offhandoffset, cg.refdef.vieworg, origin);
|
||||
}
|
||||
|
||||
convertFromVR(cgVR->calculated_weaponoffset, cg.refdef.vieworg, origin);
|
||||
origin[2] -= 64;
|
||||
origin[2] += (cgVR->hmdposition[1] + cg_heightAdjust.value) * cg_worldScale.value;
|
||||
|
||||
switch (cg.predictedPlayerState.weapon)
|
||||
{
|
||||
case WP_KNIFE:
|
||||
|
@ -1997,7 +1989,6 @@ void CG_CalculateVRWeaponPosition( int weaponNum, vec3_t origin, vec3_t angles )
|
|||
VectorCopy(cgVR->weaponangles, angles);
|
||||
break;
|
||||
}
|
||||
|
||||
angles[YAW] += cg.refdefViewAngles[YAW] - cgVR->hmdorientation[YAW];
|
||||
}
|
||||
|
||||
|
@ -2017,6 +2008,14 @@ void CG_CalculateVROffHandPosition( vec3_t origin, vec3_t angles ) {
|
|||
angles[YAW] += cg.refdefViewAngles[YAW] - cgVR->hmdorientation[YAW];
|
||||
}
|
||||
|
||||
void CG_CalculateVROffHandWeaponPosition( vec3_t origin, vec3_t angles ) {
|
||||
convertFromVR(cgVR->offhandoffset, cg.refdef.vieworg, origin);
|
||||
origin[2] -= 64;
|
||||
origin[2] += (cgVR->hmdposition[1] + cg_heightAdjust.value) * cg_worldScale.value;
|
||||
VectorCopy(cgVR->offhandweaponangles, angles);
|
||||
angles[YAW] += cg.refdefViewAngles[YAW] - cgVR->hmdorientation[YAW];
|
||||
}
|
||||
|
||||
void CG_CalculateVRPositionInWorld( const vec3_t in_position, vec3_t in_offset, vec3_t in_orientation, vec3_t origin, vec3_t angles )
|
||||
{
|
||||
vec3_t offset;
|
||||
|
@ -2036,9 +2035,13 @@ CG_CalculateWeaponPositionAndScale
|
|||
*/
|
||||
|
||||
|
||||
static float CG_CalculateWeaponPositionAndScale( playerState_t *ps, vec3_t origin, vec3_t angles ) {
|
||||
static float CG_CalculateWeaponPositionAndScale( playerState_t *ps, vec3_t origin, vec3_t angles, qboolean akimbo ) {
|
||||
|
||||
CG_CalculateVRWeaponPosition(0, origin, angles);
|
||||
if (akimbo) {
|
||||
CG_CalculateVROffHandWeaponPosition(origin, angles);
|
||||
} else {
|
||||
CG_CalculateVRWeaponPosition(0, origin, angles);
|
||||
}
|
||||
|
||||
vec3_t offset;
|
||||
|
||||
|
@ -2080,7 +2083,11 @@ static float CG_CalculateWeaponPositionAndScale( playerState_t *ps, vec3_t origi
|
|||
else if (ps->weapon != 0)
|
||||
{
|
||||
char cvar_name[64];
|
||||
Com_sprintf(cvar_name, sizeof(cvar_name), "vr_weapon_adjustment_%i", ps->weapon);
|
||||
if (ps->weapon == WP_AKIMBO) {
|
||||
Com_sprintf(cvar_name, sizeof(cvar_name), "vr_weapon_adjustment_%i", WP_COLT);
|
||||
} else {
|
||||
Com_sprintf(cvar_name, sizeof(cvar_name), "vr_weapon_adjustment_%i", ps->weapon);
|
||||
}
|
||||
|
||||
char weapon_adjustment[256];
|
||||
trap_Cvar_VariableStringBuffer(cvar_name, weapon_adjustment, 256);
|
||||
|
@ -2096,7 +2103,7 @@ static float CG_CalculateWeaponPositionAndScale( playerState_t *ps, vec3_t origi
|
|||
&(adjust[PITCH]), &(adjust[YAW]), &(adjust[ROLL]));
|
||||
VectorScale(temp_offset, scale, offset);
|
||||
|
||||
if (!cgVR->right_handed)
|
||||
if (!cgVR->right_handed != akimbo)
|
||||
{
|
||||
//yaw needs to go in the other direction as left handed model is reversed
|
||||
adjust[YAW] *= -1.0f;
|
||||
|
@ -2120,7 +2127,7 @@ static float CG_CalculateWeaponPositionAndScale( playerState_t *ps, vec3_t origi
|
|||
AngleVectors( angles, forward, right, up );
|
||||
VectorMA( origin, offset[2], forward, origin );
|
||||
VectorMA( origin, offset[1], up, origin );
|
||||
if (cgVR->right_handed) {
|
||||
if (cgVR->right_handed != akimbo) {
|
||||
VectorMA(origin, offset[0], right, origin);
|
||||
} else {
|
||||
VectorMA(origin, -offset[0], right, origin);
|
||||
|
@ -2866,7 +2873,11 @@ static qboolean CG_CalcMuzzlePoint( int entityNum, int dist, vec3_t muzzle ) {
|
|||
cent = &cg_entities[entityNum];
|
||||
if ( entityNum == cg.snap->ps.clientNum ) {
|
||||
vec3_t angles;
|
||||
CG_CalculateVRWeaponPosition(cent->currentState.weapon, muzzle, angles);
|
||||
if (cent->currentState.weapon == WP_AKIMBO && BG_AkimboFireSequence(WP_AKIMBO, cg.snap->ps.ammoclip[WP_AKIMBO], cg.snap->ps.ammoclip[WP_COLT], cgVR->akimboTriggerState)) {
|
||||
CG_CalculateVROffHandWeaponPosition(muzzle, angles);
|
||||
} else {
|
||||
CG_CalculateVRWeaponPosition(cent->currentState.weapon, muzzle, angles);
|
||||
}
|
||||
|
||||
AngleVectors( angles, forward, NULL, NULL );
|
||||
VectorMA( muzzle, dist, forward, muzzle );
|
||||
|
@ -2908,7 +2919,7 @@ sound should only be done on the world model case.
|
|||
*/
|
||||
static qboolean debuggingweapon = qfalse;
|
||||
|
||||
void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent ) {
|
||||
void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent, qboolean akimbo ) {
|
||||
|
||||
refEntity_t gun;
|
||||
refEntity_t barrel;
|
||||
|
@ -2986,16 +2997,21 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
CG_RegisterWeapon( weaponNum );
|
||||
weapon = &cg_weapons[weaponNum];
|
||||
if (weaponNum == WP_AKIMBO) {
|
||||
CG_RegisterWeapon(WP_COLT);
|
||||
weapon = &cg_weapons[WP_COLT];
|
||||
} else {
|
||||
CG_RegisterWeapon( weaponNum );
|
||||
weapon = &cg_weapons[weaponNum];
|
||||
}
|
||||
}
|
||||
// dhm - end
|
||||
|
||||
|
||||
if ( isPlayer ) {
|
||||
akimboFire = BG_AkimboFireSequence( weaponNum, cg.predictedPlayerState.ammoclip[WP_AKIMBO], cg.predictedPlayerState.ammoclip[WP_COLT] );
|
||||
akimboFire = BG_AkimboFireSequence( weaponNum, cg.predictedPlayerState.ammoclip[WP_AKIMBO], cg.predictedPlayerState.ammoclip[WP_COLT], cgVR->akimboTriggerState );
|
||||
} else if ( ps ) {
|
||||
akimboFire = BG_AkimboFireSequence( weaponNum, ps->ammoclip[WP_AKIMBO], ps->ammoclip[WP_AKIMBO] );
|
||||
akimboFire = BG_AkimboFireSequence( weaponNum, ps->ammoclip[WP_AKIMBO], ps->ammoclip[WP_AKIMBO], 0 );
|
||||
}
|
||||
|
||||
// add the weapon
|
||||
|
@ -3111,20 +3127,19 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
|
|||
int brassOffset[WP_NUM_WEAPONS];
|
||||
memset (brassOffset, 0, sizeof brassOffset);
|
||||
brassOffset[WP_LUGER] = 1;
|
||||
brassOffset[WP_SILENCER] = 1;
|
||||
brassOffset[WP_COLT] = 1;
|
||||
brassOffset[WP_AKIMBO] = 1;
|
||||
brassOffset[WP_FG42] = 1;
|
||||
brassOffset[WP_MP40] = 2;
|
||||
brassOffset[WP_THOMPSON] = 2;
|
||||
brassOffset[WP_STEN] = 6;
|
||||
brassOffset[WP_VENOM] = 5;
|
||||
|
||||
// opposite tag in akimbo, since at this point the weapon
|
||||
// has fired and the fire seq has switched over
|
||||
if ( weaponNum == WP_AKIMBO && akimboFire ) {
|
||||
CG_PositionRotatedEntityOnTag( &brass, &gun, "tag_brass2" );
|
||||
} else if ( brassOffset[weaponNum] != 0) {
|
||||
//Correct bad tag on certain models
|
||||
CG_CalcMuzzlePoint(cent->currentState.clientNum, brassOffset[weaponNum], brass.origin);
|
||||
if ( brassOffset[weaponNum] != 0) {
|
||||
//Correct bad tag on certain models
|
||||
CG_CalcMuzzlePoint(cent->currentState.clientNum, brassOffset[weaponNum], brass.origin);
|
||||
MatrixMultiply( brass.axis, gun.axis, brass.axis );
|
||||
} else {
|
||||
CG_PositionRotatedEntityOnTag( &brass, &gun, "tag_brass" );
|
||||
}
|
||||
|
@ -3341,6 +3356,10 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
|
|||
return;
|
||||
}
|
||||
|
||||
if (isPlayer && akimbo != akimboFire) {
|
||||
return; // We are firing the other gun
|
||||
}
|
||||
|
||||
if ( weaponNum == WP_STEN ) { // sten has no muzzleflash
|
||||
flash.hModel = 0;
|
||||
}
|
||||
|
@ -3357,15 +3376,6 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
|
|||
}
|
||||
}
|
||||
|
||||
if ( isPlayer ) {
|
||||
if ( weaponNum == WP_AKIMBO ) {
|
||||
if ( !cent->akimboFire ) {
|
||||
CG_PositionRotatedEntityOnTag( &flash, &gun, "tag_flash2" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( flash.hModel ) {
|
||||
if ( weaponNum != WP_FLAMETHROWER && weaponNum != WP_TESLA ) { //Ridah, hide the flash also for now
|
||||
// RF, changed this so the muzzle flash stays onscreen for long enough to be seen
|
||||
|
@ -3481,7 +3491,7 @@ void CG_AddPlayerFoot( refEntity_t *parent, playerState_t *ps, centity_t *cent )
|
|||
|
||||
}
|
||||
|
||||
void CG_LaserSight(const playerState_t *ps) {
|
||||
void CG_LaserSight(const playerState_t *ps, qboolean akimbo) {
|
||||
|
||||
if (trap_Cvar_VariableIntegerValue("vr_lasersight") != 0 &&
|
||||
cgVR->backpackitemactive == 0 && !cgVR->binocularsActive &&
|
||||
|
@ -3513,7 +3523,11 @@ void CG_LaserSight(const playerState_t *ps) {
|
|||
vec3_t endForward;
|
||||
vec3_t angles;
|
||||
clientInfo_t ci;
|
||||
CG_CalculateVRWeaponPosition(0, origin, angles);
|
||||
if (akimbo) {
|
||||
CG_CalculateVROffHandWeaponPosition(origin, angles);
|
||||
} else {
|
||||
CG_CalculateVRWeaponPosition(0, origin, angles);
|
||||
}
|
||||
|
||||
vec3_t forward, right, up;
|
||||
AngleVectors(angles, forward, right, up);
|
||||
|
@ -3539,10 +3553,14 @@ Add the weapon, and flash for the player's view
|
|||
*/
|
||||
void CG_AddViewWeapon( playerState_t *ps ) {
|
||||
refEntity_t hand;
|
||||
refEntity_t handAkimbo;
|
||||
float fovOffset;
|
||||
vec3_t angles;
|
||||
vec3_t anglesAkimbo;
|
||||
vec3_t gunoff;
|
||||
vec3_t gunoffAkimbo;
|
||||
weaponInfo_t *weapon;
|
||||
weaponInfo_t *weaponAkimbo;
|
||||
|
||||
if ( ps->persistant[PERS_TEAM] == TEAM_SPECTATOR ) {
|
||||
return;
|
||||
|
@ -3613,53 +3631,98 @@ void CG_AddViewWeapon( playerState_t *ps ) {
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
CG_RegisterWeapon( ps->weapon );
|
||||
weapon = &cg_weapons[ ps->weapon ];
|
||||
if (ps->weapon == WP_AKIMBO) {
|
||||
CG_RegisterWeapon( WP_COLT );
|
||||
CG_RegisterWeapon( WP_AKIMBO );
|
||||
weapon = &cg_weapons[ WP_COLT ];
|
||||
weaponAkimbo = &cg_weapons[ WP_AKIMBO ];
|
||||
} else {
|
||||
CG_RegisterWeapon( ps->weapon );
|
||||
weapon = &cg_weapons[ ps->weapon ];
|
||||
}
|
||||
}
|
||||
// dhm - end
|
||||
|
||||
memset( &hand, 0, sizeof( hand ) );
|
||||
memset( &handAkimbo, 0, sizeof( handAkimbo ) );
|
||||
|
||||
// set up gun position
|
||||
float scale = CG_CalculateWeaponPositionAndScale( ps, hand.origin, angles );
|
||||
float scale = CG_CalculateWeaponPositionAndScale( ps, hand.origin, angles, qfalse );
|
||||
float scaleAkimbo = CG_CalculateWeaponPositionAndScale( ps, handAkimbo.origin, anglesAkimbo, qtrue );
|
||||
|
||||
gunoff[0] = cg_gun_x.value;
|
||||
gunoff[1] = cg_gun_y.value;
|
||||
gunoff[2] = cg_gun_z.value;
|
||||
gunoffAkimbo[0] = cg_gun_x.value;
|
||||
gunoffAkimbo[1] = cg_gun_y.value;
|
||||
gunoffAkimbo[2] = cg_gun_z.value;
|
||||
|
||||
//----(SA) removed
|
||||
|
||||
VectorMA( hand.origin, gunoff[0], cg.refdef.viewaxis[0], hand.origin );
|
||||
VectorMA( hand.origin, gunoff[1], cg.refdef.viewaxis[1], hand.origin );
|
||||
VectorMA( hand.origin, gunoff[2], cg.refdef.viewaxis[2], hand.origin );
|
||||
VectorMA( handAkimbo.origin, gunoffAkimbo[0], cg.refdef.viewaxis[0], handAkimbo.origin );
|
||||
VectorMA( handAkimbo.origin, gunoffAkimbo[1], cg.refdef.viewaxis[1], handAkimbo.origin );
|
||||
VectorMA( handAkimbo.origin, gunoffAkimbo[2], cg.refdef.viewaxis[2], handAkimbo.origin );
|
||||
|
||||
AnglesToAxis( angles, hand.axis );
|
||||
AnglesToAxis( anglesAkimbo, handAkimbo.axis );
|
||||
|
||||
if ( cg_gun_frame.integer) {
|
||||
hand.frame = hand.oldframe = cg_gun_frame.integer;
|
||||
hand.backlerp = 0;
|
||||
handAkimbo.frame = handAkimbo.oldframe = cg_gun_frame.integer;
|
||||
handAkimbo.backlerp = 0;
|
||||
} else { // get the animation state
|
||||
CG_WeaponAnimation( ps, weapon, &hand.oldframe, &hand.frame, &hand.backlerp ); //----(SA) changed
|
||||
if (ps->weapon == WP_AKIMBO) {
|
||||
int weapAnim = ( ps->weapAnim & ~ANIM_TOGGLEBIT );
|
||||
if (weapAnim == WEAP_ATTACK1 || weapAnim == WEAP_ATTACK2 || weapAnim == WEAP_ATTACK_LASTSHOT || weapAnim == WEAP_IDLE1 || weapAnim == WEAP_IDLE2) {
|
||||
// For akimbo attack animation, animate only firing weapon
|
||||
if (cgVR->akimboFire) {
|
||||
CG_WeaponAnimation( ps, weapon, &hand.oldframe, &hand.frame, &hand.backlerp );
|
||||
} else {
|
||||
CG_WeaponAnimation( ps, weaponAkimbo, &handAkimbo.oldframe, &handAkimbo.frame, &handAkimbo.backlerp );
|
||||
}
|
||||
} else if (weapAnim == WEAP_RELOAD1 || weapAnim == WEAP_RELOAD2 || weapAnim == WEAP_RELOAD3) {
|
||||
// For akimbo reload, do not animate weapon with full clip
|
||||
if (ps->ammoclip[WP_COLT] < 8) {
|
||||
CG_WeaponAnimation( ps, weapon, &hand.oldframe, &hand.frame, &hand.backlerp );
|
||||
}
|
||||
if (ps->ammoclip[WP_AKIMBO] < 8) {
|
||||
CG_WeaponAnimation( ps, weaponAkimbo, &handAkimbo.oldframe, &handAkimbo.frame, &handAkimbo.backlerp );
|
||||
}
|
||||
} else {
|
||||
CG_WeaponAnimation( ps, weapon, &hand.oldframe, &hand.frame, &hand.backlerp );
|
||||
CG_WeaponAnimation( ps, weaponAkimbo, &handAkimbo.oldframe, &handAkimbo.frame, &handAkimbo.backlerp );
|
||||
}
|
||||
} else {
|
||||
CG_WeaponAnimation( ps, weapon, &hand.oldframe, &hand.frame, &hand.backlerp ); //----(SA) changed
|
||||
}
|
||||
}
|
||||
|
||||
if (cgVR->backpackitemactive != 3 && !cgVR->binocularsActive)
|
||||
{
|
||||
hand.hModel = weapon->handsModel;
|
||||
handAkimbo.hModel = weaponAkimbo->handsModel;
|
||||
}
|
||||
|
||||
//Weapon offset debugging
|
||||
if (weaponDebugging)
|
||||
{
|
||||
hand.renderfx = RF_FIRST_PERSON | RF_MINLIGHT | RF_VIEWWEAPON; //No depth hack for weapon adjusting mode
|
||||
handAkimbo.renderfx = RF_FIRST_PERSON | RF_MINLIGHT | RF_VIEWWEAPON;
|
||||
}
|
||||
else
|
||||
{
|
||||
hand.renderfx = RF_DEPTHHACK | RF_FIRST_PERSON | RF_MINLIGHT | RF_VIEWWEAPON; //----(SA)
|
||||
handAkimbo.renderfx = RF_DEPTHHACK | RF_FIRST_PERSON | RF_MINLIGHT | RF_VIEWWEAPON;
|
||||
}
|
||||
|
||||
//scale the whole model (hand and weapon)
|
||||
for ( int i = 0; i < 3; i++ ) {
|
||||
VectorScale( hand.axis[i], (cgVR->right_handed || i != 1 || ps->weapon == WP_AKIMBO) ? scale : -scale, hand.axis[i] );
|
||||
VectorScale( hand.axis[i], (cgVR->right_handed || i != 1) ? scale : -scale, hand.axis[i] );
|
||||
VectorScale( handAkimbo.axis[i], (!cgVR->right_handed || i != 1) ? scaleAkimbo : -scaleAkimbo, handAkimbo.axis[i] );
|
||||
}
|
||||
|
||||
|
||||
|
@ -3701,7 +3764,10 @@ void CG_AddViewWeapon( playerState_t *ps ) {
|
|||
}
|
||||
|
||||
// add everything onto the hand
|
||||
CG_AddPlayerWeapon(&hand, ps, &cg.predictedPlayerEntity);
|
||||
CG_AddPlayerWeapon(&hand, ps, &cg.predictedPlayerEntity, qfalse);
|
||||
if (ps->weapon == WP_AKIMBO) {
|
||||
CG_AddPlayerWeapon(&handAkimbo, ps, &cg.predictedPlayerEntity, qtrue);
|
||||
}
|
||||
// Ridah
|
||||
} // end "if ( ps->weapon > WP_NONE)"
|
||||
|
||||
|
@ -3736,7 +3802,10 @@ void CG_AddViewWeapon( playerState_t *ps ) {
|
|||
CG_RailTrail2(&ci, origin, endUp);
|
||||
}
|
||||
|
||||
CG_LaserSight(ps);
|
||||
CG_LaserSight(ps, qfalse);
|
||||
if (ps->weapon == WP_AKIMBO) {
|
||||
CG_LaserSight(ps, qtrue);
|
||||
}
|
||||
|
||||
cg.predictedPlayerEntity.lastWeaponClientFrame = cg.clientFrame;
|
||||
}
|
||||
|
@ -3753,7 +3822,7 @@ void CG_AddViewHand( playerState_t *ps ) {
|
|||
VectorScale( handEnt.axis[i], (cgVR->right_handed || i != 1) ? 1.0f : -1.0f, handEnt.axis[i] );
|
||||
}
|
||||
|
||||
handEnt.renderfx = RF_DEPTHHACK; //| RF_VRVIEWMODEL;
|
||||
handEnt.renderfx = RF_DEPTHHACK | RF_FIRST_PERSON | RF_MINLIGHT | RF_VIEWWEAPON;
|
||||
handEnt.hModel = cgs.media.handModel;
|
||||
|
||||
trap_R_AddRefEntityToScene( &handEnt );
|
||||
|
@ -4562,6 +4631,8 @@ void CG_DrawWheelSelector( void )
|
|||
memset(&item, 0, sizeof(item));
|
||||
if (weaponNum == WP_LUGER && CG_WeaponAvailable(WP_SILENCER)) {
|
||||
item.itemId = WP_SILENCER;
|
||||
} else if (weaponNum == WP_COLT && CG_WeaponAvailable(WP_AKIMBO)) {
|
||||
item.itemId = WP_AKIMBO;
|
||||
} else {
|
||||
item.itemId = weaponNum;
|
||||
}
|
||||
|
@ -4909,6 +4980,7 @@ void CG_WheelSelectorSelect_f( void )
|
|||
if (cg.wheelSelectorType == WST_WEAPON) {
|
||||
|
||||
cgVR->binocularsActive = qfalse;
|
||||
cgVR->weaponid = cg.wheelSelectorSelection;
|
||||
if (cg.wheelSelectorSelection != cg.weaponSelect) {
|
||||
cg.weaponSelectTime = cg.time;
|
||||
cg.weaponSelect = cg.wheelSelectorSelection;
|
||||
|
@ -4922,16 +4994,19 @@ void CG_WheelSelectorSelect_f( void )
|
|||
}
|
||||
else if (cg.wheelSelectorSelection == WSI_GRENADE) {
|
||||
cgVR->binocularsActive = qfalse;
|
||||
cgVR->weaponid = WP_GRENADE_LAUNCHER;
|
||||
cg.weaponSelectTime = cg.time;
|
||||
cg.weaponSelect = WP_GRENADE_LAUNCHER;
|
||||
}
|
||||
else if (cg.wheelSelectorSelection == WSI_PINEAPPLE) {
|
||||
cgVR->binocularsActive = qfalse;
|
||||
cgVR->weaponid = WP_GRENADE_PINEAPPLE;
|
||||
cg.weaponSelectTime = cg.time;
|
||||
cg.weaponSelect = WP_GRENADE_PINEAPPLE;
|
||||
}
|
||||
else if (cg.wheelSelectorSelection == WSI_DYNAMITE) {
|
||||
cgVR->binocularsActive = qfalse;
|
||||
cgVR->weaponid = WP_DYNAMITE;
|
||||
cg.weaponSelectTime = cg.time;
|
||||
cg.weaponSelect = WP_DYNAMITE;
|
||||
}
|
||||
|
@ -5154,8 +5229,6 @@ void CG_FinishWeaponChange( int lastweap, int newweap ) {
|
|||
}
|
||||
}
|
||||
|
||||
cgVR->dualwield = (newweap == WP_AKIMBO);
|
||||
|
||||
cg.weaponSelect = newweap;
|
||||
cgVR->weaponid = newweap; //Store in case we use backpack
|
||||
}
|
||||
|
|
|
@ -55,6 +55,8 @@ extern vmCvar_t g_gametype;
|
|||
#define MAX_AMMO_FG42 MAX_AMMO_MAUSER
|
||||
#define MAX_AMMO_BAR 200
|
||||
|
||||
#define TRIGGER_SECONDARY 1
|
||||
#define TRIGGER_PRIMARY 2
|
||||
|
||||
// these defines are matched with the character torso animations
|
||||
#define DELAY_LOW 100 // machineguns, tesla, spear, flame
|
||||
|
@ -1073,9 +1075,9 @@ dual colts
|
|||
{
|
||||
"weapon_akimbo",
|
||||
"sound/misc/w_pkup.wav",
|
||||
{ "models/weapons2/colt2/colt2.md3",
|
||||
"models/weapons2/colt2/v_colt2.md3",
|
||||
"models/weapons2/colt2/pu_colt2.md3",
|
||||
{ "models/weapons2/colt/colt.md3",
|
||||
"models/weapons2/colt/v_colt.md3",
|
||||
"models/weapons2/colt/pu_colt.md3",
|
||||
0, 0 },
|
||||
|
||||
"icons/iconw_colt_1", // icon
|
||||
|
@ -3621,30 +3623,33 @@ BG_AkimboFireSequence
|
|||
==============
|
||||
*/
|
||||
//qboolean BG_AkimboFireSequence( playerState_t *ps ) {
|
||||
qboolean BG_AkimboFireSequence( int weapon, int akimboClip, int coltClip ) {
|
||||
qboolean BG_AkimboFireSequence( int weapon, int akimboClip, int coltClip, int triggerState ) {
|
||||
// NOTE: this doesn't work when clips are turned off (dmflags 64)
|
||||
|
||||
if ( weapon != WP_AKIMBO ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// If only one trigger is pushed, return weapon matching the trigger
|
||||
if ((triggerState & TRIGGER_SECONDARY) && !(triggerState & TRIGGER_PRIMARY)) {
|
||||
return qtrue; // Firing secondary weapon
|
||||
}
|
||||
if ((triggerState & TRIGGER_PRIMARY) && !(triggerState & TRIGGER_SECONDARY)) {
|
||||
return qfalse; // Firing primary weapon
|
||||
}
|
||||
|
||||
// If both triggers are pushed and one weapon is missing ammo, return the other
|
||||
if ( !akimboClip ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// no ammo in colt, must be akimbo turn
|
||||
if ( !coltClip ) {
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
// at this point, both have ammo
|
||||
|
||||
// now check 'cycle' // (removed old method 11/5/2001)
|
||||
if ( ( akimboClip + coltClip ) & 1 ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
// At this point, both have ammo and we are firing from both
|
||||
// Switch between primary and secondary after each fired shot
|
||||
return ( ( akimboClip + coltClip ) & 1 );
|
||||
}
|
||||
|
||||
//----(SA) end
|
||||
|
|
|
@ -50,6 +50,8 @@ extern vmCvar_t g_gametype;
|
|||
extern vr_client_info_t* gVR;
|
||||
#endif
|
||||
|
||||
#define TRIGGER_SECONDARY 1
|
||||
#define TRIGGER_PRIMARY 2
|
||||
|
||||
// JPW NERVE -- stuck this here so it can be seen client & server side
|
||||
float Com_GetFlamethrowerRange( void ) {
|
||||
|
@ -2373,14 +2375,14 @@ void PM_CheckForReload( int weapon ) {
|
|||
// clip is empty, but you have reserves. (auto reload)
|
||||
else if ( !( pm->ps->ammoclip[clipWeap] ) ) { // clip is empty...
|
||||
if ( pm->ps->ammo[ammoWeap] ) { // and you have reserves
|
||||
if ( weapon == WP_AKIMBO ) { // if colt's got ammo, don't force reload yet (you know you've got it 'out' since you've got the akimbo selected
|
||||
if ( !( pm->ps->ammoclip[WP_COLT] ) ) {
|
||||
if ( weapon == WP_AKIMBO ) { // reload only if both clips are empty
|
||||
if ( !( pm->ps->ammoclip[WP_COLT] ) && !( pm->ps->ammoclip[WP_COLT] ) ) {
|
||||
doReload = qtrue;
|
||||
}
|
||||
// likewise. however, you need to check if you've got the akimbo selected, since you could have the colt alone
|
||||
} else if ( weapon == WP_COLT ) { // weapon checking for reload is colt...
|
||||
if ( pm->ps->weapon == WP_AKIMBO ) { // you've got the akimbo selected...
|
||||
if ( !( pm->ps->ammoclip[WP_AKIMBO] ) ) { // and it's got no ammo either
|
||||
if ( pm->ps->weapon == WP_AKIMBO ) { // reload only if both clips are empty
|
||||
if ( !( pm->ps->ammoclip[WP_COLT] ) && !( pm->ps->ammoclip[WP_AKIMBO] ) ) {
|
||||
doReload = qtrue; // so reload
|
||||
}
|
||||
} else { // single colt selected
|
||||
|
@ -2471,7 +2473,14 @@ void PM_WeaponUseAmmo( int wp, int amount ) {
|
|||
} else {
|
||||
takeweapon = BG_FindClipForWeapon( wp );
|
||||
if ( wp == WP_AKIMBO ) {
|
||||
if ( !BG_AkimboFireSequence( wp, pm->ps->ammoclip[WP_AKIMBO], pm->ps->ammoclip[WP_COLT] ) ) {
|
||||
int triggerState = 0;
|
||||
#ifdef CGAMEDLL
|
||||
triggerState = cgVR->akimboTriggerState;
|
||||
#endif
|
||||
#ifdef GAMEDLL
|
||||
triggerState = gVR->akimboTriggerState;
|
||||
#endif
|
||||
if ( !BG_AkimboFireSequence( wp, pm->ps->ammoclip[WP_AKIMBO], pm->ps->ammoclip[WP_COLT], triggerState ) ) {
|
||||
takeweapon = WP_COLT;
|
||||
}
|
||||
}
|
||||
|
@ -2496,7 +2505,14 @@ int PM_WeaponAmmoAvailable( int wp ) {
|
|||
// return pm->ps->ammoclip[BG_FindClipForWeapon( wp )];
|
||||
takeweapon = BG_FindClipForWeapon( wp );
|
||||
if ( wp == WP_AKIMBO ) {
|
||||
if ( !BG_AkimboFireSequence( pm->ps->weapon, pm->ps->ammoclip[WP_AKIMBO], pm->ps->ammoclip[WP_COLT] ) ) {
|
||||
int triggerState = 0;
|
||||
#ifdef CGAMEDLL
|
||||
triggerState = cgVR->akimboTriggerState;
|
||||
#endif
|
||||
#ifdef GAMEDLL
|
||||
triggerState = gVR->akimboTriggerState;
|
||||
#endif
|
||||
if ( !BG_AkimboFireSequence( pm->ps->weapon, pm->ps->ammoclip[WP_AKIMBO], pm->ps->ammoclip[WP_COLT], triggerState ) ) {
|
||||
takeweapon = WP_COLT;
|
||||
}
|
||||
}
|
||||
|
@ -2786,7 +2802,14 @@ static void PM_Weapon( void ) {
|
|||
// RF, remoed this, was preventing lava from hurting player
|
||||
//pm->watertype = 0;
|
||||
|
||||
akimboFire = BG_AkimboFireSequence( pm->ps->weapon, pm->ps->ammoclip[WP_AKIMBO], pm->ps->ammoclip[WP_COLT] );
|
||||
int triggerState = 0;
|
||||
#ifdef CGAMEDLL
|
||||
triggerState = cgVR->akimboTriggerState;
|
||||
#endif
|
||||
#ifdef GAMEDLL
|
||||
triggerState = gVR->akimboTriggerState;
|
||||
#endif
|
||||
akimboFire = BG_AkimboFireSequence( pm->ps->weapon, pm->ps->ammoclip[WP_AKIMBO], pm->ps->ammoclip[WP_COLT], triggerState );
|
||||
|
||||
if ( 0 ) {
|
||||
switch ( pm->ps->weaponstate ) {
|
||||
|
@ -3061,6 +3084,12 @@ if ( pm->ps->weapon == WP_NONE ) { // this is possible since the player starts
|
|||
return;
|
||||
}
|
||||
|
||||
// In case of akimbo, fire only if player still holds at least one of triggers
|
||||
// (Sometimes with really quick tap +attack is spawned but trigger state is no longer
|
||||
// set when reaching here. Exiting solves problem of "random" weapon fire)
|
||||
if (pm->ps->weapon == WP_AKIMBO && !triggerState) {
|
||||
return;
|
||||
}
|
||||
|
||||
// JPW NERVE -- in multiplayer, don't allow panzerfaust or dynamite to fire if charge bar isn't full
|
||||
#ifdef GAMEDLL
|
||||
|
@ -3251,6 +3280,16 @@ if ( pm->ps->weapon ) {
|
|||
playswitchsound = qfalse;
|
||||
break;
|
||||
|
||||
case WP_AKIMBO:
|
||||
// do not reload but continue fire if there is ammo in other gun
|
||||
if (pm->ps->ammoclip[WP_AKIMBO] || pm->ps->ammoclip[WP_COLT]) {
|
||||
reloadingW = qfalse;
|
||||
playswitchsound = qfalse;
|
||||
// notify player that one gun is empty
|
||||
PM_AddEvent( EV_EMPTYCLIP );
|
||||
}
|
||||
break;
|
||||
|
||||
// some weapons not allowed to reload. must switch back to primary first
|
||||
case WP_SNOOPERSCOPE:
|
||||
case WP_SNIPERRIFLE:
|
||||
|
@ -3395,17 +3434,21 @@ case WP_COLT:
|
|||
|
||||
//----(SA) added
|
||||
case WP_AKIMBO:
|
||||
// if you're firing an akimbo colt, and your other gun is dry,
|
||||
// nextshot needs to take 2x time
|
||||
// if you're firing an akimbo colt, and you are firing only single gun,
|
||||
// or other gun is dry, nextshot needs to take 2x time
|
||||
|
||||
addTime = ammoTable[pm->ps->weapon].nextShotTime;
|
||||
|
||||
// (SA) (added check for last shot in both guns so there's no delay for the last shot)
|
||||
if ( !pm->ps->ammoclip[WP_AKIMBO] || !pm->ps->ammoclip[WP_COLT] ) {
|
||||
if ( ( !pm->ps->ammoclip[WP_AKIMBO] && !akimboFire ) || ( !pm->ps->ammoclip[WP_COLT] && akimboFire ) ) {
|
||||
addTime = 2 * ammoTable[pm->ps->weapon].nextShotTime;
|
||||
if (triggerState < 3) {
|
||||
// firing only single gun
|
||||
addTime = 2 * ammoTable[pm->ps->weapon].nextShotTime;
|
||||
} else {
|
||||
// (SA) (added check for last shot in both guns so there's no delay for the last shot)
|
||||
if ( !pm->ps->ammoclip[WP_AKIMBO] || !pm->ps->ammoclip[WP_COLT] ) {
|
||||
if ( ( !pm->ps->ammoclip[WP_AKIMBO] && !akimboFire ) || ( !pm->ps->ammoclip[WP_COLT] && akimboFire ) ) {
|
||||
addTime = 2 * ammoTable[pm->ps->weapon].nextShotTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aimSpreadScaleAdd = 20;
|
||||
break;
|
||||
|
|
|
@ -1312,7 +1312,7 @@ gitem_t *BG_FindItemForKey( wkey_t k, int *index );
|
|||
weapon_t BG_FindAmmoForWeapon( weapon_t weapon );
|
||||
weapon_t BG_FindClipForWeapon( weapon_t weapon );
|
||||
|
||||
qboolean BG_AkimboFireSequence( int weapon, int akimboClip, int coltClip );
|
||||
qboolean BG_AkimboFireSequence( int weapon, int akimboClip, int coltClip, int triggerState );
|
||||
//qboolean BG_AkimboFireSequence ( playerState_t *ps ); //----(SA) added
|
||||
|
||||
#define ITEM_INDEX( x ) ( ( x ) - bg_itemlist )
|
||||
|
|
|
@ -1092,7 +1092,7 @@ extern gitem_t * BG_FindItem2 ( const char * name ) ;
|
|||
extern gitem_t * BG_FindItem ( const char * pickupName ) ;
|
||||
extern gitem_t * BG_FindItemForAmmo ( int ammo ) ;
|
||||
extern gitem_t * BG_FindItemForKey ( wkey_t k , int * indexreturn ) ;
|
||||
extern qboolean BG_AkimboFireSequence ( int weapon , int akimboClip , int coltClip ) ;
|
||||
extern qboolean BG_AkimboFireSequence ( int weapon , int akimboClip , int coltClip, int triggerState ) ;
|
||||
extern weapon_t BG_FindAmmoForWeapon ( weapon_t weapon ) ;
|
||||
extern weapon_t BG_FindClipForWeapon ( weapon_t weapon ) ;
|
||||
extern gitem_t * BG_FindItemForWeapon ( weapon_t weapon ) ;
|
||||
|
|
|
@ -968,8 +968,8 @@ void Bullet_Fire( gentity_t *ent, float spread, int damage ) {
|
|||
sprintf(fire_command, "fire_%i", ent->s.weapon);
|
||||
if (ent->s.weapon == WP_AKIMBO)
|
||||
{
|
||||
right = BG_AkimboFireSequence(ent->s.weapon, ent->client->ps.ammoclip[WP_AKIMBO], ent->client->ps.ammoclip[WP_COLT] );
|
||||
trap_Vibrate(100, right ? 1 : 0, 1.0, fire_command, 0.0, 0.0);
|
||||
qboolean akimbo = BG_AkimboFireSequence(ent->s.weapon, ent->client->ps.ammoclip[WP_AKIMBO], ent->client->ps.ammoclip[WP_COLT], gVR->akimboTriggerState );
|
||||
trap_Vibrate(100, right != akimbo ? 1 : 0, 1.0, fire_command, 0.0, 0.0);
|
||||
} else{
|
||||
trap_Vibrate(100, right ? 1 : 0, 1.0, fire_command, 0.0, 0.0);
|
||||
if (gVR->weapon_stabilised) {
|
||||
|
@ -1746,7 +1746,11 @@ void CalcMuzzlePoint( gentity_t *ent, int weapon, vec3_t forward, vec3_t right,
|
|||
float worldscale = trap_Cvar_VariableIntegerValue("cg_worldScale");
|
||||
float heightAdjust = 0;
|
||||
trap_Cvar_VariableValue("cg_heightAdjust", &heightAdjust);
|
||||
convertFromVR(worldscale, ent, gVR->calculated_weaponoffset, ent->r.currentOrigin, muzzlePoint);
|
||||
if (weapon == WP_AKIMBO && BG_AkimboFireSequence(WP_AKIMBO, ent->client->ps.ammoclip[WP_AKIMBO], ent->client->ps.ammoclip[WP_COLT], gVR->akimboTriggerState)) {
|
||||
convertFromVR(worldscale, ent, gVR->offhandoffset, ent->r.currentOrigin, muzzlePoint);
|
||||
} else {
|
||||
convertFromVR(worldscale, ent, gVR->calculated_weaponoffset, ent->r.currentOrigin, muzzlePoint);
|
||||
}
|
||||
muzzlePoint[2] += (ent->client->ps.viewheight - 64);
|
||||
muzzlePoint[2] += (gVR->hmdposition[1] + heightAdjust) * worldscale;
|
||||
return;
|
||||
|
@ -1773,9 +1777,6 @@ void CalcMuzzlePoint( gentity_t *ent, int weapon, vec3_t forward, vec3_t right,
|
|||
case WP_GRENADE_LAUNCHER:
|
||||
VectorMA( muzzlePoint, 20, right, muzzlePoint );
|
||||
break;
|
||||
case WP_AKIMBO: // left side rather than right
|
||||
VectorMA( muzzlePoint, -6, right, muzzlePoint );
|
||||
VectorMA( muzzlePoint, -4, up, muzzlePoint );
|
||||
default:
|
||||
VectorMA( muzzlePoint, 6, right, muzzlePoint );
|
||||
VectorMA( muzzlePoint, -4, up, muzzlePoint );
|
||||
|
@ -1807,7 +1808,11 @@ void CalcMuzzlePointForActivate( gentity_t *ent, vec3_t forward, vec3_t right, v
|
|||
float worldscale = trap_Cvar_VariableIntegerValue("cg_worldScale");
|
||||
float heightAdjust = 0;
|
||||
trap_Cvar_VariableValue("cg_heightAdjust", &heightAdjust);
|
||||
convertFromVR(worldscale, ent, gVR->calculated_weaponoffset, ent->r.currentOrigin, muzzlePoint);
|
||||
if (ent->client->ps.weapon == WP_AKIMBO && BG_AkimboFireSequence(WP_AKIMBO, ent->client->ps.ammoclip[WP_AKIMBO], ent->client->ps.ammoclip[WP_COLT], gVR->akimboTriggerState)) {
|
||||
convertFromVR(worldscale, ent, gVR->offhandoffset, ent->r.currentOrigin, muzzlePoint);
|
||||
} else {
|
||||
convertFromVR(worldscale, ent, gVR->calculated_weaponoffset, ent->r.currentOrigin, muzzlePoint);
|
||||
}
|
||||
muzzlePoint[2] += (ent->client->ps.viewheight - 64);
|
||||
muzzlePoint[2] += (gVR->hmdposition[1] + heightAdjust) * worldscale;
|
||||
return;
|
||||
|
@ -1863,10 +1868,13 @@ void CalcMuzzlePoints( gentity_t *ent, int weapon ) {
|
|||
phase = level.time / 1000.0 * ZOOM_YAW_FREQUENCY * M_PI * 2;
|
||||
viewang[YAW] += ZOOM_YAW_AMPLITUDE * sin( phase ) * ( spreadfrac + ZOOM_YAW_MIN_AMPLITUDE );
|
||||
*/
|
||||
|
||||
|
||||
VectorCopy(gVR->weaponangles, viewang);
|
||||
viewang[YAW] = ent->client->ps.viewangles[YAW] + (gVR->weaponangles[YAW] - gVR->hmdorientation[YAW]);
|
||||
if (weapon == WP_AKIMBO && BG_AkimboFireSequence(WP_AKIMBO, ent->client->ps.ammoclip[WP_AKIMBO], ent->client->ps.ammoclip[WP_COLT], gVR->akimboTriggerState)) {
|
||||
VectorCopy(gVR->offhandweaponangles, viewang);
|
||||
viewang[YAW] = ent->client->ps.viewangles[YAW] + (gVR->offhandweaponangles[YAW] - gVR->hmdorientation[YAW]);
|
||||
} else {
|
||||
VectorCopy(gVR->weaponangles, viewang);
|
||||
viewang[YAW] = ent->client->ps.viewangles[YAW] + (gVR->weaponangles[YAW] - gVR->hmdorientation[YAW]);
|
||||
}
|
||||
|
||||
} else {
|
||||
VectorCopy( ent->client->ps.viewangles, viewang );
|
||||
|
@ -1931,7 +1939,8 @@ void FireWeapon( gentity_t *ent ) {
|
|||
case WP_SILENCER:
|
||||
case WP_COLT:
|
||||
case WP_AKIMBO:
|
||||
aimSpreadScale += 0.4f;
|
||||
// No need for penalty, dual wield penalizes enough :-)
|
||||
// aimSpreadScale += 0.4f;
|
||||
break;
|
||||
|
||||
case WP_PANZERFAUST:
|
||||
|
|
Loading…
Reference in a new issue