Hard Light Productions Forums

Modding, Mission Design, and Coding => The FRED Workshop => Topic started by: Asteroth on December 22, 2017, 04:16:18 pm

Title: Issues with Sexps and Ships Dying
Post by: Asteroth on December 22, 2017, 04:16:18 pm
So I have several issues either resolved clunkily or or not at all, but I'll start with this simple one. Got a mission, you're a defending a cruiser, called 'Cyclone', and it has a death scream if you fail. Halfway through the mission a Satis attempts to kamikaze the cruiser and will do half its total health in damage (so it may or may not kill it), if it does kill it, it plays the standard death scream, and if it doesn't it plays the 'ouch!' message instead. Think how, for a moment, you might implement this, and when you're done compare it to my attached solution (which does work as intended). Now while I'm happy it works, it is, needless to say, much more complicated than I originally thought it would be.

This stems from a few issues, like how hard it is to do a death scream that isn't set up as a persona. Obviously, simply going 'is ship dead? If so have ship death scream' doesn't work because dead ships can't send messages. In the end I took a page from volition themselves which have checked when a ship is at very low health, send a message, and then self-destruct the rest of the way on a few ships in a few missions. Another is checking if a ship did a successful kamikaze or not. Kamikaze damage doesn't count as damage from the kamikaze-er so get-damage-caused doesn't work, and I was hoping that successful kamikaze ships would be flagged as having killed themselves, but no, credit just goes to whichever enemy damaged them the most, or no one if they weren't attacked. Since the kamikaze self-destruct bypasses every % between its current health and 0% I used that to determine if it kamikazed or not.

So, I don't know if what I did is normal for this situation, or I missed a sexp that would've made this much simpler, but please let me know.

A related issue I still have yet to solve is making ships killed by the player death scream. Again, once I'm sure that the ship has been destroyed by the player it's too late to send any messages. I can do the guardian at 1% thing, but then I have to determine if it was the player that brought it to 1%.

I don't know how in demand this is, or how difficult it would be to implement, but simply having a field in the ship editor which allows to pick a message to be used as a custom death scream would be very useful in avoiding this sort of thing.

[attachment stolen by Russian hackers]
Title: Re: Issues with Sexps and Ships Dying
Post by: Spoon on December 22, 2017, 05:21:45 pm
Just have the deathscream message be send from #Cyclone when the ship hits 0% hull. Sure, you won't get the white brackets, but big deal?
Title: Re: Issues with Sexps and Ships Dying
Post by: xenocartographer on December 22, 2017, 05:51:28 pm
Just have the deathscream message be send from #Cyclone when the ship hits 0% hull. Sure, you won't get the white brackets, but big deal?

To expand on this, send-message and friends interpret #whatever as a special, non-ship sender. #Command, for example - without the #, it'd look for a ship called Command.



What's the advantage of having the Satis deal its kamikaze damage via SEXP? If you just set its damage to half the Cyclone's HP (you can look this up in ships.tbl, or the TBL Info field in FRED), the second event becomes

Code: [Select]
( when
    ( and
        ( is-destroyed-delay 1 "Kamikaze Satis" )
        ( not ( is-event-true-delay "kamikaze satis intercepted" 0 ) )
    )
    ( if-then-else
        ( is-destroyed-delay 0 "Cyclone" )
        ( send-message "#Cyclone" "High" "cyclone destroyed" )
        ( send-message "Cyclone" "High" "kamikaze satis impacted" )
    )
)

. That seems a little easier to work with, yeah? :)
Title: Re: Issues with Sexps and Ships Dying
Post by: Asteroth on December 22, 2017, 06:34:39 pm
Because kamikaze's don't deal their damage instantly. That event would always say 'kamikaze impacted'. And then it might actually destroy it and then say 'cyclone destroyed' too. Having messages from the #Ship in general is probably the most painless solution for general death screams, but i do like my white brackets : (
Title: Re: Issues with Sexps and Ships Dying
Post by: 0rph3u5 on December 22, 2017, 06:37:08 pm
Just have the deathscream message be send from #Cyclone when the ship hits 0% hull. Sure, you won't get the white brackets, but big deal?

I might be misremembering, but doesn't the engine bracket a ship with the same name (sans the #) if present?

Code: [Select]
( when
    ( and
        ( is-destroyed-delay 1 "Kamikaze Satis" )
        ( not ( is-event-true-delay "kamikaze satis intercepted" 0 ) )
    )
    ( if-then-else
        ( is-destroyed-delay 0 "Cyclone" )
        ( send-message "#Cyclone" "High" "cyclone destroyed" )
        ( send-message "Cyclone" "High" "kamikaze satis impacted" )
    )
)

. That seems a little easier to work with, yeah? :)

Use "event-incomple" instead of "not"+"is-event-true"
Title: Re: Issues with Sexps and Ships Dying
Post by: xenocartographer on December 22, 2017, 06:47:50 pm
I actually prefer not is-event-true, since the subtleties of incomplete vs. false complicate debugging. I can see why it works, but when something inevitably needs fixing, is-event-incomplete is another thing that needs checking. To each their own on this one; I'm sure some people have an easier time remembering the rules for when an event returns known-false.
Title: Re: Issues with Sexps and Ships Dying
Post by: 0rph3u5 on December 22, 2017, 06:53:12 pm
As for how to make a kamikaze hit count, that's a bit difficult but you could with a lot of fiddeling slowly work down to the distance at which the engine resolves the collision that triggers the kamikaze-destruct:

1. Make two waypoint paths for the Kamikaze and the Target.
2. Create two events on an "every-time" condition that matches the coordinates of the waypoints with the respective ships. They should have a seondary condition to stop working once the kamikaze ship is destroyed.
3. Make messages and events giving you message for when the waypoints (!!!) enter a certain distance from another. Use this to narrow down the point the ships make contact; let's call it "defining a point of no return".
4. Once you have determined the point of no-return for the collision, make it the condition to determine which message to send.
5. Remove all now superflous events from step 3.

This should allow you to bypass a standard distance-check as I am not sure if a collision actually happens at 0 distance (remember in FRED the distance between ships is measure from the "centre" not their outermost points).

EDIT: Code, quickly cocked up
Code: [Select]
$Formula: ( every-time
   ( and
      ( has-arrived-delay 0 "GTC Fenris 1" )
      ( not
         ( or
            ( is-destroyed-delay 0 "GTC Fenris 1" )
            ( is-destroyed-delay 0 "GVFr Satis 2" )
         )
      )
   )
   ( set-object-position
      "Waypoint path 1:1"
      ( get-object-x "GTC Fenris 1" )
      ( get-object-y "GTC Fenris 1" )
      ( get-object-z "GTC Fenris 1" )
   )
)
+Name: fenis waypoint coordinates
+Repeat Count: 1
+Interval: 1

$Formula: ( every-time
   ( and
      ( has-arrived-delay 0 "GVFr Satis 2" )
      ( not
         ( is-destroyed-delay 0 "GVFr Satis 2" )
      )
   )
   ( set-object-position
      "Waypoint path 2:1"
      ( get-object-x "GVFr Satis 2" )
      ( get-object-y "GVFr Satis 2" )
      ( get-object-z "GVFr Satis 2" )
   )
)
+Name: satis waypoint coordinates
+Repeat Count: 1
+Interval: 1

$Formula: ( when
   ( <
      ( distance
         "Waypoint path 1:1"
         "Waypoint path 2:1"
      )
      60
   )
   ( modify-variable
      "@CollisionHappened[False]"
      "True"
   )
)
+Name: substitue collision check
+Repeat Count: 1
+Interval: 1

$Formula: ( when
   ( is-destroyed-delay 0 "GVFr Satis 2" )
   ( if-then-else
      ( string-equals
         "@CollisionHappened[False]"
         "True"
      )
      ( send-message
         "#GTC Fenris 1"
         "High"
         "collision happened"
      )
      ( send-message
         "#GTC Fenris 1"
         "High"
         "collision avoided"
      )
   )
)
+Name: Event name
+Repeat Count: 1
+Interval: 1

Note: 60 is a dummy value for the distance check in "substitue collision check"; also there is no need to due it per string variable, just a an preference of mine
Title: Re: Issues with Sexps and Ships Dying
Post by: xenocartographer on December 22, 2017, 08:20:37 pm
Has anyone tested get-damage-caused-by and kamikazes? I'm sadly not in a position to do so right now, but iirc kamikaze damage is factored into assigning kills on the log, etc.
Title: Re: Issues with Sexps and Ships Dying
Post by: Asteroth on December 22, 2017, 11:35:29 pm
I've done some more testing and, unintuitive though it is, kamikaze damage does not get reported under get-damage-caused, but the kamikaze ship is credited as the killer of the ship it hits. Although a small amount of damage does get reported (I saw 99 from an elysium hitting a fenris) which I believe to be collision damage, and that small amount might be what is actually flagging the elysium as the fenris' killer.

And @0rph3u5, I'm hesitant to use distance, if I understand what you're describing, because a collision distance depends highly on the angle you approach from whatever number you substitute for 60, it will never be perfect, overshotting the collision distance could flag a collision as having happened even when it might not have, because it needs to actually collide to do the damage, and undershooting it can result in a successful kamikaze that is treated as if it didn't happen!
Title: Re: Issues with Sexps and Ships Dying
Post by: xenocartographer on December 23, 2017, 08:27:43 am
Well, that's annoying. :/ Okay, assuming you don't want to go with a scripted solution (if you do, lmk and I'll send you a script file), your approach of detecting the freighter's hull dropping is probably the best.