Hard Light Productions Forums

Modding, Mission Design, and Coding => FS2 Open Coding - The Source Code Project (SCP) => Topic started by: SF-Junky on February 14, 2020, 01:37:52 pm

Title: good-secondary-time
Post by: SF-Junky on February 14, 2020, 01:37:52 pm
Isn't good-secondary-time supposed to limit the number of secondary weapons a team is supposed to fire at a specific ship? Because I actually want to use that feature in a mission and it won't work for me. Those bombers should keep emptying their Cyclops bays at the enemy when they are not supposed to.

What's the best way to tell a bomber or wing of bombers: "Shot no more than two Cyclops at [ship]"?
Title: Re: good-secondary-time
Post by: mjn.mixael on February 14, 2020, 02:12:53 pm
Um. I'm pretty sure good-secondary-time tells the AI "Hey, now is a really good time to use your secondaries. Have at it."
Title: Re: good-secondary-time
Post by: 0rph3u5 on February 14, 2020, 07:54:34 pm
What's the best way to tell a bomber or wing of bombers: "Shot no more than two Cyclops at [ship]"?

Aside from limiting each enemy ship to just two cyclops via initial loadout:

Build an repeating event, with an arguments list of every hostile bomber, that checks if the enemy ship has fired 2 torpedeos (there is a Status-type check get-seconary-ammo which can be used with =/</>; it can be combined with a is-ship-class check to taylor the check across bomber classes), then either use a SEXP to lock secondaries, empty the torpedeo bank (can be refilled via SEXP later) or swap out the weapon in the bank for a dummy the AI can't use (tagged-only is a neat flag for this one).
Use invalidade-argument to prevent excess repeats, and have a nested when to validate the expended arguments when approriate.
Title: Re: good-secondary-time
Post by: SF-Junky on February 15, 2020, 11:27:19 am
Um. I'm pretty sure good-secondary-time tells the AI "Hey, now is a really good time to use your secondaries. Have at it."
Yes, but there is an argument in that SEXP that explicitly limits the number of weapons fired:

https://wiki.hard-light.net/index.php/Good-secondary-time

What's the point of that if it seemingly has no effect?



Aside from limiting each enemy ship to just two cyclops via initial loadout:

Build an repeating event, with an arguments list of every hostile bomber, that checks if the enemy ship has fired 2 torpedeos (there is a Status-type check get-seconary-ammo which can be used with =/</>; it can be combined with a is-ship-class check to taylor the check across bomber classes), then either use a SEXP to lock secondaries, empty the torpedeo bank (can be refilled via SEXP later) or swap out the weapon in the bank for a dummy the AI can't use (tagged-only is a neat flag for this one).
Use invalidade-argument to prevent excess repeats, and have a nested when to validate the expended arguments when approriate.
That sounds... excessive for a workaround. The situation is this: Two wings of friendly bombers jump in to attack a group of hostile cruisers first and then a carrier plus two escorting cruisers later. And I don't want those bombers to fire a ****load of cyclops at a single cruisers.

I think it's easier to just give them a mixed Treb/Cyclops loadout and tell them to use Trebs on cruisers and Cyclops on the carrier.
Title: Re: good-secondary-time
Post by: 0rph3u5 on February 15, 2020, 12:23:29 pm
Aside from limiting each enemy ship to just two cyclops via initial loadout:

Build an repeating event, with an arguments list of every hostile bomber, that checks if the enemy ship has fired 2 torpedeos (there is a Status-type check get-seconary-ammo which can be used with =/</>; it can be combined with a is-ship-class check to taylor the check across bomber classes), then either use a SEXP to lock secondaries, empty the torpedeo bank (can be refilled via SEXP later) or swap out the weapon in the bank for a dummy the AI can't use (tagged-only is a neat flag for this one).
Use invalidade-argument to prevent excess repeats, and have a nested when to validate the expended arguments when approriate.
That sounds... excessive for a workaround. The situation is this: Two wings of friendly bombers jump in to attack a group of hostile cruisers first and then a carrier plus two escorting cruisers later. And I don't want those bombers to fire a ****load of cyclops at a single cruisers.

I think it's easier to just give them a mixed Treb/Cyclops loadout and tell them to use Trebs on cruisers and Cyclops on the carrier.

Excessive? - Please...

Code: [Select]
$Formula: ( when-argument
   ( any-of "Beta 1" "Beta 2" "Beta 3" )
   ( and
      ( = @current-traget[1] 1 )
      ( or
         ( and
            ( is-ship-class
               "GVB Sekhmet"
               "<argument>"
            )
            ( has-secondary-weapon
               "<argument>"
               "0"
               "Cyclops"
            )
            ( <
               ( get-secondary-ammo "<argument>" 0 )
               4
            )
         )
         ( and
            ( is-ship-class
               "GVB Sekhmet"
               "<argument>"
            )
            ( has-secondary-weapon
               "<argument>"
               "1"
               "Cyclops"
            )
            ( <
               ( get-secondary-ammo "<argument>" 1 )
               4
            )
         )
         ( and
            ( is-ship-class
               "GVB Sekhmet"
               "<argument>"
            )
            ( has-secondary-weapon
               "<argument>"
               "2"
               "Cyclops"
            )
            ( <
               ( get-secondary-ammo "<argument>" 2 )
               4
            )
         )
         ( and
            ( is-ship-class
               "GVB Osiris"
               "<argument>"
            )
            ( has-secondary-weapon
               "<argument>"
               "0"
               "Cyclops"
            )
            ( <
               ( get-secondary-ammo "<argument>" 0 )
               2
            )
         )
         ( and
            ( is-ship-class
               "GVB Osiris"
               "<argument>"
            )
            ( has-secondary-weapon
               "<argument>"
               "1"
               "Cyclops"
            )
            ( <
               ( get-secondary-ammo "<argument>" 1 )
               2
            )
         )
         ( and
            ( is-ship-class
               "GVB Osiris"
               "<argument>"
            )
            ( has-secondary-weapon
               "<argument>"
               "2"
               "Cyclops"
            )
            ( <
               ( get-secondary-ammo "<argument>" 2 )
               1
            )
         )
         ( and
            ( is-ship-class
               "GVB Bakha"
               "<argument>"
            )
            ( has-secondary-weapon
               "<argument>"
               "0"
               "Cyclops"
            )
            ( <
               ( get-secondary-ammo "<argument>" 0 )
               4
            )
         )
         ( and
            ( is-ship-class
               "GVB Bakha"
               "<argument>"
            )
            ( has-secondary-weapon
               "<argument>"
               "1"
               "Cyclops"
            )
            ( <
               ( get-secondary-ammo "<argument>" 1 )
               6
            )
         )
      )
   )
   ( lock-secondary-weapon "<argument>" )
   ( modify-variable
      @event-valid-arguments[3]
      ( - @event-valid-arguments[3] 1 )
   )
   ( invalidate-argument "<argument>" )
   ( when
      ( = @event-valid-arguments[3] 0 )
      ( modify-variable
         @current-traget[1]
         2
      )
   )
)
+Name: limit torps to target 1
+Repeat Count: -1
+Trigger Count: 100
+Interval: 0

$Formula: ( when-argument
   ( any-of "Beta 1" "Beta 2" "Beta 3" )
   ( and
      ( = @current-traget[1] 2 )
      ( or
         ( and
            ( is-ship-class
               "GVB Sekhmet"
               "<argument>"
            )
            ( has-secondary-weapon
               "<argument>"
               "0"
               "Cyclops"
            )
            ( <
               ( get-secondary-ammo "<argument>" 0 )
               2
            )
         )
         ( and
            ( is-ship-class
               "GVB Sekhmet"
               "<argument>"
            )
            ( has-secondary-weapon
               "<argument>"
               "1"
               "Cyclops"
            )
            ( <
               ( get-secondary-ammo "<argument>" 1 )
               2
            )
         )
         ( and
            ( is-ship-class
               "GVB Sekhmet"
               "<argument>"
            )
            ( has-secondary-weapon
               "<argument>"
               "2"
               "Cyclops"
            )
            ( <
               ( get-secondary-ammo "<argument>" 2 )
               2
            )
         )
         ( and
            ( is-ship-class
               "GVB Osiris"
               "<argument>"
            )
            ( has-secondary-weapon
               "<argument>"
               "0"
               "Cyclops"
            )
            ( <
               ( get-secondary-ammo "<argument>" 0 )
               1
            )
         )
         ( and
            ( is-ship-class
               "GVB Osiris"
               "<argument>"
            )
            ( has-secondary-weapon
               "<argument>"
               "1"
               "Cyclops"
            )
            ( <
               ( get-secondary-ammo "<argument>" 1 )
               1
            )
         )
         ( and
            ( is-ship-class
               "GVB Osiris"
               "<argument>"
            )
            ( has-secondary-weapon
               "<argument>"
               "2"
               "Cyclops"
            )
            ( <
               ( get-secondary-ammo "<argument>" 2 )
               1
            )
         )
         ( and
            ( is-ship-class
               "GVB Bakha"
               "<argument>"
            )
            ( has-secondary-weapon
               "<argument>"
               "0"
               "Cyclops"
            )
            ( <
               ( get-secondary-ammo "<argument>" 0 )
               2
            )
         )
         ( and
            ( is-ship-class
               "GVB Bakha"
               "<argument>"
            )
            ( has-secondary-weapon
               "<argument>"
               "1"
               "Cyclops"
            )
            ( <
               ( get-secondary-ammo "<argument>" 1 )
               4
            )
         )
      )
   )
   ( lock-secondary-weapon "<argument>" )
   ( modify-variable
      @event-valid-arguments[3]
      ( - @event-valid-arguments[3] 1 )
   )
   ( invalidate-argument "<argument>" )
   ( when
      ( = @event-valid-arguments[3] 0 )
      ( modify-variable
         @current-traget[1]
         3
      )
   )
)
+Name: limit torps to target 2
+Repeat Count: -1
+Trigger Count: 100
+Interval: 0

$Formula: ( when-argument
   ( every-of "Beta 1" "Beta 2" "Beta 3" )
   ( = @current-traget[1] 2 )
   ( clear-goals "Beta" )
   ( add-goal
      "Beta"
      ( ai-chase "SC Rakshasa 5" 89 )
   )
   ( unlock-secondary-weapon
      "<argument>"
   )
   ( modify-variable
      @event-valid-arguments[3]
         3
   )
)
+Name: switch to target 2
+Repeat Count: 1
+Interval: 1

$Formula: ( when-argument
   ( every-of "Beta 1" "Beta 2" "Beta 3" )
   ( = @current-traget[1] 3 )
   ( clear-goals "Beta" )
   ( add-goal
      "Beta"
      ( ai-chase "SC Lilith 6" 89 )
   )
   ( unlock-secondary-weapon
      "<argument>"
   )
   ( modify-variable
      @event-valid-arguments[3]
         3
   )
)
+Name: switch to target 3
+Repeat Count: 1
+Interval: 1
(now that's also shuts down any dogfighting and tactical weapons, but that can remedied by using a something other lock/unlock-secondary weapon; e.g. forcing the banks to only hold two cylcops and then re-arm the banks when switching targets)
ps. also please double-check if you c&p this - its a ten minutes job and I am not sure if the math is right on those ammo counts

EDIT added the missing modify-variables



Today's peak sass aside, adding limits such as specific bomber class and only one bay of torps make this a lot easier (above is specifically made to work with a wing the player can loadout)
Title: Re: good-secondary-time
Post by: General Battuta on February 15, 2020, 01:53:39 pm
It does kinda sound like the SEXP is not working as advertised. It's possible that it's meant to function only with weapons that the AI would ordinarily *never* fire (like retail Trebuchets). Because the AI wants to fire Cyclops even without good-secondary-time, that might be overwriting the SEXP's limit. Or it's just broken!

Have you considered just NEVER letting the AI fire and weapon-creating Cyclops when you want them to be used?
Title: Re: good-secondary-time
Post by: The E on February 15, 2020, 02:18:46 pm
Because this sounded like a fun investigation to do, I did some digging in the code to figure out how good-secondary-time actually works.

So, here goes:
1. When good-secondary-time is called, an internal list named Ai_huge_fire_info is updated.
2. When the AI is doing weapon selection, this internal list is queried to see if the mission designer has designated a preferred weapon to use on the target the AI is currently looking at.
3. If so, and if the AI in question carries the designated weapon, it will choose that weapon.
4. The AI aquires the "Unload_secondaries" flag, which forces it to fire its chosen secondary as soon as possible.

Conclusions:
1. The second argument of good-secondary-time is effectively ignored. It is never really read in a way that would actually limit the amount of missiles fired.
2. There is no way to revoke a good-secondary-time instruction. Once this sexp is used, the AI will, until the end of the mission and the general AI reset, always prefer to use the designated weapon on the designated ship
Title: Re: good-secondary-time
Post by: 0rph3u5 on February 15, 2020, 02:55:22 pm
Huh...

Could an possible replacement (similar to ai-ignore) then make good on the "time" part in the name? - Considering its cousin good-rearm-time actually designated a time window?
Title: Re: good-secondary-time
Post by: The E on February 15, 2020, 03:05:10 pm
Since it's not possible to fix the shot-count bug without hiding the fix behind an AI profile flag, we should probably create an entirely new sexp (or multiple sexps) that actually have some limiters on them.
Title: Re: good-secondary-time
Post by: Nightmare on February 15, 2020, 03:12:53 pm
we should probably create an entirely new sexp (or multiple sexps) that actually have some limiters on them.

bad-secondary-time
Title: Re: good-secondary-time
Post by: 0rph3u5 on February 15, 2020, 09:00:50 pm
Meanwhile - another workaround prototype:

Code: [Select]
$Formula: ( when ( true ) ( do-nothing ) )
+Name: METHOD 2
+Repeat Count: 1
+Interval: 1

$Formula: ( when-argument
   ( any-of "Beta 1" "Beta 2" "Beta 3" )
   ( has-arrived-delay 0 "Beta" )
   ( when
      ( has-secondary-weapon
         "<argument>"
         "0"
         "Cyclops"
      )
      ( modify-variable
         @initial-trop-count[0]
         ( +
            @initial-trop-count[0]
            ( get-secondary-ammo "<argument>" 0 )
         )
      )
   )
   ( when
      ( has-secondary-weapon
         "<argument>"
         "1"
         "Cyclops"
      )
      ( modify-variable
         @initial-trop-count[0]
         ( +
            @initial-trop-count[0]
            ( get-secondary-ammo "<argument>" 1 )
         )
      )
   )
   ( when
      ( has-secondary-weapon
         "<argument>"
         "2"
         "Cyclops"
      )
      ( modify-variable
         @initial-trop-count[0]
         ( +
            @initial-trop-count[0]
            ( get-secondary-ammo "<argument>" 2 )
         )
      )
   )
   ( invalidate-argument "<argument>" )
)
+Name: initial torp count
+Repeat Count: -1
+Trigger Count: 3
+Interval: 0

$Formula: ( when-argument
   ( any-of "Beta 1" "Beta 2" "Beta 3" )
   ( and
      ( has-arrived-delay 0 "<argument>" )
      ( destroyed-or-departed-delay
         0
         "<argument>"
      )
   )
   ( modify-variable
      @calc-bombers[3]
      ( - @calc-bombers[3] 1 )
   )
   ( invalidate-argument "<argument>" )
)
+Name: check bombers
+Repeat Count: -1
+Trigger Count: 3
+Interval: 0

$Formula: ( when-argument
   ( any-of "Beta 1" "Beta 2" "Beta 3" )
   ( and
      ( has-arrived-delay 0 "<argument>" )
      ( not
         ( destroyed-or-departed-delay
            0
            "<argument>"
         )
      )
   )
   ( when
      ( and
         ( is-ship-class
            "GVB Sekhmet"
            "<argument>"
         )
         ( has-secondary-weapon
            "<argument>"
            "0"
            "Cyclops"
         )
      )
      ( modify-variable
         @current-torp-count[0]
         ( +
            @current-torp-count[0]
            ( get-secondary-ammo "<argument>" 0 )
         )
      )
   )
   ( when
      ( and
         ( is-ship-class
            "GVB Sekhmet"
            "<argument>"
         )
         ( has-secondary-weapon
            "<argument>"
            "1"
            "Cyclops"
         )
      )
      ( modify-variable
         @current-torp-count[0]
         ( +
            @current-torp-count[0]
            ( get-secondary-ammo "<argument>" 1 )
         )
      )
   )
   ( when
      ( is-ship-class
         "GVB Sekhmet"
         "<argument>"
      )
      ( modify-variable
         @current-torp-count[0]
         ( +
            ( get-secondary-ammo "<argument>" 0 )
            ( get-secondary-ammo "<argument>" 1 )
            ( get-secondary-ammo "<argument>" 2 )
         )
      )
   )
   ( when
      ( and
         ( is-ship-class
            "GVB Sekhmet"
            "<argument>"
         )
         ( has-secondary-weapon
            "<argument>"
            "0"
            "Cyclops"
         )
      )
      ( modify-variable
         @current-torp-count[0]
         ( +
            @current-torp-count[0]
            ( get-secondary-ammo "<argument>" 2 )
         )
      )
   )
   ( when
      ( and
         ( is-ship-class
            "GVB Osiris"
            "<argument>"
         )
         ( has-secondary-weapon
            "<argument>"
            "0"
            "Cyclops"
         )
      )
      ( modify-variable
         @current-torp-count[0]
         ( +
            @current-torp-count[0]
            ( get-secondary-ammo "<argument>" 0 )
         )
      )
   )
   ( when
      ( and
         ( is-ship-class
            "GVB Osiris"
            "<argument>"
         )
         ( has-secondary-weapon
            "<argument>"
            "1"
            "Cyclops"
         )
      )
      ( modify-variable
         @current-torp-count[0]
         ( +
            @current-torp-count[0]
            ( get-secondary-ammo "<argument>" 1 )
         )
      )
   )
   ( when
      ( and
         ( is-ship-class
            "GVB Osiris"
            "<argument>"
         )
         ( has-secondary-weapon
            "<argument>"
            "2"
            "Cyclops"
         )
      )
      ( modify-variable
         @current-torp-count[0]
         ( +
            @current-torp-count[0]
            ( get-secondary-ammo "<argument>" 2 )
         )
      )
   )
   ( when
      ( and
         ( is-ship-class
            "GVB Bakha"
            "<argument>"
         )
         ( has-secondary-weapon
            "<argument>"
            "0"
            "Cyclops"
         )
      )
      ( modify-variable
         @current-torp-count[0]
         ( +
            @current-torp-count[0]
            ( get-secondary-ammo "<argument>" 0 )
         )
      )
   )
   ( when
      ( and
         ( is-ship-class
            "GVB Bakha"
            "<argument>"
         )
         ( has-secondary-weapon
            "<argument>"
            "1"
            "Cyclops"
         )
      )
      ( modify-variable
         @current-torp-count[0]
         ( +
            @current-torp-count[0]
            ( get-secondary-ammo "<argument>" 1 )
         )
      )
   )
   ( invalidate-argument "<argument>" )
   ( modify-variable
      @event-valid-arguments[3]
      ( - @event-valid-arguments[3] 1 )
   )
   ( when
      ( = @event-valid-arguments[3] 0 )
      ( validate-all-arguments )
      ( modify-variable
         @event-valid-arguments[3]
         3
      )
   )
)
+Name: check current torps
+Repeat Count: -1
+Trigger Count: 9999999
+Interval: 0

$Formula: ( when
   ( and
      ( has-arrived-delay 1 "Beta" )
      ( <=
         @current-torp-count[0]
         ( -
            @initial-trop-count[0]
            ( *
               @current-traget[1]
               ( * 2 @calc-bombers[3] )
            )
         )
      )
   )
   ( when
      ( < @current-traget[1] 4 )
      ( modify-variable
         @current-traget[1]
         ( + @current-traget[1] 1 )
      )
      ( modify-variable
         @current-torp-count[0]
         0
      )
   )
   ( when
      ( >= @current-traget[1] 4 )
      ( clear-goals "Beta" )
   )
   ( add-goal "Beta" ( ai-warp-out 89 ) )
)
+Name: switch target
+Repeat Count: -1
+Trigger Count: 10
+Interval: 0

$Formula: ( when ( true ) ( do-nothing ) )
+Name: COMMON
+Repeat Count: 1
+Interval: 1

$Formula: ( when-argument
   ( every-of "Beta 1" "Beta 2" "Beta 3" )
   ( = @current-traget[1] 2 )
   ( clear-goals "Beta" )
   ( add-goal
      "Beta"
      ( ai-chase "SC Rakshasa 5" 89 )
   )
   ( unlock-secondary-weapon
      "<argument>"
   )
)
+Name: switch to target 2
+Repeat Count: 1
+Interval: 1

$Formula: ( when-argument
   ( every-of "Beta 1" "Beta 2" "Beta 3" )
   ( = @current-traget[1] 3 )
   ( clear-goals "Beta" )
   ( add-goal
      "Beta"
      ( ai-chase "SC Lilith 6" 89 )
   )
   ( unlock-secondary-weapon
      "<argument>"
   )
)
+Name: switch to target 3
+Repeat Count: 1
+Interval: 1
(not sure if that one is protected against @current-torp-count[0] overflowing - its 4 am and I really need to get to bed)
Title: Re: good-secondary-time
Post by: SF-Junky on February 16, 2020, 01:48:52 pm
Thanks to 0rph3u5 for his suggestions, but I am honstly intellectually overwhelmed by what these events do in full detail, though I just spent more than half an hour in attempting to do so. E.g. I don't understand if all this works as it should if the player choses to change the order of targets.
Title: Re: good-secondary-time
Post by: 0rph3u5 on February 16, 2020, 02:32:22 pm
Think more about what tool/SEXPs I used rather than the whole execution - I am pretty sure I made more than one mistake in each one and/or that I missed a condition; and I am sure that they can be compressed somewhat. (I happens when I prototype without the intend to test myself)

Attached is the mission file, if it is just the output that is making it hard for your to read.

Basically, the first one checks each of the Beta if they fired from their secondary banks, and that at ([Full compliment of a bank] - 2 * [target index number, starting with 1]) their secondaries would be locked, and they would be excluded from the check. If all Betas had been successfully checked in this matter, the event will move the [target index number] to the next one, which will then allow a similar check (but with a lower limit per bank) while the attack on the next target takes place.

The second one basically does something similar but instead of checking individual banks it adds up the maximum torpedoes avalible as Beta arrives and then uses that number to calculate the limit at which to switch targets. The other events basically just keep track at how many torpedoes remain (for the check against the limit) and how many Betas are actually still on the board (for the purposes of calculation).

(ps. when I started this I could have sworn there was SEXP to test if a when-argument no longer had any valid arguments; I couldn't find it so build the workaround with the variable)


The player changing the orders for Beta is a different problem, I had not yet considered... You can always overrule the player by giving the ai-chase order a priority of 100+ ...

Other than that, Scripting? ;)

[attachment eaten by a Shivan]