Inventory on Hotspots with variables

Started by Mantra of Doom, Sat 11/10/2008 00:46:32

Previous topic - Next topic

Mantra of Doom

I have this interaction code to almost work... and I've been beating my head against a wall for a week trying to straightening this out. I've cut it down to basic elements and it still doesn't seem to work exactly right. I was just wondering if somebody could tell me how to clean it up... or just tell me what I'm doing wrong.

The scenario: The player has to use a vacuum to get a rodent out of a hole in the wall (yes, I know, cliche but it works for what I need it for). The vacuum is an inventory item (once the item is collected the view will change with the character holding the thing, but that's a different code that does work.) and the hole is a hotspot. When the item is clicked on the hotspot, the little rat appears, gets sucked into the vacuum and disappears and a bag that the character is holding contains 1 rat. This is done three times, but I want the player to have a choice in what hole you can start on.

Right now, any inventory item triggers the item specific action wether or not the variables are changed. This is getting a bit irritating.

Global Ints start out as 0 and are changed when inventory items are picked up. Is this right? Maybe that's where I'm going wrong.

Code: ags
function hvent2_Interact() //Regular Left Click on Hotspot
{
player.Say("I can't get in there.");
}

function hvent2_UseInv() //Inventory Item on Hotspot
{
if (player.ActiveInventory ==iSuck3)  // used item is the vacuum
{
  if (GetGlobalInt(3) ==0)//Don't have inventory item Bag with String
{
   player.Say("I don't have anything to put the critter in.");
}
 if (GetGlobalInt(3) ==1) //Have one or the other item to combine
{
   player.Say("I think I might have an idea. Just need something else.");
}
if (GetGlobalInt(3) ==2) //Have all items necissary to get third thing.
{
  player.Say("I'll get it out.");  // vacuum was used
    player.Walk(109, 153, eBlock);
    player.Say("Gotcha stupid rat!");
    oRat1.Visible=true;
    oRat1.Move(111, 70, 3, eBlock, eAnywhere);
    oRat1.Visible=false;
 if (GetGlobalInt(2) ==0) //if player doesn't have any rats
{
   player.LoseInventory(iBag0); //empty bag
  player.AddInventory(iBag1); //bag with 1 rat
  SetGlobalInt(2, 1);
}

if (GetGlobalInt(2) ==1) //if player has one rat
{
  player.LoseInventory(iBag1); //bag with 1 rat
  player.AddInventory(iBag2); //bag with 2 rats
 SetGlobalInt(2, 2); 
}

if (GetGlobalInt(2) ==2) //if player has 2 rats
{
  player.LoseInventory(iBag2); //bag with 2 rats
 player.AddInventory(iBag3); //bag with 3 rats
  SetGlobalInt(2, 3);
}
}
}
}


Again, I'm sure it's something simple that I either missed, or maybe it's my new Left/Right click code. Which is posted below for reference. I know it's a bit of a mess... but it works most of the time.

Code: ags
// next line above rep_ex function
bool mhboi; // mouse has been over inventory
function repeatedly_execute() {
// following code inside rep_ex:
  if (GUI.GetAtScreenXY(mouse.x, mouse.y)) mhboi = true;
  else if (gInventory.Visible && mhboi) {
    gInventory.Visible = false;
    mhboi = false;
  }
//--------------------------------------REPEADEDLEY EXECUTE------------------------------------

  int x = mouse.x;
  int y = mouse.y;
  
  if (IsGamePaused() == 1) return;

  int mm = mouse.Mode;
  int nm;     // new mode
  Hotspot*h;
  Object*o;
  InventoryItem*i;
  int lt = GetLocationType(x, y);   // what's under the cursor?

  GUI*g = GUI.GetAtScreenXY(x, y);
  
  if (mm != eModeUseinv) {
    if (g == gInventory) {
      if (mm != eModeUseinv) nm = eModePointer;
    }
    else {
      if (lt == eLocationNothing) nm = eModeWalkto;
      if (lt == eLocationHotspot) {
        h = Hotspot.GetAtScreenXY(x, y);
        nm = h.GetProperty("def_curs");
      }
      if (lt == eLocationObject) {
        o = Object.GetAtScreenXY(x, y);
        nm = o.GetProperty("def_curs");
      }
      if (lt == eLocationCharacter) {
        nm = eModeTalkto;
      }
    }
    if (nm != mm) mouse.Mode = nm;  // only change if necessary
  }
}

//--------------------------------------ON_MOUSE_CLICK-----------------------------------------

function on_mouse_click(MouseButton button) {
  // called when a mouse button is clicked. button is either LEFT or RIGHT
  if (IsGamePaused() == 1) {
    // Game is paused, so do nothing (ie. don't allow mouse click)
  }
  else if (button == eMouseLeft) {
   if(GetLocationType(mouse.x, mouse.y) == eLocationNothing) {
      ProcessClick(mouse.x,mouse.y, eModeWalkto);
    }
   if (mouse.Mode == eModeUseinv) {
     mouse.Mode = eModeInteract; // kick off inventory
    }
else if(GetLocationType(mouse.x, mouse.y) != eLocationNothing) {
      ProcessClick(mouse.x,mouse.y, eModeInteract);
      mouse.Mode = eModeInteract;
   }
  }
else if (button == eMouseRight){
    // right-click
    if (mouse.Mode == eModeUseinv) mouse.Mode = eModeWalkto;   // loose inv item
    else ProcessClick(mouse.x, mouse.y, eModeLookat);             // or look at ...
  }

  else if (button == eMouseLeftInv) {
    if (mouse.Mode == eModeUseinv) inventory[game.inv_activated].RunInteraction(eModeUseinv);
    else {
     player.ActiveInventory = inventory[game.inv_activated];

    }
  }
  else if (button == eMouseRightInv) {
    if (mouse.Mode == eModeUseinv) mouse.Mode = eModePointer;
    else inventory[game.inv_activated].RunInteraction(eModeLookat);
  }
}


function show_inventory_window () {
  gInventory.Visible = true;
  mouse.Mode = eModeInteract;

}


Thanks for all the help you guys have given me so far. I know looking at a lot of strange code in one post can be annoying, so thanks for putting up with me.
 
"Imitation is the sincerest form of imitation."

Khris

You can check for inventory by using:
Code: ags
  if (player.InventoryQuantity[iBag.ID] > 0) {    //  player has one or more of iBag


Also learn to use proper indentation:
Code: ags
function blah() {
  if (something) {
    Do.Something();
    Do.AnotherThing();
  }
  else {
    Do.SomethingDifferent();
  }
}

It's more readable and saves your scripting ass ;

Mantra of Doom

#2
Cool, I think that might be able to sort out my mess. And yeah, before I do anything else, I am going to comment and indent the heck out of my code... just so I know where to find everything.

I sort of just dove in there and starting tossing stuff in as I thought to add it... I'm almost done with the game and my lack of initial neatness has come back to bite me as the more complex things I need to do have gotten lost somewhere.

EDIT:

I replaced the global variables with inventory ones, and I still can't make the interaction work properly. What happens is this

1. I go into the inventory and select the vacuum
2. With the vacuum as the cursor, I click the hotspot
3. Cursor changes back to the regular icon
4. A second click will throw out the normal Interact message

I even commented out all the variable stuff and I still get the normal interaction message. I'm stumped now, as another hotspot that I'm using an inventory on different item) seems to be doing the same thing. I know it worked at one point of time, but I changed so many things since then...
"Imitation is the sincerest form of imitation."

Khris

It's right there in your on_mouse_click code:
Code: ags
   if (mouse.Mode == eModeUseinv) {
     mouse.Mode = eModeInteract; // kick off inventory
    }

No wonder it behaves that way :=

Mantra of Doom

Oh duh! It's even commented and everything.  :o 

Thanks once again KhrisMUC, you will be mentioned in the credits of my game for being such a coding ninja.
"Imitation is the sincerest form of imitation."

SMF spam blocked by CleanTalk