@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 ADDED
@@ -0,0 +1,4 @@
1
+ import { Modifier } from './shared';
2
+ export declare namespace HumanoidStatManager {
3
+ function addModifier(char: Model, modifier: Omit<Modifier, 'id' | 'startTime'>): () => void;
4
+ }
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,5 @@
1
+ {
2
+ "properties": {
3
+ "RunContext": "Client"
4
+ }
5
+ }
@@ -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,5 @@
1
+ {
2
+ "properties": {
3
+ "RunContext": "Server"
4
+ }
5
+ }
@@ -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,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;
@@ -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
+ }