@quenty/clipcharacters 12.4.0 → 12.4.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 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
+ ## [12.4.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/clipcharacters@12.4.0...@quenty/clipcharacters@12.4.1) (2024-05-14)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * Update ClipCharacters to act as a service ([b6651b6](https://github.com/Quenty/NevermoreEngine/commit/b6651b6d01375857e022641f62461e179292a97c))
12
+
13
+
14
+
15
+
16
+
6
17
  # [12.4.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/clipcharacters@12.3.0...@quenty/clipcharacters@12.4.0) (2024-05-09)
7
18
 
8
19
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/clipcharacters",
3
- "version": "12.4.0",
3
+ "version": "12.4.1",
4
4
  "description": "Clip characters locally on the client of other clients so they don't interfer with physics.",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -25,12 +25,20 @@
25
25
  "Quenty"
26
26
  ],
27
27
  "dependencies": {
28
+ "@quenty/baseobject": "^10.3.0",
29
+ "@quenty/brio": "^14.3.0",
30
+ "@quenty/characterutils": "^12.3.0",
28
31
  "@quenty/loader": "^10.3.0",
29
32
  "@quenty/maid": "^3.2.0",
30
- "@quenty/remoting": "^12.4.0"
33
+ "@quenty/playerutils": "^8.3.0",
34
+ "@quenty/remoting": "^12.4.0",
35
+ "@quenty/servicebag": "^11.4.0",
36
+ "@quenty/statestack": "^14.4.0",
37
+ "@quenty/table": "^3.5.0",
38
+ "@quenty/valueobject": "^13.3.0"
31
39
  },
32
40
  "publishConfig": {
33
41
  "access": "public"
34
42
  },
35
- "gitHead": "3fd5cdca3128bf34c8d9dfae1e92d62533b6e6f5"
43
+ "gitHead": "4955d2477353af4833f444483d41428faa446a4f"
36
44
  }
@@ -0,0 +1,80 @@
1
+ --[=[
2
+ Clip characters locally on the client of other clients so they don't interfer with physics.
3
+ @class ClipCharacters
4
+ ]=]
5
+
6
+ local require = require(script.Parent.loader).load(script)
7
+
8
+ local BaseObject = require("BaseObject")
9
+ local ClipCharactersServiceConstants = require("ClipCharactersServiceConstants")
10
+ local RxBrioUtils = require("RxBrioUtils")
11
+ local RxCharacterUtils = require("RxCharacterUtils")
12
+ local RxPlayerUtils = require("RxPlayerUtils")
13
+
14
+ local ClipCharacters = setmetatable({}, BaseObject)
15
+ ClipCharacters.ClassName = "ClipCharacters"
16
+ ClipCharacters.__index = ClipCharacters
17
+
18
+ --[=[
19
+ Prevents characters from clipping together
20
+
21
+ @return ClipCharacters
22
+ ]=]
23
+ function ClipCharacters.new()
24
+ local self = setmetatable(BaseObject.new(), ClipCharacters)
25
+
26
+ self._maid:GiveTask(RxPlayerUtils.observePlayersBrio():Pipe({
27
+ RxBrioUtils.flatMapBrio(function(player)
28
+ return RxCharacterUtils.observeLastCharacterBrio(player)
29
+ end)
30
+ }):Subscribe(function(brio)
31
+ if brio:IsDead() then
32
+ return
33
+ end
34
+
35
+ local maid, character = brio:ToMaidAndValue()
36
+ self:_setupCharacter(maid, character)
37
+ end))
38
+
39
+ return self
40
+ end
41
+
42
+ function ClipCharacters:_onDescendantAdded(originalTable, descendant)
43
+ if not originalTable[descendant] and descendant:IsA("BasePart") then
44
+ originalTable[descendant] = descendant.CollisionGroup
45
+ descendant.CollisionGroup = ClipCharactersServiceConstants.COLLISION_GROUP_NAME
46
+ end
47
+ end
48
+
49
+ function ClipCharacters:_onDescendantRemoving(originalTable, descendant)
50
+ if originalTable[descendant] then
51
+ descendant.CollisionGroup = originalTable[descendant]
52
+ originalTable[descendant] = nil
53
+ end
54
+ end
55
+
56
+ function ClipCharacters:_setupCharacter(maid, character)
57
+ local originalTable = {}
58
+
59
+ maid:GiveTask(character.DescendantAdded:Connect(function(descendant)
60
+ self:_onDescendantAdded(originalTable, descendant)
61
+ end))
62
+
63
+ maid:GiveTask(character.DescendantRemoving:Connect(function(descendant)
64
+ self:_onDescendantRemoving(originalTable, descendant)
65
+ end))
66
+
67
+ -- Cleanup
68
+ maid:GiveTask(function()
69
+ for descendant, _ in pairs(originalTable) do
70
+ self:_onDescendantRemoving(originalTable, descendant)
71
+ end
72
+ end)
73
+
74
+ -- Initialize
75
+ for _, descendant in pairs(character:GetDescendants()) do
76
+ self:_onDescendantAdded(originalTable, descendant)
77
+ end
78
+ end
79
+
80
+ return ClipCharacters
@@ -0,0 +1,47 @@
1
+ --[=[
2
+ @class ClipCharactersServiceClient
3
+ ]=]
4
+
5
+ local require = require(script.Parent.loader).load(script)
6
+
7
+ local ClipCharacters = require("ClipCharacters")
8
+ local Maid = require("Maid")
9
+ local StateStack = require("StateStack")
10
+
11
+ local ClipCharactersServiceClient = {}
12
+ ClipCharactersServiceClient.ServiceName = "ClipCharactersServiceClient"
13
+
14
+ function ClipCharactersServiceClient:Init(serviceBag)
15
+ assert(not self._serviceBag, "Already initialized")
16
+ self._serviceBag = assert(serviceBag, "No serviceBag")
17
+ self._maid = Maid.new()
18
+
19
+ self._disableCollisions = self._maid:Add(StateStack.new(false, "boolean"))
20
+ end
21
+
22
+ --[=[
23
+ Disables collisions between default geometry and other charaters which stops some random physics
24
+ glitches from occuring.
25
+ ]=]
26
+ function ClipCharactersServiceClient:PushDisableCharacterCollisionsWithDefault()
27
+ return self._disableCollisions:PushState(true)
28
+ end
29
+
30
+ function ClipCharactersServiceClient:Start()
31
+ self._maid:GiveTask(self._disableCollisions:ObserveBrio(function(value)
32
+ return value
33
+ end):Subscribe(function(brio)
34
+ if brio:IsDead() then
35
+ return
36
+ end
37
+
38
+ local maid = brio:ToMaid()
39
+ maid:GiveTask(ClipCharacters.new())
40
+ end))
41
+ end
42
+
43
+ function ClipCharactersServiceClient:Destroy()
44
+ self._maid:DoCleaning()
45
+ end
46
+
47
+ return ClipCharactersServiceClient
@@ -0,0 +1,32 @@
1
+ --[=[
2
+ @class ClipCharactersService
3
+ ]=]
4
+
5
+ local require = require(script.Parent.loader).load(script)
6
+
7
+ local PhysicsService = game:GetService("PhysicsService")
8
+
9
+ local Maid = require("Maid")
10
+ local ClipCharactersServiceConstants = require("ClipCharactersServiceConstants")
11
+
12
+ local ClipCharactersService = {}
13
+ ClipCharactersService.ServiceName = "ClipCharactersService"
14
+
15
+ function ClipCharactersService:Init(serviceBag)
16
+ assert(not self._serviceBag, "Already initialized")
17
+ self._serviceBag = assert(serviceBag, "No serviceBag")
18
+ self._maid = Maid.new()
19
+
20
+ self:_setupPhysicsGroup()
21
+ end
22
+
23
+ function ClipCharactersService:_setupPhysicsGroup()
24
+ PhysicsService:RegisterCollisionGroup(ClipCharactersServiceConstants.COLLISION_GROUP_NAME)
25
+ PhysicsService:CollisionGroupSetCollidable(ClipCharactersServiceConstants.COLLISION_GROUP_NAME, "Default", false)
26
+ end
27
+
28
+ function ClipCharactersService:Destroy()
29
+ self._maid:DoCleaning()
30
+ end
31
+
32
+ return ClipCharactersService
@@ -0,0 +1,11 @@
1
+ --[=[
2
+ @class ClipCharacterConstants
3
+ ]=]
4
+
5
+ local require = require(script.Parent.loader).load(script)
6
+
7
+ local Table = require("Table")
8
+
9
+ return Table.readonly({
10
+ COLLISION_GROUP_NAME = "ClipCharacters"
11
+ })
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "ClipCharactersTest",
3
+ "globIgnorePaths": [ "**/.package-lock.json" ],
4
+ "tree": {
5
+ "$className": "DataModel",
6
+ "ServerScriptService": {
7
+ "clipcharacters": {
8
+ "$path": ".."
9
+ },
10
+ "Script": {
11
+ "$path": "scripts/Server"
12
+ }
13
+ },
14
+ "StarterPlayer": {
15
+ "StarterPlayerScripts": {
16
+ "Main": {
17
+ "$path": "scripts/Client"
18
+ }
19
+ }
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,12 @@
1
+ --[[
2
+ @class ClientMain
3
+ ]]
4
+ local loader = game:GetService("ReplicatedStorage"):WaitForChild("clipcharacters"):WaitForChild("loader")
5
+ local require = require(loader).bootstrapGame(loader.Parent)
6
+
7
+ local serviceBag = require("ServiceBag").new()
8
+ serviceBag:GetService(require("ClipCharactersServiceClient"))
9
+ serviceBag:Init()
10
+ serviceBag:Start()
11
+
12
+ serviceBag:GetService(require("ClipCharactersServiceClient")):PushDisableCharacterCollisionsWithDefault()
@@ -0,0 +1,12 @@
1
+ --[[
2
+ @class ServerMain
3
+ ]]
4
+ local ServerScriptService = game:GetService("ServerScriptService")
5
+
6
+ local loader = ServerScriptService:FindFirstChild("LoaderUtils", true).Parent
7
+ local require = require(loader).bootstrapGame(ServerScriptService.clipcharacters)
8
+
9
+ local serviceBag = require("ServiceBag").new()
10
+ serviceBag:GetService(require("ClipCharactersService"))
11
+ serviceBag:Init()
12
+ serviceBag:Start()
@@ -1,141 +0,0 @@
1
- --[=[
2
- Clip characters locally on the client of other clients so they don't interfer with physics.
3
- @class ClipCharacters
4
- ]=]
5
-
6
- local require = require(script.Parent.loader).load(script)
7
-
8
- local PhysicsService = game:GetService("PhysicsService")
9
- local Players = game:GetService("Players")
10
-
11
- local Maid = require("Maid")
12
- local GetRemoteFunction = require("GetRemoteFunction")
13
-
14
- local REMOTE_FUNCTION_NAME = "GetClipCharactersId"
15
-
16
- local ClipCharacters = {}
17
- ClipCharacters.ClassName = "ClipCharacters"
18
- ClipCharacters.__index = ClipCharacters
19
- ClipCharacters.COLLISION_GROUP_NAME = "ClipCharacters"
20
-
21
- --[=[
22
- Initialize on server
23
- @server
24
- ]=]
25
- function ClipCharacters.initServer()
26
- local groupId = PhysicsService:CreateCollisionGroup(ClipCharacters.COLLISION_GROUP_NAME)
27
- PhysicsService:CollisionGroupSetCollidable(ClipCharacters.COLLISION_GROUP_NAME, "Default", false)
28
-
29
- local remoteFunction = GetRemoteFunction(REMOTE_FUNCTION_NAME)
30
- remoteFunction.OnServerInvoke = function(_)
31
- return groupId
32
- end
33
- end
34
-
35
- --[=[
36
- Initialize clipping on the client. Returns a new inst
37
- @client
38
- @return ClipCharacters
39
- ]=]
40
- function ClipCharacters.new()
41
- local self = setmetatable({}, ClipCharacters)
42
-
43
- self._remoteFunction = GetRemoteFunction(REMOTE_FUNCTION_NAME)
44
-
45
- self._maid = Maid.new()
46
- self:_bindUpdatesYielding()
47
-
48
- return self
49
- end
50
-
51
- function ClipCharacters:_onDescendantAdded(originalTable, descendant)
52
- if not originalTable[descendant] and descendant:IsA("BasePart") then
53
- originalTable[descendant] = descendant.CollisionGroupId
54
- descendant.CollisionGroupId = self._collisionGroupId
55
- end
56
- end
57
-
58
- function ClipCharacters:_onDescendantRemoving(originalTable, descendant)
59
- if originalTable[descendant] then
60
- descendant.CollisionGroupId = originalTable[descendant]
61
- originalTable[descendant] = nil
62
- end
63
- end
64
-
65
- function ClipCharacters:_onCharacterAdd(playerMaid, character)
66
- local maid = Maid.new()
67
-
68
- local originalTable = {}
69
-
70
- maid:GiveTask(character.DescendantAdded:Connect(function(descendant)
71
- self:_onDescendantAdded(originalTable, descendant)
72
- end))
73
-
74
- maid:GiveTask(character.DescendantRemoving:Connect(function(descendant)
75
- self:_onDescendantRemoving(originalTable, descendant)
76
- end))
77
-
78
- -- Cleanup
79
- maid:GiveTask(function()
80
- for descendant, _ in pairs(originalTable) do
81
- self:_onDescendantRemoving(originalTable, descendant)
82
- end
83
- end)
84
-
85
- -- Initialize
86
- for _, descendant in pairs(character:GetDescendants()) do
87
- self:_onDescendantAdded(originalTable, descendant)
88
- end
89
-
90
- playerMaid._characterMaid = maid
91
- end
92
-
93
- function ClipCharacters:_onPlayerAdded(player)
94
- if player == Players.LocalPlayer then
95
- return
96
- end
97
-
98
- local maid = Maid.new()
99
-
100
- maid:GiveTask(player.CharacterAdded:Connect(function(character)
101
- self:_onCharacterAdd(maid, character)
102
- end))
103
-
104
- if player.Character then
105
- self:_onCharacterAdd(maid, player.Character)
106
- end
107
-
108
- self._maid[player] = maid
109
- end
110
-
111
- function ClipCharacters:_bindUpdatesYielding()
112
- self._collisionGroupId = self._remoteFunction:InvokeServer()
113
-
114
- if not self._collisionGroupId then
115
- warn("[ClipCharacters] - No self._collisionGroupId")
116
- end
117
-
118
- for _, player in pairs(Players:GetPlayers()) do
119
- self:_onPlayerAdded(player)
120
- end
121
-
122
- self._maid:GiveTask(Players.PlayerAdded:Connect(function(player)
123
- self:_onPlayerAdded(player)
124
- end))
125
-
126
- self._maid:GiveTask(Players.PlayerRemoving:Connect(function(player)
127
- self._maid[player] = nil
128
- end))
129
- end
130
-
131
- --[=[
132
- Stop clipping on client
133
- ]=]
134
- function ClipCharacters:Destroy()
135
- self._maid:DoCleaning()
136
- self._maid = nil
137
-
138
- setmetatable({}, nil)
139
- end
140
-
141
- return ClipCharacters