Frictional Games Forum (read-only)

Full Version: How Scripts Are Formated
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Hello all!

A lot of new script writers are joining the forum each day, with little knowledge of how to actually script. NOTHING is wrong with that, I was there not too long ago (about a month ago) and through countless hours of testing, re-writing, throwing things across my room in frustration, games crashing with errors etc. I have made coding much more easy on myself, by thinking of it all, in the following format. For you new scripters, if you are a visual and hands on learner like myself, I present you a very good resource:

The Code

So, here we have a script to open a door:
Code:
{
AddUseItemCallback("", "mainkey_1", "maindoor_1", "UsedKeyOnDoor2", true);
}
void UsedKeyOnDoor2(string &in asItem, string &in asEntity)
{
SetSwingDoorLocked("maindoor_1", false, true);
PlaySoundAtEntity("", "unlock_door.snt", "maindoor_1", 0, false);
RemoveItem("mainkey_1");
}

Watch how with one little edit I made to this, makes it 10 times easier to read.

Code:
{
        AddUseItemCallback("", "upstairskey", "upstairsdoor", "UsedKeyOnDoor2", true);
}
void UsedKeyOnDoor2(string &in asItem, string &in asEntity)
{
        SetSwingDoorLocked("maindoor_1", false, true);
        PlaySoundAtEntity("", "unlock_door.snt", "maindoor_1", 0, false);
        RemoveItem("mainkey_1");
}

Organizing your code is a major part of scripts. If you cant find where you need to script, you cant script it, case and point. So your question now is probably:
"Okay, but how the heck am I supposed to organize it"

MAJOR REQUIREMENT: http://notepad-plus-plus.org/download/v5.9.3.html

The above link is "Notepad++" its a must for HPL2 (the Amnesia engine) scripting

Once you open Notepad++, paste in the above organized code, and you can see, its still fairly easy to read. Its all about indenting your code. So for me, any "VOID" stays aligned to the left, and anything else, gets indented twice. (Tab,Tab)

Scripting It
Perfect, you made it this far! Now you should still have my code in your Notepad++ document, so if you closed it, OPEN IT AGAIN! x)

See the line:
Code:
{
        AddUseItemCallback("", "upstairskey", "upstairsdoor", "UsedKeyOnDoor2", true);
}

Think of that as the "Major Category." Then you see the other 3 lines that are indented below the "void"?

Code:
{
        SetSwingDoorLocked("maindoor_1", false, true);
        PlaySoundAtEntity("", "unlock_door.snt", "maindoor_1", 0, false);
        RemoveItem("mainkey_1");
}

You can think of these as the "details" or "sub-category" for the "AddUseItemCallback" or "Major Category." Then the "void", think of it as identification. So let me pull this back together.

Game says:
"Whats going on?"

Major Category says:
"The player is going to use an item"

Game says:
"Okay, what else?"

Sub-Category says:
They want to unlock the door, play a sound, and remove an item from their inventory."

"Game Says"
"Alrighty! DONE!"

So you may be asking:
"How does the game know where the sub category is though?"

If you look in the "Major Category" you can see the text in the second to last thing in the AddUseItemCallback (the UsedKeyOnDoor2) is also in the void right above the sub-category. Therefore, when the game reads that the void has the same name, it will take all the sub-category from under the void (until you end it with a "}") and it will play it all in game.

Avoiding Errors

Errors are tricky. They can only be one problem, but have many errors on the actual crash! So how do you avoid these? Keep your code organized like so:

Code:
{ALL MAIN CATEGORIES GO IN HERE
        AddUseItemCallback("", "mapsixkey", "demon_transfer1", "UsedKeyOnDoor", true);
        AddEntityCollideCallback("Player", "attic_sound_scare1", "OnBegin", true, 1);
        AddEntityCollideCallback("Player", "scare_1", "Scare", true, 1);
        AddEntityCollideCallback("Player", "Doorslamarea", "DoorScare", true, 1);
        AddEntityCollideCallback("Player", "scare_two", "Scare2", true, 1);
        AddEntityCollideCallback("Player", "levelchangefade", "FallOver", true, 1);
}
void OnBegin(string &in asParent, string &in asChild, int alState) <--  The indetifacation we are using
{ALL THE DETAILS FOR "OnBegin" CATEGORY.

        ChangePlayerStateToNormal();
        FadePlayerRollTo(0, 33, 33);
        FadeRadialBlurTo(0.0, 1);
        SetPlayerCrouching(false);
        FadeImageTrailTo(0,1);
}

Avoiding errors is a lot easier that way. Also, dont forget your "{}" and your ", and ;"

Pro Tip: A "//" in front of any part of code, will tell the game NOT TO READ THAT LINE. Therefore, you can add anything you want after a "//". For example, you can do this!
Code:
{
AddUseItemCallback("", "mainkey_1", "maindoor_1", "UsedKeyOnDoor", true);
}
//This is the sub-category for the callback on maindoor_1
void UsedKeyOnDoor(string &in asItem, string &in asEntity)
{
SetSwingDoorLocked("maindoor_1", false, true);
PlaySoundAtEntity("", "unlock_door.snt", "maindoor_1", 0, false);
RemoveItem("mainkey_1");
}

Adding small notes in your code, can also help you keep track of it.

Example of Code

Finally, here is an example of my code to wrap all this together, you will notice that I have lines that separate my code, this just helps me know where each sub-category ends.

Code:
void OnStart()
{
        AddUseItemCallback("", "mapsixkey", "demon_transfer1", "UsedKeyOnDoor", true);
        AddEntityCollideCallback("Player", "attic_sound_scare1", "OnBegin", true, 1);
        AddEntityCollideCallback("Player", "scare_1", "Scare", true, 1);
        AddEntityCollideCallback("Player", "Doorslamarea", "DoorScare", true, 1);
        AddEntityCollideCallback("Player", "scare_two", "Scare2", true, 1);
        AddEntityCollideCallback("Player", "levelchangefade", "FallOver", true, 1);
}
//--------------------------------------------------------------------------------//
void UsedKeyOnDoor(string &in asItem, string &in asEntity)
{
        SetLevelDoorLocked("demon_transfer1", false);
        SetLevelDoorLockedSound("demon_transfer1", "door_level_wood_locked.snt");
        RemoveItem("mapsixkey");
}
//--------------------------------------------------------------------------------//
void FallOver(string &in asParent , string &in asChild , int alState)
{
        PlaySoundAtEntity("", "player_bodyfall.snt", "Player", 0, true);
        FadeImageTrailTo(2, 2);
        FadePlayerRollTo(50, 33, 33);
        FadeRadialBlurTo(0.20, 2);
        SetPlayerCrouching(true);
        AddTimer("trig1", 15.0f, "beginStory");
        AddTimer("trig2", 3.0f, "Fadeout");
        SetPlayerActive(false);
}
//--------------------------------------------------------------------------------//
void Fadeout(string &in asTimer)
{
        FadeOut(3.0f);
        ChangeMap("map04.map", "PlayerStartArea_2", "", "");
}
//--------------------------------------------------------------------------------//
void beginStory(string &in asTimer)
{
        ChangePlayerStateToNormal();
        FadePlayerRollTo(0, 33, 33);
        FadeRadialBlurTo(0.0, 1);
        SetPlayerCrouching(false);
        FadeImageTrailTo(0,1);
}
//--------------------------------------------------------------------------------//
void DoorScare(string &in asParent, string &in asChild, int alState)
{
        SetSwingDoorClosed("mansion_8", true, true);
        SetSwingDoorLocked("mansion_8", true, true);
        PlaySoundAtEntity("", "door_level_cistern_close.snt", "Doorslamarea", 0.0f, true);
}
//--------------------------------------------------------------------------------//
void OnBegin(string &in asParent, string &in asChild, int alState)
{
        SetEntityActive("scare_1", true);
        SetEntityActive("scare_two", true);
        PlaySoundAtEntity("", "amb_idle_whimp.snt", "attic_sound_scare1", 0.0f, true);
        PlaySoundAtEntity("", "insanity_baby_cry.snt", "attic_sound_scare1", 0.0f, true);
        PlaySoundAtEntity("", "door_level_cistern_close.snt", "attic_sound_scare1", 0.0f, true);
        PlaySoundAtEntity("", "general_thunder.snt", "attic_sound_scare1", 0.0f, true);
        PlaySoundAtEntity("", "break_stairs.snt", "attic_sound_scare1", 0.0f, true);
}
//--------------------------------------------------------------------------------//
void Scare(string &in asParent, string &in asChild, int alState)
{
        SetEntityActive("levelchangefade", true);
        SetSwingDoorLocked("mansion_8", false, true);
        CreateParticleSystemAtEntity("", "ps_dust_impact", "Partdoor1", false);    
        CreateParticleSystemAtEntity("", "ps_door_damage_wood", "Partdoor1", false);
        CreateParticleSystemAtEntity("", "ps_dust_impact", "Partdoor2", false);    
        CreateParticleSystemAtEntity("", "ps_door_damage_wood", "Partdoor2", false);
        CreateParticleSystemAtEntity("", "ps_dust_impact", "Partdoor3", false);    
        CreateParticleSystemAtEntity("", "ps_door_damage_wood", "Partdoor3", false);
        CreateParticleSystemAtEntity("", "ps_dust_impact", "Partdoor4", false);    
        CreateParticleSystemAtEntity("", "ps_door_damage_wood", "Partdoor4", false);
        PlaySoundAtEntity("", "lurker_hit_Wood", "Player", 0, false);
        GiveSanityDamage(20, true);
        AddPlayerBodyForce(-40000, 25000, 0, false);
        FadePlayerRollTo(75, 3, 2);
        StartPlayerLookAt("mansion_8", 2, 2, "");
        SetPlayerCrouching(true);
        AddTimer("", 2, "Timer1");
        AddTimer("", 10, "Timer2");
        GivePlayerDamage(10, "BloodSplat", false, false);
        PlaySoundAtEntity("", "player_bodyfall", "Player", 0, false);
        FadeRadialBlurTo(1, 0.5);
}
//--------------------------------------------------------------------------------//
void Timer1(string &in asTimer)
{
        StartPlayerLookAt("mansion_8", 0.4, 0.4, "");
        FadePlayerRollTo(-75, 3, 2);
        AddTimer("", 2, "Timer3");
        PlaySoundAtEntity("", "react_sigh", "Player", 0, false);
}
//--------------------------------------------------------------------------------//
void Timer3(string &in asTimer)
{
        PlaySoundAtEntity("", "react_sigh", "Player", 0, false);
        StartPlayerLookAt("mansion_8", 0.4, 0.4, "");
        FadePlayerRollTo(0, 0, 0);
        AddTimer("", 2, "Timer5");
        FadeRadialBlurTo(0, 1);
}
//--------------------------------------------------------------------------------//
void Timer5(string &in asTimer)
{
        PlaySoundAtEntity("", "react_scare", "Player", 0, false);
}
//--------------------------------------------------------------------------------//
void Timer2(string &in asTimer)
{
        SetPlayerCrouching(false);
        StopPlayerLookAt();
        SetLanternDisabled(false);
}
//--------------------------------------------------------------------------------//
void Scare2(string &in asParent, string &in asChild, int alState)
{
        PlaySoundAtEntity("", "lurker_hit_Wood", "Player", 0, false);
        GiveSanityDamage(40, true);
        AddPlayerBodyForce(40000, 25000, 0, false);
        FadePlayerRollTo(75, 3, 2);
        SetPlayerCrouching(true);
        AddTimer("", 2, "Timerone");
        AddTimer("", 10, "Timertwo");
        SetLanternDisabled(true);
        PlaySoundAtEntity("", "player_bodyfall", "Player", 0, false);
        FadeRadialBlurTo(1, 0.5);
}
//--------------------------------------------------------------------------------//
void Timerone(string &in asTimer)
{
        FadePlayerRollTo(-75, 3, 2);
        AddTimer("", 2, "Timerthree");
        PlaySoundAtEntity("", "react_sigh", "Player", 0, false);
}
//--------------------------------------------------------------------------------//
void Timerthree(string &in asTimer)
{
        PlaySoundAtEntity("", "react_sigh", "Player", 0, false);
        FadePlayerRollTo(0, 0, 0);
        AddTimer("", 2, "Timerfive");
        FadeRadialBlurTo(0, 1);
}
//--------------------------------------------------------------------------------//
void Timerfive(string &in asTimer)
{
        PlaySoundAtEntity("", "00_laugh.snt", "Player", 0, false);
}
//--------------------------------------------------------------------------------//
void Timertwo(string &in asTimer)
{
        SetPlayerCrouching(false);
        SetLanternDisabled(false);
}
//--------------------------------------------------------------------------------//
void OnLeave ()
{
}

Please feel free to ask all questions, I will be sure to at least try to answer them Wink
Seems like you're helping alot with scripting. But I did notice that you haven't compressed or organized your timers into 1 timer function or switch statement for the last code piece you posted since you were suggesting to have people keep it neat. Tongue

What I also noticed is that you forgot the "void OnStart()" for the first three pieces of code when saying that it was the code to unlock a door. ^^
(08-21-2011, 05:03 PM)Kyle Wrote: [ -> ]Seems like you're helping alot with scripting. But I did notice that you haven't compressed or organized your timers into 1 timer function or switch statement for the last code piece you posted since you were suggesting to have people keep it neat. Tongue

What I also noticed is that you forgot the "void OnStart()" for the first three pieces of code when saying that it was the code to unlock a door. ^^

As far as the timers, I am really still learning how to work those xD

And the Void OnStart() I figure people would have that already from the starter script.
Shouldn't this be moved to the wiki as a tutorial?
I am used to a language called Torque Code, if anyone here knows the engine. If not, it is what Tribes 2 and Marble Blast are based off. As such, reading code into too difficult. I will begin learning code, but I have one question since I'm not sure how finicky this language is: Can I put the opening bracket on the same line as the command? That's how I'm used to coding, even if everyone scolds me for it.

(08-21-2011, 09:34 PM)JenniferOrange Wrote: [ -> ]Shouldn't this be moved to the wiki as a tutorial?

People are asking about code here, so having help in both locations would probably be better than redirecting everyone there. Especially when you may get a personalized response here, where as you can't directly ask on the wiki.
All kind of tutorials should be on wiki, as forum posts tend to go to old dusty archive in a few days and gets forgotten..
@MegaScience

I would not suggest adding it on the same line, but it is possible, but be prepared to get some errors.
(08-21-2011, 04:55 PM)JetlinerX Wrote: [ -> ]Pro Tip: A "//" in front of any part of code, will tell the game NOT TO READ THAT LINE. Therefore, you can add anything you want after a "//".

Should be noted, Angelscript supports multi-line comments just like C++
Code:
/*
some code or text here...
some more code or text here...
*/
(08-21-2011, 09:53 PM)MegaScience Wrote: [ -> ]Can I put the opening bracket on the same line as the command? That's how I'm used to coding, even if everyone scolds me for it.

You can put everything on one line if you really wanted to.
The compiler reads everything as one line technically.
(08-21-2011, 10:11 PM)JetlinerX Wrote: [ -> ]@MegaScience

I would not suggest adding it on the same line, but it is possible, but be prepared to get some errors.

(08-21-2011, 10:48 PM)Juby Wrote: [ -> ]You can put everything on one line if you really wanted to.
The compiler reads everything as one line technically.

I just want to be sure it can do that like I'm used to. Thanks. Smile
Pages: 1 2