Hard Light Productions Forums

Modding, Mission Design, and Coding => The FRED Workshop => Topic started by: xenocartographer on May 02, 2017, 10:21:18 am

Title: Collecting FRED tricks
Post by: xenocartographer on May 02, 2017, 10:21:18 am
It occurred to me recently that there doesn't seem to be a place to share simple FRED tricks - there's the wiki tutorial section, aye, but not everything warrants an entire tutorial page, and an easily-scrolled-through list can't hurt, either. With that in mind, here are a couple of mine. Post your own!




Un****ing support ships in escort missions

Ah, we've all had that experience - the NTF/Vasudans/Shivans/random anime bull****/whatever attack on the GTCv Primary Objective has slackened off, and it's a great time to rearm, except the support ship is 6432653464 kilometers in some useless direction because the AI doesn't know to follow you. Let's fix that.

Code: [Select]
( when-argument
   ( any-of "Support 1" "Support 2" "Support 3" "Support 4" "Support 5" )
   ( is-in-mission "<argument>" )
   ( add-goal "<argument>" ( ai-guard "GTCv Primary Objective" 20 )  )
   ( invalidate-argument "<argument>" )
)

As soon as a support ship hits the field, we give it a low priority guard order on the most important friendly ship. (This could also be an installation or the player, depending on the type of mission.) This guard order won't interfere with its ability to rearm things, as those are issued at a higher priority, and once its done rearming, the highest priority order will be the guard order once again.



script-eval-block and <argument>

This one's a little hypothetical, but, put simply, if one argument to script-eval-block is just <argument>, it'll be replaced like any other. This can be used quite nicely with Axem's in-mission jump script:

Code: [Select]
( when-argument
  ( any-of "Alpha 1" "Alpha 2" "Alpha 3" "Alpha 4" "Support 1" )
  ( < ( hits-left "<argument>" ) 40 )
  ( script-eval-block ( "IMJump:To('" "<argument>" "', '" "<argument>" " runs away')" )
  ( invalidate-argument "<argument>" )
)

Pay attention to the quotes!



Guardianing the player's comms

This isn't so much a trick as something I've been wishing would become standard practice ever since BtA did it. Guardianing the player's comm system at 1% is almost completely mechanically irrelevant (it does mean the player will eventually regain the ability to issue orders even without a support ship, but eh), and saves the frustration of arbitrarily missing out on plot points.
Title: Re: Collecting FRED tricks
Post by: 0rph3u5 on May 02, 2017, 04:24:48 pm
Randomly placed random props

currently working on a better version of this - 0rph3u5, 4/13/2019

Hidden Text: Show
Sometimes you just need an extra layer of props lying around in mission which is just nice to have but not essential to mission - abandoned cargo containers, adrift fighters, random sensor blips or maybe an odd discarded "warhead" (not a secondary but a "ship" with the model and stats of a torpedo; please consult your modeler if it works for you). Because it is always a pain to come up with a random distribution on your own and to handcraft it, how about letting the engine to do heavy lifting?

(You might want the player to face away from where this happening for the first second of the mission or block their view. Using this on large objects is not recommended as it will be quite noticeable.)

This takes care of the initial random distribution and orientation:

(http://i1020.photobucket.com/albums/af321/0rph3u5/FS%20Open/random-distribution1_zpsffl59gdh.png) (http://s1020.photobucket.com/user/0rph3u5/media/FS%20Open/random-distribution1_zpsffl59gdh.png.html)
Taken from an acutal missions, the dimensions of the box in which you want to distribute the objects as well as the number of objects can be adjusted to your needs.

And this makes sure stuff doesn't crash into things right away or is placed into other ships:

(http://i1020.photobucket.com/albums/af321/0rph3u5/FS%20Open/random-distribution2_zpsens5fdug.png) (http://s1020.photobucket.com/user/0rph3u5/media/FS%20Open/random-distribution2_zpsens5fdug.png.html)
The distance for the inital check should be scaled to your needs. Re-orienting an object isn't strictly neccessary.



ps. And now we wait how long it takes for karajorma to tell me that I am using the argument-part wrong :)
Title: Re: Collecting FRED tricks
Post by: karajorma on May 03, 2017, 12:37:22 am
The argument part is fine. I'd suggest setting the interval time to zero though. It's unlikely but otherwise you could see an object bouncing about every second until it finally comes to rest in some empty space where it isn't near anything else. Setting it to zero means the event would be checked every frame rather than every second, which means that you might possibly get a tiny glitch in the first second of the mission at worst.
Title: Re: Collecting FRED tricks
Post by: Mito [PL] on May 03, 2017, 06:06:15 am
And you can hide that glitch by starting a mission with a short fade-in effect. I've definitely saw something like that effect somewhere out there, it looked pretty nice.
Title: Re: Collecting FRED tricks
Post by: Axem on May 12, 2017, 10:31:34 am
This looks like a good thread to sticky.

I wish I had some that came to mind. After using FRED for so long, things are less "tricks" and more "this is obviously how its done #humblebrag" :cool:

I'll have to go over my old missions and see if there's anything sort of generic enough that might apply to other people...
Title: Re: Collecting FRED tricks
Post by: JSRNerdo on May 12, 2017, 11:48:26 am
Everyone and I mean EVERYONE needs an invisible, untargetable blip of a ship. You can use it for anything! Let the player give it orders to simulate commanding whole fleets or actual capships using query-order! Use it for in-front-of-ship and near-ship warpins! Cameras! Everything!
Title: Re: Collecting FRED tricks
Post by: JSRNerdo on May 12, 2017, 11:54:15 am
Oh! I also recommend using a decent text editor (i use notepad++ since MJN made the awesome fs2 syntax for it) and you can edit a mission by hand, with the text editor! Very easy for mass find-replaces or copy/pasting, or other stuff that'd be tedious to do in FRED.
Title: Re: Collecting FRED tricks
Post by: xenocartographer on July 05, 2017, 11:56:07 am
Access to support ships is controlled by IFF. If you want the enemy to call for support, and are okay with the player not having access to it, you can use the Hostile IFF for the player's team and Friendly for the enemy.
Title: Re: Collecting FRED tricks
Post by: 0rph3u5 on April 13, 2019, 06:06:34 am
PSA from the RNGpocalypse:

Do not end an event with the modification of "string"-variable via  modify-variable. Some versions of FRED2 then don't draw the required quotation marks, in the text output, around the string to set the variable to (basically treating it like a number), which then gives you a nasty error message.

Adding a dummy  do-nothing added to the event will prevent this from happening.


When modifing a "string"-type variable via modify-variable, don't just enter data into second argument (aka what you want to set your variable to). It will cause an error message upon saving.

Making sure that you use "Replace Data" -> "string" on the argument will prevent this from happening. Do not just try to enter data into the field before doing this, the engine puts a "number" field there by default and then doesn't automatically know the difference.
Title: Re: Collecting FRED tricks
Post by: karajorma on April 16, 2019, 08:17:07 am
Wait, what?

That definitely sounds like a bug rather than something you should be teaching people to do.
Title: Re: Collecting FRED tricks
Post by: 0rph3u5 on April 16, 2019, 08:21:25 am
Wait, what?

That definitely sounds like a bug rather than something you should be teaching people to do.

Yes, sounds like it. However it is more user error than a bug, as I have come to realize after 5 days of dealing with it.
Corrected the post above.
Title: Re: Collecting FRED tricks
Post by: DefCynodont119 on June 24, 2020, 08:51:36 pm
Keep your event list organized and clear.


Rather then make a bunch of return to base objectives, you can make one and chain it to an event named something like "Mission RTB State" or something and have that event become true once any of your contextual ending events becomes true.

This makes it much easier to keep track of your mission's win/fail events and diagnose "unending mission" issues.
Title: Re: Collecting FRED tricks
Post by: TopAce on June 25, 2020, 01:12:38 am
If you do that, you'll never have to worry about missing "You have left the area without authorization..." debriefings. Simply add "is-event-false-delay" 0 <RTB event name> as the stage's prerequisite. For the rest of the stages, use "is-event-true-delay" 0 <RTB event name> to make sure no miscellaneous stages will appear if the player deserts.
Title: Re: Collecting FRED tricks
Post by: JSRNerdo on July 20, 2020, 08:52:07 pm
Press `+e while in a debug build to access the event debug menu

With the event debug menu, you can see the status (true, false, permanently true/false) of every event in the mission and whether it's been triggered, when it's been triggered, and so on. It's incredibly useful if you have any SEXP-related bugs you can't quite figure out.

Turret-Pretend-To-Fire

Everyone's probably been here - you want to manually fire a turret at a ship, but FRED doesn't support that functionality in a SEXP. Well, now you can and all you need to do is an ugly hack!

You'll need to add an entry to fireball.tbl (preferably in a .tbm, with a custom unique ID) with the name of the entry being the muzzle flash effect for the weapon you want to fire, add a dummy ship to your mission (cloaked, invisible, does not move, only for calculations, we'll call it DummyBoi for now) and add a variable to your mission which we'll call TurDist for now.

This is what the event looks like:

Code: [Select]
   ( when
      ( true )
      ( set-object-position
         "Dummyboy"
         ( get-object-x "FIRING=SHIP=HERE" "TURRET=NAME=HERE" )
         ( get-object-y "FIRING=SHIP=HERE" "TURRET=NAME=HERE" )
         ( get-object-z "FIRING=SHIP=HERE" "TURRET=NAME=HERE" )
      )
      ( set-object-facing
         "Dummyboy"
         ( get-object-x
            "TARGET=SHIP=HERE"
            "<none>"
            0
            0
            ( *
               ( /
                  ( distance-ship-subsystem
                     "TARGET=SHIP=HERE"
                     "FIRING=SHIP=HERE"
                     "TURRET=NAME=HERE"
                  )
                  BULLET=SPEED=HERE
               )
               ( get-object-speed-z
                  "TARGET=SHIP=HERE"
                  ( true )
               )
            )
         )
         ( get-object-y
            "TARGET=SHIP=HERE"
            "<none>"
            0
            0
            ( *
               ( /
                  ( distance-ship-subsystem
                     "TARGET=SHIP=HERE"
                     "FIRING=SHIP=HERE"
                     "TURRET=NAME=HERE"
                  )
                  BULLET=SPEED=HERE
               )
               ( get-object-speed-z
                  "TARGET=SHIP=HERE"
                  ( true )
               )
            )
         )
         ( get-object-z
            "TARGET=SHIP=HERE"
            "<none>"
            0
            0
            ( *
               ( /
                  ( distance-ship-subsystem
                     "TARGET=SHIP=HERE"
                     "FIRING=SHIP=HERE"
                     "TURRET=NAME=HERE"
                  )
                  BULLET=SPEED=HERE
               )
               ( get-object-speed-z
                  "TARGET=SHIP=HERE"
                  ( true )
               )
            )
         )
      )
      ( weapon-create
         "FIRING=SHIP=HERE"
         "GUN=TO=SHOOT=HERE"
         ( get-object-x "FIRING=SHIP=HERE" "TURRET=NAME=HERE" )
         ( get-object-y "FIRING=SHIP=HERE" "TURRET=NAME=HERE" )
         ( get-object-z "FIRING=SHIP=HERE" "TURRET=NAME=HERE" )
         ( get-object-pitch "Dummyboy" )
         ( get-object-bank "Dummyboy" )
         ( get-object-heading "Dummyboy" )
         "TARGET=SHIP=HERE"
      )
         ( explosion-effect
            ( get-object-x
               "FIRING=SHIP=HERE"
               "TURRET=NAME=HERE"
               -10
            )
            ( get-object-y
               "FIRING=SHIP=HERE"
               "TURRET=NAME=HERE"
               -10
            )
            ( get-object-z
               "FIRING=SHIP=HERE"
               "TURRET=NAME=HERE"
               -10
            )
            0
            0
            55
            1
            1
            0
            "Custom Fireball 2"
            203
         )
   )

And one that works with arguments:

Code: [Select]
   ( when-argument
      ( any-of
         "turretXYZ"
         "turretYXZ"
         "turretZYX"
      )
      ( not
         ( is-subsystem-destroyed-delay
            "FIRING=SHIP=HERE"
            "<argument>"
            0
         )
      )
      ( when
         ( true )
         ( set-object-position
            "Dummyboy"
            ( get-object-x
               "FIRING=SHIP=HERE"
               "<argument>"
            )
            ( get-object-y
               "FIRING=SHIP=HERE"
               "<argument>"
            )
            ( get-object-z
               "FIRING=SHIP=HERE"
               "<argument>"
            )
         )
         ( set-object-facing
            "Dummyboy"
            ( get-object-x
               "TARGET=SHIP=HERE"
               "<none>"
               0
               0
               ( *
                  ( /
                     ( distance-ship-subsystem
                        "TARGET=SHIP=HERE"
                        "FIRING=SHIP=HERE"
                        "<argument>"
                     )
                     BULLET=SPEED=HERE
                  )
                  ( get-object-speed-z
                     "TARGET=SHIP=HERE"
                     ( true )
                  )
               )
            )
            ( get-object-y
               "TARGET=SHIP=HERE"
               "<none>"
               0
               0
               ( *
                  ( /
                     ( distance-ship-subsystem
                        "TARGET=SHIP=HERE"
                        "FIRING=SHIP=HERE"
                        "<argument>"
                     )
                     BULLET=SPEED=HERE
                  )
                  ( get-object-speed-z
                     "TARGET=SHIP=HERE"
                     ( true )
                  )
               )
            )
            ( get-object-z
               "TARGET=SHIP=HERE"
               "<none>"
               0
               0
               ( *
                  ( /
                     ( distance-ship-subsystem
                        "TARGET=SHIP=HERE"
                        "FIRING=SHIP=HERE"
                        "<argument>"
                     )
                     BULLET=SPEED=HERE
                  )
                  ( get-object-speed-z
                     "TARGET=SHIP=HERE"
                     ( true )
                  )
               )
            )
         )
         ( weapon-create
            "FIRING=SHIP=HERE"
            "GUN=TO=SHOOT=HERE"
            ( get-object-x
               "FIRING=SHIP=HERE"
               "<argument>"
            )
            ( get-object-y
               "FIRING=SHIP=HERE"
               "<argument>"
            )
            ( get-object-z
               "FIRING=SHIP=HERE"
               "<argument>"
            )
            ( get-object-pitch "Dummyboy" )
            ( get-object-bank "Dummyboy" )
            ( get-object-heading "Dummyboy" )
            "TARGET=SHIP=HERE"
         )
         ( explosion-effect
            ( get-object-x
               "FIRING=SHIP=HERE"
               "<argument>"
               -10
            )
            ( get-object-y
               "FIRING=SHIP=HERE"
               "<argument>"
               -10
            )
            ( get-object-z
               "FIRING=SHIP=HERE"
               "<argument>"
               -10
            )
            0
            0
            55
            1
            1
            0
            "Custom Fireball 2"
            203
         )
      )
   )
Title: Re: Collecting FRED tricks
Post by: JSRNerdo on September 05, 2020, 02:00:34 am
Turret pretend to fire has been updated to no longer need the turdist variable.
Title: Re: Collecting FRED tricks
Post by: 0rph3u5 on October 10, 2020, 04:05:08 am
Let's talk about Directives for a bit:


Make extra events for Directives

Making extra events just for the Directives may seem like an additional step, but Directives are your best tool to direct the player to do something. As such, it is very useful to control when they appear and how the are organized. (e.g. if you have an unspecific directive, e.g. "Destroy Main Guns", to follow it with directives that describe a specific step, e.g. "- dorsal canon"). Thanks to milisecond intervalls for chained events this has become considerably easier to pull of.
Plus if they are in seperate events from events that deal with the consequences, you will have no issues with you have the change the organisation of your directives, e.g. when you change a wings arrival time for balancing reasons.


More Directives instead on unspecifc ones

This might be a personal gripe of mine, but consider not having unspecific directives like "Destroy bombers" but instead breaking them up into more specific ones even if it means increasing the number of directives, like turning "Destroy bombers" into "Intercept [wing A]" and "Intercept [wing B]".
You can always increase the number of directives that display at once in Hud_gauges.tbl (https://wiki.hard-light.net/index.php/Hud_gauges.tbl#.24Max_Directives:).


Keep a consistent language in your Directives

One of the ancient arts of rhetorics is today best known as "framing" - it is basically the technique to only speak about certain topics in specific terms shaping the conversation in a specific direction, by making sure which associations are fixed in the mind of the audience through repetition.
This can work wonders for your directives - the best example is to use seperate phrases for fighter ("Destroy X wing") and bomber ("Intercept Y wing") wings, which helps your players to build a another level of battlefield awareness, in addition to messages and the radar.
HOWEVER, you must keep a consistent pattern so it works. If the pattern slips up it creates at worst confusion, at the very least irritation.