InputHandler completed, compilation errors fixed
This commit is contained in:
parent
f48eff5f67
commit
1564575a7f
5 changed files with 110 additions and 75 deletions
|
@ -3,7 +3,7 @@ export function bindToServerMessage(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?: unknown) {
|
||||
export function messageServer(messageType: string, messageContent?: unknown) {
|
||||
assert(Input?.IsA("RemoteEvent"), 'Remote event "Output" is of incorrect class or nil');
|
||||
Input.FireServer(messageType, messageContent);
|
||||
}
|
||||
|
|
|
@ -5,28 +5,49 @@ const Workspace = game.GetService("Workspace");
|
|||
const CAMERA = Workspace.CurrentCamera as Camera;
|
||||
assert(CAMERA, 'Camera of "' + Players.LocalPlayer.DisplayName + '"does not exist! (HOW???)');
|
||||
|
||||
export type inputBindings = {
|
||||
[input in keyof controlBindings]?: [((argument1?: unknown, argument2?: unknown) => void), unknown, unknown];
|
||||
};
|
||||
|
||||
export interface inputBinder {
|
||||
assignControlBindings: (controlBindings: controlBindings) => void;
|
||||
assignInputBindings: (inputBindings: inputBindings) => void;
|
||||
removeInputBindings: (inputBindings: inputBindings) => void;
|
||||
function enumTypeIs<EnumAsType>(value: unknown, EnumAsObject: Enum): value is EnumAsType {
|
||||
if (typeIs(value, "EnumItem")) {
|
||||
return value.Name in EnumAsObject
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
type validInput = Enum.KeyCode // + Include controller "keys"
|
||||
function isValidInput(value: unknown): value is validInput {
|
||||
return enumTypeIs<Enum.KeyCode>(value, Enum.KeyCode)
|
||||
}
|
||||
const actionAssignmentsReference: string[] = [
|
||||
"clicker1", // What is used to click on things (enemies in game, UI elements)
|
||||
"diamond1", // Diamond controls
|
||||
"diamond2",
|
||||
"diamond3",
|
||||
"diamond4",
|
||||
"special1", // Special controls
|
||||
"special2",
|
||||
]
|
||||
export interface actionAssignments { // Based on the reference array
|
||||
clicker1?: validInput; // What is used to click on things (enemies in game, UI elements)
|
||||
diamond1?: validInput; // Diamond controls
|
||||
diamond2?: validInput;
|
||||
diamond3?: validInput;
|
||||
diamond4?: validInput;
|
||||
special1?: validInput; // Special controls
|
||||
special2?: validInput;
|
||||
}
|
||||
type action = keyof actionAssignments
|
||||
function isValidAction(value: string): value is keyof actionAssignments {
|
||||
return value in actionAssignmentsReference; // uh oh
|
||||
}
|
||||
type actionBinding = [action, ((actionName?: string, state?: Enum.UserInputState, inputObject?: InputObject) => void)];
|
||||
type unknownTable = {[numberKey: number]: unknown, [stringKey: string]: unknown}
|
||||
export function isUnknownTable(thing: unknown): thing is unknownTable {
|
||||
return typeIs(thing, "table")
|
||||
}
|
||||
|
||||
interface inputHandler extends inputBinder {
|
||||
controlHandler: (actionName: string, state: Enum.UserInputState, inputObject: InputObject) => void;
|
||||
controlBindings?: controlBindings
|
||||
boundInputs: inputBindings
|
||||
storedInput?: string // + compound inputs
|
||||
}
|
||||
|
||||
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}
|
||||
function getMouseLocation(filterDescendantsInstances: any[]): [Vector3, Vector3, Instance | undefined] { // May be unnecessary
|
||||
const hitParams = new RaycastParams();
|
||||
hitParams.FilterType = Enum.RaycastFilterType.Blacklist;
|
||||
hitParams.FilterDescendantsInstances = filterDescendantsInstances
|
||||
const mouseLocation = UserInputService.GetMouseLocation();
|
||||
const unitRay = CAMERA.ViewportPointToRay(mouseLocation.X, mouseLocation.Y);
|
||||
const cast = Workspace.Raycast(unitRay.Origin, unitRay.Direction.mul(1000), hitParams);
|
||||
|
@ -37,51 +58,65 @@ function getMouseLocation(): [Vector3, Vector3, Instance | undefined] {
|
|||
}
|
||||
}
|
||||
|
||||
function isValidInput(controlBindings: controlBindings, value: string): value is keyof controlBindings {
|
||||
return value in controlBindings; // uh oh
|
||||
export function translateInputState(state: any) {
|
||||
if (enumTypeIs<Enum.UserInputState>(state, Enum.UserInputState)) {
|
||||
// + Translate to simple boolean
|
||||
}
|
||||
}
|
||||
//function(actionName: string, state: Enum.UserInputState, inputObject: InputObject) {
|
||||
// inputParameters[0](inputParameters[1])
|
||||
//}
|
||||
|
||||
export function makeInputHandler() {
|
||||
const t: inputHandler = {//return {
|
||||
assignControlBindings: function(controlBindings: controlBindings) {
|
||||
this.controlBindings = controlBindings // WOW!!!!!
|
||||
},
|
||||
assignInputBindings: function(inputBindings: inputBindings) {
|
||||
const controlBindings = this.controlBindings;
|
||||
if (controlBindings) {
|
||||
for (let input in inputBindings) {
|
||||
if (isValidInput(controlBindings, input)) {
|
||||
// + Check for this.boundInputs[input]
|
||||
const inputParameters = inputBindings[input]
|
||||
if (inputParameters) {
|
||||
this.boundInputs[input] = inputParameters;
|
||||
const controlArray = controlBindings[input];
|
||||
for (const control of controlArray) {
|
||||
ContextActionService.BindAction(input, this.controlHandler, false, control)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
export interface actionBinder {
|
||||
assignInputsToActions: (actionAssignments: unknownTable) => void; // The client gets these from the server (the player saves them to datastores)
|
||||
bindFunctionsToActions: (actionBindings: actionBinding[]) => void;
|
||||
unbindFunctionsFromActions: (actions: action[]) => void;
|
||||
}
|
||||
|
||||
class actionHandler implements actionBinder { // + Needs a semaphore if concurrency issues arise
|
||||
constructor() {
|
||||
// Fortnite
|
||||
}
|
||||
assignInputsToActions(actionAssignments: unknownTable) {
|
||||
let newActionAssignments: actionAssignments = {}
|
||||
actionAssignmentsReference.forEach(action => {
|
||||
const input: unknown = actionAssignments[action]
|
||||
if (isValidAction(action) && isValidInput(input)) {
|
||||
newActionAssignments[action] = input
|
||||
}
|
||||
},
|
||||
removeInputBindings: function(inputBindings: inputBindings) {},
|
||||
controlHandler: function(actionName: string, state: Enum.UserInputState, inputObject: InputObject) {
|
||||
const controlBindings = this.controlBindings;
|
||||
if (controlBindings) {
|
||||
if (isValidInput(controlBindings, actionName)) {
|
||||
const inputParameters = this.boundInputs[actionName]
|
||||
if (inputParameters) {
|
||||
inputParameters[0](inputParameters[1], inputParameters[2])
|
||||
}
|
||||
})
|
||||
}
|
||||
bindFunctionsToActions(actionBindings: actionBinding[]) {
|
||||
const actionAssignments = this.actionAssignments;
|
||||
const boundActions = this.boundActions;
|
||||
if (actionAssignments) {
|
||||
actionBindings.forEach(actionBinding => {
|
||||
const action = actionBinding[0]
|
||||
const input = actionAssignments[action];
|
||||
if (!boundActions[action] && input) {
|
||||
boundActions[action] = true;
|
||||
ContextActionService.BindAction(action, actionBinding[1], false, input);
|
||||
} else {
|
||||
// ???
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
unbindFunctionsFromActions(actions: action[]) {
|
||||
const boundActions = this.boundActions
|
||||
actions.forEach(action => {
|
||||
if (boundActions[action]) {
|
||||
boundActions[action] = undefined;
|
||||
ContextActionService.UnbindAction(action);
|
||||
} else {
|
||||
// ???
|
||||
}
|
||||
},
|
||||
|
||||
boundInputs: {}
|
||||
} //as inputHandler;
|
||||
})
|
||||
}
|
||||
|
||||
actionAssignments?: actionAssignments;
|
||||
boundActions: {[action: string]: boolean | undefined} = {};
|
||||
}
|
||||
|
||||
export function makeActionBinder(): actionBinder {
|
||||
return new actionHandler();
|
||||
}
|
||||
/*
|
||||
function handleInput(input: InputObject, otherInteraction: boolean) {
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
|
||||
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)
|
||||
}
|
||||
export const gamer: { [modeId: string]: modeLocal } = {
|
||||
["Flawless"]: {
|
||||
//aura: [[["Ball"]]], // Will come back to this later
|
||||
|
|
|
@ -4,6 +4,7 @@ const RunService = game.GetService("RunService");
|
|||
import { bindToServerMessage, messageServer } from "./ClientMessenger";
|
||||
import { handleGuiInput, drawGui, closeGui } from "./GuiHandler";
|
||||
import { makeEffectRunner, effectRunner } from "./EffectMaker";
|
||||
import { makeActionBinder, actionBinder, isUnknownTable } from "./InputHandler";
|
||||
const LOCALPLAYER = Players.LocalPlayer;
|
||||
const PLAYERGUI = LOCALPLAYER.WaitForChild("PlayerGui", 1) as PlayerGui;
|
||||
assert(
|
||||
|
@ -18,7 +19,7 @@ function openMainMenu(playerGui: PlayerGui) {
|
|||
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
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,11 +30,14 @@ function handleServerMessage(messageType: unknown, messageContent: unknown) {
|
|||
} else if (messageType === "enterGame") {
|
||||
closeGui(PLAYERGUI, "MainMenu");
|
||||
inMainMenu = false;
|
||||
} else if (messageType === "bindActions") {
|
||||
if (isUnknownTable(messageContent)) {
|
||||
mainActionBinder.assignInputsToActions(messageContent)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Bind functions
|
||||
|
||||
bindToServerMessage(handleServerMessage);
|
||||
|
||||
const effectRunners: effectRunner[] = [];
|
||||
// + Put stuff in the effectRunners table
|
||||
|
@ -42,3 +46,7 @@ RunService.RenderStepped.Connect(function(deltaTime) {
|
|||
effectRunner.runEffects(deltaTime)
|
||||
});
|
||||
})
|
||||
|
||||
const mainActionBinder: actionBinder = makeActionBinder()
|
||||
|
||||
bindToServerMessage(handleServerMessage);
|
12
src/services.d.ts
vendored
12
src/services.d.ts
vendored
|
@ -8,20 +8,8 @@ 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)
|
||||
}
|
||||
*/
|
||||
// Genuinely require being on both sides - but in the services file? No shot!
|
||||
type acceptedControls = Enum.KeyCode[] // + Include controller "keys"
|
||||
interface controlBindings {
|
||||
clicker1: acceptedControls; // What is used to click on things (enemies in game, UI elements)
|
||||
diamond1: acceptedControls; // Diamond controls
|
||||
diamond2: acceptedControls;
|
||||
diamond3: acceptedControls;
|
||||
diamond4: acceptedControls;
|
||||
special1: acceptedControls; // Special controls
|
||||
}
|
||||
|
||||
|
||||
/*interface hookInEntry {
|
||||
|
|
Loading…
Reference in a new issue