Hard Light Productions Forums

Modding, Mission Design, and Coding => The FRED Workshop => Topic started by: Erebus Alpha on April 10, 2016, 03:51:01 pm

Title: Player Warp to Target?
Post by: Erebus Alpha on April 10, 2016, 03:51:01 pm
I'm currently designing a short campaign, probably only five or so missions long, where the player plays as a Shivan. Since Shivans are really into subspace and all, it seems like Shivans would regard their subspace drives as nothing more exotic than a second afterburner, so tactical subspace jumps would be really common.

I read through the tutorial ( http://www.hard-light.net/wiki/index.php/Tutorial_-_In-Mission_Jumps ), and it covers how to make the subspace entrance window location relative to the player, but is it possible to make the subspace EXIT location relative to the player too?

Here's what I have in mind. I am curious if it is practical to do this as a core mechanic across all the missions in the campaign:

- Determine if there is anything 'in front of' the player (like a 10 degree cone or whatever)
- If so, get the distance to the object, subtract 2500 meters, and warp forward by that amount
- If not, warp 5000 meters forward.

The idea is, this can be used either as a rapid escape mechanism, or a way to very quickly close large distances with distant targets, without accidentally warping the player inside of a ship.

Normally when you press Alt-J to warp, and you are at full throttle, your ship slows down a lot. Is it possible to reconfigure this behavior so the ship instead speeds up a lot, like a capital ship does?

EDIT:

I'm not sure how to modify the 'is-facing' option to work like this. Is there an easier way to check if something is in the way/presents a collision hazard?

Preventing the player from warping inside of things is the real issue.

ANOTHER EDIT:

Proof-of-concept is working, it just needs refining so it's not just an emergency escape button, but also useful for subspace-jumping and attacking things like the Shivans do.
Title: Re: Player Warp to Target?
Post by: wardog300k on April 11, 2016, 10:29:51 am
Use this for the speed of ships entering subspace. (http://www.hard-light.net/wiki/index.php/Ships.tbl#.24Warpin_Speed:)
Title: Re: Player Warp to Target?
Post by: procdrone on April 11, 2016, 12:12:01 pm
Use this for the speed of ships entering subspace. (http://www.hard-light.net/wiki/index.php/Ships.tbl#.24Warpin_Speed:)

Wardog, this is not correct, since he wants to fake subspace entrance, not literally leave the mission. Warp in&out will not work here. Lat ship lat manoeuvre set to like 200%(%) or 250(%) should do it I believe ... ?
Title: Re: Player Warp to Target?
Post by: wardog300k on April 11, 2016, 12:50:55 pm
But it can work for AI, if you just make a new ship where you need it and use variables to set its hull&stuff.
Title: Re: Player Warp to Target?
Post by: procdrone on April 12, 2016, 02:51:49 pm
well that might be working but it is a pain, if you have control of the wing (they will appear as departed on your wingbar status even if you spawn new and rename them accordingly, secondly, you'd have to check if they are alive, copy their damage, etc..)
Title: Re: Player Warp to Target?
Post by: Erebus Alpha on April 15, 2016, 03:22:09 am
Ok, as a proof of concept, I've successfully jumped my ship 7500 meters forward from its current position.

However...this only seems to work once. The maneuver cannot be repeated.

I created another chained event, "Warp Recharge", at the end of the event sequence, which triggers 30 seconds after the warp is finished. It's a simple when-true-key-reset SEXP. Neither key-reset nor key-reset-multiple will let me warp a second time when I press Alt-J.
Title: Re: Player Warp to Target?
Post by: karajorma on April 15, 2016, 04:21:35 am
Try changing from when to every-time in the key-pressed event. This is actually one of the few times when the use of every-time rather than a repeating when is justified.
Title: Re: Player Warp to Target?
Post by: AdmiralRalwood on April 15, 2016, 04:31:55 am
If memory serves, chained events behave in potentially-counter-intuitive fashion when you're trying to make an entire chain be trigger-able multiple times. You may want to check out the $Use Alternate Chaining Behavior: (http://hard-light.net/wiki/index.php/Game_settings.tbl#.24Use_Alternate_Chaining_Behavior:) setting (although I'm not 100% clear on what behavior that will result in); alternatively, stop using chained events and instead use variables to trigger the events in sequence without chaining.
Title: Re: Player Warp to Target?
Post by: General Battuta on April 15, 2016, 12:57:48 pm
Don't use chained events when you want any of the events to repeat. Use a variable.
Title: Re: Player Warp to Target?
Post by: Erebus Alpha on April 15, 2016, 02:32:24 pm
Without event chaining, how do I insert a delay between two variable-dependent events, like the Warm Up event and the Show Warp event? I don't see a modify-variable-after-delay SEXP.

This is perhaps most important for managing the subspace drive recharge.
Title: Re: Player Warp to Target?
Post by: General Battuta on April 15, 2016, 05:11:07 pm
It's going to get hacky: you need to set up timer variables that increase by one every second when conditions are right, then reset once they've met the trigger.

Somebody post an example I am AFK! (Just trust me, as intimidating as it seems now, it ends up being way easier and more elegant)

Maybe post the tactical ability menus from The Blade Itself
Title: Re: Player Warp to Target?
Post by: Erebus Alpha on April 15, 2016, 05:47:35 pm
If I understand you correctly, I've done the same thing with Arduinos and programming to count milliseconds, using subtraction to compare elapsed time to a variable, and then setting that variable equal to elapsed time to reset the timer. :pimp:

Do the SEXP's require anything special to 'reset' them? Or are SEXP's smart enough to say "Whoops, that's not true anymore!" when the variable changes and 150 is no longer less than 155? Or should I be using 'every-time' instead of 'when'?

...Unless I'm misunderstanding horribly. That's always a likely possibility too.
Title: Re: Player Warp to Target?
Post by: karajorma on April 15, 2016, 09:28:52 pm
It's hard to know what to do exactly without seeing the events you have. But hopefully this should be enough to steer you in the right direction.


If you simply want a 30 second recharge on your warp drive and no other factors to change it, here's how I would do it.

Warp arrival                                  <--------------- This is whatever event you have trigger when the ship arrives out of a micro warp
- when
-- Your stuff here
- Modify-variable
-- LastWarpTime (999999999999)
-- Mission-time

Warp Drive Recharged (High / Infinite repeat count, 1 second interval)
when
- >=
-- mission-time
-- +
--- LastWarpTime (999999999999)
--- 30
- Modify-variable 
-- WarpDriveCharged (1)
-- 1   
- Modify-variable                                    <----------------------------------------------- Optional, but it prevents this event from triggering every second once the warp drive is charged
-- LastWarpTime (999999999999)
-- 999999999999


Do Micro Jump
-when
-- key-pressed
--- Alt + J
-- key-reset-multiple
--- Alt + J
- Modify-variable 
-- WarpDriveCharged (1)
-- 0
- All the stuff for the actual micro jump goes here.


   
I've set the variables up so that they allow you to warp immediately upon mission start. If you wanted the player to only be able to warp after 2 minutes, just set LastWarpTime to -90 and WarpDriveCharged to 0.

If that isn't enough help, post what you actually have so far and we'll figure out what you need to do.


Quote
Do the SEXP's require anything special to 'reset' them? Or are SEXP's smart enough to say "Whoops, that's not true anymore!" when the variable changes and 150 is no longer less than 155? Or should I be using 'every-time' instead of 'when'?

The vast majority of SEXPs are smart enough to do that. But there are a few edge cases where they evaluate to SEXP_KNOWN_FALSE or SEXP_KNOWN_TRUE and then are never evaluated again (for instance, testing the distance to a ship that has been destroyed doesn't work if you then respawn it somehow because the game first tests if the ship has been destroyed). In these rare cases you may need to use every-time. You should be able to get by in this case without it. I suspect the problem is the chaining not the use of when so you can ignore my earlier post.
Title: Re: Player Warp to Target?
Post by: Erebus Alpha on April 16, 2016, 01:27:37 am
Thank you, it works perfectly!

Well, mostly perfectly. I need to refine the size and position of the subspace window, and the timing of the sounds a bit, but that stuff is fairly easy to do. I'm reasonably pleased, considering it's the first SEXP I've touched in over a decade.

One other interesting note to anyone else trying to do this: All of your subspace jump events need to have a fairly high repeat count, not just the one that sets the warp-drive-charged variable back to 1 (warpable).

Now onto something a little more exotic:

- Is there a way to use SEXP's to set a variable equal to the name of the player's current target?
- Is there also a way for SEXP's to derive the distance between the player and that target?

I already found the SEXP for checking if a ship is facing another ship. The next logical iteration of the tactical subspace jump is an attack mode, where the player selects an otherwise distant target and warps into attack position, in the time-honored Shivan tradition of blowing things up.

I'm already using variables and calculating the destination coordinates of the warp relative to the player's position instead of relative to a fixed point in space. So if I am able to derive distance-from-target using SEXP's, and subtract 3000 meters or so, and do a true/false check on whether or not the player is facing the target, it should be a fairly simple matter of target, point, jump, and open fire! :drevil:

EDIT:
Also, some bells and whistles, like 'Subspace Drive Recharging' on the HUD would also be a nice touch. I know they did custom HUD elements in Blue Planet - so it's more or less a question of how hard it would be to add. Is it something that is reasonably straightforward?
Title: Re: Player Warp to Target?
Post by: karajorma on April 16, 2016, 02:41:05 am
Now onto something a little more exotic:

- Is there a way to use SEXP's to set a variable equal to the name of the player's current target?
- Is there also a way for SEXP's to derive the distance between the player and that target?

You can't get SEXPs to output a string at the moment but you can fake this behaviour using the argument SEXPs.

when-argument
-any-of
-- list all the hostile ships here
- and
-- Put the trigger you want here
- targeted
-- <argument>
- modify-variable
-- TargetedShip[]
-- <argument>

That should do what you want. The distance between ships can easily be found using the distance SEXP and the TargetedShip variable.

Quote
EDIT:
Also, some bells and whistles, like 'Subspace Drive Recharging' on the HUD would also be a nice touch. I know they did custom HUD elements in Blue Planet - so it's more or less a question of how hard it would be to add. Is it something that is reasonably straightforward?

It's pretty easy to do this with lua from what I understand. You'll have to ask a scripter how to do it though, my expertise is limited to SEXPs.
Title: Re: Player Warp to Target?
Post by: AdmiralRalwood on April 16, 2016, 05:15:57 am
Do Micro Jump
-when
-- key-pressed
--- Alt + J
-- key-reset-multiple
--- Alt + J
- Modify-variable 
-- WarpDriveCharged (1)
-- 0
- All the stuff for the actual micro jump goes here.
If you do the key-reset-multiple in the jump event, then pressing Alt+J during the recharge period will cause it to automatically jump as soon as it's recharged.

Also, you've forgotten to actually check that WarpDriveCharged is 1 before jumping.

BP's Her Finest Hour uses this somewhat-silly little event to avoid the first problem with the artillery keys:
Code: [Select]
$Formula: ( every-time
   ( and
      ( or
         ( key-pressed "1" )
         ( key-pressed "2" )
         ( key-pressed "3" )
         ( key-pressed "4" )
      )
      ( <
         ( mission-time-msecs )
         @nextNumberPoll[-1]
      )
   )
   ( key-reset-multiple "1" "2" "3" "4" )
)
+Name: Reset Keypresses the Axem Way

To avoid the second problem and save a variable, the keys check for key-pressed and ( > ( mission-time-msecs ) @nextNumberPoll[-1] ), and then set @nextNumberPoll[-1] to ( + ( mission-time-msecs ) 250 ) so that the artillery keys have a quarter-second cooldown.

So I'd use a set of events along these lines:
Code: [Select]
$Formula: ( when
   ( and
      ( key-pressed "Alt-J" )
      ( >=
         ( mission-time )
         @nextJumpTime[-1]
      )
      [ any other conditions here ]
   [ in-system jump logic here ]
   ( key-reset-multiple "Alt-J" )
   ( modify-variable
      @nextJumpTime[-1]
      ( + ( mission-time ) 30 )
   )
+Name: in-system jump trigger
+Repeat Count: -1
+Trigger Count: -1
+Interval: 0

$Formula: ( every-time
   ( and
      ( key-pressed "Alt-J" )
      ( <
         ( mission-time )
         @nextJumpTime[-1]
      )
   )
   ( key-reset-multiple "Alt-J" )
)
+Name: Reset jump key
+Repeat Count: 1
+Interval: 1

If you need multiple events in sequence for the in-system jump (and, let's face it, you do), that's when you add another variable (say, @jumpSequenceStage) and use that to trigger each event in turn (possibly in combination with @nextJumpTime in order to get the timing between stages right; if you need millisecond timing, then you just change mission-time to mission-time-msecs and add 30000 instead of 30).

For instance, add this to the jump event:
Code: [Select]
   ( modify-variable @jumpSequenceStage[-1] 0 )
and then your second event would check this:
Code: [Select]
$Formula: ( when
   ( and
      ( = @jumpSequenceStage[-1] 0 )
      ( >=
         @nextJumpTime[-1]
         ( - ( mission-time ) 25 )
      )
   )
   [ second stage of jump here ]
   ( modify-variable @jumpSequenceStage[-1] 1 )
)
Event: In-system jump stage 2
+Repeat Count: -1
+Trigger Count: -1
+Interval: 0
This example would make it wait five seconds before triggering the second stage. Then your final event just sets it back to -1 again, ready for the next jump sequence.
Title: Re: Player Warp to Target?
Post by: karajorma on April 16, 2016, 07:59:59 am
Yep. I remembered the second one when I was writing things down but forgot it when I got to that part of the event. :D

The first one should be easier to beat though, simply key-reset-multiple in the Warp Drive Recharged event. Then any key presses before the drive was ready will be ignored. You would have to make the modification of the LastWarpTime variable non-optional though. Doing things that way avoids having a nasty every-time event that triggers every frame and eats up more CPU cycles doing nothing useful.
Title: Re: Player Warp to Target?
Post by: Erebus Alpha on April 16, 2016, 02:56:49 pm
I put the key-reset-multiple in the Warp Recharge event. Every time the warp drive is ready to use, it resets Alt-J to prevent unwanted warps.

However, I seem to be having trouble finding the 'any-of' SEXP. Here is the event I am working on at the moment:

Code: [Select]
Warp Mode Selector
     op  if-then-else
      |--  op  and
      |     |--  op  =
      |     |     |-- Warp-In-Progress(0)   <-- Variable, this becomes 1 when the warp sequence is running
      |     |     |-- 1
      |     |
      |     |--  op  true <-- This is where I need to stick the "Are you facing your target?" check
      |
      |--  op  modify-variable
      |     |--  Warp-Attack-Config(0)   <-- Variable, uses the warp drive in attack configuration
      |     |--  1
      |
      |--  op  modify-variable
            |--  Warp-Attack-Config(0)   <-- The same variable, uses the subspace drive in escape configuration
            |--  0

I'm also slightly surprised that we do not have a better way to type out SEXP's.
Title: Re: Player Warp to Target?
Post by: AdmiralRalwood on April 17, 2016, 07:08:39 am
I seem to be having trouble finding the 'any-of' SEXP.
You need to use when-argument instead of when; the first argument will default to any-of, and can be changed to a variety of related SEXPs under the Conditionals menu.

If you're wondering, no, there is no if-then-else-argument. Most FREDers do not actually like if-then-else due to it being slightly harder to tell which SEXPs will get evaluated when; some prefer, instead, to be explicit by using chained "when" SEXPs. Like this:
Code: [Select]
( when
   [ base condition goes here ]
   ( when
      ( = @someVariable[0] 1 )
      [ do something ]
   )
   ( when
      ( != @someVariable[0] 1 )
      [ do something else ]
   )
)
Title: Re: Player Warp to Target?
Post by: Erebus Alpha on April 19, 2016, 12:57:00 am
Yes, it works great!

...Mostly.

As soon as the AI control kicks in for the beginning of the warp sequence, it wants to have something hostile targeted. This is completely fine if shock-jumping enemy large ships with bombers or assault fighters, but if you need to get to a friendly target rapidly (say, for an escort mission?) the AI decides to switch targets.

I'm going to try and shuffle things around a bit, so that the first event records the player's target before the AI ever takes control. Once the target is stored in a variable, the AI should be able to target whatever it wants without screwing up the warp.

So close to paste-able tactical smart warp in every mission! :D

EDIT:

I believe I solved this problem just by putting player-use-ai far enough at the back of the line so that all the important targeting-related events happen before the AI swaps targets.
Title: Re: Player Warp to Target?
Post by: Erebus Alpha on April 21, 2016, 04:37:26 am
The tactical warp feature is unbelievably useful in combat. Through trial and error, I am refining it for balance, to avoid completely trivializing dogfights. The ability to warp to a friendly capship during an escort mission is also limitlessly useful - as is the ability to subspace-jump nearly instantly into ideal bombing position. FREDing missions to work in tandem with that feature should be a lot of fun.

There are three more features I would like to implement, before I release a copy-pastable SEXP-based tactical warpdrive:

- Currently it only affects the player, and I want to expand that behavior to all of Alpha wing. The SEXPing to do it may be a little lengthy.

- Some sort of HUD thing that indicates how long until the subspace drive is recharged. Perhaps gratuitous digging around in Blue Planet's files will be productive.

- Once all the objectives are complete, the drive needs to switch off of tactical mode so the player can do the traditional Alt-J to end the mission.
Title: Re: Player Warp to Target?
Post by: AdmiralRalwood on April 21, 2016, 08:40:47 am
- Once all the objectives are complete, the drive needs to switch off of tactical mode so the player can do the traditional Alt-J to end the mission.
In this case, a simple addition to the tactical jump SEXP to specifically check that the jump-out condition isn't satisfied. For instance, create an event called, say, "Jump out condition" and chain it to another event that gives you the actual "jump out" directive; then checking whether or not "Jump out condition" has been completed lets you know whether or not the player's non-local subspace drive should be enabled. Then you add this to the "and" at the top of the tactical jump SEXP (right-click on the "and" SEXP and use "add operator" to make it check more than two conditions simultaneously):
Code: [Select]
      ( not
         ( is-event-true-delay
            "Jump out condition"
            0
         )
      )
Finally, in the "Jump out condition" event itself, change the "do-nothing" to an "alter-ship-flag" to give the player their subspace drive back.
Title: Re: Player Warp to Target?
Post by: gershom on May 19, 2016, 08:08:42 pm
Did you ever get this working? I need something similar to this for my project. I'm currently experimenting with the one from the tutorial, but having yours to work from would save a lot of trial and error.
Title: Re: Player Warp to Target?
Post by: Erebus Alpha on June 14, 2016, 07:44:12 pm
Did you ever get this working? I need something similar to this for my project. I'm currently experimenting with the one from the tutorial, but having yours to work from would save a lot of trial and error.

I did, yes. I used a variable (Warp-Attack-Config) to tell the drive which event to run, when it goes to calculate coordinates for the player's subspace exit point. Those coordinates are contained in three more variables, Player-Destination-X, Player-Destination-Y, and Player-Destination-Z.

To make this distinction, it checks to see if there is a warp in progress (determined by variable), and if any one of a list of valid targets is currently targeted by the player, and if the player is facing them. If true, it sets another variable (Warp-Target) equal to the name of the player's current target, and sets Warp-Attack-Config to 1. If this event is false, warp-attack-config just stays at zero.

If warp-attack-config is 0 (false), it sets the player destination XYZ variables equal to the player's current position, plus 5000 meters in the Z direction. That part is fairly straightforward.

If warp-attack-config is 1 (true), it takes the distance to the player's target, subtracts 2500 meters, and uses the result in place of the 5000 meter forward jump calculation above. So if you are 7700 meters from your target, the attack warp instead warps you forward 5200 meters.

During the recharging sequence, I also set warp-attack-config to 0 (false), in case it became true. Otherwise, it would try to get attack-configuration coordinates every single time, even if you are warping away from things.

Unfortunately, with ambition being ambitious, almost as soon as I had a semi-working prototype, I expanded the system to include not just tactical warps, but all kinds of other special abilities for fighters, emulating the stuff that the Blue Planet team did in missions like One Future and The Sword Itself. The tactical warp system has now ballooned into a myriad of 34 different events (and still counting, as I keep adding systems).

The Manticore has been my guinea-pig for testing the system, and it's a lot of fun.