Cache
Cache is implemented as of 03.04.2023, it makes the function GetContextOwner a bit redundant.
It is very important because script classes can have memory, and their state won't get lost after executing one of their function again.
How it works, explanation
You call the AngelScript P3S function via like this:
AngelScript "Object:self MyClass MyFunction"
The script class looks something like this:
class MyClass : IPostal3Script
{
CP3SObj@ self;
MyClass(CP3SObj@ obj)
{
@self = obj;
}
void MyFunction()
{
// ...
}
}
The game first checks if there's already a cached instance of the class named MyClass
with the context owner's pointer.
If not, then it will first create the factory, in the example above that is called MyClass(CP3SObj@ obj)
,
this will always gets called first, before eventually executing MyFunction()
.
In the factory you can set up initialization things such as making sure the self
handle is assigned to the
entity that called AngelScript.
Global (no owner)
Global version (basically no owner is attached) would look something like this in P3S:
AngelScript "GLOBAL MyClass Increment"
Then the script class would look something like this:
class MyClass : IPostal3Script
{
int num;
CP3SObj@ caller;
MyClass()
{
num = 0;
}
void Increment()
{
num++;
Printf("Incremented: %d\n", num);
}
}
No matter from which entity it was called from, the variable num
would never start again from 0 in the example above.
Only disadvantage is that you will never know which entity called this function.
Variables don't get lost after executing twice
Script classes will hold all the variables you set previously, if the context owner is the same.
If there is no context owner (i.e. engine functions, like SEngine::FireGameEvent(IGameEvent @evt)
) then cache will only look up for the class name.
You can still check for the context owner via GetContextOwner.
For example:
class MyClass : IPostal3Script
{
CP3SObj@ self;
MyClass(CP3SObj@ obj)
{
@self = obj;
}
bool bBoolean;
void MyFunction()
{
if (bBoolean == false)
Printf("Boolean is false!\n");
else
Printf("Boolean is true!\n");
bBoolean = true;
}
}
Executing MyFunction()
first will print out the message Boolean is false!
to the console, but if you
execute it twice, it'll say Boolean is true!
on the same entity it was executed from in the first place.
No Serialization, Restoration
Outdated Section
This part of the tutorial is outdated, it was written when AngelScript had no serialization.
While the information here is not that useless, we don't really recommend using this method for restoration.
Check the Serialization page for more information.
AngelScript in Catharsis Reborn do not have serialization, this means whenever you save the game and reload it (or go through a transition), AngelScript's memory will be wiped.
You can tell AngelScript which entities you wish to be "restored" whenever the game was reloaded
via a save file, or when the Player went through a transition with the following P3S attributes:
Postal3Script Attribute | Postal3Script Event |
---|---|
as_restore | OnASRestore |
as_transition | OnASTransition |
as_restore
will call OnASRestore
P3S event when the game was reloaded via a save file.
as_transition
will call OnASTransition
P3S event when the game was a transition load type.
Using these two attributes you can then attempt restoration by reinitializing their classes, like this:
// Executed from OnASRestore and OnASTransition P3S events
xpt_restore
{
actions
{
// Have to always remove attribute as_init_<className> !!
RemoveAttr "as_init_CATM"
AngelScript "Init Object:self CATM"
}
}
Depending on the complexity of your entity, you will also have to edit AngelScript code to reattach important things.
While AngelScript will never be saved to disk, Postal3Script will do, and it's highly recommended to save P3S attributes inside the entity.