SUPER Command Console

--[[ 
    -- Script Snippet added by: togagames
    for: LuaSnippets.com and CoreGames.com
    
    Toggle a UI object's visibility by pressing the F1 key
    Instead of using an "if" statement we increment 
    _healthInvis by 1 each time and check if it's
    divisible by 2, switching between 1 and 0.
    
    This script should be in a "client" context
    and the target UI (to toggle visibility of) should be 
    added as a Custom Property of this script.
--]]

local _key = require( script:GetCustomProperty("ListKeys") )                -- key codes

-- >> Follow Menu - spawn objects    << --
local _spawnObject = require( script:GetCustomProperty("ListObjects") )        -- spawnable objects
local _spawnObjects = _spawnObject._count
local _selectedSpawnObject = "tree1"
--local propListSpawnData = script:GetCustomProperty("ListSpawnData"):WaitForObject() -- pre-built spawn data


-- >> Command Console - run commands    << --
local _cmd = require( script:GetCustomProperty("ListCommands") )    -- big list of console commands
local _cmds = _cmd._count

local _cHistory = {nil} -- save the Command history
local _chs = 1 -- +1 each time a !command is added
local _chLast = "" -- keep track of the last !command
local _lUsed = 0 -- currently using the !last command?


local _owner = "togagames" -- owner of this game (for admin purposes)
local _player = Game.GetLocalPlayer() -- save local player reference
local _isFlying = 0






local _cmdConsole     = script:GetCustomProperty("ConsoleCanvas"):WaitForObject()         -- console container
local _cmdBtnEnter     = script:GetCustomProperty("ConsoleButtonEnter"):WaitForObject()     -- console 'submit' button
local _cmdBtnClear  = script:GetCustomProperty("ConsoleButtonClear"):WaitForObject()    -- console 'clear' button
local _cmdBtnExit     = script:GetCustomProperty("ConsoleButtonExit"):WaitForObject()        -- console 'exit' button
local _cmdInput        = script:GetCustomProperty("ConsoleInputText"):WaitForObject()        -- console input text
local _cmdOutput    = script:GetCustomProperty("ConsoleOutputText"):WaitForObject()        -- console output text


local propMenuGroup = script:GetCustomProperty("MenuGroup"):WaitForObject() -- "follow" menu
local propTheSpawnSpot = script:GetCustomProperty("TheSpawnSpot"):WaitForObject() -- spot where things spawn from

local _openMenuCC = 0 -- any menus open?
local _openMenuFM = 0
local _cmdInvis = 0 -- 1 if the object starts off as being "visible"
local _fmInvis = 0
local _newStr = "!"
local _fontSize = 35 -- the space we need each time text is submitted (not actual font size)
local msg = ""
local _nLoc = 0
local _needle = ""
local _hayStack = ""
local _isMatch = false
local _perm = 0
local _spot = 0
local _cs = nil
local _spawnPos = nil -- where to spawn objects from

-- switch the Command Console's visibility between 1 & 0 (on/off)
local _cmdSwitch = {nil}
_cmdSwitch[0] = Visibility.FORCE_OFF
_cmdSwitch[1] = Visibility.INHERIT
_cmdConsole.visibility = _cmdSwitch[0] -- hide console on start

-- switch the "Follow" Menu's visibility between 1 & 0 (on/off)
local _fmSwitch = {nil}
_fmSwitch[0] = Visibility.FORCE_OFF
_fmSwitch[1] = Visibility.INHERIT
propMenuGroup.visibility = _fmSwitch[0] -- hide menu on start



--[[ ~ C O M M A N D  F U N C T I O N S ~ --]]


_com = {
    com_1 = function ()
        _writeOutput("Choice 1 selected.")
    end,
    com_2 = function ()
        _writeOutput("Choice 2 selected.")
    end,
    com_3 = function ()
        _writeOutput("Choice 3 selected.")
    end,
    com_4 = function ()
        _writeOutput("Choice 4 selected.")
    end,
    com_about = function ()
        _writeOutput("About: ".._cmd._about)
    end,
    com_addnote = function ()
        _writeOutput("[NTC] Note added.")
    end,    
    com_broadcast = function (message)
        _writeOutput("You publicly broadcasted: "..message)
        _broadcast(message)
        _toggleConsole()
    end,
    com_build = function (_ob)
        _writeOutput("Placed object.")
        _selectedSpawnObject = _ob -- update current obj
        _build(_ob)
        _toggleConsole()
    end,    
    com_clear = function ()
        _clearOutput()
    end,
    com_commands = function () -- print out the full list of commands
        local _lSize = 35 * _cmd._count
        _writeOutput( _cmd._getCommandList(), _lSize )
    end,
    com_deletenote = function ()
        _writeOutput("[NTC] Note deleted.")
    end,    
    com_dice = function (_ds)
        local _nmm = tonumber(_ds)
        if( (type(_nmm) == "number") )then
            print("DICE: ",_ds)
            if(_nmm >=3 and _nmm <=20)then -- rolling die (3-20)
                local num = math.random(1, _nmm);
                _writeOutput("You rolled the d".._ds.." die. It came up a "..num..".");
            else
                local d1 = math.random(1,6) -- use this for the 'default' gambling-style 2 dice set
                local d2 = math.random(1,6)
                _writeOutput("You rolled the dice. They came up a "..d1.." and a "..d2..".")
            end
        else
            local d1 = math.random(1,6) -- use this for the 'default' gambling-style 2 dice set
            local d2 = math.random(1,6)
            _writeOutput("You rolled the dice. They came up a "..d1.." and a "..d2..".")            
        end
    end,
    com_exit = function () -- close command console
        OnClickedExit()
    end,    
    com_fly = function ()
        if(_isFlying == 0)then
            _isFlying = 1
            _writeOutput("Fly mode activated.");
            _flyMode(1)
        else
            _isFlying = 0
            _writeOutput("Fly mode disabled.");
            _flyMode(0)
        end
        _toggleConsole()
    end,
    com_heal = function (target) -- still need to check if target player exists..
        if(target == "all")then
            _writeOutput("You healed everyone.")
        elseif (target ~= "")then
            _writeOutput("You healed "..target..".")
        else
            _writeOutput("You healed yourself.")
            target = _player.name
        end
        _healPlayer(target)
        _toggleConsole()
    end,
    com_healall = function ()
        _writeOutput("You healed everyone.")
        _healPlayer("all")
        _toggleConsole()
    end,    
    com_help = function ()
        _writeOutput("Help: ".._cmd._help)
    end,
    com_join = function ()
        _writeOutput("You are set to join the next available match.")
    end,
    com_kill = function (target) -- still need to check if target player exists..
        if(target == "all")then
            _writeOutput("You killed everyone.")
        elseif (target ~= "")then
            _writeOutput("You killed "..target..".")
        else
            _writeOutput("You killed yourself.")
            target = _player.name
        end
        _killPlayer(target)
        _toggleConsole()
    end,
    com_killall = function ()
        _writeOutput("You killed everyone.")
        _killPlayer("all")
        _toggleConsole()
    end,    
    com_last = function () -- run last-used !command and keep it in the input box to quickly re-use
        -- no need to call anything with this one
        _toggleConsole()
    end,        
    com_motd = function ()
        _writeOutput("MOTD: ".._cmd._motd)
    end,
    com_note = function ()
        _writeOutput("[NTC] Note id [27]: This is my note.")
    end,
    com_notes = function ()
        _writeOutput("[NTC] Notes list: ")
    end,
    com_object = function (_ob) -- set our current spawn object
        _selectedSpawnObject = _ob
        _toggleConsole()
    end,
    com_objects = function () -- print out the full list of spawnable objects
        local _lSize = 35 * _spawnObject._count
        _writeOutput( _spawnObject._getObjectList(), _lSize )
        _cmdInput.text = "!item "
    end,
    com_rank = function ()
        _writeOutput("Leaderboard: Rank 54.")
    end,
    com_say = function (mm)
        _writeOutput("You said, '"..mm..".'")
    end,
    com_setmotd = function (data)
        _cmd._motd = data
         _toggleConsole()
    end,
    com_shout = function (mm)
        _writeOutput("You shouted, '"..mm.."!'")
    end,
    com_start = function ()
        _writeOutput("You started the match.")
    end,    
    com_stats = function (target)
        if (target ~= "")then
            _writeOutput("Stats for '"..target..": 65 coins, level 3")
        else
            _writeOutput("Your stats: 65 coins, level 3")
        end
    end,
    com_stop = function ()
        _writeOutput("You stopped the match.")
    end
}



--[[ / E N D  C O M M A N D  F U N C T I O N S --]]

function _clearOutput() -- clear the output text
    _cmdInput.text = "!"
    _cmdOutput.height = _fontSize
    _cmdOutput.text   = "Welcome to the game!"
end

-- write to the output box
function _writeOutput(vv,fsize)
    fsize = fsize or _fontSize
    _cmdOutput.height = _cmdOutput.height + fsize -- make height bigger each time    
    _cmdOutput.text = _cmdOutput.text .."\n" .. vv -- append output        
    _toggleConsole() _toggleConsole() -- to lose "focus" (bug where SPACE submits..)    
end

function _toggleConsole()
    if(_openMenuFM == 0)then -- other menu isn't open
        if (_lUsed == 0)then
            _cmdInput.text = "!" -- reset the input
        end
        _cmdInvis = _cmdInvis + 1
        _openMenuCC = _cmdInvis%2 -- 0 or 1
        _cmdConsole.visibility = _cmdSwitch[_cmdInvis%2] -- 0 or 1
        UI.SetCursorVisible(_cmdInvis%2 == 1) -- true/false
        UI.SetCanCursorInteractWithUI(_cmdInvis%2 == 1) -- true/false
        _togglePlayer() -- disable player movements while command console is up
    end
end
    
function _toggleFollowMenu()
    if(_openMenuCC == 0)then -- other menu isn't open
        --_animatePlayer("point")
        _fmInvis = _fmInvis + 1
        _openMenuFM = _fmInvis%2 -- 0 or 1
        propMenuGroup.visibility = _fmSwitch[_fmInvis%2] -- 0 or 1
        propTheSpawnSpot.visibility = _fmSwitch[(_fmInvis+1)%2] -- do the opposite
        _togglePlayer() -- disable player movements while command console is up
    end
end




--[[         >>      COMMANDS TO SERVER           <<

************************************************************
--]]
function _animatePlayer(stance)
    Events.BroadcastToServer("AnimatePlayer", stance)
end
function _build(_ob)
    _spawnPos = propTheSpawnSpot:FindChildByName("props"):FindChildByName("ring"):GetWorldPosition() + Vector3.New(0,0,-50)
    print(_spawnPos)
    Events.BroadcastToServer("Build", _ob, _spawnPos)
end
function _flyMode(_set)
    Events.BroadcastToServer("FlyMode", _set)
end
function _togglePlayer()
    if(_openMenuFM == 1 or _openMenuCC == 1)then
        Events.BroadcastToServer("PlayerEnabled", 0)
    else 
        Events.BroadcastToServer("PlayerEnabled", 1)
    end
end
function _healPlayer(tgt)
    Events.BroadcastToServer("HealPlayer", tgt)
end
function _killPlayer(tgt)
    Events.BroadcastToServer("KillPlayer", tgt)
end
function _broadcast(mm)
    Events.BroadcastToServer("Broadcast", mm)
end


--[[
        < * * * I N T E R P R E T -- I N C O M I N G -- T E X T * * * >
        -- press the console 'submit' button
--]]

local __com     = nil
local __type     = nil
local __fn         = nil
local __use     = nil
local __desc     = nil
local __perm     = nil

function OnClickedSubmit()
    -- first step: read the text and translate to a function call
    -- !say hi
    
    if(_cmdInput.text == "!last")then
        _lUsed = 1
        msg = _chLast
    else
        msg = _cmdInput.text
        _lUsed = 0
    end    
    
    --[[---------------------------------------------
            PART ONE - Finding the needle.
    -------------------------------------------------]]
    _nLoc = string.find(msg, " ") or 0         -- location of the first space !healall9
    if(_nLoc > 0)then
        _needle = string.sub(msg, 0, _nLoc-1) -- [!command] 0 to 1st space (not including space)
    else 
        _needle = msg
        _hayStack = ""
        _isMatch = false
        _perm = 0
    end
    
    
    -- find the needle in the haystack
    local _arg = {}
    for b=1,_cmds do
        -- search for the needle within the commands
        --!clear| -- do string match to first instance of |    
        _nLoc = string.find(_cmd[b], "|") or 0         -- location of the first |        
        _hayStack = string.sub(_cmd[b], 0, _nLoc-1) -- [!command] 1 to 1st | (delimiter)        
        if (_needle == _hayStack)then
            _isMatch = true; -- We have a match! A !command is being used.
            _spot = b
            _cs = _cmd[_spot] -- the command data
            local _split = {}
            local a = 1
            for i in string.gmatch(_cs, "([^|]*)|") do -- | delimiter
                _split[a] = i -- get our 6 values: split[1-6]
                a = a + 1
            end
            --com, type, fn, use, desc, lvl 
            __com     = _split[1]
            __type     = _split[2]
            __fn     = _split[3]
            __use     = _split[4]
            __desc     = _split[5]
            __perm     = _split[6]
            
            -- run the command                            STILL NEED TO GET THE REMAINING TEXT!!
            --print(__com, __type, __fn, __use, __desc, __perm )    
            --_com[__fn]() -- don't pass the above parameters
            break
        end
    end
    
    -- no command found. return msg or nothing
    if(_isMatch == false)then
        _writeOutput(msg)
    end
    
    
    
    --[[---------------------------------------------
            PART TWO - Separate parts.
    -------------------------------------------------]]    
    if(_isMatch == true)then
        _nLoc = string.find(msg, " ") or 0              -- location of the first SPACE
        local _theRest = string.sub(msg, _nLoc+1, 999) -- the rest of the string
        if(_theRest == __com)then -- remaining text should NOT equal !command
            _theRest = ""
        end
        if(__fn ~= "!last")then
            _cHistory[_chs] = msg -- keep a recorded history (exclude: !last)
            _chLast = msg
            _chs = _chs + 1
        end
        _com[__fn](_theRest)
    end
    
    
end -- end of !command search




-- press the console 'clear' button
function OnClickedClear()
    _lUsed = 0
    _toggleConsole() _toggleConsole() -- to lose "focus" (bug where SPACE submits..)
end

-- press the console 'exit' button
function OnClickedExit()
    _toggleConsole()
end



--[[         >>       Item Selection Grid           <<

************************************************************
--]]


-- 11 horz * 5 vert Follow Menu options grid
local _ghp = 1 -- grid horz pos
local _ghpMax = 11
local _gvp = 1 -- grid vert pos
local _gvpMax = 5
local _ggMax = _ghpMax * _gvpMax
local _visMap = "["
local _inner = ""
local _lastGG = 1

-- hide all but the first grid "selector"
for bb=1,_ggMax do
    propMenuGroup:FindChildByName("Screen Grid"):GetChildren()[bb].visibility = Visibility.FORCE_OFF
end
propMenuGroup:FindChildByName("Screen Grid"):GetChildren()[1].visibility = Visibility.INHERIT

function _updateGG(gg)
    propMenuGroup:FindChildByName("Screen Grid"):GetChildren()[gg].visibility = Visibility.INHERIT
    propMenuGroup:FindChildByName("Screen Grid"):GetChildren()[_lastGG].visibility = Visibility.FORCE_OFF
    _selectedSpawnObject = _spawnObject._getReferenceNameByGrid(gg) -- set selected object
    _lastGG = gg
end

local vv = 1
local _gChild = nil -- get each selected child
local _matrix = {}    -- create the matrix that will house our 1-55 visual icon selection grid
for i=1,_gvpMax do
    _matrix[i] = {}    -- create a new row
    _inner = ""
    for j=1,_ghpMax do
        --_matrix[i][j] = tostring(i..":"..j)
        _matrix[i][j] = vv
        _visMap = _visMap..tostring(vv)
        _visMap = _visMap.."," 
        vv = vv + 1
    end
    _visMap = _visMap.."], ["
end

function _moveFMHorizontal(dir)
    _animatePlayer("point")
    _ghp = _ghp + dir
    if(_ghp > _ghpMax)then
        _ghp = 1
    elseif(_ghp < 1)then
        _ghp = _ghpMax
    end
    _updateGG(_matrix[_gvp][_ghp])
end
function _moveFMVertical(dir)
    _animatePlayer("point")
    _gvp = _gvp + dir
    if(_gvp > _gvpMax)then
        _gvp = 1
    elseif(_gvp < 1)then
        _gvp = _gvpMax
    end
    _updateGG(_matrix[_gvp][_ghp])
end





--[[         >>       KEY BINDINGS           <<

************************************************************
--]]



-- keys are being pressed!
function OnBindingPressed(player, binding)
    -- user is typing in the command console, so create the input text
    if(_openMenuCC == 1)then
        _cmdInput.text = (_cmdInput.text .. _key[binding])
    end
    
    -- user is using the Follow Menu to select a spawn object
    if(_openMenuFM == 1)then
        if(binding == "ability_extra_21")then -- W (up)
            _moveFMVertical(-1)
        end
        if(binding == "ability_extra_30")then -- A (left)
            _moveFMHorizontal(-1)
        end
        if(binding == "ability_extra_31")then -- S (down)
            _moveFMVertical(1)
        end
        if(binding == "ability_extra_32")then -- D (right)
            _moveFMHorizontal(1)    
        end        
    end
    
     -- F1 key to toggle Cmd Console (open/close)
    if(binding == "ability_extra_50")then
        _toggleConsole()
    end
    
     -- E key to toggle Follow Menu (open/close)
    if(binding == "ability_2")then
        _toggleFollowMenu()
    end    
    
     -- UP key as "submit/enter"
    if(binding == "ability_extra_46")then
        OnClickedSubmit()
    end
    
     -- RIGHT MOUSE spawns items for the Follow Menu
    if(binding == "ability_secondary" and _openMenuCC == 0 and _openMenuFM == 0)then
        _build(_selectedSpawnObject)
    end
    
     -- '1' key to test output
    if(binding == "ability_extra_1TESTONLYMAKEITSTOPLOL")then
        local _cs = _cmd[38] -- we're testing command 38 '!clear'
        local _split = {} -- using | as our delimiter
        local a = 1
        for i in string.gmatch(_cs, "([^|]*)|") do -- | delimiter
            _split[a] = i -- get our 6 values: split[1-6]
            a = a + 1
        end
        --print (_split[1]," : ",_split[2], " : ",_split[3]," : ",_split[4]," : ",_split[5]," : ",_split[6])
        --cmd, cx, fn, use, desc, lvl
        --call fn from string (at position 3)
        _com[_split[3]] ( _split[1], _split[2], _split[3], _split[4], _split[5], _split[6] )
    end    
end




--[[         >>       SETUP LISTENERS           <<

************************************************************
--]]

-- on player joined/left functions need to be defined before calling event:Connect()
Game.playerJoinedEvent:Connect(function(player)
    --_player = player
    player.bindingPressedEvent:Connect(OnBindingPressed)
end)
_cmdBtnEnter.clickedEvent:Connect(OnClickedSubmit)
_cmdBtnClear.clickedEvent:Connect(OnClickedClear)
_cmdBtnExit.clickedEvent:Connect(OnClickedExit)


Latest Posts

Emulation ProcessEmulation Process

  Record Locs for Emulation in Core Grab data. Here, I am recording x,yz, and name data to emulate. Next Convert to usable array for Core template data. Snippet>> Pattern  Core template replacement pattern: Path:[C:\Users\soandso\Documents\My Games\CORE\Saved\Maps\mycoregame\Data\Tree\Emulator_