Slight additions mostly to UI

This commit is contained in:
loplkc loplkc 2022-01-13 18:29:57 -05:00
parent 1a5208b1f9
commit 67b71c0e0e
10 changed files with 115 additions and 24 deletions

View file

@ -3,7 +3,7 @@ export function bindToOutput(functionToBind: Callback) {
assert(Output?.IsA("RemoteEvent"), 'Remote event "Input" is of incorrect class or nil');
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');
Input.FireServer(messageType, messageContent);
}

View file

@ -0,0 +1 @@
export function kablooey() {}

View file

@ -50,7 +50,7 @@ interface guiEntry {
color?: Color3;
transparency: number;
pages: guiElementEntry[][];
closeFunction: Callback;
closeFunction: (baseFrame: Frame) => void;
}
interface guiTable {
@ -64,13 +64,15 @@ const stylesTable: guiStyleTable = {
BackgroundColor: Color3.fromRGB(0, 0, 0),
},
TextLabel: {
TextColor: Color3.fromRGB(255, 0, 0),
Font: Enum.Font.AmaticSC,
TextColor: Color3.fromRGB(255, 255, 255),
Font: Enum.Font.Ubuntu,
TextScaled: true,
},
TextButton: {
BackgroundTransparency: 0.125,
BackgroundColor: Color3.fromRGB(255, 0, 255),
BackgroundTransparency: 0.9,
BackgroundColor: Color3.fromRGB(255, 255, 255),
TextColor: Color3.fromRGB(255, 255, 255),
Font: Enum.Font.Ubuntu,
TextScaled: true,
},
},
@ -86,6 +88,7 @@ const guiTable: guiTable = {
Style: stylesTable["placeholder"],
Position: new UDim2(0, 0, 0.175, 0),
Size: new UDim2(1, 0, 0.15, 0),
Font: Enum.Font.Garamond,
Text: "Placeholder",
},
{
@ -112,8 +115,14 @@ const guiTable: guiTable = {
},
],
],
closeFunction: function (baseFrame) {
tweenService.Create(baseFrame, new TweenInfo(0.5), { Position: new UDim2(1, 0, 0, 0) }).Play();
closeFunction: function (this: void, baseFrame: Frame) {
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][]) {
print("fortnite");
const elementType = elementEntry["Type"];
const elementStyle = elementEntry["Style"][elementType];
const elementStyleDefault = elementEntry["Style"].default;
@ -168,22 +178,25 @@ function drawGuiElement(elementEntry: guiElementEntry, objectsToReturn: [TextBut
assert(
classIs(guiElement, "TextButton") || classIs(guiElement, "ImageButton"),
'Property "OnClick" should not exist on non-button instance!',
);
); // Temporary?
objectsToReturn.push([guiElement, elementEntry.onClick]);
}
return guiElement;
}
export function drawGui(PLAYERGUI: PlayerGui, guiName: "MainMenu") {
print("opening gui");
const objectsToReturn: [TextButton | ImageButton, onClickEntry][] = [];
const guiEntry = guiTable[guiName];
assert(guiEntry, 'Error in Gui Handler: Gui "' + guiName + " not found!");
// Actual Gui creation
const screenGui = new Instance("ScreenGui");
screenGui.Name = guiName;
screenGui.IgnoreGuiInset = true;
screenGui.ResetOnSpawn = false; // ?
screenGui.Parent = PLAYERGUI;
const baseFrame = new Instance("Frame");
baseFrame.Name = "baseFrame";
baseFrame.BackgroundTransparency = guiEntry.transparency;
baseFrame.BackgroundColor3 = guiEntry.color || Color3.fromRGB(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);
guiElement.Parent = baseFrame;
}
baseFrame.Parent = screenGui;
screenGui.Parent = PLAYERGUI;
return objectsToReturn;
}
export function closeGui(PLAYERGUI: PlayerGui, guiName: "MainMenu") {
const screenGui = PLAYERGUI.WaitForChild(guiName, 1);
assert(screenGui, 'ScreenGui"' + guiName + '" does not exist!');
screenGui;
assert(screenGui, 'ScreenGui "' + guiName + '" does not exist!');
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
View file

@ -0,0 +1,5 @@
export const gamer: { [modeId: string]: modeLocal } = {
["Flawless"]: {
//aura: [[["Ball"]]], // Will come back to this later
},
};

View file

@ -1,32 +1,58 @@
// "init": The local script. This script doesn't have to account for any other players.
const Players = game.GetService("Players");
const UserInputService = game.GetService("UserInputService");
const Workspace = game.GetService("Workspace");
import { bindToOutput, messageServer } from "./ClientMessenger";
import { handleGuiInput, drawGui, closeGui } from "./GuiHandler";
const LOCALPLAYER = Players.LocalPlayer;
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;
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");
for (const mainMenuButton of mainMenuButtons) {
mainMenuButton[0].Activated.Connect(function () {
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) {
let mousePosition: Vector3, mouseNormal: Vector3, mouseInstance: Instance | undefined;
[mousePosition, mouseNormal, mouseInstance] = getMouseLocation(); // eslint-disable-line prefer-const
if (input.UserInputType === Enum.UserInputType.MouseButton1) {
messageServer("move", mousePosition);
}
}
function handleOutput(messageType: unknown, messageContent: unknown) {
if (messageType === "init") {
openMainMenu(PLAYERGUI);
inMainMenu = true;
} else if (messageType === "enterGame") {
closeGui(PLAYERGUI, "MainMenu");
inMainMenu = false;
}
}
// Action phase

2
src/server/Hitboxer.ts Normal file
View file

@ -0,0 +1,2 @@
// Later
export function hitBox() {}

View file

@ -1,7 +1,7 @@
// "main": This is the core of reality. It serves as the highest-level abstraction.
// + Prevent this from coupling with the entity manager, if possible
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 { bindToInput, messageClient, messageAllClients } from "./ServerMessenger";
const playerStorage: (playerStorageEntry | undefined)[] = [];
@ -21,13 +21,16 @@ function handleInput(player: Player, messageType: unknown, messageContent: unkno
entityStorage[player.UserId] = loadInPlayer(player);
messageClient(player, "enterGame");
} 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);
messageClient(player, "promptError", errorMessage);
}
} else if (messageType === "placeholder") {
const entity = entityStorage[player.UserId];
if (entity && entity.puppet) {
}
} else if (messageType === "move") {
if (typeIs(messageContent, "Vector3")) {
moveEntity(entityStorage[player.UserId], messageContent);
}
}
}

12
src/services.d.ts vendored
View file

@ -1,6 +1,7 @@
type puppetEntry = ["Character", Player] | ["Placeholder", "Placeholder"];
type bodyPart = "root" | "torso" | "head" | "leftArm" | "rightArm" | "leftLeg" | "rightLeg";
type serverMessageType = "init" | "promptError" | "enterGame";
type clientMessageType = "Placeholder";
type clientMessageType = "move" | "placeholder";
interface saveDataEntry {
placeholder: string;
@ -12,6 +13,7 @@ interface playerStorageEntry {
entity?: entity;
}
interface puppet {
entry: puppetEntry;
model: Model;
rootPart: Part;
//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
}
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 {
name: string;
guiObject: GuiObject;

View file

@ -1,6 +1,6 @@
// "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.
import { makePuppet } from "./Puppetmaster";
import { makePuppet, movePuppet } from "./Puppetmaster";
export function makeEntity(puppetEntry: puppetEntry) {
const newEntity: entity = {
baseStats: [0, 0, 0, 0],
@ -9,3 +9,10 @@ export function makeEntity(puppetEntry: puppetEntry) {
};
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);
}
}

View file

@ -9,6 +9,7 @@ export function makePuppet(puppetEntry: puppetEntry) {
if (puppetEntry[0] === "Character") {
const model: [Model, Part] = puppetLibraries[puppetEntry[0]].makeModel(puppetEntry[1]);
return {
entry: puppetEntry,
model: model[0],
rootPart: model[1],
};
@ -16,3 +17,22 @@ export function makePuppet(puppetEntry: puppetEntry) {
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;
}