Actions

Script3 Things: Difference between revisions

From Populous Wiki

(Undo revision 6785 by IncaWarrior (talk) ObjectProxy is required for long term storage else the game might crash if the shaman dies.)
 
(8 intermediate revisions by 2 users not shown)
Line 1: Line 1:
== Introduction To Things ==
== Introduction To Things ==
In [[Script3|Script 3]] there is many way you may come across an object named [[Script3_Thing|Thing]] which is just the name of all objects on the game such as [[huts]], [[brave|braves]], [[spell|spells]], etc. Depending on how you come across these objects determines what you must do before you can use them. If you improperly use an object the script engine is not going to tell you; the game will just crash. Any long term storage of a Thing in your scripts should be stored in an [[Script3_ObjectProxy|ObjectProxy]] and checked for null each access. This is because if you store a raw Thing the Thing might be deleted/destroyed on the next turn and the Thing WILL NOT be null. In fact it may not even be the same Thing anymore. For example lets say you stored a [[shaman]] in a global Thing and the shaman dies on the next turn and that Thing is reused for a hut. The script may think that hut is a shaman and crash.  
In [[Script 3]] there is many way you may come across an object named [[Script3_Thing|Thing]] which is just the name of all objects on the game such as [[huts]], [[brave|braves]], [[spell|spells]], etc. Depending on how you come across these objects determines what you must do before you can use them. If you improperly use an object the script engine is not going to tell you; the game will just crash. Any long term storage of a Thing in your scripts should be stored in an [[Script3_ObjectProxy|ObjectProxy]] and checked for null each access. This is because if you store a raw Thing the Thing might be deleted/destroyed on the next turn and the Thing WILL NOT be null. In fact it may not even be the same Thing anymore. For example lets say you stored a [[shaman]] in a global Thing and the shaman dies on the next turn and that Thing is reused for a hut. The script may think that hut is a shaman and crash.  


If you call any of the ProcessList functions, every one of the calls to your function you specified to ProcessList is guaranteed to exist within the scope of your defined function. However, the return value of ProcessList MUST be checked for null if you are using the return value.
If you call any of the ProcessList functions, every one of the calls to your function you specified to ProcessList is guaranteed to exist within the scope of your defined function. However, the return value of ProcessList MUST be checked for null if you are using the return value.
Line 44: Line 44:
=== Example 1 ===
=== Example 1 ===


For example the this function listAllThingNums should always give a Thing that exists and does not need to be checked if it is null. However the return value of ProcessGlobalUsedList is not guaranteed to exist so that needs to be checked for null. Remember ProcessGlobalUsedList returns the last object processed on a return false, else it returns null.  
For example the this function giveMeFirstThingNum should always give a Thing that exists and does not need to be checked if it is null. However the return value of ProcessGlobalUsedList is not guaranteed to exist so that needs to be checked for null. Remember ProcessGlobalUsedList returns the last object processed on a return false, else it returns null.
# def giveMeFirstThingNum(Thing)
<source lang="javascript">
# {
def giveMeFirstThingNum(Thing)
#    log(Thing.ThingNum);
{
# return false;
      log(Thing.ThingNum);
# }
      return false;
# var retT = ProcessGlobalUsedList(giveMeFirstThingNum);
}
#
var retT = ProcessGlobalUsedList(giveMeFirstThingNum);
# if (retT.is_var_null())
# {
if (retT.is_var_null())
#     log(retT.ThingNum);
{
# }
     log(retT.ThingNum);
 
}
</source>
=== Bad Code Vs. Good Code ===
=== Bad Code Vs. Good Code ===


===== Bad Code: =====
===== Bad Code =====
# global shaman = getShaman(TRIBE_BLUE);
<source lang="javascript">
#
global shaman = getShaman(TRIBE_BLUE);
# def OnTurn()  
# {
def OnTurn()  
#    log(shaman.ThingNum);
{
# }
    log(shaman.ThingNum);
}
</source>
Reason: Shaman may not exist on the next turn and will not become null.  
Reason: Shaman may not exist on the next turn and will not become null.  


===== Correct Code: =====
===== Correct Code =====
# global shaman = ObjectProxy(getShaman(TRIBE_BLUE));
<source lang="javascript">
#
global shamanProxy = ObjectProxy(getShaman(TRIBE_BLUE));
# def OnTurn()  
# {
def OnTurn()  
#    if (!shaman.isNull())
{
#    {
    if (!shamanProxy.isNull())
#        log(shaman.ThingNum);
    {
#    }
        var t_thing = shamanProxy.get();
#    else
        log(t_thing.ThingNum);
#    {
    }
#        log("Shaman has died");
    else
#    }
    {
# }
        log("Shaman has died");
 
    }
===== Bad Code: =====
}
# global shaman = ObjectProxy(getShaman(TRIBE_BLUE));
</source>
#
===== Bad Code =====
# def OnTurn()  
<source lang="javascript">
# {
global shamanProxy = ObjectProxy(getShaman(TRIBE_BLUE));
#    log(shaman.ThingNum);
# }
def OnTurn()  
{
    var t_thing = shamanProxy.get();
    log(t_thing.ThingNum);
}
</source>
Reason: Once the shaman object dies shaman will become null, thus it is required to check if it is null before accessing else the game will crash.
Reason: Once the shaman object dies shaman will become null, thus it is required to check if it is null before accessing else the game will crash.


===== Good code: =====
===== Good code =====
# global shaman = ObjectProxy(getShaman(TRIBE_BLUE));
<source lang="javascript">
#
global shamanProxy = ObjectProxy(getShaman(TRIBE_BLUE));
# def OnTurn()  
# {
def OnTurn()  
#    if (!shaman.isNull())
{
#    {
    if (!shamanProxy.isNull())
#        log(shaman.ThingNum);
    {
#    }
        var t_thing = shamanProxy.get();
# }
        log(t_thing .ThingNum);
    }
}
</source>

Latest revision as of 06:33, 23 April 2019

Introduction To Things

In Script 3 there is many way you may come across an object named Thing which is just the name of all objects on the game such as huts, braves, spells, etc. Depending on how you come across these objects determines what you must do before you can use them. If you improperly use an object the script engine is not going to tell you; the game will just crash. Any long term storage of a Thing in your scripts should be stored in an ObjectProxy and checked for null each access. This is because if you store a raw Thing the Thing might be deleted/destroyed on the next turn and the Thing WILL NOT be null. In fact it may not even be the same Thing anymore. For example lets say you stored a shaman in a global Thing and the shaman dies on the next turn and that Thing is reused for a hut. The script may think that hut is a shaman and crash.

If you call any of the ProcessList functions, every one of the calls to your function you specified to ProcessList is guaranteed to exist within the scope of your defined function. However, the return value of ProcessList MUST be checked for null if you are using the return value.

Table of Functions and null check requirement.

Function Check For Null Notes
ProcessGlobalTypeList Partial Only On Return
ProcessGlobalUsedList Partial Only On Return
ProcessGlobalSpecialListAll Partial Only On Return
ProcessGlobalSpecialList Partial Only On Return
createThing Always
CREATE_THING_FOR_TRAINING Always
CREATE_THING_WITH_PARAMS4 Always
CREATE_THING_WITH_PARAMS5 Always
CREATE_THING_FOR_BUILDING_UPGRADING Always
FindNextGlobalTypeList Always
FindNextGlobalUsedList Always
FindNextSpecialList Always
findWood Always
ObjectProxy Always
GetThing Always
ConvertObjectListVectorToThingVector Never

Example 1

For example the this function giveMeFirstThingNum should always give a Thing that exists and does not need to be checked if it is null. However the return value of ProcessGlobalUsedList is not guaranteed to exist so that needs to be checked for null. Remember ProcessGlobalUsedList returns the last object processed on a return false, else it returns null.

def giveMeFirstThingNum(Thing)
{
       log(Thing.ThingNum);
       return false;
}
var retT = ProcessGlobalUsedList(giveMeFirstThingNum);
 
if (retT.is_var_null())
{
    log(retT.ThingNum);
}

Bad Code Vs. Good Code

Bad Code
 global shaman = getShaman(TRIBE_BLUE);
 
 def OnTurn() 
 {
     log(shaman.ThingNum);
 }

Reason: Shaman may not exist on the next turn and will not become null.

Correct Code
 global shamanProxy = ObjectProxy(getShaman(TRIBE_BLUE));
 
 def OnTurn() 
 {
     if (!shamanProxy.isNull())
     {
         var t_thing = shamanProxy.get();
         log(t_thing.ThingNum);
     }
     else
     {
         log("Shaman has died");
     }
 }
Bad Code
 global shamanProxy = ObjectProxy(getShaman(TRIBE_BLUE));
 
 def OnTurn() 
 {
     var t_thing = shamanProxy.get();
     log(t_thing.ThingNum);
 }

Reason: Once the shaman object dies shaman will become null, thus it is required to check if it is null before accessing else the game will crash.

Good code
 global shamanProxy = ObjectProxy(getShaman(TRIBE_BLUE));
 
 def OnTurn() 
 {
     if (!shamanProxy.isNull())
     {
         var t_thing = shamanProxy.get();
         log(t_thing .ThingNum);
     }
 }