Results 1 to 12 of 12

Thread: Reload-safe Yes/No Events

  1. #1
    Withwnar's Avatar Script To The Waist
    Join Date
    Oct 2008
    Location
    Earth
    Posts
    6,329

    Default Reload-safe Yes/No Events

    (To my knowledge this isn't mentioned in any of the Yes/No tutorials out there.)

    The response to a "historic_event xxx true" will either be "accepted" or "declined", right? Not necessarily: if the player saves the game while that scroll is open then the response is "neither" when that save is reloaded.

    Code:
    monitor_event (whatever)
    
      ;show the yes/no scroll
      historic_event my_he true 
    
    terminate_monitor
    end_monitor
    
    monitor_event EventCounter EventCounterType my_he_accepted
      and EventCounter > 0
    
      ;answered "yes" ... do something
    
    terminate_monitor
    end_monitor
    
    monitor_event EventCounter EventCounterType my_he_declined
      and EventCounter > 0
      
      ;answered "no" ... do something else
    
    terminate_monitor
    end_monitor
    (NOTE: if this historic event occurs more than once in the campaign then remove the terminate_monitors.)

    As explained in other tutorials historic_event implicitly creates the my_he_accepted and my_he_declined event counters and they will be 0. When the player clicks the Accept button my_he_accepted is incremented (adds 1, so is now 1) and that second monitor fires. Likewise for the Decline button.

    BUT: if the game is saved while the scroll is open then at that point both event counters are still 0. So as far as the saved game is aware the question has been asked but no answer has been given. Therefore when that save is reloaded that is the state of things: both event counters are 0 and the reload does not automatically show the yes/no scroll. So the question has not been answered and the question will not be re-asked.

    A solution is some extra script to re-ask the question when a reload occurs...

    Code:
    declare_counter my_he_awaiting_answer ;0 = false, 1 = true
    
    monitor_event (whatever)
    
      ;show the yes/no scroll  
      set_counter my_he_awaiting_answer 1
      historic_event my_he true 
    
    end_monitor
    
    monitor_event EventCounter EventCounterType my_he_accepted
      and EventCounter > 0
    
      ;answered "yes" ... do something
      
      set_counter my_he_awaiting_answer 0
    
    terminate_monitor
    end_monitor
    
    monitor_event EventCounter EventCounterType my_he_declined
      and EventCounter > 0
      
      ;answered "no" ... do something else
    
      set_counter my_he_awaiting_answer 0
    
    terminate_monitor
    end_monitor
    
    monitor_event GameReloaded TrueCondition
    
      if I_CompareCounter my_he_awaiting_answer = 1
        campaign_wait 0.1
        historic_event my_he true
      end_if
    
    end_monitor
    I found the campaign_wait to be necessary: the scroll would not appear without it. No idea why not.

    my_he_awaiting_answer must be set to 0 in BOTH response monitors. Sometimes only one monitor is needed, e.g. you only need to handle them answering "yes" and do nothing if they answer "no". That's no good here because if they answered "no" then my_he_awaiting_answer is still 1 so when the player reloads they will be asked the question again.

    P.S. This can't be said enough: do not use monitor_conditions for your response monitors, use "monitor_event EventCounter"!
    Last edited by Withwnar; May 14, 2016 at 10:33 PM.

  2. #2
    Gigantus's Avatar I am not special - I am a limited edition.
    Patrician took an arrow to the knee spy of the council

    Join Date
    Aug 2006
    Location
    Goa - India
    Posts
    53,125
    Blog Entries
    35

    Default Re: Reload-safe Yes/No Events

    Like the stuff, a bit esoteric seeing that it's likelihood is marginally but good to know. Never came across the GameReloaded event, any other uses for it?

    Script: how about adding this terminate_monitor line? That should still keep the script functional but remove the monitor? The last monitor can be used nicely for all other historic events as well.

    Code:
    declare_counter my_he_awaiting_answer ;0 = false, 1 = true
    
    monitor_event (whatever)
    
      ;show the yes/no scroll  
      set_counter my_he_awaiting_answer 1
      historic_event my_he true 
      terminate_monitor
    end_monitor
    
    monitor_event EventCounter EventCounterType my_he_accepted
      and EventCounter > 0
    
      ;answered "yes" ... do something
      
      set_counter my_he_awaiting_answer 0
    
    terminate_monitor
    end_monitor
    
    monitor_event EventCounter EventCounterType my_he_declined
      and EventCounter > 0
      
      ;answered "no" ... do something else
    
      set_counter my_he_awaiting_answer 0
    
    terminate_monitor
    end_monitor
    
    monitor_event GameReloaded TrueCondition
    
      if I_CompareCounter my_he_awaiting_answer = 1
        campaign_wait 0.1
        historic_event my_he true
      end_if
    
    end_monitor










  3. #3
    Withwnar's Avatar Script To The Waist
    Join Date
    Oct 2008
    Location
    Earth
    Posts
    6,329

    Default Re: Reload-safe Yes/No Events

    Another scenario is when you quit after a turn end. The last-saved game is now the Autosave so if you try and load that one next time, or just Continue Campaign, then any yes/no message that was generated during that turn end will be lost ... you might not even be aware that it was ever there (if you quit before seeing what the event messages were).

    If that was an important yes/no question then that's bad news for the player. For example, in TATW to reforge Arnor you need to raise a city to Large City level (and TATW has low population growths), build an expensive building (12 turns) and hold certain regions. This all takes 80 turns or so. Then you are asked with a yes/no whether you want to do it. If you quit before answering then that's it: never asked again, unless you go back in time with an older save (if you have one).

    GameReloaded event, any other uses for it?
    Another use for the event is when script might be waiting for the player to select a character or settlement, to perform some special action. e.g. A kill character script: player initiates it somehow and now whoever the player clicks on script will kill. If the game was saved during that wait phase and reloaded (who knows when) then it's probably better that script does NOT kill the first character the player clicks on because chances are they totally forgot that the game was currently in this phase. Better to cancel the phase via GameReloaded and let the player restart the process again if/when they wish to.

    how about adding this terminate_monitor line? That should still keep the script functional but remove the monitor?
    If the question is only to be asked once per campaign then, sure, terminate that monitor. The reload-ask-again script doesn't need it. But I'm not sure that I follow the "keep the script functional" part.

    The last monitor can be used nicely for all other historic events as well.
    That's right.

  4. #4
    Gigantus's Avatar I am not special - I am a limited edition.
    Patrician took an arrow to the knee spy of the council

    Join Date
    Aug 2006
    Location
    Goa - India
    Posts
    53,125
    Blog Entries
    35

    Default Re: Reload-safe Yes/No Events

    "keep the script functional" - I wasn't sure if terminating the monitor would prevent it from being reloaded in case if the interruption.

    I think I'll incorporate that into my current mod, always nice to take care of a possible stumbling block. Thanks.










  5. #5
    Withwnar's Avatar Script To The Waist
    Join Date
    Oct 2008
    Location
    Earth
    Posts
    6,329

    Default Re: Reload-safe Yes/No Events

    I wasn't sure if terminating the monitor would prevent it from being reloaded in case if the interruption.
    I see. No, it makes no difference.

    Thanks.

  6. #6

    Default Re: Reload-safe Yes/No Events

    Just a small small detail: Since the "historic_event" command increases the value of the event_counter in reference, we can avoid using "awaiting_answer" counters by using the my_he event_counter itself. Of course, this should be avoided if the my_he event_counter is to be used elsewhere (like for example in EDCT or a later event).

    Spoiler Alert, click show to read: 
    Code:
    monitor_event (whatever)
    
      ;show the yes/no scroll  
       historic_event my_he true 
    
    end_monitor
    
    monitor_event EventCounter EventCounterType my_he_accepted
      and EventCounter > 0
    
      ;answered "yes" ... do something
      
      set_event_counter my_he 0
    
    terminate_monitor
    end_monitor
    
    monitor_event EventCounter EventCounterType my_he_declined
      and EventCounter > 0
      
      ;answered "no" ... do something else
    
      set_event_counter my_he 0
    
    terminate_monitor
    end_monitor
    
    monitor_event GameReloaded
    
        campaign_wait 0.1
       if I_EventCounter my_he > 0
         historic_event my_he true
      end_if
    
    end_monitor


    Quote Originally Posted by Withwnar View Post
    my_he_awaiting_answer must be set to 0 in BOTH response monitors. Sometimes only one monitor is needed, e.g. you only need to handle them answering "yes" and do nothing if they answer "no". That's no good here because if they answered "no" then my_he_awaiting_answer is still 1 so when the player reloads they will be asked the question again.
    In this and some other cases, it might be preferable if we do this:
    Spoiler Alert, click show to read: 
    Code:
    monitor_event (whatever)
    
        ;show the yes/no scroll  
        historic_event my_he true 
    
        while I_EventCounterType my_he_accepted = 0
        and I_EventCounterType my_he_declined = 0
        end_while
    
        set_event_counter my_he 0
    
        if I_EventCounterType my_he_accepted = 1
            ;answered "yes" ... do something
            set_event_counter my_he_accepted 0
        end_if
    
        if I_EventCounterType my_he_declined = 1
            ;answered "no" ... do something else
            set_event_counter my_he_declined 0
        end_if
    
    end_monitor
    
    monitor_event GameReloaded
    
         campaign_wait 0.1
      if I_EventCounter my_he > 0
         historic_event my_he true
      end_if
    
    end_monitor


    A note: It is intentional that I use "if I_EventCounter my_he > 0" and not "= 1". Obviously, if I had used "= 1", the GameReloaded monitor would re-pop the my-he message only once per turn; that is, if I reload for second time without answering the my_he question before, it won't pop up the my-he message.
    Last edited by gsthoed; December 05, 2014 at 04:11 PM.

  7. #7
    Withwnar's Avatar Script To The Waist
    Join Date
    Oct 2008
    Location
    Earth
    Posts
    6,329

    Default Re: Reload-safe Yes/No Events

    Since the "historic_event" command increases the value of the event_counter in reference, we can avoid using "awaiting_answer" counters by using the my_he event_counter itself.
    Good point.

    That also raises another important point: in either script (yours or mine) after the historic_event is executed in the GameReload monitor, the value of my_he will be 2 instead of 1. If any code/script is using the value of that event counter then they would need to allow for that.

    Quote Originally Posted by gsthoed View Post
    In this and some other cases, it might be preferable if we do this:
    Spoiler Alert, click show to read: 
    Code:
    monitor_event (whatever)
    
        ;show the yes/no scroll  
        historic_event my_he true 
    
        while I_EventCounterType my_he_accepted = 0
        and I_EventCounterType my_he_declined = 0
        end_while
    
        set_event_counter my_he 0
    
        if I_EventCounterType my_he_accepted = 1
            ;answered "yes" ... do something
            set_event_counter my_he_accepted 0
        end_if
    
        if I_EventCounterType my_he_declined = 1
            ;answered "no" ... do something else
            set_event_counter my_he_declined 0
        end_if
    
    end_monitor
    
    monitor_event GameReloaded
    
         campaign_wait 0.1
      if I_EventCounter my_he > 0
         historic_event my_he true
      end_if
    
    end_monitor
    There are some potential problems with that way of doing it:

    1) while loops yield execution, so while this monitor is stuck in that loop the rest of the script/game will carry on. In this example that's fine - functionally no different to using EventCounter monitors to handle the response - but it's something to keep in mind, especially when coupled with 2)...

    2) If this monitor had any other script after the while loop (e.g. spawn armies, whatever) then that won't happen until the player has answered the question. That might be a good or bad thing, depending on the situation. That is, I mean, extra script that is to execute regardless of how the question was answered.

    3) If the _accepted or _declined event counters are used by other script/code then this will break them, as the counters are being set back to 0 when they become 1, so they're effectively never 1. In that case it would be better to set both of these event counters to 0 before the historic_event in the first monitor, not in the IFs.

    Just a general heads up. In some cases, maybe even most, none of those would be issues at all.

    if I had used "= 1", the GameReloaded monitor would re-pop the my-he message only once per turn; that is, if I reload for second time without answering the my_he question before, it won't pop up the my-he message.
    Do you mean if you saved and reloaded a second time? If the question had only been asked once - by the first monitor - when the save is done then it wouldn't matter how many times you reload that save: within the save my_he is still 1. But if you save a second time, after the reload monitor reasks the question but before you answer it, then my_he will be 2 in the save.

  8. #8

    Default Re: Reload-safe Yes/No Events

    Quote Originally Posted by Withwnar View Post
    Do you mean if you saved and reloaded a second time?
    Yes!
    These potentials problems you pointed out are valid; because of this, when I want to script a yes/No event, I always start with the original OP method and I check if I can apply the "while loop" method afterwards.

    There is a "4th" potential problem that may affect even the OP method, but it is totally catastrophic for the last method. It is a rare case in hotseat campaigning and one of the bugs for which I'd say "You asked for it, buddy".
    In non-hotseat, eventually you will answer a reload-safe my_he question, as you cannot change turn having this unanswered.
    In hotseat campaigning, it is "safer" to trigger a "Yes/No" event only during human player's turn. You have pointed it elsewhere; I just repeat an example here:
    Code:
    monitor_event FactionTurnStart not IsFactionAIControlled
    
        if I_LocalFaction england
            historic_event my_he true factions { england }
        end_if
        if I_LocalFaction france
            historic_event my_he true factions { france }
        end_if
        ;etc
    
    end_monitor
    You can skip answering the my_he question with two ways:
    a) by giving the control of current local or all human controlled factions to the AI [for example, a player quits participating in a multiplayer game (?) ]
    b) A human-controlled faction gets destroyed before having answered the question! In a non-hotseat game, we don't need to do anything to prevent this, because the campaign ends at this point. In hotseat, the campaign continues if there is at least one other human-controlled faction or one AI-controlled faction passes to human control before the end of the (slave's) turn this destruction takes place*.

    The game engine can handle this. In "my" method, however, the while loop does not end and in both methods the GameReloaded monitor will pop up the my_he message to the "wrong" faction or to an AI-controlled faction (not sure how the game engine handles the latter, but I remember the game was stuck for a while when I tried this some months ago).

    There are some other possible workarounds; but I think the easiest is this:
    - In OP method, you reset the "awaiting_answer" counters in a FactionTurnEnd monitor.
    - In the "while loop" method, you reset the my_he event_counter (or one other relevant counter) in a FactionTurnEnd monitor and the while loop goes like this:

    Code:
        while I_EventCounterType my_he > 0
        and I_EventCounterType my_he_accepted = 0
        and I_EventCounterType my_he_declined = 0
        end_while
    As I said, it is a bug that someone has to "ask for it"; noteworthy though for "hotseat fanatics".

    *BTW: Once the last human-controlled faction gets destroyed and up until a new factions passes to human control or turn ends, there is no Local Faction (and this is the only case this can happen).
    Last edited by gsthoed; December 06, 2014 at 11:49 AM. Reason: fix syntax and grammar errors

  9. #9
    Withwnar's Avatar Script To The Waist
    Join Date
    Oct 2008
    Location
    Earth
    Posts
    6,329

    Default Re: Reload-safe Yes/No Events

    My dislike for hotseat just went up a couple of notches.

    That's good to know.

  10. #10
    Gigantus's Avatar I am not special - I am a limited edition.
    Patrician took an arrow to the knee spy of the council

    Join Date
    Aug 2006
    Location
    Goa - India
    Posts
    53,125
    Blog Entries
    35

    Default Re: Reload-safe Yes/No Events

    This set up just crossed my mind because I really didn't fancy editing a large multitude of 'HE true' monitors:

    Code:
    monitor_event GameReloaded TrueCondition
    
      if I_CompareCounter [he_true_event] = 1
        and I_CompareCounter [he_true_event]_accepted = 0
        and I_CompareCounter [he_true_event]_declined = 0
        campaign_wait 0.1
        historic_event [he_true_event] true
      end_if
    
    end_monitor
    Would that do the job? Unfortunately it will not help anyhow unless I copy all the other stuff below the original historic_event line as well - so it's going to be a humongous copy\paste orgy. Advising to use the last auto save is probably easier










  11. #11
    Withwnar's Avatar Script To The Waist
    Join Date
    Oct 2008
    Location
    Earth
    Posts
    6,329

    Default Re: Reload-safe Yes/No Events

    Yes, but they must be I_EventCounter not I_CompareCounter. And it is assuming that the HE is only asked once per campaign (or that its event counter and its accept/decline counters are reset to 0 before being reused).

  12. #12
    Gigantus's Avatar I am not special - I am a limited edition.
    Patrician took an arrow to the knee spy of the council

    Join Date
    Aug 2006
    Location
    Goa - India
    Posts
    53,125
    Blog Entries
    35

    Default Re: Reload-safe Yes/No Events

    Thanks, it's certainly easier then juggling counters.










Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •