Run a cycle of current Room's repeatedly_execute after every blocking routine?

Started by DrLilo, Fri 08/11/2024 18:36:10

Previous topic - Next topic

DrLilo

Hi guys.

I'm wondering if there's a way to force a single cycle of the player's current Room's repeatedly_execute function to be run each time the player is about to exit a blocking routine (but before the GUI becomes visible again).

The idea is to prevent the GUI from appearing for a single frame and then disappearing again, if a variable was set during a blocking routine that is going to trigger another blocked routine from within the repeatedly_execute function. (ie, if(solvedPuzzle==true){ something immediately happens }).

I'm already a good way into this project and have been structuring (perhaps naively) most of the events in this way, where the repeatedly_execute function is looking for a variable and then animates a cutscene when it sees the change, but the annoying result is seeing a frame of flicker where the GUI becomes visible and then gone again, in between the player's previous action and the resulting cutscene.

What I (think) I need is for there to be a single cycle of the Room's repeatedly_execute function every time the player is about to regain control (and the GUI reappear), that way we go smoothly into each cutscene or very quickly back to normal gameplay if no variable has been set.

If anyone knows if that's possible please let me know, if not, I'm open to suggestions for other ways to prevent that one frame of GUI flicker. (However if you're about to say "don't handle cutscenes that way" it's a little late, tbh...)

Crimson Wizard

Hm, could you clarify how do you make GUIs invisible during blocking actions, are you using a setting "When interface is disabled GUI should -- Be hidden", or script this GUI hide/show yourself?

In regards to the whole thing, it looks like you need a way to mark a "blocking state" by hand, to be able to unmark it 1 non-blocked cycle later.

There's a group of functions: EnableInterface, DisableInterface, IsInterfaceEnabled, and my impression is that this "disabled" state works as a counter (similar to PauseGame/UnpauseGame). Any blocking action increments this counter on start and decrements when ends, but so does any manual call to EnableInterface and DisableInterface correspondingly.

So, as theoretical possibility, you could call DisableInterface() before running first part of the cutscene, then inside "repeatedly_execute", where you don't need to run a second part of the cutscene, check IsInterfaceEnabled  and call EnableInterface() if it is. This would enable GUI right after "repeatedly_execute" is run first time.

EDIT: I also have a guess that you might be able to automate this by checking "game.disabled_user_interface" variable in "repeatedly_execute_always", and if it's only 1, then either increasing it by hand +1 or calling DisableInterface, to make it 2.

Maybe you will need extra variable to be able to tell if you just wanted to disable gui while no blocking action is played, but I don't know if you ever do.

EDIT2: If you do not use this setting, but your own custom code, then you could probably replicate the above solution using your own functions and variables.

eri0o

I think it would be easier to disable this behavior and handle it manually, then they become visible or invisible however you want to handle.

DrLilo

Quote from: Crimson Wizard on Fri 08/11/2024 18:55:23Hm, could you clarify how do you make GUIs invisible during blocking actions

I'm doing nothing special, it's the default behaviour of Tumbleweed to hide gMain whenever there's dialogue or anything with eBlock, such as player.Walk. I'm not sure whatever they're doing to hide gMain is exposed, I can't find any isntances of EnableInterface in VerbGUI.asc for example...


Crimson Wizard

Quote from: DrLilo on Fri 08/11/2024 19:03:34I'm doing nothing special, it's the default behaviour of Tumbleweed to hide gMain whenever there's dialogue or anything with eBlock, such as player.Walk. I'm not sure whatever they're doing to hide gMain is exposed, I can't find any isntances of EnableInterface in VerbGUI.asc for example...

Well, that's the first thing to begin with: you need to clarify how it's done in your game, then it will be easier to say if you can accommodate that behavior for what you want, or it's better to scrap that and script your own custom solution.

DrLilo

Thanks all, I've been experimenting based on the feedback, but I'm not having a ton of luck. I've removed the default AGS behaviour to hide the GUI and created my own code to handle it, but it's gonna take a crap lot of QA to ensure it's working as elegantly as the default soluion.

I wonder if anyone has an answer to my initial thought, is there a way to remotely trigger a cycle of the current Room's repeatedly_execute function, besides just offsetting some manual code to occur after x number of cycles I mean...

Crimson Wizard

Quote from: DrLilo on Fri 08/11/2024 19:50:18I wonder if anyone has an answer to my initial thought, is there a way to remotely trigger a cycle of the current Room's repeatedly_execute function

No.

You may call a particular script function from another script function, but that will not solve your problem, as you got to call it from some event too, and that event likely will occur after the blocking action has finished and the screen has already redrawn once. (and if you call it from functions like repeatedly_execute_always, then no new blocking actions cannot be run)

Khris

I'm too tired to really think this through but from a technical standpoint this should be possible:

Code: ags
function Room_RepExec() {
  ...
}

function on_call(int param) {
  if (param == 1) Room_RepExec();
}

  // elsewhere
  CallRoomScript(1);

No idea whether this will solve the problem though.

Another way to tackle this is to change the template's code so that the interface isn't enabled/disabled immediately but after a short timer has expired.

DrLilo

Thanks everyone, based on the feedback above I ended up disabling the global setting to hide interface and instead handled it manually using a 1 cycle delay as suggested. It feels a bit hacky, but the whole game now feels considerably more seamless without those 1 frame GUI flickers.

SMF spam blocked by CleanTalk