Scripting: Conventions – Arma Reforger

From Bohemia Interactive Community
Jump to navigation Jump to search
(Emphasized the importance of tags. Added note about modded classes requiring tags.)
m (Some wiki formatting)
 
(13 intermediate revisions by the same user not shown)
Line 14: Line 14:
{{Name|bi}} scripts have been prefixed with {{hl|SCR_}}. A mod developer must choose their own tag and not use one already taken by {{Name|bi}} or another developer.  
{{Name|bi}} scripts have been prefixed with {{hl|SCR_}}. A mod developer must choose their own tag and not use one already taken by {{Name|bi}} or another developer.  


When [[Arma_Reforger:Scripting_Modding|modding]] any class, all methods and variables within that modded class must also be distinguished by the same unique tag to prevent conflict.
When {{Link|Arma Reforger:Scripting Modding|modding}} any class, all methods and variables within that modded class must also be distinguished by the same unique tag to prevent conflict.
 


== File/Class ==
== File/Class ==
Line 26: Line 27:
** {{hl|class TAG_ExampleEntity}}
** {{hl|class TAG_ExampleEntity}}
* Enum:
* Enum:
** name must be prefixed with a capital E, e.g {{hl|EMyEnum}}
** name must be prefixed with a capital E, e.g {{hl|TAG_EMyEnum}}
** values use all capital letters with words separated by underscores, e.g {{hl|EMyEnum.VALUE_1}}
** values use all capital letters with words separated by underscores, e.g {{hl|TAG_EMyEnum.VALUE_1}}
* The file should be located in the {{hl|scripts\Game}} directory
* The file should be located in the {{hl|scripts\Game}} directory
* The use of plural is prohibited at the end of combined keywords: e.g {{hl|SCR_Notification'''s'''Component}} {{hl|SCR_NotificationComponent}}
* The use of plural is prohibited at the end of combined keywords: e.g {{hl|TAG_Notification'''s'''Component}} → {{hl|TAG_NotificationComponent}}




== Method ==
== Method ==


* '''Functions'''/'''Methods''' naming uses '''PascalCase''', e.g:<syntaxhighlight lang="C#">int ReturnNumber()</syntaxhighlight>
* '''Functions'''/'''Methods''' naming uses '''PascalCase''', e.g:<enforce>int ReturnNumber()</enforce>
* Parameters are named with '''camelCase''', e.g:<syntaxhighlight lang="C#">int ReturnNumber(bool canBeNegative)</syntaxhighlight>
* Parameters are named with '''camelCase''', e.g:<enforce>int ReturnNumber(bool canBeNegative)</enforce>




== Variable ==
== Variable ==


{{Feature|informative|See {{HashLink|Arma Reforger:Scripting: Values#Identifier|this page}} for more information.}}
{{Feature|informative|See {{Link|Arma Reforger:Scripting: Values#Identifier|this page}} for more information.}}
* '''Member''' variables are prefixed with {{hl|m_}}, eventually one-letter type prefix, and use '''PascalCase''', e.g:<syntaxhighlight lang="C#">
* '''Member''' variables are prefixed with {{hl|m_}}, a one-letter type prefix for specific types (see {{Link|Arma Reforger:Scripting: Values#Types|Value types}}), and use '''PascalCase''', e.g:<enforce>
Entity m_Entity;
Entity m_Entity;
int m_iHealth;
int m_iHealth;
bool m_bIsEnemy;
bool m_bIsEnemy;
</syntaxhighlight>
</enforce>
* '''Global''' variables are prefixed with {{hl|g_}}. {{Feature|important|Global variables are bad practice and must not be used beside the bare minimum!}}
* '''Global''' variables are prefixed with {{hl|g_}}. {{Feature|important|Global variables are bad practice and must not be used outside of absolute necessity!}}
* '''Static''' variables are prefixed with {{hl|s_}} ('''constants''' are not), eventually a one-letter type prefix, and use '''PascalCase''', e.g<syntaxhighlight lang="C#">
* '''Static''' variables are prefixed with {{hl|s_}} ('''constants''' are not), eventually a one-letter type prefix, and use '''PascalCase''', e.g<enforce>
protected static int s_iUnitsCount;
protected static int s_iUnitsCount;
</syntaxhighlight>
</enforce>
* '''Local''' variables and '''arguments''' (method parameters) use '''camelCase''', e.g:<syntaxhighlight lang="C#">
* '''Local''' variables and '''arguments''' (method parameters) use '''camelCase''', e.g:<enforce>
void MethodA()
void MethodA()
{
{
Line 57: Line 58:


float result = MethodB(value, name);
float result = MethodB(value, name);
};
}
</syntaxhighlight>
</enforce>
* '''Constant''' values use '''all capital letters''' with words separated by '''underscores''' (uppercase snake casing), e.g:<syntaxhighlight lang="C#">
* '''Constant''' values use '''all capital letters''' with words separated by '''underscores''' (uppercase snake casing), e.g:<enforce>
const int MAX_VALUE = 9999; // no 'i' type prefix
const int MAX_VALUE = 9999; // no 'm_' prefix nor 'i' type prefix
static const int TOTAL = 10; // a constant does not need
static const int TOTAL = 10; // no 's_' prefix either
</syntaxhighlight>
</enforce>
 
=== Order ===
 
* First go '''Attributes''' (if any),
* then public, protected, private '''member variables'''
* then public, protected, private '''static variables'''
* then public, protected, private '''constants'''
 
<enforce>
[Attribute()]
protected int m_iAttribute;
 
int m_iPublic;
protected int m_iProtected;
private int m_iPrivate;
 
static int s_iPublic;
protected static int s_iProtected;
private static int s_iPrivate;
 
static const int PUBLIC;
protected static const int PROTECTED;
private static const int PRIVATE;
</enforce>
 


== Script ==
== Script ==
Line 68: Line 94:
=== General ===
=== General ===


* Curly braces must always be on a new line - Enforce Script uses '''{{Wikipedia|Indentation_style#Allman_style|Allman style}}'''
* Curly braces must always be on a new line - Enforce Script uses '''{{Link|https://en.wikipedia.org/wiki/Indentation_style#Allman_style|Allman style}}'''
* Variables and functions should be '''{{hl|protected}}''' whenever possible (respecting OOP black box principle) unless they are '''intended''' to be exposed
* Variables and functions should be '''{{hl|protected}}''' whenever possible (respecting OOP black box principle) unless they are '''intended''' to be exposed
* '''Getters'''/'''Setters''': variables should be made {{hl|protected}} and accessed through getters and setters (entry methods getting/setting the value)
* '''Getters'''/'''Setters''': variables should be made {{hl|protected}} and accessed through getters and setters (entry methods getting/setting the value)
<syntaxhighlight lang="C#">
<enforce>
class SCR_HumanComponent : ScriptComponent
class SCR_HumanComponent : ScriptComponent
{
{
private int m_iAge;
protected int m_iAge;


void SetAge(int age)
void SetAge(int age)
Line 87: Line 113:
}
}
}
}
</syntaxhighlight>
</enforce>


=== Spacing ===
=== Spacing ===
Line 100: Line 126:
** a {{hl|for}} semicolon
** a {{hl|for}} semicolon
* Spaces are used inside parentheses but not around their content
* Spaces are used inside parentheses but not around their content
<syntaxhighlight lang="C#">
<enforce>
class SCR_HumanComponent : ScriptComponent
class SCR_HumanComponent : ScriptComponent
{
{
Line 125: Line 151:
}
}
}
}
</syntaxhighlight>
</enforce>


=== Method ===
=== Method ===


* All methods must be separated using this sequence of characters: two slashes followed by 96 dashes (see {{HashLink|#Example}})<syntaxhighlight lang="C#">
* All methods must be separated using this sequence of characters: two slashes followed by 96 dashes (see {{Link|#Example}})<enforce>
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
</syntaxhighlight>
</enforce>
* '''Documentation''' must be done with [[Doxygen]] support in mind, using the {{ic|//!}} syntax (see {{HashLink|#Example}})
* '''Documentation''' must be done with {{Link|Doxygen}} support in mind, using the {{hl|//!}} comment syntax (see {{Link|#Example}})
* Methods should be '''sorted''' in the following order (top to bottom):
* Methods should be '''sorted''' in the following order (top to bottom):
** General methods
** General methods
Line 139: Line 165:
** Constructor
** Constructor
** Destructor
** Destructor
<syntaxhighlight lang="C#">
<enforce>
//! A scripted entity
//! A scripted entity
class SCR_ScriptedEntity : GenericEntity
class SCR_ScriptedEntity : GenericEntity
{
{
Line 148: Line 174:
//! \param vectorB Second position, direction goal
//! \param vectorB Second position, direction goal
//! \return The direction from A to B as a normalized vector
//! \return The direction from A to B as a normalized vector
private vector GetNormalizedDirection(vector vectorA, vector vectorB)
protected vector GetNormalizedDirection(vector vectorA, vector vectorB)
{
{
vector dir = vectorB - vectorA;
vector dir = vectorB - vectorA;
Line 170: Line 196:


//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
//! Constructor
// constructor
void SCR_ScriptedEntity(IEntitySource src, IEntity parent)
void SCR_ScriptedEntity(IEntitySource src, IEntity parent)
{
{
SetEventMask(EntityEvent.INIT | EntityEvent.FRAME | EntityEvent.CONTACT);
SetEventMask(EntityEvent.INIT | EntityEvent.FRAME | EntityEvent.CONTACT);
SetFlags(EntityFlags.ACTIVE, true);
}
}


//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
//! Destructor
// destructor
void ~SCR_ScriptedEntity()
void ~SCR_ScriptedEntity()
{
{
Line 184: Line 209:
}
}
}
}
</syntaxhighlight>
</enforce>


=== Miscellaneous ===
=== Miscellaneous ===


* class instanciation with the {{hl|new}} keyword '''must''' use parentheses:<syntaxhighlight lang="C#">
* class instanciation with the {{hl|new}} keyword '''must''' use parentheses:<enforce>
SCR_Class myClass = new SCR_Class(); // correct
SCR_Class myClass = new SCR_Class(); // correct
SCR_Class myClass = new SCR_Class; // wrong
SCR_Class myClass = new SCR_Class; // wrong
</syntaxhighlight>
</enforce>
* same with arrays:<syntaxhighlight lang="C#">
* arrays can be initialised directly:<enforce>
array<string> myArray = new array<string>(); // correct
array<string> myArray = {}; // correct
array<string> myArray = new array<string>;
array<string> myArray = new array<string>(); // tolerable
</syntaxhighlight>
array<string> myArray = new array<string>; // wrong
</enforce>




== Modability ==
== Moddability ==


{{Feature|important|
It is important to keep moddability in mind when scripting to ensure.
Pay special attention here if the script you are writing should be friendly to modding.
Modded classes work very similar to inherited ones and come with the same restrictions:
Modded classes work very similar to inherited ones, and so the following things are not moddable:
* '''Constructor/Destructor''': a modded class has its own const/destructor and cannot modify the parent one
* '''Constructor/Destructor''': Modded class has its own const/destructor and cant modify parent one → you can have the constructor call another method like {{hl|InitClass()}}
* '''Private variables & methods''': a modded class cannot override parent's private members - use <enforce inline>protected</enforce> instead of <enforce inline>private</enforce>
* '''Private variables & methods''': Modded class like inherited one cannot override private members of the parent → use protected keyword instead of private
* '''Static variables & methods''': same as above - do not use unless absolutely necessary
* '''Static variables & methods''': Same as above do not use unless absolutely necessary
* '''Global methods''': no classes to mod - do not use unless absolutely necessary.
* '''Global methods''': No class to mod do not use unless absolutely necessary.
}}




== Example ==
== Example ==


<syntaxhighlight lang="C#">
<enforce>
[EditorAttribute("box", "GameScripted/SomeFolder", "Description of this component", "-0.25 -0.25 -0.25", "0.25 0.25 0.25", "255 0 0 255", "0 0 0 0", true, true, true)]
[EntityEditorProps("GameScripted/SomeFolder", "Description of this component", "255 0 0 255", true, true, "", "box", "-0.25 -0.25 -0.25", "0.25 0.25 0.25", "0 0 0 0")]
class SCR_SomeComponentClass
class SCR_SomeComponentClass
{
{
Line 225: Line 249:
MESH = 1,
MESH = 1,
BODY = 2,
BODY = 2,
HIERARCHY = 4
HIERARCHY = 4,
NET = 8
NET = 8,
}
}


Line 234: Line 258:
class SCR_SomeComponent : ScriptComponent
class SCR_SomeComponent : ScriptComponent
{
{
//! Defines the minimum distance (in metres) for this object to render. If below this value, object will be culled.
const float RENDER_DISTANCE_MINIMUM = 10;
//! Defines the maximum distance (in metres) for this object to render. If above this value, object will be culled.
const float RENDER_DISTANCE_MAXIMUM = 100;
//! Defines the maximum distance at which this object will be rendered in metres.
//! Defines the maximum distance at which this object will be rendered in metres.
[Attribute("30.0", UIWidgets.Slider, "The maximum distance at which this object will be rendered in metres.", "0 120 0.1")]
[Attribute("30.0", UIWidgets.Slider, "The maximum distance at which this object will be rendered in metres.", "0 120 0.1")]
private float m_fRenderDistance;
protected float m_fRenderDistance;
 
//! Maximum count of children that can be spawned at any time. If the limit is exceeded no more children are spawned.
//! Maximum count of children that can be spawned at any time. If the limit is exceeded no more children are spawned.
[Attribute("100.0", UIWidgets.EditBox, "Maximum count of children that can be spawned at any time. If the limit is exceeded no more children are spawned.", "0 500 1")]
[Attribute("100", desc: "Maximum count of children that can be spawned at any time. If the limit is exceeded no more children are spawned.", "0 500")]
private int m_iMaximumChildCount;
protected int m_iMaximumChildCount;
 
//! The offset of this object in metres.
//! The offset of this object in metres.
private vector m_vPositionOffset = "0 0 0";
protected vector m_vPositionOffset = "0 0 0";


//! A public variable
//! A public variable
Line 254: Line 274:
//! A public vector
//! A public vector
vector m_vOtherPublic = "1 2 3";
vector m_vOtherPublic = "1 2 3";
//! Defines the minimum distance (in metres) for this object to render. If below this value, object will be culled.
const float RENDER_DISTANCE_MINIMUM = 10;
//! Defines the maximum distance (in metres) for this object to render. If above this value, object will be culled.
const float RENDER_DISTANCE_MAXIMUM = 100;


//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
Line 264: Line 290:
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
//! Set the render distance of this object.
//! Set the render distance of this object.
//! \param renderDistance Distance in metres. Is clamped between RENDER_DISTANCE_MINIMUM and RENDER_DISTANCE_MAXIMUM.
//! \param renderDistance distance in metres. Is clamped between RENDER_DISTANCE_MINIMUM and RENDER_DISTANCE_MAXIMUM.
void SetRenderDistance(float renderDistance)
void SetRenderDistance(float renderDistance)
{
{
Line 271: Line 297:


//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
//! Prints hello to the debug console. Private function, not exposed to outside classes.
//! Prints hello to the debug console. Protected method, not exposed to outside classes but available to child classes.
private void SayHello()
protected void SayHello()
{
{
string localString = "Hello!";
string localString = "Hello!";
Line 280: Line 306:
//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
//! Compare two integers, return the larger one. (Don't mind the silly documentation, mind the syntax)
//! Compare two integers, return the larger one. (Don't mind the silly documentation, mind the syntax)
//! \param a First parameter to be compared with the second one
//! \param a first parameter to be compared with the second one
//! \param b Second parameter to be compared with the first one
//! \param b second parameter to be compared with the first one
//! \return Returns true if a is equal to b, false otherwise.
//! \return true if a is equal to b, false otherwise.
bool IsEqual(int a, int b)
bool AreEqual(int a, int b)
{
{
// can be simplified to "return a == b;"
// can be simplified to "return a == b;"
Line 299: Line 325:


//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
// constructor - remove if empty
void SCR_SomeComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
void SCR_SomeComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
{
{
Line 315: Line 342:


//------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
// destructor - remove if left empty
void ~SCR_SomeComponent()
void ~SCR_SomeComponent()
{
{
}
}
};
}
</syntaxhighlight>
</enforce>




{{GameCategory|armaR|Modding|Guidelines|Scripting}}
{{GameCategory|armaR|Modding|Guidelines|Scripting}}

Latest revision as of 19:20, 14 November 2023

Format reminder:
  • camelCase is writing by gluing words together and making their first letter capital, but for the first one, e.g namingLikeThis.
  • PascalCase is writing in camelCase but with the first letter set uppercase, e.g NamingLikeThis.
  • snake casing (naming_like_this) is not a convention used in Enfusion.
    Only const values should be NAMED_LIKE_THIS.


Tag

To prevent conflict with other scripts all classes, and global functions must be distinguished by a Tag.

Bohemia Interactive scripts have been prefixed with SCR_. A mod developer must choose their own tag and not use one already taken by Bohemia Interactive or another developer.

When modding any class, all methods and variables within that modded class must also be distinguished by the same unique tag to prevent conflict.


File/Class

  • File should be called TAG_MyObject.c
    • A component must end with "component": TAG_ExampleComponent.c
    • An entity must end with "entity': TAG_ExampleEntity.c
  • Class should be called the same (without file extension):
    • class TAG_MyObject
    • class TAG_ExampleComponent
    • class TAG_ExampleEntity
  • Enum:
    • name must be prefixed with a capital E, e.g TAG_EMyEnum
    • values use all capital letters with words separated by underscores, e.g TAG_EMyEnum.VALUE_1
  • The file should be located in the scripts\Game directory
  • The use of plural is prohibited at the end of combined keywords: e.g TAG_NotificationsComponentTAG_NotificationComponent


Method

  • Functions/Methods naming uses PascalCase, e.g:
    int ReturnNumber()
  • Parameters are named with camelCase, e.g:
    int ReturnNumber(bool canBeNegative)


Variable

See this page for more information.
  • Member variables are prefixed with m_, a one-letter type prefix for specific types (see Value types), and use PascalCase, e.g:
    Entity m_Entity; int m_iHealth; bool m_bIsEnemy;
  • Global variables are prefixed with g_.
    Global variables are bad practice and must not be used outside of absolute necessity!
  • Static variables are prefixed with s_ (constants are not), eventually a one-letter type prefix, and use PascalCase, e.g
    protected static int s_iUnitsCount;
  • Local variables and arguments (method parameters) use camelCase, e.g:
    void MethodA() { int value = 42; string name = "John"; float result = MethodB(value, name); }
  • Constant values use all capital letters with words separated by underscores (uppercase snake casing), e.g:
    const int MAX_VALUE = 9999; // no 'm_' prefix nor 'i' type prefix static const int TOTAL = 10; // no 's_' prefix either

Order

  • First go Attributes (if any),
  • then public, protected, private member variables
  • then public, protected, private static variables
  • then public, protected, private constants

[Attribute()] protected int m_iAttribute; int m_iPublic; protected int m_iProtected; private int m_iPrivate; static int s_iPublic; protected static int s_iProtected; private static int s_iPrivate; static const int PUBLIC; protected static const int PROTECTED; private static const int PRIVATE;


Script

General

  • Curly braces must always be on a new line - Enforce Script uses Allman style
  • Variables and functions should be protected whenever possible (respecting OOP black box principle) unless they are intended to be exposed
  • Getters/Setters: variables should be made protected and accessed through getters and setters (entry methods getting/setting the value)

class SCR_HumanComponent : ScriptComponent { protected int m_iAge; void SetAge(int age) { m_iAge = age; PrintFormat("Age of instance %1 is now %2", this, m_iAge); } int GetAge() { return m_iAge; } }

Spacing

  • Tabs are used for indentation - they are set to a size of 4 spaces in Script Editor
  • A space is used before and after:
    • a binary operator
    • a foreach colon
    • a class' inheritance colon
  • A space is used after:
    • if, for, foreach, switch, while keywords
    • a for semicolon
  • Spaces are used inside parentheses but not around their content

class SCR_HumanComponent : ScriptComponent { if (true) { } for (int i = 0; i < 10; i++) { } foreach (string item : stringArray) { } switch (value) { case 42: break; } while (true) { } }

Method

  • All methods must be separated using this sequence of characters: two slashes followed by 96 dashes (see Example)
    //------------------------------------------------------------------------------------------------
  • Documentation must be done with Doxygen support in mind, using the //! comment syntax (see Example)
  • Methods should be sorted in the following order (top to bottom):
    • General methods
    • EOnFrame
    • EOnInit
    • Constructor
    • Destructor

//! A scripted entity class SCR_ScriptedEntity : GenericEntity { //------------------------------------------------------------------------------------------------ //! Get the normalized direction vector at position A pointing to B //! \param vectorA First position, direction origin //! \param vectorB Second position, direction goal //! \return The direction from A to B as a normalized vector protected vector GetNormalizedDirection(vector vectorA, vector vectorB) { vector dir = vectorB - vectorA; return dir.Normalized(); } //------------------------------------------------------------------------------------------------ //! Frame override void EOnFrame(IEntity owner, float timeSlice) { vector direction = GetNormalizedDirection(owner.GetOrigin(), vector.Zero); Print("OnFrame was called! Direction: " + direction); } //------------------------------------------------------------------------------------------------ //! Init override void EOnInit(IEntity owner) { Print("Init was called!"); } //------------------------------------------------------------------------------------------------ // constructor void SCR_ScriptedEntity(IEntitySource src, IEntity parent) { SetEventMask(EntityEvent.INIT | EntityEvent.FRAME | EntityEvent.CONTACT); } //------------------------------------------------------------------------------------------------ // destructor void ~SCR_ScriptedEntity() { Print("Destructing SCR_ScriptedEntity"); } }

Miscellaneous

  • class instanciation with the new keyword must use parentheses:
    SCR_Class myClass = new SCR_Class(); // correct SCR_Class myClass = new SCR_Class; // wrong
  • arrays can be initialised directly:
    array<string> myArray = {}; // correct array<string> myArray = new array<string>(); // tolerable array<string> myArray = new array<string>; // wrong


Moddability

It is important to keep moddability in mind when scripting to ensure. Modded classes work very similar to inherited ones and come with the same restrictions:

  • Constructor/Destructor: a modded class has its own const/destructor and cannot modify the parent one
  • Private variables & methods: a modded class cannot override parent's private members - use protected instead of private
  • Static variables & methods: same as above - do not use unless absolutely necessary
  • Global methods: no classes to mod - do not use unless absolutely necessary.


Example

[EntityEditorProps("GameScripted/SomeFolder", "Description of this component", "255 0 0 255", true, true, "", "box", "-0.25 -0.25 -0.25", "0.25 0.25 0.25", "0 0 0 0")] class SCR_SomeComponentClass { } SCR_SomeComponentClass SCR_SomeComponentSource; //! Flags used for an entity to define its currently active components. enum SomeFlags { MESH = 1, BODY = 2, HIERARCHY = 4, NET = 8, } //! A brief explanation of what this component does. //! The explanation can be spread across multiple lines. //! This should help with quickly understanding the script's purpose. class SCR_SomeComponent : ScriptComponent { //! Defines the maximum distance at which this object will be rendered in metres. [Attribute("30.0", UIWidgets.Slider, "The maximum distance at which this object will be rendered in metres.", "0 120 0.1")] protected float m_fRenderDistance; //! Maximum count of children that can be spawned at any time. If the limit is exceeded no more children are spawned. [Attribute("100", desc: "Maximum count of children that can be spawned at any time. If the limit is exceeded no more children are spawned.", "0 500")] protected int m_iMaximumChildCount; //! The offset of this object in metres. protected vector m_vPositionOffset = "0 0 0"; //! A public variable float m_fSomethingPublic = 3.2; //! A public vector vector m_vOtherPublic = "1 2 3"; //! Defines the minimum distance (in metres) for this object to render. If below this value, object will be culled. const float RENDER_DISTANCE_MINIMUM = 10; //! Defines the maximum distance (in metres) for this object to render. If above this value, object will be culled. const float RENDER_DISTANCE_MAXIMUM = 100; //------------------------------------------------------------------------------------------------ //! Returns the render distance of this object (metres). float GetRenderDistance() { return m_fRenderDistance; } //------------------------------------------------------------------------------------------------ //! Set the render distance of this object. //! \param renderDistance distance in metres. Is clamped between RENDER_DISTANCE_MINIMUM and RENDER_DISTANCE_MAXIMUM. void SetRenderDistance(float renderDistance) { m_fRenderDistance = Math.Clamp(renderDistance, RENDER_DISTANCE_MINIMUM, RENDER_DISTANCE_MAXIMUM); } //------------------------------------------------------------------------------------------------ //! Prints hello to the debug console. Protected method, not exposed to outside classes but available to child classes. protected void SayHello() { string localString = "Hello!"; Print(localString); } //------------------------------------------------------------------------------------------------ //! Compare two integers, return the larger one. (Don't mind the silly documentation, mind the syntax) //! \param a first parameter to be compared with the second one //! \param b second parameter to be compared with the first one //! \return true if a is equal to b, false otherwise. bool AreEqual(int a, int b) { // can be simplified to "return a == b;" if (a == b) return true; else return false; } //------------------------------------------------------------------------------------------------ override void EOnInit(IEntity owner) { Print("Initialized some component!"); } //------------------------------------------------------------------------------------------------ // constructor - remove if empty void SCR_SomeComponent(IEntityComponentSource src, IEntity ent, IEntity parent) { ent.SetEventMask(EntityEvent.INIT); // If offset is 0, no need to update if (m_vPositionOffset != "0 0 0") { // Get current transformation matrix, add the position offset and update transformation. vector mat[4]; ent.GetTransform(mat); mat[3] = mat[3] + m_vPositionOffset; ent.SetTransform(mat); } } //------------------------------------------------------------------------------------------------ // destructor - remove if left empty void ~SCR_SomeComponent() { } }