@quenty/hintscoringutils 14.20.0 → 14.20.1
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 +11 -0
- package/package.json +11 -11
- package/src/Client/HintScoringUtils.lua +48 -36
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [14.20.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/hintscoringutils@14.20.0...@quenty/hintscoringutils@14.20.1) (2025-04-05)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Add types to packages ([2374fb2](https://github.com/Quenty/NevermoreEngine/commit/2374fb2b043cfbe0e9b507b3316eec46a4e353a0))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
# [14.20.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/hintscoringutils@14.19.2...@quenty/hintscoringutils@14.20.0) (2025-04-02)
|
|
7
18
|
|
|
8
19
|
**Note:** Version bump only for package @quenty/hintscoringutils
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/hintscoringutils",
|
|
3
|
-
"version": "14.20.
|
|
3
|
+
"version": "14.20.1",
|
|
4
4
|
"description": "Utility functions that let you score a proximity prompt (i.e. a Hint) based upon its relation to a character in 3D space.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -26,18 +26,18 @@
|
|
|
26
26
|
"Quenty"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@quenty/adorneeutils": "^3.3.
|
|
30
|
-
"@quenty/boundingboxutils": "^4.3.
|
|
31
|
-
"@quenty/camera": "^14.20.
|
|
32
|
-
"@quenty/draw": "^7.8.
|
|
33
|
-
"@quenty/loader": "^10.8.
|
|
34
|
-
"@quenty/maid": "^3.4.
|
|
35
|
-
"@quenty/math": "^2.7.
|
|
36
|
-
"@quenty/region3utils": "^10.9.
|
|
37
|
-
"@quenty/vector3utils": "^10.8.
|
|
29
|
+
"@quenty/adorneeutils": "^3.3.2",
|
|
30
|
+
"@quenty/boundingboxutils": "^4.3.1",
|
|
31
|
+
"@quenty/camera": "^14.20.1",
|
|
32
|
+
"@quenty/draw": "^7.8.2",
|
|
33
|
+
"@quenty/loader": "^10.8.1",
|
|
34
|
+
"@quenty/maid": "^3.4.1",
|
|
35
|
+
"@quenty/math": "^2.7.2",
|
|
36
|
+
"@quenty/region3utils": "^10.9.1",
|
|
37
|
+
"@quenty/vector3utils": "^10.8.2"
|
|
38
38
|
},
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"access": "public"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "78c3ac0ab08dd18085b6e6e6e4f745e76ed99f68"
|
|
43
43
|
}
|
|
@@ -40,14 +40,14 @@ local HintScoringUtils = {}
|
|
|
40
40
|
@return Vector3? -- Position
|
|
41
41
|
@return Vector3? -- LookVector
|
|
42
42
|
]=]
|
|
43
|
-
function HintScoringUtils.getHumanoidPositionDirection(humanoid: Humanoid)
|
|
43
|
+
function HintScoringUtils.getHumanoidPositionDirection(humanoid: Humanoid): (Vector3?, Vector3?)
|
|
44
44
|
local rootPart = humanoid.RootPart
|
|
45
45
|
if not rootPart then
|
|
46
46
|
return nil, nil
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
local rootCFrame = rootPart.CFrame
|
|
50
|
-
return rootCFrame.Position, rootCFrame.
|
|
50
|
+
return rootCFrame.Position, rootCFrame.LookVector
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
--[=[
|
|
@@ -58,13 +58,13 @@ end
|
|
|
58
58
|
@param getAdorneeFunction (Instance) -> Instance?
|
|
59
59
|
@return { [Instance]: true }
|
|
60
60
|
]=]
|
|
61
|
-
function HintScoringUtils.getAdorneeInRegionSet(position, radius, ignoreList, getAdorneeFunction)
|
|
61
|
+
function HintScoringUtils.getAdorneeInRegionSet(position: Vector3, radius: number, ignoreList, getAdorneeFunction)
|
|
62
62
|
assert(type(getAdorneeFunction) == "function", "Bad getAdorneeFunction")
|
|
63
63
|
|
|
64
64
|
local region3 = Region3Utils.fromRadius(position, radius)
|
|
65
65
|
local adorneesSet = {}
|
|
66
66
|
|
|
67
|
-
for _, part in
|
|
67
|
+
for _, part in Workspace:FindPartsInRegion3WithIgnoreList(region3, ignoreList, MAX_PARTS_IN_REGION3) do
|
|
68
68
|
local adornee = getAdorneeFunction(part)
|
|
69
69
|
if adornee then
|
|
70
70
|
adorneesSet[adornee] = true
|
|
@@ -80,10 +80,13 @@ if DEBUG_ENABLED then
|
|
|
80
80
|
@param adornee Instance
|
|
81
81
|
@param score number
|
|
82
82
|
]=]
|
|
83
|
-
function HintScoringUtils.debugScore(adornee, score)
|
|
83
|
+
function HintScoringUtils.debugScore(adornee: Instance, score)
|
|
84
84
|
assert(adornee, "Bad adornee")
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
local position = AdorneeUtils.getCenter(adornee)
|
|
87
|
+
if position then
|
|
88
|
+
debugMaid:GiveTask(Draw.text(position, string.format("%0.6f", score)))
|
|
89
|
+
end
|
|
87
90
|
end
|
|
88
91
|
else
|
|
89
92
|
function HintScoringUtils.debugScore(_, _)
|
|
@@ -101,13 +104,19 @@ end
|
|
|
101
104
|
@param extraDistance number
|
|
102
105
|
@return Vector3 -- Hit position
|
|
103
106
|
]=]
|
|
104
|
-
function HintScoringUtils.raycastToAdornee(
|
|
107
|
+
function HintScoringUtils.raycastToAdornee(
|
|
108
|
+
raycaster,
|
|
109
|
+
humanoidCenter: Vector3,
|
|
110
|
+
adornee: Instance,
|
|
111
|
+
closestBoundingBoxPoint: Vector3,
|
|
112
|
+
extraDistance: number
|
|
113
|
+
)
|
|
105
114
|
local offset = closestBoundingBoxPoint - humanoidCenter
|
|
106
|
-
if offset.
|
|
115
|
+
if offset.Magnitude == 0 then
|
|
107
116
|
return nil
|
|
108
117
|
end
|
|
109
118
|
|
|
110
|
-
local ray = Ray.new(humanoidCenter, offset.
|
|
119
|
+
local ray = Ray.new(humanoidCenter, offset.Unit * (offset.Magnitude + extraDistance))
|
|
111
120
|
local hitData = raycaster:FindPartOnRay(ray)
|
|
112
121
|
|
|
113
122
|
if DEBUG_ENABLED then
|
|
@@ -117,7 +126,7 @@ function HintScoringUtils.raycastToAdornee(raycaster, humanoidCenter, adornee, c
|
|
|
117
126
|
|
|
118
127
|
if adornee:IsA("Attachment") then
|
|
119
128
|
if hitData then
|
|
120
|
-
if (hitData.Position - closestBoundingBoxPoint).
|
|
129
|
+
if (hitData.Position - closestBoundingBoxPoint).Magnitude > MAX_DIST_FOR_ATTACHMENTS then
|
|
121
130
|
return nil
|
|
122
131
|
else
|
|
123
132
|
return closestBoundingBoxPoint
|
|
@@ -151,13 +160,13 @@ end
|
|
|
151
160
|
@return Vector3? -- clamped point
|
|
152
161
|
@return Vector3? -- center of bounding box
|
|
153
162
|
]=]
|
|
154
|
-
function HintScoringUtils.clampToBoundingBox(adornee: Instance, humanoidCenter: Vector3)
|
|
163
|
+
function HintScoringUtils.clampToBoundingBox(adornee: Instance, humanoidCenter: Vector3): (Vector3?, Vector3?)
|
|
155
164
|
if adornee:IsA("Attachment") then
|
|
156
165
|
return adornee.WorldPosition, adornee.WorldPosition
|
|
157
166
|
end
|
|
158
167
|
|
|
159
168
|
local cframe, size = AdorneeUtils.getBoundingBox(adornee)
|
|
160
|
-
if not cframe then
|
|
169
|
+
if not cframe or not size then
|
|
161
170
|
return nil, nil
|
|
162
171
|
end
|
|
163
172
|
|
|
@@ -178,31 +187,34 @@ end
|
|
|
178
187
|
@return boolean | number -- [0, 1]
|
|
179
188
|
]=]
|
|
180
189
|
function HintScoringUtils.scoreAdornee(
|
|
181
|
-
adornee,
|
|
190
|
+
adornee: Instance,
|
|
182
191
|
raycaster,
|
|
183
|
-
humanoidCenter,
|
|
184
|
-
humanoidLookVector,
|
|
185
|
-
maxViewRadius,
|
|
186
|
-
maxTriggerRadius,
|
|
187
|
-
maxViewAngle,
|
|
188
|
-
maxTriggerAngle,
|
|
189
|
-
isLineOfSightRequired
|
|
190
|
-
)
|
|
192
|
+
humanoidCenter: Vector3,
|
|
193
|
+
humanoidLookVector: Vector3,
|
|
194
|
+
maxViewRadius: number,
|
|
195
|
+
maxTriggerRadius: number,
|
|
196
|
+
maxViewAngle: number,
|
|
197
|
+
maxTriggerAngle: number,
|
|
198
|
+
isLineOfSightRequired: boolean
|
|
199
|
+
): number?
|
|
191
200
|
assert(maxTriggerAngle, "Bad maxTriggerAngle")
|
|
192
201
|
|
|
193
202
|
-- local center = AdorneeUtils.getCenter(adornee)
|
|
194
203
|
-- if not center then
|
|
195
|
-
-- return
|
|
204
|
+
-- return nil
|
|
196
205
|
-- end
|
|
197
206
|
|
|
198
207
|
local boundingBoxPoint, center = HintScoringUtils.clampToBoundingBox(adornee, humanoidCenter)
|
|
199
|
-
if
|
|
200
|
-
return
|
|
208
|
+
if boundingBoxPoint == nil then
|
|
209
|
+
return nil
|
|
210
|
+
end
|
|
211
|
+
if center == nil then
|
|
212
|
+
return nil
|
|
201
213
|
end
|
|
202
214
|
|
|
203
215
|
local isOnScreen = CameraUtils.isOnScreen(Workspace.CurrentCamera, boundingBoxPoint)
|
|
204
216
|
if not isOnScreen then
|
|
205
|
-
return
|
|
217
|
+
return nil
|
|
206
218
|
end
|
|
207
219
|
|
|
208
220
|
local extraDistance = 10
|
|
@@ -211,13 +223,13 @@ function HintScoringUtils.scoreAdornee(
|
|
|
211
223
|
HintScoringUtils.raycastToAdornee(raycaster, humanoidCenter, adornee, boundingBoxPoint, extraDistance)
|
|
212
224
|
|
|
213
225
|
-- Round objects be sad
|
|
214
|
-
if
|
|
226
|
+
if closestPoint == nil then
|
|
215
227
|
closestPoint = HintScoringUtils.raycastToAdornee(raycaster, humanoidCenter, adornee, center, 4)
|
|
216
228
|
end
|
|
217
229
|
|
|
218
|
-
if
|
|
230
|
+
if closestPoint == nil then
|
|
219
231
|
if isLineOfSightRequired then
|
|
220
|
-
return
|
|
232
|
+
return nil
|
|
221
233
|
else
|
|
222
234
|
-- just pretend like we're here, and all good
|
|
223
235
|
closestPoint = boundingBoxPoint
|
|
@@ -240,17 +252,17 @@ function HintScoringUtils.scoreAdornee(
|
|
|
240
252
|
local flatOffset = angleOffset * Vector3.new(1, 0, 1)
|
|
241
253
|
local angle = Vector3Utils.angleBetweenVectors(flatOffset.Unit, humanoidLookVector * Vector3.new(1, 0, 1))
|
|
242
254
|
if not angle then
|
|
243
|
-
return
|
|
255
|
+
return nil
|
|
244
256
|
end
|
|
245
257
|
|
|
246
|
-
local distScore = HintScoringUtils.scoreDist(flatHumanoidOffset.
|
|
258
|
+
local distScore = HintScoringUtils.scoreDist(flatHumanoidOffset.Magnitude, maxViewRadius, maxTriggerRadius)
|
|
247
259
|
if not distScore then
|
|
248
|
-
return
|
|
260
|
+
return nil
|
|
249
261
|
end
|
|
250
262
|
|
|
251
263
|
local angleScore = HintScoringUtils.scoreAngle(angle, maxViewAngle, maxTriggerAngle)
|
|
252
264
|
if not angleScore then
|
|
253
|
-
return
|
|
265
|
+
return nil
|
|
254
266
|
end
|
|
255
267
|
|
|
256
268
|
return (distScore + angleScore) / 2
|
|
@@ -264,11 +276,11 @@ end
|
|
|
264
276
|
@param maxTriggerRadius number
|
|
265
277
|
@return number -- [0, 1]
|
|
266
278
|
]=]
|
|
267
|
-
function HintScoringUtils.scoreDist(distance, maxViewDistance, maxTriggerRadius)
|
|
279
|
+
function HintScoringUtils.scoreDist(distance: number, maxViewDistance: number, maxTriggerRadius: number): number?
|
|
268
280
|
assert(maxViewDistance >= maxTriggerRadius, "maxViewDistance < maxTriggerRadius")
|
|
269
281
|
|
|
270
282
|
if distance > maxViewDistance then
|
|
271
|
-
return
|
|
283
|
+
return nil
|
|
272
284
|
end
|
|
273
285
|
|
|
274
286
|
if distance > maxTriggerRadius then
|
|
@@ -287,11 +299,11 @@ end
|
|
|
287
299
|
@param maxTriggerAngle number
|
|
288
300
|
@return number -- [0, 1]
|
|
289
301
|
]=]
|
|
290
|
-
function HintScoringUtils.scoreAngle(angle, maxViewAngle, maxTriggerAngle)
|
|
302
|
+
function HintScoringUtils.scoreAngle(angle: number, maxViewAngle: number, maxTriggerAngle: number): number?
|
|
291
303
|
assert(maxViewAngle >= maxTriggerAngle, "maxViewDistance < maxTriggerRadius")
|
|
292
304
|
|
|
293
305
|
if angle > maxViewAngle then
|
|
294
|
-
return
|
|
306
|
+
return nil
|
|
295
307
|
end
|
|
296
308
|
if angle > maxTriggerAngle then
|
|
297
309
|
return -math.huge
|