--[[ These are the tables for all the info we will need when dealing with the functions. ["Handle"] = { First we name it, this is the string that will be put in the command to be used with ToggleClothing, or ToggleProps. Drawable = 11, Then we assign its drawable/prop id. Table = Variations.Jackets, Then we assign its table found in Variations, if it has one, alternatively we can do. Table = { Standalone = true, Male = 34, Female = 35 }, Which makes it standalone, this example is for shoes, now when the player does the command it checks if they are currently wearing id 34. If they are not it takes the drawable off and saves the one they had equipped. Emote = { Hey lets do the Emote, Pretty self explanatory. Dict = "missmic4", This is the dict of the emote. Anim = "michael_tux_fidget", Anim of the emote. Move = 51, The move type of the emote, 51 is upper body only so you can move, 0 does not allow you to move. Dur = 1500 Duration of the emote. Alternatively for the props theres a seperate emote for taking off/putting on the prop. } }, ]]-- local Drawables = { ["Top"] = { Drawable = 11, Table = Variations.Jackets, Emote = {Dict = "missmic4", Anim = "michael_tux_fidget", Move = 51, Dur = 1500} }, ["Gloves"] = { Drawable = 3, Table = Variations.Gloves, Remember = true, Emote = {Dict = "nmt_3_rcm-10", Anim = "cs_nigel_dual-10", Move = 51, Dur = 1200} }, ["Shoes"] = { Drawable = 6, Table = {Standalone = true, Male = 34, Female = 35}, Emote = {Dict = "random@domestic", Anim = "pickup_low", Move = 0, Dur = 1200} }, ["Neck"] = { Drawable = 7, Table = {Standalone = true, Male = 0, Female = 0 }, Emote = {Dict = "clothingtie", Anim = "try_tie_positive_a", Move = 51, Dur = 2100} }, ["Vest"] = { Drawable = 9, Table = {Standalone = true, Male = 0, Female = 0 }, Emote = {Dict = "clothingtie", Anim = "try_tie_negative_a", Move = 51, Dur = 1200} }, ["Bag"] = { Drawable = 5, Table = Variations.Bags, Emote = {Dict = "anim@heists@ornate_bank@grab_cash", Anim = "intro", Move = 51, Dur = 1600} }, ["Mask"] = { Drawable = 1, Table = {Standalone = true, Male = 0, Female = 0 }, Emote = {Dict = "mp_masks@standard_car@ds@", Anim = "put_on_mask", Move = 51, Dur = 800} }, ["Hair"] = { Drawable = 2, Table = Variations.Hair, Remember = true, Emote = {Dict = "clothingtie", Anim = "check_out_a", Move = 51, Dur = 2000} }, } local Extras = { ["Shirt"] = { Drawable = 11, Table = { Standalone = true, Male = 252, Female = 74, Extra = { {Drawable = 8, Id = 15, Tex = 0, Name = "Extra Undershirt"}, {Drawable = 3, Id = 15, Tex = 0, Name = "Extra Gloves"}, {Drawable = 10, Id = 0, Tex = 0, Name = "Extra Decals"}, } }, Emote = {Dict = "clothingtie", Anim = "try_tie_negative_a", Move = 51, Dur = 1200} }, ["Pants"] = { Drawable = 4, Table = {Standalone = true, Male = 61, Female = 14}, Emote = {Dict = "re@construction", Anim = "out_of_breath", Move = 51, Dur = 1300} }, ["Bagoff"] = { Drawable = 5, Table = {Standalone = true, Male = 0, Female = 0}, Emote = {Dict = "clothingtie", Anim = "try_tie_negative_a", Move = 51, Dur = 1200} }, } local Props = { ["Visor"] = { Prop = 0, Variants = Variations.Visor, Emote = { On = {Dict = "mp_masks@standard_car@ds@", Anim = "put_on_mask", Move = 51, Dur = 600}, Off = {Dict = "missheist_agency2ahelmet", Anim = "take_off_helmet_stand", Move = 51, Dur = 1200} } }, ["Hat"] = { Prop = 0, Emote = { On = {Dict = "mp_masks@standard_car@ds@", Anim = "put_on_mask", Move = 51, Dur = 600}, Off = {Dict = "missheist_agency2ahelmet", Anim = "take_off_helmet_stand", Move = 51, Dur = 1200} } }, ["Glasses"] = { Prop = 1, Emote = { On = {Dict = "clothingspecs", Anim = "take_off", Move = 51, Dur = 1400}, Off = {Dict = "clothingspecs", Anim = "take_off", Move = 51, Dur = 1400} } }, ["Ear"] = { Prop = 2, Emote = { On = {Dict = "mp_cp_stolen_tut", Anim = "b_think", Move = 51, Dur = 900}, Off = {Dict = "mp_cp_stolen_tut", Anim = "b_think", Move = 51, Dur = 900} } }, ["Watch"] = { Prop = 6, Emote = { On = {Dict = "nmt_3_rcm-10", Anim = "cs_nigel_dual-10", Move = 51, Dur = 1200}, Off = {Dict = "nmt_3_rcm-10", Anim = "cs_nigel_dual-10", Move = 51, Dur = 1200} } }, ["Bracelet"] = { Prop = 7, Emote = { On = {Dict = "nmt_3_rcm-10", Anim = "cs_nigel_dual-10", Move = 51, Dur = 1200}, Off = {Dict = "nmt_3_rcm-10", Anim = "cs_nigel_dual-10", Move = 51, Dur = 1200} } }, } LastEquipped = {} Cooldown = false local function PlayToggleEmote(e, cb) local Ped = PlayerPedId() while not HasAnimDictLoaded(e.Dict) do RequestAnimDict(e.Dict) Wait(100) end if IsPedInAnyVehicle(Ped) then e.Move = 51 end TaskPlayAnim(Ped, e.Dict, e.Anim, 3.0, 3.0, e.Dur, e.Move, 0, false, false, false) local Pause = e.Dur-500 if Pause < 500 then Pause = 500 end IncurCooldown(Pause) Wait(Pause) -- Lets wait for the emote to play for a bit then do the callback. cb() end function ResetClothing(anim) local Ped = PlayerPedId() local e = Drawables.Top.Emote if anim then TaskPlayAnim(Ped, e.Dict, e.Anim, 3.0, 3.0, 3000, e.Move, 0, false, false, false) end for k,v in pairs(LastEquipped) do if v then if v.Drawable then SetPedComponentVariation(Ped, v.Id, v.Drawable, v.Texture, 0) elseif v.Prop then ClearPedProp(Ped, v.Id) SetPedPropIndex(Ped, v.Id, v.Prop, v.Texture, true) end end end LastEquipped = {} end function ToggleClothing(which, extra) if Cooldown then return end local Toggle = Drawables[which] if extra then Toggle = Extras[which] end local Ped = PlayerPedId() local Cur = { -- Lets check what we are currently wearing. Drawable = GetPedDrawableVariation(Ped, Toggle.Drawable), Id = Toggle.Drawable, Ped = Ped, Texture = GetPedTextureVariation(Ped, Toggle.Drawable), } local Gender = IsMpPed(Ped) if which ~= "Mask" then if not Gender then Notify(Lang("NotAllowedPed")) return false end -- We cancel the command here if the person is not using a multiplayer model. end local Table = Toggle.Table[Gender] if not Toggle.Table.Standalone then -- "Standalone" is for things that dont require a variant, like the shoes just need to be switched to a specific drawable. Looking back at this i should have planned ahead, but it all works so, meh! for k,v in pairs(Table) do if not Toggle.Remember then if k == Cur.Drawable then PlayToggleEmote(Toggle.Emote, function() SetPedComponentVariation(Ped, Toggle.Drawable, v, Cur.Texture, 0) end) return true end else if not LastEquipped[which] then if k == Cur.Drawable then PlayToggleEmote(Toggle.Emote, function() LastEquipped[which] = Cur SetPedComponentVariation(Ped, Toggle.Drawable, v, Cur.Texture, 0) end) return true end else local Last = LastEquipped[which] PlayToggleEmote(Toggle.Emote, function() SetPedComponentVariation(Ped, Toggle.Drawable, Last.Drawable, Last.Texture, 0) LastEquipped[which] = false end) return true end end end Notify(Lang("NoVariants")) return else if not LastEquipped[which] then if Cur.Drawable ~= Table then PlayToggleEmote(Toggle.Emote, function() LastEquipped[which] = Cur SetPedComponentVariation(Ped, Toggle.Drawable, Table, 0, 0) if Toggle.Table.Extra then local Extras = Toggle.Table.Extra for k,v in pairs(Extras) do local ExtraCur = {Drawable = GetPedDrawableVariation(Ped, v.Drawable), Texture = GetPedTextureVariation(Ped, v.Drawable), Id = v.Drawable} SetPedComponentVariation(Ped, v.Drawable, v.Id, v.Tex, 0) LastEquipped[v.Name] = ExtraCur end end end) return true end else local Last = LastEquipped[which] PlayToggleEmote(Toggle.Emote, function() SetPedComponentVariation(Ped, Toggle.Drawable, Last.Drawable, Last.Texture, 0) LastEquipped[which] = false if Toggle.Table.Extra then local Extras = Toggle.Table.Extra for k,v in pairs(Extras) do if LastEquipped[v.Name] then local Last = LastEquipped[v.Name] SetPedComponentVariation(Ped, Last.Id, Last.Drawable, Last.Texture, 0) LastEquipped[v.Name] = false end end end end) return true end end Notify(Lang("AlreadyWearing")) return false end function ToggleProps(which) if Cooldown then return end local Prop = Props[which] local Ped = PlayerPedId() local Gender = IsMpPed(Ped) local Cur = { -- Lets get out currently equipped prop. Id = Prop.Prop, Ped = Ped, Prop = GetPedPropIndex(Ped, Prop.Prop), Texture = GetPedPropTextureIndex(Ped, Prop.Prop), } if not Prop.Variants then if Cur.Prop ~= -1 then -- If we currently are wearing this prop, remove it and save the one we were wearing into the LastEquipped table. PlayToggleEmote(Prop.Emote.Off, function() LastEquipped[which] = Cur ClearPedProp(Ped, Prop.Prop) end) return true else local Last = LastEquipped[which] -- Detect that we have already taken our prop off, lets put it back on. if Last then PlayToggleEmote(Prop.Emote.On, function() SetPedPropIndex(Ped, Prop.Prop, Last.Prop, Last.Texture, true) end) LastEquipped[which] = false return true end end Notify(Lang("NothingToRemove")) return false else local Gender = IsMpPed(Ped) if not Gender then Notify(Lang("NotAllowedPed")) return false end -- We dont really allow for variants on ped models, Its possible, but im pretty sure 95% of ped models dont really have variants. local Variations = Prop.Variants[Gender] for k,v in pairs(Variations) do if Cur.Prop == k then PlayToggleEmote(Prop.Emote.On, function() SetPedPropIndex(Ped, Prop.Prop, v, Cur.Texture, true) end) return true end end Notify(Lang("NoVariants")) return false end end function DrawDev() -- Draw text for all the stuff we are wearing, to make grabbing the variants of stuff much simpler for people. local Entries = {} for k,v in PairsKeys(Drawables) do table.insert(Entries, { Name = k, Drawable = v.Drawable }) end for k,v in PairsKeys(Extras) do table.insert(Entries, { Name = k, Drawable = v.Drawable }) end for k,v in PairsKeys(Props) do table.insert(Entries, { Name = k, Prop = v.Prop }) end for k,v in pairs(Entries) do local Ped = PlayerPedId() local Cur if v.Drawable then Cur = { Id = GetPedDrawableVariation(Ped, v.Drawable), Texture = GetPedTextureVariation(Ped, v.Drawable) } elseif v.Prop then Cur = { Id = GetPedPropIndex(Ped, v.Prop), Texture = GetPedPropTextureIndex(Ped, v.Prop) } end Text(0.2, 0.8*k/18, 0.30, "~o~"..v.Name.."~w~ = \n ("..Cur.Id.." , "..Cur.Texture..")", false, 1) DrawRect(0.23, 0.8*k/18+0.025, 0.07, 0.045, 0, 0, 0, 150) end end local TestThreadActive = nil function DevTestVariants(d) -- If debug mode is enabled we can try all the variants to check for scuff. if not TestThreadActive then Citizen.CreateThread(function() TestThreadActive = true local Ped = PlayerPedId() local Drawable = Drawables[d] local Prop = Props[d] local Gender = IsMpPed(Ped) if Drawable then if Drawable.Table then if type(Drawable.Table[Gender]) == "table" then for k,v in PairsKeys(Drawable.Table[Gender]) do Notify(d.." : ~o~"..k) SoundPlay("Open") SetPedComponentVariation(Ped, Drawable.Drawable, k, 0, 0) Wait(300) Notify(d.." : ~b~"..v) SoundPlay("Close") SetPedComponentVariation(Ped, Drawable.Drawable, v, 0, 0) Wait(300) end end end elseif Prop then if Prop.Variants then for k,v in PairsKeys(Prop.Variants[Gender]) do Notify(d.." : ~o~"..k) SoundPlay("Open") SetPedPropIndex(Ped, Prop.Prop, k, 0, true) Wait(300) Notify(d.." : ~b~"..v) SoundPlay("Close") SetPedPropIndex(Ped, Prop.Prop, v, 0, true) Wait(300) ClearPedProp(Ped, Prop.Prop) Wait(200) end end end TestThreadActive = false end) else Notify("Already testing variants.") end end for k,v in pairs(Config.Commands) do RegisterCommand(k, v.Func) --log("Created /"..k.." ("..v.Desc..")") -- Useful for translation checking. TriggerEvent("chat:addSuggestion", "/"..k, v.Desc) end if Config.ExtrasEnabled then for k,v in pairs(Config.ExtraCommands) do RegisterCommand(k, v.Func) --log("Created /"..k.." ("..v.Desc..")") -- Useful for translation checking. TriggerEvent("chat:addSuggestion", "/"..k, v.Desc) end end AddEventHandler('onResourceStop', function(resource) -- Mostly for development, restart the resource and it will put all the clothes back on. if resource == GetCurrentResourceName() then ResetClothing() end end)