Author Topic: Take item only one time...  (Read 612 times)  Share 

TheRoger

  • Old pic got blocked...
    • I can help with translating
    •  
Take item only one time...
« on: 21 Mar 2010, 16:03 »
I wanted to do that player could take item from somewhere only one time. I did this code for that

else if(UsedAction(eGA_Open)) {
  if (player.HasInventory(itape)) {
  player.Say("There's nothing useful anymore.");
  }
  else {player.Say("There might be something useful.");
  player.Say("Let me check.");
  cEgo.Walk(384, 314, eBlock, eWalkableAreas);
  cEgo.FaceLocation(cEgo.x, cEgo.y - 50);
  player.Say("Junk, junk, more junk...");
  player.Say("Eureka");
  cEgo.AddInventory(itape);
  }}

It says that if character has tape, he wont be able to get new one and vice-versa. Well when I was testing the game, I noticed that if I got that Item, used it somewhere else, and don't have in inventory, it gives me a new one(logical). How should I do that it won't happen.
« Last Edit: 21 Mar 2010, 17:35 by TheRoger »

Khris

  • Evil Dark Emperor Death-Kill
    • Lifetime Achievement Award Winner
    •  
    • I can help with play testing
    •  
    • I can help with scripting
    •  
    • I can help with translating
    •  
Re: Take item only one time...
« Reply #1 on: 21 Mar 2010, 16:33 »
Usually the answer is use a variable, in this case though, there's the handy DoOnceOnly function:

[code]  else if (UsedAction(eGA_Open)) {
    if (Game.DoOnceOnly("finding tape")) {
      player.Say("There might be something useful.");
      player.Say("Let me check.");
      player.Walk(384, 314, eBlock);
      player.FaceDirection(eDirUp);
      player.Say("Junk, junk, more junk...");
      player.Say("Eureka");
      player.AddInventory(itape);
    }
    else player.Say("There's nothing useful anymore.");
  }[/code]

For a specific string, this function returns true the first time, then false thereafter.
http://whathaveyoutried.com/

The other day on yahoo answers:
"Can you print colored images with black ink? If so tell me how please Thanx Kimberly"

Piotr OBKINSKI

  • Ph'nglui mglwnafh R'lyeh wgah'nagl Cthulhu fhtagn
    • I can help with backgrounds
    •  
    • I can help with characters
    •  
    • I can help with play testing
    •  
    • I can help with story design
    •  
    • I can help with translating
    •  
    • I can help with voice acting
    •  
    • I can help with web design
    •  
Re: Take item only one time...
« Reply #2 on: 21 Mar 2010, 16:38 »
woh ! great one :)

I write it down too, I always used variables, this function is quite handy !

alternatively I was about to tell

set a variable to whatever, once the tape is used : ie :  vtape =1;

then  update your

 if (player.HasInventory(itape)) {

to

  if (player.HasInventory(itape) || vtape == 1) {
Working on my games ! AGAIN ! More information soon.

TheRoger

  • Old pic got blocked...
    • I can help with translating
    •  
Re: Take item only one time...
« Reply #3 on: 21 Mar 2010, 17:14 »
Didn't knew about DoOnceOnly function, It'll be time saver for me, thank you for help

TheRoger

  • Old pic got blocked...
    • I can help with translating
    •  
Re: Take item only one time...
« Reply #4 on: 21 Mar 2010, 17:36 »
Can't get this work with this code:
player.HasInventory(icap)
any ideas?

Crimson Wizard

  • AGS Project Admins
  • not et suppotreD
    • I can help with translating
    •  
Re: Take item only one time...
« Reply #5 on: 21 Mar 2010, 18:06 »
Can't get this work with this code:
player.HasInventory(icap)
any ideas?
What is not working, exactly?

Khris

  • Evil Dark Emperor Death-Kill
    • Lifetime Achievement Award Winner
    •  
    • I can help with play testing
    •  
    • I can help with scripting
    •  
    • I can help with translating
    •  
Re: Take item only one time...
« Reply #6 on: 22 Mar 2010, 01:21 »
Post the code you're using.
http://whathaveyoutried.com/

The other day on yahoo answers:
"Can you print colored images with black ink? If so tell me how please Thanx Kimberly"

TheRoger

  • Old pic got blocked...
    • I can help with translating
    •  
Re: Take item only one time...
« Reply #7 on: 22 Mar 2010, 05:26 »
I wanted to that, if player has bottle cap, he gets bottle, and won't lose the cap

else if(UsedAction(eGA_Use)) {
   
  if (player.HasInventory(icap))  {
    Game.DoOnceOnly("finding tape");
      player.Say("Maybe I have something here.");
      player.Walk(715, 325, eBlock);
      cEgo.FaceLocation(cEgo.x, cEgo.y - 50);
      player.Say("Found it");
      player.AddInventory(ihalfbottle);
    }
    else player.Say("There's nothing useful anymore.");
}}

But character still gets bottle if has cap.

Actually I think it's my fault, because I don't know where to put DoOnceOnly, I tried many locations before hasinventory and this, but it doesn't work...

Piotr OBKINSKI

  • Ph'nglui mglwnafh R'lyeh wgah'nagl Cthulhu fhtagn
    • I can help with backgrounds
    •  
    • I can help with characters
    •  
    • I can help with play testing
    •  
    • I can help with story design
    •  
    • I can help with translating
    •  
    • I can help with voice acting
    •  
    • I can help with web design
    •  
Re: Take item only one time...
« Reply #8 on: 22 Mar 2010, 07:22 »
you should use kriss code ( see upper )

the "if doonceonly" is as the beginning, once you've picked the tape, that you have or not in the inventory doesnt matter, it has been taken ! That's what does this function.

dont test the HasInventory value then !

quote :
Quote
  else if (UsedAction(eGA_Open)) {
    if (Game.DoOnceOnly("finding tape")) {
      player.Say("There might be something useful.");
      player.Say("Let me check.");
      player.Walk(384, 314, eBlock);
      player.FaceDirection(eDirUp);
      player.Say("Junk, junk, more junk...");
      player.Say("Eureka");
      player.AddInventory(itape);
    }
    else player.Say("There's nothing useful anymore.");
  }
Working on my games ! AGAIN ! More information soon.

Khris

  • Evil Dark Emperor Death-Kill
    • Lifetime Achievement Award Winner
    •  
    • I can help with play testing
    •  
    • I can help with scripting
    •  
    • I can help with translating
    •  
Re: Take item only one time...
« Reply #9 on: 22 Mar 2010, 10:43 »
One sec.
After the player uses something, they will find an item, but only if they have a bottle cap in their possession?
That doesn't make sense.

Regarding the technical side:
DoOnceOnly is supposed to be used like this:

[code]  if (Game.DoOnceOnly("arbitrary but unique string")) {

    // code in here will be executed only the first time

  }
  else {

    // code in here will be executed not the first but every subsequent time

  }[/code]

So don't use the string "finding tape" again, use another string instead, e.g. "finding bottle".
http://whathaveyoutried.com/

The other day on yahoo answers:
"Can you print colored images with black ink? If so tell me how please Thanx Kimberly"

TheRoger

  • Old pic got blocked...
    • I can help with translating
    •  
Re: Take item only one time...
« Reply #10 on: 22 Mar 2010, 14:13 »
Here's what I need, If player has bottle cap, he will take the bottle, because it is needed only after getting bottle cap, and before that, player don't even need bottle...

Crimson Wizard

  • AGS Project Admins
  • not et suppotreD
    • I can help with translating
    •  
Re: Take item only one time...
« Reply #11 on: 22 Mar 2010, 14:38 »
Maybe this:

[code]
if (player.HasInventory(icap) && !player.HasInventory(ihalfbottle))
{
      player.Say("Maybe I have something here.");
      player.Walk(715, 325, eBlock);
      cEgo.FaceLocation(cEgo.x, cEgo.y - 50);
      player.Say("Found it");
      player.AddInventory(ihalfbottle);
}
[/code]

This will make character find bottle ONLY if he already has the cup AND if he does not have the bottle yet.

Just in case you did not know, ! operator means "not".
« Last Edit: 22 Mar 2010, 14:39 by Crimson Wizard »

Khris

  • Evil Dark Emperor Death-Kill
    • Lifetime Achievement Award Winner
    •  
    • I can help with play testing
    •  
    • I can help with scripting
    •  
    • I can help with translating
    •  
Re: Take item only one time...
« Reply #12 on: 22 Mar 2010, 15:09 »
This'll make the original problem resurface, because as soon as the player looses the bottle, they can get it again.

[code]  else if(UsedAction(eGA_Use)) {
    if (player.HasInventory(icap))  {
      if (Game.DoOnceOnly("finding bottle")) {
        player.Say("Maybe I have something here.");
        player.Walk(715, 325, eBlock);
        player.FaceDirection(eDirUp);
        player.Say("Found it");
        player.AddInventory(ihalfbottle);
      }
      else player.Say("There's nothing useful anymore.");
    }
    else player.Say("I don't think there's anything in there I need.");
  }[/code]
http://whathaveyoutried.com/

The other day on yahoo answers:
"Can you print colored images with black ink? If so tell me how please Thanx Kimberly"

Crimson Wizard

  • AGS Project Admins
  • not et suppotreD
    • I can help with translating
    •  
Re: Take item only one time...
« Reply #13 on: 22 Mar 2010, 15:29 »
Oh... right.  :P

monkey_05_06

  • AGS Project Admins
  • Has left the building.
Re: Take item only one time...
« Reply #14 on: 23 Mar 2010, 12:08 »
[code]  if (Game.DoOnceOnly("arbitrary but unique string")) {
  // ...
}[/code]

So don't use the string "finding tape" again, use another string instead, e.g. "finding bottle".

I just wanted to clarify this a bit. What happens is when you call Game.DoOnceOnly you specify a string value as the parameter. It can be anything you want it to be. AGS then takes that value and checks if you ever used it before. If you have, then the function returns false; otherwise it returns true.

So, technically speaking, the following is completely valid:

[code]if (Game.DoOnceOnly("some repeated string")) {
  Display("1");
}
else if (Game.DoOnceOnly("some repeated string")) {
  Display("2");
}
else if (Game.DoOnceOnly("some repeated string")) {
  Display("3");
}[/code]

That will compile and run fine. However, you will only ever see the message, "1" displayed. Since you're passing the same string AGS detects that you have used it before and will return false for each of the else clauses.

My reason behind pointing this out is that you might want to check whether the user has found the bottle in more than one place. Although the code will compile properly, if you are specifying the same identifier string value in more than one location in your script, the Game.DoOnceOnly function will only return true one time for every instance of that identifier.

This can be useful if properly applied, but it's important to recognize what exactly is taking place when you are using this function.
Let's be honest. Most people suck at coding. I suck at coding, but at least my code is readable. To Hell with anyone too lazy to maintain consistent formatting in their code. I could deal with bad interfaces and structure if I could even read your horrible code. And that's putting it nicely. -monkey

TheRoger

  • Old pic got blocked...
    • I can help with translating
    •  
Re: Take item only one time...
« Reply #15 on: 23 Mar 2010, 13:13 »
I'll try to play more with this. Is there a code that I could do action if I did action before. For example: There are drawers, and you can't use them, but if you go and talk to a man, you can use drawers to take something from there.

Re: Take item only one time...
« Reply #16 on: 23 Mar 2010, 14:31 »
Just use a variable for these kind of things. Create a bool ("opendrawers" or something) and set it to true after talking to the man. Then in the drawer's action event, ask if the bool is true or not.