Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: julius on Tue 29/06/2010 06:30:22

Title: mouse over hotspot -display name of hotspot over coursor
Post by: julius on Tue 29/06/2010 06:30:22
how do i make ags display a name of an object over the mouse coursor when i move the coursor over a hotspot?

i guese i click on "mouse move over hotspot" action , but what do i put in the script??
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: Rulaman on Tue 29/06/2010 07:28:06
It's really simple.

Make a gui (transparent if you wish) and place a label on it.
As label text write simple @OVERHOTSPOT@.
Make the GUI visible and place it somewhere on your screen.

In the manual search for: Interface text
@OVERHOTSPOT@ Name of the hotspot which the cursor is over

Greetings
Rulaman
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: barefoot on Tue 29/06/2010 07:32:22
Hi

Maybe above post is what you need if you are looking for objects actual name etc..

anyhow.. the below is still useful to know,,

well, mouse over hotspot displays text etc as normal, you can put what you like such as:


function hHotspot1_MouseMove()
{
cprof_plum.Say("Look, there's a door Indy");
}


This can be quite useful as you dont need to change cursor mode, thats if you really need it..

-barefoot-
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: julius on Tue 29/06/2010 09:12:15
Quote from: Rulaman on Tue 29/06/2010 07:28:06
It's really simple.

Make a gui (transparent if you wish) and place a label on it.
As label text write simple @OVERHOTSPOT@.
Make the GUI visible and place it somewhere on your screen.

In the manual search for: Interface text
@OVERHOTSPOT@ Name of the hotspot which the cursor is over

Greetings
Rulaman


first of all thanks for the quick reply ,
but i have a quastion: the gui i created will be displayed at a fix place , i would like to place it over where the mouse coursor is...(like in so many lucasarts games like the dig monkey island and so on).
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: barefoot on Tue 29/06/2010 09:17:38
well, you can adjust x and y for the GUI where you would like it displayed, if thats any use?

-barefoot-
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: julius on Tue 29/06/2010 09:36:44
yes but the mouse coursor allways moves how do i make the hotspot name move with it??
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: Khris on Tue 29/06/2010 10:43:10
You'd put the lines inside repeatedly_execute, a function in Global.asc that's executed every game loop.

  // small offset from mouse cursor hotspot
  int x = mouse.x+3;
  int y = mouse.y+3;

  GUI*g = gCursor;  // change gCursor to the scriptname of your GUI

  // make sure new coordinates are within screen limits
  if (x > 320-g.Width) x = 320-g.Width;
  if (y > 240-g.Height) y = 240-g.Height;

  // reposition gui
  g.SetPosition(x, y);


There's room for improvement; e.g. if you cursor is a TheDig style cross, you could move the text to the upper corner in the lower half and left corner in the right half of the screen.
Or you could keep it in one place while the mouse is still over the hotspot.

What you want to keep in mind is that for global behavior like this, you never, ever use functions specific to a single hotspot, like barefoot suggested in his first post.
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: julius on Tue 29/06/2010 12:41:47
Quote from: Khris on Tue 29/06/2010 10:43:10
You'd put the lines inside repeatedly_execute, a function in Global.asc that's executed every game loop.

  // small offset from mouse cursor hotspot
  int x = mouse.x+3;
  int y = mouse.y+3;

  GUI*g = gCursor;  // change gCursor to the scriptname of your GUI

  // make sure new coordinates are within screen limits
  if (x > 320-g.Width) x = 320-g.Width;
  if (y > 240-g.Height) y = 240-g.Height;

  // reposition gui
  g.SetPosition(x, y);


There's room for improvement; e.g. if you cursor is a TheDig style cross, you could move the text to the upper corner in the lower half and left corner in the right half of the screen.
Or you could keep it in one place while the mouse is still over the hotspot.

What you want to keep in mind is that for global behavior like this, you never, ever use functions specific to a single hotspot, like barefoot suggested in his first post.

thanks man but i already found a much simpler way:
1.create an action on the hotspot under-mouse over hotspot
2.create a gui ,with transparant background and border with a lable on it (inside the lable place :"@OVERHOTSPOT@")
3.inside the script of the mouse over hotspot put:
        nameofgui.visible = true;
        nameofgui.setposition(mouse.x+1,mouse.y+1);


thats it.....very simple ;D
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: Sslaxx on Tue 29/06/2010 12:46:24
I was thinking about how to do this the other day. The way I'm leaning towards is using two GUIs, maybe transparent, one at the top of the screen and one at the bottom. Hovering over a hotspot would show text on the top GUI, over an object the bottom GUI. The GUIs would only be enabled when the cursor was over an object or hotspot. I shall have to give it a go...
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: Ryan Timothy B on Tue 29/06/2010 15:54:52
I could be wrong, but using your method Julius
nameofgui.setposition(mouse.x+1,mouse.y+1);
The game can crash if the room isn't scrolling and you move the mouse to the very right or bottom edge. 

Or at least it did for me the other week when I had a GUI following the mouse and it went off the background.  When the GUI left the 'background' it would crash.
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: Crimson Wizard on Tue 29/06/2010 16:18:25
Quote from: Ryan Timothy on Tue 29/06/2010 15:54:52
I could be wrong, but using your method Julius
nameofgui.setposition(mouse.x+1,mouse.y+1);
The game can crash if the room isn't scrolling and you move the mouse to the very right or bottom edge.  

Or at least it did for me the other week when I had a GUI following the mouse and it went off the background.  When the GUI left the 'background' it would crash.
This is easily solved by checking if it is beyond the screen border and aligning gui to the left from cursor. But! ofcourse you'll have to calculate text's width first.
If anyone interested, you may check how I did this in my template here:
http://www.box.net/shared/o6l46lnho1

Also, I remember there was more complex template or module for this kind of stuff.... but I forgot its name.
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: Ryan Timothy B on Tue 29/06/2010 16:24:08
Well, what I used the GUI to follow the mouse for wasn't text and it had to literally follow the mouse.  All I do is change the visiblity instead of the location if the GUI is off screen.
I posted that just because I figured I'd let the poor guy know that he has a game crashing issue if he leaves it as is.
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: Khris on Tue 29/06/2010 18:20:47
Quote from: julius on Tue 29/06/2010 12:41:47
thanks man but i already found a much simpler way:
1.create an action on the hotspot under-mouse over hotspot
2.create a gui ,with transparant background and border with a lable on it (inside the lable place :"@OVERHOTSPOT@")
3.inside the script of the mouse over hotspot put:
        nameofgui.visible = true;
        nameofgui.setposition(mouse.x+1,mouse.y+1);


thats it.....very simple ;D

First of all, please don't quote the entire previous post. The Reply button is beneath the last post, to the right.

Back to the topic now:
Please read again the final sentence of my last post:
QuoteWhat you want to keep in mind is that for global behavior like this, you never, ever use functions specific to a single hotspot, like barefoot suggested in his first post.

The reason is twofold:
-You have to add identical code for every hotspot in the game. This is tedious and more importantly completely unnecessary.
-If you ever were to change the look of it, you'd have to change the code hundreds of times, all over the place.

So, again:
For global behavior like this, you never, ever use functions specific to a single hotspot.
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: Snarky on Sun 18/09/2011 09:31:12
There isn't a module or anything for this, is there?

I started out doing essentially this (Khris's method), but I ran into a series of problems. The solution ended up being not particularly simple:


Finally, this worked. But it's a lot of code for something that started out so simple. That's why I was wondering if anyone's made a module or anything to make it easier.
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: hedgefield on Mon 19/09/2011 00:12:00
Quote from: Snarky on Sun 18/09/2011 09:31:12
There isn't a module or anything for this, is there?

There is, actually. A very robust one made by SSH called the Description Module (http://www.adventuregamestudio.co.uk/yabb/index.php?topic=26306.0). I'm surprised no one has mentioned it yet.
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: Snarky on Mon 19/09/2011 09:30:46
Ah, nice. It doesn't look like it does what I needed, but the idea of setting button fonts to transparent and using that text as the mouseover label is cool, and I'll borrow that.

I also have a bunch of code to highlight the cursor over hotspots, and change to different cursors depending on the value of a custom hotspot/object/character property, and since all of that affects the positioning of the mouseover label, it might in fact be better for me to do all the logic in one place.
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: Dualnames on Wed 21/09/2011 06:19:14
There's a more focused module to satisfy your needs. Last time I used it, it was about 4 years ago, and it seemed to work just fine, if you give us more details about that "bunch of code", perhaps we could come up with something.

OverHot Module (http://www.mediafire.com/?dwr1ndtsghg4z6x)

A readme is included
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: Gilbert on Wed 21/09/2011 07:05:33
Hmmm. I don't know muchyes about the OverHot module, but because of its age and incompleteness I think it's possibly better to move to SSH's more complete Description module like hedgefield has mentioned.
The OverHot module is even categorised as obsolete in the Wiki (http://americangirlscouts.org/agswiki/OverHot) and it too recommends using the newer module instead. I also think that the author of OverHot died long time ago already so there's no point to dig up his grave.
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: Dualnames on Wed 21/09/2011 09:46:07
Your past is not safe with me!
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: Arjunaz78 on Sat 22/10/2011 12:00:09
i still wondering how to make a custom GUI that can display a current hotspot name when hovering the mouse cursor like Sslaxx told before like Ben Jordan Games,how come?
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: Khris on Sat 22/10/2011 12:35:40
Topic from first page dealing extensively with this exact problem:
http://www.adventuregamestudio.co.uk/yabb/index.php?topic=44591.0
Title: Re: mouse over hotspot -display name of hotspot over coursor
Post by: Snarky on Sat 22/10/2011 19:13:37
Quote from: Dualnames on Wed 21/09/2011 06:19:14
if you give us more details about that "bunch of code", perhaps we could come up with something.

I guess that was directed at me? I'll just post the code, if you're interested. I'm sure this can be cleaned up and condensed, but at least it seems to work:


#define TOOLTIPWIDTH 50

bool _oldhighlight = false;
int _olddir = 0; // for exit pointers in various directions. Numbered 1-4 in the order up, right, down, left; 0 is regular pointer
bool _clickable = true;

String[] Split(this String*, String divider)
{
  String heads[] = new String[this.Length];
  int i;

  String tail = this;
  int nextDivider = this.IndexOf(divider);
  while(nextDivider != -1)
  {
    heads[i] = tail.Substring(0, nextDivider);
    tail = tail.Substring(nextDivider+divider.Length, tail.Length - nextDivider-divider.Length);
    nextDivider = tail.IndexOf(divider);
    i++;
  }
  if(tail.Length>0)
    heads[i] = tail;
 
  return heads;
}

void DimToolTip(String text)
{
  int width = GetTextWidth(text, eFontMiniFontOutline);
  int height = GetTextHeight(text, eFontMiniFontOutline, TOOLTIPWIDTH+1);
  int lines = height / GetTextHeight(text, eFontMiniFontOutline, GetTextWidth(text, eFontMiniFontOutline)+1);
  if(width > TOOLTIPWIDTH)
  {
    // Set the width to the minimum width that doesn't wrap over more lines than TOOLTIPWIDTH does
    width = TOOLTIPWIDTH;
    while(GetTextHeight(text, eFontMiniFontOutline, width) == height)
      width--;
    width++;
   
    // If any individual words are longer, set the width to that
    String tooltipwords[] = text.Split(" ");
    int i = 0;
    while(tooltipwords[i] != null)
    {
      int wordwidth = GetTextWidth(tooltipwords[i], eFontMiniFontOutline);
      if(width < wordwidth)
        width = wordwidth;
      i++;
    }
  }
 
  // Set the dimensions of the tooltip
  gHotspot.Width = width+1;
  gHotspot.Height = height+lines;
  lblHotspot.Width = width+1;
  lblHotspot.Height = height+lines;
}

function SetHighlight(bool forceupdate)
{
  if(_uimode == eUiTwoButton)
  {
    bool highlight = false;
    int dir = 0;
    String tooltip = "";
   
    // Check if the cursor is over an interactive GUI control
    GUIControl* gc =  GUIControl.GetAtScreenXY(mouse.x, mouse.y);
    if(gc != null)
    {
      Button* b = gc.AsButton;  // if gc is a button, b points to it, otherwise b is null
      ListBox* lb = gc.AsListBox;
      Slider*  s = gc.AsSlider;
      TextBox* tb = gc.AsTextBox;
      if (b != null || lb != null || s != null || tb != null)
      {
        highlight = true;
      }
      else
      {
        // If we're over an inventory window, check if we're actually over an inventory item
        InventoryItem* ii = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
        if(ii != null)
        {
          highlight = true;
          tooltip = ii.Name;
        }
        /*
        InvWindow* iw = gc.AsInvWindow;
        if(iw != null)
        {
          GUI* g = GUI.GetAtScreenXY(mouse.x, mouse.y);
          if(mouse.x < g.X + iw.X + iw.ItemWidth*(iw.ItemCount-iw.TopItem))
            highlight = true;
        }
        */
       
      }
     
      // This bit should be replaced by putting the tooltip as the button label in invisible font, and reading that
      if(gc == gmSaveButton)
        tooltip = "Save";
      else if(gc == gmLoadButton)
        tooltip = "Load";
      else if(gc == gmQuitButton)
        tooltip = "Quit";
    }
   
   
    else if (_clickable)  // If game is clickable, check if the cursor is over anything else interactive
    {
      //InventoryItem* ii = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
      LocationType ltype = GetLocationType(mouse.x, mouse.y);
      if (ltype != eLocationNothing)
      {
        if(ltype == eLocationHotspot)
        {
          Hotspot* hs = Hotspot.GetAtScreenXY(mouse.x, mouse.y);
          if(hs != null)
          {
            dir = hs.GetProperty("ExitDirection");
            tooltip = hs.Name;
          }
        }
        else if (ltype == eLocationObject)
        {
          Object* o = Object.GetAtScreenXY(mouse.x, mouse.y);
          if(o != null)
          {
            dir = o.GetProperty("ExitDirection");
            tooltip = o.Name;
          }
        }
        else if(ltype == eLocationCharacter)
        {
          Character* c = Character.GetAtScreenXY(mouse.x, mouse.y);
          if(c != null)
          {
            tooltip = c.Name;
          }
        }
        highlight = true;
      }
    }
   
    // Highlight cursor if moved over something active (or force update), or direction has changed
    if(highlight && (!_oldhighlight || forceupdate || dir != _olddir))
    {
      SetCursorMode(dir);
    }
    else if (!highlight && (_oldhighlight || forceupdate)) // Un-highlight cursor if moved away from something active (or force update)
    {
      SetCursorMode(-1);
    }

    // When game isn't clickable, show the tooltip (huh?)
    gHotspot.Visible = (mouse.Mode != eModeWait || !IsGameClickable());
   
    if(tooltip != null && tooltip.Length>0 && tooltip != lblHotspot.Text)
      DimToolTip(tooltip);

    int gHotspotX;
    int gHotspotY;
    // Show a tooltip by the cursor if over a hotspot/object/character
    if(dir == 1)  // up
    {
      gHotspotX = mouse.x - gHotspot.Width/2;
      gHotspotY = mouse.y + 11;
    }
    else if(dir == 2)  // right
    {
      gHotspotX = mouse.x - gHotspot.Width - 9;
      gHotspotY = mouse.y - gHotspot.Height/2;
    }
    else if (dir == 3) // down
    {
      gHotspotX = mouse.x - gHotspot.Width/2;
      gHotspotY = mouse.y - gHotspot.Height - 9;
    }
    else if (dir == 4) // left
    {
      gHotspotX = mouse.x + 11;
      gHotspotY = mouse.y - gHotspot.Height/2;
    }
    else // pointer
    {
      gHotspotX = mouse.x - gHotspot.Width/2;
      gHotspotY = mouse.y - gHotspot.Height;
    }
    if(gHotspotX < 1)
      gHotspotX = 1;
    else if(gHotspotX + gHotspot.Width >= System.ViewportWidth)
      gHotspotX = System.ViewportWidth - gHotspot.Width -1;
    if(gHotspotY < 1)
      gHotspotY = 1;
   
    gHotspot.X = gHotspotX;
    gHotspot.Y = gHotspotY;
   
    lblHotspot.Text = tooltip;

    _oldhighlight = highlight;
    _olddir = dir;
  }
}