Inventory Area Scriptable?

Started by subspark, Fri 14/09/2007 17:23:24

Previous topic - Next topic

subspark

Is there any way to change the cursormode if you right click in an inventory area? Infact is it possible at all to RunScript on an inventory area?

I'm using the default template and I want to use right click to perform
Code: ags
mouse.Mode = eModeInteract;
mouse.UseModeGraphic(eModePointer);
instead of the arrow button. (Think Sam & Max)

I've experimented with the following to no avail:

Code: ags

#sectionstart invCustomInv_Click  // DO NOT EDIT OR REMOVE THIS LINE
function invCustomInv_Click(InvWindow *control, MouseButton button) {
   if (button == eMouseRight) {
      if (player.ActiveInventory != null) {
          mouse.Mode = eModeInteract;
          mouse.UseModeGraphic(eModePointer);
      }
  }
  else {
  }
}
#sectionend invCustomInv_Click  // DO NOT EDIT OR REMOVE THIS LINE


Any ideas on how one would handle this?

Cheers,
Paul.

Ghost

Doesn't sound too tricky, since you can check if your cursor is over an invenory item. Plus, you could use coordinates. I think your code doesn't work because it is only triggered after a click. Repeatedly execute is where the code should go.

Pumaman

You need to put the code in on_mouse_click like this:

if (button == eMouseRightInv)
{
// do stuff
}

assuming that "handle inventory clicks in script" is enabled.

subspark

#3
Thanks so much Chris. I didn't expect a reply from yourself.
Thanks Ghost. Cheers.

EDIT:
Chris, would you be so kind as to post the default code that is automatically run if you do have inventory clicks handled by the editor?

Most appreciated you guys thankyou.
Paul.

Pumaman

It's basically this:

InventoryItem *selectedItem = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
if (button == eMouseRight)
{
  selectedItem.RunInteraction(eModeLookat);
}
else if (mouse.Mode == eModeInteract)
{
  player.ActiveInventory = selectedItem;
}
else
{
  selectedItem.RunInteraction(mouse.Mode);
}

subspark

#5
Darn! An internal error has occurred.

Error: run_text_script1: error
-6 running function
'on_mouse_click':
Error: Null pointer referenced
in "GlobalScript.asc", line 73

Code: ags

#sectionstart on_mouse_click  // DO NOT EDIT OR REMOVE THIS LINE
function on_mouse_click(MouseButton button) {
  // called when a mouse button is clicked. button is either LEFT or RIGHT

InventoryItem *selectedItem = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
if (button == eMouseRight) // If right clicked mouse anywhere while gInventory is visible.
{
   mouse.Mode = eModeInteract;
   mouse.UseModeGraphic(eModePointer);
}
else if (mouse.Mode == eModeInteract)
{
  player.ActiveInventory = selectedItem;
}
else
{
  selectedItem.RunInteraction(mouse.Mode);  [[[LINE 73...Doesnt like this line]]]
}

// If right clicked mouse whithin the inventory area:  
if (button == eMouseRightInv)
{
   mouse.Mode = eModeInteract;             [[[DOESNT DO ANYTHING]]]
   mouse.UseModeGraphic(eModePointer);
}  

if (IsGamePaused() == 1) { // If game is paused, don't allow mouse clicks.
  }
  else if (button == eMouseLeft) {
    ProcessClick(mouse.x, mouse.y, mouse.Mode );
  }
  else { // If right clicked mouse, cycle the cursor modes.
        mouse.SelectNextMode();
  }
}
#sectionend on_mouse_click  // DO NOT EDIT OR REMOVE THIS LINE


I'm sure all this code is tangled up.
Chris, you said before that was basically the code for inventory clicks. Am I missing something? When I say inventory area I don't just mean the GUI itself, I mean the actual rectangle where the item icons are drawn.

Cheers,
Paul.

Pumaman

Was the mouse actually over an item at the time? The code I posted was just pseudocode, I wouldn't expect it to work as-is. For one thing, you'd need to check if selectedItem is returned as null, which will happen if the mouse isn't on an inventory item at the time.

subspark

#7
I have in fact made more sense of it as the last hour passed. I'm sorry I couldn't update my original post before you saw it. I guess I caught you at the right time here in Italy. I'm actually using 30 min logon sessions at the hotel. They don't have the internet cafe idea quite worked out yet here in Rome so I'm stuck to 30 minute periods until I have to go to reception and sign a form over and over. Bloody hell.  >:(

If you see anything wrong with the following code and ONLY if you can spare 30 seconds, could you edit it to at least resemble working code so that i can test it myself. I know I'm a long way off so if you could perhaps throw me a few steps ahead in a forward direction I would really appreciate it.

Okay well this is my entire mouse click function code:

Code: ags
#sectionstart on_mouse_click  // DO NOT EDIT OR REMOVE THIS LINE
function on_mouse_click(MouseButton button) {
InventoryItem *selectedItem = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
  
  // called when a mouse button is clicked. Button is either LEFT or RIGHT

  if (IsGamePaused() == 1) { // If game is paused, don't allow mouse clicks.
  }
  else if (button == eMouseLeft) {
    if (mouse.Mode == eModeInteract) {
      player.ActiveInventory = selectedItem;
    }
    else {
    selectedItem.RunInteraction(mouse.Mode);
    }
  }
  else {
    ProcessClick(mouse.x, mouse.y, mouse.Mode );
  }
  
  // If right clicked mouse:
  if (button == eMouseRight) {
    if (gInventory.Visible == true) {
      mouse.Mode = eModeInteract;
      mouse.UseModeGraphic(eModePointer);
    }
    else {
      mouse.SelectNextMode();
    }
  }

  // If right clicked mouse whithin the inventory area:
  if (button == eMouseRightInv) {
    mouse.Mode = eModeInteract;
    mouse.UseModeGraphic(eModePointer);
  }  
}
#sectionend on_mouse_click  // DO NOT EDIT OR REMOVE THIS LINE


Thanks anyway CJ for you time.

Ciao,
Paul.

subspark

Im still way off. I'm not a programmer and while this is a technical issue it may best be put into the beginners thread. Unfortunately help is a little slow there as not as many programmers seem to like reading posts there because of how simple these questions must seem to them.
It is however important to me as I am building a small demo while I travel overseas and while most of my game is pretty easy for me to program, coding things like these melt my brain. I have a very light understanding of the AGS programming language and even less of any other.

This is a personal experiment to see how far I can get with the knowledge I have and can get from others, including any avaliable tutorials and it is also an enjoable pastime.

I would appreciate as much example code as I can get. I don't expect to be able to make any sense of a few lines. I need more than 80% to make a mental map of how the code works and where it goes. Again, I'm very light in my understanding and I ask the community willing to assist to be patient with me.

I know CJ has other priorities and I'm extreamly appreciative of his help so far but if there is anyone else out there who can offer their expertise that would be most appreciated.

I'm not asking them to write my game I just need half a minute of their time for them to show me how to code what I want the game to do. It's actually extremely simple.

Cheers,
Paul.

Ashen

#9
Code: ags

#sectionstart on_mouse_click  // DO NOT EDIT OR REMOVE THIS LINE
function on_mouse_click(MouseButton button) {
InventoryItem *selectedItem = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
  
  // called when a mouse button is clicked. Button is either LEFT or RIGHT

  if (IsGamePaused() == 1) { // If game is paused, don't allow mouse clicks.
  }
  else if (button == eMouseLeftInv) {
    if (mouse.Mode == eModeInteract) {
      player.ActiveInventory = selectedItem;
    }
    else {
    selectedItem.RunInteraction(mouse.Mode);
    }
  }
  else if (button == eMouseLeft {
    ProcessClick(mouse.x, mouse.y, mouse.Mode );
  }
  
  // If right clicked mouse:
  else if (button == eMouseRight) {
    mouse.SelectNextMode();
  }

  // If right clicked mouse whithin the inventory area:
  else if (button == eMouseRightInv) {
    mouse.Mode = eModeInteract;
    mouse.UseModeGraphic(eModePointer);
  }  
}
#sectionend on_mouse_click  // DO NOT EDIT OR REMOVE THIS LINE


Should be working code. Whether in works in the way you want, is another matter...

AFAIK, the eMouseLeft/RightInv code is only run for click on Inventory ITEMS, not the Inventory WINDOW GUI object. Also AFAIK, InvWindows can't have _click functions - did you just add the one in your first post to the global script, and hope for the best?

I think the best way to achieve what you want is what Ghost suggested (or at least, what I think Ghost suggested, because it's a pretty good idea). Use repeatedly_execute(_always, if needed), check if the mouse button is down, and if the cursor is over the InvWindow. E.g.:
Code: ags

  if (mouse.IsButtonDown(eMouseRight) && GUIControl.GetAtScreenXY(mouse.x,mouse.y) == invCustomInv) {
      if (player.ActiveInventory != null) {
          mouse.Mode = eModeInteract;
          mouse.UseModeGraphic(eModePointer);
      }
  }


You'll probably also want to add a check to stop the code repeating for as long as the mouse button is down (like making it player.ActiveInventory != null && mouse.Mode != eModeInteract). Oh, and I'm not sure how that'll interact with clicks on Inventory Items - maybe add a check that it's not over one?
I know what you're thinking ... Don't think that.

subspark

Most appreciated Ashen. Thanks a million for the example code. this should be enough for me to solve the problem. You have to understand that what I am doing is racking my brain at full capacity. Its like being thrown in a chinese maths school  and having to learn the language and algebra at the same time.

Anyway I really appreciate everybodys help. If I have any more stumps Ill post back.

Cheers,
Paul.

subspark

Okay guys, Ive made leaps and strides and Im stuck on this last thing.

Basically what happens is when I click the mouse button down on an inventory item before I can release the mouse button, the inventory item is used on itself and thus whatever happens when i use that slot on itself occurs. cEgo.Say("I dont want to crease my money")

It seems that the game doesnt know when Ive actually released the mouse and it doesnt stop the code. I know you were talking about this, Ashen, however exactly what part I am doing wrong seems to elude me.

If you could have a look at my code:
Code: ags
#sectionstart repetedly_execute // DO NOT EDIT OR REMOVE THIS LINE
function repededly_execute() {
InventoryItem *selectedItem = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
  // Mouse Left:
  if ((mouse.IsButtonDown(eMouseLeft)) && (InventoryItem.GetAtScreenXY(mouse.x,mouse.y) != null)) {
    if (mouse.Mode == eModeInteract) {
        player.ActiveInventory = selectedItem;
    }
    else {
        selectedItem.RunInteraction(mouse.Mode);
    }
  }
  // Mouse Right:
  if ((mouse.IsButtonDown(eMouseRight)) && (GUIControl.GetAtScreenXY(mouse.x,mouse.y) == invCustomInv)) {
    if (player.ActiveInventory != null {
      mouse.Mode = eModeInteract;
      mouse.UseModeGraphic(eModePointer);
    }
  }
#sectionend repetedly_execute // DO NOT EDIT OR REMOVE THIS LINE


Ignore any typos as I am typing this while reading from another monitor. If this stupid hotel offered wireless internet services I would have used my laptop and copied the code from AGS. Sorry in advance for that.

Cheers,
Paul.

Ashen

Quote
It seems that the game doesnt know when Ive actually released the mouse and it doesn't stop the code.

Or, it could be that it does know you've released the button and is behaving properly - I think interactions are normally triggered on release of the mouse button. So in this case, you press the left button, the rep_ex code kicks in, sets the Active Inventory Item and changes to eModeUseInv (again, normal behaviour when ActiveInv is set). Then you release the button, and normal click handling executes the current mode (using the Item on itself).


Anyway, try this. From the top:
- Check the 'Handle Inventory clicks in script' option.
- on_mouse_click:
Code: ags

function on_mouse_click(MouseButton button) {  
  // called when a mouse button is clicked. Button is either LEFT or RIGHT

  if (IsGamePaused() == 1) { // If game is paused, don't allow mouse clicks.
    // NOTE: This assumes your Inventory GUI is Popup Modal - they pause the game.
    if (button == eMouseLeftInv) {
      InventoryItem *selectedItem = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
      if (mouse.Mode == eModeInteract) {
        player.ActiveInventory = selectedItem;
      }
      else {
        selectedItem.RunInteraction(mouse.Mode);
      }
    }
    // else if (button == eMouseRightInv) goes here, if you want it...
  }
  else if (button == eMouseLeft) {
    ProcessClick(mouse.x, mouse.y, mouse.Mode );
  }
  
  // If right clicked mouse:
  else if (button == eMouseRight) {
    mouse.SelectNextMode();
  }
}

- repeatedly_execute:
Code: ags

#sectionstart repeatedly_execute // DO NOT EDIT OR REMOVE THIS LINE
function repeatedly_execute() {
  if ((mouse.IsButtonDown(eMouseRight)) && (GUIControl.GetAtScreenXY(mouse.x,mouse.y) == invCustomInv)) {
    // If you don't want this to work for right-clicks over Items, add a check of InventoryItem.GetAtScreenXY(mouse.x, mouse.y)
    if (player.ActiveInventory != null) {
      mouse.Mode = eModeInteract;
      mouse.UseModeGraphic(eModePointer);
    }
  }
}
#sectionend repeatedly_execute // DO NOT EDIT OR REMOVE THIS LINE


This has been briefly tested, and does what I'd expect. If it doesn't do what you want ... Tough. Or, you know, just let me know what's wrong.

Perhaps you should wait on this until you're not travelling? I'm not trying to be funny, but there's only pretty basic stuff here - if you're really having such problems with it, it might just be because you're not focused, and not that it's actually that difficult.
I know what you're thinking ... Don't think that.

subspark

Sure. Thanks anyway Ashen.

Before I began attempting to code the interface stuff I imagined it would be rather basic. And I agree I reckon I was working under unusual circumstances. The thing that really gets me stuck is the mouse interactions. If, as you said the interactions are set to mouse release by default then coding around that may prove more difficult than what I originally had in mind.
Anyway, I'm back home now, and when I copy my stuff over I'll dive back into it. If I can't figure it all out by then, I'll move this issue into the beginners forum.

Thanks again for your help, Ashen. Your a total champ.

Cheers,
Paul.

Ashen

Actually, I realised I was wrong - well, confused at least. GUI Button clicks don't process untill you release the mouse button; I assumed it was the same for other mouse clicks, but it doesn't seem to be. I might've got the cause wrong, but I still think I'm right about the effect - duplicating the code in on_mouse_click and repeatedly_execute means the interaction runs twice.

Try it again once you get more settled in - it's not 'Read the Manual/BFAQ' basic admittedly, but it's not overly difficult either. Most of your problems seem to have been logical ones, with the placement of code, etc, that'll hopefully solve themselves when you're not fighting with some hotel's odd internet policy at the same time.
I know what you're thinking ... Don't think that.

SMF spam blocked by CleanTalk