-
-
Save daftmugi/41d0324107e8734f364bb3e50ff00794 to your computer and use it in GitHub Desktop.
Patch: Add Hold Frob for Alternate Interaction
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git game/Grabber.cpp game/Grabber.cpp | |
index b3c08eb..c70baf8 100755 | |
--- game/Grabber.cpp | |
+++ game/Grabber.cpp | |
@@ -1612,10 +1612,48 @@ bool CGrabber::ToggleEquip( void ) | |
return rc; | |
} | |
+bool CGrabber::EquipFrobEntity( idPlayer *player ) | |
+{ | |
+ idEntity* frobEnt = player->m_FrobEntity.GetEntity(); | |
+ | |
+ // If attachment, such as head, get its body. | |
+ idEntity* ent = (frobEnt && frobEnt->IsType(idAFAttachment::Type)) | |
+ ? static_cast<idAFAttachment*>(frobEnt)->GetBindMaster() | |
+ : frobEnt; | |
+ | |
+ if (!(ent && ent->spawnArgs.GetBool("equippable"))) | |
+ return false; | |
+ | |
+ if (EquipEntity(ent)) | |
+ { | |
+ if (ent->IsType(idAFEntity_Base::Type)) | |
+ { | |
+ // If the body ent frob state is not set to 'false' after shouldering, | |
+ // the body will be stuck in a highlighted state after dropping it | |
+ // until the player highlights the body again. So, ensure 'false'. | |
+ ent->SetFrobbed(false); | |
+ } | |
+ else | |
+ { | |
+ // Unless shouldering a body, make sure nothing is equipped. | |
+ Forget(ent); | |
+ } | |
+ | |
+ return true; | |
+ } | |
+ | |
+ return false; | |
+} | |
+ | |
bool CGrabber::Equip( void ) | |
{ | |
- idStr str; | |
idEntity *ent = m_dragEnt.GetEntity(); | |
+ return EquipEntity(ent); | |
+} | |
+ | |
+bool CGrabber::EquipEntity( idEntity *ent ) | |
+{ | |
+ idStr str; | |
if( !ent || !ent->spawnArgs.GetBool("equippable") ) | |
return false; | |
diff --git game/Grabber.h game/Grabber.h | |
index c09bcdd..b68aeba 100755 | |
--- game/Grabber.h | |
+++ game/Grabber.h | |
@@ -147,9 +147,16 @@ public: | |
**/ | |
bool ToggleEquip( void ); | |
/** | |
+ * Daft Mugi #6316 | |
+ * Try to Use/Equip frob-highlighted item without holding it. | |
+ * Examples: bodies, candles, lanterns, and food | |
+ **/ | |
+ bool EquipFrobEntity( idPlayer *player ); | |
+ /** | |
* Actual functions for equipping and dequipping | |
**/ | |
bool Equip( void ); | |
+ bool EquipEntity( idEntity *ent ); | |
bool Dequip( void ); | |
/** | |
diff --git game/Player.cpp game/Player.cpp | |
index 305b900..b0b2ee3 100644 | |
--- game/Player.cpp | |
+++ game/Player.cpp | |
@@ -706,6 +706,12 @@ idPlayer::idPlayer() : | |
multiloot = false; | |
multiloot_lastfrob = 0; | |
+ // Daft Mugi #6316 | |
+ holdFrobEntity = NULL; | |
+ holdFrobDraggedBodyEntity = NULL; | |
+ holdFrobStartTime = 0; | |
+ holdFrobStartViewAxis.Zero(); | |
+ | |
// greebo: Initialise the frob trace contact material to avoid | |
// crashing during map save when nothing has been frobbed yet | |
memset(&m_FrobTrace, 0, sizeof(trace_t)); | |
@@ -2423,6 +2429,13 @@ void idPlayer::Restore( idRestoreGame *savefile ) { | |
multiloot = false; | |
multiloot_lastfrob = 0; | |
+ // Daft Mugi #6316: Hold Frob for alternate interaction | |
+ // The hold frob values don't get saved, but reset on load. | |
+ holdFrobEntity = NULL; | |
+ holdFrobDraggedBodyEntity = NULL; | |
+ holdFrobStartTime = 0; | |
+ holdFrobStartViewAxis.Zero(); | |
+ | |
savefile->ReadInt( buttonMask ); | |
savefile->ReadInt( oldButtons ); | |
savefile->ReadInt( oldFlags ); | |
@@ -6021,13 +6034,7 @@ void idPlayer::PerformKeyRepeat(int impulse, int holdTime) | |
case IMPULSE_INVENTORY_USE: // Inventory Use Item | |
{ | |
- const CInventoryCursorPtr& crsr = InventoryCursor(); | |
- CInventoryItemPtr it = crsr->GetCurrentItem(); | |
- | |
- if (it != NULL && it->GetType() != CInventoryItem::IT_DUMMY) | |
- { | |
- UseInventoryItem(ERepeat, it, holdTime, false); | |
- } | |
+ InventoryUseKeyRepeat(holdTime); | |
} | |
break; | |
} | |
@@ -8818,6 +8825,56 @@ void idPlayer::SetInfluenceFov( float fov ) { | |
influenceFov = fov; | |
} | |
+/* | |
+================ | |
+idPlayer::IsHoldFrobEnabled | |
+================ | |
+*/ | |
+bool idPlayer::IsHoldFrobEnabled( void ) | |
+{ | |
+ // Hold-frob delay of 0 matches TDM v2.11 (and prior) behavior | |
+ return cv_holdfrob_delay.GetInteger() > 0; | |
+} | |
+ | |
+/* | |
+================ | |
+idPlayer::CanHoldFrobAction | |
+================ | |
+*/ | |
+bool idPlayer::CanHoldFrobAction( void ) | |
+{ | |
+ int delay = cv_holdfrob_delay.GetInteger(); | |
+ // Is hold frob enabled and has enough time elapsed? | |
+ return (delay > 0) | |
+ && (gameLocal.time - holdFrobStartTime >= delay); | |
+} | |
+ | |
+/* | |
+================ | |
+idPlayer::SetHoldFrobView | |
+================ | |
+*/ | |
+void idPlayer::SetHoldFrobView( void ) | |
+{ | |
+ holdFrobStartViewAxis = renderView->viewaxis; | |
+} | |
+ | |
+/* | |
+================ | |
+idPlayer::HoldFrobViewDistance | |
+================ | |
+*/ | |
+float idPlayer::HoldFrobViewDistance( void ) | |
+{ | |
+ // Relative to the player's view axis (x,y,z = forward,left,up). | |
+ // Use a point in front of the player. | |
+ idVec3 frobStartView = idVec3(100, 0, 0) * holdFrobStartViewAxis; | |
+ idVec3 frobCurrentView = idVec3(100, 0, 0) * renderView->viewaxis; | |
+ float holdFrobDistance = (frobCurrentView - frobStartView).Length(); | |
+ | |
+ return holdFrobDistance; | |
+} | |
+ | |
/* | |
================ | |
idPlayer::OnLadder | |
@@ -9893,6 +9950,17 @@ float idPlayer::GetMovementVolMod( void ) | |
return returnval; | |
} | |
+void idPlayer::InventoryUseKeyRepeat(int holdTime) | |
+{ | |
+ const CInventoryCursorPtr& crsr = InventoryCursor(); | |
+ CInventoryItemPtr it = crsr->GetCurrentItem(); | |
+ | |
+ if (it != NULL && it->GetType() != CInventoryItem::IT_DUMMY) | |
+ { | |
+ UseInventoryItem(ERepeat, it, holdTime, false); | |
+ } | |
+} | |
+ | |
void idPlayer::InventoryUseKeyRelease(int holdTime) | |
{ | |
const CInventoryCursorPtr& crsr = InventoryCursor(); | |
@@ -11457,7 +11525,7 @@ void idPlayer::PerformFrob(EImpulseState impulseState, idEntity* target, bool al | |
if ( (GetImmobilization() & EIM_FROB_COMPLEX) && !target->m_bFrobSimple ) | |
{ | |
// TODO: Rename this "uh-uh" sound to something more general? | |
- StartSound( "snd_drop_item_failed", SND_CHANNEL_ITEM, 0, false, NULL ); | |
+ StartSound( "snd_drop_item_failed", SND_CHANNEL_ITEM, 0, false, NULL ); | |
return; | |
} | |
@@ -11465,7 +11533,7 @@ void idPlayer::PerformFrob(EImpulseState impulseState, idEntity* target, bool al | |
// Retrieve the entity before trying to add it to the inventory, the pointer | |
// might be cleared after calling AddToInventory(). | |
idEntity* highlightedEntity = m_FrobEntity.GetEntity(); | |
- | |
+ | |
if (impulseState == EPressed) | |
{ | |
// Fire the STIM_FROB response on key down (if defined) on this entity | |
@@ -11503,10 +11571,9 @@ void idPlayer::PerformFrob(EImpulseState impulseState, idEntity* target, bool al | |
// Inventory item could not be used with the highlighted entity, proceed with ordinary frob action | |
- // These actions are only applicable for EPressed buttonstate | |
+ // Try to add world item to inventory | |
if (impulseState == EPressed || ((impulseState == ERepeat) && multiloot)) | |
{ | |
- | |
// First we have to check whether that entity is an inventory | |
// item. In that case, we have to add it to the inventory and | |
// hide the entity. | |
@@ -11548,63 +11615,163 @@ void idPlayer::PerformFrob(EImpulseState impulseState, idEntity* target, bool al | |
// grayman #3011 - is anything sitting on this inventory item? | |
target->ActivateContacts(); | |
+ | |
+ // Item added to inventory, so skip other frob code | |
+ return; | |
} | |
- if (impulseState == EPressed) | |
+ } | |
+ | |
+ | |
+ // Item could not be added to inventory, so handle body and equip/use frob. | |
+ | |
+ const bool grabableType = target->spawnArgs.GetBool("grabable", "1"); // allow override | |
+ const bool bodyType = grabableType | |
+ && (target->IsType(idAFEntity_Base::Type) || target->IsType(idAFAttachment::Type)); | |
+ const bool moveableType = grabableType | |
+ && (target->IsType(idMoveable::Type) || target->IsType(idMoveableItem::Type)); | |
+ | |
+ // If an attachment, such as a head, get its body. | |
+ idEntity* bodyTarget = target->IsType(idAFAttachment::Type) | |
+ ? static_cast<idAFAttachment*>(target)->GetBindMaster() | |
+ : target; | |
+ | |
+ const bool holdFrobBodyType = bodyType | |
+ && bodyTarget | |
+ && bodyTarget->spawnArgs.GetBool("shoulderable", "0") | |
+ && IsHoldFrobEnabled(); | |
+ const bool holdFrobUsableType = moveableType | |
+ && target->spawnArgs.GetBool("equippable", "0") | |
+ && IsHoldFrobEnabled(); | |
+ | |
+ // Do not pick up live, conscious AI | |
+ if (target->IsType(idAI::Type)) | |
+ { | |
+ idAI* AItarget = static_cast<idAI*>(target); | |
+ if ((AItarget->health > 0) && !AItarget->IsKnockedOut()) | |
+ return; | |
+ } | |
+ | |
+ // Daft Mugi #6257: Auto-Search Bodies | |
+ if (bodyType && cv_tdm_autosearch_bodies.GetBool()) | |
+ { | |
+ // delay > 0 and shoulderable, hold-frob behavior (on EReleased) | |
+ bool isHoldFrob = holdFrobBodyType && impulseState == EReleased; | |
+ // delay > 0 and non-shoulderable, regular behavior (on EPressed) | |
+ // delay == 0, TDM v2.11 (and prior) regular behavior (on EPressed) | |
+ bool isRegular = !holdFrobBodyType && impulseState == EPressed; | |
+ | |
+ if (isHoldFrob || isRegular) | |
{ | |
- // Grab it if it's a grabable class | |
- if (target->IsType(idMoveable::Type) || target->IsType(idAFEntity_Base::Type) || | |
- target->IsType(idMoveableItem::Type) || target->IsType(idAFAttachment::Type)) | |
+ // If looted body this time, do not shoulder/pick up body. | |
+ // NOTE: The body being frobbed might not be an idAI. | |
+ if (bodyTarget | |
+ && bodyTarget->IsType(idAFEntity_Base::Type) | |
+ && bodyTarget->AddAttachmentsToInventory(this)) | |
{ | |
- // allow override of default grabbing behavior | |
- if (!target->spawnArgs.GetBool("grabable", "1")) | |
- { | |
- return; | |
- } | |
- | |
- // Do not pick up live, conscious AI | |
- if (target->IsType(idAI::Type)) | |
- { | |
- idAI* AItarget = static_cast<idAI*>(target); | |
- if ((AItarget->health > 0) && !AItarget->IsKnockedOut()) | |
- { | |
- return; | |
- } | |
- } | |
+ return; | |
+ } | |
+ } | |
+ } | |
- if (cv_tdm_autosearch_bodies.GetBool()) | |
- { | |
- // If attachment, such as head, get its body. | |
- idEntity* body = target->IsType(idAFAttachment::Type) ? | |
- static_cast<idAFAttachment*>(target)->GetBindMaster() : | |
- target; | |
+ if (impulseState == EPressed) | |
+ { | |
+ if (holdFrobBodyType || holdFrobUsableType) | |
+ { | |
+ // Store frobbed entity and start time tracking. | |
+ holdFrobEntity = highlightedEntity; | |
+ holdFrobDraggedBodyEntity = NULL; | |
+ holdFrobStartTime = gameLocal.time; | |
+ SetHoldFrobView(); | |
+ return; | |
+ } | |
+ } | |
- // NOTE: The body being looted might not be an idAI. | |
- if (body && body->IsType(idAFEntity_Base::Type)) | |
- { | |
- // Daft Mugi #6257 | |
- // If looted body this time, do not pick up. | |
- if (body->AddAttachmentsToInventory(this)) | |
- return; | |
- } | |
- } | |
+ if (impulseState == ERepeat && holdFrobEntity.GetEntity() == highlightedEntity) | |
+ { | |
+ if (holdFrobBodyType) | |
+ { | |
+ // Drag body if enough time has passed or view has moved outside of bounds. | |
+ if (CanHoldFrobAction() | |
+ || (HoldFrobViewDistance() > cv_holdfrob_bounds.GetFloat())) | |
+ { | |
+ gameLocal.m_Grabber->Update(this, false, true); | |
+ holdFrobEntity = NULL; | |
+ // Store grabber entity of dragged body, so the body can be released later. | |
+ holdFrobDraggedBodyEntity = gameLocal.m_Grabber->GetSelected(); | |
+ return; | |
+ } | |
+ } | |
- gameLocal.m_Grabber->Update(this, false, true); // preservePosition = true #4149 | |
+ if (holdFrobUsableType) | |
+ { | |
+ // Equip/Use, if enough time has passed. | |
+ if (CanHoldFrobAction()) | |
+ { | |
+ gameLocal.m_Grabber->EquipFrobEntity(this); | |
+ holdFrobEntity = NULL; | |
+ return; | |
} | |
} | |
} | |
+ | |
+ if (impulseState == EReleased && holdFrobEntity.GetEntity() == highlightedEntity) | |
+ { | |
+ if (holdFrobBodyType) | |
+ { | |
+ // Shoulder/pick up body | |
+ gameLocal.m_Grabber->EquipFrobEntity(this); | |
+ holdFrobEntity = NULL; | |
+ return; | |
+ } | |
+ | |
+ if (holdFrobUsableType) | |
+ { | |
+ // Pick up, since it was not equipped/used (or toggled on/off). | |
+ gameLocal.m_Grabber->Update(this, false, true); | |
+ holdFrobEntity = NULL; | |
+ return; | |
+ } | |
+ } | |
+ | |
+ | |
+ // Item could not be added to inventory, so try to pick it up. | |
+ | |
+ if (impulseState == EPressed && (moveableType || bodyType)) | |
+ { | |
+ // Grab it if it's a grabable class and not overridden | |
+ gameLocal.m_Grabber->Update(this, false, true); // preservePosition = true #4149 | |
+ return; | |
+ } | |
} | |
void idPlayer::PerformFrob() | |
{ | |
+ // Initialize/reset hold frob | |
+ holdFrobEntity = NULL; | |
+ holdFrobDraggedBodyEntity = NULL; | |
+ | |
// Ignore frobs if player-frobbing is immobilized. | |
if ( GetImmobilization() & EIM_FROB ) | |
{ | |
return; | |
} | |
- // if the grabber is currently holding something and frob is pressed, | |
+ idEntity* grabberEnt = gameLocal.m_Grabber->GetSelected(); | |
+ | |
+ // If holding an equippable item, begin tracking frob for later | |
+ // equip/use or drop. | |
+ if (IsHoldFrobEnabled() | |
+ && grabberEnt | |
+ && grabberEnt->spawnArgs.GetBool("equippable", "0")) | |
+ { | |
+ holdFrobEntity = grabberEnt; | |
+ holdFrobStartTime = gameLocal.time; | |
+ return; | |
+ } | |
+ | |
+ // If the grabber is currently holding something and frob is pressed, | |
// release it. Do not frob anything new since you're holding an item. | |
- if ( gameLocal.m_Grabber->GetSelected() ) | |
+ if (grabberEnt) | |
{ | |
gameLocal.m_Grabber->Update( this ); | |
return; | |
@@ -11613,6 +11780,16 @@ void idPlayer::PerformFrob() | |
// Get the currently frobbed entity | |
idEntity* frob = m_FrobEntity.GetEntity(); | |
+ // If there is nothing highlighted and shouldering a body, | |
+ // drop the body. | |
+ if (IsHoldFrobEnabled() | |
+ && !frob | |
+ && IsShoulderingBody()) | |
+ { | |
+ gameLocal.m_Grabber->Dequip(); | |
+ return; | |
+ } | |
+ | |
// Relay the function to the specialised method | |
PerformFrob(EPressed, frob, true); | |
} | |
@@ -11625,6 +11802,18 @@ void idPlayer::PerformFrobKeyRepeat(int holdTime) | |
return; | |
} | |
+ idEntity* grabberEnt = gameLocal.m_Grabber->GetSelected(); | |
+ | |
+ // If holding an equippable item, use it if frob held long enough. | |
+ if (holdFrobEntity.GetEntity() | |
+ && holdFrobEntity.GetEntity() == grabberEnt | |
+ && CanHoldFrobAction()) | |
+ { | |
+ gameLocal.m_Grabber->ToggleEquip(); | |
+ holdFrobEntity = NULL; | |
+ return; | |
+ } | |
+ | |
// Get the currently frobbed entity | |
idEntity* frob = m_FrobEntity.GetEntity(); | |
@@ -11643,12 +11832,39 @@ void idPlayer::PerformFrobKeyRelease(int holdTime) | |
{ | |
// Obsttorte: multilooting | |
multiloot = false; | |
+ | |
// Ignore frobs if player-frobbing is immobilized. | |
if ( GetImmobilization() & EIM_FROB ) | |
{ | |
return; | |
} | |
+ idEntity* grabberEnt = gameLocal.m_Grabber->GetSelected(); | |
+ | |
+ if (IsHoldFrobEnabled()) | |
+ { | |
+ idEntity* holdFrobEnt = holdFrobEntity.GetEntity(); | |
+ | |
+ // NOTE: When hold-frob drag body behavior is false, do not | |
+ // stop dragging. (Matches original TDM behavior) | |
+ if (holdFrobDraggedBodyEntity.GetEntity() | |
+ && cv_holdfrob_drag_body_behavior.GetBool()) | |
+ { | |
+ holdFrobEnt = holdFrobDraggedBodyEntity.GetEntity(); | |
+ } | |
+ | |
+ // If currently dragging a body, stop dragging. | |
+ // If currently holding an equippable item, drop it. | |
+ // When hold-frob delay is 0, behavior matches TDM v2.11 (and prior). | |
+ if (holdFrobEnt && holdFrobEnt == grabberEnt) | |
+ { | |
+ gameLocal.m_Grabber->Update(this); | |
+ holdFrobDraggedBodyEntity = NULL; | |
+ holdFrobEntity = NULL; | |
+ return; | |
+ } | |
+ } | |
+ | |
// Get the currently frobbed entity | |
idEntity* frob = m_FrobEntity.GetEntity(); | |
diff --git game/Player.h game/Player.h | |
index b4f2fd5..8bafba6 100644 | |
--- game/Player.h | |
+++ game/Player.h | |
@@ -827,6 +827,12 @@ public: | |
bool IsShoulderingBody( void ) { return m_bShoulderingBody; }; | |
+ // Daft Mugi #6316: Hold Frob for alternate interaction | |
+ bool IsHoldFrobEnabled( void ); | |
+ bool CanHoldFrobAction( void ); | |
+ void SetHoldFrobView( void ); | |
+ float HoldFrobViewDistance( void ); | |
+ | |
bool OnLadder( void ) const; | |
// Virtal override of idActor::OnElevator() | |
virtual CMultiStateMover* OnElevator(bool mustBeMoving) const; | |
@@ -871,6 +877,12 @@ public: | |
bool multiloot; | |
int multiloot_lastfrob; | |
+ // Daft Mugi #6316: Hold Frob for alternate interaction | |
+ idEntityPtr<idEntity> holdFrobEntity; | |
+ idEntityPtr<idEntity> holdFrobDraggedBodyEntity; | |
+ int holdFrobStartTime; | |
+ idMat3 holdFrobStartViewAxis; | |
+ | |
// angua: Set ideal crouch state | |
void EvaluateCrouch(); | |
@@ -946,6 +958,9 @@ public: | |
**/ | |
bool DropToHands( idEntity *ent, CInventoryItemPtr item = CInventoryItemPtr() ); | |
+ // Performs the inventory action for onButtonRepeat | |
+ void InventoryUseKeyRepeat(int holdTime); | |
+ | |
// Performs the inventory action for onButtonRelease | |
void InventoryUseKeyRelease(int holdTime); | |
diff --git game/gamesys/SysCvar.cpp game/gamesys/SysCvar.cpp | |
index 0c174e5..d5984c5 100644 | |
--- game/gamesys/SysCvar.cpp | |
+++ game/gamesys/SysCvar.cpp | |
@@ -344,9 +344,29 @@ idCVar cv_frobhelper_fadein_duration( "tdm_frobhelper_fadein_duration", "1500", | |
idCVar cv_frobhelper_fadeout_duration( "tdm_frobhelper_fadeout_duration", "500", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER | CVAR_NOCHEAT, "The FrobHelper cursor is faded out for this duration specified in ms.", 0.0f, 5000.0f); | |
idCVar cv_frobhelper_ignore_size( "tdm_frobhelper_ignore_size", "40.0", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT | CVAR_NOCHEAT, "The FrobHelper is not activated for entites that are bigger than this ignore size along one dimension. Set to 0, to disable ignoring entities.", 0.0f, 10000.0f); | |
+// Daft Mugi #6316: Hold Frob for alternate interaction | |
+idCVar cv_holdfrob_delay( | |
+ "tdm_holdfrob_delay", "300", CVAR_GAME | CVAR_ARCHIVE | CVAR_INTEGER | CVAR_NOCHEAT, | |
+ "The hold-frob delay (in ms) before drag body or use world item.\n" | |
+ "Set to 0 for original TDM behavior.", | |
+ 0, 2000 | |
+); | |
+idCVar cv_holdfrob_bounds( | |
+ "tdm_holdfrob_bounds", "7", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT | CVAR_NOCHEAT, | |
+ "The view position must stay within the bounds in order to perform an interaction.", | |
+ 0.0f, 1000.0f | |
+); | |
+idCVar cv_holdfrob_drag_body_behavior( | |
+ "tdm_holdfrob_drag_body_behavior", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL | CVAR_NOCHEAT, | |
+ "Which drag body behavior?\n" | |
+ " 1 --- on first frob release (key up), let go of body.\n" | |
+ " 0 --- on second frob, let go of body. (original TDM behavior)" | |
+); | |
+ | |
// Obsttorte: #5984 (multilooting) | |
idCVar cv_multiloot_min_interval("tdm_multiloot_min_interval", "300", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT | CVAR_NOCHEAT, "The minimum interval between two consecutive frobs when multifrobbing."); | |
idCVar cv_multiloot_max_interval("tdm_multiloot_max_interval", "2000", CVAR_GAME | CVAR_ARCHIVE | CVAR_FLOAT | CVAR_NOCHEAT, "The amount of time after which multilooting gets disabled again."); | |
+ | |
// #4289 | |
idCVar cv_pm_blackjack_indicate("tdm_blackjack_indicate", "1", CVAR_GAME | CVAR_ARCHIVE | CVAR_BOOL | CVAR_NOCHEAT, "Set to 1 to activate blackjack indicator.", 0, 1); | |
diff --git game/gamesys/SysCvar.h game/gamesys/SysCvar.h | |
index 73c51f4..5ec646a 100644 | |
--- game/gamesys/SysCvar.h | |
+++ game/gamesys/SysCvar.h | |
@@ -280,6 +280,11 @@ extern idCVar cv_frobhelper_fadein_duration; | |
extern idCVar cv_frobhelper_fadeout_duration; | |
extern idCVar cv_frobhelper_ignore_size; | |
+// Daft Mugi #6316: Hold Frob for alternate interaction | |
+extern idCVar cv_holdfrob_delay; | |
+extern idCVar cv_holdfrob_bounds; | |
+extern idCVar cv_holdfrob_drag_body_behavior; | |
+ | |
//Obsttorte: #5984 (multilooting) | |
extern idCVar cv_multiloot_min_interval; | |
extern idCVar cv_multiloot_max_interval; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment