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
//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.
//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.
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.
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");
}
//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.
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);
}
//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.
//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
//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 :)
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.
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