Battlegen Instructions

 

1. Decide which an8 file you are going to use

2. Go to setup->files, and open the file you are going to use

3. Click hide me.  This screen doesn’t do much, but you have to load the file.

4. Go to setup-> types, and setup the types to go along with the figures you just loaded

5. With each type, make sure you type the figure name right, or else it will get an error when you hit apply.

6.  Go to setup->positioning, and follow the instructions given at the top of the screen once you select a type to position

7. Now it is time to code.  If you have experience programming with objects, go to “instructions for people with experience”.  Otherwise, go to “instructions for people with no experience”.  For those with no experience, it would be good to read through the instructions for people with experience eventually, to get the hang of things.

 

Instructions for people with Experience

 

The battlegen structure is essentially a loop that runs x times, where x is the number of frames desired.  At every loop, there is a counted loop that runs through an array of avatars, which is a class that contains the position and data relating to that object.  Within each loop, the code contained in Avatars(x) is loaded into a MS Scriptcontrol, and the code is executed. 

 

Inside the code, the current avatar is called thisguy, and he can only see the world around him as described by the functions available in battlegen.  Some of these will return values telling you what array element of avatars is the closest to thisguy, some will tell you the distance to the closest array element of avatars.  Some will format a keyframe so that you can make thisguy move about.

 

 

 

When designing the code, you must think: “If I were in this guy’s position, and knew this data, what would I do?”  You could call a function that tells you how far away the closest enemy was, and act on that.  If the closest enemy is very close, then you may want to execute a melee attack.

 

 

For somewhat less experienced people, and code explanations for all.

The avatar class saves the an8 code generated during the program in 3 strings within the class.  The strings are posoutput, seqoutput, and faceoutput.  They are compiled by the program into the proper positions in the an8 file once the loop is done.  All you have to worry about is putting your animation, movement, and face information into them.  To do this, all you have to do is concatenate the output from a movement, animation, or facing function onto the strings.

 

Ex: (to run the animation “attack”, at frame 30)

 

thisguy.seqoutput = thisguy.seqoutput & dosomething(“attack”,30)

 

This code will create a keyframe in an8 code that will cause the figure currently occupied by thisguy to run its “attack” animation at frame 30.  To make this more applicable in a battle sense, you could do this:

 

if disttoclosest(thisguy.mynum, 2) < 10 then

            thisguy.seqoutput = thisguy.seqoutput & dosomething(attack”,thisguy.whatframe)

            thisguy.faceoutput = thisguy.faceoutput & FaceClosest(thisguy.mynum,thisguy.whatframe,2)

end if

 

This code reads as: “(first line) If the distance to the closest member of team 2 is less than 10 units then (second line) run my attack animation at the current frame, and (third line) face the closest member of team 2 at the current frame.”  Thisguy.whatframe is a variable that you must increment by one every cycle, or animation will be difficult.  Thisguy.mynum is a number that is automatically set by the program that identifies the characer and allows the function to know which character it is dealing with at the moment.  So, a complete program would be this:

 

1: sub main

2: thisguy.whatframe = thisguy.whatframe + 1

 

3: if disttoclosest(thisguy.mynum,2) < 10 then

4:         thisguy.seqoutput = thisguy.seqoutput & dosomething(attack”,thisguy.whatframe)

5:         thisguy.faceoutput = thisguy.faceoutput & faceclosest(thisguy.mynum,thisguy.whatframe,2)

6: end if

7: thisguy.xpos = thisguy.xpos + 5

8: thisguy.posoutput = thisguy.posoutput & outputloc(thisguy.mynum,thisguy.whatframe)

 

9: end sub

 

Line 1: This is required so that VBScript knows where to start executing code

Line 2: This increments thisguy.whatframe each frame so that you can simply keyframe things by entering it as the current frame

Line 3: This says “if the closest member of team 2 is less than 10 units away then execute all statements between here and ‘end if’”

Line 4: This is the first action taken if the enemy is close, and makes the attack animation of the figure play

Line 5: This is the second action taken, and makes the figure face the closest member of team 2

Line 6: This ends the if statement, and all code after this is executed regardless of the result of the if statement

Line 7: This makes thisguy move ‘right’ relative to the front view

Line 8: This keyframes thisguy, so that his movement is actually recorded in anim8or

Line 9: This tells VBScript that we are done for this guy, so it moves onto the next.

 

If you want to copy/paste this code into battlegen, you must remove the line labels, including the :

Let’s say that this code was put into a ‘marine’.  The marine will increase his x co-ordinate by 5 units every frame, and keyframe himself every frame.  If he comes within 10 units of a member of team 2, then he will attempt to run his attack animation, and will face the enemy.  By default, all units face the origin of the scene (0,0,0), so you will want to have them facing something.  There is a function available that makes them face the direction they’re moving, but you have to use the xvel, yvel, and zvel variables to allow it to work.

 

Function List (explanations of variables at bottom)

 

  OutputLoc(myNum, whatFrame) As String – this outputs a keyframe corresponding to the position of the character

  DoSomething(doWhat, whatFrame) As String – this keys a sequence in the character’s scene, at the specified frame

  FacePos(myNum, whatFrame, xPos, yPos, zPos) As String – this keys the character to face a point in 3D space at the specified frame

  FaceContact(whatC, whatFrame) As String – this keys the character to point at a specified other character

  MoveToClosest(myNum, byWhen, whatTeam) As String – this makes a keyframe that moves the character to the closest member of whatteam by the specified frame

  FaceClosest(myNum, byWhen, whatTeam) As String – this keys the character to face the closest member of whatTeam by the specified frame

  FaceDirection(myNum, whatFrame) As String – this keys the character to face the direction it is moving (according to xvel, yvel, and zvel) at the specified frame

  FaceTargetOnGround(myNum, whatC, whatFrame, floor) As String – this makes the character face another character in 3D space, although thisguy will only pivot on it’s y-axis.  Useful for artillery, etc. that you don’t want to be pointing all over the place.

 

  GetCX(whatC) As Double – gets the x-co-ordinate of the specified other character

  getcy(whatC) As Double – gets the y-coordinate of the specified other character

  getCZ(whatC) As Double – gets the z-coordinate of the specified other character

  GetCT(whatC) As Long   - gets the team number of the speicifed other character

  DistFromMe(myNum, whatC) As Double – gets the distance from thisguy of the specified other character

  WhoClosest(myNum, OnTeam) As Variant – gets the ID# of the closest member of a specified team to thisguy

  Attack(whatC, Damage) As Boolean – subtracts a specified amount of damage (thisguy.damage) from a specified other character.  Returns true if an attack killed someone.  So, “if attack(<enemy id#>, 10) = true then”

  DistToClosest(myNum, whatTeam) As String – returns the distance in units to the closest member of a specified team

  MovetoRandom(byWhen, whatTeam) As String – makes thisguy move toward a randomly selected member of a specified team by a specified frame

  OneToTen() As Long – generates a random number between one and ten

  MoveContactToMe(myNum, whatC) – moves a specified character to the position of thisguy

  SetOtherSpeed(xVel, yVel, zVel, whatC) – sets the x,y,and z velocities of a specified character

  SetOtherMiscData(whatC, whatDatNum, whatData) – sets a specified miscdata component of a specified character to a specified value

  ExplodeMe(myNum, Radius, Damage) As Boolean – creates a sphere of damage at thisguy’s location.  For an explosive shell, perhaps?  Like attack( ), returns true if you killed anybody

  Randz() As Double – returns a truly random number

 

myNum – for any function that takes mynum as a parameter (a parameter is a thing in brackets), simply type ‘thisguy.mynum’ (without quotes)

whatC – the ID# that corresponds to the player you want to interact with.  Used on functions that modify/retrieve data about other characters in the battle

OnTeam/WhatTeam – the team number.  Usually used to search for the closest member.  So, you would usually put in the team number of the opposing side.

byWhen/whatframe – usually for this, put ‘thisguy.whatframe’ (without quotes).  The definition is that this is the frame number that goes beside the keyframe.  So, if you always want a keyframe at frame 30, you CAN put 30 in for this.  Or, if you want the character to do it in 30 frames, write ‘thisguy.whatframe + 30’

xVel, yVel, zVel – used in the SetOtherSpeed function.  These just set the velocity of another character (which is specified by the whatC).  Velocity is in units/frame

whatDatNum, whatdata – advanced uses only.  All characters have an array of 10 variants called miscdata( ).  Used for artillery.  Look below

Radius, Damage – used for the ExplodeMe function.  Used for explosives with a radius.  Look below

 

 

Projectile Usage

Assuming you understand all above, you can now attempt to something advanced: projectile units.

 

All projectile units contain at least 2 items: a shooter and a shootee.  The shooter is the person with the bow/gun/catapult/whatever.  The shootee is the a bullet/arrow/shell/rock.  In order for a realistic-looking shot, the shooter must run a throwing/shooting/launching animation at the same time the shootee is launched.  To do this, you must set the shootee’s AI up so that it constantly checks to see if it has been fired/launched/thrown, and the shooter basically, when it attacks, has a few more functions to call.  When the shooter shoots, you must run it’s animation, set the shootee’s velocity and position, and tell the shootee’s AI that it has been shot.  For this, battlegen has 10 slots for data you may want to fill up during execution.  So, here’s some code:

Shooter Code

1: Sub Main

2: thisguy.whatframe = thisguy.whatframe + 1

3: if disttoclosest(thisguy.mynum,2) < 10 then

4:         thisguy.dosomething(FireArrow”,thisguy.whatframe)

5:         thisguy.faceclosest(thisguy.mynum,thisguy.whatframe,2)

6:         SetOtherMiscData(thisguy.mynum + 1,1,”SHOT”)

7:         SetOtherSpeed(10,0,0,thisguy.mynum + 1)

7.5:      MoveContactToMe(thisguy.mynum,thisguy.mynum+1)

8: end if

9: End Sub

 

Lines 1, 2, 3, 4, 5, 8, and 9 you’ve seen before.  If not, look above to the coding example.

Line 6: This sets a miscdata element on the character ‘above’ (thisguy.mynum + 1) thisguy to “SHOT”.  This means that in this particular battle, you would have set it up so that there was only one shooter and one shootee, so that the character ‘above’ would be guaranteed to be a shootee. 

Line 7: I didn’t really want to set it up so that there was a big calculation to figure out what direction to shoot the shootee, so I just made the shootee have an xvelocity of 10, and 0 for it’s y and z velocities.  This sets the character ‘above’ thisguy to have those speeds.

Line 7.5: This moves the character ‘above’ thisguy so that it is at the same position as thisguy, so that the arrow will appear to release from thisguy.

 

Shootee Code

1: Sub Main

2: thisguy.whatframe = thisguy.whatframe + 1

3: if thisguy.getmiscdata(1) = “SHOT” then

4:         thisguy.xpos = thisguy.xpos + thisguy.xvel

5:         thisguy.ypos = thisguy.ypos + thisguy.yvel

6:         thisguy.zpos = thisguy.zpos + thisguy.zvel

7:         thisguy.faceoutput = thisguy.faceoutput & facedirection(thisguy.mynum, thisguy.whatframe)

8:         thisguy.posoutput = thisguy.posoutput & outputloc(thisguy.mynum,thisguy.whatframe)

9:end if

10: End Sub

 

Lines 1, 2, 9, and 10 you’ve seen before.

3: GetMiscData is the way that you look at those 10 little miscdata values.  This asks for the first one, and sees if it says “SHOT”.  If it does, then the code within the if statement is executed

4,5,6: these lines make thisguy move according to the speeds.  If you remember from above, only his xvel got changed, but this is general purpose projectile code, so it moves according to his y and z velocities as well.

7: This uses the xvel, yvel, and zvel numbers to make the shootee face in the direction it is moving, so it looks nice.

8: This keyframes the position of the shootee each frame.

1