BigTruck's Fan Page

BOD Python Scripting

07 - Controling Enemies

Once you have your enemy, he is free to do and go wherever he likes. He will chase you all around the map. You may not always want this.
Enemies will react to sounds and go off exploring to investigate sounds. Because of these things it is a good idea to try and control their behaviour.

Most enemies are 'hidden' until needed. Do this directly after they are created with:
darfuncs.HideBadGuy("Ork1")
Remember to import the darfuncs file. This file is in the Lib folder.
Browse though some of the files you have imported so far. You can start to see how things work this way. darfuncs has a lot of useful functions in it. btw. You may have noticed in the Lib and Scripts folders a lot of files with the extension *.pyc. When a file is imported, Python makes a copy of it in compiled machine-readable code in order to read it faster. Later, when some of your own files need to be imported, you will see these .pyc files appearing in the installed copy of your map in the main Severance/Maps/MyMap folder.
You need pay no attention to these files. They look after themselves.
You don't need to include them in the release version of your map.

Ok you have hidden your Ork. He and his weapons will be totally invisible and he will not react to anything. To 'unhide' him use:
darfuncs.UnhideBadGuy("Ork1")
This call wil be contained in a function in your DefFuncs file, waiting for the event that triggers it.
			def UnHideOrk1():
				darfuncs.UnhideBadGuy("Ork1")
one function can do more than one thing...
def UnHideOrkGroup1():
	darfuncs.UnhideBadGuy("Ork1") 
	darfuncs.UnhideBadGuy("Ork2") 
	darfuncs.UnhideBadGuy("Ork3") 
	darfuncs.UnhideBadGuy("GreatOrk6")
What you are doing is using a function to call other function(s). These functions in turn will call others and so on.

When the Ork is unhidden, he will be instantly visable and come out fighting if he sees you. You have to arrange things so that the event that unhides him happens when the Player cannot see the place where he is hidden. This event is usually a trigger sector. Sectors are coded in the engine to raise an event when anything enters or leaves them. A function can be assigned to these OnEnter and OnLeave events.
I'll come to this later. Also the unhide function call can be tagged on to other functions such as the opening of a door. This way, opening the door will unhide the Ork standing on the other side.

Now you are writing functions, a bit more theory. In most cases functions are always put in DefFuncs file. Don't put them in the .p y files that you use to create stuff and don't create stuff in the DefFuncs file (unless within the body of a function). Doing these things will not affect anything in a 'live' game, but will certainly foul things up in a saved game. Keep testing the savegame as you proceed. It can be a nightmare to sort out savegame bugs when you have a lot of code.

You made have noticed that some code is indented in the functions. This is part of the Python structure. It is important to be consistant with your indentation. One space is enough but using a Tab makes the code easier to read. You can use any text editor to write code. Notepad is OK, but as your files get bigger Windows will eventually tell you that the file is too big for Notepad and would you like to use Wordpad? A word of warning here. Wordpad is Ok but is not ideal. I have had trouble using Wordpad. Even if you stick to plain text it can foul up the code and I have had perfectly sound code that won't work due to some invisible formatting introduced in Wordpad. If you are going to do some serious coding, get a proper code editor.

Back to the map. You have probably noticed in the game that some enemies have their own small territories. If you enter a certain area they will come and attack you but if you back off they abandon the attack and retreat. This is a nice feature to stop enemies wandering off and getting lost. To do this, you need to define action areas in the LED. An enemy needs two contiguous areas: Primary and Secondary.
You start him in the Primary area. He will venture into the Secondary area only to attack the Player, as long as the Player is in the Secondary area. Move out of Secondary area and the enemy will retreat.
(He may stand there making obscene gestures, but will not chase you.)

To set these areas in LED, select a sector (or group of sectors). Goto properties window and scroll along to the 'Groups' tab. You see 32 little tick boxes. Like a lot of things in LED they are not logically numbered from 1-32. Past 9 you have to count them but they do represent 1-32. Tick box 1 and press Enter in the usual fashion. Next. Select any sectors around the Primary one(s) that you want to use as the Secondary area. Tick box 2 in the Groups box, press Enter. You need to recompile the map for these groups to work.
A few observations here... You will realise that only 16 areas are possible. It may be that if another area is far enough away that you can repeat the groups numbers but I have never proved this. Make sure all the Secondary sectors join the Primaries. Don't leave even small gaps. Also beware sectors that are spilt horizontally so that an enemy has his feet in Primary area and head in an unassigned one above. They do not like it. In any case, try to avoid this arrangement of sectors in any places wher you intend to stage fighting. It can confuse enemy pathfinding and I have noticed that with Chaos Knights it can stop the using attacks altogether.
As with slopes, any moves you layer make to sectors that have action areas defined can cause the settings to be lost. If you move any of these sectors, check the AAs again.

Alright, you have your map recompiled with an action area. Create your enemies in the Primary area. Now you have to tell them where their own patch is. Add this code after creation code for area 1-2:
			ork1.ActionAreaMin=pow(2,0) # Prim
			ork1.ActionAreaMax=pow(2,1) # Sec
(** to use the pow func in the math file use:
from math import pow
You will notice something peculiar here. The 2nd arg is the area but I have 0 and 1, not 1 and 2. This is back to the Python counting from 0 not 1 thing. Basically, whatever group number you assigned to a sector, represent it in the scripts by a number 1 less.

If you have a lot of areas, make a note in the enemies file.
			# MainArena pri 1
			# MainArena sec 2
etc....

* you may notice in scripts a lot of ######s Putting a # at the begining of a line makes it 'invisible'. Python will ignore it and anything that follows it om the same line. It is called a 'comment' in code terminology. This way you can add notes (or comments) to your code. Also useful for temporarily disabling lines of code when debugging. If you want to add a lot of notes in a block or disable a lot of lines, add triple quotes at begining and end:
			"""
			lot
			of 
			lines
			here
			....
			....
			"""
Python will skip the bit between the """s

Ok, now test the action area. If you have archers up on high walls, AAs are essential to stop them trying to jump off. Even so, archers sometimes do fall. (There is a Knight in the Temple map who regularly does this. Once he his out of his AA he will go into a trance and try in vain to get back to his Primary AA.)