Okay, here we are again, ready to fill our heads full of more scripting fun! This time around I won't treat you like utter newbs by highlighting every little important word and hoping that it'll sink in. I believe we've moved beyond the need for that, how 'bout you?
Alright, I think we now have the skills and scripting common sense to make a script of our own!
I decided that I don't like the current script for the Automed they give us in the scifi section. I want it more like the Med Units in Half-Life. So in today's lesson, we're gonna come up with a script that will do the following:
- Give the player health, 1 unit at a time
- Continually give health as long as the player has the Use Key held down
- Loop a sound while the med unit is giving health
- Won't give the player more health than they are supposed to have
- Will ONLY give up to 100 health to the player before "running out" (This will keep the player from camping the automed device and being immortal)
Okay, let's get right to work!
Tutorial #3:
"Half-Life AutoMed"
First things first, we want the automed to give health. So let's look in our trusty manual and find an action that'll do that for us. After a little searching I found this action that will do just nicely:
plraddhealth=X
This action will give the player an amount of health equal to X. So if we want to give the player 10 health right away the action would read "plraddhealth=10". Simple, right? ... Right.
Okay, we also want this thing to loop a sound while it's pumping our players full of med dopamine. Let's see, the manual says that this action will do the trick:
loopsound=X
Sound actions can work in two different ways. Just like the "sound=" action that we covered in Tutorial 2, where X would equal "$0" or "$1" and we would put the sound in the entity's properties. But any sound action can also be given a specific path to a sound file!
Remember, the engine assumes that the current directory is the "Files" directory. So, in general the current directory would be the "C:/Program Files/The Game Creators/FPS Creator/Files" directory. From there we would be able to give it a specific path to any sound in the "audiobank" folder.
Example would be: "audiobank/items/healthup.wav"
Alright, so now we know the commands to give the player some health and to loop a sound. What about when the player decides they had enough health for now and stop pressing the Use Key? Or when the unit runs out of that fine dine health serum? We gotta stop that sound or it'll just keep on loopin'!
Welp, the manual doesn't have this action listed so I'll fill you guys in. In order to "stop sounds" the command is:
stopsound
And it does exactly what it sounds like. No values needed. Just use that action and your looping sound will stop. Hurray!
Let's start up our script!
Open a new Notepad file and type this in:
;The Half-Life Automed Unit, Tutorial #3
;Header
desc = AutoMed Station
;Triggers
Well, let's start brainstorming for a minute on how we're gonna do this.
First, we need to see if the player is in range of using our AutoMed. After all, we don't want them to be accessing free bodyjuice telepathically from the basement when our AutoMed is on the top floor! Let's say if the player is within 100 units (1 segment width) then they can use it.
So to start off let's put in a condition to check for the "state" variable at 0 (Since it just came into being and check for the player being within 100 units. The line should look like this so far:
:state=0,plrdistwithin=100
Don't put in the Action Colon just yet, we still have more things to check for!
If we left it like that and started pumping out sweet syringical goodness then the player would need only run up to the automed and it'd start doing it without the player pushing a button! Well, you could do that if you want, just leave off this next piece:
Check for the player pushing down the Use Key. You remember that condition, right? That was in Tutorial #2 for flipping the light switch! Same deal here, we'll use the "plrusingaction=X" condition! Now, we want to know if they ARE pushing it so X would be equal to "1", right?
So after we put that in our line looks like this:
:state=0,plrdistwithin=100,plrusingaction=1
Hmmm, welp, that sounds good for right now. If all those conditions are true, then we need to give the deserving player some lovin'! And by that, I mean health.
Put in the Action Colon now so we can move onto executing some actions.
We said we wanted to give health to them 1 unit at a time, so we'll use the "plraddhealth=X" action where X is gonna equal "1".
We also said that we wanted to loop a sound while the player was getting their health, se we'll use the "loopsound=X" action.
I took a listen at all the sounds in the audiobank and I thought that the "acidhum.wav" sounded the best for my health looping purposes. You may not think so, so if you'd like you can go find a sound more suitable to your needs.
The file I wanted is in the "audiobank/atmos" directory.
Adding those two actions onto our first line we should have what looks like this:
:state=0,plrdistwithin=100,plrusingaction=1:plraddhealth=1,loopsound=audiobank/atmos/acidhum.wav
Awesome, now when the player gets in range of the Automed and presses (and holds) the Use Key, they'll get health and hear a cool looping sound to boot!
But wait, we can't run this just yet. What was that other command we just learned about? The one NOT in the manual? That's right, we gotta stop the looping sound when the player's not gettin' anymore health!
So when should we stop the sound? When the player isn't using the Automed anymore, right? ...Right!
Let's make a new line and check for the player NOT pressing the Use Key. Then in our Action List we'll just tell the sound to stop. We'll get something looking like this to start with:
:state=0,plrusingaction=0:stopsound
Okay, just using those two lines our Automed will work! But, unfortunately, it won't work the way we want it to.
What's wrong with it? Well, let's take a moment to "idiot proof" our script, as it's said in the professional realm.
Q. What if a player were to walk up to our Automed, hold down the Use Key, then walk away from it?
A. The player would stop getting health, but the sound would not stop until the player released the Use Key!
That's a problem, as it makes our Automed very amateurish. So, let's make a new line that will check for the player being further than 100 units from our Automed and then stop the sound if they are.
Well, we haven't yet covered how to detect if the player is FURTHER than a certain distance from the entity, so let's look in the manual.
The manual gives us this condition to detect if the player is FURTHER than a certain distance from the entity:
plrdistfurther=X
Yes, it is very self-explanatory. Use this condition to find out if the player is further than X units from the entity.
Let's use that condition and finish up our line of code to get something that looks like this:
:state=0,plrdistfurther=100:stopsound
Great! Now the sound will stop when the player runs away from our Automed! Problem solved.
Using just what we have now, we'll discover yet another set back, but nothing us scripters can't handle!
Q. What's wrong now?
A. The player can indeed use our Automed to get health and the sound is just perfect, but the Automed doesn't STOP giving us health!
How do we get around this? Well, we'll need a way to keep track of how much health our Automed has given the player overall. To do this, we'd need a "variable". Now I know what some of you expert scripters are probably thinking. "But the only way to get variables is to use empty's mod or to modify the source code ourselves in V1.0!!!"
Wrong! I do recall that I've used the term "variable" to describe TWO things thus far. Can anyone tell me what they are?
You guessed it, class! The "state" and "active status" variables!
Those will allow us to stick in whatever numbers we want and to detect what number they are! But, only one of those will fit the bill, so to speak. We need to INCREMENT our variable by 1 every time the player gets 1 unit of health!
Hmmm, this poses a problem, so let's reference our manual and see what we can dig up.
*rummages through the manual for a second*
...
AHA!!! The manual says that we are allowed to increment the script's "state" variable by any amount that we want! But we're already using the "state" variable, aren't we? Yes, indeed we are, but it's not serving us any purpose right now. If you notice, we don't DO anything with it except check for a "state" value of "0"!
I smell a sneaky under-handed technique coming on, don't you?
Okay, let's see what we have so far in terms of code:
;The Half-Life Automed Unit, Tutorial #3
;Header
desc = AutoMed Station
;Triggers
:state=0,plrdistwithin=100,plrusingaction=1:plraddhealth=1,loopsound=audiobank/atmos/acidhum.wav
:state=0,plrusingaction=0:stopsound
:state=0,plrdistfurther=100:stopsound
I think that's it... well, since we would like to use the "state" variable for our counter, let's delete all the conditions checking the state variable.
That'll give us:
;The Half-Life Automed Unit, Tutorial #3
;Header
desc = AutoMed Station
;Triggers
:plrdistwithin=100,plrusingaction=1:plraddhealth=1,loopsound=audiobank/atmos/acidhum.wav
:plrusingaction=0:stopsound
:plrdistfurther=100:stopsound
Good, now we are free to use the "state" variable as we please.
We know that it starts with a value of "0", which is good because at the beginning our Automed has not given the player any health.
What was the action in the manual for incrementing the "state" variable?
Oh yeah:
incstate=X
We use this action by replacing X with how much we would like to increment the "state" variable.
Well, we want to increment it by 1 every time the player gets 1 unit of health, so let's use this action next to where we give the player 1 unit of health in our first line of code.
Just stick it in the list and your first line should now look like this:
:plrdistwithin=100,plrusingaction=1:incstate=1,plraddhealth=1,loopsound=audiobank/atmos/acidhum.wav
Now, our "state" variable will always be equal to how much health the player has drawn out of the Automed.
All we gotta do now is check for when the "state" variable has reached the maximum amount of health that can be drawn out, then stop the player from getting any more... cuz we're greedy like that. lol
We said we wanted the player to only get 100 units of health out of our Automed, so...
add a new line of code at the bottom of our script that will check for the "state" variable being at a value of 100.
Now, we need to think of some way to keep the player from getting more health out once it has reached this much...
Well, we still have one variable left, why don't we use it as a flag that says "No more health for mister player."
Our "active status" variable will be our stopping flag, so when it equals "0" (like it does when the game first starts) the player can draw out health, and when it equals "1" the player WON'T be able to draw out more health.
So, in our Action List, let's set the "active status" to "1" on this line of code.
How do we do that? We haven't covered how to make a script set it's OWN "active status" variable! Manual time!!
...
Okay the manual gives us:
activate=X
This will set the current script's "active status" to X. So let's put it in:
Let's also increment the state ONE more time so the engine isn'y constantly running this line of our script and lagging us down just a tad.
:state=100:activate=1,incstate=1
We're forgetting something else... what is it? Hmmmm... oh right! We need to stop that looping sound as soon as our Automed runs out of health!
:state=100:activate=1,incstate=1,stopsound
And last but not least, we need to check that the "active status" variable is "0" in our earlier lines of code! That way the player only gets to have health if our Automed hasn't already given them 100 units of goodness!
So, let's go back and put in a condition to check for that in our first three lines of code!
What we should have so far will look something like this:
;The Half-Life Automed Unit, Tutorial #3
;Header
desc = AutoMed Station
;Triggers
:activated=0,plrdistwithin=100,plrusingaction=1:plraddhealth=1,loopsound=audiobank/atmos/acidhum.wav
:activated=0,plrusingaction=0:stopsound
:activated=0,plrdistfurther=100:stopsound
:state=100:activate=1,incstate=1,stopsound
Alright!!! Now our automed is smart enough to limit our little drug...I mean, health addict players!
But something isn't quite right. We are ALMOST there, it's just that we still need one little thing. As it stands right now our players can go over their maximum health using our Automed!!! That's not good.
Let's go back to our first line of code and put in a condition for if the player has less than their maxmimum health. In my game, the player has a maximum of 500 health, but yours may be different.
Wow, yet another command we haven't covered before! How do we detect if the player has less than a certain amount of health? Guess it's back to the manual for us.
Alright, I dug up this condition from our trusty little paperback:
plrhealthless=X
This condition will be TRUE if the player has less than X units of health. Let's put it in:
:activated=0,plrdistwithin=100,plrusingaction=1,plrhealthless=500:plraddhealth=1,loopsound=audiobank/atmos/acidhum.wav
And now, we also have to turn off the looping sound if the player happens to hit their maximum health before the Automed runs out. So let us insert a new line of code before the last line, just to keep it organized.
In this line we're going to check if the player is able to pull out more health ("active status" variable is "0") and if the player has their maximum amount of health. Problem here is there doesn't seem to be a condition for detecting a specific amount of health! Well, we're clever little scripters and we know that we can just detect if the player has health greater than 1 unit LESS than their maximum amount of health.
What does that mean? In my player's case, I'm going to detect if they have MORE THAN 499 units of health.
The manual says we can do that using this condition:
plrhealthgreater=X
And just like it's brother condition, X is going to be the value we are checking against.
When we put in our line it should look like this:
:activated=0,plrhealthgreater=499:stopsound
Wait... wait a minute. What's this?!? Are we...? Yes! We are!!!
We're done!!!
After all that scripting and thinking we came up with a script that probably looks similar to this:
;The Half-Life Automed Unit, Tutorial #3
;Header
desc = AutoMed Station
;Triggers
:activated=0,plrdistwithin=100,plrusingaction=1:plraddhealth=1,loopsound=audiobank/atmos/acidhum.wav
:activated=0,plrusingaction=0:stopsound
:activated=0,plrdistfurther=100:stopsound
:activated=0,plrhealthgreater=499:stopsound
:state=100:activate=1,incstate=1,stopsound
If you'd like you can comment on the end of the script, but it isn't necessary.
[EDIT]
Now, go to File->Save As... and save this file as a ".fpi" type file. To do this in Notepad, change the dropdown box near the bottom labeled "Save as type" to read "All files", then just put the ".fpi" at the end of what you'll name it.
I decided to name mine "MyAutoMed.fpi" so that I'll know what it is later on.
[/EDIT]
When we put this script into the "Main AI" of our Wall-mounted med kit provided to us by TGC, it will function just as we initially intended it to!
NOTE: The wall-mounted medkit seems to be a little fritsy and so, I would suggest turning the "Physics On?" property to "No". When I didn't do that, it flew off the wall as soon as the game started, lol!
This concludes Tutorial #3, The Half-Life AutoMed! Made by Us.
Now get out there and show me what you're made of!
The one and only,
~PlystirE~
Dammit, Jim! I'm a programmer not a graphic designer!!!
(P)suedo code (L)inguist, (Y)ou (Sti)ll (R)eap (E)verything