Facebook Twitter YouTube Frictional Games | Forum | Newsletter | Dev Blog | Dev Wiki | Support


Thread Closed 
 
Thread Rating:
  • 2 Votes - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Advanced script widgets
Author Message
palistov Offline
Posting Freak

Posts: 1,213
Joined: Mar 2011
Reputation: 57
Post: #1
Information Advanced script widgets

This is a working thread. It will be changed/added to. Feel free to ask questions and make requests!

Hey guys, I've decided to make a thread with very useful script 'widgets' that new modders can just copy and paste into their .hps file! This will help you get a jumpstart in your map's script, as well as help you see exactly what a function or composition of functions does! It will start off fairly basic and get more complex and intricate as it progresses! Don't be afraid to browse the script tutorials from the Frictional Games wiki and toss them in there too! Variety is the spice of life!

NOTE: You must change many of the string names used here. Make sure they match your map's entities, areas, and the sound files you want to use. These are merely frameworks.

Make a door swing open on player collide/interact
A classic. Pushes a door open/closed. If you want to push it closed, ignore the first line in the DoorSwing() function

Spoiler below!
void OnStart()
{
    AddEntityCollideCallback("Player", "DoorSwingTrigger", "DoorSwing", true, 1);    
}


void DoorSwing(string &in asParent, string &in asChild, int alState)
{
    SetSwingDoorClosed("SpookySwingingDoor", false, false);
    AddPropImpulse("SpookySwingingDoor", float X, float Y, float Z, "World");
}

//DoorSwingTrigger is the area which the player enters to trigger the event and DoorSwing is the name of the function to callback

//Play around with your x, y and z float values. It depends on the orientation of your door and how fast you want it to swing open.





Create an ambient sound across the map
This is a simple function, but ambient and background sound is often overlooked. Make sure the file you play is under the sounds\ambience\ folder. It must a) loop seamlessly and b) play across the entire map to be properly used as an ambient effect.
Spoiler below!
void OnStart()
{
    PlaySoundAtEntity("ambience", "[i]soundfile.snt[/i]", "Player", 0, false);
}

//Just a note, make sure you choose a file under the ambience folder. Those sound files loop and usually correspond to spooky ambient environments.




Give an enemy a patrol path
This will create a route that a grunt will patrol. It will continuously follow this path until the nodes are cleared via the ClearEnemyPatrolNodes() function and new ones assigned.
Spoiler below!
void OnStart()
{
    for(int n=1;n<5;n++) AddEnemyPatrolNode("grunt", "patrol_node_"+n, 0, "");
}

//orient your 4 patrol nodes however you want. Just know that the grunt will walk along them in sequence, so make it at least look "natural"

//the last string is used for animations to be played while waiting at the node. Doesn't seem to work for me...



LookAt event
Event that triggers when player looks at an entity. Classic.
Spoiler below!
void OnStart()
{
    SetEntityPlayerLookAtCallback("entity_name", "OhLookSomethingHappened", true);
}

void OhLookSomethingHappened(string &in entity, int alState)
{
    if(alState == 1) {
    //Do some scary stuff here.
    }
}

//you can also change the if statement to require alState to be -1, meaning the events will happen when the player looks away from the object. They will not trigger until the player looks at the entity and then looks away. Works just like collisions.


Create random and spooky ambience
This function creates random sounds at random intervals at random spots around the map. Entirely random. Using this properly, as in, with the right lighting, particle systems, ambience, music, and environment can cause even hardened Amnesia players to shake in their seats. This is an essential tool to creating a proper atmosphere for the player.

Option 1:
Spoiler below!
void OnStart()
{
    SpookyLoop(); //copy & paste this line if you already have an OnStart() function
}

void SpookyLoop()
{
    int iSpooky = RandInt(1, a); //a = total number of areas you have
    int iTime = RandInt(b, c); //b and c constitute the range of values to choose from for iTime
    int iFile = RandInt(1, d); //d is the total number of files to randomly pick from
    switch(iFile) {
        case 1:
            PlaySoundAtEntity("spooky_sound", "file1.snt", "spook_area_"+iSpooky, 0, false);
        break;
        case 2:
            PlaySoundAtEntity("spooky_sound", "file2.snt", "spook_area_"+iSpooky, 0, false);
        break;
        case 3:
            PlaySoundAtEntity("spooky_sound", "file3.snt", "spook_area_"+iSpooky, 0, false);
                             //repeat above if you want more files
    }
    AddTimer("reloop", iTime, "SpookyLoopFunc");
}

void SpookyLoopFunc(string &in asTimer)
{
    SpookyLoop();
}

//iSpooky...corresponds to the area the sound will play at. It is chosen randomly each time the function is called

//iTime...this is the value the timer will use before it re-calls the loop function. I choose to use integers over float values, but you can  make it 'float fTime = RandFloat(10, 20) if you wish

//iFile...this integer is used by the function to check which file to use. Variety is the spice of life, so use multiple spooky sounds that fit your zone map. A cellar would be great to have lots of creaks and wooden sounds. A dungeon would do well with chains or water drops or wails. An area with lots of windows would be awesome with windy sounds, etc

//there are multiple ways to make this loop. I've done it several different ways across my maps, they all work just fine.


Option 2 (contributed by Apjjm):
Spoiler below!
void playRandomSound(string soundName, string[] sounds, string atEntity, float fadeTime, bool saveSound)
{
    //Select a random index from the array
    int rand = RandInt(0,sounds.length()-1);
    //Play the sound at that index with the given settings
    PlaySoundAtEntity(soundName, sounds[rand], atEntity, fadeTime, saveSound);
}

void someFunction()
{
    string[] mySounds = {"Sound1.snt","Sound2.snt","randomSound.snt","Magic.snt"};
    playRandomSound("Random",mySounds,"Player",0.5f,false);
}

//Option 2 is very eloquent. I would edit it to have the sounds play at random areas to give a 3d effect, but I'm afraid of breaking the script :O




Scary footsteps
Ghostly footsteps! You MUST create areas and name them properly, as well as orient them properly, depending on which way you want the footsteps to lead.

Spoiler below!
void OnStart()
{
    AddEntityCollideCallback("Player", "StartFootsteps", "ScaryFootsteps", true, 1); //add to your OnStart()
}

void ScaryFootsteps(string &in asParent, string &in asChild, int alState)
{
    for(int s=1;s<11;s++) AddTimer("step"+s, 0.8 * s, "CreateFootstep");
}

void CreateFootstep(string &in asTimer)
{
    PlaySoundAtEntity("scary"+asTimer, "stepfile.snt", asTimer, 0, false);
    if(asTimer == "step2") {
        //Do some scary stuff
    }
    AddDebugMessage("scary"+asTimer+" played! Oooo", false);
}

//The timer duration 0.8 * s creates a series of timers based on which step it is in the series. This way they happen sequentially, not all at once. You can change the float value coeffcient to your liking. 0.8 is about a medium-pace walk. A good jog will be about 0.7, while a sprint will be at 0.5ish. Tweak them to your liking!

//make sure asTimer (the name of the timer which calls the CreateFootsteps function) MATCHES the area you want to play the step at. In this case, your areas MUST be named "step1", "step2", etc until you reach "step10", just as the timers are named "step1", "step2", etc. There are only 10 steps, because the for loop stops when s reaches 11.

//do some scary stuff. Why step2? I prefer to add a short delay to my scare effects like sanity damage and player sounds. It makes no sense for the player to react immediately when something scary happens. If you time it perfectly, the scare effects will coincide with the real player's (yes, the human being, not "Daniel") reaction, giving EXTRA scare :)



Insanity Hall
This is a function I put together at the request of another user. I may be wrong, but I believe they wanted to create an underwater effect by having sanity constantly drain while the player remained in the area so that the screen remained distorted and warping. This type of composition can also be used to create a neat little insanity hall where the player will constantly lose sanity. Just thought of this idea on whim, use it however you want Big Grin

Spoiler below!
void OnStart()
{
    AddEntityCollideCallback("Player", "InsanityHall", "FuncInsanityHall", false, 0);
}

void FuncInsanityHall(string &in asParent, string &in asChild, int alState)
{
    if(alState == 1) {
        SetLocalVarFloat("init_sanity", GetPlayerSanity());
        AddTimer("start_drain", 0.01, "SanityDrain");
    }
    if(alState == -1) {
        SetPlayerSanity(GetLocalvarFloat("init_sanity"));
        RemoveTimer("drain_loop");
        RemoveTimer("start_drain");
    }
}

void SanityDrain(string &in asTimer)
{
    if(asTimer == "start_drain") return;
    if(GetPlayerSanity() > 20) GiveSanityDamage(5, false);
    AddTimer("drain_loop", 1, "SanityDrain");
}

//feel free to change the values of the damage, timers, etc. I suggest not removing the sanity minimum function. if the player's sanity is low already, they'll pass out in the hall...no bueno :(

//i haven't tested this personally. it may be buggy. I will when I get the chance, I'm working out kinks in my custom models and stuff >_> Give it a shot though :)


(This post was last modified: 04-27-2011 10:28 PM by palistov.)
04-24-2011 01:22 AM
Find all posts by this user
Kyle Offline
Posting Freak

Posts: 910
Joined: Sep 2010
Reputation: 7
Post: #2
RE: Script widgets for new modders!

You might as well copy over the Scripts from over here: Link

04-24-2011 02:11 AM
Find all posts by this user
palistov Offline
Posting Freak

Posts: 1,213
Joined: Mar 2011
Reputation: 57
Post: #3
RE: Script widgets for new modders!

I'm actually checking to make sure what I post isn't on there Smile I'm going to post scripts which you won't find on a wiki or beginner tutorial.

04-24-2011 02:25 AM
Find all posts by this user
MrBigzy Offline
Senior Member

Posts: 616
Joined: Mar 2011
Reputation: 8
Post: #4
RE: Script widgets for new modders!

This shall be dubbed the advanced script thread. Big Grin
04-24-2011 02:36 AM
Find all posts by this user
Kyle Offline
Posting Freak

Posts: 910
Joined: Sep 2010
Reputation: 7
Post: #5
RE: Script widgets for new modders!

I might want to make a request about how to use local and global variables.

I'm used to using something like having an "int x = 0;" and then something happens causing int x to become 1 (x = 1; ) thus causing events to change because x = 1.

(This post was last modified: 04-24-2011 02:38 AM by Kyle.)
04-24-2011 02:37 AM
Find all posts by this user
palistov Offline
Posting Freak

Posts: 1,213
Joined: Mar 2011
Reputation: 57
Post: #6
RE: Script widgets for new modders!

Quote:I might want to make a request about how to use local and global variables.

I'm used to using something like having an "int x = 0;" and then something happens causing int x to become 1 (x = 1; ) thus causing events to change because x = 1.

Ahh I see. Those indeed will serve your purpose, but only within the same function. If you set int x = 0, you will only be able to call "x" in that same function. Local variables, however, you can call anywhere within that same script.

So do SetLocalVarInt("var1", 0); and then you can do all kinds of stuff like

GetLocalVarInt("var1");
AddLocalVarInt("var1", x); //where x is any integer you choose

and combine those with if statements to give you more functionality.

Global variables work the same way, but you need to set up a global.hps file under your custom story's root. In that file you have to put

void OnGameStart()
{
    SetGlobalVarInt("gvar1", 0);

}

Then you can toy with those variables anywhere within the same custom story! Just use

GetGlobalVarInt("gvar1");
AddGlobalVarInt("gvar1", x); //where x is any integer

and also use if statements too! Smile

04-24-2011 02:52 AM
Find all posts by this user
Kyle Offline
Posting Freak

Posts: 910
Joined: Sep 2010
Reputation: 7
Post: #7
RE: Script widgets for new modders!

Thanks! Smile

04-24-2011 03:06 AM
Find all posts by this user
laser50 Offline
Member

Posts: 243
Joined: Apr 2011
Reputation: 0
Post: #8
RE: Advanced script widgets

What is the sound name of the grunt Moaning??? I can't find it Big Grin
(This post was last modified: 04-24-2011 10:06 AM by laser50.)
04-24-2011 09:27 AM
Find all posts by this user
Kyle Offline
Posting Freak

Posts: 910
Joined: Sep 2010
Reputation: 7
Post: #9
RE: Advanced script widgets

(04-24-2011 09:27 AM)laser50 Wrote:  What is the sound name of the grunt Moaning??? I can't find it Big Grin

Sounds-->Enemy-->Grunt--> And then most of the sounds there can be a moaning sound like "amb_idle.snt"

04-24-2011 11:11 AM
Find all posts by this user
teddifisk Offline
Senior Member

Posts: 303
Joined: Dec 2010
Reputation: 2
Post: #10
RE: Advanced script widgets

I cant get the random sound thingy working can anyone post a working script?

04-25-2011 09:10 PM
Find all posts by this user
Thread Closed 




User(s) browsing this thread: 1 Guest(s)