Slight additions mostly to UI
This commit is contained in:
parent
1a5208b1f9
commit
67b71c0e0e
10 changed files with 115 additions and 24 deletions
|
@ -3,7 +3,7 @@ export function bindToOutput(functionToBind: Callback) {
|
||||||
assert(Output?.IsA("RemoteEvent"), 'Remote event "Input" is of incorrect class or nil');
|
assert(Output?.IsA("RemoteEvent"), 'Remote event "Input" is of incorrect class or nil');
|
||||||
Output.OnClientEvent.Connect(functionToBind);
|
Output.OnClientEvent.Connect(functionToBind);
|
||||||
}
|
}
|
||||||
export function messageServer(messageType: clientMessageType, messageContent?: string) {
|
export function messageServer(messageType: clientMessageType, messageContent?: unknown) {
|
||||||
assert(Input?.IsA("RemoteEvent"), 'Remote event "Output" is of incorrect class or nil');
|
assert(Input?.IsA("RemoteEvent"), 'Remote event "Output" is of incorrect class or nil');
|
||||||
Input.FireServer(messageType, messageContent);
|
Input.FireServer(messageType, messageContent);
|
||||||
}
|
}
|
||||||
|
|
1
src/client/EffectMaker.ts
Normal file
1
src/client/EffectMaker.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export function kablooey() {}
|
|
@ -50,7 +50,7 @@ interface guiEntry {
|
||||||
color?: Color3;
|
color?: Color3;
|
||||||
transparency: number;
|
transparency: number;
|
||||||
pages: guiElementEntry[][];
|
pages: guiElementEntry[][];
|
||||||
closeFunction: Callback;
|
closeFunction: (baseFrame: Frame) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface guiTable {
|
interface guiTable {
|
||||||
|
@ -64,13 +64,15 @@ const stylesTable: guiStyleTable = {
|
||||||
BackgroundColor: Color3.fromRGB(0, 0, 0),
|
BackgroundColor: Color3.fromRGB(0, 0, 0),
|
||||||
},
|
},
|
||||||
TextLabel: {
|
TextLabel: {
|
||||||
TextColor: Color3.fromRGB(255, 0, 0),
|
TextColor: Color3.fromRGB(255, 255, 255),
|
||||||
Font: Enum.Font.AmaticSC,
|
Font: Enum.Font.Ubuntu,
|
||||||
TextScaled: true,
|
TextScaled: true,
|
||||||
},
|
},
|
||||||
TextButton: {
|
TextButton: {
|
||||||
BackgroundTransparency: 0.125,
|
BackgroundTransparency: 0.9,
|
||||||
BackgroundColor: Color3.fromRGB(255, 0, 255),
|
BackgroundColor: Color3.fromRGB(255, 255, 255),
|
||||||
|
TextColor: Color3.fromRGB(255, 255, 255),
|
||||||
|
Font: Enum.Font.Ubuntu,
|
||||||
TextScaled: true,
|
TextScaled: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -86,6 +88,7 @@ const guiTable: guiTable = {
|
||||||
Style: stylesTable["placeholder"],
|
Style: stylesTable["placeholder"],
|
||||||
Position: new UDim2(0, 0, 0.175, 0),
|
Position: new UDim2(0, 0, 0.175, 0),
|
||||||
Size: new UDim2(1, 0, 0.15, 0),
|
Size: new UDim2(1, 0, 0.15, 0),
|
||||||
|
Font: Enum.Font.Garamond,
|
||||||
Text: "Placeholder",
|
Text: "Placeholder",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -112,8 +115,14 @@ const guiTable: guiTable = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
closeFunction: function (baseFrame) {
|
closeFunction: function (this: void, baseFrame: Frame) {
|
||||||
tweenService.Create(baseFrame, new TweenInfo(0.5), { Position: new UDim2(1, 0, 0, 0) }).Play();
|
print(baseFrame);
|
||||||
|
tweenService
|
||||||
|
.Create(baseFrame, new TweenInfo(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {
|
||||||
|
Position: new UDim2(1, 0, 0, 0),
|
||||||
|
})
|
||||||
|
.Play();
|
||||||
|
wait(1);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -143,6 +152,7 @@ function configureTextElement(
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawGuiElement(elementEntry: guiElementEntry, objectsToReturn: [TextButton | ImageButton, onClickEntry][]) {
|
function drawGuiElement(elementEntry: guiElementEntry, objectsToReturn: [TextButton | ImageButton, onClickEntry][]) {
|
||||||
|
print("fortnite");
|
||||||
const elementType = elementEntry["Type"];
|
const elementType = elementEntry["Type"];
|
||||||
const elementStyle = elementEntry["Style"][elementType];
|
const elementStyle = elementEntry["Style"][elementType];
|
||||||
const elementStyleDefault = elementEntry["Style"].default;
|
const elementStyleDefault = elementEntry["Style"].default;
|
||||||
|
@ -168,22 +178,25 @@ function drawGuiElement(elementEntry: guiElementEntry, objectsToReturn: [TextBut
|
||||||
assert(
|
assert(
|
||||||
classIs(guiElement, "TextButton") || classIs(guiElement, "ImageButton"),
|
classIs(guiElement, "TextButton") || classIs(guiElement, "ImageButton"),
|
||||||
'Property "OnClick" should not exist on non-button instance!',
|
'Property "OnClick" should not exist on non-button instance!',
|
||||||
);
|
); // Temporary?
|
||||||
objectsToReturn.push([guiElement, elementEntry.onClick]);
|
objectsToReturn.push([guiElement, elementEntry.onClick]);
|
||||||
}
|
}
|
||||||
return guiElement;
|
return guiElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function drawGui(PLAYERGUI: PlayerGui, guiName: "MainMenu") {
|
export function drawGui(PLAYERGUI: PlayerGui, guiName: "MainMenu") {
|
||||||
|
print("opening gui");
|
||||||
const objectsToReturn: [TextButton | ImageButton, onClickEntry][] = [];
|
const objectsToReturn: [TextButton | ImageButton, onClickEntry][] = [];
|
||||||
const guiEntry = guiTable[guiName];
|
const guiEntry = guiTable[guiName];
|
||||||
assert(guiEntry, 'Error in Gui Handler: Gui "' + guiName + " not found!");
|
assert(guiEntry, 'Error in Gui Handler: Gui "' + guiName + " not found!");
|
||||||
// Actual Gui creation
|
// Actual Gui creation
|
||||||
const screenGui = new Instance("ScreenGui");
|
const screenGui = new Instance("ScreenGui");
|
||||||
screenGui.Name = guiName;
|
screenGui.Name = guiName;
|
||||||
|
screenGui.IgnoreGuiInset = true;
|
||||||
screenGui.ResetOnSpawn = false; // ?
|
screenGui.ResetOnSpawn = false; // ?
|
||||||
screenGui.Parent = PLAYERGUI;
|
screenGui.Parent = PLAYERGUI;
|
||||||
const baseFrame = new Instance("Frame");
|
const baseFrame = new Instance("Frame");
|
||||||
|
baseFrame.Name = "baseFrame";
|
||||||
baseFrame.BackgroundTransparency = guiEntry.transparency;
|
baseFrame.BackgroundTransparency = guiEntry.transparency;
|
||||||
baseFrame.BackgroundColor3 = guiEntry.color || Color3.fromRGB(0, 0, 0);
|
baseFrame.BackgroundColor3 = guiEntry.color || Color3.fromRGB(0, 0, 0);
|
||||||
baseFrame.Position = guiEntry.position || new UDim2(0, 0, 0, 0);
|
baseFrame.Position = guiEntry.position || new UDim2(0, 0, 0, 0);
|
||||||
|
@ -192,12 +205,16 @@ export function drawGui(PLAYERGUI: PlayerGui, guiName: "MainMenu") {
|
||||||
const guiElement = drawGuiElement(guiElementEntry, objectsToReturn);
|
const guiElement = drawGuiElement(guiElementEntry, objectsToReturn);
|
||||||
guiElement.Parent = baseFrame;
|
guiElement.Parent = baseFrame;
|
||||||
}
|
}
|
||||||
|
baseFrame.Parent = screenGui;
|
||||||
screenGui.Parent = PLAYERGUI;
|
screenGui.Parent = PLAYERGUI;
|
||||||
return objectsToReturn;
|
return objectsToReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function closeGui(PLAYERGUI: PlayerGui, guiName: "MainMenu") {
|
export function closeGui(PLAYERGUI: PlayerGui, guiName: "MainMenu") {
|
||||||
const screenGui = PLAYERGUI.WaitForChild(guiName, 1);
|
const screenGui = PLAYERGUI.WaitForChild(guiName, 1);
|
||||||
assert(screenGui, 'ScreenGui"' + guiName + '" does not exist!');
|
assert(screenGui, 'ScreenGui "' + guiName + '" does not exist!');
|
||||||
screenGui;
|
const baseFrame = screenGui.WaitForChild("baseFrame", 1);
|
||||||
|
assert(baseFrame && classIs(baseFrame, "Frame"), 'Baseframe of "' + guiName + '" does not exist!');
|
||||||
|
const closeFunction = guiTable[guiName].closeFunction(baseFrame);
|
||||||
|
screenGui.Destroy();
|
||||||
}
|
}
|
||||||
|
|
5
src/client/ModesLocal.ts
Normal file
5
src/client/ModesLocal.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
export const gamer: { [modeId: string]: modeLocal } = {
|
||||||
|
["Flawless"]: {
|
||||||
|
//aura: [[["Ball"]]], // Will come back to this later
|
||||||
|
},
|
||||||
|
};
|
|
@ -1,32 +1,58 @@
|
||||||
// "init": The local script. This script doesn't have to account for any other players.
|
// "init": The local script. This script doesn't have to account for any other players.
|
||||||
const Players = game.GetService("Players");
|
const Players = game.GetService("Players");
|
||||||
const UserInputService = game.GetService("UserInputService");
|
const UserInputService = game.GetService("UserInputService");
|
||||||
|
const Workspace = game.GetService("Workspace");
|
||||||
import { bindToOutput, messageServer } from "./ClientMessenger";
|
import { bindToOutput, messageServer } from "./ClientMessenger";
|
||||||
import { handleGuiInput, drawGui, closeGui } from "./GuiHandler";
|
import { handleGuiInput, drawGui, closeGui } from "./GuiHandler";
|
||||||
const LOCALPLAYER = Players.LocalPlayer;
|
const LOCALPLAYER = Players.LocalPlayer;
|
||||||
const PLAYERGUI = LOCALPLAYER.WaitForChild("PlayerGui", 1) as PlayerGui;
|
const PLAYERGUI = LOCALPLAYER.WaitForChild("PlayerGui", 1) as PlayerGui;
|
||||||
assert(PLAYERGUI && classIs(PLAYERGUI, "PlayerGui"), 'PlayerGui of "' + LOCALPLAYER.Name + '"does not exist! (HOW???)');
|
assert(
|
||||||
|
PLAYERGUI && classIs(PLAYERGUI, "PlayerGui"),
|
||||||
|
'PlayerGui of "' + LOCALPLAYER.DisplayName + '"does not exist! (HOW???)',
|
||||||
|
);
|
||||||
|
const CAMERA = Workspace.CurrentCamera as Camera;
|
||||||
|
assert(CAMERA, 'Camera of "' + LOCALPLAYER.DisplayName + '"does not exist! (HOW???)');
|
||||||
let inMainMenu = true;
|
let inMainMenu = true;
|
||||||
|
|
||||||
function openMainMenu(playerGui: PlayerGui) {
|
function openMainMenu(playerGui: PlayerGui) {
|
||||||
messageServer("Placeholder", "OpeningMainMenu"); // > Server should check if there are entities to clean up
|
messageServer("placeholder", "OpeningMainMenu"); // > Server should check if there are entities to clean up + new messagetype?
|
||||||
const mainMenuButtons = drawGui(playerGui, "MainMenu");
|
const mainMenuButtons = drawGui(playerGui, "MainMenu");
|
||||||
for (const mainMenuButton of mainMenuButtons) {
|
for (const mainMenuButton of mainMenuButtons) {
|
||||||
mainMenuButton[0].Activated.Connect(function () {
|
mainMenuButton[0].Activated.Connect(function () {
|
||||||
handleGuiInput(messageServer, mainMenuButton[1][0], mainMenuButton[1][1]);
|
handleGuiInput(messageServer, mainMenuButton[1][0], mainMenuButton[1][1]);
|
||||||
});
|
}); // + Good ETC extension - Add support for other controller types
|
||||||
}
|
}
|
||||||
inMainMenu = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hitParams = new RaycastParams();
|
||||||
|
//hitParams.FilterDescendantsInstances = {efFolder,Plr.Character}
|
||||||
|
//hitParams.FilterType = Enum.RaycastFilterType.Blacklist;
|
||||||
|
function getMouseLocation(): [Vector3, Vector3, Instance | undefined] {
|
||||||
|
//hitParams.FilterDescendantsInstances = {efFolder,Plr.Character}
|
||||||
|
const mouseLocation = UserInputService.GetMouseLocation();
|
||||||
|
const unitRay = CAMERA.ViewportPointToRay(mouseLocation.X, mouseLocation.Y);
|
||||||
|
const cast = Workspace.Raycast(unitRay.Origin, unitRay.Direction.mul(1000), hitParams);
|
||||||
|
if (cast) {
|
||||||
|
return [cast.Position, cast.Normal, cast.Instance];
|
||||||
|
} else {
|
||||||
|
return [unitRay.Origin.add(unitRay.Direction.mul(1000)), new Vector3(0, 0, 0), undefined];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handleInput(input: InputObject, otherInteraction: boolean) {
|
function handleInput(input: InputObject, otherInteraction: boolean) {
|
||||||
|
let mousePosition: Vector3, mouseNormal: Vector3, mouseInstance: Instance | undefined;
|
||||||
|
[mousePosition, mouseNormal, mouseInstance] = getMouseLocation(); // eslint-disable-line prefer-const
|
||||||
if (input.UserInputType === Enum.UserInputType.MouseButton1) {
|
if (input.UserInputType === Enum.UserInputType.MouseButton1) {
|
||||||
|
messageServer("move", mousePosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function handleOutput(messageType: unknown, messageContent: unknown) {
|
function handleOutput(messageType: unknown, messageContent: unknown) {
|
||||||
if (messageType === "init") {
|
if (messageType === "init") {
|
||||||
openMainMenu(PLAYERGUI);
|
openMainMenu(PLAYERGUI);
|
||||||
|
inMainMenu = true;
|
||||||
} else if (messageType === "enterGame") {
|
} else if (messageType === "enterGame") {
|
||||||
closeGui(PLAYERGUI, "MainMenu");
|
closeGui(PLAYERGUI, "MainMenu");
|
||||||
|
inMainMenu = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Action phase
|
// Action phase
|
||||||
|
|
2
src/server/Hitboxer.ts
Normal file
2
src/server/Hitboxer.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
// Later
|
||||||
|
export function hitBox() {}
|
|
@ -1,7 +1,7 @@
|
||||||
// "main": This is the core of reality. It serves as the highest-level abstraction.
|
// "main": This is the core of reality. It serves as the highest-level abstraction.
|
||||||
// + Prevent this from coupling with the entity manager, if possible
|
// + Prevent this from coupling with the entity manager, if possible
|
||||||
const Players = game.GetService("Players");
|
const Players = game.GetService("Players");
|
||||||
import { makeEntity } from "shared/EntityManager";
|
import { makeEntity, moveEntity } from "shared/EntityManager";
|
||||||
import { initPlayer, deinitPlayer, loadInPlayer, teleportPlayer } from "shared/PlayerManager";
|
import { initPlayer, deinitPlayer, loadInPlayer, teleportPlayer } from "shared/PlayerManager";
|
||||||
import { bindToInput, messageClient, messageAllClients } from "./ServerMessenger";
|
import { bindToInput, messageClient, messageAllClients } from "./ServerMessenger";
|
||||||
const playerStorage: (playerStorageEntry | undefined)[] = [];
|
const playerStorage: (playerStorageEntry | undefined)[] = [];
|
||||||
|
@ -21,13 +21,16 @@ function handleInput(player: Player, messageType: unknown, messageContent: unkno
|
||||||
entityStorage[player.UserId] = loadInPlayer(player);
|
entityStorage[player.UserId] = loadInPlayer(player);
|
||||||
messageClient(player, "enterGame");
|
messageClient(player, "enterGame");
|
||||||
} catch (thrownError) {
|
} catch (thrownError) {
|
||||||
const errorMessage = 'Error when creating entity of "' + player.DisplayName + '": ' + thrownError;
|
if (typeIs(thrownError, "string")) {
|
||||||
|
const errorMessage: string =
|
||||||
|
'Error when creating entity of "' + player.DisplayName + '": ' + thrownError;
|
||||||
warn(errorMessage);
|
warn(errorMessage);
|
||||||
messageClient(player, "promptError", errorMessage);
|
messageClient(player, "promptError", errorMessage);
|
||||||
}
|
}
|
||||||
} else if (messageType === "placeholder") {
|
}
|
||||||
const entity = entityStorage[player.UserId];
|
} else if (messageType === "move") {
|
||||||
if (entity && entity.puppet) {
|
if (typeIs(messageContent, "Vector3")) {
|
||||||
|
moveEntity(entityStorage[player.UserId], messageContent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
12
src/services.d.ts
vendored
12
src/services.d.ts
vendored
|
@ -1,6 +1,7 @@
|
||||||
type puppetEntry = ["Character", Player] | ["Placeholder", "Placeholder"];
|
type puppetEntry = ["Character", Player] | ["Placeholder", "Placeholder"];
|
||||||
|
type bodyPart = "root" | "torso" | "head" | "leftArm" | "rightArm" | "leftLeg" | "rightLeg";
|
||||||
type serverMessageType = "init" | "promptError" | "enterGame";
|
type serverMessageType = "init" | "promptError" | "enterGame";
|
||||||
type clientMessageType = "Placeholder";
|
type clientMessageType = "move" | "placeholder";
|
||||||
|
|
||||||
interface saveDataEntry {
|
interface saveDataEntry {
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
|
@ -12,6 +13,7 @@ interface playerStorageEntry {
|
||||||
entity?: entity;
|
entity?: entity;
|
||||||
}
|
}
|
||||||
interface puppet {
|
interface puppet {
|
||||||
|
entry: puppetEntry;
|
||||||
model: Model;
|
model: Model;
|
||||||
rootPart: Part;
|
rootPart: Part;
|
||||||
//placeholder: (x: string) => string; // + "Puppet string" functions will (not?) go here
|
//placeholder: (x: string) => string; // + "Puppet string" functions will (not?) go here
|
||||||
|
@ -27,6 +29,14 @@ interface event {
|
||||||
timeout?: number; // A timeout for the event; passes a lose condition if there are other completion requirements that have not been satisfied
|
timeout?: number; // A timeout for the event; passes a lose condition if there are other completion requirements that have not been satisfied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type meshType = "Ball";
|
||||||
|
type effectState = [CFrame, Vector3, Color3, number]; // The number is transparency
|
||||||
|
type effectEntry = [meshType, EnumItem, effectState[]]; // The enumitem is material
|
||||||
|
|
||||||
|
interface modeLocal {
|
||||||
|
aura?: [effectEntry, bodyPart?, number?][]; // effect, part it is attached to (default root), how many times it should be called per frame (default 1)
|
||||||
|
}
|
||||||
|
|
||||||
/*interface hookInEntry {
|
/*interface hookInEntry {
|
||||||
name: string;
|
name: string;
|
||||||
guiObject: GuiObject;
|
guiObject: GuiObject;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// "EntityManager": Create entities objects and deck them out with functions to use.
|
// "EntityManager": Create entities objects and deck them out with functions to use.
|
||||||
// + Functions are here, as to avoid storing unecessary data in the server store.
|
// + Functions are here, as to avoid storing unecessary data in the server store.
|
||||||
import { makePuppet } from "./Puppetmaster";
|
import { makePuppet, movePuppet } from "./Puppetmaster";
|
||||||
export function makeEntity(puppetEntry: puppetEntry) {
|
export function makeEntity(puppetEntry: puppetEntry) {
|
||||||
const newEntity: entity = {
|
const newEntity: entity = {
|
||||||
baseStats: [0, 0, 0, 0],
|
baseStats: [0, 0, 0, 0],
|
||||||
|
@ -9,3 +9,10 @@ export function makeEntity(puppetEntry: puppetEntry) {
|
||||||
};
|
};
|
||||||
return newEntity;
|
return newEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This exists because the main server should never see the puppets, but it is a bit weird
|
||||||
|
export function moveEntity(entity: entity | undefined, location: Vector3) {
|
||||||
|
if (entity) {
|
||||||
|
entity.puppet = movePuppet(entity.puppet, location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ export function makePuppet(puppetEntry: puppetEntry) {
|
||||||
if (puppetEntry[0] === "Character") {
|
if (puppetEntry[0] === "Character") {
|
||||||
const model: [Model, Part] = puppetLibraries[puppetEntry[0]].makeModel(puppetEntry[1]);
|
const model: [Model, Part] = puppetLibraries[puppetEntry[0]].makeModel(puppetEntry[1]);
|
||||||
return {
|
return {
|
||||||
|
entry: puppetEntry,
|
||||||
model: model[0],
|
model: model[0],
|
||||||
rootPart: model[1],
|
rootPart: model[1],
|
||||||
};
|
};
|
||||||
|
@ -16,3 +17,22 @@ export function makePuppet(puppetEntry: puppetEntry) {
|
||||||
throw 'Invalid puppet type "' + puppetEntry[0] + '"!';
|
throw 'Invalid puppet type "' + puppetEntry[0] + '"!';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function verifyPuppetExistence(puppet: puppet) {
|
||||||
|
if (puppet.rootPart.Parent) {
|
||||||
|
// Placeholder; puppet integrity will include other body parts
|
||||||
|
return puppet;
|
||||||
|
} else {
|
||||||
|
print("No puppet!");
|
||||||
|
return makePuppet(puppet.entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function movePuppet(puppet: puppet, location: Vector3) {
|
||||||
|
print("executing puppet move");
|
||||||
|
puppet = verifyPuppetExistence(puppet); //const newPuppet = verifyPuppetExistence(puppet);
|
||||||
|
//puppet.rootPart = newPuppet.rootPart;
|
||||||
|
//puppet.model = newPuppet.model;
|
||||||
|
puppet.rootPart.CFrame = new CFrame(location);
|
||||||
|
return puppet;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue