Type of Identifier Differs from Original Declaration

Started by Baron, Thu 23/09/2010 20:33:11

Previous topic - Next topic

Baron

Hi Again,
      I've upgraded to AGS 3.2 and I'm having a hard time making a function work.  It's my only function so far, and I'm a little rusty at this sort of thing, but still.... I used to be able to do this stuff.  I get the error mentioned in the subject line when my function is introduced.  Research gives me only this thread , which doesn't really seem to resolve anything.
      What I am trying to do: I have a "phantom inventory" that I'm using for the sake of it's built in index, while my function sorts inventory graphics according to their order in the index elsewhere.  But the error seems to occur right at the beginning of the function, so maybe I'm doing this in an outdated fashion.  Here's the error line:

Code: ags

function increaseInv (String item){


      I'm sure it's simple, but what am I doing wrong here?

--------------
Edit: Alright, apparently my "import function" statement in the header script was being interpreted as a declaration.  I'm off to figure out how the heck to use that header properly, but I've got a new error to work with:

GlobalScript.asc(17): Error (line 17): Type mismatch: cannot convert 'String*' to 'InventoryItem*'

In this line I am trying to dump the name of the inventory item just interacted with into an AddInventory command:

Code: ags

function increaseInv (String item){
  cplayer.AddInventory(item);


The error message clearly states that this is not possible, but I'm having a hard time figuring out how I can construct something similar (i.e. a variable that can save the inventory item I'm working with).  Must I resort to working with inventory items by number the old fashioned way?  Or is this InventoryItem* some sort of new syntax that I haven't figured out?
--------------------
Edit Again: Well, I can get it to work using (int item) instead of (String item) and some new syntax:

Code: ags

function increaseInv (int item){
  player.AddInventory(inventory[item]);


But I'm still not happy about having to use ints instead of Strings.  So one specific question:

1) How can I set a String variable to (or Pointer to?) an inventory item's name so that I can reference it in a function elsewhere?


Khris

Use a pointer:

Code: ags
function increaseInv (InventoryItem*item){
  cplayer.AddInventory(item);
}

  increaseInv(iBox);

Or do it using an extender function:

Code: ags
function Increase(this InventoryItem*){
  cplayer.AddInventory(this);
}

  iBox.Increase();


Dualnames

#2
Khris is definitely showing the way, if you still want to do it otherwise..

Code: ags

function Baron(String item) {
int i;
  while (i != Game.InventoryItemCount) {
      if ((cplayer.HasInventory(inventory[i])==false)  && (item == inventory[i].Name)) {
            cplayer.AddInventory(inventory[i]);
       }
  i++;
  }
}


EDIT: Fixed my forgetfulness.
Worked on Strangeland, Primordia, Hob's Barrow, The Cat Lady, Mage's Initiation, Until I Have You, Downfall, Hunie Pop, and every game in the Wadjet Eye Games catalogue (porting)

Baron

Khris definitely clarified how to use a pointer in a function, and I'd like to do it that way if I can iron out a few wrinkles.  Thanks.

Quote from: Dualnames on Fri 24/09/2010 11:55:47
Khris is definitely showing the way, if you still want to do it otherwise..

Code: ags

function Baron(String item) {
int i;
  while (i != Game.InventoryItemCount) {
      if ((cplayer.HasInventory(inventory[i]))  && (item == inventory[i].Name)) {
            cplayer.AddInventory(inventory[i]);
       }
  i++;
  }
}


If the player.HasInventory(inventory[i ]), why must cplayer.AddInventory(inventory[i ])? 

        Otherwise this is similar to the workaround I was using before -but it is still basically numeric (i is an int).  How do I take a String, which saves a specific item's name, and make it useful for the code again?  In ActionScript I can reconstruct variables by adding Strings together: "String"+"_01" can be read as variable Baron_01 (if String held the characters "Baron"), but AGS doesn't want to recognize my inventory script names if they are saved in Strings.  For example, String invslot1 saves the inventory name of the inventory item at InvMain.ItemAtIndex[0].  That item will change through the game when the original item is used (and lost), so I want to keep track of it with a variable.  Not only that, but "slot1" could rotate depending on what inventory is being viewed, so I really would like to keep track of this data as a versatile variable.  Anyway, in AGS I will get an error if I use invslot1 as a String here:
Code: ags

if (Mouse.Mode == eModeInteract) player.ActiveInventory =inventory[invslot1];


      But when invslot1 is an int (or char, actually), I can save the number and plug it back in to other code easily:
Code: ags

if (Mouse.Mode == eModeInteract) player.ActiveInventory =inventory[invslot1];


     Everything works, except I have to remember the inventory items by number (not a huge deal).  What I really want is to be able to use a String variable to record an inventory item pointed at -so I can remember what it is - and then be able to use that data usefully again in the script.  Is the solution to make invslot1 (and all the other slots) into pointers and use them like variables?  Is this possible?



     

Dualnames

i meant ! in that first part of the argument. ::)
Worked on Strangeland, Primordia, Hob's Barrow, The Cat Lady, Mage's Initiation, Until I Have You, Downfall, Hunie Pop, and every game in the Wadjet Eye Games catalogue (porting)

Calin Leafshade

#5
You can't really use a string to 'point' at an inventory item and it's bad programming practice anyway.

The only way you *could* do that is be iterating through the array like Dualnames did but thats really unnecessary unless you're taking input from the user.

You should use pointers for this like Khris suggested.

The problem most people have with understanding pointers (or at least i certainly did) is that they think it's like declaring any other kind of variable.

when you declare 'int i;' the compiler runtime sets aside enough memory to hold an integer (4 bytes?) and calls that space in memory 'i'.

However when you declare 'InventoryItem *invitem;' that does not set aside enough memory for an InventoryItem object it only sets aside enough memory to hold a memory address (those weird hexadecimal numbers you sometimes see when your computer crashes)

So when you declare 'InventoryItem *invitem;' you are not declaring a NEW inventory item you are just making a reference to an EXISTING inventory item. (Although when it is first declared it is 'null', which is where you get 'Null Pointer Referenced' from)

So you can use this as a kind of substitution.

Let's assume you have some kind of method to deal with hotspot clicks and you want to do several things to the hotspot that the user just clicked:

Code: ags

//this is done without the editor so spare me some mistakes

Hotspot *hs = Game.GetHotspotAtScreen(mouse.x, mouse.y); // this sets the pointer hs to be a reference to the hotspot we just clicked.

if (hs.GetProperty('WalkTo')) player.Walk(hs.WalkToX, hs.WalkToY);
player.Loop = hs.GetProperty('FaceDir');
hs.RunInteraction(eModeInteract);



Using pointers is a fantastic way to dramatically cut down the amount of code required to do stuff.

I'm sorry if you already fully understand pointers.. I just thought it would be helpful to clarify what they are/do.


Dualnames

You should use pointers alright, but I just thought Baron may just WANT to do it his way badly. Doesn't mean its correct. It really depends on what the user feels more comfortable with. Of course that doesn't mean that it's correct.
Worked on Strangeland, Primordia, Hob's Barrow, The Cat Lady, Mage's Initiation, Until I Have You, Downfall, Hunie Pop, and every game in the Wadjet Eye Games catalogue (porting)

Baron

@Calin: Thanks for the pointers on.... pointers.  You are correct to assume that I'm not yet entirely comfortable in their use and I did find your example educational.

@Dualnames: Yes, I will definitely use pointers where possible, but I don't think this is an instance where they will be.  As I understand it from Calin's post, pointers point to specific memory, but I really do need something that can store variable information.  So I think I'm doing my inventory system numerically this time around.  Thanks for all your help!


SMF spam blocked by CleanTalk