more hotspots and music(SOLVED)

Started by lafouine88, Sat 20/06/2020 20:32:16

Previous topic - Next topic

lafouine88

Hey guys.

I'm facing a few problems on my game. It's not much for you I guess, that's why I put it all in the same topic (to avoid flooding too much :) ).

1)HOTSPOTS : I followed a code that was previously given to me here. I'm going for a Sam and max interface. For those who don't know it, the pointers (walk, look,pick up speak and use) animate when the mouse is over a hotspot, item or character. This isn't initially coded on  I had too add it :

        - 1)first, to animate the pointer when over a hotspot (thanks @Khris)

Code: ags

                  bool wasHovering = false;
function HandleCursorHighlight() {
  bool isHovering = GetLocationType(mouse.x, mouse.y) != eLocationNothing;
 
  if (isHovering && !wasHovering) {
    // cursor entered interactive area
    if (player.ActiveInventory) mouse.ChangeModeGraphic(eModeUseinv, player.ActiveInventory.Graphic + 1);    
  }
  else if (!isHovering && wasHovering) {
    // cursor left interactive area
    if (player.ActiveInventory) mouse.ChangeModeGraphic(eModeUseinv, player.ActiveInventory.Graphic);
  }
 
  wasHovering = isHovering;
}


It works just fine, but I was wandering if I could adjust it so that the animation doesn't go if the hotspot isn't scripted for the specific action. For instance an item on the floor would not animate the "speak" cursor because I haven't planned to script something in "talk to hotspot". It would just animate the pick up and look at cursors, because this is what the hotspot has functions for. I was thinking maybe with the properties of the hotspot, or if there is a function that recognizes if clicking will do something or not.

       - About hotspots again, weirdly enough, the "walk to" cursor doesn't go through hotspots. If I create a hotspot to changeroom, it doesn't activate. So I used this code to force the action :
Code: ags

function on_mouse_click(MouseButton button)
{
  // called when a mouse button is clicked. button is either LEFT or RIGHT
  if (IsGamePaused())
  {
    // game is paused, so do nothing (i.e. don't process mouse clicks)
  }
  else if (button == eMouseLeft)
{
    // if it is walk-to command
    if (mouse.Mode == eModeWalkto)
    {
      // if there's a hotspot under mouse cursor
      if (GetLocationType(mouse.x, mouse.y) == eLocationHotspot)
      {
        
         //then fire "interact" event
        Room.ProcessClick(mouse.x, mouse.y, eModeInteract);
        return;} // do not do anything else
           Room.ProcessClick(mouse.x,mouse.y, mouse.Mode);
      }
    }
    // in all other cases - just do default action
    Room.ProcessClick(mouse.x,mouse.y, mouse.Mode);
  }
  else // right-click, so cycle cursor
  {   
    mouse.SelectNextMode();
  }
}


Once again, it does the trick. When I "walk to" a hotspot that changes the room, it works. But when I "walk to an "item hotspot" it plays the interact script, which is not cool. I could'nt find the way to have both the interaction on specific hotspots(the exit ones) and the no interaction on regular ones. Again there might be a function that determines the id of the hotspot, that i could use to determine whether it's an exit one or not(1->3 are exits,4+ are regular), or maybe by including comments that a function could recognize? Any ideas ?



2)Second point is about music, I guess an easy one. It's pretty easy to put the music changes in specific room loads so that it loops and there is no discontinuity through the game. But I'm going with 2 playable characters here, and so the player changes will disturb this beautiful continuity.
Actually I tried to write an example but it was so terribly unclear I will just go with the gerenal question and will be more precise if needed :
-imagine you have like in DOTT, two houses with many rooms inside. You want music1 for one house(and all its rooms) and music2 for the other. Music 1 si on cause you play the main character in house1. The music doesn't restart every time you go from a room to the other(so you ant' use music1.play at each room load) but if you switch characters, you need the music to change to music2.
One last thing,in reality there are more than 2 houses and more than one music in one house so you can't just systematically change when you switch character.

I hope that is clear enough...I'm ready to explain as precisely as needed^^


Thanks a lot, and actually, maybe I should have posted different topics.


lafouine88

Yo.

I think I came out with quite an easy solution for the music issue. A global int for each character that changes according to the places they go. Then on the GUI button that changes the player character I would add a line to stop the current music and play the aMUSIC(intcharacter1 or 2). I haven't tried it yet but I'm pretty sure this is an easy way.

Still working on the rest :)

Cassiebsg

#2
Let me check the code from my game, since I did mine like that.

Edit:
The command you need is: IsInteractionAvailable

You place it inside a if/else condition that checks if the mode is available. This if/else will of course be checked where your change/show the options available.

Code: ags

function name()
{
 int click_x = mouse.x;
 int click_y = mouse.y;
 if (IsInteractionAvailable(click_x, click_y, eModeInteract) // this might be inside another condition or have extra conditions to make it work right with your game 
 {
   // Add the code to [i]display[/i] the interaction button here
 }
 else // Add the code to [i]hide[/i] the interaction button here
  
// Repeate if/else condition for all your mouse modes here (or there might be simpler way to go thru them)

}



Hope it helps.
There are those who believe that life here began out there...

lafouine88

Yeah cassiebg this seems perfect. I m currently on vacations so don't have access to my computer to check but I ll confirm asap that it is solved with it. I guess it s gonna be.

Thanks a lot

lafouine88

#4
Hey guys, me again

So I tried cassiebg function, and just added it to my (slightly modified) hovering script as follows :
Code: ags

function HandleCursorHighlight() {
  bool isHovering = GetLocationType(mouse.x, mouse.y) != eLocationNothing;
 int click_x = mouse.x;
 int click_y = mouse.y;
   bool inter = IsInteractionAvailable(click_x, click_y, eModeInteract);
 
  
    if (isHovering && inter) {
    // cursor entered interactive area  && interaction is available  
        if (player.ActiveInventory) mouse.ChangeModeGraphic(eModeUseinv, player.ActiveInventory.CursorGraphic + 1);    
    }
  else if (!isHovering) {
    // cursor left interactive area
    if (player.ActiveInventory) mouse.ChangeModeGraphic(eModeUseinv, player.ActiveInventory.CursorGraphic);
  }
 
}


That was just a try only with the interaction function. So if my hotspot isn't planned an interaction, the cursor shouldn't animate.

It doesn't but only in "useinventory" mode as planned in the code. But it still does with the regular cursors(walk to, pickup...). Any ideas on how to include this last lot.

Thanks

,and btw if found out a way to solve the exit hotspots problem using "ifinteractionavailable". I just put a lookat interaction on all my hotspots but the exit ones.
Then i added a check,if the lookat interaction was available then
The mouse stayed normal. If not(exit then) it forced the mouse to emodeinteract, to use the exit.

Cassiebsg

You need to add an if/else condition for each mode, not just for interact with/without inventory

That means: IsInteractionAvailable(click_x, click_y, eModelookat); ... IsInteractionAvailable(click_x, click_y, eModeWalkto); ...  IsInteractionAvailable(click_x, click_y, eModePickup); ...
There are those who believe that life here began out there...

lafouine88

Yop cassiebsg.

I'm not sure I uderstand. I know that I need to add the other interactions (lookat,speakto...) if I want to be complete. But my current problem is not that yet. It actually does'nt overwrite the cursors' animations.
The code I wrote is good, but only because I can specify "player.active inventory". If I try to go with something equivalent like this :
Code: ags

function actions() {
  bool isHovering = GetLocationType(mouse.x, mouse.y) != eLocationNothing;
 int click_x = mouse.x;
 int click_y = mouse.y;
   bool inter = IsInteractionAvailable(click_x, click_y, eModeInteract);
 
  
    if (isHovering && inter) {
    // cursor entered interactive area
      if (IsInteractionAvailable(click_x, click_y, eModeInteract)==1){
        if (mouse.Mode==eModeInteract) mouse.ChangeModeGraphic(eModeInteract, 42);    
    }}
  else if (!isHovering) {
    // cursor left interactive area
    if (mouse.Mode==eModeInteract) mouse.ChangeModeGraphic(eModeInteract, 41);
  }
 
}



the basic animation planned in the system when you go over  hotspots still goes(on the interaction cursor of course). Did you find a way to get over this ? Maybe my code isn't placed properly or has something wrong. To make it clear, I feel like the cursors work slightly differently to the useinventory. So I could have what I want (I just need to add the lines you wrote for look etc.) for "useinv" but I can't get it for the other cursors.

Thanks and sorry if I don't understand what you're saying.

Cassiebsg

Uhm, I think you probably have to turn off the automatic "animate over hotspots" and code your manually, so it only animates where you code it.

I used my code on a VerbCoin system, to only display the available options for each hotspot, but my cursor always animated/highlighted when it was over a hotspot, since that was what I wanted it to do.

I can't remember how Sam&Max system worked and I have trouble understanding exactly what you want to do. Sorry. (maybe post a video/animated gif so we can see what's it doing and what you want it to do?)
I'm no experienced coder, I just go in a trial and error mode until things work the way I want, then I look the code through and try to see if I can improve it and tidy it.
There are those who believe that life here began out there...

lafouine88

Hi cassiebsg. I'm back on my game after some time off. Sorry for not replying.

I'm still looking for a solution. But I won't let it block my progression on the game, I'm pretty sure I'll find something.
https://www.youtube.com/watch?v=U58BFV8yQBA&list=PL02340E9A5B7695BA&index=2
At 1'35 you have an example of the interface I'm doing and what I want. The hand closes on the mail and there is an adapted answer(stealing the mail etc.)however the sign just after it is NOT pickable, so the hand DOESN'T close on it. It still is a hotspot because yoiu can read it and sam says "I can't pick that up"(he doesn't if you just clic randomly).

I tried something that I put in "repetedly execute of my room(If it worked I would copy it in all the rooms, although unelegant...it doesn't^^)
Code: ags

function room_RepExec()
{

 bool hotsp = GetLocationType(mouse.x, mouse.y) != eLocationNothing;
  
    if (hotsp) {
      if ((IsInteractionAvailable(mouse.x, mouse.y, eModeInteract)==0)&&Mouse.Mode==eModeInteract){
        mouse.ChangeModeGraphic(eModeInteract, 41);    
    }}
  }


It does force the interact mode into its "idle" graphic when I'm on a hotspot that doesn't have an interaction. But it actually struggles against the system that wants it to get back to the "usable" icon. I end up with a blinking cursor that still stays on the "notusable" icon I want but makes the thing irritating and messy.

If anybody has an idea that s very cool, otherwise I'll just let you know if I find out something in the end.

Thanks a lot anyway to cassiebsg, the (IsInteractionAvailable) function is so useful :)

Khris

Put this in a new script module (leave the header empty):
Code: ags
int cursorSlot[10], cursorSlotActive[10];

void game_start() {
  for (int mode = eModeLookat; mode <= 9; mode++) {
    cursorSlot[mode] = mouse.GetModeGraphic(mode);
  }
  // set active cursor mode slots
  cursorSlotActive[eModeLookat] = 2105;
  cursorSlotActive[eModeInteract] = 2111;
}

void repeatedly_execute() {
  bool iia = IsInteractionAvailable(mouse.x, mouse.y, mouse.Mode);
  int mg = mouse.GetModeGraphic(mouse.Mode);
  int csa = cursorSlotActive[mouse.Mode];
  
  // default cursor over available interaction: change to active slot
  if (iia && csa > 0 && mg != csa) mouse.ChangeModeGraphic(mouse.Mode, csa);
  
  // no interaction but cursor still using active sprite: change back to default slot
  if (!iia && mg == csa) mouse.ChangeModeGraphic(mouse.Mode, cursorSlot[mouse.Mode]);
}


At the end of game start, set the sprite slots for the active cursors.

lafouine88

Hey Khris. Thanks a lot for your code.
So if I understand I just needed to change the sprite number as so :
Code: ags

void game_start() {
  for (int mode = eModeLookat; mode <= 9; mode++) {
    cursorSlot[mode] = mouse.GetModeGraphic(mode);
  }
  // set active cursor mode slots
  cursorSlotActive[eModeLookat] = 32;
  cursorSlotActive[eModeInteract] = 40;
  cursorSlotActive[eModeTalkto]=43;
  cursorSlotActive[eModePickup]=35;
}


In that case it still doesn't make the trick. I wasn't really familiar with the functions you used but I tried to understand them and ended up removing the thing that could be the problem.
Code: ags

void repeatedly_execute() {
  bool iia = IsInteractionAvailable(mouse.x, mouse.y, mouse.Mode);
  int mg = mouse.GetModeGraphic(mouse.Mode);
  int csa = cursorSlotActive[mouse.Mode];
  
  // default cursor over available interaction: change to active slot
  if (iia && csa > 0 && mg != csa) mouse.ChangeModeGraphic(mouse.Mode, csa);
  
  // no interaction but cursor still using active sprite: change back to default slot
  if (!iia) mouse.ChangeModeGraphic(mouse.Mode, cursorSlot[mouse.Mode]);        ////////////////////////////<---here 
}


I didn't really understand this part of the code, so I tried without. And it does what we need, way better than I wrote it initially. But the fact that it's again a repetedly executed function makes the cursors blink again.
Yet again, maybe I should'nt have removed it, but with the intial lines, it didn't work :(

Thanks again for your help

Khris

I implemented that change and it made no difference.
Did you revert all the changes to the cursor modes? As in, reset their View to 0, and set all the Animation* properties back to false?

lafouine88

Oh no I didn't do that, and now it works. PERFECT thanks a million!
I'll just put back your intial code then^^

Have a good day

SMF spam blocked by CleanTalk