-
Notifications
You must be signed in to change notification settings - Fork 84
Fixed thirdperson animations from third-party addons #1858
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
a63dd4f
76720bb
4fc0b13
3936983
6b73ed3
129bf85
87ec35e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| local net = net | ||
| local CurTime = CurTime | ||
|
|
||
| local plymeta = FindMetaTable("Player") | ||
| if not plymeta then | ||
|
|
@@ -7,6 +8,94 @@ if not plymeta then | |
| return | ||
| end | ||
|
|
||
| -- use a dedicated slot if available to reduce collisions with third-party gesture addons | ||
| local ttt2GestureSlot = GESTURE_SLOT_VCD or GESTURE_SLOT_CUSTOM | ||
|
|
||
| -- safety padding to avoid one frame desync when external gestures end | ||
| local extGestureDurationPadding = 0.1 | ||
|
|
||
| -- marks the end time of an externally started gesture on the player | ||
| local function MarkExternalGesture(ply, sequence) | ||
| if not isnumber(sequence) or sequence < 0 then | ||
| return | ||
| end | ||
|
|
||
| local sequenceDuration = ply:SequenceDuration(sequence) | ||
|
|
||
| if not isnumber(sequenceDuration) or sequenceDuration <= 0 then | ||
| return | ||
| end | ||
|
|
||
| local endTime = CurTime() + sequenceDuration + extGestureDurationPadding | ||
|
|
||
| if endTime > (ply.ttt2ExternalGestureEndTime or 0) then | ||
| ply.ttt2ExternalGestureEndTime = endTime | ||
| end | ||
| end | ||
|
|
||
| -- wrap this once to track externally started gestures on all slots while ignoring TTT2 internal writes | ||
| if | ||
| not plymeta._ttt2WrappedAddVCDSequenceToGestureSlot | ||
| and isfunction(plymeta.AddVCDSequenceToGestureSlot) | ||
| then | ||
| plymeta._ttt2WrappedAddVCDSequenceToGestureSlot = true | ||
|
|
||
| local plymeta_old_AddVCDSequenceToGestureSlot = plymeta.AddVCDSequenceToGestureSlot | ||
|
|
||
| --- | ||
| -- Wrapped version of @{Player:AddVCDSequenceToGestureSlot} to track external gesture activity. | ||
| -- @param number slot The gesture slot. | ||
| -- @param number sequence The sequence id. | ||
| -- @param number cycle Cycle to start the animation. Value must be ranging from 0 to 1. | ||
| -- @param boolean autokill Whether the gesture should stop automatically. | ||
| -- @realm client | ||
| -- @see https://wiki.facepunch.com/gmod/Player:AddVCDSequenceToGestureSlot | ||
| function plymeta:AddVCDSequenceToGestureSlot(slot, sequence, cycle, autokill) | ||
| -- depth > 0 means this call originates from TTT2's AnimApplyGesture and should not count as external | ||
| if (self._ttt2InternalGestureWriteDepth or 0) <= 0 then | ||
|
Comment on lines
+54
to
+55
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is never called from the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried to make it similar to |
||
| MarkExternalGesture(self, sequence) | ||
| end | ||
|
|
||
| return plymeta_old_AddVCDSequenceToGestureSlot(self, slot, sequence, cycle, autokill) | ||
| end | ||
| end | ||
|
|
||
| if not plymeta._ttt2WrappedAnimRestartGesture and isfunction(plymeta.AnimRestartGesture) then | ||
| plymeta._ttt2WrappedAnimRestartGesture = true | ||
|
|
||
| local plymeta_old_AnimRestartGesture = plymeta.AnimRestartGesture | ||
|
|
||
| --- | ||
| -- Wrapped version of @{Player:AnimRestartGesture} to track external gesture activity. | ||
| -- @param number slot The gesture slot. | ||
| -- @param ACT activity The @{ACT} that should be played. | ||
| -- @param boolean autokill Whether the gesture should stop automatically. | ||
| -- @realm client | ||
| -- @see https://wiki.facepunch.com/gmod/Player:AnimRestartGesture | ||
| function plymeta:AnimRestartGesture(slot, activity, autokill) | ||
| -- some addons use AnimRestartGesture -> map activity to sequence to track duration | ||
| if | ||
| (self._ttt2InternalGestureWriteDepth or 0) <= 0 | ||
| and isnumber(activity) | ||
| and activity >= 0 | ||
| then | ||
| local sequence = self:SelectWeightedSequence(activity) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I could not find how this is handled internally within GMOD, but this can be wrong, when the sequence here is different from the one that GMOD chooses when playing ACT gestures that hold multiple sequences. This is because you select one sequence at random here, you would need to pass this exact sequence to the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That makes sense. |
||
|
|
||
| MarkExternalGesture(self, sequence) | ||
| end | ||
|
|
||
| return plymeta_old_AnimRestartGesture(self, slot, activity, autokill) | ||
| end | ||
| end | ||
|
|
||
| --- | ||
| -- Returns whether an external gesture is currently active on this player. | ||
| -- @return boolean | ||
| -- @realm client | ||
| function plymeta:HasExternalGestureActive() | ||
| return (self.ttt2ExternalGestureEndTime or 0) > CurTime() | ||
| end | ||
|
|
||
| --- | ||
| -- Applies a animation gesture | ||
| -- @param ACT act The @{ACT} or sequence that should be played | ||
|
|
@@ -15,8 +104,11 @@ end | |
| -- @see https://wiki.facepunch.com/gmod/Player:AnimRestartGesture | ||
| -- @see https://wiki.facepunch.com/gmod/Player:AnimSetGestureWeight | ||
| function plymeta:AnimApplyGesture(act, weight) | ||
| self:AnimRestartGesture(GESTURE_SLOT_CUSTOM, act, true) -- true = autokill | ||
| self:AnimSetGestureWeight(GESTURE_SLOT_CUSTOM, weight) | ||
| -- prevent our own gesture writes from being treated as external | ||
| self._ttt2InternalGestureWriteDepth = (self._ttt2InternalGestureWriteDepth or 0) + 1 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This does not have to be a counter and can be a simple boolean flag.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, that can be simplified. |
||
| self:AnimRestartGesture(ttt2GestureSlot, act, true) -- true = autokill | ||
| self:AnimSetGestureWeight(ttt2GestureSlot, weight) | ||
| self._ttt2InternalGestureWriteDepth = math.max(0, self._ttt2InternalGestureWriteDepth - 1) | ||
| end | ||
|
|
||
| local function MakeSimpleRunner(act) | ||
|
|
@@ -37,6 +129,11 @@ local act_runner = { | |
| -- ear grab needs weight control | ||
| -- sadly it's currently the only one | ||
| [ACT_GMOD_IN_CHAT] = function(ply, w) | ||
| -- prevent voice chat ear grab gesture from interfering with active third-party gestures | ||
| if ply:HasExternalGestureActive() then | ||
| return 0 | ||
| end | ||
|
|
||
|
Comment on lines
+132
to
+136
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about all the other native gestures listed below in the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I forgot about them first and only did it for the voicechat because it was enabled by default and caused visual interference with the Custom Taunt gestures. |
||
| local dest = ply:IsSpeaking() and 1 or 0 | ||
|
|
||
| w = math.Approach(w, dest, FrameTime() * 10) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I cannot really understand the reasoning here. What is the intention of using the VCD slot?
GMOD and sandbox gamemode both default to the GESTUR_SLOT_CUSTOM.
Besides, those two slot variables are always defined, so i'd assume this or statement to not be effective at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was from my first iteration where I just tried a different slot and noticed that it began working again but not ideal because of the voice chat for example but I never changed it afterwards.
So yes, that can be changed again.