Frictional Games Forum (read-only)

Full Version: Scripts Recollection - revisited
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
As it seems Arvaga has stopped participating in these Forums and I have nothing to do at the moment, this is the 2nd version of his 'Scripts Recollection'-thread.

I will update this post with new tutorials from time to time, so be sure to check in regularly and maybe contribute yourself!

FIRST THINGs FIRST: I assume you know HPS, or at least have read this and set up Notepad++ according to this!

-- CALLBACKS --

Callbacks are script functions that continually check if a certain specified condition or situation has occured and then call a function which plays a sound / spawns a grunt / etc. Also called triggers.

There are different kinds of callbacks which check different kinds of conditions, but their syntax is mostly the same. The following are ordered alphabetically:

EntityCollideCallbacks
Spoiler below!
This type of callbacks is used when one entity collides with another, for examples you use it to check if the Player has entered a script area.

Code:
void  AddEntityCollideCallback(string& asParentName, string& asChildName, string& asFunction, bool abDeleteOnCollide, int alStates);

asParentName - the parent entity, most of the times it's "Player"
asChildName - the child entity or the object (script areas for example) the parent entity / Player collides with
asFunction - the name of the function that gets called if the entities collide
abDeleteOnCollide - if the callback should be removed once the function has been called
alStates - either
1 = function is called when asParent enters asChild
0 = function called when entering and leaving asChild
-1 = function called when leaving asChild

Callback function syntax:
Code:
void asFunction(string &in asParent, string &in asChild, int alState)

Example script
Code:
void OnStart()
{
    AddEntityCollideCallback("Player", "Script_Area_Door", "Door_Function", true, -1);
}

void Door_Function(string &in asParent, string &in asChild, int alState)
{
    SetSwingDoorClosed("mansion_door", true, true);
    PlaySoundAtEntity("slam!", "door_slam.snt", "mansion_door", 0.0f, false);
}

In this script, once the Player leaves (alState = -1) our script area Script_Area_Door the callback function Door_Function is called.
abDeleteOnCollide set true means the callback then is removed.

Door_Function then uses SetSwingDoorClosed to close the door mansion_door and play an accurate door slam sound.

If you want to remove the callback before it has been called (maybe because something different happened), use

Code:
void  RemoveEntityCollideCallback(string& asParentName, string& asChildName);


UseItemCallbacks
Spoiler below!
This is the callback function that is used if you want to make item interaction with the player's environment possible.

Code:
void  AddUseItemCallback(string& asName, string& asItem, string& asEntity, string& asFunction, bool abAutoDestroy);

asName - literally name of the callback, use explained down below
asItem - the item the player has selected from his inventory, can be a key, a crowbar, anything
asEntity - the entity the item is supposed to be used on, in case of keys = a door, or script areas
asFunction - the function the callback triggers
abAutoDestroy - the same as abDeleteOnCollide, removes the callback when set true

Callback function syntax:
Code:
void asFunction(string &in asItem, string &in asEntity)

Example script
Code:
void OnStart()
{
    AddUseItemCallback("", "key_library", "library_door", "Open_Library", true);
}

void Open_Library(string &in asItem, string &in asEntity)
{
    SetSwingDoorLocked("library_door", false, true);
    PlaySoundAtEntity("click", "unlock_door.snt", "library_door", 0.0f, false);
}

One of the most common ItemCallbacks, which opens a locked door. key_library is our key which is used on the door library_door. This triggers the function Open_Library which opens the door with SetSwindDoorLocked and plays a nifty unlock sound.
You can get very creative with this kind of callbacks, remember the padlock puzzle from Frictional's prison level?

If you want to remove this callback, use

Code:
void  RemoveUseItemCallback(string& asName);

This is what asName is for. If you don't plan on doing so, just leave it empty, like in my example script.

EntityCallbacks
Spoiler below!
These are callbacks that refer to one specific entity only and include Interact-, LookAt- and .. just Callbacks. They are set in the entity tab of the entity in the level editor, but you can also add them in your script.

EntityCallback
Code:
void  SetEntityCallbackFunc(string& asName, string& asCallback);

asName - name of the entity
asCallback - callback function

You may now ask yourself - "What is this used for? When is this even called?" Well, the secret lies in the callback function:

Code:
void asCallback(string &in Entityname, string &in Type)

type can be three things: OnPickup, Break, OnIgnite
You check these with an if (type = x) condition!

OnPickup = this is used when the entity is picked up, so mostly for items if you want to make something happens when, for example, the player picks up a key (how Frictional triggers some monsters, for example).

Break = when the entity breaks (glass bottles, but also doors that monsters may break down!)

OnIgnite = this is used for (surprise!) lamps or candles

Example script
Code:
void BookPickUp(string &in EntityName, string &in Type)
{
    if(Type == "OnPickup")
    {
        SetEntityActive("TeleportChangeItemArea", true);
    }
}

I've written BookPickUp in the callback text field of an item, so there's no need to use SetEntityCallbackFunc here. So when the if condition has checked if string &in Type is OnPickup, it activates an area called TeleportChangeItemArea. I rarely use this type of callbacks, but there are occasions where they are necessary.

EntityLookAtCallback
Code:
void  SetEntityPlayerLookAtCallback(string& asName, string& asCallback, bool abRemoveWhenLookedAt);

asName - name of the entity the player looks at
asCallback - callback function; as you can see, the syntax of these is pretty minimal
abRemoveWhenLookedAt - .. self-explanatory by now

This type of callback checks if the player looks at a specific entity. In a horror game, I think you can guess what these are used for.

Callback function syntax (this is where the fun begins):
Code:
void asCallback(string &in entity, int alState)

alState can be either 1 (player is looking) or -1 (player is not looking).
You don't have to use an if condition, in that case the callback function will automatically trigger when the player looks at the entity. Keep in mind that entities can be script areas too, so if you want to do something behind the player.. look at the example script!

Example script
Code:
void Surprise_Monster(string &in entity, int alState)
{
    if (alState == -1)
    {
        SetEntityActive("Heinz", true);
        ShowEnemyPlayerPosition("Heinz");
    }
}

So.. how this works: Let's assume we have a little room. One half of that room is covered with a script area, which has the EntityLookAtCallback Suprise_Monster, which only triggers when the player does NOT look at the script area, which means not looking at one half of the room which ensures the player has his back to the area when Heinz, our grunt, spawns there and attacks, with a little help from ShowEnemyPlayerPosition, the player.
Some of you may ask: "But what if the player even isn't in that room? Wouldn't the monster instantly spawn when the player is just somewhere else?" and I'd say "You're absolutely right!". The trick is only activating the callback when the player enters the room and deactivating it once he leaves. Use an EntityCollideCallback with an area that covers the whole room and checks when the player enters and leaves the area or the room!

EntityPlayerInteractCallback
Code:
void  SetEntityPlayerInteractCallback(string& asName, string& asCallback, bool abRemoveOnInteraction);
asName - name of the entity the player interacts with.. you should get this by now
asCallback - callback function
abRemoveOnInteraction - self-explanatory

This one is simple. It calls its callback function once the player interacts with an entity, which could be opening a door / drawer, picking up a chest etc.

Callback function syntax:
Code:
void asCallback(string &in entity)

Example script
Code:
void OnStart()
{
    SetEntityPlayerInteractCallback("pandora's box", "Bad_Move", true);
}

void Bad_Move(string &in entity)
{
    PlaySoundAtEntity("pandora", "end_of_the_world.snt", "Player", 5.0f, false);
}

Once the player interacts (meaning grabbing it / opening it) with Pandora's box, we play an eerie sound which initiates the end of the world!

- Doors
- Monsters
- Items
- Beginner
- Intermediate
- Advanced
- Timers
- Levers/Buttons
- Language edit

Just some suggestions on categories.
And better explanations would be great.
bump

How about just getting all of the old scripts in ? Smile
Probably should add more complex scripts in here, and dab deeper into changing configurations and such rather than just scripts themselves.
Wouldn't it be better to put all these things in a nice thread in the wiki?

Joint-effort, Frontcannon? ^^
Well, how do we sort them? First things first, fellas Big Grin

I have some ideas, but they would include rewriting almost anything.

Organising stuff:

Callbacks
Basically everything that gets called when another thing happens. LookAtCallbacks, InteractCallbacks, CollideCallbacks etc etc. Some explaining of the basic principles and syntax and lots of examples.

Timers
How to use timers effectively. Believe me, there is TONS of stuff you can do with timers (especially the asTimer string).

There's more, but this approach is very.. syntax-focused, we could do it the other way round and do it from a user-based view and organise it after how you do stuff (like opening a door, playing a sound), but that is quite cumbersome.

Sorting it by difficulty is another good idea, I think sorting it by themes like Neatherblade did is the simplest way to do it right now.

@ Shev: Do you mean changing configs and actually modding stuff? You better ask DIGIbyte or xiphirx for that Big Grin
BUMP

The callback section is done, though there is still some stuff missing (ConnectionStateChangeCallbacks and CombineCallbacks), would someone help me with those?

Next stop, Timers.
I'm sorry if I've read over it but I'd like my monster to spot the player immidiatly when it spawns and runs through the map to the player. I know theres a command for it but I don't understand it.
I don't think that will work. You'd just put ShowEnemyPlayerPosition in OnStart(), but I doubt the monster will make it to the player, most likely it will get stuck somewhere.
Does any1 have the full script for breaking a door open with a crowbar? There is one script in another thread but it isn't complete or some wrong names/items are used in the script I can't get it to work. It gets kinda lame to find a key all the time to unlock the next room =/