Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - imagazzell

#21
Thank you, Snarky. Timers are one thing I was definitely missing in my scripting, and using one has gotten me much closer. I've got it set up so that the subsequent scripts only happen once the timer runs out, allowing the voice clip to play as desired. I've even got the pseudo speaking animation working.

The only issue I'm experiencing now is that my overlay disappears as soon as my script cuts away to another function (as I'm sure it's designed to do), but I need it to stay displayed while my script bounces around between other functions. Can this be done?

I can't use Wait commands in conjunction with the timer, because the player needs un-blocked control while it's running.

I tried putting the Overlay.CreateTextual command (with conditional statements) in repeatedly_execute and repeatedly_execute_always, but AGS didn't seem to like that and kept crashing.

How else can I keep the overlay displayed when leaving the function in which it was generated?
#22
Thanks for the replies, guys. I'm still having trouble getting it to work. Perhaps a bit more context would be helpful...

I'm trying to create a little mini-game within my game in which the player must repeatedly click a button on a custom GUI for as long as the NPC is speaking in order to succeed. I suppose you could call it something like a quick time event.

The scripting for it is currently spread across a few modules.

The first one simply handles the animation of a meter on the custom GUI that the player must keep from running out by clicking the button repeatedly. That all works fine, as tested on its own without characters speaking. The function should be called at the start and end of the quick time event with "meter_toggle(int on_off)" (where 1 = on, 0 = off), to start and stop the animation of the meter.

In the script for the room where the quick time event happens, I have some simple commands for what happens if the meter DOES run out, under the repeatedly_execute_always function. Again, no issue here so far.

The bulk of the mini-game is handled in a dedicated script for the QTE, with the relevant portions as follows (originally):

Code: ags
gMeter.Visible = true;
meter_toggle(1);

cNPC.Say("&1 Blah, blah, blah.");

meter_toggle(0);

But, as was the point of my OP, since Character.Say is a blocking function, this doesn't allow the player to click the GUI button.

So I tried implementing Crimson's suggestion...

Code: ags
gMeter.Visible = true;
meter_toggle(1);

Overlay* myOverlay = Overlay.CreateTextual(50, 80, 120, Game.SpeechFont, 15, "Blah, blah, blah.");
Game.PlayVoiceClip(cNPC, 1, true);
    
meter_toggle(0);

...but I must be doing something wrong because, while it displays the text, the voice clip does not play, and the script races onward to the subsequent lines. I'll also need to figure out how to implement myOverlay.Remove after the audio stops playing.

And I'll still need to work in playing the character's speaking animation (sans lip-sync) somewhere, but I'm trying to get one step to work at a time.

Any further advice?


PS: Kastchey, I like the clever workaround for getting the cursor to show, but like you said, clicks are handled on game loops, so I don't think that's going to do the trick here.
#23
Hi all,

Okay, here's the premise of what I'm trying to do: simply put, I want the player to be able to click a button on a custom GUI while another character is speaking (LucasArts-style).

I think I've got most of it handled. The one big sticking point, as far as I can see, is Character.Say being a blocking function, making the mouse/cursor unavailable while the character is talking.

I don't think I want to use SayBackground, because I want the character's speaking animation and speech clip to play like normal. I suppose, with no other option, I could fake it with SayBackground, a non-blocking animation of the character's talking view, and audio clips of the lines of dialogue, but that seems a bit clunky and sacrifices lip-syncing.

Is there any other (better) way to do this?

Thanks in advance for any tips.
#24
Quote from: eri0o on Sun 04/09/2022 00:01:42
Really nice theme! I think the gray script is a bit hard to read.
Thanks for the feedback. I've tweaked the light script version to make the script editor's background a touch lighter for better readability. I don't think I'd want to push it much more though, since the goal is low contrast.

I've updated the link above with the new files. Please re-download to check it out.
#25
Modules, Plugins & Tools / Gray Color Theme
Sat 03/09/2022 22:47:57
Hello all,

In the interest of reducing eye-strain, I made a gray color theme for the editor. The VisualStudioDark theme was better than the default white, but sometimes even dark themes are too high-contrasty for my liking. This theme is essentially half way between the two.

If, like me, your eyes crave a softer look, you're welcome to use it too. There are two versions: one using the VisualStudioDark theme's colors for the script editor, which is nice when balanced out by the rest of AGS in gray, as well as a version with lighter script editor colors.

Download here and import the theme(s) via the Preferences menu in AGS.

Enjoy!
#26
After going a couple weeks without any bites on here, I went ahead and put in the work to match the default theme as close as I could figure out while retaining the dark theme for the script text editor. Having gotten to know the theme file a bit, I also took the initiative to make a gray theme, essentially half way between the default and dark themes. That's what I'm using now, and it seems much easier on my eyes compared to the more high-contrast variants. If interested in any of these, feel free to PM me and I'll share a link with you.
#27
Hi gang,

So I'm looking to make a little tweak to the color theme of AGS. I like the majority of the plain default theme, but want to use a dark mode for just the script text editor, to be easier on the eyes while scripting.

I tried starting with the Visual Studio Dark theme and deleting everything but the relevant lines, but it appears the program wants values for everything.

Is there a .json file of the default theme somewhere that I can copy over the rest of the values from?

Alternatively, is there a resource with more themes somewhere? I could only find a couple here on the forums.

Thanks in advance.
#28
*facepalm* Thanks, Snarky. I hadn't seen that, but at least now I know my intuition was on the right track, and it led me to a solution. I added my Mouse.Click command to the OnActivate event and voila, got me the behavior I was looking for. Thanks again.
#29
Hi guys,

I've been working on setting up my hotkeys for optional keyboard control, and so far everything had been working fine. However, in my custom savegame GUI, while the arrow and escape keys still work fine, the return (enter) key is not responding with its hotkey assignment (Mouse.Click), in just this one GUI. If I hit enter on any of the GUI's buttons, nothing happens, yet if I click those same buttons with the mouse, they work fine.

What could cause this misbehavior? I've tried using other hotkey assignments for the enter key (e.g., GUI.ProcessClick), as well as directly calling the buttons' functions, all to no avail.

My only guess is that it may have something to do with the fact that I have a text box (for entering savegame names) in that GUI, and since that requires the keyboard for typing in names, maybe that's overriding the use of the enter key or something...?

Any ideas and suggestions are much appreciated!
#30
So I've almost gotten the text width-constrained highlighting to work. It waits until you are actually over the text on the x-axis before highlighting, but there is a side-effect where, if you mouse above a line of text, parallel to its x-axis but not on its y-axis, it will still highlight it.

Here's the relevant part of the script, with my addition starting at the "&&" on line 8:

Code: ags

int ypos = 0;
// Find the option that corresponds to where the mouse cursor is
for (int i = 1; i <= info.DialogToRender.OptionCount; i++)
{
  if (info.DialogToRender.GetOptionState(i) == eOptionOn)
  {
    ypos += GetTextHeight(info.DialogToRender.GetOptionText(i), eFontFont0, info.Width - 10);
    if ((mouse.y - info.Y) < ypos && (mouse.x < GetTextWidth(info.DialogToRender.GetOptionText(i), eFontFont0)))
    {
      info.ActiveOptionID = i;
      return;
    }
  }
}


Any ideas?

Here's the complete code from the global script, if anyone would like to test it on their end:

Code: ags

int dlg_opt_acolor = 13;
int dlg_opt_ncolor = 4;

function dialog_options_get_dimensions(DialogOptionsRenderingInfo *info)
{
  // Create a 400x200 dialog options area at (50,100)
  info.X = 50;
  info.Y = 100;
  info.Width = 400;
  info.Height = 200;
  // Enable alpha channel for the drawing surface
  info.HasAlphaChannel = true;
}

function dialog_options_render(DialogOptionsRenderingInfo *info)
{
  int ypos = 0;
  
  for (int i = 1; i <= info.DialogToRender.OptionCount; i++)
  {
    if (info.DialogToRender.GetOptionState(i) == eOptionOn)
    {
      if (info.ActiveOptionID == i)
        info.Surface.DrawingColor = dlg_opt_acolor;
      else
        info.Surface.DrawingColor = dlg_opt_ncolor;

      info.Surface.DrawStringWrapped(5, ypos, info.Width - 10,
              eFontFont0, eAlignLeft, info.DialogToRender.GetOptionText(i));
      ypos += GetTextHeight(info.DialogToRender.GetOptionText(i), eFontFont0, info.Width - 10);
    }
  }
}

function dialog_options_repexec(DialogOptionsRenderingInfo *info)
{
  info.ActiveOptionID = 0;
  if (mouse.y < info.Y || mouse.y >= info.Y + info.Height ||
      mouse.x < info.X || mouse.x >= info.X + info.Width)
  {
    return; // return if the mouse is outside UI bounds
  }

  int ypos = 0;
  // Find the option that corresponds to where the mouse cursor is
  for (int i = 1; i <= info.DialogToRender.OptionCount; i++)
  {
    if (info.DialogToRender.GetOptionState(i) == eOptionOn)
    {
      ypos += GetTextHeight(info.DialogToRender.GetOptionText(i), eFontFont0, info.Width - 10);
      if ((mouse.y - info.Y) < ypos && (mouse.x < GetTextWidth(info.DialogToRender.GetOptionText(i), eFontFont0)))
      {
        info.ActiveOptionID = i;
        return;
      }
    }
  }
}

function dialog_options_mouse_click(DialogOptionsRenderingInfo *info, MouseButton button)
{
  if (button == eMouseLeft) {
    if (info.ActiveOptionID > 0)
    info.RunActiveOption();
  }
}
#31
OK, I missed one small (but integral) detail on my first run through of the 'custom dialog options rendering' manual entry - the bit that says, "you need to do the following:" and that BOTH the dialog_options_get_dimensions and dialog_options_render functions are mandatory. On my first attempt, I tried using only one of the functions, which is why nothing was happening. So I've got it working now...

...partially...

I've got the text colors, placement, and sizing all how I want them, but am still unsure as to how to implement page arrows for overflow options.

Also, I would still like to limit the highlighting action to when you hover over only the actual text of each option, instead of the full width of the drawing surface. I imagine this might be achieved with a GetTextWidth command, similar to the GetTextHeight bits already being used in the code, but am not sure quite how to write that out, and in which part(s) of the script to place it.

Here's my current code, copied and adapted from one of the examples given in the manual article:

Code: ags

int dlg_opt_acolor = 13;
int dlg_opt_ncolor = 4;

function dialog_options_get_dimensions(DialogOptionsRenderingInfo *info)
{
  // Create a 400x200 dialog options area at (50,100)
  info.X = 50;
  info.Y = 100;
  info.Width = 400;
  info.Height = 200;
  // Enable alpha channel for the drawing surface
  info.HasAlphaChannel = true;
}

function dialog_options_render(DialogOptionsRenderingInfo *info)
{
  int ypos = 0;
  
  for (int i = 1; i <= info.DialogToRender.OptionCount; i++)
  {
    if (info.DialogToRender.GetOptionState(i) == eOptionOn)
    {
      if (info.ActiveOptionID == i)
        info.Surface.DrawingColor = dlg_opt_acolor;
      else
        info.Surface.DrawingColor = dlg_opt_ncolor;

      info.Surface.DrawStringWrapped(5, ypos, info.Width - 10,
              eFontFont0, eAlignLeft, info.DialogToRender.GetOptionText(i));
      ypos += GetTextHeight(info.DialogToRender.GetOptionText(i), eFontFont0, info.Width - 10);
    }
  }
}

function dialog_options_repexec(DialogOptionsRenderingInfo *info)
{
  info.ActiveOptionID = 0;
  if (mouse.y < info.Y || mouse.y >= info.Y + info.Height ||
      mouse.x < info.X || mouse.x >= info.X + info.Width)
  {
    return; // return if the mouse is outside UI bounds
  }

  int ypos = 0;
  // Find the option that corresponds to where the mouse cursor is
  for (int i = 1; i <= info.DialogToRender.OptionCount; i++)
  {
    if (info.DialogToRender.GetOptionState(i) == eOptionOn)
    {
      ypos += GetTextHeight(info.DialogToRender.GetOptionText(i), eFontFont0, info.Width - 10);
      if ((mouse.y - info.Y) < ypos)
      {
        info.ActiveOptionID = i;
        return;
      }
    }
  }
}

function dialog_options_mouse_click(DialogOptionsRenderingInfo *info, MouseButton button)
{
  if (button == eMouseLeft) {
    if (info.ActiveOptionID > 0)
    info.RunActiveOption();
  }
}
#32
Hi, folks.

Well I'm now venturing into dialog territory, and I wanted to set up a system akin to the CMI style - a transparent background overlay, different text colors than AGS' defaults, arrows for scrolling copious dialog options, etc.

I quickly gathered that I couldn't have all of these things with the built-in system, so naturally I turned toward using a custom GUI (not a text window GUI either, because I wish to control the placement of the GUI and don't want a border), but now I've hit a few roadblocks. I read through several older posts about similar matters, but am not sure if some things that were previously considered impossible now have workarounds. I also went through the 'custom dialog options rendering' article in the manual and tried implementing some of the functions, but it wasn't quite working out for me (not sure if it's not applicable for what I'm trying to do or if I was just doing it wrong).

Here's what I'm after but haven't been able to figure out:

1. The default color for dialog options. I believe this is normally tied to the player character's speech color, but (if possible) I'd like to be able to adjust this.

2. The highlight color for dialog options when hovered over with the mouse. I know this can be done with a text window GUI, but again I'm not using that here (for the reasons given above), and I saw that someone in an older thread was able to figure out how to change this for Sierra style dialog, but at the time it seemed like it wasn't possible to do so with the method I'm using. I'm hoping this has changed or that one of you clever wizards can come up with something.

3. How would I implement arrows (using custom graphics, no less) for scrolling through excess options? Is it anything like how it's done for inventory pages?

4. This one's just a minor niggle: Is there any way to constrain the act of highlighting an option to hovering over only the actual text of each option, rather than the entire width of the GUI for each line?


Any assistance with these is much appreciated.
#33
Great! Thank you. Seems obvious now, looking back at it.

And thanks again for the clever idea. I'll report back if I encounter any roadblocks implementing it.
#34
Quote from: timid_dolphin on Mon 22/11/2021 19:26:23
Ok, so here's how it works:

first you need to go into the character editor and add a custom property to the schema for your alternate views, eg angryView. For each character you can initialise this in the character editor with the view you want to use.
Hey, timid_dolphin. I like the sound of this approach for the organization and streamlined scripting, but I'm a little unclear on how to set up the custom properties (i.e., what to set as the type and value, etc.). Are you simply setting the type to "number" and the value to the number of the appropriate view?
#35
Quote from: timid_dolphin on Wed 17/11/2021 04:45:34
I've got a bunch of general mood functions in a script file with all of my little character animations.
So all of the logic around changing character views is encapsulated in these, and they can be easily called from anywhere in the script, or within dialogue scripts.

eg:
  paulThinking();
PAUL: Hey, wait a second...
  paulAngry();
PAUL: That guy didn't pay for those bananas!
  paulShakeFist();
  paulSigh();
  paulNeutral();
PAUL: Oh well...
Yeah, something like that is what I had in mind for the mood views. Did you just put all of the called functions in your global script or did you create a new script for all of them?
#36
Yeah, the mood-specific view changes would be in addition to the normal view variations, and in those cases, you are exactly right.
#37
Hey, Khris. Maybe I'm not following what you're suggesting, but my idea for a function under repeatedly_execute was for randomizing the plain (moodless) speech view between, say, 3-4 different animations, so that each time the character says something, it won't be the same single view every time, without the need to manually write in a view change for every line of speech. The thought was that whenever the character speaks, it will play the currently assigned view animation, which is continuously, automatically randomizing in the background, without me needing to tell it to use a different view each time. Is there a better approach for such a result?
#38
Yeah, I figured it would come down to having a bunch of different views and changing SpeechView each time, I was just wondering if there was a more clever and efficient way of doing it that I wasn't aware of. Maybe I can throw a function under repeatedly_execute that randomizes the standard speech view automatically, so that I'd only have to write in a manual view change when the character takes on a specific mood, rather than with every single line of dialogue. I'll think on it some more.

Thanks for the feedback, all.
#39
Quote from: Khris on Fri 12/11/2021 08:22:30
For a second idle view you can use
Code: ags
  cEgo.SetIdleView(ROGERIDLE + Random(1) * (ROGERLEGIDLE - ROGERIDLE), Random(5)+5);

in that case, this will play either view randomly.
Thanks, Khris! And if I wanted to have the foot-tapping happen less frequently than the blinking (say, between every four blinking animations)? Maybe just set a counter within the randomized blinking code that would trigger the foot-tapping instead? Seems fairly straightforward.

Quote from: Cassiebsg on Fri 12/11/2021 16:05:33
Make sure that all the sprites are in the correct loop.
On my latest game I had a "bug" that was driving me nuts, as my character was facing the wrong way on a single view/loop, and I couldn't figure out why. After several days trying to fix it, I looked at the sprites and noticed that I had a single wrong sprite in that exact loop.  (roll)

Not saying it's your case, but just make sure.  ;)
Thank you for the suggestion, Cassiebsg, but I was sure to double and triple-check and re-assign the sprites again, but the error still occurred. I'm thinking it's either something else in my scripts throwing it off, the idle view not honoring diagonal directions, or indeed a bug, as Khris said.
#40
Quote from: Khris on Thu 11/11/2021 23:27:10
You mean like the character is both tapping their foot and blinking, independently? That's much harder because AGS doesn't really support animating the head and body separately the way the Lucasfilm games did. It's possible somehow but can't be achieved with just a few lines of code unfortunately.
The animations don't have to occur independently. The foot tapping (or whatever else) can happen between blinking animations by itself, either at specific intervals or randomly too. Thoughts on how best to approach that? Another timer within the function we already created, perhaps?


I've also noticed a strange issue with the blinking animations. Do idle views not honor diagonal loops like walking views do? The wrong blink loops seem to be firing after my character has walked in a diagonal direction and gone idle. The four primary directions seem to be using the correct loops.
SMF spam blocked by CleanTalk