409 lines
13 KiB
Lua
409 lines
13 KiB
Lua
--[[
|
|
|
|
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 = { Standalone = true, Male = 15, Female = 15 },
|
|
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 = 99, Female = 51 },
|
|
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 = { Standalone = true, Male = 0, Female = 0 },
|
|
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 = 8,
|
|
Table = {
|
|
Standalone = true, Male = 15, Female = 15,
|
|
-- Extra = {
|
|
-- -- { Drawable = 8, Id = 15, Tex = 0, Name = "Extra Undershirt"},
|
|
-- { Drawable = 3, Id = 28, 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 = 14, Female = 47 },
|
|
Emote = { Dict = "re@construction", Anim = "out_of_breath", Move = 51, Dur = 1300 }
|
|
},
|
|
}
|
|
|
|
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()
|
|
local Ped = PlayerPedId()
|
|
for k,v in pairs(LastEquipped) do
|
|
if v then
|
|
if v.Ped == Ped then
|
|
if v.Drawable then
|
|
SendNUIMessage({
|
|
action = 'getallresets',
|
|
cloth = k,
|
|
})
|
|
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)
|
|
SendNUIMessage({
|
|
action = 'getallresets',
|
|
cloth = k,
|
|
})
|
|
end
|
|
else
|
|
print("Skipped "..k.." (Ped Changed)")
|
|
SendNUIMessage({
|
|
action = 'getallresets',
|
|
cloth = k,
|
|
})
|
|
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)
|
|
SendNUIMessage({
|
|
action = 'update',
|
|
cloth = which,
|
|
})
|
|
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
|
|
|
|
SendNUIMessage({
|
|
action = 'update2',
|
|
cloth = which,
|
|
})
|
|
|
|
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)
|
|
SendNUIMessage({
|
|
action = 'update',
|
|
cloth = which,
|
|
})
|
|
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}
|
|
if v.Drawable ~= ExtraCur.Drawable then
|
|
SetPedComponentVariation(Ped, v.Drawable, v.Id, v.Tex, 0)
|
|
|
|
LastEquipped[v.Name] = ExtraCur
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
return true
|
|
end
|
|
else
|
|
local Last = LastEquipped[which]
|
|
PlayToggleEmote(Toggle.Emote, function()
|
|
SetPedComponentVariation(Ped, Toggle.Drawable, Last.Drawable, Last.Texture, 0)
|
|
SendNUIMessage({
|
|
action = 'update2',
|
|
cloth = which,
|
|
})
|
|
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()
|
|
SendNUIMessage({
|
|
action = 'update',
|
|
cloth = which,
|
|
})
|
|
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()
|
|
SendNUIMessage({
|
|
action = 'update2',
|
|
cloth = which,
|
|
})
|
|
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) |