Facepunch / garrysmod-issues

Garry's Mod issue tracker
147 stars 56 forks source link

If looped animation has 0-6 sequence index, it won't be looped #3229

Closed DBotThePony closed 4 years ago

DBotThePony commented 7 years ago

Code to reproduce


local SWEP = {}

SWEP.PrintName = 'Bug Display'
SWEP.Author = 'DBot'
SWEP.Spawnable = true
SWEP.AdminSpawnable = true

SWEP.ViewModel = 'models/weapons/c_models/c_soldier_arms.mdl'
SWEP.WorldModel = 'models/weapons/c_models/c_rocketlauncher/c_rocketlauncher.mdl'
SWEP.UseHands = false

function SWEP:Initialize()
    self.nextTestAnim = 0
    self.nextAnimChange = CurTime() + 1
end

function SWEP:SetupDataTables()
    self:NetworkVar('Entity', 0, 'TF2WeaponModel')
end

function SWEP:Deploy()
    if SERVER and not IsValid(self.viewModel) then
        self.viewModel = ents.Create('gmod_hands')
        local ent = self.viewModel
        ent:SetPos(self:GetPos())
        ent:SetModel(self.WorldModel)
        ent:Spawn()
        ent:Activate()
        ent:SetParent(self:GetOwner():GetViewModel())
        ent:AddEffects(EF_BONEMERGE)
        self:DeleteOnRemove(ent)
        self:SetTF2WeaponModel(ent)
    end

    return true
end

function SWEP:PostDrawViewModel()
    if IsValid(self:GetTF2WeaponModel()) then
        self:GetTF2WeaponModel():SetNoDraw(true)
        self:GetTF2WeaponModel():DrawModel()
    end
end

function SWEP:Think()
    if CLIENT then return end
    if self.nextAnimChange > CurTime() then return end
    self.nextAnimChange = CurTime() + 1
    if self.nextTestAnim < 4 then
        self:GetOwner():GetViewModel():SendViewModelMatchingSequence(6) -- dh_reload_loop
        self.nextTestAnim = self.nextTestAnim + 1
    else
        self.nextTestAnim = 0
        self:GetOwner():GetViewModel():SendViewModelMatchingSequence(0)
    end
end

function SWEP:OnRemove()
    if IsValid(self.viewModel) then
        self.viewModel:Remove()
    end
end

weapons.Register(SWEP, 'rocket_launcher_bug')

Animation just stucks after it finishes playing, while it should re-play itself with animations and sound. When i re-play animation manually, it visually doesn't play, but sound still plays. If looped animation has sequence index higher than 6 (found by bruteforce tests), it doesn't require to be even restarted manually, it loops itself with visuals and sound.

If you put if SERVER then return end instead of if CLIENT then return end, animation would not play at all.

robotboy655 commented 4 years ago

It's essentially another prediction issue. What you want to do is run SendViewModelMatchingSequence on both client and server in a predicted manner, then it works properly. It's due to the "interpolation" of the view model cycle (Set/GetCycle), essentially making the cycle get stuck on last frame, because an internal variable does not get reset in mutliplayer.

I have committed a fix for this, but I am not sure it won't cause issues elsewhere. Didn't find any regressions in my testing though.

I could not reproduce any specific sequence index related issues.