Author Topic: Making AI Move In One Direction Indefinitely  (Read 2814 times)

0 Members and 1 Guest are viewing this topic.

Making AI Move In One Direction Indefinitely
A number of people have noticed the problem with the set-object-speed-(x, y or z) SEXP:  It only does it for one frame, and going:

-every-time
--true
--set-object-speed-(x, y or z)
---(object)
---(speed)

...yields mixed results at best.  Since there is as yet no SEXP for setting an AI ship to glide (unless there's one in a new build that I don't have), we would seem to be a little stuck here, especially as pertains to doing silly tricks in cutscenes.

But take heart!  I have discovered a SEXP workaround.  I'll show you what I've done, and most likely you'll instantly realize what I've done.  I wanted to move Gamma 1 along the absolute z axis.  Here's my work:

getpos
-every-time
--true
--modify-variable
---player-x(0)
---get-object-x
----Gamma 1
--modify-variable
---player-y(0)
---get-object-y
----Gamma 1
--modify-variable
---player-z(0)
---get-object-z
----Gamma 1
setpos
-every-time
--true
--set-object-position
---Gamma 1
----+
-----player-x(0)
-----0
----+
-----player-y(0)
-----0
----+
-----player-z(0)
-----1

For the sake of flexibility, I went ahead and made the x and y coordinate arguments for set-object-position Gamma 1 arithmetical as well.  This just makes it easier for me to mess with further on down the line.

If you don't quite see what's going on (or my way of writing out SEXPs in the forums is just giving you headaches) I basically have one every-time event that gets the x-, y- and z-coordinates of the object Gamma 1 and assigns them to variables, and then another every-time event that sets the position of Gamma 1 to the coordinates it just read plus whatever number of units I want Gamma 1 to move along that axis in that frame.  If I want it to move faster, I add a larger number.

So!  Now we have a way to make this move for as long as FS2 is being told to check for coordinates and then set position some distance away from those coordinates every frame.  Better yet, this one doesn't give you a shaky camera, because it's updating every frame just like everything else.

The biggest drawback, of course, is that this doesn't give you a clean-cut way to set a specific speed.  However:  If you know your framerate, you can work out the speed.  It also makes changing direction smoothly or imitating the smooth movements that we now have for set-camera-position tricky at best and require an awful lot of SEXPs.

But for the basics, hey, it's a workaround.

(I'm using FRED and FS2 3.6.10, designing for The Babylon Project with the Zathras mod.)

 

Offline karajorma

  • King Louie - Jungle VIP
  • Administrator
  • 214
    • Karajorma's Freespace FAQ
Re: Making AI Move In One Direction Indefinitely
Why are you using  variables at all? Why aren't you just using

setpos
-every-time
--true
--set-object-position
---Gamma 1
----get-object-x
-----Gamma 1
----get-object-y
-----Gamma 1
---- +
-----get-object-z
------Gamma 1
-----1
Karajorma's Freespace FAQ. It's almost like asking me yourself.

[ Diaspora ] - [ Seeds Of Rebellion ] - [ Mind Games ]

 
Re: Making AI Move In One Direction Indefinitely
Well, there are three reasons, and they're all bad ones.  First of all, I figured that out at like three in the morning and was all excited.  Secondly, I'm actually using the constantly-updating variables anyways for some other things--one of which is to simulate a long fiery trail behind a ship by constantly creating a small, no-damage, no-blast explosion at its coordinates.

The other thing I'm using them for--and actually this doesn't affect the set-object-position thing, but I think it put me in the habit of using these even though they're kind of a messy burden to the mission design and the engine--is a remote target designator for beam weapons.

Third, putting things into variables and spelling them out helps me to proofread my work and make sure my SEXPs are as unbreakable as possible.  I can always simplify later.

Oh, and one more thing, a bug that I forgot to mention:  Moving objects by constantly relocating them means that they will sometimes fail to detect collisions.

The following is strictly for the curious.  No need to read it.

In creating this remote designator, basically, I did this:

Created extra-wep.tbm in data/tables to recreate something a little bit like the Targeting Laser, except as a secondary weapon, and with $Cargo Size set in such a way that none of the fighters that can carry it can carry more than one at a time per bank, and not available when selecting a loadout.

Created gettarget-sct.tbm in data/tables with the following script:
#Global Hooks
$Simulation: [
ship = Mission.Ships['Gamma 2']
starget = ship.Target
if starget:isValid() then
mn.SEXPVariables ['ptarget'] = tostring(ship.Target)
end
#End
(and this took me a while because I'd never coded before)

and of course created extras-shp.tbm to allow all the classes of StarFury to carry this thing.  ("Gamma 2" in the Lua because that's the name of the player ship in the mission I'm working on.)

With all that and the follow SEXP:

turret-disable
-when
--true
--turret-lock-all
---EA G.O.D. Satellite 1
get-ptarget-loc
-every-time
--not
---string-equals
----ptarget(none)
----none
--modify-variable
---ptargetx(0)
---get-object-x
----ptarget(none)
--modify-variable
---ptargety(0)
---get-object-y
----ptarget(none)
--modify-variable
---ptargetz(0)
---get-object-z
----ptarget(none)
align-GOD
-every-time
--and
---not
----string-equals
-----ptarget(none)
-----none
---not
----string-equals
-----ptarget(none)
-----EA G.O.D. Satellite 1
--set-object-facing
---EA G.O.D. Satellite 1
---ptargetx(0)
---ptargety(0)
---ptargetz(0)
---20000
iffcheck
-every-time
--true
--when
---is-iff
----Friendly
----ptarget(none)
---modify-variable
----iffcheck(1)
----0
--when
---not
----is-if
-----Friendly
-----ptarget(none)
---modify-variable
----iffcheck(1)
----1
rechargecheck
-every-time
--true
--when
---=
--- -
----mission-time
----firetime(0)
---15
---modify-variable
----rechargecheck(0)
----1
---training-msg
----ready
---key-reset-multiple
----Spacebar
---set-secondary-ammo
----Gamma 2
----0
----1
ammocheck
-every-time
--true
--when
---true
---modify-variable
----ammocheck(0)
----get-secondary-ammo
-----Gamma 2
-----0
firebeam
-every-time
--true
---when
----and
-----key-pressed
------Spacebar
-----=
------iffcheck(1)
------0
----training-msg
-----friendly
----key-reset-multiple
---when
----and
-----=
------iffcheck(1)
------rechargecheck(1)
------ammocheck(1)
------1
-----key-pressed
------Spacebar
-----missile-locked
------0
----fire-beam
-----EA G.O.D. Satellite 1
-----turret01a
-----ptarget(none)
----key-reset-multiple
-----Spacebar
----modify-variable
-----firetime(0)
-----mission-time
----modify-variable
-----rechargecheck(0)
-----0
lockstop
-every-time
--when
---and
----not
-----missile-locked
------0
-----key-pressed
------Spacebar
---key-reset-multiple
----Spacebar

...and all this to be later called conditionally so that it only works at a certain point in the mission.

I created a remote-designator that fires only when you have a missile lock, only when the recharge time has passed, and only when the target is not a friendly.  The only safeguard that isn't spelled out here is that of the turning time on the satellite--if the target is not in the firing cone of the beam turret when you press the firing button, even if everything else is ready, it won't fire.  This is prevented because the minimum time for the targeting laser to acquire a lock is greater than the time it takes the satellite to traverse 180 degrees.

As you can see, I was again spelling everything out and making heavy use of variables so that I could more easily proofread myself and make sure there is no easy way to break this thing.  I did take a shortcut with the ammo check which means that, if it were enabled for any ships that have a large enough secondary capacity to carry more than one of these things at a time, that would break some parts of it.  Of course that's an easy fix, but just for now I'm not worried about it.

Sadly I know nothing of Lua, so I'm sure many easier ways to do it than messing around with SEXPs passed me by.  If anyone wants to take up that challenge, go with my blessings.

(I apologize if all that was painful to read.  I actually only started creating missions with FRED three days ago.)

 
Re: Making AI Move In One Direction Indefinitely
Oh and obviously an easy way to break it is to destroy the satellite while it's in use.  I just had the satellite invulnerable while this was going on.  Obviously it's easy to factor in a precaution against the satellite being destroyed if you don't want to make it invulnerable.

 

Offline General Battuta

  • Poe's Law In Action
  • 214
  • i wonder when my postcount will exceed my iq
Re: Making AI Move In One Direction Indefinitely
That is pretty cool. I've actually tried using similar SEXPs (only using the much simpler method Karajorma outlined), but the problem is the object seems to 'skip' along jerkily.

 
Re: Making AI Move In One Direction Indefinitely
There were some SEXPs recently added to do pretty much this. In this case, use Change -> Coordinate manipulation -> ship-lat-maneuver, with a very long turn time (what's the maximum value for that?).
Also, make sure to use clear-goals before this SEXP.

 

Offline karajorma

  • King Louie - Jungle VIP
  • Administrator
  • 214
    • Karajorma's Freespace FAQ
Re: Making AI Move In One Direction Indefinitely
(I apologize if all that was painful to read.  I actually only started creating missions with FRED three days ago.)

You're doing pretty well for someone who is just beginning. Usually I spend more time teaching new users that they shouldn't be scared of variables than telling them that they've mis/overused them. :)
Karajorma's Freespace FAQ. It's almost like asking me yourself.

[ Diaspora ] - [ Seeds Of Rebellion ] - [ Mind Games ]

 
Re: Making AI Move In One Direction Indefinitely
Quote
There were some SEXPs recently added to do pretty much this. In this case, use Change -> Coordinate manipulation -> ship-lat-maneuver, with a very long turn time (what's the maximum value for that?).

Thanks!  I'll get the latest FRED and catch up with all you cool cats.

Quote
You're doing pretty well for someone who is just beginning. Usually I spend more time teaching new users that they shouldn't be scared of variables than telling them that they've mis/overused them.

If you can't abuse variables, who CAN you abuse?

 
Re: Making AI Move In One Direction Indefinitely
For anyone who might be searching the forums in the future:

There's a much slimmer way to do all this.  After walking away for a few minutes, of coure, it hit me like a truck.

If you add a targeting laser to you weapons--say, making targetlaser-wep.tbm--make sure you make it a homing weapon, and make sure you have the "no dumbfire" flag.  In fact I already had these and just didn't realize that the simplest answer was right in front of me.  Witness the benefits of going outside now and again.

With that and the script I mentioned above--which I'm trying to make into something more flexible--all you really need in terms of SEXPs to get the same result is this:

No Turrets [This is just if you want to keep the GOD sat from opening up with missiles]
-when
--true
--turret-lock-all
---[name of your GOD sat]
Get Target
-every-time
--not
---string-equals
----ptarget(none)
----none
---modify-variable
----ptarget-x(0)
----get-object-x
-----ptarget(none)
---modify-variable
----ptarget-y(0)
----get-object-y
-----ptarget(none)
---modify-variable
----ptarget-z(0)
----get-object-z
-----ptarget(none)
Align GOD
-every-time
--and
---not
----string-equals
-----ptarget(none)
-----none
---not
----string-equals
-----ptarget(none)
-----[name of your GOD sat]
--set-object-facing
---[name of your GOD sat]
---ptarget-x(0)
---ptarget-y(0)
---ptarget-z(0)
---20000
Recharge Check
-every-time
--true
---when
----=
----- -
------mission-time
------time-fired(0)
-----15 [or however long you want the recharge delay to be]
----modify-variable
-----recharge-check(0)
-----1
----training-msg
-----ready [optional, in fact I'm going to use subtitles in my final version]
----key-reset-multiple
-----Spacebar
----set-secondary-ammo
-----Gamma 2 [see note below]
-----0
-----1
Lock Stop
-every-time
--true
--when
---and
----not
-----missile-locked
------0
----key-pressed
-----Spacebar
---key-reset-multiple
----Spacebar
Fire Beam
-every-time
--true
--when
---and
----=
-----recharge-check(0)
-----(0)
----key-pressed
-----Spacebar
----missile-locked
-----0
---key-reset-multiple
----Spacebar
---fire-beam
----[name of your GOD sat]
----turret01a
----ptarget(none)
---modify-variable
----time-fired(0)
----mission-time

As regards using Gamma 2:  The script I wrote is specifically for a campaign I'm working on.  In this campaign, the player is Gamma 2.  This can be changed in the script, but I'm also trying to figure out (with my pitiable LUA abilities) a way to make that more flexible, so that the script will work with any given name for the player.

If you're still reading, you might be as new to this as I was when I wrote this, so I'll go into some detail.  Experienced modders may skip the following.

You may wonder why I used set-object-facing and then the coordinates of the variable ptarget, rather than just set-object-facing-object and pointing the GOD sat at ptarget.  Well, set-object-facing-object seems to also align the object you're setting with the object you're point it at, and just for visual effect I didn't want my GOD sat spinning on its (relative) Z axis, just rotating about its X and Y to face its target.

If you read the previous SEXPs, you might have noticed that I eliminated the all-important IFF check.  Well, when I put this into action I realized pretty quickly that it, like so many other things I was doing, was unnecessary.  The GOD sat won't fire on friendlies--or in fact anything but hostiles--because it requires a missile lock to fire, and your weapons will not lock onto anything but hostiles.  The "no dumbfire" tag in your weapons table prevented you from using up your one-at-a-time targeting laser ammo on a shot that the GOD sat won't take.

And if you are indeed new to this whole thing, I know the hardest part for me was learning the scripting.  I'll go really quickly through the script I used and how it works, so you can have some place to start from.  You will still want to read about scripting some to get some definitions.  The definitions you'll need are here: http://www.hard-light.net/wiki/index.php/FS2_Open_Lua_Scripting#What_You_Need

#Global Hooks
$Simulation
;;read about these here: http://www.hard-light.net/wiki/index.php/Scripting.tbl

[
ship = Mission.Ships['Gamma 2']
;;This sets the handle "ship" to 'Gamma 2.'  It calls up the library "Mission" and retrieves the ship 'Gamma 2' for future reference.  This part, until I learn a better way, dictates that for the script to work, the player ship must be Gamma 2.  Of course, if you want to play as something else, just change Gamma 2 to Alpha 1 or whatever.  Don't forget the single quotation marks around the name of the ship.

starget = ship.Target
;;This creates the variable 'starget' and sets it to the target selected by the handle 'ship.'  And because of the line above it, the handle 'ship' currently refers to Gamma 2.

if starget:isValid()then
;;Basic preventative debugging.  The script doesn't try to do anything within the "If-then-end" statement if there's something wrong with starget.  This prevents your script from crashing the game.

mn.SEXPVariables['ptarget'] = tostring(ship.Target)
;;"mn" is the short version for "Mission," so it's going into the Mission library again.  mn.SEXPVariables does exactly what it sounds like--it sets a SEXP variable to a value that you come up with in LUA scripting.  "tostring" is necessary for this to work, because it changes the object data "ship.Target" to a string.  SEXP variables can only do strings and numbers.  Instead of LUA stuff that SEXPs can't understand, you just get the name of whatever happens to be ship.Target at that time.  And, again, the handle 'ship' is still referring to 'Gamma 2.'

end
;;ends the if-then statement.

]
#End

Hopefully that did some small part to make your learning process a little less painful than mine.

  

Offline Angelus

  • 210
  • The Angriest Angel
Re: Making AI Move In One Direction Indefinitely

*snip*

  Since there is as yet no SEXP for setting an AI ship to glide (unless there's one in a new build that I don't have), we would seem to be a little stuck here, especially as pertains to doing silly tricks in cutscenes.

*snip*


A couple of months ago, i requested a "Force-AI-Glide" SEXP, but it was rejected, sadly.

The event you have there is pretty cool, kudos! :yes: