Boolean constants

From Dragon Age Toolset Wiki
Jump to: navigation, search
Source: script.ldf
Constant name Type Value Description Source
FALSE int 0 script.ldf
TRUE int 1 script.ldf

Remarks

In dascript there is no Boolean type. Instead integer values are used to represent the Boolean states: zero represents the false state and any non-zero integer represents the true state. For convenience the boolean constants have been defined in script.ldf to represent the true and false states.

These constants are used in the following ways in script.ldf, the Core Game Resources and the Single Player Campaign:

// Assigning a value to a integer variable.
int bStillLooking = TRUE;
 
// Setting the a value of an integer argument in a function call.
SetItemDroppable(oItem, TRUE);
 
// Setting the default value of an integer argument in a function's declaration or definition.
void AddAbility(object oObject, int nAbility, int bSendNotification = FALSE);
 
// Setting a return value from an integer function.
return TRUE;

The constants are also referenced in the comments describing a function's return values, for example, as seen is IsObjectValid, to indicate that the function is constrained to return 0 or 1. This is probably reliable for engine functions (i.e. those in script.ldf) which are presumably converting from a native C++ bool type but should be treated with scepticism for scripted functions.

Finally the constants are also used in boolean expressions, for example, in an if statement:

if(<expression> == TRUE)
{
    ...
}

Typically this will be seen in connection with the various Is* and Has* functions, for example, as seen with the use of IsObjectValid in the item_singletarget script:

// make sure there is a location, just in case
if(IsObjectValid(stEvent.oTarget) == TRUE)
{
    stEvent.lTarget = GetLocation(stEvent.oTarget);
}

While not technically wrong - provided the function returns 0 or 1 as it does here - the comparison with the boolean constant is redundant and is not considered best practice. The above example should have been simplified to:

// make sure there is a location, just in case
if(IsObjectValid(stEvent.oTarget))
{
    stEvent.lTarget = GetLocation(stEvent.oTarget);
}

The rationale for avoiding comparisons with the boolean constants, specifically with the TRUE constant, is because the TRUE constant is only one of many values that can represent the true state and therefore can introduce ambiguity or unintended behaviour (i.e. a bug).

An example of this might be where an include file contains the following function:

int HasSuperValuableGems(object oCreature)
{
    return CountItemsByTag(oCreature, "SuperValuableGem");
}

And the action script or plot script contains the following:

// The PC needs a "super valuable gem" in order to bribe the noble!
if(HasSuperValuableGems(oHero) == TRUE)
{
    ...
}

The logic may appear correct however because the function is not constrained to return a boolean constant but is being compared against one the result will be that the PC can only bribe the noble when they have EXACTLY one gem which is probably not the intended behaviour. Removing the comparison against the TRUE constant would resolve this (although it could also be argued that the function should also be renamed to better indicate its behaviour).

Note that while comparisons against the FALSE constant do not suffer from the same ambiguity (as both it and the false state only ever equate to zero) they are nonetheless redundant and should be simplified using the logical negation operator:

// Replace this:
if(IsObjectValid(oTarget) == FALSE)
{
    ...
}
 
// With this:
if(!IsObjectValid(oTarget))
{
    ...
}

In conclusion it is best to only use the boolean constants for the following purposes:

  1. Assigning a value to a integer variable.
  2. Setting the a value of an integer argument in a function call.
  3. Setting the default value of an integer argument in a function's declaration or definition.
  4. Setting a return value from an integer function.

See also