User:JulienDethurens/Scripts/Heading code: Difference between revisions
From Legacy Roblox Wiki
Jump to navigationJump to search
User:JulienDethurens/Scripts/Heading code (view source)
Revision as of 20:37, 24 April 2012
, 24 April 2012Updated.
>JulienDethurens |
>JulienDethurens (Updated.) |
||
Line 17: | Line 17: | ||
*InsertService | *InsertService | ||
{{code | {{code|= | ||
local Players = Game:GetService('Players') | local Players = Game:GetService('Players') | ||
local StarterPack = Game:GetService('StarterPack') | local StarterPack = Game:GetService('StarterPack') | ||
Line 27: | Line 27: | ||
local InsertService = Game:GetService('InsertService') | local InsertService = Game:GetService('InsertService') | ||
local Terrain = Workspace.Terrain | local Terrain = Workspace.Terrain | ||
local verify_arg -- Since other functions defined before need to use it, this needs to be defined here. | |||
}} | }} | ||
Line 42: | Line 44: | ||
This function returns {{true}} if <var>value</var> is of type <var>data_type</var>. Otherwise, it returns {{false}}. | This function returns {{true}} if <var>value</var> is of type <var>data_type</var>. Otherwise, it returns {{false}}. | ||
It supports the following types: Lua types | It supports the following types: | ||
*all the Lua types (recognized by the Lua type function) | |||
*all the Instance types (recognized by the [[IsA]] method | |||
*all the Enum types | |||
*Enum (the enum object itself, accessed through the Enum variable | |||
*Color3 | |||
*BrickColor | |||
*Vector2 | |||
*Vector3 | |||
*CFrame/CoordinateFrame (both names are recognized by the function) | |||
*UDim | |||
*UDim2 | |||
*RBXScriptSignal (the real name of events) | |||
*Axes | |||
*Faces | |||
*Ray | |||
Just as a note, you can't use a "fake" value to make it return {{true}} with a value that is similar to a real value of the correct data type. If it says that the value is of the correct data type, then the value <strong>is</strong> of the correct data type. | Just as a note, you can't use a "fake" value to make it return {{true}} with a value that is similar to a real value of the correct data type. If it says that the value is of the correct data type, then the value <strong>is</strong> of the correct data type. | ||
{{code | {{code|= | ||
local function is_a(value, data_type) | local function is_a(value, data_type) | ||
-- Supported types: Lua types, Instance types, Enum types, Enum, Color3, BrickColor, Vector2, Vector3, CFrame/CoordinateFrame, UDim, UDim2, RBXScriptSignal, Axes, Faces, Ray | -- Supported types: Lua types, Instance types, Enum types, Enum, Color3, BrickColor, Vector2, Vector3, CFrame/CoordinateFrame, UDim, UDim2, RBXScriptSignal, Axes, Faces, Ray | ||
Line 55: | Line 72: | ||
-- Here is a nice collection of bad practices, ugly hacks, and other things you should never use, but that you don't have the choice of using, because of ROBLOX's lack of an official way to distinguish data types: | -- Here is a nice collection of bad practices, ugly hacks, and other things you should never use, but that you don't have the choice of using, because of ROBLOX's lack of an official way to distinguish data types: | ||
data_type = verify_arg(data_type, 'string', "data_type") | |||
if type(value) == data_type then return true end -- Lua types | if type(value) == data_type then return true end -- Lua types | ||
if pcall(function() assert(Game.IsA(value, data_type)) end) then return true end -- Instance types | if pcall(function() assert(Game.IsA(value, data_type)) end) then return true end -- Instance types | ||
Line 85: | Line 103: | ||
if _ and connection then | if _ and connection then | ||
connection:disconnect() | connection:disconnect() | ||
return true | |||
end | |||
end | |||
return false | |||
end | |||
}} | |||
== cpp_is_a(<var>value</var>, <var>data_type</var>) == | |||
{| class="wikitable" | |||
|+ Parameters | |||
! Name !! Type !! Description | |||
|- | |||
| value || || The value you want to check the type of. | |||
|- | |||
| data_type || string || The type you want to check if the value is of. | |||
|} | |||
This function is like the is_a function, but is used with the C++ types used by ROBLOX methods and properties. It should be used to know if a certain value would be accepted by a method or a property. | |||
It supports the following types: | |||
*int | |||
*double | |||
*bool | |||
*string | |||
*float | |||
{{code|= | |||
local function cpp_is_a(value, data_type) | |||
-- Same as is_a, but for methods and properties. Only supports basic types. | |||
-- Supports: int, double, bool, string, float | |||
-- Note: this function should be used to know if it is safe to send an argument to a method or a property, as it will also return true for values that will be automatically coerced by ROBLOX. | |||
data_type = verify_arg(data_type, 'string', "data_type") | |||
if data_type == 'int' then | |||
if pcall(function() Instance.new('IntValue').Value = value end) then | |||
return true | |||
end | |||
elseif data_type == 'double' then | |||
if pcall(function() Instance.new('NumberValue').Value = value end) then | |||
return true | |||
end | |||
elseif data_type == 'bool' then | |||
if pcall(function() Instance.new('BoolValue').Value = value end) then | |||
return true | |||
end | |||
elseif data_type == 'string' then | |||
if pcall(function() Instance.new('StringValue').Value = value end) then | |||
return true | |||
end | |||
elseif data_type == 'float' then | |||
if pcall(function() Instance.new('ClickDetector').MaxActivationDistance = value end) then | |||
return true | return true | ||
end | end | ||
Line 96: | Line 166: | ||
{| class="wikitable" | {| class="wikitable" | ||
|+ Parameters | |+ Parameters | ||
! Name !! Type !! Description | ! Name !! Type !! Description | ||
|- | |- | ||
|value || || The value you want to get the type of. | | value || || The value you want to get the type of. | ||
|} | |} | ||
This function returns the most specific type it can get for a certain value. It supports all the types supported by the '''is_a''' function. | This function returns the most specific type it can get for a certain value. It supports all the types supported by the '''is_a''' function. | ||
{{code | {{code|= | ||
local function get_type(value) | local function get_type(value) | ||
-- Returns the most specific type it can return. Supports the same types as the is_a function, except the enum types. | -- Returns the most specific type it can return. Supports the same types as the is_a function, except the enum types. | ||
Line 124: | Line 194: | ||
}} | }} | ||
== verify_arg(<var>value</var>, <var>data_type</var>, <var> | == verify_arg(<var>value</var>, <var>data_type</var>, <var>arg_name</var>, <var>optional</var>) == | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 134: | Line 204: | ||
| data_type || string || The data type the value should be of. | | data_type || string || The data type the value should be of. | ||
|- | |- | ||
| | | arg_name || string || The name of the argument. | ||
|- | |- | ||
| optional || boolean || Whether the argument can be nil or not. | |||
| optional || boolean || Whether the argument | |||
|} | |} | ||
This function will check if <var>value</var> is of type <var>data_type</var>. If not, it will print an error message | This function will check if <var>value</var> is of type <var>data_type</var>. If not, it will print an error message relating to the type. | ||
Use it in functions that receive arguments to check if arguments are of the correct type. Using this function can make debugging <strong>a lot</strong> easier (trust me, that's from experience). | Use it in functions that receive arguments to check if arguments are of the correct type. Using this function can make debugging <strong>a lot</strong> easier (trust me, that's from experience). | ||
{{code | {{code|= | ||
function verify_arg(value, data_type, arg_name, optional) | |||
-- Makes the function that called the calling function error, with an error message relating to a wrong type. Supports the | -- Makes the function that called the calling function error, with an error message relating to a wrong type. Supports all the types supported by the is_a and the cpp_is_a functions. | ||
-- Also supports coercion for the number and string types. | -- Also supports coercion for the number and string types. | ||
-- Returns the value, as it might be automatically converted if a coercion has been done. | -- Returns the value, as it might be automatically converted if a coercion has been done. | ||
if type(data_type) ~= 'string' then error("bad | if type(data_type) ~= 'string' then error("bad 'data_type' argument (string expected, got " .. get_type(data_type) .. ")", 2) end | ||
if | if type(arg_name) ~= 'string' then error("bad 'arg_name' argument (string expected, got " .. get_type(arg_name) .. ")") end | ||
if optional and value == nil then | if optional and value == nil then | ||
return value | return value | ||
elseif is_a(value, data_type) then | elseif type(value) == data_type then | ||
return value | |||
elseif is_a(value, data_type) or cpp_is_a(value, data_type) then | |||
return value | return value | ||
elseif data_type == 'number' and tonumber(value) then | elseif data_type == 'number' and tonumber(value) then | ||
Line 169: | Line 232: | ||
return tostring(value) | return tostring(value) | ||
else | else | ||
error("bad | error("bad '" .. arg_name .. "'" .. (optional and " optional" or "") .. " argument (" .. data_type .. " expected, got " .. get_type(value) .. ")", 3) | ||
end | end | ||
end | end | ||
Line 187: | Line 250: | ||
This function allows you to edit the properties and the hierarchy of a certain object. Because I am too lazy to explain exactly how it works, and because you already have the code anyways, I will only give you an example: | This function allows you to edit the properties and the hierarchy of a certain object. Because I am too lazy to explain exactly how it works, and because you already have the code anyways, I will only give you an example: | ||
{{code | {{code|= | ||
local part = modify(Instance.new('Part'), { | local part = modify(Instance.new('Part'), { | ||
Name = "Wall"; | Name = "Wall"; | ||
Position = Vector3.new(10, 50, 10); | Position = Vector3.new(10, 50, 10); | ||
with (Instance.new('Fire') | with (Instance.new('Fire'), { | ||
Heat = 10; | Heat = 10; | ||
Size = 50; | Size = 50; | ||
}; | }); | ||
}) | }) | ||
}} | }} | ||
Line 200: | Line 263: | ||
That code creates a part, sets its name to "Wall", sets its position to a certain Vector3, creates a Fire object in it, sets some of the properties of that Fire object, and stores the part in the <var>part</var> variable. | That code creates a part, sets its name to "Wall", sets its position to a certain Vector3, creates a Fire object in it, sets some of the properties of that Fire object, and stores the part in the <var>part</var> variable. | ||
{{code | {{code|= | ||
local function modify(instance, t) | local function modify(instance, t) | ||
verify_arg(instance, 'Instance' | instance = verify_arg(instance, 'Instance', "instance") | ||
verify_arg(t, 'table' | t = verify_arg(t, 'table', "t") | ||
for key, value in next, t do | for key, value in next, t do | ||
if type(key) == 'number' then | if type(key) == 'number' then | ||
Line 215: | Line 278: | ||
}} | }} | ||
== call_on_descendants(<var> | == call_on_descendants(<var>instance</var>, <var>func</var>) == | ||
{| class="wikitable" | {| class="wikitable" | ||
|+ Parameters | |+ Parameters | ||
! Name | ! Name !! Type !! Description | ||
|- | |- | ||
| | | instance || Instance || The object you want to call a function on all the descendants of. | ||
|- | |- | ||
| func | | func || function || The function you want to call on all the descendants of the object. | ||
|} | |} | ||
This function calls <var>func</var> on all the descendants of <var> | This function calls <var>func</var> on all the descendants of <var>instance</var>, including <var>instance</var> itself. | ||
{{code | {{code|= | ||
local function call_on_descendants( | local function call_on_descendants(instance, func) | ||
-- Calls 'func' on ' | -- Calls 'func' on 'instance' and all its descendants, with the instance or descendant as argument. | ||
verify_arg( | instance = verify_arg(instance, 'Instance', "instance") | ||
verify_arg(func, 'function' | func = verify_arg(func, 'function', "func") | ||
func( | func(instance) | ||
for _, child in next, | for _, child in next, instance:GetChildren() do | ||
call_on_descendants(child, func) | call_on_descendants(child, func) | ||
end | end | ||
Line 240: | Line 303: | ||
}} | }} | ||
== get_nearest_ancestor(<var> | == get_nearest_ancestor(<var>instance</var>, <var>class_name</var>) == | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 246: | Line 309: | ||
! Name !! Type !! Description | ! Name !! Type !! Description | ||
|- | |- | ||
| | | instance || Instance || The object of which you want to find an ancestor. | ||
|- | |- | ||
| class_name || string || The class name of the ancestor you want to find. | | class_name || string || The class name of the ancestor you want to find. | ||
|} | |} | ||
This function returns the nearest ancestor of <var> | This function returns the nearest ancestor of <var>instance</var> of type <var>class_name</var> in ascending order. | ||
{{code | {{code|= | ||
local function get_nearest_ancestor( | local function get_nearest_ancestor(instance, class_name) | ||
-- Returns the nearest ancestor of a certain | -- Returns the nearest ancestor of a certain instance which is of a certain type. | ||
local ancestor = | instance = verify_arg(instance, 'Instance', "instance") | ||
class_name = verify_arg(class_name, 'string', "class_name") | |||
local ancestor = instance | |||
repeat | repeat | ||
ancestor = ancestor.Parent | ancestor = ancestor.Parent | ||
Line 267: | Line 332: | ||
}} | }} | ||
== | == get_character(<var>descendant</var>) == | ||
This is | {| class="wikitable" | ||
|+ Parameters | |||
! Name !! Type !! Description | |||
|- | |||
| descendant || Instance || The descendant of the character you want to get. | |||
|} | |||
This function returns the character a descendant is a part of. | |||
{{code|= | |||
local function get_character(descendant) | |||
-- Returns a character from one of its descendants. | |||
descendant = verify_arg(descendant, 'Instance', "descendant") | |||
local character = descendant | |||
repeat | |||
if character.Parent then | |||
character = character.Parent | |||
else | |||
return nil | |||
end | |||
until Players:GetPlayerFromCharacter(character) | |||
return character | |||
end | |||
}} | |||
== show_message(<var>text</var>, <var>lifetime</var>) == | |||
{{code| | {| class="wikitable" | ||
|+ Parameters | |||
! Name !! Type !! Description | |||
|- | |||
| text || string || The text you want to show in the message. | |||
|- | |||
| lifetime || number || The time, in seconds, during which the message must be displayed. | |||
|} | |||
This function shows a message and removes it after a certain time. | |||
{{code|= | |||
local function show_message(text, lifetime) | |||
-- Shows a message for a certain time, which is set to be 3 seconds by default. | |||
text = verify_arg(text, 'string', "text") | |||
lifetime = verify_arg(lifetime, 'number', "lifetime") | |||
local message = Instance.new('Message') | |||
message.Text = text | |||
Debris:AddItem(message, lifetime or 3) | |||
end | |||
}} | |||
== show_hint(<var>text</var>, <var>lifetime</var>) == | |||
{| class="wikitable" | |||
|+ Parameters | |||
! Name !! Type !! Description | |||
|- | |||
| text || string || The text you want to show in the hint. | |||
|- | |||
| lifetime || number || The time, in seconds, during which the hint must be displayed. | |||
|} | |||
This function shows a hint and removes it after a certain time. | |||
{{code|= | |||
local function show_hint(text, lifetime) | |||
-- Shows a hint for a certain time, which is set to be 3 seconds by default. | |||
text = verify_arg(text, 'string', "text") | |||
lifetime = verify_arg(lifetime, 'number', "lifetime") | |||
local hint = Instance.new('Hint') | |||
hint.Text = text | |||
Debris:AddItem(hint, lifetime or 3) | |||
end | |||
}} | |||
== Entire code == | |||
Here is the whole code: | |||
{{code|= | |||
local Players = Game:GetService('Players') | local Players = Game:GetService('Players') | ||
local StarterPack = Game:GetService('StarterPack') | local StarterPack = Game:GetService('StarterPack') | ||
Line 281: | Line 421: | ||
local InsertService = Game:GetService('InsertService') | local InsertService = Game:GetService('InsertService') | ||
local Terrain = Workspace.Terrain | local Terrain = Workspace.Terrain | ||
local verify_arg -- Since other functions defined before need to use it, this needs to be defined here. | |||
local function is_a(value, data_type) | local function is_a(value, data_type) | ||
Line 290: | Line 432: | ||
-- Here is a nice collection of bad practices, ugly hacks, and other things you should never use, but that you don't have the choice of using, because of ROBLOX's lack of an official way to distinguish data types: | -- Here is a nice collection of bad practices, ugly hacks, and other things you should never use, but that you don't have the choice of using, because of ROBLOX's lack of an official way to distinguish data types: | ||
data_type = verify_arg(data_type, 'string', "data_type") | |||
if type(value) == data_type then return true end -- Lua types | if type(value) == data_type then return true end -- Lua types | ||
if pcall(function() assert(Game.IsA(value, data_type)) end) then return true end -- Instance types | if pcall(function() assert(Game.IsA(value, data_type)) end) then return true end -- Instance types | ||
Line 320: | Line 463: | ||
if _ and connection then | if _ and connection then | ||
connection:disconnect() | connection:disconnect() | ||
return true | |||
end | |||
end | |||
return false | |||
end | |||
local function cpp_is_a(value, data_type) | |||
-- Same as is_a, but for methods and properties. Only supports basic types. | |||
-- Supports: int, double, bool, string, float | |||
-- Note: this function should be used to know if it is safe to send an argument to a method or a property, as it will also return true for values that will be automatically coerced by ROBLOX. | |||
data_type = verify_arg(data_type, 'string', "data_type") | |||
if data_type == 'int' then | |||
if pcall(function() Instance.new('IntValue').Value = value end) then | |||
return true | |||
end | |||
elseif data_type == 'double' then | |||
if pcall(function() Instance.new('NumberValue').Value = value end) then | |||
return true | |||
end | |||
elseif data_type == 'bool' then | |||
if pcall(function() Instance.new('BoolValue').Value = value end) then | |||
return true | |||
end | |||
elseif data_type == 'string' then | |||
if pcall(function() Instance.new('StringValue').Value = value end) then | |||
return true | |||
end | |||
elseif data_type == 'float' then | |||
if pcall(function() Instance.new('ClickDetector').MaxActivationDistance = value end) then | |||
return true | return true | ||
end | end | ||
Line 345: | Line 517: | ||
end | end | ||
function verify_arg(value, data_type, arg_name, optional) | |||
-- Makes the function that called the calling function error, with an error message relating to a wrong type. Supports the | -- Makes the function that called the calling function error, with an error message relating to a wrong type. Supports all the types supported by the is_a and the cpp_is_a functions. | ||
-- Also supports coercion for the number and string types. | -- Also supports coercion for the number and string types. | ||
-- Returns the value, as it might be automatically converted if a coercion has been done. | -- Returns the value, as it might be automatically converted if a coercion has been done. | ||
if type(data_type) ~= 'string' then error("bad | if type(data_type) ~= 'string' then error("bad 'data_type' argument (string expected, got " .. get_type(data_type) .. ")", 2) end | ||
if | if type(arg_name) ~= 'string' then error("bad 'arg_name' argument (string expected, got " .. get_type(arg_name) .. ")") end | ||
if optional and value == nil then | if optional and value == nil then | ||
return value | return value | ||
elseif is_a(value, data_type) then | elseif type(value) == data_type then | ||
return value | |||
elseif is_a(value, data_type) or cpp_is_a(value, data_type) then | |||
return value | return value | ||
elseif data_type == 'number' and tonumber(value) then | elseif data_type == 'number' and tonumber(value) then | ||
Line 366: | Line 535: | ||
return tostring(value) | return tostring(value) | ||
else | else | ||
error("bad | error("bad '" .. arg_name .. "'" .. (optional and " optional" or "") .. " argument (" .. data_type .. " expected, got " .. get_type(value) .. ")", 3) | ||
end | end | ||
end | end | ||
local function modify(instance, t) | local function modify(instance, t) | ||
verify_arg(instance, 'Instance' | instance = verify_arg(instance, 'Instance', "instance") | ||
verify_arg(t, 'table' | t = verify_arg(t, 'table', "t") | ||
for key, value in next, t do | for key, value in next, t do | ||
if type(key) == 'number' then | if type(key) == 'number' then | ||
Line 383: | Line 552: | ||
end | end | ||
local function call_on_descendants( | local function call_on_descendants(instance, func) | ||
-- Calls 'func' on ' | -- Calls 'func' on 'instance' and all its descendants, with the instance or descendant as argument. | ||
verify_arg( | instance = verify_arg(instance, 'Instance', "instance") | ||
verify_arg(func, 'function' | func = verify_arg(func, 'function', "func") | ||
func( | func(instance) | ||
for _, child in next, | for _, child in next, instance:GetChildren() do | ||
call_on_descendants(child, func) | call_on_descendants(child, func) | ||
end | end | ||
end | end | ||
local function get_nearest_ancestor( | local function get_nearest_ancestor(instance, class_name) | ||
-- Returns the nearest ancestor of a certain | -- Returns the nearest ancestor of a certain instance which is of a certain type. | ||
local ancestor = | instance = verify_arg(instance, 'Instance', "instance") | ||
class_name = verify_arg(class_name, 'string', "class_name") | |||
local ancestor = instance | |||
repeat | repeat | ||
ancestor = ancestor.Parent | ancestor = ancestor.Parent | ||
Line 403: | Line 574: | ||
until ancestor:IsA(class_name) | until ancestor:IsA(class_name) | ||
return ancestor | return ancestor | ||
end | |||
local function get_character(descendant) | |||
-- Returns a character from one of its descendants. | |||
descendant = verify_arg(descendant, 'Instance', "descendant") | |||
local character = descendant | |||
repeat | |||
if character.Parent then | |||
character = character.Parent | |||
else | |||
return nil | |||
end | |||
until Players:GetPlayerFromCharacter(character) | |||
return character | |||
end | |||
local function show_message(text, lifetime) | |||
-- Shows a message for a certain time, which is set to be 3 seconds by default. | |||
text = verify_arg(text, 'string', "text") | |||
lifetime = verify_arg(lifetime, 'number', "lifetime") | |||
local message = Instance.new('Message') | |||
message.Text = text | |||
Debris:AddItem(message, lifetime or 3) | |||
end | |||
local function show_hint(text, lifetime) | |||
-- Shows a hint for a certain time, which is set to be 3 seconds by default. | |||
text = verify_arg(text, 'string', "text") | |||
lifetime = verify_arg(lifetime, 'number', "lifetime") | |||
local hint = Instance.new('Hint') | |||
hint.Text = text | |||
Debris:AddItem(hint, lifetime or 3) | |||
end | end | ||
}} | }} |