Created VScript : Basic Entity Code Tutorial (markdown)

Blixibon 2020-05-29 11:35:14 -05:00
parent 5e4c101193
commit 18e0ba935b

@ -0,0 +1,213 @@
VScripts are a lot like the I/O system. Like how entities can take inputs, entities also have their own functions that could be "fired" in VScript.
For this tutorial, we'll create a simple script which sets the player's health to the health of a NPC with the name "wyatt". In the I/O system, it would be difficult to get the health of an entity. You may have to use `logic_keyfield` or `logic_datadesc_accessor` *(both are Mapbase entities)* to get the entity's health. In VScript, this is much easier.
---
### 1. Creating a script file
First, go to the `scripts/vscripts` directory of your mod. If that directory does not exist, create it.
Inside of the `scripts/vscripts` directory, create a `.txt` file and change its extension to `.nut`. You can name it anything you want, like `test_transfer_health`. It should not have any spaces.
Open the file using Notepad, Notepad++, or any other text editor.
---
### 2. Adding the code
Inside of this script file, we will add code which finds the "wyatt" NPC by name, gets its health, and then sets the player's health to that number.
First, add `function SetPlayerHealthToNPC()` at the top of the file. This is where all of our code will be written. You can technically use any name for this function, but the name `SetPlayerHealthToNPC` will be used in this tutorial for simplicity.
After you have added `SetPlayerHealthToNPC`, add a `{` on the line below it. Then, add a `}` below that one.
Your file should now look like this:
```squirrel
function SetPlayerHealthToNPC()
{
}
```
Now we will make the function actually find the "wyatt" NPC and get its health.
In between the `{` and `}` lines, add a new line with the text "local wyatt".
```squirrel
function SetPlayerHealthToNPC()
{
local wyatt
}
```
Then, on that same line, add the text "= Entities.FindByName()".
```squirrel
function SetPlayerHealthToNPC()
{
local wyatt = Entities.FindByName()
}
```
`local wyatt` creates a new variable named "wyatt" inside of `SetPlayerHealthToNPC`.
`Entities.FindByName()` is a VScript function which finds an entity in the map by its name, similar to how an output finds an entity and fires an input on it. The `=` makes the `wyatt` variable point to the NPC it finds.
This function takes parameters in between the parentheses, separated by commas. These parameters are similar to what you'd use in an output. To make `Entities.FindByName()` find "wyatt", it must use parameters in this order:
```squirrel
Entities.FindByName(null, "wyatt")
```
The first parameter is used for finding multiple entities of the same name, so we use `null` to indicate that we're looking for the first entity named "wyatt" instead of, say, the second entity named "wyatt".
In the function itself, it would look like this:
```squirrel
function SetPlayerHealthToNPC()
{
local wyatt = Entities.FindByName(null, "wyatt")
}
```
`wyatt` will now refer to a NPC named "wyatt", but if there is no NPC named "wyatt" in the level, the `wyatt` variable will simply be `null`, which means `wyatt` doesn't point to anything.
To make sure `wyatt` actually points to an entity, we use an `if` statement:
```squirrel
if (wyatt != null)
```
Similar to the function, an `if` statement could have its own code which only runs if the statement is true. They can be enclosed with `{` and `}`. In the function itself, it would look like this:
```squirrel
function SetPlayerHealthToNPC()
{
local wyatt = Entities.FindByName(null, "wyatt")
if (wyatt != null)
{
}
}
```
Now that we know `wyatt` is an entity which exists, we can get its health.
First, we'll add a new variable called `health`:
```squirrel
local health
```
Then, we use a `=` followed by `wyatt.GetHealth()`:
```squirrel
local health = wyatt.GetHealth()
```
This gets the in-game health of the wyatt NPC, storing it in the `health` variable.
In the function itself, it would look like this:
```squirrel
function SetPlayerHealthToNPC()
{
local wyatt = Entities.FindByName(null, "wyatt")
if (wyatt != null)
{
local health = wyatt.GetHealth()
}
}
```
Now it's time to set the player's health to this value. This is done in a similar fashion to getting wyatt's health.
In entity scripts, there's always a variable called `player` which refers to the player. It can only be used in SP games, like Half-Life 2.
To set the player's health to our new `health` variable, we just use `player` followed by `.SetHealth(health)`:
```squirrel
player.SetHealth(health)
```
In the function itself:
```squirrel
function SetPlayerHealthToNPC()
{
local wyatt = Entities.FindByName(null, "wyatt")
if (wyatt != null)
{
local health = wyatt.GetHealth()
player.SetHealth(health)
}
}
```
Our code is now complete. `SetPlayerHealthToNPC` searches for an entity named "wyatt" and, if it exists, it sets the player's health to the entity's health.
Now that we've written our code, it's time to access it from the map.
---
### 3. Running the file
Like outputs, an entity can run a VScript file and store its code until the entity is removed.
Entities can run VScript files through a keyvalue (**Entity scripts**) or an input (`RunScriptFile`). Both of these take the filename of the script(s) to run. The extension is optional and you do not need to insert `scripts/vscripts`. For example, if you named your file `test_script.nut` and the file is already in `scripts/vscripts`, then you will only need to use "test_script" as the keyvalue or parameter.
In Hammer, create an entity (e.g. a `logic_relay` or an `info_target`) and use either the "Entity scripts" keyvalue or the `RunScriptFile` input on the entity to run your test file.
---
### 4. Calling `SetPlayerHealthTo85`
When the entity runs the script, it will have the `SetPlayerHealthTo85` function stored and waiting to be fired, similar an output. We need to call that function from somewhere, which would then set the player's health to `85`.
In the I/O system, this can be done by firing `RunScriptCode` on the entity running the script. This input should have a parameter of "SetPlayerHealthTo85()", which will tell the entity to call its `SetPlayerHealthTo85` function.
You can fire `RunScriptCode` with this parameter by using something in the map or by using the `ent_fire` console command in-game.
---
### 5. Testing
Compile your map and load it in-game. Test the `RunScriptCode` input with the `SetPlayerHealthTo85()` parameter. If you followed these steps correctly, the player's health will be set to 85.
If this does not work, check the steps above and make sure you followed them correctly.
---
### 6. Conclusion
You have now written a basic script file which interacts with the I/O system. This tutorial was meant to give a simple interpretation of what VScript can do. The function we wrote was very simple and not very useful alone, but it's a starting point for more complicated logic.
For example, this is the script we used in the tutorial:
```squirrel
function SetPlayerHealthTo85()
{
EntFire("!player", "SetHealth", "85")
}
```
Now look at this one:
```squirrel
function SetPlayerHealthToRandom()
{
local health = RandomInt( 55, 85 )
EntFire("!player", "SetHealth", health)
}
```
This slightly different function, `SetPlayerHealthToRandom`, sets the player's health to a random number in between `55` and `85`.
That is a peek at some of the more complicated logic you can use in VScript, where it actually becomes proper coding. There's even a way to set the player's health without using the I/O system at all.
---
* [Back to Mapbase's VScript Tutorials](https://github.com/mapbase-source/source-sdk-2013/wiki/VScript-in-Mapbase#Tutorials)