Item Selector

and a number of other changes:
- Scrolling text on main menu for patron credits
- Off-hand force powers using trigger
- vr_weapon_velocity_trigger - cvar controls speed for velocity triggered weapons
- walk direction is hmd based
This commit is contained in:
Simon 2022-10-12 18:00:26 +01:00
parent faacc3daf1
commit 0c9d6d3e86
21 changed files with 1027 additions and 559 deletions

View file

@ -1268,7 +1268,7 @@ void JKVR_Init()
vr_turn_mode = Cvar_Get( "vr_turn_mode", "0", CVAR_ARCHIVE); // 0 = snap, 1 = smooth
vr_turn_angle = Cvar_Get( "vr_turn_angle", "45", CVAR_ARCHIVE);
vr_positional_factor = Cvar_Get( "vr_positional_factor", "12", CVAR_ARCHIVE);
vr_walkdirection = Cvar_Get( "vr_walkdirection", "0", CVAR_ARCHIVE);
vr_walkdirection = Cvar_Get( "vr_walkdirection", "1", CVAR_ARCHIVE);
vr_movement_multiplier = Cvar_Get( "vr_movement_multiplier", "0.8", CVAR_ARCHIVE);
vr_weapon_pitchadjust = Cvar_Get( "vr_weapon_pitchadjust", "-20.0", CVAR_ARCHIVE);
vr_virtual_stock = Cvar_Get( "vr_virtual_stock", "0", CVAR_ARCHIVE);
@ -1279,6 +1279,7 @@ void JKVR_Init()
vr_immersive_cinematics = Cvar_Get("vr_immersive_cinematics", "0", CVAR_ARCHIVE);
vr_screen_dist = Cvar_Get( "vr_screen_dist", "2.5", CVAR_ARCHIVE);
vr_weapon_velocity_trigger = Cvar_Get( "vr_weapon_velocity_trigger", "1.6", CVAR_ARCHIVE);
}

View file

@ -37,6 +37,8 @@ typedef struct {
vec3_t weaponoffset_history[NUM_WEAPON_SAMPLES];
float weaponoffset_history_timestamp[NUM_WEAPON_SAMPLES];
bool item_selector;
bool pistol; // True if the weapon is a pistol
//Lots of scope weapon stuff
@ -49,7 +51,9 @@ typedef struct {
bool velocitytriggered;
float primaryswingvelocity;
bool primaryVelocityTriggeredAttack;
float secondaryswingvelocity;
bool secondaryVelocityTriggeredAttack;
vec3_t offhandangles;
vec3_t offhandangles_last; // Don't use this, it is just for calculating delta!

View file

@ -9,4 +9,5 @@ extern cvar_t *vr_virtual_stock;
extern cvar_t *vr_switch_sticks;
extern cvar_t *vr_immersive_cinematics;
extern cvar_t *vr_screen_dist;
extern cvar_t *vr_weapon_velocity_trigger;

View file

@ -29,6 +29,7 @@ cvar_t *vr_virtual_stock;
cvar_t *vr_switch_sticks;
cvar_t *vr_immersive_cinematics;
cvar_t *vr_screen_dist;
cvar_t *vr_weapon_velocity_trigger;
ovrInputStateTrackedRemote leftTrackedRemoteState_old;
ovrInputStateTrackedRemote leftTrackedRemoteState_new;

View file

@ -156,308 +156,48 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
bool offhandGripPushed = (pOffTrackedRemoteNew->Buttons & ovrButton_GripTrigger);
if ( (offhandGripPushed != (pOffTrackedRemoteOld->Buttons & ovrButton_GripTrigger)) &&
offhandGripPushed && (distance < STABILISATION_DISTANCE))
#ifndef DEBUG
//#ifndef DEBUG
{
stabilised = qtrue;
}
#else
//#else
// {
// Cvar_Set("vr_control_scheme", "99");
// }
//#endif
dominantGripPushed = (pDominantTrackedRemoteNew->Buttons &
ovrButton_GripTrigger) != 0;
bool dominantButton1Pushed = (pDominantTrackedRemoteNew->Buttons &
domButton1) != 0;
bool dominantButton2Pushed = (pDominantTrackedRemoteNew->Buttons &
domButton2) != 0;
//Do this early so we can suppress other button actions when item selector is up
{
Cvar_Set("vr_control_scheme", "99");
}
#endif
vr.weapon_stabilised = stabilised;
//Engage scope / virtual stock if conditions are right
bool scopeready = vr.weapon_stabilised && (distanceToHMD < SCOPE_ENGAGE_DISTANCE);
static bool lastScopeReady = qfalse;
if (scopeready != lastScopeReady) {
if (vr.scopedweapon && !vr.scopedetached) {
if (!vr.scopeengaged && scopeready) {
ALOGV("**WEAPON EVENT** trigger scope mode");
sendButtonActionSimple("weapalt");
if (dominantGripPushed) {
if (dominantGripPushTime == 0) {
dominantGripPushTime = GetTimeInMilliSeconds();
}
else if (vr.scopeengaged && !scopeready) {
ALOGV("**WEAPON EVENT** disable scope mode");
sendButtonActionSimple("weapalt");
vr.item_selector = true;
}
else
{
dominantGripPushTime = 0;
if (vr.item_selector)
{
sendButtonActionSimple("itemselectorselect");
vr.item_selector = false;
}
lastScopeReady = scopeready;
}
}
//ALOGV("**GB WEAPON ACTIVE** %i",vr.weaponid);
if(!scopeready && vr.weaponid >= 15 && vr.weaponid <= 17)
{
lastScopeReady = false;
ALOGV("**WEAPON EVENT** disable scope mode forced");
sendButtonActionSimple("weapalt");
}
//Engage scope / virtual stock (iron sight lock) if conditions are right
static bool scopeEngaged = qfalse;
if (scopeEngaged != vr.scopeengaged)
{
scopeEngaged = vr.scopeengaged;
}
//dominant hand stuff first
{
//Record recent weapon position for trajectory based stuff
for (int i = (NUM_WEAPON_SAMPLES-1); i != 0; --i)
{
VectorCopy(vr.weaponoffset_history[i-1], vr.weaponoffset_history[i]);
vr.weaponoffset_history_timestamp[i] = vr.weaponoffset_history_timestamp[i-1];
}
VectorCopy(vr.weaponoffset, vr.weaponoffset_history[0]);
vr.weaponoffset_history_timestamp[0] = vr.weaponoffset_timestamp;
vr.weaponposition[0] = pWeapon->HeadPose.Pose.Position.x;
vr.weaponposition[1] = pWeapon->HeadPose.Pose.Position.y;
vr.weaponposition[2] = pWeapon->HeadPose.Pose.Position.z;
///Weapon location relative to view
vr.weaponoffset[0] = pWeapon->HeadPose.Pose.Position.x - vr.hmdposition[0];
vr.weaponoffset[1] = pWeapon->HeadPose.Pose.Position.y - vr.hmdposition[1];
vr.weaponoffset[2] = pWeapon->HeadPose.Pose.Position.z - vr.hmdposition[2];
vr.weaponoffset_timestamp = Sys_Milliseconds( );
vr.primaryswingvelocity = sqrtf(powf(pWeapon->HeadPose.LinearVelocity.x, 2) +
powf(pWeapon->HeadPose.LinearVelocity.y, 2) +
powf(pWeapon->HeadPose.LinearVelocity.z, 2));
vr.secondaryswingvelocity = sqrtf(powf(pOff->HeadPose.LinearVelocity.x, 2) +
powf(pOff->HeadPose.LinearVelocity.y, 2) +
powf(pOff->HeadPose.LinearVelocity.z, 2));
//For melee right hand is alt attack and left hand is attack
static bool primaryVelocityTriggeredAttack = false;
static bool secondaryVelocityTriggeredAttack = false;
if (vr.weaponid == WP_MELEE) {
//Does weapon velocity trigger attack (melee) and is it fast enough
if (vr.velocitytriggered) {
static bool fired = qfalse;
primaryVelocityTriggeredAttack = (vr.primaryswingvelocity > WEAPON_VELOCITY_TRIGGER);
if (fired != primaryVelocityTriggeredAttack) {
ALOGV("**WEAPON EVENT** veocity triggered %s",
primaryVelocityTriggeredAttack ? "+altattack" : "-altattack");
//normal attack is a punch with the left hand
sendButtonAction("+altattack", primaryVelocityTriggeredAttack);
fired = primaryVelocityTriggeredAttack;
}
} else if (primaryVelocityTriggeredAttack) {
//send a stop attack as we have an unfinished velocity attack
primaryVelocityTriggeredAttack = qfalse;
ALOGV("**WEAPON EVENT** veocity triggered -altattack");
sendButtonAction("+altattack", primaryVelocityTriggeredAttack);
}
if (vr.velocitytriggered) {
static bool fired = qfalse;
secondaryVelocityTriggeredAttack = (vr.secondaryswingvelocity >
WEAPON_VELOCITY_TRIGGER);
if (fired != secondaryVelocityTriggeredAttack) {
ALOGV("**WEAPON EVENT** veocity triggered %s",
secondaryVelocityTriggeredAttack ? "+attack" : "-attack");
//normal attack is a punch with the left hand
sendButtonAction("+attack", secondaryVelocityTriggeredAttack);
fired = secondaryVelocityTriggeredAttack;
}
} else if (secondaryVelocityTriggeredAttack) {
//send a stop attack as we have an unfinished velocity attack
secondaryVelocityTriggeredAttack = qfalse;
ALOGV("**WEAPON EVENT** veocity triggered -attack");
sendButtonAction("+attack", secondaryVelocityTriggeredAttack);
}
}
else if (vr.weaponid == WP_SABER) {
//Does weapon velocity trigger attack
if (vr.velocitytriggered) {
static bool fired = qfalse;
primaryVelocityTriggeredAttack = (vr.primaryswingvelocity > WEAPON_VELOCITY_TRIGGER);
if (fired != primaryVelocityTriggeredAttack) {
ALOGV("**WEAPON EVENT** veocity triggered %s",
primaryVelocityTriggeredAttack ? "+attack" : "-attack");
//normal attack is a punch with the left hand
sendButtonAction("+attack", primaryVelocityTriggeredAttack);
fired = primaryVelocityTriggeredAttack;
}
} else if (primaryVelocityTriggeredAttack) {
//send a stop attack as we have an unfinished velocity attack
primaryVelocityTriggeredAttack = qfalse;
ALOGV("**WEAPON EVENT** veocity triggered -attack");
sendButtonAction("+attack", primaryVelocityTriggeredAttack);
}
}
if (vr.weapon_stabilised)
{
if (vr.scopeengaged || vr_virtual_stock->integer == 1)
{
//offset to the appropriate eye a little bit
vec2_t xy;
rotateAboutOrigin(Cvar_VariableValue("cg_stereoSeparation") / 2.0f, 0.0f, -vr.hmdorientation[YAW], xy);
float x = pOff->HeadPose.Pose.Position.x - (vr.hmdposition[0] + xy[0]);
float y = pOff->HeadPose.Pose.Position.y - (vr.hmdposition[1] - 0.1f); // Use a point lower
float z = pOff->HeadPose.Pose.Position.z - (vr.hmdposition[2] + xy[1]);
float zxDist = length(x, z);
if (zxDist != 0.0f && z != 0.0f) {
VectorSet(vr.weaponangles, -degrees(atanf(y / zxDist)),
-degrees(atan2f(x, -z)), 0);
}
}
else
{
float x = pOff->HeadPose.Pose.Position.x - pWeapon->HeadPose.Pose.Position.x;
float y = pOff->HeadPose.Pose.Position.y - pWeapon->HeadPose.Pose.Position.y;
float z = pOff->HeadPose.Pose.Position.z - pWeapon->HeadPose.Pose.Position.z;
float zxDist = length(x, z);
if (zxDist != 0.0f && z != 0.0f) {
VectorSet(vr.weaponangles, -degrees(atanf(y / zxDist)),
-degrees(atan2f(x, -z)), vr.weaponangles[ROLL] / 2.0f); //Dampen roll on stabilised weapon
}
}
}
// Calculate if player tries to reach backpack
bool handInBackpack = false;
bool bpDistToHMDOk = false, bpWeaponHeightOk = false, bpWeaponAngleOk = false, bpHmdToWeaponAngleOk = false;
vec3_t hmdForwardXY = {}, weaponForwardXY = {};
float weaponToDownAngle = 0, hmdToWeaponDotProduct = 0;
static vec3_t downVector = {0.0, 0.0, -1.0};
bool bpTrackOk = pOffTracking->Status & VRAPI_TRACKING_STATUS_POSITION_TRACKED; // 1) Position must be tracked
if (bpTrackOk && (bpDistToHMDOk = distanceToHMD >= 0.2 && distanceToHMD <= 0.35) // 2) Weapon-to-HMD distance must be within <0.2-0.35> range
&& (bpWeaponHeightOk = vr.weaponoffset[1] >= -0.10 && vr.weaponoffset[1] <= 0.10)) // 3) Weapon height in relation to HMD must be within <-0.10, 0.10> range
{
AngleVectors(vr.hmdorientation, hmdForwardXY, NULL, NULL);
AngleVectors(vr.weaponangles, weaponForwardXY, NULL, NULL);
float weaponToDownAngle = AngleBetweenVectors(downVector, weaponForwardXY);
// 4) Angle between weapon forward vector and a down vector must be within 80-140 degrees
if(bpWeaponAngleOk = weaponToDownAngle >= 80.0 && weaponToDownAngle <= 140.0)
{
hmdForwardXY[2] = 0;
VectorNormalize(hmdForwardXY);
weaponForwardXY[2] = 0;
VectorNormalize(weaponForwardXY);
hmdToWeaponDotProduct = DotProduct(hmdForwardXY, weaponForwardXY);
// 5) HMD and weapon forward on XY plane must go in opposite directions (i.e. dot product < 0)
handInBackpack = bpHmdToWeaponAngleOk = hmdToWeaponDotProduct < 0;
}
}
//off-hand stuff (done here as I reference it in the save state thing
{
vr.offhandposition[0] = pOff->HeadPose.Pose.Position.x;
vr.offhandposition[1] = pOff->HeadPose.Pose.Position.y;
vr.offhandposition[2] = pOff->HeadPose.Pose.Position.z;
vr.offhandoffset[0] = pOff->HeadPose.Pose.Position.x - vr.hmdposition[0];
vr.offhandoffset[1] = pOff->HeadPose.Pose.Position.y - vr.hmdposition[1];
vr.offhandoffset[2] = pOff->HeadPose.Pose.Position.z - vr.hmdposition[2];
vec3_t rotation = {0};
QuatToYawPitchRoll(pOff->HeadPose.Pose.Orientation, rotation, vr.offhandangles);
if (vr_walkdirection->value == 0) {
controllerYawHeading = vr.offhandangles[YAW] - vr.hmdorientation[YAW];
}
else
{
controllerYawHeading = 0.0f;
}
}
// Use off hand as well to trigger save condition
canUseQuickSave = false;
bool bpOffhandDistToHMDOk = false, bpOffhandHeightOk = false, bpOffhandAngleOk = false, bpHmdToOffhandAngleOk = false;
vec3_t offhandForwardXY = {};
float hmdToOffhandDotProduct = 0;
float offhandToDownAngle = 0;
if (bpTrackOk && (bpOffhandDistToHMDOk = distanceToHMDOff >= 0.2 && distanceToHMDOff <= 0.35) // 2) Off-to-HMD distance must be within <0.2-0.35> range
&& (bpOffhandHeightOk = vr.offhandoffset[1] >= -0.10 && vr.offhandoffset[1] <= 0.10)) // 3) Offhand height in relation to HMD must be within <-0.10, 0.10> range
{
//Need to do this again as might not have done it above and cant be bothered to refactor
AngleVectors(vr.hmdorientation, hmdForwardXY, NULL, NULL);
AngleVectors(vr.offhandangles, offhandForwardXY, NULL, NULL);
offhandToDownAngle = AngleBetweenVectors(downVector, offhandForwardXY);
// 4) Angle between weapon forward vector and a down vector must be within 80-140 degrees
if(bpOffhandAngleOk = offhandToDownAngle >= 80.0 && offhandToDownAngle <= 140.0)
{
hmdForwardXY[2] = 0;
VectorNormalize(hmdForwardXY);
offhandForwardXY[2] = 0;
VectorNormalize(offhandForwardXY);
hmdToOffhandDotProduct = DotProduct(hmdForwardXY, offhandForwardXY);
// 5) HMD and weapon forward on XY plane must go in opposite directions (i.e. dot product < 0)
canUseQuickSave = bpHmdToOffhandAngleOk = hmdToOffhandDotProduct < 0;
}
}
// Uncomment to debug offhand reaching
ALOGV("Quick Save> Dist: %f | OffHandToDownAngle: %f | HandOffs: %f %f %f\nHmdHandDot: %f | HmdFwdXY: %f %f | WpnFwdXY: %f %f\nTrackOk: %i, DistOk: %i, HeightOk: %i, HnadAngleOk: %i, HmdHandDotOk: %i",
distanceToHMDOff, offhandToDownAngle, vr.offhandoffset[0], vr.offhandoffset[1], vr.offhandoffset[2],
hmdToOffhandDotProduct, hmdForwardXY[0], hmdForwardXY[1], offhandForwardXY[0], offhandForwardXY[1],
bpTrackOk, bpOffhandDistToHMDOk, bpOffhandHeightOk, bpOffhandAngleOk, bpHmdToOffhandAngleOk);
// Check quicksave
if (canUseQuickSave) {
int channel = (vr_control_scheme->integer >= 10) ? 1 : 0;
JKVR_Vibrate(40, channel, 0.5); // vibrate to let user know they can switch
if (((pOffTrackedRemoteNew->Buttons & offButton1) !=
(pOffTrackedRemoteOld->Buttons & offButton1)) &&
(pOffTrackedRemoteNew->Buttons & offButton1)) {
sendButtonActionSimple("savegame quicksave");
}
if (((pOffTrackedRemoteNew->Buttons & offButton2) !=
(pOffTrackedRemoteOld->Buttons & offButton2)) &&
(pOffTrackedRemoteNew->Buttons & offButton2)) {
sendButtonActionSimple("loadgame quicksave");
}
}
dominantGripPushed = (pDominantTrackedRemoteNew->Buttons &
ovrButton_GripTrigger) != 0;
bool dominantButton1Pushed = (pDominantTrackedRemoteNew->Buttons &
domButton1) != 0;
bool dominantButton2Pushed = (pDominantTrackedRemoteNew->Buttons &
domButton2) != 0;
{
if (dominantGripPushed) {
if (dominantGripPushTime == 0) {
dominantGripPushTime = GetTimeInMilliSeconds();
}
Cvar_Set("timescale", "0.22");
}
else
{
dominantGripPushTime = 0;
Cvar_Set("timescale", "1.0");
}
}
}
#define JOYX_SAMPLE_COUNT 4
static float joyx[JOYX_SAMPLE_COUNT] = {0};
for (int j = JOYX_SAMPLE_COUNT-1; j > 0; --j)
joyx[j] = joyx[j-1];
for (int j = JOYX_SAMPLE_COUNT - 1; j > 0; --j)
joyx[j] = joyx[j - 1];
joyx[0] = pPrimaryJoystick->x;
float sum = 0.0f;
for (int j = 0; j < JOYX_SAMPLE_COUNT; ++j)
@ -465,201 +205,471 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
float primaryJoystickX = sum / 4.0f;
//Right-hand specific stuff
{
//This section corrects for the fact that the controller actually controls direction of movement, but we want to move relative to the direction the
//player is facing for positional tracking
//Positional movement speed correction for when we are not hitting target framerate
static double lastframetime = 0;
int refresh = GetRefresh();
double newframetime = GetTimeInMilliSeconds();
float multiplier = (float)((1000.0 / refresh) / (newframetime - lastframetime));
lastframetime = newframetime;
vec2_t v;
float factor = (refresh / 72.0F) * vr_positional_factor->value; // adjust positional factor based on refresh rate
rotateAboutOrigin(-vr.hmdposition_delta[0] * factor * multiplier,
vr.hmdposition_delta[2] * factor * multiplier, - vr.hmdorientation[YAW], v);
positional_movementSideways = v[0];
positional_movementForward = v[1];
ALOGV(" positional_movementSideways: %f, positional_movementForward: %f",
positional_movementSideways,
positional_movementForward);
//Jump (A Button)
if ((primaryButtonsNew & primaryButton1) != (primaryButtonsOld & primaryButton1))
{
sendButtonAction("+moveup", (primaryButtonsNew & primaryButton1));
}
//Alt Fire (B Button)
if ((primaryButtonsNew & primaryButton2) != (primaryButtonsOld & primaryButton2))
{
sendButtonAction("+altattack", (primaryButtonsNew & primaryButton2));
}
static bool firing = false;
{
//Fire Primary - Doesn't trigger the saber
if (!vr.velocitytriggered && // Don't fire velocity triggered weapons
(pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) !=
(pDominantTrackedRemoteOld->Buttons & ovrButton_Trigger)) {
ALOGV("**WEAPON EVENT** Not Grip Pushed %sattack", (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) ? "+" : "-");
firing = (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger);
sendButtonAction("+attack", firing);
//Left/right to switch between which selector we are using
if (vr.item_selector) {
static bool itemSwitched = false;
if (between(-0.2f, pPrimaryJoystick->y, 0.2f) &&
(between(0.8f, primaryJoystickX, 1.0f) ||
between(-1.0f, primaryJoystickX, -0.8f))) {
if (!itemSwitched) {
if (between(0.8f, primaryJoystickX, 1.0f)) {
sendButtonActionSimple("itemselectornext");
} else {
sendButtonActionSimple("itemselectorprev");
}
itemSwitched = true;
}
} else {
itemSwitched = false;
}
//Duck - off hand joystick
if ((secondaryButtonsNew & secondaryThumb) !=
(secondaryButtonsOld & secondaryThumb)) {
sendButtonAction("+movedown", (secondaryButtonsNew & secondaryThumb));
}
//Use
if ((pDominantTrackedRemoteNew->Buttons & primaryThumb) !=
(pDominantTrackedRemoteOld->Buttons & primaryThumb)) {
sendButtonAction("+use", (pDominantTrackedRemoteNew->Buttons & primaryThumb));
}
//Weapon Chooser
static bool itemSwitched = false;
if (between(-0.2f, primaryJoystickX, 0.2f) &&
(between(0.8f, pPrimaryJoystick->y, 1.0f) ||
between(-1.0f, pPrimaryJoystick->y, -0.8f)))
{
if (!itemSwitched) {
if (between(0.8f, pPrimaryJoystick->y, 1.0f))
{
sendButtonActionSimple("weapprev");
}
else
{
sendButtonActionSimple("weapnext");
}
itemSwitched = true;
}
} else {
itemSwitched = false;
}
}
vr.weapon_stabilised = stabilised;
//if (!vr.item_selector)
{
//Apply a filter and quadratic scaler so small movements are easier to make
float dist = length(pSecondaryJoystick->x, pSecondaryJoystick->y);
float nlf = nonLinearFilter(dist);
float x = (nlf * pSecondaryJoystick->x) + pFootTrackingNew->LeftJoystick.x;
float y = (nlf * pSecondaryJoystick->y) - pFootTrackingNew->LeftJoystick.y;
vr.player_moving = (fabs(x) + fabs(y)) > 0.05f;
//Adjust to be off-hand controller oriented
vec2_t v;
rotateAboutOrigin(x, y, controllerYawHeading, v);
//Move a lot slower if scope is engaged
remote_movementSideways = v[0] * (vr.scopeengaged ? 0.3f : 1.0f) * vr_movement_multiplier->value;
remote_movementForward = v[1] * (vr.scopeengaged ? 0.3f : 1.0f) * vr_movement_multiplier->value;
ALOGV(" remote_movementSideways: %f, remote_movementForward: %f",
remote_movementSideways,
remote_movementForward);
//Use Force (X button)
if (!canUseQuickSave) {
if ((secondaryButtonsNew & secondaryButton1) !=
(secondaryButtonsOld & secondaryButton1)) {
sendButtonAction("+useforce", (secondaryButtonsNew & secondaryButton1));
//Engage scope / virtual stock if conditions are right
bool scopeready = vr.weapon_stabilised && (distanceToHMD < SCOPE_ENGAGE_DISTANCE);
static bool lastScopeReady = qfalse;
if (scopeready != lastScopeReady) {
if (vr.scopedweapon && !vr.scopedetached) {
if (!vr.scopeengaged && scopeready) {
ALOGV("**WEAPON EVENT** trigger scope mode");
sendButtonActionSimple("weapalt");
} else if (vr.scopeengaged && !scopeready) {
ALOGV("**WEAPON EVENT** disable scope mode");
sendButtonActionSimple("weapalt");
}
lastScopeReady = scopeready;
}
}
//Open the datapad
if (!canUseQuickSave) {
if (((secondaryButtonsNew & secondaryButton2) !=
(secondaryButtonsOld & secondaryButton2)) &&
(secondaryButtonsNew & secondaryButton2)) {
Sys_QueEvent( 0, SE_KEY, A_TAB, true, 0, NULL );
//ALOGV("**GB WEAPON ACTIVE** %i",vr.weaponid);
if (!scopeready && vr.weaponid >= 15 && vr.weaponid <= 17) {
lastScopeReady = false;
ALOGV("**WEAPON EVENT** disable scope mode forced");
sendButtonActionSimple("weapalt");
}
//Engage scope / virtual stock (iron sight lock) if conditions are right
static bool scopeEngaged = qfalse;
if (scopeEngaged != vr.scopeengaged) {
scopeEngaged = vr.scopeengaged;
}
//dominant hand stuff first
{
//Record recent weapon position for trajectory based stuff
for (int i = (NUM_WEAPON_SAMPLES - 1); i != 0; --i) {
VectorCopy(vr.weaponoffset_history[i - 1], vr.weaponoffset_history[i]);
vr.weaponoffset_history_timestamp[i] = vr.weaponoffset_history_timestamp[i - 1];
}
}
VectorCopy(vr.weaponoffset, vr.weaponoffset_history[0]);
vr.weaponoffset_history_timestamp[0] = vr.weaponoffset_timestamp;
//We need to record if we have started firing primary so that releasing trigger will stop definitely firing, if user has pushed grip
//in meantime, then it wouldn't stop the gun firing and it would get stuck
{
//Run
handleTrackedControllerButton(pOffTrackedRemoteNew,
pOffTrackedRemoteOld,
ovrButton_Trigger, A_SHIFT);
}
VectorSet(vr.weaponposition, pWeapon->HeadPose.Pose.Position.x,
pWeapon->HeadPose.Pose.Position.y, pWeapon->HeadPose.Pose.Position.z);
//Resync Yaw on mounted gun transition
static int usingMountedGun = false;
if (vr.mountedgun != usingMountedGun)
{
usingMountedGun = vr.mountedgun;
}
///Weapon location relative to view
VectorSet(vr.weaponoffset, pWeapon->HeadPose.Pose.Position.x,
pWeapon->HeadPose.Pose.Position.y, pWeapon->HeadPose.Pose.Position.z);
VectorSubtract(vr.weaponoffset, vr.hmdposition, vr.weaponoffset);
vr.weaponoffset_timestamp = Sys_Milliseconds();
//No snap turn when using mounted gun
static int syncCount = 0;
static int increaseSnap = true;
if (!vr.mountedgun && !vr.scopeengaged) {
if (primaryJoystickX > 0.7f) {
if (increaseSnap) {
float turnAngle = vr_turn_mode->integer ? (vr_turn_angle->value / 9.0f) : vr_turn_angle->value;
vr.snapTurn -= turnAngle;
vec3_t velocity;
VectorSet(velocity, pWeapon->HeadPose.LinearVelocity.x,
pWeapon->HeadPose.LinearVelocity.y, pWeapon->HeadPose.LinearVelocity.z);
vr.primaryswingvelocity = VectorLength(velocity);
if (vr_turn_mode->integer == 0) {
increaseSnap = false;
VectorSet(velocity, pOff->HeadPose.LinearVelocity.x,
pOff->HeadPose.LinearVelocity.y, pOff->HeadPose.LinearVelocity.z);
vr.secondaryswingvelocity = VectorLength(velocity);
//For melee right hand is alt attack and left hand is attack
if (vr.weaponid == WP_MELEE) {
//Does weapon velocity trigger attack (melee) and is it fast enough
if (vr.velocitytriggered) {
static bool fired = false;
vr.primaryVelocityTriggeredAttack = (vr.primaryswingvelocity >
vr_weapon_velocity_trigger->value);
if (fired != vr.primaryVelocityTriggeredAttack) {
ALOGV("**WEAPON EVENT** veocity triggered %s",
vr.primaryVelocityTriggeredAttack ? "+altattack" : "-altattack");
//normal attack is a punch with the left hand
sendButtonAction("+altattack", vr.primaryVelocityTriggeredAttack);
fired = vr.primaryVelocityTriggeredAttack;
}
} else if (vr.primaryVelocityTriggeredAttack) {
//send a stop attack as we have an unfinished velocity attack
vr.primaryVelocityTriggeredAttack = false;
ALOGV("**WEAPON EVENT** veocity triggered -altattack");
sendButtonAction("+altattack", vr.primaryVelocityTriggeredAttack);
}
if (vr.snapTurn < -180.0f) {
vr.snapTurn += 360.f;
if (vr.velocitytriggered) {
static bool fired = false;
vr.secondaryVelocityTriggeredAttack = (vr.secondaryswingvelocity >
vr_weapon_velocity_trigger->value);
if (fired != vr.secondaryVelocityTriggeredAttack) {
ALOGV("**WEAPON EVENT** veocity triggered %s",
vr.secondaryVelocityTriggeredAttack ? "+attack" : "-attack");
//normal attack is a punch with the left hand
sendButtonAction("+attack", vr.secondaryVelocityTriggeredAttack);
fired = vr.secondaryVelocityTriggeredAttack;
}
} else if (vr.secondaryVelocityTriggeredAttack) {
//send a stop attack as we have an unfinished velocity attack
vr.secondaryVelocityTriggeredAttack = qfalse;
ALOGV("**WEAPON EVENT** veocity triggered -attack");
sendButtonAction("+attack", vr.secondaryVelocityTriggeredAttack);
}
} else if (vr.weaponid == WP_SABER) {
//Does weapon velocity trigger attack
if (vr.velocitytriggered) {
static bool fired = false;
vr.primaryVelocityTriggeredAttack = (vr.primaryswingvelocity >
vr_weapon_velocity_trigger->value);
if (fired != vr.primaryVelocityTriggeredAttack) {
ALOGV("**WEAPON EVENT** veocity triggered %s",
vr.primaryVelocityTriggeredAttack ? "+attack" : "-attack");
//normal attack is a punch with the left hand
sendButtonAction("+attack", vr.primaryVelocityTriggeredAttack);
fired = vr.primaryVelocityTriggeredAttack;
}
} else if (vr.primaryVelocityTriggeredAttack) {
//send a stop attack as we have an unfinished velocity attack
vr.primaryVelocityTriggeredAttack = false;
ALOGV("**WEAPON EVENT** veocity triggered -attack");
sendButtonAction("+attack", vr.primaryVelocityTriggeredAttack);
}
}
if (vr.weapon_stabilised) {
if (vr.scopeengaged || vr_virtual_stock->integer == 1) {
//offset to the appropriate eye a little bit
vec2_t xy;
rotateAboutOrigin(Cvar_VariableValue("cg_stereoSeparation") / 2.0f, 0.0f,
-vr.hmdorientation[YAW], xy);
float x = pOff->HeadPose.Pose.Position.x - (vr.hmdposition[0] + xy[0]);
float y = pOff->HeadPose.Pose.Position.y -
(vr.hmdposition[1] - 0.1f); // Use a point lower
float z = pOff->HeadPose.Pose.Position.z - (vr.hmdposition[2] + xy[1]);
float zxDist = length(x, z);
if (zxDist != 0.0f && z != 0.0f) {
VectorSet(vr.weaponangles, -degrees(atanf(y / zxDist)),
-degrees(atan2f(x, -z)), 0);
}
} else {
float x =
pOff->HeadPose.Pose.Position.x - pWeapon->HeadPose.Pose.Position.x;
float y =
pOff->HeadPose.Pose.Position.y - pWeapon->HeadPose.Pose.Position.y;
float z =
pOff->HeadPose.Pose.Position.z - pWeapon->HeadPose.Pose.Position.z;
float zxDist = length(x, z);
if (zxDist != 0.0f && z != 0.0f) {
VectorSet(vr.weaponangles, -degrees(atanf(y / zxDist)),
-degrees(atan2f(x, -z)), vr.weaponangles[ROLL] /
2.0f); //Dampen roll on stabilised weapon
}
}
} else if (primaryJoystickX < 0.3f) {
increaseSnap = true;
}
static int decreaseSnap = true;
if (primaryJoystickX < -0.7f) {
if (decreaseSnap) {
// Calculate if player tries to reach backpack
bool handInBackpack = false;
bool bpDistToHMDOk = false, bpWeaponHeightOk = false, bpWeaponAngleOk = false, bpHmdToWeaponAngleOk = false;
vec3_t hmdForwardXY = {}, weaponForwardXY = {};
float weaponToDownAngle = 0, hmdToWeaponDotProduct = 0;
static vec3_t downVector = {0.0, 0.0, -1.0};
float turnAngle = vr_turn_mode->integer ? (vr_turn_angle->value / 9.0f) : vr_turn_angle->value;
vr.snapTurn += turnAngle;
//If snap turn configured for less than 10 degrees
if (vr_turn_mode->integer == 0) {
decreaseSnap = false;
}
if (vr.snapTurn > 180.0f) {
vr.snapTurn -= 360.f;
}
}
} else if (primaryJoystickX > -0.3f) {
decreaseSnap = true;
}
}
else {
if (fabs(primaryJoystickX) > 0.5f) {
increaseSnap = false;
}
else
bool bpTrackOk = pOffTracking->Status &
VRAPI_TRACKING_STATUS_POSITION_TRACKED; // 1) Position must be tracked
if (bpTrackOk && (bpDistToHMDOk = distanceToHMD >= 0.2 && distanceToHMD <=
0.35) // 2) Weapon-to-HMD distance must be within <0.2-0.35> range
&& (bpWeaponHeightOk = vr.weaponoffset[1] >= -0.10 && vr.weaponoffset[1] <=
0.10)) // 3) Weapon height in relation to HMD must be within <-0.10, 0.10> range
{
increaseSnap = true;
AngleVectors(vr.hmdorientation, hmdForwardXY, NULL, NULL);
AngleVectors(vr.weaponangles, weaponForwardXY, NULL, NULL);
float weaponToDownAngle = AngleBetweenVectors(downVector, weaponForwardXY);
// 4) Angle between weapon forward vector and a down vector must be within 80-140 degrees
if (bpWeaponAngleOk = weaponToDownAngle >= 80.0 && weaponToDownAngle <= 140.0) {
hmdForwardXY[2] = 0;
VectorNormalize(hmdForwardXY);
weaponForwardXY[2] = 0;
VectorNormalize(weaponForwardXY);
hmdToWeaponDotProduct = DotProduct(hmdForwardXY, weaponForwardXY);
// 5) HMD and weapon forward on XY plane must go in opposite directions (i.e. dot product < 0)
handInBackpack = bpHmdToWeaponAngleOk = hmdToWeaponDotProduct < 0;
}
}
//off-hand stuff (done here as I reference it in the save state thing
{
vr.offhandposition[0] = pOff->HeadPose.Pose.Position.x;
vr.offhandposition[1] = pOff->HeadPose.Pose.Position.y;
vr.offhandposition[2] = pOff->HeadPose.Pose.Position.z;
vr.offhandoffset[0] = pOff->HeadPose.Pose.Position.x - vr.hmdposition[0];
vr.offhandoffset[1] = pOff->HeadPose.Pose.Position.y - vr.hmdposition[1];
vr.offhandoffset[2] = pOff->HeadPose.Pose.Position.z - vr.hmdposition[2];
vec3_t rotation = {0};
QuatToYawPitchRoll(pOff->HeadPose.Pose.Orientation, rotation, vr.offhandangles);
if (vr_walkdirection->value == 0) {
controllerYawHeading = vr.offhandangles[YAW] - vr.hmdorientation[YAW];
} else {
controllerYawHeading = 0.0f;
}
}
// Use off hand as well to trigger save condition
canUseQuickSave = false;
bool bpOffhandDistToHMDOk = false, bpOffhandHeightOk = false, bpOffhandAngleOk = false, bpHmdToOffhandAngleOk = false;
vec3_t offhandForwardXY = {};
float hmdToOffhandDotProduct = 0;
float offhandToDownAngle = 0;
if (bpTrackOk && (bpOffhandDistToHMDOk = distanceToHMDOff >= 0.2 &&
distanceToHMDOff <=
0.35) // 2) Off-to-HMD distance must be within <0.2-0.35> range
&& (bpOffhandHeightOk = vr.offhandoffset[1] >= -0.10 && vr.offhandoffset[1] <=
0.10)) // 3) Offhand height in relation to HMD must be within <-0.10, 0.10> range
{
//Need to do this again as might not have done it above and cant be bothered to refactor
AngleVectors(vr.hmdorientation, hmdForwardXY, NULL, NULL);
AngleVectors(vr.offhandangles, offhandForwardXY, NULL, NULL);
offhandToDownAngle = AngleBetweenVectors(downVector, offhandForwardXY);
// 4) Angle between weapon forward vector and a down vector must be within 80-140 degrees
if (bpOffhandAngleOk =
offhandToDownAngle >= 80.0 && offhandToDownAngle <= 140.0) {
hmdForwardXY[2] = 0;
VectorNormalize(hmdForwardXY);
offhandForwardXY[2] = 0;
VectorNormalize(offhandForwardXY);
hmdToOffhandDotProduct = DotProduct(hmdForwardXY, offhandForwardXY);
// 5) HMD and weapon forward on XY plane must go in opposite directions (i.e. dot product < 0)
canUseQuickSave = bpHmdToOffhandAngleOk = hmdToOffhandDotProduct < 0;
}
}
// Uncomment to debug offhand reaching
ALOGV("Quick Save> Dist: %f | OffHandToDownAngle: %f | HandOffs: %f %f %f\nHmdHandDot: %f | HmdFwdXY: %f %f | WpnFwdXY: %f %f\nTrackOk: %i, DistOk: %i, HeightOk: %i, HnadAngleOk: %i, HmdHandDotOk: %i",
distanceToHMDOff, offhandToDownAngle, vr.offhandoffset[0],
vr.offhandoffset[1], vr.offhandoffset[2],
hmdToOffhandDotProduct, hmdForwardXY[0], hmdForwardXY[1], offhandForwardXY[0],
offhandForwardXY[1],
bpTrackOk, bpOffhandDistToHMDOk, bpOffhandHeightOk, bpOffhandAngleOk,
bpHmdToOffhandAngleOk);
// Check quicksave
if (canUseQuickSave) {
int channel = (vr_control_scheme->integer >= 10) ? 1 : 0;
JKVR_Vibrate(40, channel, 0.5); // vibrate to let user know they can switch
if (((pOffTrackedRemoteNew->Buttons & offButton1) !=
(pOffTrackedRemoteOld->Buttons & offButton1)) &&
(pOffTrackedRemoteNew->Buttons & offButton1)) {
sendButtonActionSimple("savegame quicksave");
}
if (((pOffTrackedRemoteNew->Buttons & offButton2) !=
(pOffTrackedRemoteOld->Buttons & offButton2)) &&
(pOffTrackedRemoteNew->Buttons & offButton2)) {
sendButtonActionSimple("loadgame quicksave");
}
}
}
}
updateScopeAngles();
//Right-hand specific stuff
{
//This section corrects for the fact that the controller actually controls direction of movement, but we want to move relative to the direction the
//player is facing for positional tracking
//Positional movement speed correction for when we are not hitting target framerate
static double lastframetime = 0;
int refresh = GetRefresh();
double newframetime = GetTimeInMilliSeconds();
float multiplier = (float) ((1000.0 / refresh) / (newframetime - lastframetime));
lastframetime = newframetime;
vec2_t v;
float factor = (refresh / 72.0F) *
vr_positional_factor->value; // adjust positional factor based on refresh rate
rotateAboutOrigin(-vr.hmdposition_delta[0] * factor * multiplier,
vr.hmdposition_delta[2] * factor * multiplier,
-vr.hmdorientation[YAW], v);
positional_movementSideways = v[0];
positional_movementForward = v[1];
ALOGV(" positional_movementSideways: %f, positional_movementForward: %f",
positional_movementSideways,
positional_movementForward);
//Jump (A Button)
if ((primaryButtonsNew & primaryButton1) != (primaryButtonsOld & primaryButton1)) {
sendButtonAction("+moveup", (primaryButtonsNew & primaryButton1));
}
//Alt Fire (B Button)
if ((primaryButtonsNew & primaryButton2) != (primaryButtonsOld & primaryButton2)) {
sendButtonAction("+altattack", (primaryButtonsNew & primaryButton2));
}
static bool firing = false;
{
//Fire Primary - Doesn't trigger the saber
if (!vr.velocitytriggered && // Don't fire velocity triggered weapons
(pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) !=
(pDominantTrackedRemoteOld->Buttons & ovrButton_Trigger)) {
ALOGV("**WEAPON EVENT** Not Grip Pushed %sattack",
(pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) ? "+" : "-");
firing = (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger);
sendButtonAction("+attack", firing);
}
}
//Duck - off hand joystick
if ((secondaryButtonsNew & secondaryThumb) !=
(secondaryButtonsOld & secondaryThumb)) {
sendButtonAction("+movedown", (secondaryButtonsNew & secondaryThumb));
}
//Use
if ((pDominantTrackedRemoteNew->Buttons & primaryThumb) !=
(pDominantTrackedRemoteOld->Buttons & primaryThumb)) {
sendButtonAction("+use", (pDominantTrackedRemoteNew->Buttons & primaryThumb));
}
}
{
//Apply a filter and quadratic scaler so small movements are easier to make
float dist = length(pSecondaryJoystick->x, pSecondaryJoystick->y);
float nlf = nonLinearFilter(dist);
float x = (nlf * pSecondaryJoystick->x) + pFootTrackingNew->LeftJoystick.x;
float y = (nlf * pSecondaryJoystick->y) - pFootTrackingNew->LeftJoystick.y;
vr.player_moving = (fabs(x) + fabs(y)) > 0.05f;
//Adjust to be off-hand controller oriented
vec2_t v;
rotateAboutOrigin(x, y, controllerYawHeading, v);
//Move a lot slower if scope is engaged
remote_movementSideways =
v[0] * (vr.scopeengaged ? 0.3f : 1.0f) * vr_movement_multiplier->value;
remote_movementForward =
v[1] * (vr.scopeengaged ? 0.3f : 1.0f) * vr_movement_multiplier->value;
ALOGV(" remote_movementSideways: %f, remote_movementForward: %f",
remote_movementSideways,
remote_movementForward);
if (!canUseQuickSave) {
if ((secondaryButtonsNew & secondaryButton1) !=
(secondaryButtonsOld & secondaryButton1)) {
//Toggle walk/run somehow?!
}
}
//Open the datapad
if (!canUseQuickSave) {
if (((secondaryButtonsNew & secondaryButton2) !=
(secondaryButtonsOld & secondaryButton2)) &&
(secondaryButtonsNew & secondaryButton2)) {
Sys_QueEvent(0, SE_KEY, A_TAB, true, 0, NULL);
}
}
//Use Force - off hand trigger
{
if ((pOffTrackedRemoteNew->Buttons & ovrButton_Trigger) !=
(pOffTrackedRemoteOld->Buttons & ovrButton_Trigger)) {
sendButtonAction("+useforce", (pOffTrackedRemoteNew->Buttons & ovrButton_Trigger));
}
}
//Resync Yaw on mounted gun transition
static int usingMountedGun = false;
if (vr.mountedgun != usingMountedGun) {
usingMountedGun = vr.mountedgun;
}
//No snap turn when using mounted gun
static int syncCount = 0;
static int increaseSnap = true;
if (!vr.item_selector && !vr.mountedgun && !vr.scopeengaged) {
if (primaryJoystickX > 0.7f) {
if (increaseSnap) {
float turnAngle = vr_turn_mode->integer ? (vr_turn_angle->value / 9.0f)
: vr_turn_angle->value;
vr.snapTurn -= turnAngle;
if (vr_turn_mode->integer == 0) {
increaseSnap = false;
}
if (vr.snapTurn < -180.0f) {
vr.snapTurn += 360.f;
}
}
} else if (primaryJoystickX < 0.3f) {
increaseSnap = true;
}
static int decreaseSnap = true;
if (primaryJoystickX < -0.7f) {
if (decreaseSnap) {
float turnAngle = vr_turn_mode->integer ? (vr_turn_angle->value / 9.0f)
: vr_turn_angle->value;
vr.snapTurn += turnAngle;
//If snap turn configured for less than 10 degrees
if (vr_turn_mode->integer == 0) {
decreaseSnap = false;
}
if (vr.snapTurn > 180.0f) {
vr.snapTurn -= 360.f;
}
}
} else if (primaryJoystickX > -0.3f) {
decreaseSnap = true;
}
} else {
if (fabs(primaryJoystickX) > 0.5f) {
increaseSnap = false;
} else {
increaseSnap = true;
}
}
}
updateScopeAngles();
}
}
//Save state

View file

@ -2018,6 +2018,76 @@ void CL_PlayInGameCinematic_f(void)
}
// Text crawl defines
#define TC_PLANE_WIDTH 250
#define TC_PLANE_NEAR 90
#define TC_PLANE_FAR 715
#define TC_PLANE_TOP 0
#define TC_PLANE_BOTTOM 1100
#define TC_DELAY 9000
#define TC_STOPTIME 81000
void SCR_AddCreditTextCrawl()
{
static int startTime = cls.realtime;
refdef_t refdef;
polyVert_t verts[4];
// Set up refdef
memset( &refdef, 0, sizeof( refdef ));
refdef.rdflags = RDF_NOWORLDMODEL;
AxisClear( refdef.viewaxis );
refdef.fov_x = 150;
refdef.fov_y = 150;
refdef.x = 0;
refdef.y = -50;
refdef.width = cls.glconfig.vidWidth;
refdef.height = cls.glconfig.vidHeight * 2; // deliberately extend off the bottom of the screen
// use to set shaderTime for scrolling shaders
refdef.time = 0;
// Set up the poly verts
float fadeDown = 1.0;
for ( int i = 0; i < 4; i++ )
{
verts[i].modulate[0] = 255*fadeDown; // gold color?
verts[i].modulate[1] = 235*fadeDown;
verts[i].modulate[2] = 127*fadeDown;
verts[i].modulate[3] = 255*fadeDown;
}
VectorScaleM( verts[2].modulate, 0.1f, verts[2].modulate ); // darken at the top??
VectorScaleM( verts[3].modulate, 0.1f, verts[3].modulate );
float timeoffset = (cls.realtime-startTime)*0.000015f -1;
VectorSet( verts[0].xyz, TC_PLANE_NEAR, -TC_PLANE_WIDTH, TC_PLANE_TOP );
verts[0].st[0] = 1;
verts[0].st[1] = 1 +timeoffset;
VectorSet( verts[1].xyz, TC_PLANE_NEAR, TC_PLANE_WIDTH, TC_PLANE_TOP );
verts[1].st[0] = 0;
verts[1].st[1] = 1 +timeoffset;
VectorSet( verts[2].xyz, TC_PLANE_FAR, TC_PLANE_WIDTH, TC_PLANE_BOTTOM );
verts[2].st[0] = 0;
verts[2].st[1] = 0 +timeoffset;
VectorSet( verts[3].xyz, TC_PLANE_FAR, -TC_PLANE_WIDTH, TC_PLANE_BOTTOM );
verts[3].st[0] = 1;
verts[3].st[1] = 0 +timeoffset;
// render it out
re.ClearScene();
re.AddPolyToScene( re.RegisterShaderNoMip( "menu/video/tc_demo" ), 4, verts );
re.RenderScene( &refdef );
}
// Externally-called only, and only if cls.state == CA_CINEMATIC (or CL_IsRunningInGameCinematic() == true now)
//
void SCR_DrawCinematic (void)

View file

@ -404,6 +404,7 @@ void SCR_Init( void ) {
void UI_SetActiveMenu( const char* menuname,const char *menuID );
void _UI_Refresh( int realtime );
void UI_DrawConnect( const char *servername, const char * updateInfoString );
void SCR_AddCreditTextCrawl( void );
/*
==================
@ -412,6 +413,7 @@ SCR_DrawScreenField
This will be called twice if rendering in stereo mode
==================
*/
void SCR_DrawScreenField( stereoFrame_t stereoFrame ) {
re.BeginFrame( stereoFrame );
@ -455,7 +457,6 @@ void SCR_DrawScreenField( stereoFrame_t stereoFrame ) {
break;
}
}
re.ProcessDissolve();
// draw downloading progress bar
@ -470,6 +471,11 @@ void SCR_DrawScreenField( stereoFrame_t stereoFrame ) {
if ( cl_debuggraph->integer || cl_timegraph->integer ) {
SCR_DrawDebugGraph ();
}
if ( uiFullscreen )
{
SCR_AddCreditTextCrawl();
}
}
/*

View file

@ -83,6 +83,7 @@ void BG_CalculateVRWeaponPosition( vec3_t origin, vec3_t angles );
void BG_CalculateVRSaberPosition( vec3_t origin, vec3_t angles );
void BG_CalculateVROffHandPosition( vec3_t origin, vec3_t angles );
void BG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out);
void BG_CalculateVRPositionInWorld( vec3_t in_position, vec3_t in_offset, vec3_t in_orientation, vec3_t origin, vec3_t angles );
#endif

View file

@ -733,7 +733,7 @@ void BG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out)
}
}
static void BG_CalculateVRPositionInWorld( vec3_t in_position, vec3_t in_offset, vec3_t in_orientation, vec3_t origin, vec3_t angles )
void BG_CalculateVRPositionInWorld( vec3_t in_position, vec3_t in_offset, vec3_t in_orientation, vec3_t origin, vec3_t angles )
{
vec3_t offset;
VectorCopy(in_offset, offset);

View file

@ -31,9 +31,6 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "../qcommon/q_shared.h"
//How fast the saber/melee needs to be physically swung in order to trigger sounds and trails etc
#define WEAPON_VELOCITY_TRIGGER 1.6f
typedef enum //# weapon_e
{
WP_NONE,

View file

@ -202,6 +202,10 @@ int cmdcmp( const void *a, const void *b ) {
return Q_stricmp( (const char *)a, ((consoleCommand_t*)b)->cmd );
}
void CG_ItemSelectorSelect_f( void );
void CG_ItemSelectorNext_f( void );
void CG_ItemSelectorPrev_f( void );
/* This array MUST be sorted correctly by alphabetical name field */
static consoleCommand_t commands[] = {
{ "cam_disable", CMD_CGCam_Disable }, //gets out of camera mode for debuggin
@ -239,6 +243,9 @@ static consoleCommand_t commands[] = {
{ "weapprev", CG_PrevWeapon_f },
{ "writecam", CG_WriteCam_f },
{ "zoom", CG_ToggleBinoculars },
{ "itemselectorselect", CG_ItemSelectorSelect_f },
{ "itemselectornext", CG_ItemSelectorNext_f },
{ "itemselectorprev", CG_ItemSelectorPrev_f },
};
static const size_t numCommands = ARRAY_LEN( commands );

View file

@ -2582,7 +2582,9 @@ void CG_DrawActive( stereoFrame_t stereoView ) {
return;
}
CG_DrawCrosshair3D();
if (!vr->item_selector) {
CG_DrawCrosshair3D();
}
//FIXME: these globals done once at start of frame for various funcs
AngleVectors (cg.refdefViewAngles, vfwd, vright, vup);

View file

@ -444,6 +444,13 @@ typedef struct {
int weaponAnimation;
int weaponAnimationTime;
int itemSelectorType; // 0 - weapons, 1 - force powers, 2 - gadgets
int itemSelectorSelection;
int itemSelectorTime;
vec3_t itemSelectorAngles;
vec3_t itemSelectorOrigin;
vec3_t itemSelectorOffset;
int inventorySelect; // Current inventory item chosen
int inventorySelectTime;
@ -845,6 +852,8 @@ void CG_FireWeapon( centity_t *cent, qboolean alt_fire );
void CG_AddViewWeapon (playerState_t *ps);
void CG_DrawWeaponSelect( void );
void CG_DrawItemSelector( void );
void CG_OutOfAmmoChange( void ); // should this be in pmove?
void CG_Chunks( int owner, vec3_t origin, const vec3_t normal, const vec3_t min, const vec3_t maxs,
float speed, int numChunks, material_t chunkType, int customChunk, float baseScale );

View file

@ -2535,7 +2535,7 @@ INVENTORY SELECTION
CG_InventorySelectable
===============
*/
static qboolean CG_InventorySelectable( int index)
qboolean CG_InventorySelectable( int index)
{
if (cg.snap->ps.inventory[index]) // Is there any in the inventory?
{
@ -3524,7 +3524,9 @@ void CG_DrawForceSelect( void )
{
int w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 1.0f);
int x = ( SCREEN_WIDTH - w ) / 2;
cgi_R_Font_DrawString(x, (SCREEN_HEIGHT / 2 + 50), text, colorTable[CT_ICON_BLUE], cgs.media.qhFontSmall, -1, 1.0f);
int y = (SCREEN_HEIGHT / 2 + 50);
CG_AdjustFrom640Int(&x, &y, NULL, NULL);
cgi_R_Font_DrawString(x, y, text, colorTable[CT_ICON_BLUE], cgs.media.qhFontSmall, -1, 1.0f);
}
}

View file

@ -3443,7 +3443,7 @@ void CG_AddRefEntityWithPowerups( refEntity_t *ent, int powerups, centity_t *cen
cgi_R_AddRefEntityToScene(ent);
}
if (player1stPersonSaber && !cent->currentState.saberInFlight)
if (player1stPersonSaber && !cent->currentState.saberInFlight && !vr->item_selector)
{
memset( &hiltEnt, 0, sizeof(refEntity_t) );
hiltEnt.renderfx = RF_DEPTHHACK;
@ -3459,14 +3459,11 @@ void CG_AddRefEntityWithPowerups( refEntity_t *ent, int powerups, centity_t *cen
cgi_R_AddRefEntityToScene(&hiltEnt);
static int playingSaberSwingSound = 0;
if (vr->primaryswingvelocity > WEAPON_VELOCITY_TRIGGER && ((cg.time - playingSaberSwingSound) > 800))
if (vr->primaryVelocityTriggeredAttack && ((cg.time - playingSaberSwingSound) > 800))
{
cgi_S_StartSound ( hiltEnt.origin, cent->gent->s.number, CHAN_AUTO, cgi_S_RegisterSound( va( "sound/weapons/saber/saberhup%d.wav", Q_irand( 1, 9 ) ) ) );
playingSaberSwingSound = cg.time;
}
//Try setting ent to be the hilt entity, then any subsequent effects below are applied to that instead
ent = &hiltEnt;
}
// Disruptor Gun Alt-fire
@ -4457,6 +4454,11 @@ void CG_AddSaberBlade( centity_t *cent, centity_t *scent, refEntity_t *saber, in
return;
}
if (vr->item_selector)
{
return;
}
/*
Ghoul2 Insert Start
*/
@ -5549,60 +5551,70 @@ extern vmCvar_t cg_thirdPersonAlpha;
}
}
}
}
//play special force effects
if ( cent->gent->NPC && ( cent->gent->NPC->confusionTime > cg.time || cent->gent->NPC->charmedTime > cg.time || cent->gent->NPC->controlledTime > cg.time) )
{// we are currently confused, so play an effect at the headBolt position
theFxScheduler.PlayEffect( cgs.effects.forceConfusion, cent->gent->client->renderInfo.eyePoint );
//play special force effects
if ( cent->gent->NPC && ( cent->gent->NPC->confusionTime > cg.time || cent->gent->NPC->charmedTime > cg.time || cent->gent->NPC->controlledTime > cg.time) )
{// we are currently confused, so play an effect at the headBolt position
theFxScheduler.PlayEffect( cgs.effects.forceConfusion, cent->gent->client->renderInfo.eyePoint );
}
if ( cent->gent->client && cent->gent->forcePushTime > cg.time )
{//being pushed
CG_ForcePushBodyBlur( cent, ent.origin, tempAngles );
}
if ( cent->gent->client->ps.powerups[PW_FORCE_PUSH] > cg.time || (cent->gent->client->ps.forcePowersActive & (1<<FP_GRIP)) )
{//doing the pushing/gripping
CG_ForcePushBlur( cent->gent->client->renderInfo.handLPoint );
}
if ( cent->gent->client->ps.eFlags & EF_FORCE_GRIPPED )
{//being gripped
CG_ForcePushBlur( cent->gent->client->renderInfo.headPoint );
}
if ( cent->gent->client && cent->gent->client->ps.powerups[PW_SHOCKED] > cg.time )
{//being electrocuted
CG_ForceElectrocution( cent, ent.origin, tempAngles );
}
if ( cent->gent->client->ps.forcePowersActive&(1<<FP_LIGHTNING) )
{//doing the electrocuting
vec3_t tAng, fxDir;
if (cent->gent->client->ps.clientNum == 0)
{
vec3_t origin, angles;
BG_CalculateVROffHandPosition(origin, tAng);
}
if ( cent->gent->client && cent->gent->forcePushTime > cg.time )
{//being pushed
CG_ForcePushBodyBlur( cent, ent.origin, tempAngles );
}
if ( cent->gent->client->ps.powerups[PW_FORCE_PUSH] > cg.time || (cent->gent->client->ps.forcePowersActive & (1<<FP_GRIP)) )
{//doing the pushing/gripping
CG_ForcePushBlur( cent->gent->client->renderInfo.handLPoint );
}
if ( cent->gent->client->ps.eFlags & EF_FORCE_GRIPPED )
{//being gripped
CG_ForcePushBlur( cent->gent->client->renderInfo.headPoint );
}
if ( cent->gent->client && cent->gent->client->ps.powerups[PW_SHOCKED] > cg.time )
{//being electrocuted
CG_ForceElectrocution( cent, ent.origin, tempAngles );
}
if ( cent->gent->client->ps.forcePowersActive&(1<<FP_LIGHTNING) )
{//doing the electrocuting
vec3_t tAng, fxDir;
else
{
VectorCopy( cent->lerpAngles, tAng );
/*
if ( cent->currentState.number )
{
VectorSet( tAng, cent->pe.torso.pitchAngle, cent->pe.torso.yawAngle, 0 );
}
else
{//FIXME: this dir looks right on players, but not on NPCs, NPCs pe angles are absolute, not relative?
VectorSet( tAng, tempAngles[0]+cent->pe.torso.pitchAngle, tempAngles[1]+cent->pe.torso.yawAngle, 0 );
}
*/
if ( cent->gent->client->ps.forcePowerLevel[FP_LIGHTNING] > FORCE_LEVEL_2 )
{//arc
vec3_t fxAxis[3];
AnglesToAxis( tAng, fxAxis );
theFxScheduler.PlayEffect( cgs.effects.forceLightningWide, cent->gent->client->renderInfo.handLPoint, fxAxis );
}
else
{//line
AngleVectors( tAng, fxDir, NULL, NULL );
theFxScheduler.PlayEffect( cgs.effects.forceLightning, cent->gent->client->renderInfo.handLPoint, fxDir );
}
}
/*
if ( cent->currentState.number )
{
VectorSet( tAng, cent->pe.torso.pitchAngle, cent->pe.torso.yawAngle, 0 );
}
else
{//FIXME: this dir looks right on players, but not on NPCs, NPCs pe angles are absolute, not relative?
VectorSet( tAng, tempAngles[0]+cent->pe.torso.pitchAngle, tempAngles[1]+cent->pe.torso.yawAngle, 0 );
}
*/
if ( cent->gent->client->ps.forcePowerLevel[FP_LIGHTNING] > FORCE_LEVEL_2 )
{//arc
vec3_t fxAxis[3];
AnglesToAxis( tAng, fxAxis );
theFxScheduler.PlayEffect( cgs.effects.forceLightningWide, cent->gent->client->renderInfo.handLPoint, fxAxis );
}
else
{//line
AngleVectors( tAng, fxDir, NULL, NULL );
theFxScheduler.PlayEffect( cgs.effects.forceLightning, cent->gent->client->renderInfo.handLPoint, fxDir );
}
}
//As good a place as any, I suppose, to do this keyframed sound thing
CGG2_AnimSounds( cent );
//setup old system for gun to look at

View file

@ -30,6 +30,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "../game/wp_saber.h"
#include "../game/anims.h"
#include "../game/g_functions.h"
#include "bg_local.h"
#include <JKVR/VrClientInfo.h>
#define MASK_CAMERACLIP (MASK_SOLID)
@ -1309,7 +1310,7 @@ qboolean CG_CalcFOVFromX( float fov_x )
return (inwater);
}
float CG_ForceSpeedFOV( void )
float CG_ForceSpeedFOV( float infov )
{
gentity_t *player = &g_entities[0];
float fov;
@ -1318,15 +1319,15 @@ float CG_ForceSpeedFOV( void )
float amt = forceSpeedFOVMod[player->client->ps.forcePowerLevel[FP_SPEED]];
if ( timeLeft < 500 )
{//start going back
fov = cg_fov.value + (timeLeft)/500*amt;
fov = infov + (timeLeft)/500*amt;
}
else if ( length - timeLeft < 1000 )
{//start zooming in
fov = cg_fov.value + (length - timeLeft)/1000*amt;
fov = infov + (length - timeLeft)/1000*amt;
}
else
{//stay at this FOV
fov = cg_fov.value+amt;
fov = infov+amt;
}
return fov;
}
@ -1357,7 +1358,7 @@ static qboolean CG_CalcFov( void ) {
g_entities[cg.snap->ps.viewEntity].NPC )
{//FIXME: looks bad when take over a jedi... but never really do that, do we?
//fov_x = g_entities[cg.snap->ps.viewEntity].NPC->stats.hfov;
fov_x = vr ? vr->fov : 90.0f;
fov_x = vr ? vr->fov : cg_fov.value;
//sanity-cap?
if ( fov_x > 120 )
{
@ -1377,13 +1378,13 @@ static qboolean CG_CalcFov( void ) {
else
{
//fov_x = 120;//FIXME: read from the NPC's fov stats?
fov_x = vr ? vr->fov : 90.0f;
fov_x = vr ? vr->fov : cg_fov.value;
}
}
}
else if ( (!cg.zoomMode || cg.zoomMode > 2) && (cg.snap->ps.forcePowersActive&(1<<FP_SPEED)) && player->client->ps.forcePowerDuration[FP_SPEED] )//cg.renderingThirdPerson &&
{
fov_x = CG_ForceSpeedFOV();
fov_x = CG_ForceSpeedFOV(vr ? vr->fov : cg_fov.value);
} else {
/*
// user selectable
@ -1401,7 +1402,7 @@ static qboolean CG_CalcFov( void ) {
fov_x = 160;
}*/
fov_x = vr ? vr->fov : 90.0f;
fov_x = vr ? vr->fov : cg_fov.value;
// Disable zooming when in third person
if ( cg.zoomMode && cg.zoomMode < 3 )//&& !cg.renderingThirdPerson ) // light amp goggles do none of the zoom silliness
@ -1987,18 +1988,55 @@ wasForceSpeed=isForceSpeed;
cgi_CM_SnapPVS( cg.refdef.vieworg, cg.snap->areamask );
}
// Don't draw the in-view weapon when in camera mode
if ( !in_camera
&& !cg_pano.integer
&& cg.snap->ps.weapon != WP_SABER
&& ( cg.snap->ps.viewEntity == 0 || cg.snap->ps.viewEntity >= ENTITYNUM_WORLD ) )
if (vr->item_selector)
{
CG_AddViewWeapon( &cg.predicted_player_state );
CG_DrawItemSelector();
}
else if( cg.snap->ps.viewEntity != 0 && cg.snap->ps.viewEntity < ENTITYNUM_WORLD &&
g_entities[cg.snap->ps.viewEntity].client)
{
CG_AddViewWeapon( &g_entities[cg.snap->ps.viewEntity ].client->ps ); // HAX - because I wanted to --eez
else {
// Don't draw the in-view weapon when in camera mode
if (!in_camera
&& !cg_pano.integer
&& cg.snap->ps.weapon != WP_SABER
&& (cg.snap->ps.viewEntity == 0 || cg.snap->ps.viewEntity >= ENTITYNUM_WORLD)) {
CG_AddViewWeapon(&cg.predicted_player_state);
} else if (cg.snap->ps.viewEntity != 0 && cg.snap->ps.viewEntity < ENTITYNUM_WORLD &&
g_entities[cg.snap->ps.viewEntity].client) {
CG_AddViewWeapon(
&g_entities[cg.snap->ps.viewEntity].client->ps); // HAX - because I wanted to --eez
}
if (!in_camera
&& !cg.renderingThirdPerson
&& cg.predicted_player_state.stats[STAT_HEALTH] > 0
&& !vr->weapon_stabilised
&& !cg_pano.integer
&& (cg.snap->ps.viewEntity == 0 || cg.snap->ps.viewEntity >= ENTITYNUM_WORLD))
{
vec3_t end, forward;
refEntity_t handEnt;
memset( &handEnt, 0, sizeof(refEntity_t) );
BG_CalculateVROffHandPosition(handEnt.origin, handEnt.angles);
AngleVectors(handEnt.angles, forward, NULL, NULL);
VectorMA( handEnt.origin, 8.0f, forward, end );
//If the current force power is directional, show the nav arrow from off-hand for now
if (showPowers[cg.forcepowerSelect] >= FP_PUSH) {
vec3_t color = {0.0f, 1.0f, 0.0f};
FX_AddLine(handEnt.origin, end, 0.1f, 1.0f, 0.0f,
1.0f, 0.0f, 0.0f,
color, color, 0.0f,
60, cgi_R_RegisterShader("gfx/misc/nav_line"),
FX_SIZE_LINEAR | FX_ALPHA_LINEAR);
}
handEnt.renderfx = RF_DEPTHHACK;
handEnt.hModel = cgi_R_RegisterModel( "models/weapons2/thermal/thermal_hand.md3" );
VectorCopy(handEnt.origin, handEnt.oldorigin);
AnglesToAxis(handEnt.angles, handEnt.axis);
cgi_R_AddRefEntityToScene(&handEnt);
}
}
if ( !cg.hyperspace )

View file

@ -975,7 +975,7 @@ Add the weapon, and flash for the player's view
==============
*/
extern int PM_TorsoAnimForFrame( gentity_t *ent, int torsoFrame );
extern float CG_ForceSpeedFOV( void );
extern float CG_ForceSpeedFOV( float infov );
void CG_AddViewWeapon( playerState_t *ps )
{
@ -1066,7 +1066,7 @@ void CG_AddViewWeapon( playerState_t *ps )
gentity_t *player = &g_entities[0];
if ( (cg.snap->ps.forcePowersActive&(1<<FP_SPEED)) && player->client->ps.forcePowerDuration[FP_SPEED] )//cg.renderingThirdPerson &&
{
actualFOV = CG_ForceSpeedFOV();
actualFOV = CG_ForceSpeedFOV(cg_fov.value);
actualFOV = (cg_fovViewmodel.integer) ? actualFOV + (cg_fovViewmodel.integer - cg_fov.integer) : actualFOV;
}
else
@ -1124,25 +1124,26 @@ void CG_AddViewWeapon( playerState_t *ps )
trace_t trace;
VectorMA(origin, 256, forward, endForward);
static vec3_t WHITE ={1.0f,1.0f,1.0f};
static vec3_t RED = {1.0f,0.0f,0.0f};
FX_AddLine( origin, endForward, 0.1f, 4.0f, 0.0f,
1.0f, 0.0f, 0.0f,
WHITE, WHITE, 0.0f,
120, cgi_R_RegisterShader( "gfx/effects/redLine" ),
RED, RED, 0.0f,
120, cgi_R_RegisterShader( "gfx/effects/whiteline2" ),
FX_SIZE_LINEAR | FX_ALPHA_LINEAR );
VectorMA(origin, 20, right, endRight);
vec3_t color = { 0, 0, 255 };
vec3_t BLUE = {0.0f,0.0f,1.0f};
FX_AddLine( origin, endRight, 0.1f, 4.0f, 0.0f,
1.0f, 0.0f, 0.0f,
color, color, 0.0f,
120, cgi_R_RegisterShader( "gfx/misc/nav_line" ),
BLUE, BLUE, 0.0f,
120, cgi_R_RegisterShader( "gfx/misc/whiteline2" ),
FX_SIZE_LINEAR | FX_ALPHA_LINEAR );
VectorMA(origin, 20, up, endUp);
vec3_t GREEN = {0.0f,1.0f,0.0f};
FX_AddLine( origin, endUp, 0.1f, 4.0f, 0.0f,
1.0f, 0.0f, 0.0f,
WHITE, WHITE, 0.0f,
GREEN, GREEN, 0.0f,
120, cgi_R_RegisterShader( "gfx/misc/whiteline2" ),
FX_SIZE_LINEAR | FX_ALPHA_LINEAR );
@ -2141,7 +2142,9 @@ void CG_DrawWeaponSelect( void )
{
int w = cgi_R_Font_StrLenPixels(text, cgs.media.qhFontSmall, 1.0f);
int x = ( SCREEN_WIDTH - w ) / 2;
cgi_R_Font_DrawString(x, (SCREEN_HEIGHT - 24), text, textColor, cgs.media.qhFontSmall, -1, 1.0f);
int y = (SCREEN_HEIGHT - 24);
CG_AdjustFrom640Int(&x, &y, NULL, NULL);
cgi_R_Font_DrawString(x, y, text, textColor, cgs.media.qhFontSmall, -1, 1.0f);
}
}
@ -2644,6 +2647,276 @@ void CG_Weapon_f( void )
cg.weaponSelect = num;
}
void Cmd_UseInventory_f(gentity_t *ent);
//Selects the currently selected thing (if one _is_ selected)
void CG_ItemSelectorSelect_f( void )
{
cg.itemSelectorTime = 0;
cgi_Cvar_Set("timescale", "1.0");
if (cg.itemSelectorSelection == -1)
{
cg.itemSelectorType = 0;
return;
}
if (cg.itemSelectorType == 0)
{
if (cg.weaponSelect == cg.itemSelectorSelection)
{
return;
}
cg.weaponSelectTime = cg.time;
cg.weaponSelect = cg.itemSelectorSelection;
}
else if (cg.itemSelectorType == 1)
{
if (cg.forcepowerSelect == cg.itemSelectorSelection)
{
return;
}
cg.forcepowerSelectTime = cg.time;
cg.forcepowerSelect = cg.itemSelectorSelection;
}
else if (cg.itemSelectorType == 2)
{
cg.inventorySelectTime = cg.time;
cg.inventorySelect = cg.itemSelectorSelection;
//Immediately use the selected inventory item
if (player)
{
Cmd_UseInventory_f(player);
}
}
//reset ready for next time
cg.itemSelectorType = 0;
cg.itemSelectorSelection = -1;
}
void CG_ItemSelectorNext_f( void )
{
cg.itemSelectorType = (cg.itemSelectorType+1) % 3;
cg.itemSelectorTime = cg.time;
}
void CG_ItemSelectorPrev_f( void )
{
if (--cg.itemSelectorType < 0)
cg.itemSelectorType = 2;
cg.itemSelectorTime = cg.time;
}
extern int force_icons[NUM_FORCE_POWERS];
extern int inv_icons[INV_MAX];
qboolean CG_InventorySelectable( int index);
qboolean ForcePower_Valid(int index);
void CG_DrawItemSelector( void )
{
if (cg.itemSelectorTime == 0)
{
cg.itemSelectorTime = cg.time;
VectorCopy(vr->weaponangles, cg.itemSelectorAngles);
VectorCopy(vr->weaponposition, cg.itemSelectorOrigin);
VectorCopy(vr->weaponoffset, cg.itemSelectorOffset);
}
float dist = 10.0f;
float radius = 4.4f;
float scale = 0.05f;
float frac = (cg.time - cg.itemSelectorTime) / 20.0f;
if (frac > 1.0f)
{
frac = 1.0f;
}
cgi_Cvar_Set("timescale", "0.22");
vec3_t controllerOrigin, controllerAngles, controllerOffset, selectorOrigin;
BG_CalculateVRWeaponPosition(controllerOrigin, controllerAngles);
VectorSubtract(vr->weaponposition, cg.itemSelectorOrigin, controllerOffset);
vec3_t wheelAngles, wheelOrigin, beamOrigin, wheelForward, wheelRight, wheelUp;
BG_CalculateVRPositionInWorld(cg.itemSelectorOrigin, cg.itemSelectorOffset, cg.itemSelectorAngles, wheelOrigin, wheelAngles);
AngleVectors(wheelAngles, wheelForward, wheelRight, wheelUp);
VectorCopy(controllerOrigin, wheelOrigin);
VectorCopy(wheelOrigin, beamOrigin);
VectorMA(wheelOrigin, (dist * frac), wheelForward, wheelOrigin);
VectorCopy(wheelOrigin, selectorOrigin);
vec3_t pos;
memset(&pos, 0, sizeof pos);
{
pos[0] = (sinf(DEG2RAD(wheelAngles[YAW] - controllerAngles[YAW])) / sinf(DEG2RAD(22.5f)));
pos[1] = ((wheelAngles[PITCH] - controllerAngles[PITCH]) / 22.5f);
float len = VectorLength(pos);
if (len > 1.0f)
{
pos[0] *= (1.0f / len);
pos[1] *= (1.0f / len);
}
}
VectorMA(selectorOrigin, radius * pos[0], wheelRight, selectorOrigin);
VectorMA(selectorOrigin, radius * pos[1], wheelUp, selectorOrigin);
{
vec3_t color = { 0, 0, 255 };
FX_AddLine( beamOrigin, selectorOrigin, 0.1f, 1.0f, 0.0f,
1.0f, 0.0f, 0.0f,
color, color, 0.0f,
60, cgi_R_RegisterShader( "gfx/misc/nav_line" ),
FX_SIZE_LINEAR | FX_ALPHA_LINEAR );
}
int count;
switch (cg.itemSelectorType)
{
case 0: //weapons
count = WP_EMPLACED_GUN;
break;
case 1: // force powers
count = MAX_SHOWPOWERS;
break;
case 2: //gadgets
count = INV_GOODIE_KEY;
break;
}
qboolean selected = qfalse;
for (int index = 0; index < count; ++index)
{
int itemId = index;
if (cg.itemSelectorType == 0) {
itemId = index+1; // We need to ignore WP_NONE for weapons
if (itemId == count)
{
break;
}
if (itemId == WP_SABER ||
itemId == WP_BRYAR_PISTOL ||
itemId == WP_BLASTER ||
itemId == WP_FLECHETTE ||
itemId == WP_REPEATER ||
itemId == WP_THERMAL) {
CG_RegisterWeapon(itemId);
} else {
continue;
}
}
{
bool selectable;
switch (cg.itemSelectorType)
{
case 0: //weapons
selectable = CG_WeaponSelectable(itemId, cg.weaponSelect, qfalse) && cg.snap->ps.ammo[weaponData[itemId].ammoIndex];
break;
case 1: // force powers
selectable = ForcePower_Valid(itemId);
break;
case 2: //gadgets
selectable = CG_InventorySelectable(itemId) && inv_icons[itemId];
break;
}
if (selectable) {
//first calculate wheel slot position
vec3_t angles, iconOrigin, iconBackground, iconForeground;
VectorClear(angles);
angles[YAW] = wheelAngles[YAW];
angles[PITCH] = wheelAngles[PITCH];
angles[ROLL] =
(360 / count) * (itemId - 1);
vec3_t forward, up;
AngleVectors(angles, forward, NULL, up);
VectorMA(wheelOrigin, (radius * frac), up, iconOrigin);
VectorMA(iconOrigin, 0.2f, forward, iconBackground);
VectorMA(iconOrigin, -0.2f, forward, iconForeground);
{
vec3_t diff;
VectorSubtract(selectorOrigin, iconOrigin, diff);
float length = VectorLength(diff);
if (length <= 1.0f &&
frac == 1.0f &&
selectable) {
if (cg.itemSelectorSelection != itemId) {
cg.itemSelectorSelection = itemId;
//trap_HapticEvent("selector_icon", 0, 0, 100, 0, 0);
}
selected = qtrue;
}
}
if (cg.itemSelectorSelection == itemId) {
refEntity_t sprite;
memset(&sprite, 0, sizeof(sprite));
VectorCopy(iconOrigin, sprite.origin);
sprite.origin[2] += 2.5f + (0.5f * sinf(DEG2RAD(
AngleNormalize360(cg.time - cg.itemSelectorTime))));
sprite.reType = RT_SPRITE;
sprite.customShader = cgs.media.binocularArrow;
sprite.radius = 0.6f;
sprite.shaderRGBA[0] = 255;
sprite.shaderRGBA[1] = 255;
sprite.shaderRGBA[2] = 255;
sprite.shaderRGBA[3] = 255;
cgi_R_AddRefEntityToScene(&sprite);
}
{
refEntity_t sprite;
memset(&sprite, 0, sizeof(sprite));
float sRadius = 1.3f;
VectorCopy(iconOrigin, sprite.origin);
sprite.reType = RT_SPRITE;
switch (cg.itemSelectorType)
{
case 0: //weapons
sprite.customShader = cg_weapons[itemId].weaponIcon;
break;
case 1: // force powers
sprite.customShader = force_icons[showPowers[itemId]];
break;
case 2: //gadgets
sprite.customShader = inv_icons[itemId];
break;
}
sprite.radius =
sRadius * (cg.itemSelectorSelection == itemId ? 1.3f : 0.6f);
sprite.shaderRGBA[0] = 255;
sprite.shaderRGBA[1] = 255;
sprite.shaderRGBA[2] = 255;
sprite.shaderRGBA[3] = 255;
cgi_R_AddRefEntityToScene(&sprite);
}
}
}
}
if (!selected)
{
cg.itemSelectorSelection = -1;
}
}
/*
===================
CG_OutOfAmmoChange

View file

@ -83,6 +83,7 @@ void BG_CalculateVRWeaponPosition( vec3_t origin, vec3_t angles );
void BG_CalculateVRSaberPosition( vec3_t origin, vec3_t angles );
void BG_CalculateVROffHandPosition( vec3_t origin, vec3_t angles );
void BG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out);
void BG_CalculateVRPositionInWorld( vec3_t in_position, vec3_t in_offset, vec3_t in_orientation, vec3_t origin, vec3_t angles );
#endif

View file

@ -674,7 +674,7 @@ void BG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out)
}
}
static void BG_CalculateVRPositionInWorld( vec3_t in_position, vec3_t in_offset, vec3_t in_orientation, vec3_t origin, vec3_t angles )
void BG_CalculateVRPositionInWorld( vec3_t in_position, vec3_t in_offset, vec3_t in_orientation, vec3_t origin, vec3_t angles )
{
vec3_t offset;
VectorCopy(in_offset, offset);

View file

@ -31,9 +31,6 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "../../code/qcommon/q_shared.h"
//How fast the saber/melee needs to be physically swung in order to trigger sounds and trails
#define WEAPON_VELOCITY_TRIGGER 1.6f
typedef enum //# weapon_e
{
WP_NONE,

View file

@ -5706,7 +5706,15 @@ void ForceThrow( gentity_t *self, qboolean pull )
G_Sound( self, soundIndex );
VectorCopy( self->client->ps.viewangles, fwdangles );
if (self->client->ps.clientNum == 0)
{
vec3_t origin, angles;
BG_CalculateVROffHandPosition(origin, fwdangles);
}
else
{
VectorCopy( self->client->ps.viewangles, fwdangles );
}
//fwdangles[1] = self->client->ps.viewangles[1];
AngleVectors( fwdangles, forward, right, NULL );
VectorCopy( self->currentOrigin, center );
@ -6226,7 +6234,16 @@ void ForceThrow( gentity_t *self, qboolean pull )
vec3_t pushDir;
float damage = 800;
AngleVectors( self->client->ps.viewangles, forward, NULL, NULL );
if (self->client->ps.clientNum == 0)
{
vec3_t origin, angles;
BG_CalculateVROffHandPosition(origin, angles);
AngleVectors(angles, forward, right, NULL);
}
else
{
AngleVectors(self->client->ps.viewangles, forward, right, NULL);
}
VectorNormalize( forward );
VectorMA( self->client->renderInfo.eyePoint, radius, forward, end );
gi.trace( &tr, self->client->renderInfo.eyePoint, vec3_origin, vec3_origin, end, self->s.number, MASK_SHOT, G2_NOCOLLIDE, 0 );
@ -6937,7 +6954,16 @@ void ForceGrip( gentity_t *self )
self->client->ps.weaponTime = floor( self->client->ps.weaponTime * g_timescale->value );
}
AngleVectors( self->client->ps.viewangles, forward, NULL, NULL );
if (self->client->ps.clientNum == 0)
{
vec3_t origin, angles;
BG_CalculateVROffHandPosition(origin, angles);
AngleVectors(angles, forward, NULL, NULL);
}
else
{
AngleVectors(self->client->ps.viewangles, forward, NULL, NULL);
}
VectorNormalize( forward );
VectorMA( self->client->renderInfo.handLPoint, FORCE_GRIP_DIST, forward, end );
@ -7259,7 +7285,17 @@ void ForceShootLightning( gentity_t *self )
return;
}
AngleVectors( self->client->ps.viewangles, forward, NULL, NULL );
if (self->client->ps.clientNum == 0)
{
vec3_t origin, angles;
BG_CalculateVROffHandPosition(origin, angles);
AngleVectors(angles, forward, NULL, NULL);
}
else
{
AngleVectors(self->client->ps.viewangles, forward, NULL, NULL);
}
VectorNormalize( forward );
//FIXME: if lightning hits water, do water-only-flagged radius damage from that point