User Tools

Site Tools


hpl2:tutorials:script:monsterpathnodes

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
hpl2:tutorials:script:monsterpathnodes [2012/11/11 11:13]
aldarion (i != 1 || i != 10) is ALWAYS true. Replaced wirh correct switch.
hpl2:tutorials:script:monsterpathnodes [2013/06/12 22:15] (current)
yourcomputer [Loops]
Line 1: Line 1:
 ====== Setting Up a Monster ====== ====== Setting Up a Monster ======
  
 +To set up a monster in your custom story, you need to place it in the level editor. Monsters can be found when you click the "​Entities"​ tab and then go to the subsection "​enemy"​. For this tutorial, we'll choose the monster that is called "​servant_grunt"​. Select it and then place it wherever you want. I'll assume you have a least part of your level constructed and know how to make a custom story entirely. Once you placed it, go to the select tool and select the monster you just placed. Under it's name, there will be a checkbox called "​Active"​. Click the checkbox to set the monster inactive. You will notice that the monster is partially "​faded"​ in a sense. We do this so that the monster doesn'​t activate when you start the level.
  
-To set up a monster in your custom story, you need to place it in the level editor. Monsters can be found when you click the "​Entities"​ tab and then go to the subsection "​enemy"​. For this tutorial, we'll choose the monster that is called "​servant_grunt"​. Select it and then place it wherever you want. I'll assume you have a least part of your level constructed and know how to make a custom story entirely. Once you placed it, go to the select tool and select the monster you just placed. Under it's name, there will be a checkbox called "​Active"​. Click the checkbox to set the monster inactive. You will notice that the monster is partially "​faded"​ in a sense. We do this so that the monster doesn'​t exist from when you start the level. +Now go to the tab called "​Areas"​. The area type should say "​Script"​. Click in the level editor on where you want the player to touch for when you want the monster to spawn. Go to the select tool and click on the area where it says "​AREA"​. You will see that it's name is ''​ScriptArea_1''​. It is possible that it could be a different number at the end. Now click on where it says it's name and change it to "​PlayerCollide"​ without quotes. Press enter. Then near the top right corner of the level editor you'll see that there are 3 buttons. From top to bottom they say "​Translate",​ "​Rotate",​ and "​Scale"​. Click on the bottom one that says "​Scale"​. Now scale the script area box to fit whatever hallway or path the player will touch to set the monster active.
- +
- +
-Now go to the tab called "​Areas"​. The area type should say "​Script"​. Click in the level editor on where you want the player to touch for when you want the monster to spawn. Go to the select tool and click on the area where it says "​AREA"​. You will see that it's name is "ScriptArea_1". It is possible that it could be a different number at the end. Now click on where it says it's name and change it to "​PlayerCollide"​ without quotes. Press enter. Then near the top right corner of the level editor you'll see that there are 3 buttons. From top to bottom they say "​Translate",​ "​Rotate",​ and "​Scale"​. Click on the bottom one that says "​Scale"​. Now scale the script area box to fit whatever hallway or path the player will touch to set the monster active. +
  
 ====== Adding Path Nodes ====== ====== Adding Path Nodes ======
  
 +We will now add path nodes to the map so the monster walks from one place to another. When testing/​playing your custom story, the monster will find you if you go too close to it and it sees you. If the path nodes aren't near you, then the monster can't look for you over where you are, but for now we will have the monster walk from one place to another.
  
-We will now add path nodes to the map so the monster walks from one place to another. When testing/​playing your custom story, the monster will find you if you go too close to it. If the path nodes aren't near you, then the monster can't look for you over where you are, but for now we will have the monster walk from one place to another. +Go click on the tab where it says "​Areas"​ and then go to the subsection called "​PathNode"​. Now make a path you want the monster to go to. Try not to put too many of them; Perhaps keep them a meter or two apart. Make sure the monster doesn'​t have to cut corners which could get him stuck. The monster will automatically disappear if it reaches the final path node given to it and the player isn't looking at the monster and the player ​is at least 10 meters away from the monster.
- +
- +
-Go click on the tab where it says "​Areas"​ and then go to the subsection called "​PathNode"​. Now make a path you want the monster to go to. Try not to put too many of them; Perhaps keep them a meter apart. Make sure the monster doesn'​t have to cut corners which could get him stuck. If you make him go up or down some stairs, make sure you put a path node on every step up or down. The monster will automatically disappear if it runs out of path nodes and the player isn't looking at it. +
- +
- +
-Keep track of the last path node you put. If you click on the last one, that is how many path nodes you put. It's name should be "​PathNodeArea_ " with the number of that path node is at the end. +
  
 ====== Scripting It All Together ====== ====== Scripting It All Together ======
  
 +Now you got the monster and path nodes set up. Now it's time to script. We will have the player collide with an area called ''​PlayerCollide'',​ which will activate the mosnter.
  
-Now you got the monster and path nodes set up. Now it'​s ​time to scriptIf the player collides with an area called "​PlayerCollide",​ and, for this example, have ten path nodes with monster called "​servant_grunt_1"​then we can create the script for our monster.+Let'​s ​assume that we have over 10 path nodes in our map, leading to each other, that we want the monster ​to follow''​PathNodeArea_1''​ will be the starting path node, ''​PathNodeArea_5''​ is at the center of an intersection where the monster will make a left turn towards ''​PathNodeArea_10''​which is where we want the monster to come to an end. Each of these path nodes have other path nodes leading to them, each separated no further than 2 meters apart. From ''​PathNodeArea_1''​ to ''​PathNodeArea_5''​ is straight pathand from ''​PathNodeArea_5''​ to ''​PathNodeArea_10''​ is also a straight path.
  
 +With that assumption, we would write our script like this:
  
 <code cpp>void OnStart() ​ <code cpp>void OnStart() ​
  
  AddEntityCollideCallback("​Player",​ "​PlayerCollide",​ "​MonsterFunction",​ true, 1);   AddEntityCollideCallback("​Player",​ "​PlayerCollide",​ "​MonsterFunction",​ true, 1); 
-+} 
 void MonsterFunction(string &in asParent, string &in asChild, int alState) void MonsterFunction(string &in asParent, string &in asChild, int alState)
 { {
- SetEntityActive("​servant_grunt_1",​ true);  + AddEnemyPatrolNode("​servant_grunt_1",​ "​PathNodeArea_1",​ 0, ""​);​ 
- AddEnemyPatrolNode("​servant_grunt_1",​ "​PathNodeArea_1", 2, ""​);​ + AddEnemyPatrolNode("​servant_grunt_1",​ "​PathNodeArea_5",​ 0.001, ""​);​ 
- AddEnemyPatrolNode("​servant_grunt_1",​ "​PathNodeArea_2",​ 0, ""​);​ + AddEnemyPatrolNode("​servant_grunt_1",​ "PathNodeArea_10", 0, ""​);​ 
- AddEnemyPatrolNode("​servant_grunt_1",​ "​PathNodeArea_3",​ 0, ""​);​ + SetEntityActive("​servant_grunt_1", ​true);
- AddEnemyPatrolNode("​servant_grunt_1",​ "​PathNodeArea_4", 0, ""​);​ +
- AddEnemyPatrolNode("​servant_grunt_1",​ "​PathNodeArea_5",​ 0, ""​);​ +
- AddEnemyPatrolNode("​servant_grunt_1",​ "PathNodeArea_6", 0, ""​);​ +
- AddEnemyPatrolNode("​servant_grunt_1", ​"​PathNodeArea_7",​ 0, ""​);​ +
- AddEnemyPatrolNode("​servant_grunt_1",​ "​PathNodeArea_8",​ 0, ""​);​ +
- AddEnemyPatrolNode("​servant_grunt_1",​ "​PathNodeArea_9",​ 0, ""​);​ +
- AddEnemyPatrolNode("​servant_grunt_1",​ "​PathNodeArea_10",​ 4, ""​);+
 } }
 </​code>​ </​code>​
  
 +<​note>​
 +Notice that we have 0.001 for the 5th path node. This is because a wait time of 0 does not mean 0, and 0.001 secs is practically 1 millisecond! We don't want the monster to be spending any time at the intersection,​ and so we have the game waste the least amount possible on the path node.
 +</​note>​
 +<​note>​
 +The parameter for monster animation is practically useless, so we leave it blank.
 +</​note>​
  
-Keep adding more "​AddEnemyPatrolNode"​s if there are more path nodes that you placed and then take away some "​AddEnemyPatrolNode"​s if there are less path nodes that you placed. ​In the Script Functions Page, this is what it says about the "AddEnemyPatrolNode" command: +In the Script Functions Page, this is what it says about the ''​AddEnemyPatrolNode''​ function:
- +
- +
-<code c++>void AddEnemyPatrolNode(string&​ asName, string& asNodeName, float afWaitTime, string& asAnimation);​ +
-</​code>​+
  
 +<code c++>void AddEnemyPatrolNode(string&​ asName, string& asNodeName, float afWaitTime, string& asAnimation);</​code>​
  
 Adds a patrol node to the enemy'​s path. Adds a patrol node to the enemy'​s path.
  
 +//asName //- internal name of the enemy\\
 +//​asNodeName //- Name of path node\\
 +//​afWaitTime //- Time in seconds that the enemy waits at the path node before continuing (remember, 0 does not mean 0!)\\
 +//​asAnimation //- The animation the enemy uses when reaching the path node (this, however, provides no results, so just leave it blank)
  
-//asName //- internal name of the enemy\\  +====== ​Infinite ​Loops ======
-//​asNodeName //- path node\\  +
-//​afWaitTime //- time in seconds that the enemy waits at the path node before continuing\\  +
-//​asAnimation //- the animation the enemy uses when reaching the path node +
-====== Loops ======+
  
 +It is possible to make the monster to follow a set of patrol nodes and never stop repeating them until the monster is disabled manually by ''​SetEntityActive''​ or until the player is out of the monster'​s activation distance. By default, monsters will automatically loop through the path nodes assigned to them, but there are many factors that would cause them to auto-disable before then. Before the release of Justine, people had relied on continuously adding path nodes to the monster while having increased the monster'​s activation distance to a large amount, therefore the monster never reaches the final path node in its memory and so never given a chance to auto-disable and the player is always within its activation distance. Since the release of Justine, we've had the option to disable "​auto-disable on final path node" for the monster. By default, the enemy suitors ''​Basile''​ and ''​Malo''​ have auto-disable disabled for them. In order to do the same for other monsters, you need to manually edit the ENT file for the monster.
  
-It is possible to make the monster to follow ​set of patrol nodes and never stop repeating them until the monster is set disabled manually by "​SetEntityActive("​MonsterName",​ false);"​ With "​MonsterName"​ being the name of the monster. Lets say, from the example above, that the monster follows those 10 path nodes, then reaches another 5 path nodes that he repeats until disabled. When the monster collides with the area "​PNScriptArea",​ he will do the 5 path nodes in a loop The example below will include the "for" loop in which I discuss in another tutorial. Feel free to check it out.+<note warning>​Never modify ​the original Amensia content without first making ​separate copy which you can safely modify ​for your own purposes!</​note>​
  
 +Open the monster ENT in a plain text editor and add the following line under the ''​UserDefinedVariables''​ element:
  
-<​code ​cpp>void OnStart() ​  +<​code>​<Var Name="AutoRemoveAtPathEnd" ​Value="​false" ​/></code>
-+
- AddEntityCollideCallback("Player""PlayerCollide",​ "​MonsterFunction",​ true, 1);  +
- AddEntityCollideCallback("​Player",​ "​MonsterEnd",​ "​MonsterEnd",​ true, 1); +
- AddEntityCollideCallback("​servant_grunt_1",​ "​PNScriptArea",​ "​MonsterFunction2", ​false, 1); +
-+
-void MonsterFunction2() +
-+
- for (int i = 1; i <6; i++) +
-+
-  AddEnemyPatrolNode("servant_grunt_1",​ "​PathNodeArea_"​+i,​ 0, ""​);​ +
-+
-+
-void MonsterFunction(string &in asParent, string &in asChild, int alState) +
-{  +
- SetEntityActive("​servant_grunt_1",​true);​ +
- for (int i = 1; i <11; i++) +
-+
-  int x;+
  
 +Also, look for the variable ''​ActivationDistance''​ and change its value to a large number (e.g. 1000).
  
- switch) +Save the changes, and then add the monster to your level (or replace a previous monster).
-                { +
-                case 0: +
-  x = 2; +
- ​ break;​+
  
 +==== Updating the script ====
  
- ​ case 10: +Let's assume we've replaced the monster with one that doesn'​t auto-disable when reaching the final path node. We would update the script like so:
-  x = 4; +
- ​ break;​+
  
- +<code cpp>void OnStart() ​ 
-  default + 
-  x = 0;  + AddEntityCollideCallback("Player", "PlayerCollide", "MonsterFunction", true, 1); 
-  } +
- AddEnemyPatrolNode("servant_grunt_1", "PathNodeArea_"+i, x, ""​);​ +
- }+
 } }
-void MosterEnd(string &in asParent, string &in asChild, int alState)+ 
 +void MonsterFunction(string &in asParent, string &in asChild, int alState)
 { {
- SetEntityActive("​servant_grunt_1", ​false);+ AddEnemyPatrolNode("​servant_grunt_1",​ "​PathNodeArea_1",​ 0, ""​);​ 
 + AddEnemyPatrolNode("​servant_grunt_1",​ "​PathNodeArea_5",​ 0.001, ""​);​ 
 + AddEnemyPatrolNode("​servant_grunt_1",​ "​PathNodeArea_10",​ 0, ""​);​ 
 + AddEnemyPatrolNode("​servant_grunt_1",​ "​PathNodeArea_5",​ 0.001, ""​);​ 
 + SetEntityActive("​servant_grunt_1", ​true);
 } }
-  
-  
 </​code>​ </​code>​
  
 +<​note>​
 +Since the monster will automatically patrol the path nodes, we don't have to duplicate the line for PathNodeArea_1
 +</​note>​
  
 ====== Tips ====== ====== Tips ======
Line 121: Line 94:
  
  
-    - A Monster can't follow ​the player too far away from their path that is designated ​to them or else they'​ll ignore you and continue on their path. Even the unscripted ​path nodes work.+    - Monsters have difficulty navigating ​the map without ​path nodes. Be sure to place path nodes all over the map, even if you're not going to reference them in your script file.
     - Be careful when placing path nodes for a monster on stairs because if there is one that is missing or not placed right, it'll mess up completely.     - Be careful when placing path nodes for a monster on stairs because if there is one that is missing or not placed right, it'll mess up completely.
 +    - Monsters have difficulty turning corners, so always place a path node at every intersection (and lead the monster there if need be).
     - The Script Function page is your friend! Under "​Enemies",​ there are many things that can be used to "spice it up".     - The Script Function page is your friend! Under "​Enemies",​ there are many things that can be used to "spice it up".
     - Any monster can bash through doors if their path nodes go through it and the box is unchecked for "​DisableBreakable"​ for it.     - Any monster can bash through doors if their path nodes go through it and the box is unchecked for "​DisableBreakable"​ for it.
- 
- 
-**This wiki entry has been made by Kyle S. If you have any comments or need help with this, send me a private message on the Frictional Games Forum. (My name on there is Kyle)** 
  
hpl2/tutorials/script/monsterpathnodes.1352632391.txt.gz · Last modified: 2012/11/11 11:13 by aldarion