· 7 years ago · Feb 08, 2019, 01:34 AM
1--[[
2
3 Uniform Handler
4
5 This script runs the automated uniform feature for the game. All of the
6 actual uniform settings are contained in ModuleScript objects which are
7 loaded when the game starts.
8
9 Created by RBX_Lua - 2/6/19
10--]]
11
12local MarketplaceService = game:GetService("MarketplaceService")
13
14local uniformSettings = script.UniformSettings
15
16local COMMAND_SYNTAX = ":uniform"
17
18--[[
19 Load Modules
20--]]
21
22local settingsModules = {}
23
24--[[
25 loadSettingsModule(ModuleScript object)
26
27 Responsible for requiring the @object ModuleScript object and adding it
28 to the table of settings modules.
29--]]
30function loadSettingModule(object)
31
32 local newModule = require(object)
33
34 if newModule then
35 table.insert(settingsModules, newModule)
36 end
37
38end
39
40--[[
41 loadSettings()
42
43 Responsible for collecting all of the ModuleScript children of UniformSettings
44 and loading them. Loads each module in a separate thread.
45--]]
46function loadSettings()
47 for int, object in pairs(uniformSettings:GetChildren()) do
48
49 if object:IsA("ModuleScript") then
50 pcall(function() -- Load the module in a separate thread to prevent an error from stopping this loop
51 loadSettingModule(object)
52 end)
53 end
54
55 end
56end
57
58--[[
59 Outfit Handling
60--]]
61
62--[[
63 getHighestOutfitRank(Player player, Table module)
64
65 Gets the player's rank in a given group based on @module and determines the highest ranking outfit
66 the player can wear. Returns the (int) rank of the outfit.
67--]]
68function getHighestOutfitRank(player, module)
69
70 local playerRank = player:GetRankInGroup(module.groupId) -- Get the player's rank in the given group
71
72 if playerRank and playerRank >= 1 then -- Make sure that the player is at least a first-rank member of the group
73
74 local rankTable = {}
75
76 -- Create a table of outfits with lower ranks
77 for int, outfit in pairs(module.outfits) do
78 if outfit.rank <= playerRank then
79 table.insert(rankTable, outfit.rank)
80 end
81 end
82
83 -- Determine the outfit with the highest rank
84 local highestRank = math.max(unpack(rankTable))
85
86 print("Highest outfit rank: " .. highestRank)
87
88 return highestRank
89 end
90
91end
92
93--[[
94 getOutfitByRank(Table module, int rank)
95
96 Returns the (first) outfit table in the provided module with the given rank.
97--]]
98function getOutfitByRank(module, rank)
99
100 for int, outfit in pairs(module.outfits) do
101
102 if outfit.rank == rank then
103 return outfit
104 end
105
106 end
107
108end
109
110--[[
111 Avatar Clothing
112--]]
113
114--[[
115 getclothingAsset(int assetId)
116
117 Uses MarketplaceService to verify that the asset is a shirt, pants, hat, or accessory. When
118 that is verified, loads and returns the asset using InsertService.
119--]]
120function getClothingAsset(assetId)
121
122 local assetInfo = MarketplaceService:GetProductInfo(assetId)
123
124 if assetInfo then
125
126 -- Make sure the asset is shirt, pants, or accessory
127 if assetInfo.AssetTypeId == 11 or assetInfo.AssetTypeId == 12 or assetInfo.AssetTypeId == 8 or assetInfo.AssetTypeId >= 41 and assetInfo.AssetTypeId <= 47 then
128
129 -- Return the asset loaded into the game
130 return game:GetService("InsertService"):LoadAsset(assetId):GetChildren()[1]
131
132 end
133
134 end
135
136end
137
138--[[
139 equipShirt(Model character, int shirtId)
140
141 Loads the Shirt asset with the given shirtId, destroys the player's current Shirt, and equips the new one
142--]]
143function equipShirt(character, shirtId)
144
145 -- Get existing shirt
146 local shirt = character:FindFirstChild("Shirt")
147
148 -- Load and equip new shirt
149 local shirtAsset = getClothingAsset(shirtId)
150
151 if shirtAsset then
152
153 -- Remove existing shirt AFTER we know that the asset has loaded. To comply with Roblox character standards.
154 if shirt then
155 shirt:Destroy()
156 end
157
158 shirtAsset.Parent = character
159 end
160
161end
162
163--[[
164 equipPants(Model character, int pantsId)
165
166 Loads the Shirt asset with the given shirtId, destroys the player's current Shirt, and equips the new one
167--]]
168function equipPants(character, pantsId)
169
170 -- Get existing pants
171 local pants = character:FindFirstChild("Pants")
172
173 -- Load and equip new pants
174 local pantsAsset = getClothingAsset(pantsId)
175
176 if pantsAsset then
177
178 -- Remove existing pants AFTER we know that the asset has loaded. To comply with Roblox character standards.
179 if pants then
180 pants:Destroy()
181 end
182
183 pantsAsset.Parent = character
184 end
185
186end
187
188--[[
189 Avatar Accessories
190--]]
191
192--[[
193 removeAccessories(Model character)
194
195 Removes any accessory class children of the model passed to @character.
196--]]
197function removeAccessories(character)
198
199 for int, object in pairs(character:GetChildren()) do
200 if object:IsA("Accessory") then
201 object:Destroy()
202 end
203 end
204
205end
206
207--[[
208 equipHat(Model character, int hatId)
209
210 Loads the Roblox hat with the given @hatId value; equips it to the character.
211--]]
212function equipHat(character, hatId)
213
214 local newHat = getClothingAsset(hatId)
215
216 if newHat then
217 character.Humanoid:AddAccessory(newHat)
218 end
219
220end
221
222
223--[[
224 loadOutfit(Player player, table outfitTable)
225
226 Sorts through all of the properties of a @outfitTable and loads all of the provided assets.
227--]]
228function loadOutfit(player, outfitTable)
229
230 local character = player.Character
231
232 if character and not character:FindFirstChild("CharacterLoaded") then
233
234 if outfitTable.shirtId then
235 equipShirt(character, outfitTable.shirtId)
236 end
237
238 if outfitTable.shirtId then
239 equipPants(character, outfitTable.pantsId)
240 end
241
242 if outfitTable.hats and #outfitTable.hats > 0 then
243
244 removeAccessories(character)
245
246 for int, hatId in pairs(outfitTable.hats) do
247 equipHat(character, hatId)
248 end
249
250 end
251
252 Instance.new("Folder", character).Name = "CharacterLoaded"
253
254 end
255
256end
257
258--[[
259 Module Matching
260--]]
261
262--[[
263 getModuleById(int groupId)
264
265 Returns the module, if one exists, with the provided @groupId value.
266--]]
267function getModuleById(groupId)
268 for int, module in pairs(settingsModules) do
269
270 if tostring(module.groupId) == tostring(groupId) then
271 return module
272 end
273
274 end
275end
276
277--[[
278 getModuleByName(string groupName)
279
280 Returns the module, if one exists, with the provided @groupName value.
281--]]
282function getModuleByName(groupName)
283 for int, module in pairs(settingsModules) do
284
285 if tostring(module.groupName) == tostring(groupName) then
286
287 print("Found maching module")
288
289 return module
290
291 else
292 print("groupName of " .. module.groupName .. " is not the same as requested groupName of " .. groupName)
293 end
294
295 end
296end
297
298--[[
299 Player and Command Handling
300--]]
301
302game.Players.PlayerAdded:Connect(function(player)
303 player.Chatted:Connect(function(message)
304
305 local cmdString = string.sub(message, 1, string.len(COMMAND_SYNTAX)) -- Get the first few characters of the message to verify that it matches our command
306
307 if cmdString == COMMAND_SYNTAX then -- check that the subtracted string contains our command
308 local groupId = string.sub(message, (string.len(COMMAND_SYNTAX) + 2))
309
310 if groupId and string.len(groupId) >= 1 then -- Make sure the groupId exists before we bother checking
311
312 local groupModule = getModuleById(groupId) or getModuleByName(groupId)
313
314 if groupModule then
315
316 local outfitTable = getOutfitByRank(groupModule, getHighestOutfitRank(player, groupModule))
317
318 loadOutfit(player, outfitTable)
319
320 end
321
322 end
323 end
324
325 end)
326end)
327
328--[[
329 Init
330--]]
331
332loadSettings()