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.
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.
// 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.
You can check for inventory by using:
if (player.InventoryQuantity[iBag.ID] > 0) { // player has one or more of iBag
Also learn to use proper indentation:
function blah() {
if (something) {
Do.Something();
Do.AnotherThing();
}
else {
Do.SomethingDifferent();
}
}
It's more readable and saves your scripting ass ;
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...
It's right there in your on_mouse_click code:
if (mouse.Mode == eModeUseinv) {
mouse.Mode = eModeInteract; // kick off inventory
}
No wonder it behaves that way :=
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.