Scripting issue with inventoryitem - hotspot interaction

Started by Guba, Mon 14/04/2008 11:47:29

Previous topic - Next topic

Guba

At first note that I use AGS v3.0

Alright, I made a room which was a panel, that is no character visible etc, anyhow my intention was that the player must insert an item into the panel, thus bringing it online (changing room) and moving onward in the game. Now I got this to work with the command

function hhotspot_useinv()
{
player.changeroom(x);
}

now there is a certain backside with this as I found out it doesnt matter which item you use on this hotspot the player will still change the room. Now this is silly. So I wondered if someone could advice me exactly how to define a restriction on this sort of command so you can select which item can be used and prevent other items to be used on the particular hotspot. I have searched the manual but perhaps this is too simple a thing to be mentioned there. I, however, have failed to find out the solution whatever I have tried to do.

So here I am  :P

Thanks for your (future) assistance.

TwinMoon

Try this:

function hhotspot_useinv()
{
if (player.ActiveInventory==iCard) player.changeroom(x);
}

where iCard is the script name of the inventory item you want the player to use.

Guba

Thanks for the swift reply!

I tried this out however now the game crashes when I try this with whichever item in the inventory resulting in the following error message:

"Error: prepare_script: error -18 (no such function in script) trying to run 'hhotspot_UseInv' (room 3)"

AGS doesnt note any errors in scripting when I hit F5.

Ideas what this might mean?

.M.M.

Quote from: Guba on Mon 14/04/2008 12:19:27
...hhotspot_UseInv (room 3)...
Ideas what this might mean?
Quote from: TwinMoon on Mon 14/04/2008 12:01:35
function hhotspot_useinv()...
I am not sure, but I think the problem is that there are some upper case in your function.

Guba

Ah never mind, I got it to work. Apparently I had tried something similar before and not removed the script entry from the hotspots actions panel. I did this and remade the script and now it works fine.

Thanks for the assistance!

m0ds

Sorry to drag up an old thread, but I have a basic inventory issue.

I'm trying to display the name of an inventory item to use with something in the play window in a label, ie; "Use bottle with tap". Ive got the use .. with tap bit working but when clicking on the bottle in the inventory I cannot get the status bar to display it.

Here is my code;

if (GetCursorMode() == eModeUseinv)
   { SetLabelText(3,0,"Use player.ActiveInventory.Name with @OVERHOTSPOT@");

Naturally on the status bar that just displays "Use player.ActiveInventoryName with tap" lol, but I've tried putting "player.ActiveInventory.Name" in there in different ways ie putting another speech mark after use then using a comma, but AGS doesn't like it. Is there anyway I can easily rectify this, and without too much code? :)

Oh, and yes, this may be "old" code. I couldn't find any explanations in the SetLabelText help topic, maybe I was looking in the wrong place. Any help appreciated, cheers!!

TwinMoon

What version of AGS are you using???

Anyway, in 2.72 this works for me:

Code: ags

  String text = player.ActiveInventory.Name;
  txtLabel.Text = String.Format("use %s with tap", text);

monkey0506

It's not really necessary to store the name into a variable (i.e, you could just use String.Format("Use %s with @OVERHOTSPOT@", player.ActiveInventory.Name)), but it's probably a good idea to put a null-check in there:

Code: ags
if (mouse.Mode == eModeUseinv) {
  if (player.ActiveInventory != null) {
    gui[3].Controls[0].AsLabel.Text = String.Format("Use %s with @OVERHOTSPOT@", player.ActiveInventory.Name);
  }
}


mouse.Mode is the replacement property for Get/SetCursorMode. Its use is basically the same except when setting it you just use "mouse.Mode = ..." instead of calling a function.

I've just used a generic method of the code you produced, but as TwinMoon represented, as of AGS 2.7 you can assign a script o-name to your label to avoid having to provide GUI and GUIControl ID numbers; you only need provide the o-name.

The reason I said you may want to provide a null-check is just a safety precaution. Whenever you're working with pointers (check the manual for more info) it's always best to make sure it's not null, because otherwise it may crash your game. The player keyword will never be null, it's automatically managed; but the player's ActiveInventory property is a pointer-to-InventoryItem (InventoryItem*) which may possibly be null, so better safe than sorry.

m0ds

Many thanks! These work, so thats great. I do use 2.72 but I'm reluctant to use the newer methods of code, but thats mostly cos I know the older stuff pretty well and don't have the time to learn all the new ins and outs. But many thanks you two, problem solved! I may have another inventory question in a few days time, though ;)

m0ds

Hehe, okay, sooner than I thought! Everything on my GUI is working fine, but I have the final "GIVE" one verb to sort out. I'm having difficulty with this because it works a bit different from the "Use" which can be applied to inventory items..doesn't it?

On clicking the GIVE button it sets the cursor mode to eModeGive, but when you click on the inventory item I'm not sure what code to put. I've tried using the previous code you guys gave me and manipulating it but to no avail.

Any advice? Let me know if im not being clear :)

monkey0506

Previously people have tried combining Use and Give into one cursor mode, but I found it easier to keep it separated anyway. Once you're handling inventory-clicks yourself it's more work to try and merge them than allowing them to work separate anyway.

I'm guessing from what you've said you've already got eModeGive as a separate mode. If so, that's great and you're already a step ahead. Otherwise, go ahead and make a new cursor mode for it. ;) You'll also need a eModeGiveinv for giving inventory.

Next inside on_mouse_click, look for the inventory click handler, and add the code to handle give mode:

Code: ags
if (button == eMouseLeftInv) {
  InventoryItem *iat = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
  if (mouse.Mode == eModeGive) {
    player.ActiveInventory = iat;
    mouse.Mode = eModeGiveinv;
  }
}


That's basically what I've used.

m0ds

Thanks, well, I've added it, and there's no errors, but it's seems you've forgotten that I need the label to display "Give inventory item to @OVERHOTSPOT@"...how do I get that to work?

Also, how do I make the character invisible? Although AGS accepts character[EGO].on = false; it doesn't make EGO invisible anymore  ???

Thanks for your help here :)

Khris


monkey0506

#13
Regarding the label display code, it should be identical just substituting in eModeGiveinv in place of eModeUseinv:

Code: ags
if (mouse.Mode == eModeGiveinv) {
  if (player.ActiveInventory != null) {
    gui[3].Controls[0].AsLabel.Text = String.Format("Give %s to @OVERHOTSPOT@", player.ActiveInventory.Name);
  }
}


As for making characters invisible, the Character.on property was never officially supported, so perhaps it's malfunctioning? Other things you could try:

Code: ags
Character.Transparency = 100;
// OR
Character.x = -1000; // I'm moderately certain AGS allows the Character to be placed at absurd co-ordinates
Character.y = -1000; // I could be wrong though
// OR
Character.ChangeRoom(-1);


Of course replacing Character with whatever Character you want to use (such as character[EGO]). By the way, character[EGO] can be abbreviated as cEgo in case you didn't know. It's called the character's script o-name, and it's just a bit less to type. ;)

And as Khris pointed out by posting while I was taking my sweet time typing...:=...you probably want to use the player Character and not just the Ego Character, right? If so, it's best to use the player keyword instead of character[EGO] or cEgo.

m0ds

Wow, that sucks! character.on has always worked for me, but it doesn't seem to in 2.72. And now it means I have to do stupid code like put the character off screen or make him transparent? That is most sucky suck!

As for the Give command, it's still not functioning :( Which part do i put this code in?

Code: ags
if (button == eMouseLeftInv) {
  InventoryItem *iat = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
  if (mouse.Mode == eModeGive) {
    player.ActiveInventory = iat;
    mouse.Mode = eModeGiveinv;
  }
}


should it go in;

function repeatedly_execute() {

function on_mouse_click(MouseButton button) {

function btnInvSelect_Click(GUIControl *control, MouseButton button) {

??

Ive tried it in all three, none seem to do anything positive.

gah

m0ds

Just so you know, here's what I've got in each thingy:

Firstly, in repeatedly_execute;

Code: ags
if (GetCursorMode() == eModeGive)
   { SetLabelText(3,0,"Give @OVERHOTSPOT@"); 
}


followed by

Code: ags
if (mouse.Mode == eModeGiveinv) {
  if (player.ActiveInventory != null) {
    gui[3].Controls[0].AsLabel.Text = String.Format("Give %s to @OVERHOTSPOT@", player.ActiveInventory.Name);
  }
}




Then in function_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) {
    // Game is paused, so do nothing (ie. don't allow mouse click)
  }
  else if (button == eMouseLeft) {
    ProcessClick(mouse.x, mouse.y, mouse.Mode );
    SetCursorMode(eModeWalkto);
}

if (button == eMouseLeftInv) {
  InventoryItem *iat = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
  if (mouse.Mode == eModeGive) {
    player.ActiveInventory = iat;
    mouse.Mode = eModeGiveinv;
  }
}



  else {   // right-click, so cycle cursor
    //mouse.SelectNextMode();
  } 



on clicking the "give" button;

Code: ags
SetCursorMode(eModeGive);    


and on clicking an inventory item, in this case, a cog;

Code: ags
if (GetCursorMode() == eModeGive) {
SetCursorMode(eModeGiveinv);
}  


which is currently under "other click on hotspot"

monkey0506

That particular code snippet there should go inside the on_mouse_click function. You'll also need to make sure that "Handle inventory clicks in script" is enabled (General settings pane).

The other code about setting the label's text would be better suited to repeatedly_execute.

And about Character.on, I've never personally had issues with it not working, so I can't really say why it wouldn't be. Perhaps playing around with it could reveal the source of the problem to be something else? But if you can't narrow it down to any other conclusion, at least you do have other options, right?

Okay, new post. Everything looks okay (mixed old and new, but I get the drift (I have been here since 2.6! ;))) except that very last code snippet you shouldn't need at all. It should be handled by the on_mouse_click function. Oh, and also, you may want to make that an else-if clause and add support for the use cursor here:

Code: ags
else if (button == eMouseLeftInv) {
  InventoryItem *iat = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
  if (mouse.Mode == eModeGive) {
    player.ActiveInventory = iat;
    mouse.Mode = eModeGiveinv;
  }
  else if (mouse.Mode == eModeUse) {
    player.ActiveInventory = iat;
    mouse.Mode = eModeUseinv;
  }
}


Sorry if I assumed too much about your scripting knowledge there mate. I've been keeping up with the latest AGS and the AGScript standards since I've been here, so somehow I always assumed everyone else had too. But then I look at your list of games you've worked on and see that mostly you do music! If you have any further questions feel free to ask.

m0ds

Many thanks, it's working!

I have two final questions though, before you dissapear ;)

1. I now want something to happen when I give cog (icog) to Mr Smit (smit).

So, on character Smit's interactions, I've put the following on Use inventory with..

Quoteif (player.ActiveInventory == icog) {

But the script doesn't run. What am I missing, or forgetting here??

2. At the end of the above script, it leads into a dialogue, dSmitIntro

so I've used the new code;

dSmitIntro.Start();

but when the game reaches that point it crashes telling me something about dialog set to null.... why is that? Again what am I missing or forgetting?

Many thanks for all your help, everything is just about functioning perfectly, so thank you!!!

monkey0506

Quote from: Mods on Thu 15/05/2008 12:34:52Many thanks, it's working!

Yay! You're welcome! ;D

Quote from: Mods on Thu 15/05/2008 12:34:52I have two final questions though, before you dissapear ;)

1. I now want something to happen when I give cog (icog) to Mr Smit (smit).

So, on character Smit's interactions, I've put the following on Use inventory with..

You've said that you're trying to give the cog, but you've put the code in Use inventory. You're working with two (actually 4 counting inventory cursors) different cursor modes here. If you're using the give cursor you'll need to put the interaction in "Any click" and then check the cursor mode (such as "mouse.Mode == eModeGiveinv").

Quote from: Mods on Thu 15/05/2008 12:34:522. At the end of the above script, it leads into a dialogue, dSmitIntro

so I've used the new code;

dSmitIntro.Start();

but when the game reaches that point it crashes telling me something about dialog set to null.... why is that? Again what am I missing or forgetting?

I can't really say for sure why it might say that. Perhaps you could post the error message given? Does it make a difference if you index the dialog via the ID (dialog[1].Start() or such)? Is the dialog complete with options and script?

Quote from: Mods on Thu 15/05/2008 12:34:52Many thanks for all your help, everything is just about functioning perfectly, so thank you!!!

:=

m0ds

Thanks, I see the logic. I've tried this in "any click"

Code: ags
if (GetCursorMode() == eModeGiveinv) {
if (player.ActiveInventory == icog) {


but nothing happens...  ???

Note, I also tried adding in being able to start the dialog by choosing "Pull Mr Smit"

Code: ags
else


if (GetCursorMode() == eModePull) {
  dSmitIntro.Start();
  }


Again though, nothing happens. Could this be related to the "process_click" function?

Its almost as if all of the things under Mr Smit's "interaction" options are being ignored..

SMF spam blocked by CleanTalk