cluaupp 0.2.2 → 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/CHANGELOG.md +14 -75
- package/README.md +42 -88
- package/docs/README.md +25 -21
- package/docs/architecture.md +13 -76
- package/docs/cli.md +12 -64
- package/docs/comparison.md +6 -24
- package/docs/config.md +6 -7
- package/docs/cpp-advanced.md +6 -3
- package/docs/cpp-types.md +2 -0
- package/docs/examples/combat.md +19 -227
- package/docs/examples/hud.md +13 -81
- package/docs/examples/index.md +9 -16
- package/docs/examples/leaderstats.md +44 -115
- package/docs/getting-started.md +20 -135
- package/docs/intellisense.md +5 -42
- package/docs/intro.md +16 -15
- package/docs/libraries/dataservice.md +4 -1
- package/docs/libraries/index.md +2 -1
- package/docs/libraries/more.md +3 -1
- package/docs/libraries/ui.md +76 -0
- package/docs/migration.md +38 -0
- package/docs/oop/file-tags.md +12 -36
- package/docs/oop/index.md +18 -11
- package/docs/roblox-api.md +4 -56
- package/docs/syntax.md +54 -179
- package/editors/vscode/extension.js +1 -1
- package/editors/vscode/package.json +4 -4
- package/examples/README.md +5 -7
- package/examples/game/.vscode/extensions.json +2 -2
- package/examples/game/.vscode/settings.json +6 -23
- package/examples/game/src/client/hud.client.clpp +54 -0
- package/examples/game/src/client/init.client.clpp +6 -0
- package/examples/game/src/server/combat.server.clpp +85 -0
- package/examples/game/src/server/leaderstats.server.clpp +28 -0
- package/examples/game/src/shared/PlayerData.clh +20 -0
- package/examples/game/src/shared/config.clp +6 -0
- package/examples/game/src/shared/features.clp +88 -0
- package/generated/api.js +15 -1
- package/generated/cli.js +40 -24
- package/generated/clpp/contract.js +5 -0
- package/generated/clpp/index.js +27 -0
- package/generated/clpp/paths.js +121 -0
- package/generated/clpp/postprocess.js +78 -0
- package/generated/clpp/runner.js +102 -0
- package/generated/compile.js +26 -138
- package/generated/emit.js +79 -3
- package/generated/intellisense.js +83 -207
- package/generated/lex.js +3 -0
- package/generated/libs.js +1 -1
- package/generated/lsp.js +1 -8
- package/generated/parse.js +119 -24
- package/generated/preprocess.js +8 -179
- package/generated/system-understander.js +1 -1
- package/generated/transpile.js +3 -50
- package/generated/utils/project.js +13 -28
- package/include/{cluaupp/datatypes.hpp → clpp/datatypes.clh} +5 -1
- package/include/{cluaupp/generated/instances.hpp → clpp/generated/instances.clh} +1 -1
- package/include/{cluaupp/libs/chrono.hpp → clpp/libs/chrono.clh} +9 -9
- package/include/{cluaupp/libs/cmdr.hpp → clpp/libs/cmdr.clh} +4 -4
- package/include/{cluaupp/libs/dataservice.hpp → clpp/libs/dataservice.clh} +8 -15
- package/include/{cluaupp/libs/display.hpp → clpp/libs/display.clh} +1 -2
- package/include/{cluaupp/libs/ezvisual.hpp → clpp/libs/ezvisual.clh} +1 -3
- package/include/{cluaupp/libs/formatnumber.hpp → clpp/libs/formatnumber.clh} +2 -3
- package/include/{cluaupp/libs/fusion.hpp → clpp/libs/fusion.clh} +5 -5
- package/include/{cluaupp/libs/iris.hpp → clpp/libs/iris.clh} +2 -2
- package/include/{cluaupp/libs/janitor.hpp → clpp/libs/janitor.clh} +1 -2
- package/include/{cluaupp/libs/module3d.hpp → clpp/libs/module3d.clh} +2 -4
- package/include/{cluaupp/libs/net.hpp → clpp/libs/net.clh} +2 -4
- package/include/{cluaupp/libs/promise.hpp → clpp/libs/promise.clh} +1 -4
- package/include/{cluaupp/libs/spring.hpp → clpp/libs/spring.clh} +1 -2
- package/include/{cluaupp/libs/statemachine.hpp → clpp/libs/statemachine.clh} +2 -3
- package/include/{cluaupp/libs/stickybillboard.hpp → clpp/libs/stickybillboard.clh} +1 -2
- package/include/{cluaupp/libs/topbarplus.hpp → clpp/libs/topbarplus.clh} +3 -4
- package/include/clpp/libs.clh +24 -0
- package/include/clpp/roblox.clh +31 -0
- package/package.json +20 -16
- package/src/api.ts +15 -1
- package/src/cli.ts +39 -25
- package/src/clpp/contract.ts +39 -0
- package/src/clpp/index.ts +18 -0
- package/src/clpp/paths.ts +117 -0
- package/src/clpp/postprocess.ts +93 -0
- package/src/clpp/runner.ts +102 -0
- package/src/compile.ts +26 -149
- package/src/intellisense.ts +82 -211
- package/src/libs.ts +1 -1
- package/src/lsp.ts +1 -5
- package/src/preprocess.ts +8 -180
- package/src/system-understander.ts +1 -1
- package/src/transpile.ts +9 -52
- package/src/utils/project.ts +12 -28
- package/templates/game/.vscode/extensions.json +2 -2
- package/templates/game/.vscode/settings.json +6 -23
- package/templates/game/src/client/init.client.clpp +6 -0
- package/templates/game/src/server/leaderstats.server.clpp +29 -0
- package/templates/game/src/shared/config.clp +6 -0
- package/examples/game/.clangd +0 -25
- package/examples/game/.vscode/c_cpp_properties.json +0 -27
- package/examples/game/compile_flags.txt +0 -6
- package/examples/game/src/client/hud.client.cpp +0 -12
- package/examples/game/src/client/init.client.cpp +0 -6
- package/examples/game/src/server/combat.server.cpp +0 -23
- package/examples/game/src/server/leaderstats.server.cpp +0 -29
- package/examples/game/src/shared/config.cpp +0 -5
- package/examples/game/src/shared/config.h +0 -5
- package/include/cluaupp/libs.hpp +0 -25
- package/include/cluaupp/roblox.hpp +0 -47
- package/src/architecture.ts +0 -500
- package/src/ast.ts +0 -37
- package/src/emit.ts +0 -531
- package/src/emitter/luau-codegen.ts +0 -187
- package/src/emitter/translators.ts +0 -168
- package/src/headers.ts +0 -233
- package/src/layout.ts +0 -114
- package/src/lex.ts +0 -155
- package/src/parse.ts +0 -630
- package/src/parser/collector.ts +0 -148
- package/src/parser/index.ts +0 -27
- package/src/tree-sitter-cpp.d.ts +0 -4
- package/src/understand.ts +0 -322
- package/templates/game/.vscode/c_cpp_properties.json +0 -27
- package/templates/game/src/client/init.client.cpp +0 -6
- package/templates/game/src/server/leaderstats.server.cpp +0 -29
- package/templates/game/src/shared/config.cpp +0 -5
- package/templates/game/src/shared/config.h +0 -5
- /package/include/{cluaupp/generated/enums.hpp → clpp/generated/enums.clh} +0 -0
- /package/include/{cluaupp/libs/math.hpp → clpp/libs/math.clh} +0 -0
- /package/include/{cluaupp/libs/twinkle.hpp → clpp/libs/twinkle.clh} +0 -0
- /package/include/{cluaupp/libs/vfx.hpp → clpp/libs/vfx.clh} +0 -0
package/docs/syntax.md
CHANGED
|
@@ -1,205 +1,80 @@
|
|
|
1
|
-
#
|
|
1
|
+
# CL++ syntax (Cluaupp)
|
|
2
2
|
|
|
3
|
-
Cluaupp
|
|
4
|
-
|
|
5
|
-
Generated Luau follows the current language: [`local`](https://luau.org/getting-started), `const`, and `const function`. Injected `require` / `GetService` lines are `const`. `--!strict` is emitted only when the file has `#pragma strict` (or `"strict": true` in config).
|
|
3
|
+
Cluaupp does **not** define the language. Write CL++ (`.clpp` / `.clp` / `.clh`); `clpp` emits Luau. Full course and reference: **[kartzrbx.github.io/CLPP](https://kartzrbx.github.io/CLPP/)**.
|
|
6
4
|
|
|
7
5
|
## Files
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
## Functions
|
|
17
|
-
|
|
18
|
-
```cpp
|
|
19
|
-
void CreateLeaderstats(Player* player) {
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
int doubleCoins(int coins) {
|
|
24
|
-
return coins;
|
|
25
|
-
}
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
```luau
|
|
29
|
-
const function CreateLeaderstats(player: Player)
|
|
30
|
-
return
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
const function doubleCoins(coins: number): number
|
|
34
|
-
return coins
|
|
35
|
-
end
|
|
36
|
-
```
|
|
7
|
+
| Source | Rojo |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| `*.server.clpp` | Script |
|
|
10
|
+
| `*.client.clpp` | LocalScript |
|
|
11
|
+
| `*.plugin.clpp` | Plugin Script |
|
|
12
|
+
| `*.clp` / untagged `.clpp` | ModuleScript |
|
|
13
|
+
| `*.clh` | ModuleScript (types / structs) |
|
|
37
14
|
|
|
38
|
-
`void`
|
|
15
|
+
`void init()` is the script entry. There is no `int main()`.
|
|
39
16
|
|
|
40
|
-
|
|
17
|
+
## Accessors
|
|
41
18
|
|
|
42
|
-
|
|
19
|
+
CL++ does **not** use `->`.
|
|
43
20
|
|
|
44
|
-
|
|
21
|
+
| Write | Meaning | Luau |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| `player.Name` | property | `.` |
|
|
24
|
+
| `player::FindFirstChild("x")` | method | `:` |
|
|
25
|
+
| `DataService:Server` | table key | `.` |
|
|
26
|
+
| `"hi " .: name` | concat | `..` |
|
|
27
|
+
| `signal~>Connect(fn)` | janitor Connect | `janitor:Add(..., "Disconnect")` |
|
|
28
|
+
| `signal~>Once(fn)` | one-shot | `Once` + janitor |
|
|
45
29
|
|
|
46
|
-
|
|
47
|
-
int coins = 10;
|
|
48
|
-
const int STARTING_COINS = 0;
|
|
49
|
-
auto* folder = new Folder(player);
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
```luau
|
|
53
|
-
local coins: number = 10
|
|
54
|
-
const STARTING_COINS: number = 0
|
|
55
|
-
local folder: Folder = Instance.new("Folder")
|
|
56
|
-
folder.Parent = player
|
|
57
|
-
```
|
|
30
|
+
`post` / `warn` / `report` → `print` / `warn` / `error`. `null` is `nil`.
|
|
58
31
|
|
|
59
|
-
|
|
32
|
+
## Exclusive CL++ (compiled by `clpp`)
|
|
60
33
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (player->FindFirstChild("leaderstats") != nullptr) {
|
|
34
|
+
```clpp
|
|
35
|
+
guard (player != null) else {
|
|
36
|
+
warn("Invalid player");
|
|
65
37
|
return;
|
|
66
|
-
} else {
|
|
67
|
-
print("ok");
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
while (true) {
|
|
71
|
-
print("tick");
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
for (auto* player : players->GetPlayers()) {
|
|
75
|
-
CreateLeaderstats(player);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
switch (action) {
|
|
79
|
-
case "buy":
|
|
80
|
-
case "purchase":
|
|
81
|
-
Grant(player);
|
|
82
|
-
break;
|
|
83
|
-
case "sell":
|
|
84
|
-
if (amount <= 0) {
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
Take(player);
|
|
88
|
-
break;
|
|
89
|
-
default:
|
|
90
|
-
warn("unknown");
|
|
91
|
-
break;
|
|
92
38
|
}
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
```luau
|
|
96
|
-
if player:FindFirstChild("leaderstats") ~= nil then
|
|
97
|
-
return
|
|
98
|
-
else
|
|
99
|
-
print("ok")
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
while true do
|
|
103
|
-
print("tick")
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
for _, player in players:GetPlayers() do
|
|
107
|
-
CreateLeaderstats(player)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
repeat
|
|
111
|
-
if action == "buy" or action == "purchase" then
|
|
112
|
-
Grant(player)
|
|
113
|
-
elseif action == "sell" then
|
|
114
|
-
if amount <= 0 then
|
|
115
|
-
break
|
|
116
|
-
end
|
|
117
|
-
Take(player)
|
|
118
|
-
else
|
|
119
|
-
warn("unknown")
|
|
120
|
-
end
|
|
121
|
-
until true
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
`switch` evaluates the discriminant **once**, then becomes `if` / `elseif` / `else` inside `repeat … until true` so `break` still exits the switch (even from inside an `if`). Stacked `case` labels share a body (`case "buy": case "purchase":`). There is no C-style fall-through into the next case’s statements. C-style `for (int i = 0; i < n; i++)` is not supported yet.
|
|
125
39
|
|
|
126
|
-
|
|
40
|
+
match (child) {
|
|
41
|
+
BasePart* p => BindPart(p),
|
|
42
|
+
Model* m => post("model spawned " .: m.Name),
|
|
43
|
+
_ => warn("ignored instance")
|
|
44
|
+
};
|
|
127
45
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
| `true` / `false` | `true` / `false` |
|
|
132
|
-
| `!=` | `~=` |
|
|
133
|
-
| `&&` | `and` |
|
|
134
|
-
| `\|\|` | `or` |
|
|
135
|
-
| `==` `+` `-` `*` `/` `<` `>` `<=` `>=` | same |
|
|
136
|
-
| `"text"` | `"text"` |
|
|
137
|
-
| `obj->Prop` | `obj.Prop` |
|
|
138
|
-
| `obj->Method(a)` | `obj:Method(a)` if the method is a Roblox API |
|
|
139
|
-
| `fn(a)` | `fn(a)` |
|
|
140
|
-
| `signal.Connect(fn)` | `signal:Connect(fn)` |
|
|
141
|
-
| `Type { .Field = value }` | `{ Field = value }` |
|
|
142
|
-
|
|
143
|
-
Designated initializers become Luau tables. Nested braces work the same way:
|
|
144
|
-
|
|
145
|
-
```cpp
|
|
146
|
-
DataService::Server.Init(DataServiceOptions {
|
|
147
|
-
.Template = playerData,
|
|
148
|
-
.StoreName = "PlayerData",
|
|
149
|
-
.UseMock = true,
|
|
46
|
+
observable int wallet = 100;
|
|
47
|
+
wallet.OnChange(func [](int newValue) {
|
|
48
|
+
post("Coins changed to: " .: newValue);
|
|
150
49
|
});
|
|
151
|
-
```
|
|
152
50
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
})
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
## `new` and services
|
|
162
|
-
|
|
163
|
-
```cpp
|
|
164
|
-
auto* coins = new IntValue(leaderstats);
|
|
165
|
-
auto* players = GetService<Players>();
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
```luau
|
|
169
|
-
local coins: IntValue = Instance.new("IntValue")
|
|
170
|
-
coins.Parent = leaderstats
|
|
171
|
-
local players: Players = game:GetService("Players")
|
|
172
|
-
```
|
|
51
|
+
signal<Player*, int> OnHit;
|
|
52
|
+
OnHit~>Connect(func [](Player* player, int amount) {
|
|
53
|
+
post(player.Name .: " dmg " .: amount);
|
|
54
|
+
});
|
|
55
|
+
OnHit::Fire(player, 10);
|
|
173
56
|
|
|
174
|
-
|
|
57
|
+
array<string> names = {"Kartz", "Player1"};
|
|
58
|
+
dictionary<string, int> stats = { {"Coins", 100}, {"Gems", 50} };
|
|
175
59
|
|
|
176
|
-
|
|
60
|
+
spawn { task::wait(1); post("ready"); };
|
|
61
|
+
parallel { post("desync"); };
|
|
177
62
|
|
|
178
|
-
|
|
63
|
+
async Data* FetchData(Player* player) {
|
|
64
|
+
return await DataService:Server::WaitFor(player);
|
|
65
|
+
}
|
|
179
66
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
cout::print << "EnsureStat: " << name << " not found" << endl;
|
|
183
|
-
cerr << "failed";
|
|
184
|
-
cout::print("ok");
|
|
185
|
-
cout::warn("careful");
|
|
186
|
-
cout::error("fail");
|
|
187
|
-
cout::ping("here");
|
|
188
|
-
```
|
|
67
|
+
[[server]]
|
|
68
|
+
void SaveData(Player* player) { post(player.Name); }
|
|
189
69
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
warn("failed")
|
|
193
|
-
print("ok")
|
|
194
|
-
warn("careful")
|
|
195
|
-
error("fail")
|
|
196
|
-
print("here")
|
|
70
|
+
[[client]]
|
|
71
|
+
void UpdateUI() { post("ui"); }
|
|
197
72
|
```
|
|
198
73
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
## Not supported yet
|
|
74
|
+
Fusion HUD uses `Fusion:scoped`, `Fusion:Value`, `Fusion:Computed`, `Fusion:New`. See [`examples/game`](../examples/game) (`combat.server.clpp`, `hud.client.clpp`, `features.clp`, `PlayerData.clh`).
|
|
202
75
|
|
|
203
|
-
|
|
76
|
+
## What Cluaupp adds after `clpp`
|
|
204
77
|
|
|
205
|
-
|
|
78
|
+
- `require(ClppLibs.X)` → `require(ReplicatedStorage.CluauppLibs.X)`
|
|
79
|
+
- `--!strict` from `cluaupp.config.json` / `#pragma strict`
|
|
80
|
+
- `out/` layout for Rojo (`init`, `build`, `watch`)
|
|
@@ -55,7 +55,7 @@ function activate(context) {
|
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
const refreshDiagnostics = (document) => {
|
|
58
|
-
if (!document || document.languageId !== "cpp") {
|
|
58
|
+
if (!document || (document.languageId !== "clpp" && document.languageId !== "cpp")) {
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
61
|
if (typeof loaded.engine.diagnosticsFor !== "function") {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cluaupp-diagnostics",
|
|
3
3
|
"displayName": "Cluaupp",
|
|
4
|
-
"description": "Cluaupp
|
|
5
|
-
"version": "0.
|
|
4
|
+
"description": "Cluaupp project diagnostics. Language highlighting and IntelliSense come from clpp install (CL++).",
|
|
5
|
+
"version": "1.0.0",
|
|
6
6
|
"publisher": "kartzdev",
|
|
7
7
|
"engines": {
|
|
8
8
|
"vscode": "^1.74.0"
|
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
"Linters"
|
|
12
12
|
],
|
|
13
13
|
"activationEvents": [
|
|
14
|
-
"onLanguage:
|
|
14
|
+
"onLanguage:clpp"
|
|
15
15
|
],
|
|
16
16
|
"main": "./extension.js",
|
|
17
17
|
"contributes": {
|
|
18
18
|
"commands": [
|
|
19
19
|
{
|
|
20
20
|
"command": "cluaupp.restartIntelliSense",
|
|
21
|
-
"title": "Cluaupp: Reload
|
|
21
|
+
"title": "Cluaupp: Reload CL++ diagnostics"
|
|
22
22
|
}
|
|
23
23
|
]
|
|
24
24
|
}
|
package/examples/README.md
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
# Sample game
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
CL++ sources for a Cluaupp project — **not** the compiler. Language samples: [CL++ examples](https://github.com/KartzRbx/CLPP/tree/main/examples).
|
|
4
4
|
|
|
5
5
|
| Folder | Rojo | Tag |
|
|
6
6
|
| --- | --- | --- |
|
|
7
|
-
| `src/server/*.server.
|
|
8
|
-
| `src/client/*.client.
|
|
9
|
-
| `src/shared
|
|
10
|
-
|
|
11
|
-
`src/` of **this repo** is the TypeScript CLI ([roblox-ts](https://github.com/roblox-ts/roblox-ts) does the same). The sample scripts live here so they never mix with `understand.ts`.
|
|
7
|
+
| `src/server/*.server.clpp` | Script | server |
|
|
8
|
+
| `src/client/*.client.clpp` | LocalScript | client |
|
|
9
|
+
| `src/shared/*.clp` / `*.clh` | ModuleScript | none |
|
|
12
10
|
|
|
13
11
|
```bash
|
|
14
12
|
cd examples/game
|
|
15
13
|
npx cluaupp build .
|
|
16
14
|
```
|
|
17
15
|
|
|
18
|
-
`cluaupp init` copies `templates/game
|
|
16
|
+
`cluaupp init` copies `templates/game`. This folder adds combat (`guard` / `match` / `signal` / `observable` / `spawn`), a Fusion HUD, `features.clp`, and `PlayerData.clh`.
|
|
@@ -1,27 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"C_Cpp.intelliSenseEngine": "Disabled",
|
|
3
|
-
"C_Cpp.default.cppStandard": "c++20",
|
|
4
|
-
"C_Cpp.default.cStandard": "c17",
|
|
5
|
-
"C_Cpp.default.compilerPath": "clang++",
|
|
6
|
-
"C_Cpp.default.intelliSenseMode": "windows-clang-x64",
|
|
7
|
-
"C_Cpp.default.includePath": [
|
|
8
|
-
"${workspaceFolder}/include",
|
|
9
|
-
"${workspaceFolder}/src"
|
|
10
|
-
],
|
|
11
|
-
"clangd.enable": true,
|
|
12
|
-
"clangd.arguments": [
|
|
13
|
-
"--compile-commands-dir=${workspaceFolder}",
|
|
14
|
-
"--header-insertion=never",
|
|
15
|
-
"--query-driver=**/clang++*,**/clang++.exe,**/g++*,**/g++.exe"
|
|
16
|
-
],
|
|
17
2
|
"files.associations": {
|
|
18
|
-
"*.
|
|
19
|
-
"*.
|
|
20
|
-
"*.
|
|
21
|
-
"*.
|
|
22
|
-
"*.
|
|
23
|
-
"*.
|
|
24
|
-
"*.legacy.server.cpp": "cpp",
|
|
25
|
-
"*.legacy.client.cpp": "cpp"
|
|
3
|
+
"*.clpp": "clpp",
|
|
4
|
+
"*.clp": "clpp",
|
|
5
|
+
"*.clh": "clpp",
|
|
6
|
+
"*.server.clpp": "clpp",
|
|
7
|
+
"*.client.clpp": "clpp",
|
|
8
|
+
"*.plugin.clpp": "clpp"
|
|
26
9
|
}
|
|
27
10
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#pragma strict
|
|
2
|
+
#include <clpp/roblox.clh>
|
|
3
|
+
#include <clpp/libs/fusion.clh>
|
|
4
|
+
|
|
5
|
+
[[client]]
|
|
6
|
+
void init() {
|
|
7
|
+
Players* players = GetService<Players>();
|
|
8
|
+
Player* localPlayer = players.LocalPlayer;
|
|
9
|
+
guard (localPlayer != null) else {
|
|
10
|
+
report("LocalPlayer missing");
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
Instance* playerGui = localPlayer::WaitForChild("PlayerGui");
|
|
15
|
+
auto scope = Fusion:scoped();
|
|
16
|
+
auto Children = Fusion:Children;
|
|
17
|
+
|
|
18
|
+
auto coins = Fusion:Value(scope, 0);
|
|
19
|
+
auto title = Fusion:Computed(scope, func []() {
|
|
20
|
+
return "Coins: " .: coins();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
auto newScreenGui = Fusion:New(scope, "ScreenGui");
|
|
24
|
+
auto newFrame = Fusion:New(scope, "Frame");
|
|
25
|
+
auto newLabel = Fusion:New(scope, "TextLabel");
|
|
26
|
+
|
|
27
|
+
auto label = newLabel({
|
|
28
|
+
{"Name", "Amount"},
|
|
29
|
+
{"BackgroundTransparency", 1},
|
|
30
|
+
{"Size", UDim2.fromScale(1, 1)},
|
|
31
|
+
{"Text", title},
|
|
32
|
+
{"TextColor3", Color3.fromRGB(255, 255, 255)},
|
|
33
|
+
{"TextScaled", true}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
auto frame = newFrame({
|
|
37
|
+
{"Name", "Hud"},
|
|
38
|
+
{"AnchorPoint", Vector2(0, 1)},
|
|
39
|
+
{"Position", UDim2.fromScale(0, 1)},
|
|
40
|
+
{"Size", UDim2.fromOffset(220, 64)},
|
|
41
|
+
{"BackgroundColor3", Color3.fromRGB(28, 18, 48)},
|
|
42
|
+
{Children, label}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
newScreenGui({
|
|
46
|
+
{"Name", "CoinsHud"},
|
|
47
|
+
{"ResetOnSpawn", false},
|
|
48
|
+
{"Parent", playerGui},
|
|
49
|
+
{Children, frame}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
coins(100);
|
|
53
|
+
post("hud ready");
|
|
54
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#pragma strict
|
|
2
|
+
#include <clpp/roblox.clh>
|
|
3
|
+
#include <clpp/libs/janitor.clh>
|
|
4
|
+
|
|
5
|
+
struct CombatServer {
|
|
6
|
+
Janitor* janitor;
|
|
7
|
+
signal<Player*, int> OnHit;
|
|
8
|
+
void PlayerEntered(Player* player);
|
|
9
|
+
void BindPart(BasePart* part);
|
|
10
|
+
void WatchWorkspace();
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
void CombatServer::BindPart(BasePart* part) {
|
|
14
|
+
guard (part != null) else {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
part.Touched~>Once(func [](BasePart* other) {
|
|
19
|
+
Instance* character = other.Parent;
|
|
20
|
+
guard (character != null) else {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
match (character::FindFirstChild("Humanoid")) {
|
|
25
|
+
Humanoid* humanoid => {
|
|
26
|
+
guard (humanoid.Health > 0) else {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
Players* players = GetService<Players>();
|
|
30
|
+
Player* player = players::GetPlayerFromCharacter(character);
|
|
31
|
+
guard (player != null) else {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
OnHit::Fire(player, 10);
|
|
35
|
+
part::Destroy();
|
|
36
|
+
},
|
|
37
|
+
_ => warn("touch without humanoid")
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
void CombatServer::PlayerEntered(Player* player) {
|
|
43
|
+
guard (player != null) else {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
observable int combo = 0;
|
|
48
|
+
OnHit~>Connect(func [](Player* victim, int amount) {
|
|
49
|
+
guard (victim == player) else {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
combo = combo + 1;
|
|
53
|
+
post(player.Name .: " combo " .: combo .: " dmg " .: amount);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
[[server]]
|
|
58
|
+
void CombatServer::WatchWorkspace() {
|
|
59
|
+
workspace.ChildAdded~>Connect(func [](Instance* child) {
|
|
60
|
+
match (child) {
|
|
61
|
+
BasePart* p => BindPart(p),
|
|
62
|
+
Model* m => post("model spawned " .: m.Name),
|
|
63
|
+
_ => warn("ignored instance")
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
void init() {
|
|
69
|
+
CombatServer combat;
|
|
70
|
+
combat.janitor = new Janitor();
|
|
71
|
+
|
|
72
|
+
spawn {
|
|
73
|
+
task::wait(1);
|
|
74
|
+
post("combat ready");
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
Players* players = GetService<Players>();
|
|
78
|
+
for (Player* player : players::GetPlayers()) {
|
|
79
|
+
combat::PlayerEntered(player);
|
|
80
|
+
}
|
|
81
|
+
players::PlayerAdded~>Connect(func [](Player* p) {
|
|
82
|
+
combat::PlayerEntered(p);
|
|
83
|
+
});
|
|
84
|
+
combat::WatchWorkspace();
|
|
85
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#pragma strict
|
|
2
|
+
#include <clpp/roblox.clh>
|
|
3
|
+
|
|
4
|
+
void CreateLeaderstats(Player* player) {
|
|
5
|
+
if (player::FindFirstChild("leaderstats") != null) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
Folder* leaderstats = new Folder(player);
|
|
10
|
+
leaderstats.Name = "leaderstats";
|
|
11
|
+
|
|
12
|
+
IntValue* coins = new IntValue(leaderstats);
|
|
13
|
+
coins.Name = "Coins";
|
|
14
|
+
coins.Value = 0;
|
|
15
|
+
|
|
16
|
+
IntValue* level = new IntValue(leaderstats);
|
|
17
|
+
level.Name = "Level";
|
|
18
|
+
level.Value = 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
void init() {
|
|
22
|
+
Players* players = GetService<Players>();
|
|
23
|
+
for (Player* player : players::GetPlayers()) {
|
|
24
|
+
CreateLeaderstats(player);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
players::PlayerAdded::Connect(CreateLeaderstats);
|
|
28
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <clpp/datatypes.clh>
|
|
4
|
+
|
|
5
|
+
struct PlayerDataCurrencies {
|
|
6
|
+
int Coins = 0;
|
|
7
|
+
int Rebirths = 0;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
struct PlayerDataInventory {
|
|
11
|
+
array<int> HotBar;
|
|
12
|
+
array<int> Storage;
|
|
13
|
+
|
|
14
|
+
int MaxStorage = 90;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
struct PlayerData {
|
|
18
|
+
PlayerDataCurrencies Currencies;
|
|
19
|
+
PlayerDataInventory Inventory;
|
|
20
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#include <clpp/roblox.clh>
|
|
3
|
+
|
|
4
|
+
void ShowcaseFeatures(int coins, Player* playerRef) {
|
|
5
|
+
int n = 100;
|
|
6
|
+
float speed = 16.5;
|
|
7
|
+
string name = "Kartz";
|
|
8
|
+
bool isActive = true;
|
|
9
|
+
func callback = []() {};
|
|
10
|
+
(void)speed;
|
|
11
|
+
(void)isActive;
|
|
12
|
+
(void)callback;
|
|
13
|
+
|
|
14
|
+
array<string> names = {"Kartz", "Player1"};
|
|
15
|
+
dictionary<string, int> stats = {
|
|
16
|
+
{"Coins", 100},
|
|
17
|
+
{"Gems", 50}
|
|
18
|
+
};
|
|
19
|
+
(void)names;
|
|
20
|
+
(void)stats;
|
|
21
|
+
|
|
22
|
+
if (coins > 50) {
|
|
23
|
+
post("Enough balance!");
|
|
24
|
+
} else if (coins == 0) {
|
|
25
|
+
warn("No coins!");
|
|
26
|
+
} else {
|
|
27
|
+
report("Balance sync error.");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
for (int i = 0; i < 10; i++) {
|
|
31
|
+
post("Count: " .: i);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
n += 1;
|
|
35
|
+
|
|
36
|
+
observable int wallet = 100;
|
|
37
|
+
wallet.OnChange(func [](int newValue) {
|
|
38
|
+
post("Coins changed to: " .: newValue);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
signal<Player*, int> OnCoinsUpdated;
|
|
42
|
+
OnCoinsUpdated~>Connect(func [](Player* player, int newAmount) {
|
|
43
|
+
post("New coins for " .: player.Name .: ": " .: newAmount);
|
|
44
|
+
});
|
|
45
|
+
OnCoinsUpdated~>Once(func [](Player* player, int newAmount) {
|
|
46
|
+
(void)newAmount;
|
|
47
|
+
post("First coins for " .: player.Name);
|
|
48
|
+
});
|
|
49
|
+
OnCoinsUpdated::Fire(playerRef, wallet);
|
|
50
|
+
|
|
51
|
+
guard (playerRef != null) else {
|
|
52
|
+
warn("Invalid player");
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
playerRef::GetPropertyChangedSignal("Name")~>Connect(func []() {
|
|
57
|
+
post("Name changed");
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
auto [success, result] = pcall(func []() {
|
|
61
|
+
return 1;
|
|
62
|
+
});
|
|
63
|
+
(void)result;
|
|
64
|
+
|
|
65
|
+
const int moeda = 4;
|
|
66
|
+
match (moeda) {
|
|
67
|
+
int a => post(a),
|
|
68
|
+
_ => post("Not found")
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
if (success) {
|
|
72
|
+
post("Data loaded successfully!");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
spawn {
|
|
76
|
+
task::wait(2);
|
|
77
|
+
post("Delay finished!");
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
parallel {
|
|
81
|
+
post("desync");
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
match (name) {
|
|
85
|
+
string s => post(s),
|
|
86
|
+
_ => warn("Instance not supported")
|
|
87
|
+
};
|
|
88
|
+
}
|