@rbxts/humanoid-stat-manager 1.0.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/out/index.d.ts +4 -0
- package/out/init.luau +168 -0
- package/out/loaders/client.meta.json +5 -0
- package/out/loaders/client.server.d.ts +1 -0
- package/out/loaders/client.server.luau +10 -0
- package/out/loaders/server.meta.json +5 -0
- package/out/loaders/server.server.d.ts +1 -0
- package/out/loaders/server.server.luau +10 -0
- package/out/shared.d.ts +16 -0
- package/out/shared.luau +79 -0
- package/package.json +33 -0
package/out/index.d.ts
ADDED
package/out/init.luau
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _services = TS.import(script, TS.getModule(script, "@rbxts", "services"))
|
|
4
|
+
local HttpService = _services.HttpService
|
|
5
|
+
local Players = _services.Players
|
|
6
|
+
local RunService = _services.RunService
|
|
7
|
+
local observeCharacters = TS.import(script, TS.getModule(script, "@rbxts", "roblox-observers").out["observe-characters"]).observeCharacters
|
|
8
|
+
local _shared = TS.import(script, script, "shared")
|
|
9
|
+
local _internalCreateModifier = _shared._internalCreateModifier
|
|
10
|
+
local pruneExpiredModifiers = _shared.pruneExpiredModifiers
|
|
11
|
+
local calculateStat = _shared.calculateStat
|
|
12
|
+
local REMOTE_NAME = "ServerToClient"
|
|
13
|
+
local IS_SERVER = RunService:IsServer()
|
|
14
|
+
local serverNpcModifiers = {}
|
|
15
|
+
local clientModifiers = {}
|
|
16
|
+
local clientHumanoid
|
|
17
|
+
local remote
|
|
18
|
+
local clientAddInternal, clientRemoveInternal
|
|
19
|
+
if IS_SERVER then
|
|
20
|
+
remote = Instance.new("RemoteEvent")
|
|
21
|
+
remote.Name = REMOTE_NAME
|
|
22
|
+
remote.Parent = script
|
|
23
|
+
RunService.Heartbeat:Connect(function()
|
|
24
|
+
for char, modifiers in serverNpcModifiers do
|
|
25
|
+
if not char.Parent then
|
|
26
|
+
serverNpcModifiers[char] = nil
|
|
27
|
+
continue
|
|
28
|
+
end
|
|
29
|
+
pruneExpiredModifiers(modifiers)
|
|
30
|
+
if #modifiers == 0 then
|
|
31
|
+
serverNpcModifiers[char] = nil
|
|
32
|
+
end
|
|
33
|
+
local humanoid = char:FindFirstChildOfClass("Humanoid")
|
|
34
|
+
if humanoid then
|
|
35
|
+
humanoid.WalkSpeed = calculateStat("WalkSpeed", modifiers)
|
|
36
|
+
humanoid.JumpHeight = calculateStat("JumpHeight", modifiers)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end)
|
|
40
|
+
else
|
|
41
|
+
remote = script:WaitForChild(REMOTE_NAME)
|
|
42
|
+
RunService.Heartbeat:Connect(function()
|
|
43
|
+
pruneExpiredModifiers(clientModifiers)
|
|
44
|
+
if not clientHumanoid then
|
|
45
|
+
return nil
|
|
46
|
+
end
|
|
47
|
+
clientHumanoid.WalkSpeed = calculateStat("WalkSpeed", clientModifiers)
|
|
48
|
+
clientHumanoid.JumpHeight = calculateStat("JumpHeight", clientModifiers)
|
|
49
|
+
end)
|
|
50
|
+
remote.OnClientEvent:Connect(function(action, ...)
|
|
51
|
+
local args = { ... }
|
|
52
|
+
if action == "Add" then
|
|
53
|
+
local modifier = args[1]
|
|
54
|
+
clientAddInternal(modifier)
|
|
55
|
+
elseif action == "Remove" then
|
|
56
|
+
local id = args[1]
|
|
57
|
+
clientRemoveInternal(id)
|
|
58
|
+
end
|
|
59
|
+
end)
|
|
60
|
+
observeCharacters(function(char, player)
|
|
61
|
+
if player ~= Players.LocalPlayer then
|
|
62
|
+
return nil
|
|
63
|
+
end
|
|
64
|
+
table.clear(clientModifiers)
|
|
65
|
+
clientHumanoid = char:WaitForChild("Humanoid")
|
|
66
|
+
return function()
|
|
67
|
+
clientHumanoid = nil
|
|
68
|
+
end
|
|
69
|
+
end)
|
|
70
|
+
end
|
|
71
|
+
function clientAddInternal(modifier)
|
|
72
|
+
local _modifier = modifier
|
|
73
|
+
table.insert(clientModifiers, _modifier)
|
|
74
|
+
end
|
|
75
|
+
function clientRemoveInternal(id)
|
|
76
|
+
-- ▼ ReadonlyArray.findIndex ▼
|
|
77
|
+
local _callback = function(m)
|
|
78
|
+
return m.id == id
|
|
79
|
+
end
|
|
80
|
+
local _result = -1
|
|
81
|
+
for _i, _v in clientModifiers do
|
|
82
|
+
if _callback(_v, _i - 1, clientModifiers) == true then
|
|
83
|
+
_result = _i - 1
|
|
84
|
+
break
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
-- ▲ ReadonlyArray.findIndex ▲
|
|
88
|
+
local index = _result
|
|
89
|
+
if index ~= -1 then
|
|
90
|
+
table.remove(clientModifiers, index + 1)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
local addModifierServer, addModifierClient
|
|
94
|
+
local HumanoidStatManager = {}
|
|
95
|
+
do
|
|
96
|
+
local _container = HumanoidStatManager
|
|
97
|
+
local function addModifier(char, modifier)
|
|
98
|
+
if IS_SERVER then
|
|
99
|
+
return addModifierServer(char, modifier)
|
|
100
|
+
end
|
|
101
|
+
return addModifierClient(char, modifier)
|
|
102
|
+
end
|
|
103
|
+
_container.addModifier = addModifier
|
|
104
|
+
end
|
|
105
|
+
function addModifierServer(char, modifier)
|
|
106
|
+
local player = Players:GetPlayerFromCharacter(char)
|
|
107
|
+
local id = HttpService:GenerateGUID(false)
|
|
108
|
+
if player then
|
|
109
|
+
local _remote = remote
|
|
110
|
+
local _object = table.clone(modifier)
|
|
111
|
+
setmetatable(_object, nil)
|
|
112
|
+
_object.id = id
|
|
113
|
+
_remote:FireClient(player, "Add", _object)
|
|
114
|
+
return function()
|
|
115
|
+
remote:FireClient(player, "Remove", id)
|
|
116
|
+
end
|
|
117
|
+
else
|
|
118
|
+
local _char = char
|
|
119
|
+
local modifiers = serverNpcModifiers[_char]
|
|
120
|
+
if not modifiers then
|
|
121
|
+
modifiers = {}
|
|
122
|
+
local _char_1 = char
|
|
123
|
+
local _modifiers = modifiers
|
|
124
|
+
serverNpcModifiers[_char_1] = _modifiers
|
|
125
|
+
end
|
|
126
|
+
local _object = table.clone(modifier)
|
|
127
|
+
setmetatable(_object, nil)
|
|
128
|
+
_object.id = id
|
|
129
|
+
local internalMod = _internalCreateModifier(_object)
|
|
130
|
+
table.insert(modifiers, internalMod)
|
|
131
|
+
return function()
|
|
132
|
+
local _char_1 = char
|
|
133
|
+
local currentMods = serverNpcModifiers[_char_1]
|
|
134
|
+
if not currentMods then
|
|
135
|
+
return nil
|
|
136
|
+
end
|
|
137
|
+
-- ▼ ReadonlyArray.findIndex ▼
|
|
138
|
+
local _callback = function(m)
|
|
139
|
+
return m.id == id
|
|
140
|
+
end
|
|
141
|
+
local _result = -1
|
|
142
|
+
for _i, _v in currentMods do
|
|
143
|
+
if _callback(_v, _i - 1, currentMods) == true then
|
|
144
|
+
_result = _i - 1
|
|
145
|
+
break
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
-- ▲ ReadonlyArray.findIndex ▲
|
|
149
|
+
local index = _result
|
|
150
|
+
if index ~= -1 then
|
|
151
|
+
table.remove(currentMods, index + 1)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
function addModifierClient(char, modifier)
|
|
157
|
+
if char ~= Players.LocalPlayer.Character then
|
|
158
|
+
error("HumanoidStatManager: Client can only modify the LocalPlayer\'s character.")
|
|
159
|
+
end
|
|
160
|
+
local internalMod = _internalCreateModifier(modifier)
|
|
161
|
+
clientAddInternal(internalMod)
|
|
162
|
+
return function()
|
|
163
|
+
clientRemoveInternal(internalMod.id)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
return {
|
|
167
|
+
HumanoidStatManager = HumanoidStatManager,
|
|
168
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local _module = script.Parent
|
|
3
|
+
if _module ~= nil then
|
|
4
|
+
_module = _module.Parent
|
|
5
|
+
end
|
|
6
|
+
local module = _module
|
|
7
|
+
local _arg0 = module and module:IsA("ModuleScript")
|
|
8
|
+
local _arg1 = `Module not found`
|
|
9
|
+
assert(_arg0, _arg1)
|
|
10
|
+
require(module)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local _module = script.Parent
|
|
3
|
+
if _module ~= nil then
|
|
4
|
+
_module = _module.Parent
|
|
5
|
+
end
|
|
6
|
+
local module = _module
|
|
7
|
+
local _arg0 = module and module:IsA("ModuleScript")
|
|
8
|
+
local _arg1 = `Module not found`
|
|
9
|
+
assert(_arg0, _arg1)
|
|
10
|
+
require(module)
|
package/out/shared.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface Modifier {
|
|
2
|
+
id?: string;
|
|
3
|
+
stat: 'WalkSpeed' | 'JumpHeight';
|
|
4
|
+
type: 'Add' | 'Multiply' | 'Set';
|
|
5
|
+
value: number;
|
|
6
|
+
duration?: number;
|
|
7
|
+
startTime?: number;
|
|
8
|
+
priority?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare const BASE_STATS: {
|
|
11
|
+
WalkSpeed: number;
|
|
12
|
+
JumpHeight: number;
|
|
13
|
+
};
|
|
14
|
+
export declare function calculateStat(stat: Modifier['stat'], modifiers: Modifier[]): number;
|
|
15
|
+
export declare function pruneExpiredModifiers(modifiers: Modifier[]): void;
|
|
16
|
+
export declare function _internalCreateModifier(modifier: Omit<Modifier, 'startTime'>): Modifier;
|
package/out/shared.luau
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
-- Compiled with roblox-ts v3.0.0
|
|
2
|
+
local TS = _G[script]
|
|
3
|
+
local _services = TS.import(script, TS.getModule(script, "@rbxts", "services"))
|
|
4
|
+
local HttpService = _services.HttpService
|
|
5
|
+
local StarterPlayer = _services.StarterPlayer
|
|
6
|
+
local BASE_STATS = {
|
|
7
|
+
WalkSpeed = StarterPlayer.CharacterWalkSpeed,
|
|
8
|
+
JumpHeight = StarterPlayer.CharacterJumpHeight,
|
|
9
|
+
}
|
|
10
|
+
local function calculateStat(stat, modifiers)
|
|
11
|
+
local base = BASE_STATS[stat]
|
|
12
|
+
local setMod
|
|
13
|
+
for _, modifier in modifiers do
|
|
14
|
+
if modifier.stat ~= stat then
|
|
15
|
+
continue
|
|
16
|
+
end
|
|
17
|
+
if modifier.type == "Set" then
|
|
18
|
+
local _condition = not setMod
|
|
19
|
+
if not _condition then
|
|
20
|
+
local _condition_1 = modifier.priority
|
|
21
|
+
if _condition_1 == nil then
|
|
22
|
+
_condition_1 = 0
|
|
23
|
+
end
|
|
24
|
+
local _condition_2 = setMod.priority
|
|
25
|
+
if _condition_2 == nil then
|
|
26
|
+
_condition_2 = 0
|
|
27
|
+
end
|
|
28
|
+
_condition = _condition_1 > _condition_2
|
|
29
|
+
end
|
|
30
|
+
if _condition then
|
|
31
|
+
setMod = modifier
|
|
32
|
+
end
|
|
33
|
+
elseif not setMod then
|
|
34
|
+
if modifier.type == "Add" then
|
|
35
|
+
base += modifier.value
|
|
36
|
+
elseif modifier.type == "Multiply" then
|
|
37
|
+
base *= modifier.value
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
return if setMod then setMod.value else base
|
|
42
|
+
end
|
|
43
|
+
local function pruneExpiredModifiers(modifiers)
|
|
44
|
+
local now = tick()
|
|
45
|
+
for i = #modifiers - 1, 0, -1 do
|
|
46
|
+
local modifier = modifiers[i + 1]
|
|
47
|
+
local _condition = modifier.duration ~= nil
|
|
48
|
+
if _condition then
|
|
49
|
+
local _condition_1 = modifier.startTime
|
|
50
|
+
if _condition_1 == nil then
|
|
51
|
+
_condition_1 = 0
|
|
52
|
+
end
|
|
53
|
+
_condition = now - _condition_1 >= modifier.duration
|
|
54
|
+
end
|
|
55
|
+
if _condition then
|
|
56
|
+
local _modifiers = modifiers
|
|
57
|
+
local _i = i
|
|
58
|
+
table.remove(_modifiers, _i + 1)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
local function _internalCreateModifier(modifier)
|
|
63
|
+
local _object = table.clone(modifier)
|
|
64
|
+
setmetatable(_object, nil)
|
|
65
|
+
local _left = "id"
|
|
66
|
+
local _condition = modifier.id
|
|
67
|
+
if _condition == nil then
|
|
68
|
+
_condition = HttpService:GenerateGUID(false)
|
|
69
|
+
end
|
|
70
|
+
_object[_left] = _condition
|
|
71
|
+
_object.startTime = tick()
|
|
72
|
+
return _object
|
|
73
|
+
end
|
|
74
|
+
return {
|
|
75
|
+
calculateStat = calculateStat,
|
|
76
|
+
pruneExpiredModifiers = pruneExpiredModifiers,
|
|
77
|
+
_internalCreateModifier = _internalCreateModifier,
|
|
78
|
+
BASE_STATS = BASE_STATS,
|
|
79
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rbxts/humanoid-stat-manager",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "out/init.lua",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "rbxtsc",
|
|
8
|
+
"watch": "rbxtsc -w",
|
|
9
|
+
"prepublishOnly": "npm run build"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [],
|
|
12
|
+
"author": "",
|
|
13
|
+
"license": "ISC",
|
|
14
|
+
"type": "commonjs",
|
|
15
|
+
"types": "out/index.d.ts",
|
|
16
|
+
"files": [
|
|
17
|
+
"out",
|
|
18
|
+
"!**/*.tsbuildinfo"
|
|
19
|
+
],
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@rbxts/compiler-types": "^3.0.0-types.0",
|
|
25
|
+
"@rbxts/types": "^1.0.896",
|
|
26
|
+
"roblox-ts": "^3.0.0",
|
|
27
|
+
"typescript": "^5.9.3"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@rbxts/roblox-observers": "^1.0.8",
|
|
31
|
+
"@rbxts/services": "^1.6.0"
|
|
32
|
+
}
|
|
33
|
+
}
|