Actions

Script3 Things

From Populous Wiki

Revision as of 08:35, 18 April 2019 by IncaWarrior (talk | contribs) (→‎Correct Code: made correct code closer to bad code)

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 shaman = getShaman(TRIBE_BLUE);
 
 def OnTurn() 
 {
     if (!shaman.isNull())
     {
         var t_thing = shaman.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);
     }
 }