Migrate to flamework + strating rewrite ragdoll.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,3 +2,4 @@
|
||||
/out
|
||||
/include
|
||||
*.tsbuildinfo
|
||||
flamework.build
|
||||
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
@@ -11,5 +11,10 @@
|
||||
},
|
||||
"eslint.run": "onType",
|
||||
"eslint.format.enable": true,
|
||||
"eslint.useFlatConfig": false
|
||||
"eslint.useFlatConfig": false,
|
||||
"files.autoSave": "onWindowChange",
|
||||
"editor.formatOnSave": true,
|
||||
"files.associations": {
|
||||
"*.luau": "lua"
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,9 @@
|
||||
"$className": "Folder",
|
||||
"@rbxts": {
|
||||
"$path": "node_modules/@rbxts"
|
||||
},
|
||||
"@flamework": {
|
||||
"$path": "node_modules/@flamework"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -46,6 +46,9 @@ export default defineConfig([
|
||||
|
||||
rules: {
|
||||
"prettier/prettier": "warn",
|
||||
"@typescript-eslint/no-unused-vars": ["error", {
|
||||
"varsIgnorePattern": "^[A-Z].*(Service|Controller|Component)$"
|
||||
}]
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
990
package-lock.json
generated
990
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
11
package.json
11
package.json
@@ -9,14 +9,13 @@
|
||||
"lint": "eslint"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"author": "Aconit team",
|
||||
"license": "ISC",
|
||||
"type": "commonjs",
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@eslint/js": "^9.37.0",
|
||||
"@rbxts/compiler-types": "^3.0.0-types.0",
|
||||
"@rbxts/net": "^3.0.10",
|
||||
"@rbxts/services": "^1.5.5",
|
||||
"@rbxts/signal": "^1.1.1",
|
||||
"@rbxts/types": "^1.0.882",
|
||||
@@ -27,11 +26,15 @@
|
||||
"eslint-plugin-prettier": "^5.5.4",
|
||||
"eslint-plugin-roblox-ts": "^1.2.1",
|
||||
"prettier": "^3.6.2",
|
||||
"rbxts-transformer-flamework": "^1.3.2",
|
||||
"rbxts-transformer-instances": "^1.0.1",
|
||||
"rbxts-transformer-services": "^1.1.1",
|
||||
"roblox-ts": "^3.0.0",
|
||||
"typescript": "^5.9.2"
|
||||
"typescript": "~5.5.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"-": "^0.0.1"
|
||||
"@flamework/components": "^1.3.2",
|
||||
"@flamework/core": "^1.3.2",
|
||||
"@flamework/networking": "^1.3.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
import { Players, UserInputService } from "@rbxts/services";
|
||||
import Gameplay_Remotes from "shared/gameplay";
|
||||
import { UserInputService } from "@rbxts/services";
|
||||
import { GameplayClientEvents } from "./networking";
|
||||
import { Controller, OnStart } from "@flamework/core";
|
||||
|
||||
const sprint = Gameplay_Remotes.Client.Get("Sprint");
|
||||
|
||||
UserInputService.InputBegan.Connect((input) => {
|
||||
@Controller()
|
||||
class GameplayController implements OnStart {
|
||||
onStart(): void {
|
||||
UserInputService.InputBegan.Connect((input) => {
|
||||
if (input.KeyCode === Enum.KeyCode.LeftShift) {
|
||||
sprint.SendToServer(true);
|
||||
GameplayClientEvents.sprint(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
UserInputService.InputEnded.Connect((input) => {
|
||||
UserInputService.InputEnded.Connect((input) => {
|
||||
if (input.KeyCode === Enum.KeyCode.LeftShift) {
|
||||
sprint.SendToServer(false);
|
||||
GameplayClientEvents.sprint(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
3
src/client/networking.ts
Normal file
3
src/client/networking.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { GameplayEvents } from "shared/networking";
|
||||
|
||||
export const GameplayClientEvents = GameplayEvents.createClient({});
|
||||
@@ -1,29 +1,35 @@
|
||||
import { OnInit, OnStart, Service } from "@flamework/core";
|
||||
import { Players, TextChatService } from "@rbxts/services";
|
||||
import { makeRagdoll, stopRagdoll, takeNetworkOwner } from "shared/ragdoll";
|
||||
|
||||
const ragdollCommand = new Instance("TextChatCommand");
|
||||
ragdollCommand.Parent = TextChatService.WaitForChild("TextChatCommands");
|
||||
ragdollCommand.PrimaryAlias = "/ragdoll";
|
||||
ragdollCommand.Triggered.Connect((TextSource) => {
|
||||
/**
|
||||
* Setup Chat Command
|
||||
*/
|
||||
@Service()
|
||||
class CommandsService implements OnStart {
|
||||
onStart(): void {
|
||||
const ragdollCommand = new TextChatCommand();
|
||||
ragdollCommand.Parent = TextChatService.WaitForChild("TextChatCommands");
|
||||
ragdollCommand.PrimaryAlias = "/ragdoll";
|
||||
ragdollCommand.Triggered.Connect((TextSource) => {
|
||||
const player = Players.GetPlayerByUserId(TextSource.UserId);
|
||||
|
||||
makeRagdoll(player!.Character!);
|
||||
});
|
||||
});
|
||||
|
||||
const unragdollCommand = new Instance("TextChatCommand");
|
||||
unragdollCommand.Parent = TextChatService.WaitForChild("TextChatCommands");
|
||||
unragdollCommand.PrimaryAlias = "/unragdoll";
|
||||
unragdollCommand.Triggered.Connect((TextSource) => {
|
||||
const unragdollCommand = new TextChatCommand();
|
||||
unragdollCommand.Parent = TextChatService.WaitForChild("TextChatCommands");
|
||||
unragdollCommand.PrimaryAlias = "/unragdoll";
|
||||
unragdollCommand.Triggered.Connect((TextSource) => {
|
||||
const player = Players.GetPlayerByUserId(TextSource.UserId);
|
||||
|
||||
stopRagdoll(player!.Character!);
|
||||
});
|
||||
});
|
||||
|
||||
const takeownerCommand = new Instance("TextChatCommand");
|
||||
takeownerCommand.Parent = TextChatService.WaitForChild("TextChatCommands");
|
||||
takeownerCommand.PrimaryAlias = "/takeowner";
|
||||
takeownerCommand.Triggered.Connect((TextSource) => {
|
||||
const takeownerCommand = new TextChatCommand();
|
||||
takeownerCommand.Parent = TextChatService.WaitForChild("TextChatCommands");
|
||||
takeownerCommand.PrimaryAlias = "/takeowner";
|
||||
takeownerCommand.Triggered.Connect((TextSource) => {
|
||||
const player = Players.GetPlayerByUserId(TextSource.UserId);
|
||||
|
||||
takeNetworkOwner(player!.Character!);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
import { OnStart, Service } from "@flamework/core";
|
||||
import { ReplicatedStorage } from "@rbxts/services";
|
||||
import { randomDecorationPlace } from "shared/build";
|
||||
|
||||
const flowers = ReplicatedStorage.FindFirstChild("Decoration")?.FindFirstChild("FlowerTypes")?.GetChildren();
|
||||
if (flowers) {
|
||||
/** Place Decorator on map. */
|
||||
@Service()
|
||||
class DecoratorService implements OnStart {
|
||||
onStart(): void {
|
||||
//#region Castle
|
||||
const flowers = ReplicatedStorage.FindFirstChild("Decoration")?.FindFirstChild("FlowerTypes")?.GetChildren();
|
||||
if (flowers) {
|
||||
randomDecorationPlace("Build_Flower", flowers as Model[]);
|
||||
}
|
||||
}
|
||||
|
||||
const rocks = ReplicatedStorage.FindFirstChild("Decoration")?.FindFirstChild("RockTypes")?.GetChildren();
|
||||
if (rocks) {
|
||||
const rocks = ReplicatedStorage.FindFirstChild("Decoration")?.FindFirstChild("RockTypes")?.GetChildren();
|
||||
if (rocks) {
|
||||
randomDecorationPlace("Build_Gravel", rocks as Model[]);
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,62 +1,74 @@
|
||||
import { Players } from "@rbxts/services";
|
||||
import Gameplay_Remotes from "shared/gameplay";
|
||||
import { GameplayServerEvents } from "./networking";
|
||||
import { OnStart, Service } from "@flamework/core";
|
||||
import { getRagdollEvent, makeRagdoll, prepareRagdoll, stopRagdoll, waitMotionLess } from "shared/ragdoll";
|
||||
|
||||
const sprint = Gameplay_Remotes.Server.Get("Sprint");
|
||||
/**
|
||||
* Service related to Gameplay.
|
||||
* - Contains Script related to Sprinting, Ragdoll, etc.
|
||||
*/
|
||||
@Service()
|
||||
class GameplayService implements OnStart {
|
||||
// Sprint config.
|
||||
private base_sprint_speed = 16;
|
||||
private sprint_speed = 1.5;
|
||||
private is_running = new Map<number, boolean>();
|
||||
|
||||
const RunAnim = new Instance("Animation");
|
||||
RunAnim.AnimationId = "rbxassetid://88297455683117";
|
||||
const base_sprint_speed = 16;
|
||||
const sprint_speed = 1.5;
|
||||
const runanim = new Map<number, AnimationTrack>();
|
||||
const isrunning = new Map<number, boolean>();
|
||||
onStart(): void {
|
||||
// Handle Animation.
|
||||
const RunAnim = new Animation();
|
||||
RunAnim.AnimationId = "rbxassetid://88297455683117";
|
||||
|
||||
Players.PlayerAdded.Connect((player) => {
|
||||
let runningConn: RBXScriptConnection;
|
||||
Players.PlayerAdded.Connect((player) => {
|
||||
let running_connection: RBXScriptConnection;
|
||||
|
||||
player.CharacterAdded.Connect((character) => {
|
||||
prepareRagdoll(character);
|
||||
getRagdollEvent(character).Connect(() => {
|
||||
makeRagdoll(character);
|
||||
waitMotionLess(character, 0.1).Wait();
|
||||
stopRagdoll(character);
|
||||
});
|
||||
|
||||
const humanoid = character.FindFirstChildWhichIsA("Humanoid");
|
||||
if (humanoid) {
|
||||
const animator = humanoid.FindFirstChildOfClass("Animator");
|
||||
const anim = animator!.LoadAnimation(RunAnim);
|
||||
anim.Priority = Enum.AnimationPriority.Action;
|
||||
runanim.set(player.UserId, anim);
|
||||
// Setup the animation.
|
||||
const animator = humanoid.WaitForChild("Animator") as Animator;
|
||||
const animation_track = animator.LoadAnimation(RunAnim);
|
||||
animation_track.Priority = Enum.AnimationPriority.Action;
|
||||
|
||||
runningConn = humanoid.Running.Connect((speed) => {
|
||||
if (isrunning.get(player.UserId)) {
|
||||
// Change the animation when the running speed change.
|
||||
running_connection = humanoid.Running.Connect((speed) => {
|
||||
if (this.is_running.get(player.UserId)) {
|
||||
if (speed > 2) {
|
||||
if (!anim.IsPlaying) anim.Play(0.2);
|
||||
if (!animation_track.IsPlaying) animation_track.Play(0.2);
|
||||
} else {
|
||||
if (anim.IsPlaying) anim?.Stop(0.2);
|
||||
if (animation_track.IsPlaying) animation_track?.Stop(0.2);
|
||||
}
|
||||
} else if (anim?.IsPlaying) {
|
||||
anim?.Stop(1);
|
||||
} else if (animation_track?.IsPlaying) {
|
||||
animation_track?.Stop(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
// Clean up the connection when the character died.
|
||||
player.CharacterRemoving.Once(() => running_connection.Disconnect());
|
||||
});
|
||||
|
||||
player.CharacterRemoving.Once(() => runningConn.Disconnect());
|
||||
});
|
||||
|
||||
sprint.Connect((player, enabled) => {
|
||||
// Change the sprint state with networking
|
||||
GameplayServerEvents.sprint.connect((player, enabled) => {
|
||||
const character = player.Character;
|
||||
isrunning.set(player.UserId, enabled);
|
||||
this.is_running.set(player.UserId, enabled);
|
||||
if (character) {
|
||||
const humanoid = character.FindFirstChildOfClass("Humanoid");
|
||||
if (humanoid) {
|
||||
if (enabled) {
|
||||
humanoid.WalkSpeed = base_sprint_speed * sprint_speed;
|
||||
// if (humanoid.GetStateEnabled(Enum.HumanoidStateType.Running)) {
|
||||
// const anim = runanim.get(player.UserId);
|
||||
// anim?.Play(0.2);
|
||||
// }
|
||||
humanoid.WalkSpeed = this.base_sprint_speed * this.sprint_speed;
|
||||
} else {
|
||||
humanoid.WalkSpeed = base_sprint_speed;
|
||||
// if (humanoid.GetStateEnabled(Enum.HumanoidStateType.Running)) {
|
||||
// const anim = runanim.get(player.UserId);
|
||||
// anim?.Stop(1);
|
||||
// }
|
||||
humanoid.WalkSpeed = this.base_sprint_speed;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import { Players } from "@rbxts/services";
|
||||
import { makeRagdoll, stopRagdoll, waitMotionLess } from "shared/ragdoll";
|
||||
|
||||
Players.PlayerAdded.Connect((player) => {
|
||||
player.CharacterAdded.Connect((character) => {
|
||||
const humanoid = character.FindFirstChildOfClass("Humanoid");
|
||||
if (!humanoid) return;
|
||||
humanoid.FreeFalling.Connect(() => {
|
||||
makeRagdoll(character);
|
||||
waitMotionLess(character, 0.1).Wait();
|
||||
stopRagdoll(character);
|
||||
});
|
||||
});
|
||||
});
|
||||
3
src/server/networking.ts
Normal file
3
src/server/networking.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { GameplayEvents } from "shared/networking";
|
||||
|
||||
export const GameplayServerEvents = GameplayEvents.createServer({});
|
||||
11
src/shared/character/builder.ts
Normal file
11
src/shared/character/builder.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
class AbilityBuilder {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
class PasiveBuilder {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
class CharacterBuilder {
|
||||
constructor() {}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import Net from "@rbxts/net";
|
||||
|
||||
const Gameplay_Remotes = Net.Definitions.Create({
|
||||
Sprint: Net.Definitions.ClientToServerEvent<[enabled: boolean]>(),
|
||||
});
|
||||
|
||||
export default Gameplay_Remotes;
|
||||
11
src/shared/networking.ts
Normal file
11
src/shared/networking.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Networking } from "@flamework/networking";
|
||||
|
||||
const { createEvent, createFunction } = Networking;
|
||||
|
||||
interface GameplayClient {
|
||||
sprint(enabled: boolean): void;
|
||||
}
|
||||
|
||||
interface GameplayServer {}
|
||||
|
||||
export const GameplayEvents = createEvent<GameplayClient, GameplayServer>();
|
||||
@@ -1,5 +1,50 @@
|
||||
import { RunService } from "@rbxts/services";
|
||||
import Signal from "@rbxts/signal";
|
||||
|
||||
class RagdollHandler {
|
||||
private character: Model;
|
||||
private humanoid: Humanoid;
|
||||
constructor(character: Model) {
|
||||
this.character = character;
|
||||
this.humanoid = character.FindFirstAncestorOfClass("Humanoid")!;
|
||||
}
|
||||
|
||||
prepareRagdoll() {
|
||||
const children = this.character.GetDescendants();
|
||||
children.forEach((motor) => {
|
||||
if (motor.IsA("Motor6D")) {
|
||||
const ballsocketconstraint = new BallSocketConstraint(),
|
||||
attachment0 = new Attachment(),
|
||||
attachment1 = new Attachment();
|
||||
|
||||
attachment0.CFrame = motor.C0;
|
||||
attachment0.Parent = motor.Part0;
|
||||
attachment0.AddTag("Ragdoll");
|
||||
attachment0.Name = motor.Name;
|
||||
|
||||
attachment1.CFrame = motor.C1;
|
||||
attachment1.Parent = motor.Part1;
|
||||
attachment1.AddTag("Ragdoll");
|
||||
attachment1.Name = motor.Name;
|
||||
|
||||
ballsocketconstraint.Attachment0 = attachment0;
|
||||
ballsocketconstraint.Attachment1 = attachment1;
|
||||
ballsocketconstraint.Parent = motor.Parent;
|
||||
ballsocketconstraint.AddTag("Ragdoll");
|
||||
ballsocketconstraint.Enabled = false;
|
||||
|
||||
if (motor.Name === "Left Hip") {
|
||||
attachment0.CFrame = attachment0.CFrame.add(new Vector3(0.5, 0, 0));
|
||||
attachment1.CFrame = attachment1.CFrame.add(new Vector3(0.5, 0, 0));
|
||||
} else if (motor.Name === "Right Hip") {
|
||||
attachment0.CFrame = attachment0.CFrame.sub(new Vector3(0.5, 0, 0));
|
||||
attachment1.CFrame = attachment1.CFrame.sub(new Vector3(0.5, 0, 0));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the Network Ownership of a player's character.
|
||||
* @param character The character of a player.
|
||||
@@ -28,36 +73,57 @@ export function releaseNetworkOwnership(character: Model) {
|
||||
});
|
||||
}
|
||||
|
||||
export function prepareRagdoll(character: Model) {
|
||||
const children = character.GetDescendants();
|
||||
const humanoid = character.FindFirstChildOfClass("Humanoid")!;
|
||||
humanoid.RequiresNeck = false;
|
||||
children.forEach((motor) => {
|
||||
if (motor.IsA("Motor6D")) {
|
||||
const ballsocketconstraint = new BallSocketConstraint(),
|
||||
attachment0 = new Attachment(),
|
||||
attachment1 = new Attachment();
|
||||
|
||||
attachment0.CFrame = motor.C0;
|
||||
attachment0.Parent = motor.Part0;
|
||||
attachment0.AddTag("Ragdoll");
|
||||
attachment0.Name = motor.Name;
|
||||
|
||||
attachment1.CFrame = motor.C1;
|
||||
attachment1.Parent = motor.Part1;
|
||||
attachment1.AddTag("Ragdoll");
|
||||
attachment1.Name = motor.Name;
|
||||
|
||||
ballsocketconstraint.Attachment0 = attachment0;
|
||||
ballsocketconstraint.Attachment1 = attachment1;
|
||||
ballsocketconstraint.Parent = motor.Parent;
|
||||
ballsocketconstraint.AddTag("Ragdoll");
|
||||
ballsocketconstraint.Enabled = false;
|
||||
|
||||
if (motor.Name === "Left Hip") {
|
||||
attachment0.CFrame = attachment0.CFrame.add(new Vector3(0.5, 0, 0));
|
||||
attachment1.CFrame = attachment1.CFrame.add(new Vector3(0.5, 0, 0));
|
||||
} else if (motor.Name === "Right Hip") {
|
||||
attachment0.CFrame = attachment0.CFrame.sub(new Vector3(0.5, 0, 0));
|
||||
attachment1.CFrame = attachment1.CFrame.sub(new Vector3(0.5, 0, 0));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the player's character Ragdoll by creating attachments for each part of the R6 Model.
|
||||
* @param character The character of a player.
|
||||
*/
|
||||
export function makeRagdoll(character: Model) {
|
||||
takeNetworkOwner(character);
|
||||
const children = character.GetDescendants();
|
||||
const humanoid = character.FindFirstChildOfClass("Humanoid")!;
|
||||
humanoid.RequiresNeck = false;
|
||||
humanoid.ChangeState(Enum.HumanoidStateType.Physics);
|
||||
children.forEach((motor) => {
|
||||
if (motor.IsA("Motor6D")) {
|
||||
const ballsocketconstraint = new Instance("BallSocketConstraint"),
|
||||
attachment0 = new Instance("Attachment"),
|
||||
attachment1 = new Instance("Attachment");
|
||||
|
||||
attachment0.CFrame = motor.C0;
|
||||
attachment0.Parent = motor.Part0;
|
||||
attachment0.AddTag("Ragdoll");
|
||||
|
||||
attachment1.CFrame = motor.C1;
|
||||
attachment1.Parent = motor.Part1;
|
||||
attachment1.AddTag("Ragdoll");
|
||||
|
||||
ballsocketconstraint.Attachment0 = attachment0;
|
||||
ballsocketconstraint.Attachment1 = attachment1;
|
||||
ballsocketconstraint.Parent = motor.Parent;
|
||||
ballsocketconstraint.AddTag("Ragdoll");
|
||||
|
||||
motor.Enabled = false;
|
||||
character.GetDescendants().forEach((des) => {
|
||||
if (des.HasTag("Ragdoll") && des.IsA("BallSocketConstraint")) {
|
||||
des.Enabled = true;
|
||||
}
|
||||
if (des.IsA("Motor6D")) {
|
||||
des.Enabled = false;
|
||||
}
|
||||
});
|
||||
takeNetworkOwner(character);
|
||||
@@ -66,8 +132,8 @@ export function makeRagdoll(character: Model) {
|
||||
export function stopRagdoll(character: Model) {
|
||||
releaseNetworkOwnership(character);
|
||||
character.GetDescendants().forEach((des) => {
|
||||
if (des.HasTag("Ragdoll")) {
|
||||
des.Destroy();
|
||||
if (des.HasTag("Ragdoll") && des.IsA("BallSocketConstraint")) {
|
||||
des.Enabled = false;
|
||||
}
|
||||
if (des.IsA("Motor6D")) {
|
||||
des.Enabled = true;
|
||||
@@ -96,3 +162,27 @@ export function waitMotionLess(character: Model, threshold: number) {
|
||||
});
|
||||
return signal;
|
||||
}
|
||||
|
||||
export function getRagdollEvent(character: Model) {
|
||||
const humanoid = character.FindFirstChildOfClass("Humanoid");
|
||||
const root = character.WaitForChild("HumanoidRootPart") as Part;
|
||||
if (!humanoid) throw "nya UwU eat my paw.";
|
||||
const event = new Signal();
|
||||
let fired = false;
|
||||
let beatEvent: RBXScriptConnection;
|
||||
humanoid.FreeFalling.Connect((active) => {
|
||||
if (active) {
|
||||
beatEvent = RunService.Heartbeat.Connect(() => {
|
||||
if (root.AssemblyLinearVelocity.Y < -38 && !fired) {
|
||||
event.Fire();
|
||||
fired = true;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
beatEvent.Disconnect();
|
||||
fired = false;
|
||||
}
|
||||
});
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import Net from "@rbxts/net";
|
||||
const Remotes = Net.Definitions.Create({
|
||||
SendAttack: Net.Definitions.ClientToServerEvent<[attackId: number]>(),
|
||||
});
|
||||
export default Remotes;
|
||||
6
src/shared/utils/restorarray.ts
Normal file
6
src/shared/utils/restorarray.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export type RestOrArray<Type> = Type[] | [Type[]];
|
||||
|
||||
export function normalizeArray<ItemType>(arr: RestOrArray<ItemType>): ItemType[] {
|
||||
if (typeIs(arr[0], "table")) return [...arr[0]];
|
||||
return arr as ItemType[];
|
||||
}
|
||||
@@ -15,13 +15,31 @@
|
||||
"moduleDetection": "force",
|
||||
"strict": true,
|
||||
"target": "ESNext",
|
||||
"typeRoots": ["node_modules/@rbxts"],
|
||||
|
||||
"typeRoots": [
|
||||
"node_modules/@rbxts",
|
||||
"node_modules/@flamework"
|
||||
],
|
||||
// configurable
|
||||
"rootDir": "src",
|
||||
"outDir": "out",
|
||||
"baseUrl": "src",
|
||||
"incremental": true,
|
||||
"tsBuildInfoFile": "out/tsconfig.tsbuildinfo"
|
||||
"tsBuildInfoFile": "out/tsconfig.tsbuildinfo",
|
||||
"plugins": [
|
||||
{
|
||||
"transform": "rbxts-transformer-flamework",
|
||||
"obfuscation": true
|
||||
},
|
||||
{
|
||||
"transform": "rbxts-transformer-instances"
|
||||
},
|
||||
{
|
||||
"transform": "rbxts-transformer-services"
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
"node_modules/rbxts-transformer-instances"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user