MODULE: SpeechBubble v0.8.0

Started by Snarky, Sun 03/12/2017 11:28:04

Previous topic - Next topic

bx83

Snarky, I have two things and wondering if they’re possible:
1. Turn off speechbubble easily (so they never display) by setting one option.
2. Not allow a speech bubble to be written off the right edge of the screen (at the moment it must start at x=0, but if a character is standing too far to the right, they’re speech bubble may be cut off). Is there a way to make their right edge or both edges impossible to be drawn off screen?

Snarky

Quote from: bx83 on Fri 09/04/2021 06:56:05
Snarky, I have two things and wondering if they’re possible:
1. Turn off speechbubble easily (so they never display) by setting one option.

I'm not sure what this means, exactly. The speech bubble is shown when you explicitly tell it to be shown, by a command such as cCharlie.SayBubble("Blah, blah");. If you don't want it to be shown, you should not call this method. If you want to be able to switch between displaying text in a speech bubble or with built-in speech, you would need to write a custom function for that which would check the variable and call the appropriate function.

Quote from: bx83 on Fri 09/04/2021 06:56:05
2. Not allow a speech bubble to be written off the right edge of the screen (at the moment it must start at x=0, but if a character is standing too far to the right, they’re speech bubble may be cut off). Is there a way to make their right edge or both edges impossible to be drawn off screen?

Looking over the module code, I don't see how it could position the bubble to be cut off on the right by more than 1 pixels:

Code: ags
// SpeechBubble.asc

int _clampInt(int value, int minRange, int maxRange) // line 347
{
  if(value<minRange) return minRange;
  if(value>maxRange) return maxRange;
  return value;
}

// ...
  x = _clampInt(x, 0, System.ViewportWidth - bubbleSprite.Width); // line 1314
  // ...
    bubbleOverlay = Overlay.CreateGraphical(x, y, bubbleSprite.Graphic, true); // line 1320


The position is constrained so that the sprite x-position is not above System.ViewportWidth - bubbleSprite.Width, and therefore it should only be cut off by 1 pixel at most (that's a small bug, but it sounds like you're talking about something bigger).

So unless you've modified the code, I don't see how this is possible.

bx83

I've just found out this only happens to Julius (main character), as he has a separate talking function (to accout for Z-axis alteration). I "reverse engineered" (ie hacked together unknowingly) the speech bubble function, which looks like this:

Code: ags
function cJulius_spk(String msg)
{
  // Calculate text dimensions
  int textWidth = -1;

  int w = System.ViewportWidth * 2/3;
  if(cJulius.x - GetViewportX() <= System.ViewportWidth/4 || cJulius.x - GetViewportX() >= System.ViewportWidth * 3/4) {
    w -= System.ViewportWidth/5;
  }
  textWidth=w;

  if(textWidth < (System.ViewportWidth - 40)) {
    textWidth=textWidth;
  } else {
    textWidth=System.ViewportWidth - 40;
  }
  
  int textHeight = GetTextHeight(msg, 1, textWidth);
  
  int cut = textWidth;
  int height = textHeight;
  while(cut>1) {
    cut = (cut+1) >> 1; // Subtract half as much as we tried last time, rounding up
    height = GetTextHeight(msg, 1, textWidth - cut);
    if(height == textHeight) {
      textWidth -= cut;
    }
  }
  height = GetTextHeight(msg, 1, textWidth-1);
  if(height == textHeight) {
    textWidth=textWidth-1;
  } else {
    textWidth=textWidth;
  }

  int totalWidth = textWidth + 20 + 20;
  int bubbleHeight = textHeight + 10 + 10;
  int totalHeight;
  totalHeight = bubbleHeight + 9;

  SpeechBubbleHeight_blr=totalHeight;

  int headHeight=355;     //constant
  int spaceAboveHead=8;  //constant

  float h=IntToFloat( SpeechBubbleHeight_blr ); //constant
  float f=( (IntToFloat(headHeight+spaceAboveHead)/100.0)*IntToFloat(cJulius.Scaling) ) + h;
 
  cJulius.SayAtBubble(cJulius.x, cJulius.y - FloatToInt(f), msg);
}


Would you be able to help me insert the viewport code? I can work it out but it'll take a long time.

bx83

Solved it. Had the problem in the code, for SayAtBubble().

Had
x = _clampInt(x, 0, System.ViewportWidth - bubbleSprite.Width/2);
instead of
x = _clampInt(x, 0, System.ViewportWidth - bubbleSprite.Width);

Not that it matters, but all good now :)

bx83

How can I display a Speechbubble so that it is on top of all GUIs? ie. Make it's ZOrder=1000 -- despite the fact it has no ZOrder and no obvious way of doing this... :/

Snarky

#105
By default, speech bubbles are drawn on overlays, which I think always appear below GUIs? Anyway, you cannot control their Z-order (though I believe this will be available in an upcoming AGS version). However, you can make it appear on a GUI by passing a bubbleGui argument to the SayBubble function, or setting the SpeechBubble.DefaultGui property. With a GUI you can control the Z-order through the property GUI.ZOrder.

(Only one character's speech can be displayed on a single GUI at a time, so if you have overlapping dialog through SayBackgroundBubble, you will need to set different GUIs for the different speakers.)

bx83

To myself, it's good to have a plan, but I don't think I could implement this in 6months. Basically all I'll trying to do is display a speech bubble at x=20, y=30, and have it appear above the Inventory GUI (which has a solid background) for all speech connected to i[something]_look() functions.

But anyway - when do you think this feature will be coming out re ZOrder? Is in the next version or 5 months of bug-fixing away? Just trying to get an idea.

Snarky

#107
I guess I wasn't explicit enough in my last reply. If you add a GUI gSpeechBubble to your project, then this code should display the speech on top:

Code: ags
gSpeechBubble.ZOrder = 1000; // Any number higher than the inventory GUI's z-order
cBob.SayBubble("Blah Blah Blah", gSpeechBubble);


Alternatively, you can put this in game start, and it will always use the GUI:

Code: ags
SpeechBubble.DefaultGui = gSpeechBubble;
gSpeechBubble.ZOrder = 1000;


However, as I tried to explain, this could potentially lead to trouble if you have overlapping speech using SayBackgroundBubble.

bx83

fir creating a bubble - you mean initialised with SpeechBubble *gInvBubble = SpeechBubble.Create(....  or..?

bx83

Okay, ignore that, made no sense.

I've made some progress...

Code: ags
void SayAtBubble(this Character*, int x, int y, String message, GUI* bubbleGui)
{
  if(message == null) return;
  if(!game.bgspeech_stay_on_display)
    _stopAllBackgroundBubbles();
  if((Speech.VoiceMode == eSpeechVoiceOnly && hasVoiceClip(message)) || message == "...") {
    this.SB_sayImpl(message);
  } else {
    DynamicSprite* bubbleSprite = this.renderBubble32(message, true);

.....
		} else {		
			x = this.x - GetViewportX() - bubbleSprite.Width/2;					//BLR
		}
		
		x = _clampInt(x, 0, System.ViewportWidth - bubbleSprite.Width);   // /2);
		
    if (DescribeItemInv) {
      cJulius.realSayAtBubble(1, 1, message, gInventory, null);
    } else {
      this.realSayAtBubble(x, y, message, bubbleGui, null);
    }
  }
}


DescribeItemInv is a switch I set up to say 'the inventory is showing'. Don't ask me why, I'll clean it up later.

Anyway - it now:
1. Instantly removes the gInventory GUI
2. Does the speech bubble
3. Prevents you from ever bringing the gInventory GUI up again

:/


ps. I have BTN_SB as a blank element in the gInventory GUI as a button. Should I leave it in?

bx83

....Aaaand I'm a moron. It was replacing the GUI not attaching to it. I created a new one with ZOrder=999, and it worked :)

Now - is there a way to get rid of the tail?

Snarky

I wish you would stop modifying the module code, and instead build helper functions on top of the module for stuff like this. It's very hard to support when the code you're using is not the code I wrote.

As for the tail, it should be a matter of setting SpeechBubble.TalkTail = null;
I seem to recall that there was some AGS bug/quirk that kept this from working correctly, but if so you can add the line import void set_TalkTail(static SpeechBubble, String value[]); and call SpeechBubble.set_TalkTail(null); instead.

Dave Gilbert

Hello! Quick question. I would like to have my speech bubbles display when a GUI is up on the screen. Right now they display behind the GUIs. Is there a way to set the zorder of the bubble?

Snarky

Hey Dave, this issue is discussed a few posts up in the thread, here.

Dave Gilbert


bx83

I have a problem that when I set a bubble with SayAtBubble(), it's x/y coords are totally static. If the speech bubble is placed directly above the head of a character, and it turns out it's 5 lines long, it will continue to go down the screen and obscure the character's head.

How would I alter things? eg:

Code: ags
SayAtBubble(talk_x, talk_y-(bubbleSprite.GetNumberOfLines*8), "&777 line");   //will push the speech bubble up by number of lines used in speechbubble * 8 pixels for each


Basically, I am wondering how I would alter SayAtBubble so that the bubble's tail, *NOT* the upper-left corner, is used to position it; though obviously this is very difficult, I just want to know where I would get the variable controlling number of text lines so I can do it sort-of automatically.

Snarky

#116
That is not supported because SayAtBubble() doesn't have any positioning logic. If you want to position the speech bubble to align the tail with the character, use SayBubble().

I would suggest you go back to the official version of the SpeechBubble module and use it as intended. If there's anything it won't allow you to do, or you have any bug reports or feature requests, let me know and I'll see how to address it. I am not going to continue supporting a hacked version.

Edit: At the same time, I know I have been neglecting this module for a long time, and it does need an update. PM me and let's figure out how I can best support your development and get the module to version 1.0.

eri0o

Hey Snarky, when you update the module, if you can please add the border support that was here : https://www.adventuregamestudio.co.uk/forums/index.php?topic=56121.msg636587529#msg636587529 (I don't think they made into the latest release).

bx83

Snarky, okay no worries. I'll keep in touch, atm just hacking-away all last known errors before release.

Snarky

Quote from: eri0o on Fri 21/05/2021 11:56:37
Hey Snarky, when you update the module, if you can please add the border support that was here : https://www.adventuregamestudio.co.uk/forums/index.php?topic=56121.msg636587529#msg636587529 (I don't think they made into the latest release).

Absolutely. I have a half-completed internal build that merges those additions. IIRC, the main outstanding issues that remain to be addressed are:

-Logic to handle speech repositioning (in cases of scrolling rooms or character movement)
-Support for integration with lipsync module (which turned out to be more complicated than expected; may drop this for the next version)
-Weird bugs related to the custom blocking functions (redundant as of upcoming 3.5.x version with Wait() extensions)
-Streamline the code: in particular related to not allowing pointers inside managed structs and the AGS compiler bug about static structs/attributes (I don't suppose that has been fixed yet?)

I seem to recall I abandoned it last time around because I found it so tedious to work around the AGS limitations. Providing a nice API required literally thousands of lines of boilerplate.

SMF spam blocked by CleanTalk