hi
Last active
March 21, 2025 12:30
-
-
Save jLn0n/fe59b29cb2d0d6a26273a892dcfd104a to your computer and use it in GitHub Desktop.
https://github.com/jLn0n/sb-scripts/tree/4108d218255c517c5cea456010b9221a51214f28/scripts/movement-system - processed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| local __DARKLUA_BUNDLE_MODULES __DARKLUA_BUNDLE_MODULES={cache={}, load=function(m)if not __DARKLUA_BUNDLE_MODULES.cache[m]then __DARKLUA_BUNDLE_MODULES.cache[m]={c=__DARKLUA_BUNDLE_MODULES[m]()}end return __DARKLUA_BUNDLE_MODULES.cache[m].c end}do function __DARKLUA_BUNDLE_MODULES.a() | |
| return nil end function __DARKLUA_BUNDLE_MODULES.b() | |
| local RunService=game:GetService("RunService") | |
| local types=__DARKLUA_BUNDLE_MODULES.load('a') | |
| local IS_SERVER=RunService:IsServer() | |
| local __internal_default_remote_from_handler_initialized=false | |
| local function _DEFAULT_REMOTE_HANDLER(remote_registry) | |
| if __internal_default_remote_from_handler_initialized then | |
| return false | |
| end | |
| __internal_default_remote_from_handler_initialized=true | |
| local REMOTE_CONTAINER_NAME=string.format('communiception_%s', tostring(game.PlaceId)) | |
| local _container_parent | |
| if owner then | |
| _container_parent=((owner:FindFirstChildWhichIsA("PlayerGui"))) | |
| else | |
| _container_parent=game:GetService("ReplicatedStorage") | |
| end | |
| local _container | |
| if IS_SERVER then | |
| _container=((_container_parent:FindFirstChild(REMOTE_CONTAINER_NAME))) | |
| if not _container then | |
| local new_container=Instance.new("Folder") | |
| new_container.Name=REMOTE_CONTAINER_NAME | |
| new_container.Parent=_container_parent | |
| _container=new_container | |
| end | |
| else | |
| _container=((_container_parent:WaitForChild(REMOTE_CONTAINER_NAME,10))) | |
| if not _container then | |
| error("[communiception]: could not fetch remote container",0) | |
| end | |
| end | |
| local reliable_remote=((_container:FindFirstChildWhichIsA("RemoteEvent"))) | |
| local unreliable_remote=((_container:FindFirstChildWhichIsA("UnreliableRemoteEvent"))) | |
| if not(reliable_remote and unreliable_remote)then | |
| if not IS_SERVER then | |
| error("[communiception]: internal remotes cannot be fully fetched",0) | |
| end | |
| reliable_remote=Instance.new("RemoteEvent",_container) | |
| unreliable_remote=Instance.new("UnreliableRemoteEvent",_container) | |
| end | |
| remote_registry.reliable=reliable_remote | |
| remote_registry.unreliable=unreliable_remote | |
| return true | |
| end | |
| local _DEFAULT_CONFIGURATION={ | |
| INCOMING_PACKET_THRESHOLD=30, | |
| OUTCOMING_PACKET_THRESHOLD=30, | |
| INTERNAL_REMOTE_HANDLER=_DEFAULT_REMOTE_HANDLER | |
| } | |
| local CommuniceptionCommon={ | |
| DEFAULT_CONFIGURATION=_DEFAULT_CONFIGURATION | |
| } | |
| function CommuniceptionCommon.initializeInternalRemotes( | |
| remote_handler | |
| ) | |
| local registry_changed_event=Instance.new("BindableEvent") | |
| local remote_registry=({}) | |
| task.spawn(function() | |
| while true do RunService.PostSimulation:Wait() | |
| local new_registry=remote_handler(remote_registry) | |
| if new_registry then | |
| registry_changed_event:Fire() | |
| end | |
| end | |
| end) | |
| registry_changed_event.Event:Wait() | |
| return remote_registry,registry_changed_event | |
| end | |
| function CommuniceptionCommon.getEmptyIndex(tbl_array,start) | |
| local tbl_size=#tbl_array | |
| for idx=start or 1,tbl_size do local __DARKLUA_CONTINUE_2=false repeat | |
| if tbl_array[idx]then __DARKLUA_CONTINUE_2=true | |
| break | |
| end | |
| return idx until true if not __DARKLUA_CONTINUE_2 then break end | |
| end | |
| return tbl_size+1 | |
| end | |
| return CommuniceptionCommon end function __DARKLUA_BUNDLE_MODULES.c() | |
| local RunService=game:GetService("RunService") | |
| local types=__DARKLUA_BUNDLE_MODULES.load('a') | |
| local common=__DARKLUA_BUNDLE_MODULES.load('b') | |
| local IS_SERVER=RunService:IsServer() | |
| local _initialized=false | |
| local registered_ids={} | |
| local incoming_packets={} | |
| local outcoming_packets={} | |
| local incoming_packet_listeners={} | |
| local CommuniceptionEventObj={} | |
| function CommuniceptionEventObj._init(self) | |
| incoming_packet_listeners[self.id]=function(sender,...) | |
| for _,listener in self._internal.listeners do | |
| task.spawn(listener,{...},sender) | |
| end | |
| end | |
| end | |
| function CommuniceptionEventObj.send(self,...) | |
| assert(not IS_SERVER,"[communiception]: CommuniceptionEvent::send can only be called on client-side") | |
| table.insert(outcoming_packets,{ | |
| type=((self.mode)), | |
| id=self.id, | |
| args={...}, | |
| }) | |
| end | |
| function CommuniceptionEventObj.sendTo(self,target,...) | |
| assert(IS_SERVER,"[communiception]: CommuniceptionEvent::sendTo can only be called on server-side") | |
| table.insert(outcoming_packets,{ | |
| type=((self.mode)), | |
| id=self.id, | |
| args={...}, | |
| targets={target}, | |
| }) | |
| end | |
| function CommuniceptionEventObj.sendToMultiple(self,targets,...) | |
| assert(IS_SERVER,"[communiception]: CommuniceptionEvent::sendToMultiple can only be called on server-side") | |
| table.insert(outcoming_packets,{ | |
| type=((self.mode)), | |
| id=self.id, | |
| args={...}, | |
| targets=targets, | |
| }) | |
| end | |
| function CommuniceptionEventObj.listen(self,listener) | |
| local listener_id=common.getEmptyIndex(self._internal.listeners) | |
| self._internal.listeners[listener_id]=listener | |
| return function() | |
| self._internal.listeners[listener_id]=nil | |
| end | |
| end | |
| function CommuniceptionEventObj.listenOnce(self,listener) | |
| local disconnect_func | |
| local function listener_wrapper(...) | |
| listener(...) | |
| disconnect_func() | |
| end | |
| disconnect_func=CommuniceptionEventObj.listen(self,listener_wrapper) | |
| return disconnect_func | |
| end | |
| function CommuniceptionEventObj.wait(self) | |
| local thread=coroutine.running() | |
| local disconnect_func | |
| local function listener_wrapper(...) | |
| disconnect_func() | |
| task.spawn(thread,...) | |
| end | |
| disconnect_func=CommuniceptionEventObj.listen(self,listener_wrapper) | |
| return coroutine.yield() | |
| end | |
| function CommuniceptionEventObj.disconnectAll(self) | |
| table.clear(self._internal.listeners) | |
| end | |
| local CommuniceptionFunctionObj={} | |
| function CommuniceptionFunctionObj._init(self) | |
| incoming_packet_listeners[string.format('i_%s', tostring(self.id))]=function(sender,callback_id,...) | |
| local listener=self._internal.listeners[callback_id] | |
| if not listener then | |
| return | |
| end | |
| listener(sender,...) | |
| end | |
| incoming_packet_listeners[string.format('o_%s', tostring(self.id))]=function(sender,callback_id,...) | |
| local current_callback=self._internal.callback | |
| if not current_callback then | |
| return | |
| end | |
| task.spawn(function(...) | |
| table.insert(outcoming_packets,{ | |
| type=("reliable"), | |
| id=string.format('i_%s', tostring(self.id)), | |
| args={callback_id,current_callback({...},sender)}, | |
| targets=({sender}), | |
| }) | |
| end,...) | |
| end | |
| end | |
| function CommuniceptionFunctionObj.invoke(self,timeout,...) | |
| assert(not IS_SERVER,"[communiception]: CommuniceptionFunction::invoke can only be called on client-side") | |
| local thread=coroutine.running() | |
| local callback_recieved=false | |
| local callback_id=common.getEmptyIndex(self._internal.listeners) | |
| self._internal.listeners[callback_id]=function(...) | |
| callback_recieved=true | |
| self._internal.listeners[callback_id]=nil | |
| task.spawn(thread,true,...) | |
| end | |
| task.delay(timeout,function() | |
| if callback_recieved then | |
| return | |
| end | |
| self._internal.listeners[callback_id]=nil | |
| task.spawn(thread,false) | |
| end) | |
| table.insert(outcoming_packets,{ | |
| type=("reliable"), | |
| id=string.format('o_%s', tostring(self.id)), | |
| args={callback_id,...}, | |
| }) | |
| return coroutine.yield() | |
| end | |
| function CommuniceptionFunctionObj.invokeTo(self,target,timeout,...) | |
| assert(IS_SERVER,"[communiception]: CommuniceptionFunction::invokeTo can only be called on server-side") | |
| local thread=coroutine.running() | |
| local callback_recieved=false | |
| local callback_id=common.getEmptyIndex(self._internal.listeners) | |
| self._internal.listeners[callback_id]=function(sender,...) | |
| if sender and(target.UserId~=sender.UserId)then | |
| return | |
| end | |
| callback_recieved=true | |
| self._internal.listeners[callback_id]=nil | |
| task.spawn(thread,true,...) | |
| end | |
| task.delay(timeout,function() | |
| if callback_recieved then | |
| return | |
| end | |
| self._internal.listeners[callback_id]=nil | |
| task.spawn(thread,false) | |
| end) | |
| table.insert(outcoming_packets,{ | |
| type=("reliable"), | |
| id=string.format('o_%s', tostring(self.id)), | |
| args={callback_id,...}, | |
| targets={target}, | |
| }) | |
| return coroutine.yield() | |
| end | |
| function CommuniceptionFunctionObj.setListener(self,callback) | |
| self._internal.callback=callback | |
| end | |
| local module={} | |
| function module.initialize(config) | |
| if _initialized then | |
| return error("[communiception]: already initialized.") | |
| end | |
| _initialized=true | |
| local current_config=config or common.DEFAULT_CONFIGURATION | |
| local current_remotes,_registry_changed=common.initializeInternalRemotes(current_config.INTERNAL_REMOTE_HANDLER) | |
| local __RBXSignalConnect=_registry_changed.Event.Connect | |
| local _registration_event | |
| local _remote_refs=({}) | |
| local _registering_funcs | |
| =({}) | |
| if IS_SERVER then | |
| _registration_event="OnServerEvent" | |
| _registering_funcs.reliable=function(sender,id,...) | |
| table.insert(incoming_packets,{ | |
| type=("reliable"), | |
| id=id, | |
| args={...}, | |
| sender=sender | |
| }) | |
| end | |
| _registering_funcs.unreliable=function(sender,id,...) | |
| table.insert(incoming_packets,{ | |
| type=("unreliable"), | |
| id=id, | |
| args={...}, | |
| sender=sender | |
| }) | |
| end | |
| else | |
| _registration_event="OnClientEvent" | |
| _registering_funcs.reliable=function(id,...) | |
| table.insert(incoming_packets,{ | |
| type=("reliable"), | |
| id=id, | |
| args={...}, | |
| }) | |
| end | |
| _registering_funcs.unreliable=function(id,...) | |
| table.insert(incoming_packets,{ | |
| type=("unreliable"), | |
| id=id, | |
| args={...}, | |
| }) | |
| end | |
| end | |
| local function _onRemoteRegistryChanged() | |
| for remote_type,remote_obj in pairs(current_remotes)do local __DARKLUA_CONTINUE_4=false repeat | |
| if _remote_refs[remote_type]==remote_obj then __DARKLUA_CONTINUE_4=true | |
| break | |
| end | |
| _remote_refs[remote_type]=remote_obj | |
| __RBXSignalConnect(remote_obj[_registration_event],_registering_funcs[remote_type])__DARKLUA_CONTINUE_4=true until true if not __DARKLUA_CONTINUE_4 then break end | |
| end | |
| end | |
| RunService.PostSimulation:Connect(function() | |
| for _=1,current_config.INCOMING_PACKET_THRESHOLD do local __DARKLUA_CONTINUE_5=false repeat | |
| local incoming_packet=table.remove(incoming_packets) | |
| if not incoming_packet then | |
| break | |
| end | |
| if IS_SERVER and(not incoming_packet.sender)then __DARKLUA_CONTINUE_5=true | |
| break | |
| end | |
| local listener=incoming_packet_listeners[incoming_packet.id] | |
| if not listener then __DARKLUA_CONTINUE_5=true | |
| break | |
| end | |
| task.spawn(listener,incoming_packet.sender,unpack(incoming_packet.args))__DARKLUA_CONTINUE_5=true until true if not __DARKLUA_CONTINUE_5 then break end | |
| end | |
| for _=1,current_config.OUTCOMING_PACKET_THRESHOLD do local __DARKLUA_CONTINUE_6=false repeat | |
| local outcoming_packet=table.remove(outcoming_packets) | |
| if not outcoming_packet then | |
| break | |
| end | |
| if IS_SERVER then | |
| if(not outcoming_packet.targets)then __DARKLUA_CONTINUE_6=true | |
| break | |
| end | |
| for _,target in outcoming_packet.targets do | |
| current_remotes[outcoming_packet.type]:FireClient(target,outcoming_packet.id,unpack(outcoming_packet.args)) | |
| end | |
| else | |
| current_remotes[outcoming_packet.type]:FireServer(outcoming_packet.id,unpack(outcoming_packet.args)) | |
| end __DARKLUA_CONTINUE_6=true until true if not __DARKLUA_CONTINUE_6 then break end | |
| end | |
| end) | |
| _onRemoteRegistryChanged() | |
| _registry_changed.Event:Connect(_onRemoteRegistryChanged) | |
| end | |
| function module.newEvent( | |
| id, | |
| mode | |
| ) | |
| if registered_ids[id]then | |
| return error(string.format('[communiception]: remote[id=%s] is already registered', tostring(id))) | |
| end | |
| registered_ids[id]=true | |
| local self=setmetatable({},{ | |
| __index=CommuniceptionEventObj | |
| }) | |
| self.id=id | |
| self.mode=mode | |
| self._internal={ | |
| listeners={}, | |
| } | |
| self._init(self) | |
| return(self) | |
| end | |
| function module.newFunction( | |
| id | |
| ) | |
| if registered_ids[id]then | |
| return error(string.format('[communiception]: remote[id=%s] is already registered', tostring(id))) | |
| end | |
| registered_ids[id]=true | |
| local self=setmetatable({},{ | |
| __index=CommuniceptionFunctionObj | |
| }) | |
| self.id=id | |
| self._internal={ | |
| listeners={}, | |
| } | |
| self._init(self) | |
| return(self) | |
| end | |
| return module end end | |
| print("client waiting") | |
| repeat task.wait()until script:GetAttribute("server_ready") | |
| local input_service=game:GetService("UserInputService") | |
| local run_service=game:GetService("RunService") | |
| local communiception=__DARKLUA_BUNDLE_MODULES.load('c') | |
| local camera=workspace.CurrentCamera | |
| local MOVEMENT_FIELDS={ | |
| forward=1, | |
| backward=2, | |
| leftward=4, | |
| rightward=8, | |
| jump=16, | |
| } | |
| local MOVEMENT_CONTROLS={ | |
| forward=Enum.KeyCode.W, | |
| backward=Enum.KeyCode.S, | |
| leftward=Enum.KeyCode.A, | |
| rightward=Enum.KeyCode.D, | |
| jump=Enum.KeyCode.Space | |
| } | |
| local send_movement_states=communiception.newEvent("send_movement_state","unreliable") | |
| local thingamajig=communiception.newFunction("thingamajig") | |
| local character_data={ | |
| movement_states={ | |
| forward=0, | |
| backward=0, | |
| leftward=0, | |
| rightward=0, | |
| jump=0 | |
| } | |
| } | |
| local function encode_movement(movement_states) | |
| local result | |
| result=bit32.band((movement_states.forward),MOVEMENT_FIELDS.forward) | |
| result=result+bit32.band(bit32.lshift((movement_states.backward),1),MOVEMENT_FIELDS.backward) | |
| result=result+bit32.band(bit32.lshift((movement_states.leftward),2),MOVEMENT_FIELDS.leftward) | |
| result=result+bit32.band(bit32.lshift((movement_states.rightward),3),MOVEMENT_FIELDS.rightward) | |
| result=result+bit32.band(bit32.lshift((movement_states.jump),4),MOVEMENT_FIELDS.jump) | |
| return result | |
| end | |
| local function send_current_state() | |
| local movement_state=encode_movement(character_data.movement_states) | |
| local _,yaw_rot=camera.CFrame:ToOrientation() | |
| local state_buff=buffer.create(4) | |
| local mapped_yaw=math.floor(math.map(yaw_rot,-math.pi,math.pi,0,65535)) | |
| buffer.writeu16(state_buff,0,mapped_yaw) | |
| buffer.writeu16(state_buff,2,movement_state) | |
| send_movement_states:send(state_buff) | |
| end | |
| print("initializing communiception") | |
| communiception.initialize() | |
| print("communiception initialized") | |
| run_service.PreSimulation:Connect(function() | |
| if input_service:GetFocusedTextBox()then return end | |
| for movement_name,movement_keycode in pairs(MOVEMENT_CONTROLS)do | |
| character_data.movement_states[movement_name]=(input_service:IsKeyDown(movement_keycode)and 1 or 0) | |
| end | |
| end) | |
| run_service.PostSimulation:Connect(function() | |
| send_current_state() | |
| end) | |
| print("[communiception test]: thingamajig return got:",thingamajig:invoke(5,"ghi","helow",69420.1)) | |
| print("client initialized") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| local __DARKLUA_BUNDLE_MODULES __DARKLUA_BUNDLE_MODULES={cache={}, load=function(m)if not __DARKLUA_BUNDLE_MODULES.cache[m]then __DARKLUA_BUNDLE_MODULES.cache[m]={c=__DARKLUA_BUNDLE_MODULES[m]()}end return __DARKLUA_BUNDLE_MODULES.cache[m].c end}do function __DARKLUA_BUNDLE_MODULES.a() | |
| local HttpService=game:GetService("HttpService") | |
| local RunService=game:GetService("RunService") | |
| local GITHUB_API_URL="https://gist-shenanigans.jln0n-xd.workers.dev" | |
| local GIST_FETCH_RETRIES=10 | |
| local function gist_url_constructor(gist_id,gist_owner,commit_hash) | |
| return"https://gist.githubusercontent.com/"..gist_owner.."/"..gist_id.."/raw/"..commit_hash.."/" | |
| end | |
| local function fetch_url(url,no_cache) | |
| local success,result=pcall(HttpService.GetAsync,HttpService,url,no_cache) | |
| if not success then | |
| warn(string.format("Failed to load URL '%s'\n%s", tostring(url), tostring(result))) | |
| return nil | |
| end | |
| return result | |
| end | |
| local function load_url(url,chunk_name) | |
| local result=fetch_url(url,true) | |
| return((result and{(loadstring(result,chunk_name or url))}or{nil})[1]) | |
| end | |
| return function(gist_id) | |
| if not RunService:IsServer()then | |
| return error("This can only be utilized in server-side!",2) | |
| end | |
| local _retries=0 | |
| local raw_gist_commits; | |
| repeat | |
| raw_gist_commits=fetch_url(string.format('%s/gists/%s/commits', tostring(GITHUB_API_URL), tostring(gist_id)),true) | |
| if raw_gist_commits then | |
| break | |
| end | |
| task.wait(1) | |
| _retries=_retries+1 | |
| until _retries>GIST_FETCH_RETRIES | |
| if not raw_gist_commits then | |
| return error(string.format("Failed to fetch gist '%s' atmost %s tries!", tostring(gist_id), tostring(GIST_FETCH_RETRIES)),2) | |
| end | |
| local gist_commits=HttpService:JSONDecode(raw_gist_commits) | |
| local gist_latest_commit=gist_commits[1] | |
| local commit_hash=gist_latest_commit.version | |
| local gist_owner=gist_latest_commit.user.login | |
| local gist_url=gist_url_constructor(gist_id,gist_owner,commit_hash) | |
| return{ | |
| fetch=function(path,no_cache) | |
| return fetch_url(gist_url..path,no_cache) | |
| end, | |
| load_src=function(path) | |
| return load_url(gist_url..path,string.format('github-gist/%s/%s', tostring(gist_id), tostring(path))) | |
| end, | |
| } | |
| end end function __DARKLUA_BUNDLE_MODULES.b() | |
| return nil end function __DARKLUA_BUNDLE_MODULES.c() | |
| local RunService=game:GetService("RunService") | |
| local types=__DARKLUA_BUNDLE_MODULES.load('b') | |
| local IS_SERVER=RunService:IsServer() | |
| local __internal_default_remote_from_handler_initialized=false | |
| local function _DEFAULT_REMOTE_HANDLER(remote_registry) | |
| if __internal_default_remote_from_handler_initialized then | |
| return false | |
| end | |
| __internal_default_remote_from_handler_initialized=true | |
| local REMOTE_CONTAINER_NAME=string.format('communiception_%s', tostring(game.PlaceId)) | |
| local _container_parent | |
| if owner then | |
| _container_parent=((owner:FindFirstChildWhichIsA("PlayerGui"))) | |
| else | |
| _container_parent=game:GetService("ReplicatedStorage") | |
| end | |
| local _container | |
| if IS_SERVER then | |
| _container=((_container_parent:FindFirstChild(REMOTE_CONTAINER_NAME))) | |
| if not _container then | |
| local new_container=Instance.new("Folder") | |
| new_container.Name=REMOTE_CONTAINER_NAME | |
| new_container.Parent=_container_parent | |
| _container=new_container | |
| end | |
| else | |
| _container=((_container_parent:WaitForChild(REMOTE_CONTAINER_NAME,10))) | |
| if not _container then | |
| error("[communiception]: could not fetch remote container",0) | |
| end | |
| end | |
| local reliable_remote=((_container:FindFirstChildWhichIsA("RemoteEvent"))) | |
| local unreliable_remote=((_container:FindFirstChildWhichIsA("UnreliableRemoteEvent"))) | |
| if not(reliable_remote and unreliable_remote)then | |
| if not IS_SERVER then | |
| error("[communiception]: internal remotes cannot be fully fetched",0) | |
| end | |
| reliable_remote=Instance.new("RemoteEvent",_container) | |
| unreliable_remote=Instance.new("UnreliableRemoteEvent",_container) | |
| end | |
| remote_registry.reliable=reliable_remote | |
| remote_registry.unreliable=unreliable_remote | |
| return true | |
| end | |
| local _DEFAULT_CONFIGURATION={ | |
| INCOMING_PACKET_THRESHOLD=30, | |
| OUTCOMING_PACKET_THRESHOLD=30, | |
| INTERNAL_REMOTE_HANDLER=_DEFAULT_REMOTE_HANDLER | |
| } | |
| local CommuniceptionCommon={ | |
| DEFAULT_CONFIGURATION=_DEFAULT_CONFIGURATION | |
| } | |
| function CommuniceptionCommon.initializeInternalRemotes( | |
| remote_handler | |
| ) | |
| local registry_changed_event=Instance.new("BindableEvent") | |
| local remote_registry=({}) | |
| task.spawn(function() | |
| while true do RunService.PostSimulation:Wait() | |
| local new_registry=remote_handler(remote_registry) | |
| if new_registry then | |
| registry_changed_event:Fire() | |
| end | |
| end | |
| end) | |
| registry_changed_event.Event:Wait() | |
| return remote_registry,registry_changed_event | |
| end | |
| function CommuniceptionCommon.getEmptyIndex(tbl_array,start) | |
| local tbl_size=#tbl_array | |
| for idx=start or 1,tbl_size do local __DARKLUA_CONTINUE_3=false repeat | |
| if tbl_array[idx]then __DARKLUA_CONTINUE_3=true | |
| break | |
| end | |
| return idx until true if not __DARKLUA_CONTINUE_3 then break end | |
| end | |
| return tbl_size+1 | |
| end | |
| return CommuniceptionCommon end function __DARKLUA_BUNDLE_MODULES.d() | |
| local RunService=game:GetService("RunService") | |
| local types=__DARKLUA_BUNDLE_MODULES.load('b') | |
| local common=__DARKLUA_BUNDLE_MODULES.load('c') | |
| local IS_SERVER=RunService:IsServer() | |
| local _initialized=false | |
| local registered_ids={} | |
| local incoming_packets={} | |
| local outcoming_packets={} | |
| local incoming_packet_listeners={} | |
| local CommuniceptionEventObj={} | |
| function CommuniceptionEventObj._init(self) | |
| incoming_packet_listeners[self.id]=function(sender,...) | |
| for _,listener in self._internal.listeners do | |
| task.spawn(listener,{...},sender) | |
| end | |
| end | |
| end | |
| function CommuniceptionEventObj.send(self,...) | |
| assert(not IS_SERVER,"[communiception]: CommuniceptionEvent::send can only be called on client-side") | |
| table.insert(outcoming_packets,{ | |
| type=((self.mode)), | |
| id=self.id, | |
| args={...}, | |
| }) | |
| end | |
| function CommuniceptionEventObj.sendTo(self,target,...) | |
| assert(IS_SERVER,"[communiception]: CommuniceptionEvent::sendTo can only be called on server-side") | |
| table.insert(outcoming_packets,{ | |
| type=((self.mode)), | |
| id=self.id, | |
| args={...}, | |
| targets={target}, | |
| }) | |
| end | |
| function CommuniceptionEventObj.sendToMultiple(self,targets,...) | |
| assert(IS_SERVER,"[communiception]: CommuniceptionEvent::sendToMultiple can only be called on server-side") | |
| table.insert(outcoming_packets,{ | |
| type=((self.mode)), | |
| id=self.id, | |
| args={...}, | |
| targets=targets, | |
| }) | |
| end | |
| function CommuniceptionEventObj.listen(self,listener) | |
| local listener_id=common.getEmptyIndex(self._internal.listeners) | |
| self._internal.listeners[listener_id]=listener | |
| return function() | |
| self._internal.listeners[listener_id]=nil | |
| end | |
| end | |
| function CommuniceptionEventObj.listenOnce(self,listener) | |
| local disconnect_func | |
| local function listener_wrapper(...) | |
| listener(...) | |
| disconnect_func() | |
| end | |
| disconnect_func=CommuniceptionEventObj.listen(self,listener_wrapper) | |
| return disconnect_func | |
| end | |
| function CommuniceptionEventObj.wait(self) | |
| local thread=coroutine.running() | |
| local disconnect_func | |
| local function listener_wrapper(...) | |
| disconnect_func() | |
| task.spawn(thread,...) | |
| end | |
| disconnect_func=CommuniceptionEventObj.listen(self,listener_wrapper) | |
| return coroutine.yield() | |
| end | |
| function CommuniceptionEventObj.disconnectAll(self) | |
| table.clear(self._internal.listeners) | |
| end | |
| local CommuniceptionFunctionObj={} | |
| function CommuniceptionFunctionObj._init(self) | |
| incoming_packet_listeners[string.format('i_%s', tostring(self.id))]=function(sender,callback_id,...) | |
| local listener=self._internal.listeners[callback_id] | |
| if not listener then | |
| return | |
| end | |
| listener(sender,...) | |
| end | |
| incoming_packet_listeners[string.format('o_%s', tostring(self.id))]=function(sender,callback_id,...) | |
| local current_callback=self._internal.callback | |
| if not current_callback then | |
| return | |
| end | |
| task.spawn(function(...) | |
| table.insert(outcoming_packets,{ | |
| type=("reliable"), | |
| id=string.format('i_%s', tostring(self.id)), | |
| args={callback_id,current_callback({...},sender)}, | |
| targets=({sender}), | |
| }) | |
| end,...) | |
| end | |
| end | |
| function CommuniceptionFunctionObj.invoke(self,timeout,...) | |
| assert(not IS_SERVER,"[communiception]: CommuniceptionFunction::invoke can only be called on client-side") | |
| local thread=coroutine.running() | |
| local callback_recieved=false | |
| local callback_id=common.getEmptyIndex(self._internal.listeners) | |
| self._internal.listeners[callback_id]=function(...) | |
| callback_recieved=true | |
| self._internal.listeners[callback_id]=nil | |
| task.spawn(thread,true,...) | |
| end | |
| task.delay(timeout,function() | |
| if callback_recieved then | |
| return | |
| end | |
| self._internal.listeners[callback_id]=nil | |
| task.spawn(thread,false) | |
| end) | |
| table.insert(outcoming_packets,{ | |
| type=("reliable"), | |
| id=string.format('o_%s', tostring(self.id)), | |
| args={callback_id,...}, | |
| }) | |
| return coroutine.yield() | |
| end | |
| function CommuniceptionFunctionObj.invokeTo(self,target,timeout,...) | |
| assert(IS_SERVER,"[communiception]: CommuniceptionFunction::invokeTo can only be called on server-side") | |
| local thread=coroutine.running() | |
| local callback_recieved=false | |
| local callback_id=common.getEmptyIndex(self._internal.listeners) | |
| self._internal.listeners[callback_id]=function(sender,...) | |
| if sender and(target.UserId~=sender.UserId)then | |
| return | |
| end | |
| callback_recieved=true | |
| self._internal.listeners[callback_id]=nil | |
| task.spawn(thread,true,...) | |
| end | |
| task.delay(timeout,function() | |
| if callback_recieved then | |
| return | |
| end | |
| self._internal.listeners[callback_id]=nil | |
| task.spawn(thread,false) | |
| end) | |
| table.insert(outcoming_packets,{ | |
| type=("reliable"), | |
| id=string.format('o_%s', tostring(self.id)), | |
| args={callback_id,...}, | |
| targets={target}, | |
| }) | |
| return coroutine.yield() | |
| end | |
| function CommuniceptionFunctionObj.setListener(self,callback) | |
| self._internal.callback=callback | |
| end | |
| local module={} | |
| function module.initialize(config) | |
| if _initialized then | |
| return error("[communiception]: already initialized.") | |
| end | |
| _initialized=true | |
| local current_config=config or common.DEFAULT_CONFIGURATION | |
| local current_remotes,_registry_changed=common.initializeInternalRemotes(current_config.INTERNAL_REMOTE_HANDLER) | |
| local __RBXSignalConnect=_registry_changed.Event.Connect | |
| local _registration_event | |
| local _remote_refs=({}) | |
| local _registering_funcs | |
| =({}) | |
| if IS_SERVER then | |
| _registration_event="OnServerEvent" | |
| _registering_funcs.reliable=function(sender,id,...) | |
| table.insert(incoming_packets,{ | |
| type=("reliable"), | |
| id=id, | |
| args={...}, | |
| sender=sender | |
| }) | |
| end | |
| _registering_funcs.unreliable=function(sender,id,...) | |
| table.insert(incoming_packets,{ | |
| type=("unreliable"), | |
| id=id, | |
| args={...}, | |
| sender=sender | |
| }) | |
| end | |
| else | |
| _registration_event="OnClientEvent" | |
| _registering_funcs.reliable=function(id,...) | |
| table.insert(incoming_packets,{ | |
| type=("reliable"), | |
| id=id, | |
| args={...}, | |
| }) | |
| end | |
| _registering_funcs.unreliable=function(id,...) | |
| table.insert(incoming_packets,{ | |
| type=("unreliable"), | |
| id=id, | |
| args={...}, | |
| }) | |
| end | |
| end | |
| local function _onRemoteRegistryChanged() | |
| for remote_type,remote_obj in pairs(current_remotes)do local __DARKLUA_CONTINUE_5=false repeat | |
| if _remote_refs[remote_type]==remote_obj then __DARKLUA_CONTINUE_5=true | |
| break | |
| end | |
| _remote_refs[remote_type]=remote_obj | |
| __RBXSignalConnect(remote_obj[_registration_event],_registering_funcs[remote_type])__DARKLUA_CONTINUE_5=true until true if not __DARKLUA_CONTINUE_5 then break end | |
| end | |
| end | |
| RunService.PostSimulation:Connect(function() | |
| for _=1,current_config.INCOMING_PACKET_THRESHOLD do local __DARKLUA_CONTINUE_6=false repeat | |
| local incoming_packet=table.remove(incoming_packets) | |
| if not incoming_packet then | |
| break | |
| end | |
| if IS_SERVER and(not incoming_packet.sender)then __DARKLUA_CONTINUE_6=true | |
| break | |
| end | |
| local listener=incoming_packet_listeners[incoming_packet.id] | |
| if not listener then __DARKLUA_CONTINUE_6=true | |
| break | |
| end | |
| task.spawn(listener,incoming_packet.sender,unpack(incoming_packet.args))__DARKLUA_CONTINUE_6=true until true if not __DARKLUA_CONTINUE_6 then break end | |
| end | |
| for _=1,current_config.OUTCOMING_PACKET_THRESHOLD do local __DARKLUA_CONTINUE_7=false repeat | |
| local outcoming_packet=table.remove(outcoming_packets) | |
| if not outcoming_packet then | |
| break | |
| end | |
| if IS_SERVER then | |
| if(not outcoming_packet.targets)then __DARKLUA_CONTINUE_7=true | |
| break | |
| end | |
| for _,target in outcoming_packet.targets do | |
| current_remotes[outcoming_packet.type]:FireClient(target,outcoming_packet.id,unpack(outcoming_packet.args)) | |
| end | |
| else | |
| current_remotes[outcoming_packet.type]:FireServer(outcoming_packet.id,unpack(outcoming_packet.args)) | |
| end __DARKLUA_CONTINUE_7=true until true if not __DARKLUA_CONTINUE_7 then break end | |
| end | |
| end) | |
| _onRemoteRegistryChanged() | |
| _registry_changed.Event:Connect(_onRemoteRegistryChanged) | |
| end | |
| function module.newEvent( | |
| id, | |
| mode | |
| ) | |
| if registered_ids[id]then | |
| return error(string.format('[communiception]: remote[id=%s] is already registered', tostring(id))) | |
| end | |
| registered_ids[id]=true | |
| local self=setmetatable({},{ | |
| __index=CommuniceptionEventObj | |
| }) | |
| self.id=id | |
| self.mode=mode | |
| self._internal={ | |
| listeners={}, | |
| } | |
| self._init(self) | |
| return(self) | |
| end | |
| function module.newFunction( | |
| id | |
| ) | |
| if registered_ids[id]then | |
| return error(string.format('[communiception]: remote[id=%s] is already registered', tostring(id))) | |
| end | |
| registered_ids[id]=true | |
| local self=setmetatable({},{ | |
| __index=CommuniceptionFunctionObj | |
| }) | |
| self.id=id | |
| self._internal={ | |
| listeners={}, | |
| } | |
| self._init(self) | |
| return(self) | |
| end | |
| return module end function __DARKLUA_BUNDLE_MODULES.e() | |
| return nil end function __DARKLUA_BUNDLE_MODULES.f() | |
| local SimulationTypes=__DARKLUA_BUNDLE_MODULES.load('e') | |
| return nil end function __DARKLUA_BUNDLE_MODULES.g() | |
| local module={} | |
| function module.FlatVector(vect3) | |
| return Vector3.new(vect3.X,0,vect3.Z) | |
| end | |
| function module.Friction(value,friction,delta_time) | |
| return(1/(1+(delta_time/friction)))*value | |
| end | |
| function module.VelocityFriction(velocity,friction,delta_time) | |
| local speed=velocity.Magnitude | |
| speed=module.Friction(speed,friction,delta_time) | |
| if speed<0.001 then | |
| return Vector3.new(0,0,0) | |
| end | |
| velocity=velocity.Unit*speed | |
| return velocity | |
| end | |
| function module.ClipVelocity(input,normal,overbounce) | |
| local backoff=input:Dot(normal) | |
| if backoff<0 then | |
| backoff=backoff*overbounce | |
| else | |
| backoff=backoff/overbounce | |
| end | |
| local changex=normal.X*backoff | |
| local changey=normal.Y*backoff | |
| local changez=normal.Z*backoff | |
| return Vector3.new(input.X-changex,input.Y-changey,input.Z-changez) | |
| end | |
| function module.GroundAccelerate( | |
| direction, | |
| speed, | |
| acceleration, | |
| velocity, | |
| delta_time | |
| ) | |
| local vel_speed=velocity.Magnitude | |
| if vel_speed>speed then | |
| velocity=velocity.Unit*speed | |
| end | |
| local wish_vel=direction*speed | |
| local push_dir=wish_vel-velocity | |
| local push_dist=push_dir.Magnitude | |
| local can_push=acceleration*delta_time*speed | |
| if can_push>push_dist then | |
| can_push=push_dist | |
| end | |
| if can_push<0.00001 then | |
| return velocity | |
| end | |
| return velocity+(can_push*push_dir.Unit) | |
| end | |
| function module.Accelerate( | |
| direction, | |
| speed, | |
| acceleration, | |
| velocity, | |
| delta_time | |
| ) | |
| local vel_speed=velocity.Magnitude | |
| local current_speed=velocity:Dot(direction) | |
| local added_speed=speed-current_speed | |
| if added_speed<=0 then | |
| return velocity | |
| end | |
| local accel_speed=acceleration*delta_time*speed | |
| if accel_speed>added_speed then | |
| accel_speed=added_speed | |
| end | |
| velocity=velocity+(accel_speed*direction) | |
| if vel_speed>speed and velocity.Magnitude>vel_speed then | |
| velocity=velocity.Unit*vel_speed | |
| end | |
| return velocity | |
| end | |
| return module end function __DARKLUA_BUNDLE_MODULES.h() | |
| local types=__DARKLUA_BUNDLE_MODULES.load('e') | |
| local MathUtils=__DARKLUA_BUNDLE_MODULES.load('g') | |
| local COLLISION_SHIFTBACK=1 | |
| local COLLISION_SIZE=Vector3.new(3,5,3) | |
| local COLLISION_CASTPARAMS=RaycastParams.new() | |
| COLLISION_CASTPARAMS.RespectCanCollide=true | |
| COLLISION_CASTPARAMS.IgnoreWater=true | |
| local module={} | |
| function module.Sweep(start_pos,end_pos) | |
| local data={ | |
| start_pos=start_pos, | |
| end_pos=end_pos, | |
| normal=Vector3.new(0,1,0), | |
| fraction=1, | |
| start_solid=false, | |
| all_solid=false, | |
| } | |
| local offset=(end_pos-start_pos) | |
| local distance=offset.Magnitude | |
| if not(distance>=0 and distance<=1024)then | |
| return data | |
| end | |
| local direction=offset.Unit | |
| local cast_origin=start_pos-(direction*COLLISION_SHIFTBACK) | |
| local ray_result=workspace:Blockcast( | |
| CFrame.identity+(cast_origin), | |
| COLLISION_SIZE, | |
| direction*(distance+COLLISION_SHIFTBACK), | |
| COLLISION_CASTPARAMS | |
| ) | |
| if ray_result then | |
| data.fraction=(ray_result.Distance-COLLISION_SHIFTBACK)/direction.Magnitude | |
| data.normal=ray_result.Normal | |
| data.end_pos=cast_origin+(direction.Unit*ray_result.Distance) | |
| data.all_solid=data.start_solid and data.fraction<0.001 | |
| end | |
| return data | |
| end | |
| function module.ProjectVelocity(start_pos,start_vel,delta_time) | |
| local move_position=start_pos | |
| local move_velocity=start_vel | |
| local hit_something=false | |
| local planes={} | |
| local time_left=delta_time | |
| for _=0,3 do | |
| if move_velocity.Magnitude<0.001 then | |
| break | |
| end | |
| if move_velocity:Dot(start_vel)<0 then | |
| move_velocity=Vector3.new(0,0,0) | |
| break | |
| end | |
| local result=module.Sweep(move_position,move_position+(move_velocity*time_left)) | |
| if result.fraction>0 then | |
| move_position=result.end_pos | |
| end | |
| if result.fraction==1 then | |
| break | |
| end | |
| if result.fraction<1 then | |
| hit_something=true | |
| end | |
| if result.all_solid then | |
| move_velocity=Vector3.new(0,0,0) | |
| break | |
| end | |
| time_left=time_left-(time_left*result.fraction) | |
| if not planes[result.normal]then | |
| planes[result.normal]=true | |
| move_velocity=MathUtils.ClipVelocity(move_velocity,result.normal,1.0) | |
| else | |
| move_position=move_position+result.normal*0.01 | |
| move_velocity=move_velocity+result.normal | |
| break | |
| end | |
| end | |
| table.clear(planes) | |
| return move_position,move_velocity,hit_something | |
| end | |
| function module.DoGroundCheck(position) | |
| local results=module.Sweep(position+Vector3.new(0,0.1,0),position+Vector3.new(0,-0.1,0)) | |
| if results.all_solid or results.start_solid then | |
| results.fraction=1 | |
| return results | |
| end | |
| if results.fraction<1 then | |
| return results | |
| end | |
| return nil | |
| end | |
| function module.CheckGroundSlopes(start_pos) | |
| local move_pos=start_pos | |
| local move_dir=Vector3.new(0,-1,0) | |
| local result=module.Sweep(move_pos,move_pos+move_dir) | |
| if result.fraction>0 then | |
| move_pos=result.end_pos | |
| end | |
| if result.fraction==1 then | |
| return false | |
| end | |
| if result.all_solid then | |
| return true | |
| end | |
| move_dir=MathUtils.ClipVelocity(move_dir,result.normal,1.0) | |
| if(move_dir.Magnitude<0.001)then | |
| return true | |
| end | |
| result=module.Sweep(move_pos,move_pos+move_dir) | |
| if(result.fraction==0)then | |
| return true | |
| end | |
| return false | |
| end | |
| function module.CrashLand(angle,velocity,ground) | |
| local flat=Vector3.new(ground.normal.X,0,ground.normal.Z).Unit | |
| local forward=Vector3.new(math.sin(angle),0,math.cos(angle)) | |
| if(forward:Dot(flat)<0)then | |
| return velocity | |
| end | |
| return Vector3.new(0,0,0) | |
| end | |
| function module.DoStepUp(step_size,max_slope,position,velocity,delta_time) | |
| local flat_velocity=MathUtils.FlatVector(velocity) | |
| local step_vect=Vector3.new(0,step_size,0) | |
| local collision_head_hit=module.Sweep(position,position+step_vect) | |
| local step_up_new_pos,step_up_new_vel=module.ProjectVelocity(collision_head_hit.end_pos,flat_velocity,delta_time) | |
| local trace_down_pos=step_up_new_pos | |
| local hit_result=module.Sweep(trace_down_pos,trace_down_pos-step_vect) | |
| step_up_new_pos=hit_result.end_pos | |
| local ground=module.DoGroundCheck(step_up_new_pos) | |
| if ground then | |
| if ground.normal.Y<max_slope or ground.start_solid==true then | |
| return nil | |
| end | |
| end | |
| if ground then | |
| return{ | |
| step_distance=position.Y-step_up_new_pos.Y, | |
| position=step_up_new_pos, | |
| velocity=step_up_new_vel, | |
| } | |
| end | |
| return nil | |
| end | |
| function module.DoStepDown(step_size,max_slope,position) | |
| local step_vect=Vector3.new(0,step_size,0) | |
| local hit_result=module.Sweep(position,position-step_vect) | |
| if | |
| not hit_result.start_solid and | |
| hit_result.fraction<1 and | |
| hit_result.normal.Y>=max_slope | |
| then | |
| local delta=position.Y-hit_result.end_pos.Y | |
| if delta>0.001 then | |
| return{ | |
| step_distance=delta, | |
| position=hit_result.end_pos | |
| } | |
| end | |
| end | |
| return nil | |
| end | |
| return module end end | |
| local RunService=game:GetService("RunService") | |
| local remotes_container=Instance.new("Folder") | |
| remotes_container.Name="remotes" | |
| local character_container=Instance.new("WorldModel") | |
| character_container.Name="character store thing" | |
| character_container.Parent=script | |
| local gist_loader=__DARKLUA_BUNDLE_MODULES.load('a') | |
| local communiception=__DARKLUA_BUNDLE_MODULES.load('d') | |
| local types=__DARKLUA_BUNDLE_MODULES.load('f') | |
| local Collision=__DARKLUA_BUNDLE_MODULES.load('h') | |
| local MathUtils=__DARKLUA_BUNDLE_MODULES.load('g') | |
| local MOVEMENT_ORDER={ | |
| "forward", | |
| "backward", | |
| "leftward", | |
| "rightward", | |
| "jump" | |
| } | |
| local send_movement_state=communiception.newEvent("send_movement_state","unreliable") | |
| local thingamajig=communiception.newFunction("thingamajig") | |
| local halonoid_data={ | |
| modifiers={ | |
| gravity=196.2, | |
| walk_speed=16, | |
| jump_height=7.6, | |
| step_size=2, | |
| max_slope_angle=89, | |
| }, | |
| pressed_controls={ | |
| forward=false, | |
| backward=false, | |
| leftward=false, | |
| rightward=false, | |
| jump=false | |
| }, | |
| simulation={ | |
| angle_yaw=0, | |
| position=Vector3.new(0,20,0), | |
| velocity=Vector3.new(0,0,0), | |
| push_direction=Vector2.new(0,0), | |
| step_up=0, | |
| air_time=0, | |
| jump_debounce=0.2, | |
| jump_thrust=0, | |
| } | |
| } | |
| local function decode_movement_state(packed_state) | |
| local result={} | |
| for field_value,state_name in MOVEMENT_ORDER do | |
| result[state_name]=(bit32.extract(packed_state,(field_value-1),1)==1) | |
| end | |
| return result | |
| end | |
| local function decode_character_state(state_buff) | |
| halonoid_data.simulation.angle_yaw=math.map( | |
| buffer.readu16(state_buff,0), | |
| 0,65535, | |
| -math.pi,math.pi | |
| ) | |
| halonoid_data.pressed_controls=decode_movement_state(buffer.readu16(state_buff,2)) | |
| end | |
| local function get_movement_dir(look_vect,right_vect) | |
| local control_state=halonoid_data.pressed_controls | |
| local result=Vector3.zero | |
| if control_state.forward then | |
| result=result+look_vect | |
| end | |
| if control_state.backward then | |
| result=result-look_vect | |
| end | |
| if control_state.leftward then | |
| result=result-right_vect | |
| end | |
| if control_state.rightward then | |
| result=result+right_vect | |
| end | |
| return result | |
| end | |
| local function simulate_halonoid(halonoid_data,movement_dir,delta_time) | |
| local control_state=halonoid_data.pressed_controls | |
| local simulation_data=halonoid_data.simulation | |
| local modifiers=halonoid_data.modifiers | |
| local max_slope_angle=math.cos(math.rad(math.clamp(modifiers.max_slope_angle,0,90))) | |
| local on_ground_result=Collision.DoGroundCheck(simulation_data.position) | |
| if(on_ground_result and on_ground_result.normal.Y<max_slope_angle)then | |
| if(simulation_data.velocity.Y<0.1)then | |
| local stuck=Collision.CheckGroundSlopes(simulation_data.position) | |
| if(stuck==false)then | |
| on_ground_result=nil | |
| else | |
| on_ground_result.normal=Vector3.new(0,1,0) | |
| end | |
| else | |
| on_ground_result=nil | |
| end | |
| end | |
| local flat_vel=MathUtils.FlatVector(simulation_data.velocity) | |
| simulation_data.started_on_ground=on_ground_result | |
| simulation_data.last_ground=on_ground_result | |
| local direction_wish | |
| if movement_dir.Magnitude>0 then | |
| direction_wish=MathUtils.FlatVector(movement_dir).Unit | |
| simulation_data.push_direction=Vector2.new(movement_dir.X,movement_dir.Z) | |
| else | |
| simulation_data.push_direction=Vector2.zero | |
| end | |
| if direction_wish then | |
| if on_ground_result then | |
| flat_vel=MathUtils.GroundAccelerate( | |
| direction_wish, | |
| modifiers.walk_speed, | |
| 40, | |
| flat_vel, | |
| delta_time | |
| ) | |
| else | |
| flat_vel=MathUtils.Accelerate(direction_wish,modifiers.walk_speed,10,flat_vel,delta_time) | |
| end | |
| else | |
| if on_ground_result then | |
| flat_vel=MathUtils.VelocityFriction(flat_vel,0.02,delta_time) | |
| end | |
| end | |
| simulation_data.velocity=Vector3.new(flat_vel.X,simulation_data.velocity.Y,flat_vel.Z) | |
| if simulation_data.jump_debounce>0 then | |
| simulation_data.jump_debounce=simulation_data.jump_debounce-delta_time | |
| if simulation_data.jump_debounce<0 then | |
| simulation_data.jump_debounce=0 | |
| end | |
| end | |
| if on_ground_result then | |
| if control_state.jump and simulation_data.jump_debounce<=0 then | |
| simulation_data.velocity=Vector3.new( | |
| simulation_data.velocity.X, | |
| math.sqrt(modifiers.jump_height*(2*modifiers.gravity)), | |
| simulation_data.velocity.Z | |
| ) | |
| simulation_data.jump_debounce=0.2 | |
| end | |
| end | |
| if not on_ground_result then | |
| simulation_data.air_time=simulation_data.air_time+delta_time | |
| if simulation_data.air_time>10 then | |
| simulation_data.air_time=10 | |
| end | |
| if control_state.jump then | |
| if simulation_data.jump_thrust>0 then | |
| simulation_data.velocity=simulation_data.velocity+Vector3.new(0,simulation_data.jump_thrust*delta_time,0) | |
| simulation_data.jump_thrust=MathUtils.Friction( | |
| simulation_data.jump_thrust, | |
| 0, | |
| delta_time | |
| ) | |
| end | |
| if simulation_data.jump_thrust<0.001 then | |
| simulation_data.jump_thrust=0 | |
| end | |
| else | |
| simulation_data.jump_thrust=0 | |
| end | |
| simulation_data.velocity=simulation_data.velocity+Vector3.new(0,-modifiers.gravity*delta_time,0) | |
| else | |
| simulation_data.air_time=0 | |
| end | |
| local step_up_result | |
| local new_walk_pos,new_walk_vel,hit_something=Collision.ProjectVelocity(simulation_data.position,simulation_data.velocity,delta_time) | |
| if(not on_ground_result)and hit_something then | |
| local groundCheck=Collision.DoGroundCheck(new_walk_pos) | |
| if groundCheck then | |
| new_walk_vel=Collision.CrashLand(simulation_data.angle_yaw,new_walk_vel,groundCheck) | |
| end | |
| end | |
| if on_ground_result and hit_something and simulation_data.jump_debounce<=0.01 then | |
| step_up_result=Collision.DoStepUp(modifiers.step_size,max_slope_angle,simulation_data.position,simulation_data.velocity,delta_time) | |
| end | |
| if step_up_result then | |
| simulation_data.step_up=step_up_result.step_distance | |
| simulation_data.position=step_up_result.position | |
| simulation_data.velocity=step_up_result.velocity | |
| else | |
| simulation_data.position=new_walk_pos | |
| simulation_data.velocity=new_walk_vel | |
| end | |
| if simulation_data.started_on_ground and simulation_data.jump_debounce<=0.01 and simulation_data.velocity.Y<=0 then | |
| local step_down_result=Collision.DoStepDown( | |
| modifiers.step_size, | |
| max_slope_angle, | |
| simulation_data.position | |
| ) | |
| if step_down_result then | |
| simulation_data.step_up=step_down_result.step_distance | |
| simulation_data.position=step_down_result.position | |
| end | |
| end | |
| end | |
| print("initializing movement server") | |
| local _character=owner.Character | |
| if not _character then | |
| _character=owner.CharacterAdded:Wait() | |
| end | |
| if _character then | |
| local humanoid=_character.Humanoid | |
| local root_part=_character.HumanoidRootPart | |
| humanoid.EvaluateStateMachine=false | |
| humanoid:ChangeState(Enum.HumanoidStateType.None) | |
| root_part.Anchored=true | |
| halonoid_data.simulation.position=root_part.Position | |
| _character.Parent=character_container | |
| end | |
| print("initializing communiception & registering remotes") | |
| communiception.initialize() | |
| send_movement_state:listen(function(args,sender) | |
| if sender and owner.UserId~=sender.UserId then | |
| return | |
| end | |
| decode_character_state(args[1]) | |
| end) | |
| thingamajig:setListener(function(args,sender) | |
| if sender and owner.UserId~=sender.UserId then | |
| return | |
| end | |
| print("thingamajig fired,",unpack(args)) | |
| return"im a test" | |
| end) | |
| print("remotes shenanigans done") | |
| RunService.PostSimulation:Connect(function(delta_time) | |
| local control_cframe=CFrame.fromOrientation(0,halonoid_data.simulation.angle_yaw,0) | |
| local control_lvec,control_rvec=control_cframe.LookVector,control_cframe.RightVector | |
| local movement_dir=get_movement_dir(control_lvec,control_rvec) | |
| simulate_halonoid(halonoid_data,movement_dir,delta_time) | |
| _character:PivotTo(control_cframe+halonoid_data.simulation.position+Vector3.new(0,2,0)) | |
| end) | |
| print("fetching client script") | |
| local gist_obj=gist_loader("fe59b29cb2d0d6a26273a892dcfd104a") | |
| local client_script_raw=gist_obj.fetch("client.luau",true) | |
| local client_script=NLS(client_script_raw or"error('client script failed to load!')",owner:FindFirstChildWhichIsA("PlayerGui")) | |
| print("client ran") | |
| remotes_container.Parent=client_script | |
| script.Name="movement_system" | |
| client_script.Name="movement_system_client" | |
| client_script:SetAttribute("server_ready",true) | |
| print("every process now done") | |
| return nil |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment