mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2025-02-17 01:21:47 +00:00
Support for a selectable weapon system
much quicker and cleaner than "next" and "previous" on the right stick. That approach can still be set up using the mappings
This commit is contained in:
parent
e4d49b44e6
commit
73bbcf8882
10 changed files with 201 additions and 9 deletions
|
@ -26,10 +26,10 @@ set vr_button_map_Y_ALT ""
|
|||
set vr_button_map_SECONDARYTHUMBSTICK "+scores"
|
||||
set vr_button_map_SECONDARYTHUMBSTICK_ALT ""
|
||||
set vr_button_map_PRIMARYTHUMBSTICK ""
|
||||
set vr_button_map_PRIMARYTHUMBSTICK_ALT "weapon 1"
|
||||
set vr_button_map_RTHUMBFORWARD "weapnext"
|
||||
set vr_button_map_PRIMARYTHUMBSTICK_ALT ""
|
||||
set vr_button_map_RTHUMBFORWARD "+weapon_select"
|
||||
set vr_button_map_RTHUMBFORWARD_ALT ""
|
||||
set vr_button_map_RTHUMBBACK "weapprev"
|
||||
set vr_button_map_RTHUMBBACK "+weapon_select"
|
||||
set vr_button_map_RTHUMBBACK_ALT ""
|
||||
set vr_button_map_SECONDARYTRIGGER "+moveup"
|
||||
set vr_button_map_SECONDARYTRIGGER_ALT ""
|
||||
|
|
|
@ -470,6 +470,7 @@ static consoleCommand_t commands[] = {
|
|||
{ "tcmd", CG_TargetCommand_f },
|
||||
{ "tell_target", CG_TellTarget_f },
|
||||
{ "tell_attacker", CG_TellAttacker_f },
|
||||
{ "holster_select", CG_HolsterSelect_f },
|
||||
#ifdef MISSIONPACK
|
||||
{ "vtell_target", CG_VoiceTellTarget_f },
|
||||
{ "vtell_attacker", CG_VoiceTellAttacker_f },
|
||||
|
|
|
@ -2789,9 +2789,13 @@ void CG_DrawActive( stereoFrame_t stereoView ) {
|
|||
|
||||
VectorCopy( baseOrg, cg.refdef.vieworg );
|
||||
|
||||
// draw status bar and other floating elements
|
||||
hudStereoView = stereoView;
|
||||
CG_Draw2D(hudStereoView);
|
||||
//Don't draw HUD whilst selecting the weapon with the holster (it gets in the way)
|
||||
if (cg.weaponHolsterTime == 0)
|
||||
{
|
||||
// draw status bar and other floating elements
|
||||
hudStereoView = stereoView;
|
||||
CG_Draw2D(hudStereoView);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -618,6 +618,9 @@ typedef struct {
|
|||
int weaponAnimation;
|
||||
int weaponAnimationTime;
|
||||
|
||||
int weaponHolsterSelection;
|
||||
int weaponHolsterTime;
|
||||
|
||||
// blend blobs
|
||||
float damageTime;
|
||||
float damageX, damageY, damageValue;
|
||||
|
@ -783,6 +786,8 @@ typedef struct {
|
|||
qhandle_t blueKamikazeShader;
|
||||
#endif
|
||||
|
||||
qhandle_t smallSphereModel;
|
||||
|
||||
// weapon effect models
|
||||
qhandle_t bulletFlashModel;
|
||||
qhandle_t ringFlashModel;
|
||||
|
@ -1114,6 +1119,7 @@ extern vmCvar_t cg_drawFPS;
|
|||
extern vmCvar_t cg_drawSnapshot;
|
||||
extern vmCvar_t cg_draw3dIcons;
|
||||
extern vmCvar_t cg_debugWeaponAiming;
|
||||
extern vmCvar_t cg_holsterSimple2DIcons;
|
||||
extern vmCvar_t cg_drawIcons;
|
||||
extern vmCvar_t cg_drawAmmoWarning;
|
||||
extern vmCvar_t cg_drawCrosshair;
|
||||
|
@ -1380,6 +1386,7 @@ void CG_PositionRotatedEntityOnTag( refEntity_t *entity, const refEntity_t *pare
|
|||
void CG_NextWeapon_f( void );
|
||||
void CG_PrevWeapon_f( void );
|
||||
void CG_Weapon_f( void );
|
||||
void CG_HolsterSelect_f( void );
|
||||
|
||||
void rotateAboutOrigin(float x, float y, float rotation, vec2_t out);
|
||||
void CG_CalculateVRWeaponPosition( vec3_t origin, vec3_t angles );
|
||||
|
@ -1397,6 +1404,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 );
|
||||
void CG_GrappleTrail( centity_t *ent, const weaponInfo_t *wi );
|
||||
void CG_AddViewWeapon (playerState_t *ps);
|
||||
void CG_DrawHolsteredWeapons( void );
|
||||
void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent, int team );
|
||||
void CG_DrawWeaponSelect( void );
|
||||
void CG_LaserSight( vec3_t start, vec3_t end );
|
||||
|
|
|
@ -117,6 +117,7 @@ vmCvar_t cg_drawAmmoWarning;
|
|||
vmCvar_t cg_drawCrosshair;
|
||||
vmCvar_t cg_drawCrosshairNames;
|
||||
vmCvar_t cg_debugWeaponAiming;
|
||||
vmCvar_t cg_holsterSimple2DIcons;
|
||||
vmCvar_t cg_fragMessage;
|
||||
vmCvar_t cg_drawRewards;
|
||||
vmCvar_t cg_crosshairSize;
|
||||
|
@ -235,6 +236,7 @@ static cvarTable_t cvarTable[] = {
|
|||
{ &cg_drawSnapshot, "cg_drawSnapshot", "0", CVAR_ARCHIVE },
|
||||
{ &cg_draw3dIcons, "cg_draw3dIcons", "1", CVAR_ARCHIVE },
|
||||
{ &cg_debugWeaponAiming, "cg_debugWeaponAiming", "0", CVAR_ARCHIVE },
|
||||
{ &cg_holsterSimple2DIcons, "cg_holsterSimple2DIcons", "0", CVAR_ARCHIVE },
|
||||
{ &cg_drawIcons, "cg_drawIcons", "1", CVAR_ARCHIVE },
|
||||
{ &cg_drawAmmoWarning, "cg_drawAmmoWarning", "1", CVAR_ARCHIVE },
|
||||
{ &cg_drawAttacker, "cg_drawAttacker", "0", CVAR_ARCHIVE },
|
||||
|
@ -1047,6 +1049,9 @@ static void CG_RegisterGraphics( void ) {
|
|||
|
||||
cgs.media.reticleShader = trap_R_RegisterShader( "scope.tga" );
|
||||
|
||||
//Used for the weapon selector
|
||||
cgs.media.smallSphereModel = trap_R_RegisterModel("models/powerups/health/small_sphere.md3");
|
||||
|
||||
// register the inline models
|
||||
cgs.numInlineModels = trap_CM_NumInlineModels();
|
||||
for ( i = 1 ; i < cgs.numInlineModels ; i++ ) {
|
||||
|
|
|
@ -975,6 +975,7 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
|
|||
CG_AddParticles ();
|
||||
CG_AddLocalEntities();
|
||||
}
|
||||
|
||||
CG_AddViewWeapon( &cg.predictedPlayerState );
|
||||
|
||||
// add buffered sounds
|
||||
|
|
|
@ -1635,7 +1635,6 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
CG_AddViewWeapon
|
||||
|
@ -1692,6 +1691,12 @@ void CG_AddViewWeapon( playerState_t *ps ) {
|
|||
}
|
||||
*/
|
||||
|
||||
if (vr->weapon_select)
|
||||
{
|
||||
CG_DrawHolsteredWeapons();
|
||||
return;
|
||||
}
|
||||
|
||||
cent = &cg.predictedPlayerEntity; // &cg_entities[cg.snap->ps.clientNum];
|
||||
CG_RegisterWeapon( ps->weapon );
|
||||
weapon = &cg_weapons[ ps->weapon ];
|
||||
|
@ -1997,6 +2002,147 @@ void CG_Weapon_f( void ) {
|
|||
cg.weaponSelect = num;
|
||||
}
|
||||
|
||||
//Selects the currently selected holstered weapon (if one _is_ selected)
|
||||
void CG_HolsterSelect_f( void )
|
||||
{
|
||||
cg.weaponHolsterTime = 0;
|
||||
|
||||
if (cg.weaponHolsterSelection == WP_NONE ||
|
||||
cg.weaponSelect == cg.weaponHolsterSelection)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cg.weaponSelectTime = cg.time;
|
||||
cg.weaponSelect = cg.weaponHolsterSelection;
|
||||
cg.weaponHolsterSelection = WP_NONE;
|
||||
}
|
||||
|
||||
void CG_DrawHolsteredWeapons( void )
|
||||
{
|
||||
int weapons[MAX_WEAPONS];
|
||||
memset(weapons, 0, sizeof(int) * MAX_WEAPONS);
|
||||
|
||||
if (cg.weaponHolsterTime == 0)
|
||||
{
|
||||
cg.weaponHolsterTime = cg.time;
|
||||
}
|
||||
|
||||
int j = 0;
|
||||
for ( int i = 0 ; i < MAX_WEAPONS ; i++ ) {
|
||||
if (cg.weaponSelect == i)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( CG_WeaponSelectable( i ) ) {
|
||||
weapons[j++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
const float SCALE = 0.1f;
|
||||
const float DIST = 10.0f;
|
||||
const float SEP = 14.0f;
|
||||
cg.weaponHolsterSelection = WP_NONE;
|
||||
|
||||
vec3_t weaponOrigin, weaponAngles;
|
||||
CG_CalculateVRWeaponPosition(weaponOrigin, weaponAngles);
|
||||
{
|
||||
refEntity_t blob;
|
||||
memset( &blob, 0, sizeof( blob ) );
|
||||
VectorCopy( weaponOrigin, blob.origin );
|
||||
AnglesToAxis(weaponAngles, blob.axis);
|
||||
VectorScale( blob.axis[0], 0.07f, blob.axis[0] );
|
||||
VectorScale( blob.axis[1], 0.07f, blob.axis[1] );
|
||||
VectorScale( blob.axis[2], 0.07f, blob.axis[2] );
|
||||
blob.nonNormalizedAxes = qtrue;
|
||||
blob.hModel = cgs.media.smallSphereModel;
|
||||
trap_R_AddRefEntityToScene( &blob );
|
||||
}
|
||||
|
||||
float startingPositionYaw = cg.refdefViewAngles[YAW] + (((j - (j&1 ? 0 : 1)) / 2.0f) * SEP);
|
||||
startingPositionYaw = AngleNormalize360(startingPositionYaw);
|
||||
for (int w = j-1; w >= 0; --w)
|
||||
{
|
||||
if ( cg_weapons[ weapons[w] ].item ) {
|
||||
//first calculate holster slot position
|
||||
vec3_t angles, iconOrigin;
|
||||
VectorClear(angles);
|
||||
angles[YAW] = startingPositionYaw - (w * SEP) - 4; // add a few degrees as models aren't central
|
||||
vec3_t forward;
|
||||
AngleVectors(angles, forward, NULL, NULL);
|
||||
|
||||
int dist = (cg.time - cg.weaponHolsterTime) / 10;
|
||||
if (dist > DIST) dist = DIST;
|
||||
VectorMA(cg.refdef.vieworg, dist, forward, iconOrigin);
|
||||
|
||||
float worldscale = trap_Cvar_VariableValue("vr_worldscale");
|
||||
iconOrigin[2] -= PLAYER_HEIGHT;
|
||||
iconOrigin[2] += (vr->hmdposition[1] * 0.85f) * worldscale;
|
||||
|
||||
//Float sprite above selected weapon
|
||||
qboolean selected = qfalse;
|
||||
vec3_t length;
|
||||
VectorSubtract(weaponOrigin, iconOrigin, length);
|
||||
if (VectorLength(length) <= 1.75f && dist == DIST)
|
||||
{
|
||||
cg.weaponHolsterSelection = weapons[w];
|
||||
selected = qtrue;
|
||||
|
||||
refEntity_t sprite;
|
||||
memset( &sprite, 0, sizeof( sprite ) );
|
||||
VectorCopy( iconOrigin, sprite.origin );
|
||||
sprite.origin[2] += 2.5f + (0.5f * sinf(DEG2RAD(AngleNormalize360(cg.time/6))));
|
||||
sprite.reType = RT_SPRITE;
|
||||
sprite.customShader = cgs.media.friendShader;
|
||||
sprite.radius = 0.5f;
|
||||
sprite.shaderRGBA[0] = 255;
|
||||
sprite.shaderRGBA[1] = 255;
|
||||
sprite.shaderRGBA[2] = 255;
|
||||
sprite.shaderRGBA[3] = 255;
|
||||
trap_R_AddRefEntityToScene( &sprite );
|
||||
}
|
||||
|
||||
if (!cg_holsterSimple2DIcons.integer)
|
||||
{
|
||||
refEntity_t ent;
|
||||
memset(&ent, 0, sizeof(ent));
|
||||
VectorCopy(iconOrigin, ent.origin);
|
||||
|
||||
vec3_t iconAngles;
|
||||
VectorCopy(cg.refdefViewAngles, iconAngles);
|
||||
iconAngles[YAW] -= 145.0f;
|
||||
if (weapons[w] == WP_GAUNTLET)
|
||||
{
|
||||
iconAngles[ROLL] -= 90.0f;
|
||||
}
|
||||
AnglesToAxis(iconAngles, ent.axis);
|
||||
VectorScale(ent.axis[0], SCALE + (selected ? 0.04f : 0), ent.axis[0]);
|
||||
VectorScale(ent.axis[1], SCALE + (selected ? 0.04f : 0), ent.axis[1]);
|
||||
VectorScale(ent.axis[2], SCALE + (selected ? 0.04f : 0), ent.axis[2]);
|
||||
ent.nonNormalizedAxes = qtrue;
|
||||
|
||||
ent.hModel = cg_weapons[weapons[w]].weaponModel;
|
||||
trap_R_AddRefEntityToScene(&ent);
|
||||
}
|
||||
else
|
||||
{
|
||||
refEntity_t sprite;
|
||||
memset( &sprite, 0, sizeof( sprite ) );
|
||||
VectorCopy( iconOrigin, sprite.origin );
|
||||
sprite.reType = RT_SPRITE;
|
||||
sprite.customShader = cg_weapons[weapons[w]].weaponIcon;
|
||||
sprite.radius = 0.6f + (selected ? 0.1f : 0);
|
||||
sprite.shaderRGBA[0] = 255;
|
||||
sprite.shaderRGBA[1] = 255;
|
||||
sprite.shaderRGBA[2] = 255;
|
||||
sprite.shaderRGBA[3] = 255;
|
||||
trap_R_AddRefEntityToScene( &sprite );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
CG_OutOfAmmoChange
|
||||
|
|
|
@ -56,8 +56,9 @@ VR OPTIONS MENU
|
|||
#define ID_LASERSIGHT 142
|
||||
#define ID_GORE 143
|
||||
#define ID_HAPTICINTENSITY 144
|
||||
#define ID_HOLSTER2D 145
|
||||
|
||||
#define ID_BACK 145
|
||||
#define ID_BACK 146
|
||||
|
||||
#define NUM_HUDDEPTH 6
|
||||
#define NUM_DIRECTIONMODE 2
|
||||
|
@ -88,6 +89,7 @@ typedef struct {
|
|||
menuradiobutton_s sendroll;
|
||||
menuradiobutton_s lasersight;
|
||||
menuslider_s hapticintensity;
|
||||
menuradiobutton_s holster2d;
|
||||
menulist_s gore;
|
||||
|
||||
menubitmap_s back;
|
||||
|
@ -127,6 +129,8 @@ static void VR_SetMenuItems( void ) {
|
|||
s_VR.hudyoffset.curvalue = trap_Cvar_VariableValue( "vr_hudYOffset" ) + 200;
|
||||
s_VR.sendroll.curvalue = trap_Cvar_VariableValue( "vr_sendRollToServer" ) != 0;
|
||||
s_VR.lasersight.curvalue = trap_Cvar_VariableValue( "vr_lasersight" ) != 0;
|
||||
s_VR.hapticintensity.curvalue = trap_Cvar_VariableValue( "vr_hapticIntensity" );
|
||||
s_VR.holster2d.curvalue = trap_Cvar_VariableValue( "cg_holsterSimple2DIcons" ) != 0;
|
||||
|
||||
//GORE
|
||||
{
|
||||
|
@ -225,7 +229,11 @@ static void VR_Event( void* ptr, int notification ) {
|
|||
trap_Cvar_SetValue( "vr_hapticIntensity", s_VR.hapticintensity.curvalue);
|
||||
break;
|
||||
|
||||
case ID_GORE: {
|
||||
case ID_HOLSTER2D:
|
||||
trap_Cvar_SetValue( "cg_holsterSimple2DIcons", s_VR.holster2d.curvalue);
|
||||
break;
|
||||
|
||||
case ID_GORE: {
|
||||
switch ((int)s_VR.gore.curvalue) {
|
||||
case 0:
|
||||
trap_Cvar_SetValue( "com_blood", 0);
|
||||
|
@ -495,6 +503,15 @@ static void VR_MenuInit( void ) {
|
|||
s_VR.hapticintensity.minvalue = 0;
|
||||
s_VR.hapticintensity.maxvalue = 1.0;
|
||||
|
||||
y += BIGCHAR_HEIGHT;
|
||||
s_VR.holster2d.generic.type = MTYPE_RADIOBUTTON;
|
||||
s_VR.holster2d.generic.name = "Simple Icons on Weapon Selector:";
|
||||
s_VR.holster2d.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT;
|
||||
s_VR.holster2d.generic.callback = VR_Event;
|
||||
s_VR.holster2d.generic.id = ID_HOLSTER2D;
|
||||
s_VR.holster2d.generic.x = VR_X_POS;
|
||||
s_VR.holster2d.generic.y = y;
|
||||
|
||||
y += BIGCHAR_HEIGHT + 10;
|
||||
s_VR.gore.generic.type = MTYPE_SPINCONTROL;
|
||||
s_VR.gore.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT;
|
||||
|
@ -535,6 +552,7 @@ static void VR_MenuInit( void ) {
|
|||
Menu_AddItem( &s_VR.menu, &s_VR.hudyoffset );
|
||||
Menu_AddItem( &s_VR.menu, &s_VR.sendroll );
|
||||
Menu_AddItem( &s_VR.menu, &s_VR.lasersight );
|
||||
Menu_AddItem( &s_VR.menu, &s_VR.holster2d );
|
||||
Menu_AddItem( &s_VR.menu, &s_VR.hapticintensity );
|
||||
Menu_AddItem( &s_VR.menu, &s_VR.gore );
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ typedef struct {
|
|||
qboolean virtual_screen;
|
||||
qboolean local_server; // used in bg_pmove.c
|
||||
followMode_t follow_mode;
|
||||
qboolean weapon_select;
|
||||
|
||||
int realign; // used to realign the fake 6DoF playspace in a multiplayer game
|
||||
|
||||
|
|
|
@ -252,6 +252,14 @@ static void IN_SendButtonAction(const char* action, qboolean pressed)
|
|||
{
|
||||
vr.weapon_stabilised = pressed;
|
||||
}
|
||||
else if (strcmp(action, "+weapon_select") == 0)
|
||||
{
|
||||
vr.weapon_select = pressed;
|
||||
if (!pressed)
|
||||
{
|
||||
Cbuf_AddText("holster_select");
|
||||
}
|
||||
}
|
||||
else if (action[0] == '+')
|
||||
{
|
||||
char command[256];
|
||||
|
|
Loading…
Reference in a new issue