@quenty/bodycolorsutils 1.0.1-canary.345.60686f2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ## 1.0.1-canary.345.60686f2.0 (2023-03-31)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * Fix body color serialization and add additional attribute support ([4490c02](https://github.com/Quenty/NevermoreEngine/commit/4490c02d990b9531ef6f4a49340be06a26f1ee52))
12
+
13
+
14
+ ### Features
15
+
16
+ * Add baseline bodycolors package ([04cb07f](https://github.com/Quenty/NevermoreEngine/commit/04cb07fa0ae789f1534ea4310120c2dde97c1d4e))
17
+ * Add BodyColorsDataUtils ([80aa539](https://github.com/Quenty/NevermoreEngine/commit/80aa53906a1ff4e3a736fd4a3cacc861b047c6e5))
18
+ * Add RxBodyColorDataUtils ([2eb64e2](https://github.com/Quenty/NevermoreEngine/commit/2eb64e24f643a75e926eb32cc35775a2da7e1196))
19
+ * Add serialization ([f08cbce](https://github.com/Quenty/NevermoreEngine/commit/f08cbce0e807ec1c911b48f88cd3c34dbefc11a3))
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2014-2023 James Onnen (Quenty)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,23 @@
1
+ ## BodyColorsUtils
2
+
3
+ <div align="center">
4
+ <a href="http://quenty.github.io/NevermoreEngine/">
5
+ <img src="https://github.com/Quenty/NevermoreEngine/actions/workflows/docs.yml/badge.svg" alt="Documentation status" />
6
+ </a>
7
+ <a href="https://discord.gg/mhtGUS8">
8
+ <img src="https://img.shields.io/discord/385151591524597761?color=5865F2&label=discord&logo=discord&logoColor=white" alt="Discord" />
9
+ </a>
10
+ <a href="https://github.com/Quenty/NevermoreEngine/actions">
11
+ <img src="https://github.com/Quenty/NevermoreEngine/actions/workflows/build.yml/badge.svg" alt="Build and release status" />
12
+ </a>
13
+ </div>
14
+
15
+ Body color helper utilities for merging and representing body colors over the network and datastore
16
+
17
+ <div align="center"><a href="https://quenty.github.io/NevermoreEngine/api/BodyColorsDataUtils">View docs →</a></div>
18
+
19
+ ## Installation
20
+
21
+ ```
22
+ npm install @quenty/bodycolorsutils --save
23
+ ```
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "bodycolorsutils",
3
+ "tree": {
4
+ "$path": "src"
5
+ }
6
+ }
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@quenty/bodycolorsutils",
3
+ "version": "1.0.1-canary.345.60686f2.0",
4
+ "description": "Body color helper utilities for merging and representing body colors over the network and datastore",
5
+ "keywords": [
6
+ "Roblox",
7
+ "Nevermore",
8
+ "Lua",
9
+ "bodycolorutils"
10
+ ],
11
+ "bugs": {
12
+ "url": "https://github.com/Quenty/NevermoreEngine/issues"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/Quenty/NevermoreEngine.git",
17
+ "directory": "src/bodycolorsutils/"
18
+ },
19
+ "funding": {
20
+ "type": "patreon",
21
+ "url": "https://www.patreon.com/quenty"
22
+ },
23
+ "license": "MIT",
24
+ "contributors": [
25
+ "Quenty"
26
+ ],
27
+ "dependencies": {
28
+ "@quenty/attributeutils": "8.8.0",
29
+ "@quenty/color3serializationutils": "2.1.0",
30
+ "@quenty/color3utils": "5.12.1-canary.345.60686f2.0",
31
+ "@quenty/loader": "6.2.0",
32
+ "@quenty/rx": "7.7.0",
33
+ "@quenty/table": "3.2.0"
34
+ },
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "gitHead": "60686f2af2e3db9a768ca47d2636bf84ea263494"
39
+ }
@@ -0,0 +1,18 @@
1
+ --[=[
2
+ @class BodyColorsDataConstants
3
+ ]=]
4
+
5
+ local require = require(script.Parent.loader).load(script)
6
+
7
+ local Table = require("Table")
8
+
9
+ return Table.readonly({
10
+ ATTRIBUTE_MAPPING = {
11
+ headColor = "HeadColor";
12
+ leftArmColor = "LeftArmColor";
13
+ leftLegColor = "LeftLegColor";
14
+ rightArmColor = "RightArmColor";
15
+ rightLegColor = "RightLegColor";
16
+ torsoColor = "TorsoColor";
17
+ };
18
+ })
@@ -0,0 +1,326 @@
1
+ --[=[
2
+ Utility to transfer and manipulate body colors for a character
3
+
4
+ @class BodyColorsDataUtils
5
+ ]=]
6
+
7
+ local require = require(script.Parent.loader).load(script)
8
+
9
+ local Color3Utils = require("Color3Utils")
10
+ local Color3SerializationUtils = require("Color3SerializationUtils")
11
+ local BodyColorsDataConstants = require("BodyColorsDataConstants")
12
+
13
+ local BodyColorsDataUtils = {}
14
+
15
+ --[=[
16
+ Represents body colors data for a humanoid
17
+
18
+ @interface BodyColorsData
19
+ .headColor Color3
20
+ .leftArmColor Color3
21
+ .leftLegColor Color3
22
+ .rightArmColor Color3
23
+ .rightLegColor Color3
24
+ .torsoColor Color3
25
+ @within BodyColorsDataUtils
26
+ ]=]
27
+
28
+ --[=[
29
+ Creates a new BodyColorsData
30
+ @param bodyColorsData any
31
+ @return BodyColorsData
32
+ ]=]
33
+ function BodyColorsDataUtils.createBodyColorsData(bodyColorsData)
34
+ assert(BodyColorsDataUtils.isBodyColorsData(bodyColorsData), "Bad bodyColorsData")
35
+
36
+ return bodyColorsData
37
+ end
38
+
39
+ --[=[
40
+ Returns true if it's a body color data
41
+ @param value any
42
+ @return boolean
43
+ ]=]
44
+ function BodyColorsDataUtils.isBodyColorsData(value)
45
+ return type(value) == "table"
46
+ and (typeof(value.headColor) == "Color3" or value.headColor == nil)
47
+ and (typeof(value.leftArmColor) == "Color3" or value.leftArmColor == nil)
48
+ and (typeof(value.leftLegColor) == "Color3" or value.leftLegColor == nil)
49
+ and (typeof(value.rightArmColor) == "Color3" or value.rightArmColor == nil)
50
+ and (typeof(value.rightLegColor) == "Color3" or value.rightLegColor == nil)
51
+ and (typeof(value.torsoColor) == "Color3" or value.torsoColor == nil)
52
+ end
53
+
54
+ --[=[
55
+ Creates a new BodyColorsData from a single color
56
+
57
+ @param color3 Color3
58
+ @return BodyColorsData
59
+ ]=]
60
+ function BodyColorsDataUtils.fromSingleColor(color3)
61
+ assert(typeof(color3) == "Color3", "Bad color3")
62
+
63
+ return BodyColorsDataUtils.createBodyColorsData({
64
+ headColor = color3;
65
+ leftArmColor = color3;
66
+ leftLegColor = color3;
67
+ rightArmColor = color3;
68
+ rightLegColor = color3;
69
+ torsoColor = color3;
70
+ })
71
+ end
72
+
73
+ --[=[
74
+ Creates a new BodyColorsData from a BodyColors instance
75
+
76
+ @param bodyColors BodyColors
77
+ @return BodyColorsData
78
+ ]=]
79
+ function BodyColorsDataUtils.fromBodyColors(bodyColors)
80
+ assert(typeof(bodyColors) == "Instance" and bodyColors:IsA("BodyColors"), "Bad bodyColors")
81
+
82
+ return BodyColorsDataUtils.createBodyColorsData({
83
+ headColor = bodyColors.HeadColor3;
84
+ leftArmColor = bodyColors.LeftArmColor3;
85
+ leftLegColor = bodyColors.LeftLegColor3;
86
+ rightArmColor = bodyColors.RightArmColor3;
87
+ rightLegColor = bodyColors.RightLegColor3;
88
+ torsoColor = bodyColors.TorsoColor3;
89
+ })
90
+ end
91
+
92
+ --[=[
93
+ Returns true if the data is a datastore safe body color
94
+ @param value any
95
+ @return boolean
96
+ ]=]
97
+ function BodyColorsDataUtils.isDataStoreSafeBodyColorsData(value)
98
+ return type(value) == "table"
99
+ and (Color3SerializationUtils.isSerializedColor3(value.headColor) or value.headColor == nil)
100
+ and (Color3SerializationUtils.isSerializedColor3(value.leftArmColor) or value.leftArmColor == nil)
101
+ and (Color3SerializationUtils.isSerializedColor3(value.leftLegColor) or value.leftLegColor == nil)
102
+ and (Color3SerializationUtils.isSerializedColor3(value.rightArmColor) or value.rightArmColor == nil)
103
+ and (Color3SerializationUtils.isSerializedColor3(value.rightLegColor) or value.rightLegColor == nil)
104
+ and (Color3SerializationUtils.isSerializedColor3(value.torsoColor) or value.torsoColor == nil)
105
+ end
106
+
107
+ --[=[
108
+ Gets a datastore safe version of body color
109
+ @param bodyColorsData BodyColorsData
110
+ @return DataStoreSafeBodyColorsData
111
+ ]=]
112
+ function BodyColorsDataUtils.toDataStoreSafeBodyColorsData(bodyColorsData)
113
+ assert(BodyColorsDataUtils.isBodyColorsData(bodyColorsData), "Bad bodyColorsData")
114
+
115
+ return {
116
+ headColor = bodyColorsData.headColor and Color3SerializationUtils.serialize(bodyColorsData.headColor) or nil;
117
+ leftArmColor = bodyColorsData.leftArmColor and Color3SerializationUtils.serialize(bodyColorsData.leftArmColor) or nil;
118
+ leftLegColor = bodyColorsData.leftLegColor and Color3SerializationUtils.serialize(bodyColorsData.leftLegColor) or nil;
119
+ rightArmColor = bodyColorsData.rightArmColor and Color3SerializationUtils.serialize(bodyColorsData.rightArmColor) or nil;
120
+ rightLegColor = bodyColorsData.rightLegColor and Color3SerializationUtils.serialize(bodyColorsData.rightLegColor) or nil;
121
+ torsoColor = bodyColorsData.torsoColor and Color3SerializationUtils.serialize(bodyColorsData.torsoColor) or nil;
122
+ }
123
+ end
124
+
125
+ function BodyColorsDataUtils.fromDataStoreSafeBodyColorsData(data)
126
+ assert(BodyColorsDataUtils.isDataStoreSafeBodyColorsData(data), "Bad dataStoreSafeBodyColorsData")
127
+
128
+ return BodyColorsDataUtils.createBodyColorsData({
129
+ headColor = data.headColor and Color3SerializationUtils.deserialize(data.headColor) or nil;
130
+ leftArmColor = data.leftArmColor and Color3SerializationUtils.deserialize(data.leftArmColor) or nil;
131
+ leftLegColor = data.leftLegColor and Color3SerializationUtils.deserialize(data.leftLegColor) or nil;
132
+ rightArmColor = data.rightArmColor and Color3SerializationUtils.deserialize(data.rightArmColor) or nil;
133
+ rightLegColor = data.rightLegColor and Color3SerializationUtils.deserialize(data.rightLegColor) or nil;
134
+ torsoColor = data.torsoColor and Color3SerializationUtils.deserialize(data.torsoColor) or nil;
135
+ })
136
+ end
137
+
138
+ --[=[
139
+ Constructs a BodyColorsData from a humanoidDescription
140
+
141
+ @param humanoidDescription HumanoidDescription
142
+ @return BodyColorsData
143
+ ]=]
144
+ function BodyColorsDataUtils.fromHumanoidDescription(humanoidDescription)
145
+ assert(typeof(humanoidDescription) == "Instance" and humanoidDescription:IsA("HumanoidDescription"), "Bad humanoidDescription")
146
+
147
+ return BodyColorsDataUtils.createBodyColorsData({
148
+ headColor = humanoidDescription.HeadColor;
149
+ leftArmColor = humanoidDescription.LeftArmColor;
150
+ leftLegColor = humanoidDescription.LeftLegColor;
151
+ rightArmColor = humanoidDescription.RightArmColor;
152
+ rightLegColor = humanoidDescription.RightLegColor;
153
+ torsoColor = humanoidDescription.TorsoColor;
154
+ })
155
+ end
156
+
157
+ --[=[
158
+ Returns if the body colors data represents one solid color for all body parts.
159
+
160
+ @param bodyColorsData BodyColorsData
161
+ @return boolean
162
+ ]=]
163
+ function BodyColorsDataUtils.isSingleColor(bodyColorsData)
164
+ assert(BodyColorsDataUtils.isBodyColorsData(bodyColorsData), "Bad bodyColorsData")
165
+
166
+ local headColor = bodyColorsData.headColor
167
+ if headColor == nil then
168
+ return false
169
+ end
170
+
171
+ if bodyColorsData.leftArmColor == nil or not Color3Utils.areEqual(headColor, bodyColorsData.leftArmColor) then
172
+ return false
173
+ end
174
+
175
+ if bodyColorsData.leftLegColor == nil or not Color3Utils.areEqual(headColor, bodyColorsData.leftLegColor) then
176
+ return false
177
+ end
178
+
179
+ if bodyColorsData.rightArmColor == nil or not Color3Utils.areEqual(headColor, bodyColorsData.rightArmColor) then
180
+ return false
181
+ end
182
+
183
+ if bodyColorsData.rightLegColor == nil or not Color3Utils.areEqual(headColor, bodyColorsData.rightLegColor) then
184
+ return false
185
+ end
186
+
187
+ if bodyColorsData.torsoColor == nil or not Color3Utils.areEqual(headColor, bodyColorsData.torsoColor) then
188
+ return false
189
+ end
190
+
191
+ return true
192
+ end
193
+
194
+ --[=[
195
+ Constructs a BodyColors from the bodyColorsData
196
+
197
+ @param bodyColorsData BodyColorsData
198
+ @return BodyColors
199
+ ]=]
200
+ function BodyColorsDataUtils.toBodyColors(bodyColorsData)
201
+ assert(BodyColorsDataUtils.isBodyColorsData(bodyColorsData), "Bad bodyColorsData")
202
+
203
+ local bodyColors = Instance.new("BodyColors")
204
+ BodyColorsDataUtils.applyToBodyColors(bodyColors, bodyColorsData)
205
+
206
+ return bodyColors
207
+ end
208
+
209
+ --[=[
210
+ Applies body colors to the actual body color property
211
+
212
+ @param bodyColorsData BodyColorsData
213
+ @param bodyColors BodyColors
214
+ @return BodyColors
215
+ ]=]
216
+ function BodyColorsDataUtils.applyToBodyColors(bodyColorsData, bodyColors)
217
+ assert(BodyColorsDataUtils.isBodyColorsData(bodyColorsData), "Bad bodyColorsData")
218
+ assert(typeof(bodyColors) == "Instance" and bodyColors:IsA("BodyColors"), "Bad bodyColors")
219
+
220
+ if bodyColorsData.headColor then
221
+ bodyColors.HeadColor3 = bodyColorsData.headColor
222
+ end
223
+
224
+ if bodyColorsData.leftArmColor then
225
+ bodyColors.LeftArmColor3 = bodyColorsData.leftArmColor
226
+ end
227
+
228
+ if bodyColorsData.leftLegColor then
229
+ bodyColors.LeftLegColor3 = bodyColorsData.leftLegColor
230
+ end
231
+
232
+ if bodyColorsData.rightArmColor then
233
+ bodyColors.RightArmColor3 = bodyColorsData.rightArmColor
234
+ end
235
+
236
+ if bodyColorsData.rightLegColor then
237
+ bodyColors.RightLegColor3 = bodyColorsData.rightLegColor
238
+ end
239
+
240
+ if bodyColorsData.torsoColor then
241
+ bodyColors.TorsoColor3 = bodyColorsData.torsoColor
242
+ end
243
+ end
244
+
245
+ --[=[
246
+ Extracts body colors from attributes
247
+ @param instance Instance
248
+ @return BodyColorsData
249
+ ]=]
250
+ function BodyColorsDataUtils.fromAttributes(instance)
251
+ assert(typeof(instance) == "Instance", "Bad instance")
252
+
253
+ local bodyColorsData = {}
254
+
255
+ for key, attributeName in pairs(BodyColorsDataConstants.ATTRIBUTE_MAPPING) do
256
+ local value = instance:GetAttribute(attributeName)
257
+ if value ~= nil then
258
+ if typeof(value) == "Color3" then
259
+ bodyColorsData[key] = value
260
+ else
261
+ warn(string.format("[BodyColorsDataUtils.fromAttributes] - Bad attribute %q of type %q",
262
+ attributeName,
263
+ typeof(value)))
264
+ end
265
+ end
266
+ end
267
+
268
+ return BodyColorsDataUtils.createBodyColorsData(bodyColorsData)
269
+ end
270
+
271
+ --[=[
272
+ Sets attributes to store body colors.
273
+ @param instance Instance
274
+ @param bodyColorsData BodyColorsData
275
+ ]=]
276
+ function BodyColorsDataUtils.setAttributes(instance, bodyColorsData)
277
+ assert(typeof(instance) == "Instance", "Bad instance")
278
+ assert(BodyColorsDataUtils.isBodyColorsData(bodyColorsData), "Bad bodyColorsData")
279
+
280
+ for key, attributeName in pairs(BodyColorsDataConstants.ATTRIBUTE_MAPPING) do
281
+ local value = bodyColorsData[key]
282
+ if value then
283
+ instance:SetAttribute(attributeName, value)
284
+ else
285
+ instance:SetAttribute(attributeName, nil)
286
+ end
287
+ end
288
+ end
289
+
290
+ --[=[
291
+ Applies body colors to the actual body color property
292
+
293
+ @param bodyColorsData BodyColorsData
294
+ @param humanoidDescription HumanoidDescription
295
+ @return BodyColors
296
+ ]=]
297
+ function BodyColorsDataUtils.applyToHumanoidDescription(bodyColorsData, humanoidDescription)
298
+ assert(BodyColorsDataUtils.isBodyColorsData(bodyColorsData), "Bad bodyColorsData")
299
+ assert(typeof(humanoidDescription) == "Instance" and humanoidDescription:IsA("HumanoidDescription"), "Bad humanoidDescription")
300
+
301
+ if bodyColorsData.headColor then
302
+ humanoidDescription.HeadColor = bodyColorsData.headColor
303
+ end
304
+
305
+ if bodyColorsData.leftArmColor then
306
+ humanoidDescription.LeftArmColor = bodyColorsData.leftArmColor
307
+ end
308
+
309
+ if bodyColorsData.leftLegColor then
310
+ humanoidDescription.LeftLegColor = bodyColorsData.leftLegColor
311
+ end
312
+
313
+ if bodyColorsData.rightArmColor then
314
+ humanoidDescription.RightArmColor = bodyColorsData.rightArmColor
315
+ end
316
+
317
+ if bodyColorsData.rightLegColor then
318
+ humanoidDescription.RightLegColor = bodyColorsData.rightLegColor
319
+ end
320
+
321
+ if bodyColorsData.torsoColor then
322
+ humanoidDescription.TorsoColor = bodyColorsData.torsoColor
323
+ end
324
+ end
325
+
326
+ return BodyColorsDataUtils
@@ -0,0 +1,49 @@
1
+ --[=[
2
+ @class RxBodyColorsDataUtils
3
+ ]=]
4
+
5
+ local require = require(script.Parent.loader).load(script)
6
+
7
+ local Rx = require("Rx")
8
+ local BodyColorsDataConstants = require("BodyColorsDataConstants")
9
+ local RxAttributeUtils = require("RxAttributeUtils")
10
+ local BodyColorsDataUtils = require("BodyColorsDataUtils")
11
+
12
+ local RxBodyColorsDataUtils = {}
13
+
14
+ --[=[
15
+ Observes the current body colors data from attributes
16
+
17
+ @param instance Instance
18
+ @return Observable<BodyColorsData>
19
+ ]=]
20
+ function RxBodyColorsDataUtils.observeFromAttributes(instance)
21
+ assert(typeof(instance) == "Instance", "Bad instance")
22
+
23
+ local observables = {}
24
+
25
+ for key, attributeName in pairs(BodyColorsDataConstants.ATTRIBUTE_MAPPING) do
26
+ observables[key] = RxAttributeUtils.observeAttribute(instance, attributeName)
27
+ end
28
+
29
+ return Rx.combineLatest(observables):Pipe({
30
+ Rx.map(function(latestValues)
31
+ for key, attributeName in pairs(BodyColorsDataConstants.ATTRIBUTE_MAPPING) do
32
+ local bodyColorsData = {}
33
+
34
+ local value = latestValues[key]
35
+ if typeof(value) == "Color3" then
36
+ bodyColorsData[key] = value
37
+ else
38
+ warn(string.format("[RxBodyColorsDataUtils.observeFromAttributes] - Bad attribute %q of type %q",
39
+ attributeName,
40
+ typeof(value)))
41
+ end
42
+
43
+ return BodyColorsDataUtils.createBodyColorsData(bodyColorsData)
44
+ end
45
+ end);
46
+ })
47
+ end
48
+
49
+ return RxBodyColorsDataUtils
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "node_modules",
3
+ "globIgnorePaths": [ "**/.package-lock.json" ],
4
+ "tree": {
5
+ "$path": { "optional": "../node_modules" }
6
+ }
7
+ }