MBolus@Posted: Wed Oct 20, 2004 6:46 am :
MBolus Tutorial: Monsters on the Walls, Part 2
(Walking on all walls, floors, and ceilings)

Image

Introduction
Welcome to Part 2 of my tutorial. To the best of my knowledge, this is the first time that the following techniques are being discussed (other than my messages regarding Part 1). I have developed a lot of experience with handling gravity over the past few months, and this will reveal much of what I have discovered. I will include some scripting for those who are interested, although much of it is for extraneous enhancements in Part 2. It is not absolutely necessary to have learned Part 1 first, for it was just a simple introduction to get the information out to you while I made the time to put this part of the tutorial together, and to build a foundation for those who might need it to understand Part 2.

One of the first things you will see in the rudimentary accompanying map is several maggots chasing you as you head for a way out of a quarantine area; one of your options is to use a type of ladder, but that sort of thing doesn't stop the monsters from dynamically pursuing you, and it does not require major coding. In Part 3 I can demonstrate how a monster can walk after you on the floor, climb up the ladder / fence or even the wall after you, and then follow you again on the next floor up, but you can get similar effective pursuits using the methods here, without heavy scripting.

You will also see a bit of pathing in some rooms; I did not yet take the time to fine tune some of the paths, so some errors in pathfinding are permitted for this release so you can get the information earlier. I also use my Monster Cam: for a few seconds you step into the skin of an imp walking down a hallway, with his claws where your hands should be; for a more detailed explanation, just see my nice Monster Cam tutorial!

I will also introduce a simple form of a hybrid type of creature the Imptruger, with just a few .def files for you to put into your def directory in the base directory (you may prefer another location, but that does the trick). After you also place my .map and .script files into your maps directory in the base directory, just restart Doom 3 and enjoy. (v.02 of the .rar can just be unrar'ed into your base subdirectory of your Doom 3 directory, and everything should go into its place, but the above info helps in case of errors during extracting with WinRAR or whatever you use).

By the way, you can replace the mutant type of imp with a regular one in the editor, if you don't like him. You will get just a few errors handling the Magtruger, but that should be no problem just to check it out; I haven't finished it yet, but it is soooo cute I couldn't leave it out. As you will see, for now I just defined its chest as a head_joint. I might later release a version of the map without these creatures, and maybe a version set up like pk4 etc., so you are welcome to wait until then, as the meat of the info is here in the text.

You will be able to download the file containing the .map, .script, and .def files from any of the sites listed below:

/*
http://www.doomcentral.net/hosted/MBMonsWallPart2.rar
http://www.mnemic.tk/education/writtentutorials/files/MBMonsWallPart2.rar
*/

Image

GravityDir
As I have been indicating on Doom3World.org for a while now, a great way to alter a monster’s sense of gravity is to enter a value for its key gravityDir. In my map you will see many examples of different values for gravityDir along with their effects. A value of 0 allows free floating. Any trailing zeroes in the vector can be omitted, and some of my scripting makes use of this feature which simplifies certain scenarios. For example, -.5 bases a monster on west surfaces, and permits it to jump very far from the wall. 0 .75 .75 lets it hang out on the north wall and the ceiling, as it is not attracted to an x direction but is somewhat attracted to positive y and z. Very high and low ranges can be used. The following chart shows the direction of attraction for each component of the vector:

Code:
    0     0    +z    ceiling

    0    +y     0    north walls

   +x     0     0    east walls
      
    0    -y     0    south walls

   -x     0     0    west walls

    0     0    -z    floor

   Essentially infinite combinations of values are possible


Scripting
There are multiple ways to script dynamic changes in gravityDir, e.g. for going around many corners, or even for jumping from one wall to its opposing surface. One way is to use a trigger which calls a function. It is easy enough to write more complex scripts, but I will start with a simple generalization for Part 2, which is a bit better than that in Part 1.


Code:
void reverse_monster_gravity (entity ent_mon_this) //reverse the x component of gravityDir for appropriate scenarios
{
string mon_class ;                 //className
string mon_gra ;                   //gravityDir
float mon_gra_len ;               

   sys.copySpawnArgs(ent_mon_this); //copy a lot of the spawn arguments
   sys.setSpawnArg("origin",ent_mon_this.getWorldOrigin());
   mon_class=ent_mon_this.getKey("className");    
//   sys.setSpawnArg("name",ent_mon_this.getName());       //if desired
   mon_gra=ent_mon_this.getKey("gravityDir");
   mon_gra_len=sys.strLength(mon_gra);      

   if(sys.strLeft(mon_gra,1)=="-"){
      mon_gra=sys.strRight(mon_gra,mon_gra_len-1);
   }
   else{
      mon_gra="-"+mon_gra;
   }   

   sys.setSpawnArg("gravityDir",mon_gra);                 //insert the new gravity
   ent_mon_this.remove();
   ent_mon_this.waitFrame();
   sys.spawn(mon_class); //spawn with updated settings, including gravity
}



Code:
void rev_imp_14w()             //reverse gravity for a specific entity
{
   if (sys.random(6)<2){
      reverse_monster_gravity($monster_demon_imp_crawler_14w);       //pass to reverse_monster_gravity
   }
}


Part 1 shows multiple editor screen shots, for those who are interested. I may add more images to Part 2 later, when time permits.

As you can tell, this is not a finished map, and I plan to update it including some improvement in speed, textures, and more. For example, I may remove some glass and monsters as I test it on a variety of machines. (I don't yet need messages in the thread mentioning these things, although feel free to PM me.) My machines run it well so far, but this is still a rough draft that I will still be smoothing out. You will find much extra code in the .script file for similar reasons.

... more next time!
(EDIT: added URLs for map)

Image



MNeMiC@Posted: Wed Oct 20, 2004 8:37 am :
This sure looks interesting, I'm gonna host the file ASAP when I get back from school.



Necrotoxin@Posted: Thu Oct 21, 2004 3:16 pm :
I've messed with this, but without scripts it just doesnt look natural. Like in Aliens vs. Predator, 1 or 2, the alien crawls all over the place, but in doom it just doesnt work that way. (There's just something not right about killing something on the ceiling and it falls to the ceiling. I'd like to see an AvP 3 in the Doom 3 engine or a Justin Fisher's remake of Aliens TC for Doom 1 in Doom 3)



MBolus@Posted: Fri Oct 22, 2004 1:32 am :
MNeMiC wrote:
This sure looks interesting, I'm gonna host the file ASAP when I get back from school.

Okay, I can add the url to the tut when you get it on your site!

Necrotoxin wrote:
I've messed with this, but without scripts it just doesnt look natural. Like in Aliens vs. Predator, 1 or 2, the alien crawls all over the place, but in doom it just doesnt work that way. (There's just something not right about killing something on the ceiling and it falls to the ceiling.

In my tutorial and map, they crawl between the walls, ceiling, and so on. Also, check out the Pinky on the ceiling in the Relaxation Room of the North Administration area: it is very natural, including its interaction with the ceiling Wraith. In some of the areas I do make it less natural, so you can see some of the control or pathing you can exert. Although Part 3 will be even better, Part 2 already achieves quite a bit without getting that deep and heavy.

Necrotoxin, if you shoot my ceiling creatures, they will fall to the ground as they should. Check it out!



MNeMiC@Posted: Fri Oct 22, 2004 10:32 am :
http://www.mnemic.tk/education/writtent ... lPart2.rar



Sloanbone@Posted: Fri Oct 22, 2004 12:08 pm :
http://www.doomcentral.net/hosted/MBMonsWallPart2.rar

http://www.doomcentral.net/tut1.php



pbmax@Posted: Fri Oct 22, 2004 1:03 pm :
mbolus, i have a question for you...

when you copy the spawn arguments of an imp, remove that imp and then respawn another imp (using most of the copied spawn arguments), do the animations line up correctly between the two???

for example, if it was in the middle of tossing a fireball at you, and you replace it with a new imp, does the new imp continue to throw the fireball at you as if nothing happened???



MBolus@Posted: Sat Oct 23, 2004 5:07 pm :
pbmax wrote:
mbolus, i have a question for you...when you copy the spawn arguments of an imp, remove that imp and then respawn another imp (using most of the copied spawn arguments), do the animations line up correctly between the two???
for example, if it was in the middle of tossing a fireball at you, and you replace it with a new imp, does the new imp continue to throw the fireball at you as if nothing happened???

Strictly speaking, the lineup can be imperfect if you use that simple method. What I have found is that you should explicitly specify args that absolutely must be updated since the previous spawn. Let me know how it works with your project, but you normally won't have to do a setSpawnArg for certain things like:
attack_cone
cinematic (e.g., for visibility with Monster Cam or other cameras)
name
on_activate
ragdoll (but you could change this if you want)

I do a setSpawnArg for origin after doing a getWorldOrigin on an entity that I am replacing. If you don't set the anim and frame it might not get noticed, but be aware that merely using copySpawnArgs will leave those as they initially were.

On a similar subject, I am about to test health, and anticipate a getHealth and setHealth or setSpawnArg or similar combination would be useful for it.