Author Topic: Capship Ai script  (Read 1773 times)

0 Members and 1 Guest are viewing this topic.

For the RTS mod I created a script to replace to the stupid capship vs capship AI that makes sure a capship flies into range and then rotates to get as much firepower as possible on the target. So far the basic framework works in most cases, what is missing is attacking range determination and a better way to figure out which turret is good against other capships and which isn't.
Now there is one problem I can't get around:
How can I properly calculate the angles (pitch, bank, heading) for a rotation?
At the moment this is a huge mess that may or may not do the right rotation. Working with orientations seemed promising but in the end the angles aren't unique since getting an orientation from a vector always sets bank to 0.

Something else I noticed is that variables may have completely different values if a debug build is used compared to a normal build (turret FOVs are one example with either 0 or some large integer value). Has anyone an idea what might cause this?
Here goes scripting and copy paste coding
Freespace RTS Mod
Checkpoint/Shipsaveload script

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
you basically want to do this:

http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToEuler/index.htm

the code example there is in c, but here it is written in lua (and with freespace's matrix order)
Code: [Select]

function getEuler(m)
local p,b,h
--handle singularities
if math.abs(m[2]) > 0.998 then
if m[2] < 0 then
p = -math.pi/2
else
p = math.pi/2
end
b = 0
h = math.atan2(m[3],m[9])
else
p = math.asin(m[4])
b = math.atan2(m[7],m[1])
h = math.atan2(-m[6],m[5])
end
return p,b,h
end


granted this may be what freespace does when you get a matrix's p,b,h values. it also outputs radians.
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 
If I had a matrix to begin with I wouldn't ask. Orientations can already be used with the 9 matrix values or the 3 angles p,b,h with the game taking care of the conversion.

My problem is that I merely have a vector going from the ship to the target. To make it worse the ship shouldn't just rotate it's front side towards the target but in some cases rotate so that a certain side (like a broadside in case of a GTD Orion) points to the enemy. Any way to rotate a ship requires to get p,b,h out of this information.

My current implementation is based only on coordinates of the two vectors and several comparison operations determining into which direction it has to rotate.
There is some more scripting code responsible for dampening, stopping, preventing unnecessary movement and whatever else the internal AI has to do to keep rotations smooth and without overshooting.
Here goes scripting and copy paste coding
Freespace RTS Mod
Checkpoint/Shipsaveload script

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
i believe there are functions (or events) to make a ship face a world space vector, so if you have a vector to the target you can have your ship follow it until its within optimal weapons range. if you want to do a broadside, at this point, you would just need to come up with a new vector target. just rotate the world vector about your ship 90 degrees.

Code: [Select]
v = ba.createOrientation(0,0,math.pi/2):unrotateVector(target.position - self.position)+self.position
of course this assumes the mission is laid out fairly flat and that ships keep themselves level to the grid. you dont want ships to end up on their sides so that the target is outside of a turret's firing arc. to make this a better solution, follow that up by periodically ploting a new target vector, say when you get within x distance of the current target vector, plot a new vector and follow it. you can start by plotting a vector forward vector. you can just take the ships velocity times 10 (where it will be in ~10 seconds, assuming thrust is constant). you can then rotate that vector into the target's space, normalize it, and multiply it by your desired distance:

Code: [Select]
--get a world vector from your velocity
vvec = self.physics.velocity*10 + self.position
--put it int your target's space
lv = target.orientation:rotateVector(vvec - target.position)
--scale it to the optimal firing range (normalize and scale)
lvlenr = 1/lv:getmagnitude()
lv = lv * lvlenr * desiredRange
--put it back into world space
newv = target.positon + target.orientation:unrotateVector(lv)

resulting in a vector that is in front of you and at the appropriate distance for a broadside. while your are chasing these vectors, have the ship adjust its orientation to keep the correct side of the ship facing the target. you can also do other things like try to keep the ships level to the mission, but that is not a strict requirement. you can for example take a side vector (1,0,0) and unrotate it by the ships's orientation, and dot it with (target.position-self.position):getNormalized(). if its greater than 0 its facing the target, otherwise its facing away (you want to get a value close to 1), and if you get the acos of that value, you know how many degrees radians you need to roll to face the broadside towards the target.




« Last Edit: January 02, 2013, 05:50:19 pm by Nuke »
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN

 
Looks like I have to try something like you suggested. I can always have a ship fly towards a generated waypoint.

Problem is that this approach seems to be somewhat slow. Both ships may have any orientation and position at the beginning (can't assume a flat mission layout) and one out of ~30 possible local firing directions that represents the highest firepower. The ship can't start to roll until it is actually pointing into the direction it should fly or it might never really fly towards its target. Calculating the vector/direction so that the ship has the lowest possible angle to rotate and after rotating flies with the correct angle relative to the target seems to be not as easy as I hoped it to be. All the functions have to return something usable for all possible cases. Ships getting stuck during a rotation cause of some sign changes and angle comparisons failing at pi or pi / 2 is all too common in my script.
Here goes scripting and copy paste coding
Freespace RTS Mod
Checkpoint/Shipsaveload script

 

Offline Nuke

  • Ka-Boom!
  • 212
  • Mutants Worship Me
you will probibly have to divide up the maneuver up into several phases, the first will approach to within optimal weapons range, the second will be to lign up the desired firing arc with the target, and the third phase will be to maintain relative position and to keep the target in the firing arc and in range.

the first maunver you basically are just flying to within weapons range. you are also aiming for a point where your selected firing vector is pointing in the general direction of your target. just imagine drawing a optimal weapons range radius sphere around your target, and aiming for a point on the surface of the sphere where your guns will be pointing at the target. its easy to find this point. if you take your normal firing vector (in world space) times optimal weapons range and flip it (*-1), and add it to your targets position, then thats where you need to go. of course you need to recalculate it periodically and adjust your ships course, as the target will also be moving.

once you have that position you align your firing vector to your target. cross your firing direction with your target direction, this will five you an axis of rotation. and use the dot product to calculate how much rotation is needed for the alignment.

the third manuver requires maintaining distance and orientation so that both the optimal firing range is held and the target remains in the firing arc. since you are essentially orbiting your target, you will need to adjust your orientation and speed so you either spiral in or out. and this is done by leading or lagging the target vector. essentially do the same thing as the second step, but over but intentionally under or over shoot the target (but keeping the target within the firing arc).
I can no longer sit back and allow communist infiltration, communist indoctrination, communist subversion, and the international communist conspiracy to sap and impurify all of our precious bodily fluids.

Nuke's Scripting SVN