Please login or register.

Login with username, password and session length
Advanced search  

News:

For WME related articles and tutorials visit WME Resource Center.

Author Topic: How to ALWAYS set Game.Interactive to false when actor performs action?  (Read 8036 times)

0 Members and 1 Guest are viewing this topic.

Erwin_Br

  • Lurker
  • *
  • Karma: 0
  • Offline Offline
  • Posts: 14
    • View Profile

Hi all,

When my actor performs an action, I want the game to always turn "Game.Interactive" to false. Instead of entering the false/true lines for every event in every script, I figured I could easily do this in one place by adjusting the onLeftClick event. This may save me lots of redundant lines of code in the future.  ;) Unfortunately, I have a problem.  :'( This is what I do:

Code: WME Script
  1. on "LeftClick"
  2. {
  3.   var ActObj = Game.ActiveObject; // Retrieves object under mouse cursor, if any
  4.   if(ActObj!=null) // we did click an object
  5.   {
  6.  
  7. //Code cutted away to keep the example simple. We go straight to case 1, which is triggered when the mouse pointer is 1, or "LookAt"
  8.        
  9.   case 1:
  10.     if(ActObj.CanHandleEvent("LookAt")) ActObj.ApplyEvent("LookAt");
  11.     else actor.Talk("What's so special about it?");
  12.     break;
  13.  
  14.     //Code cutted away. (The other cases)
  15.  
  16.  
  17.     WaitFor(actor); //Let actor finish his event
  18.     Game.Interactive = true; //Give control back to player
  19.   }
  20. }
  21.  

The problem is that I don't get back control of the game. Game.Interactive remains false. The funny thing is that when I use the debugger and step through the script, it suddenly DOES work.

The reason why I added the WaitFor(actor) command is that if I don't -- the game gives back control to the player while the actor still has to perform his actions.

What am I doing wrong?

Or perhaps there is a better way of accomplishing my goal?

Thanks!

« Last Edit: December 30, 2008, 10:44:29 AM by Erwin_Br »
Logged

Mnemonic

  • WME developer
  • Administrator
  • Addicted to WME forum
  • *
  • Karma: 41
  • Offline Offline
  • Gender: Male
  • Posts: 5683
    • View Profile
    • Dead:Code Site
Re: How to ALWAYS set Game.Interactive to false when actor performs action?
« Reply #1 on: December 30, 2008, 09:07:15 AM »

Am I seeing things or is the "Game.Interactive = true;" line OUTSIDE the LeftClick handler?
Logged
Yes, I do have a twitter account
Please don't send me technical questions in private messages, use the forum. ::wave

Erwin_Br

  • Lurker
  • *
  • Karma: 0
  • Offline Offline
  • Posts: 14
    • View Profile
Re: How to ALWAYS set Game.Interactive to false when actor performs action?
« Reply #2 on: December 30, 2008, 10:43:50 AM »

Am I seeing things or is the "Game.Interactive = true;" line OUTSIDE the LeftClick handler?

No, sorry about that. It's just sloppy copy and paste work on my behalf. These 2 }'s are closing the switch and another condition. Sorry. I have adjusted the example.

When I step through the code using the debugger, I see that when I call "ActObj.ApplyEvent("LookAt")", the script continues to run through the LeftClick function while it's performing its tasks in the script that's handling the event. It also stops nicely at "WaitFor(actor);", like I intended. Why does it seem to ignore this when running the game normally is beyond me. I really hope you have an idea. :)
Logged

Mnemonic

  • WME developer
  • Administrator
  • Addicted to WME forum
  • *
  • Karma: 41
  • Offline Offline
  • Gender: Male
  • Posts: 5683
    • View Profile
    • Dead:Code Site
Re: How to ALWAYS set Game.Interactive to false when actor performs action?
« Reply #3 on: December 30, 2008, 04:26:13 PM »

Now when I think of if, WaitFor() probably isn't best idea. You know, when some script waits for some game object, it also kills all other scripts waiting for the same object, this is how event handling in WME works. So, your LeftClick handler calls WaitFor and starts waiting. In the meantime, some of your other scripts calls actor.GoTo() or some similar "waiting" method, which effectively kills the waiting LeftClick handler.
Logged
Yes, I do have a twitter account
Please don't send me technical questions in private messages, use the forum. ::wave

Erwin_Br

  • Lurker
  • *
  • Karma: 0
  • Offline Offline
  • Posts: 14
    • View Profile
Re: How to ALWAYS set Game.Interactive to false when actor performs action?
« Reply #4 on: December 30, 2008, 05:06:34 PM »

Hmmm... Any suggestions of another way to globally set the Game.Interactive so I don't have to include it in every event handler?
Logged

Mnemonic

  • WME developer
  • Administrator
  • Addicted to WME forum
  • *
  • Karma: 41
  • Offline Offline
  • Gender: Male
  • Posts: 5683
    • View Profile
    • Dead:Code Site
Re: How to ALWAYS set Game.Interactive to false when actor performs action?
« Reply #5 on: December 30, 2008, 05:09:52 PM »

I'm not sure that's something that should be handled globally, because you can do many different actions in the game. If your actor performs many similar tasks, perhaps you could define some "macro-action", in the form of a custom actor method(s), and incorporate the interactivity setting into that action.
Logged
Yes, I do have a twitter account
Please don't send me technical questions in private messages, use the forum. ::wave

Erwin_Br

  • Lurker
  • *
  • Karma: 0
  • Offline Offline
  • Posts: 14
    • View Profile
Re: How to ALWAYS set Game.Interactive to false when actor performs action?
« Reply #6 on: December 30, 2008, 05:24:13 PM »

Well, bottom line is that I want to take away control when the player triggers an event on an object (look at, talk to, etc.). Obviously I don't want to do this when the player clicks anywhere else, triggering a walk to event or a menu button click, etc... But that was already covered in above example.

Well, thanks for your input so far. I'm still exploring the engine to see if it'll fit my needs, and this is not an important issue. I just don't like redundancy, and want to control things centrally as much as possible.  ;D

Thanks!
Logged

mylesblasonato

  • Developer
  • Frequent poster
  • ****
  • Karma: 0
  • Offline Offline
  • Gender: Male
  • Posts: 265
  • "Give up is to fail as sacrifice is to succeed"
    • View Profile
    • Royal Wins
Re: How to ALWAYS set Game.Interactive to false when actor performs action?
« Reply #7 on: December 31, 2008, 11:28:09 PM »

Hi Erwin,
Maybe you could try adding the Game.interactive = false; into the script of your menu like this:

Code: WME Script
  1. #include "scripts\base.inc"
  2.  
  3. global MenuObject;
  4.  
  5. ////////////////////////////////////////////////////////////////////////////////
  6. on "Take"
  7. {
  8.   this.Close();
  9.   if(MenuObject!=null)
  10.   {
  11.     if(MenuObject.CanHandleEvent("Take")){
  12.                 MenuObject.ApplyEvent("Take");
  13.                 Game.Interactive = false; // THIS IS WHAT I ADDED
  14.     }else actor.Talk("I can't take this.");
  15.   }
  16.   MenuObject = null;
  17. }
  18.  
  19.  
  20. ////////////////////////////////////////////////////////////////////////////////
  21. on "LookAt"
  22. {
  23.   this.Close();
  24.   if(MenuObject!=null)
  25.   {
  26.     if(MenuObject.CanHandleEvent("LookAt")){
  27.                 MenuObject.ApplyEvent("LookAt");
  28.                 Game.Interactive = false; // THIS IS WHAT I ADDED
  29.     }else actor.Talk("I don't know what to say about it.");
  30.   }
  31.   MenuObject = null;
  32. }
  33.  
  34.  
  35. ////////////////////////////////////////////////////////////////////////////////
  36. on "Talk"
  37. {
  38.   this.Close();
  39.   if(MenuObject!=null)
  40.   {
  41.     if(MenuObject.CanHandleEvent("Talk")){
  42.                 MenuObject.ApplyEvent("Talk");
  43.                 Game.Interactive = false; // THIS IS WHAT I ADDED
  44.     }else actor.Talk("Can't talk to this.");
  45.   }
  46.   MenuObject = null;
  47. }

After you have done that the game should not be interactive when you are doing a certain action according to the which action you choose. To set it back to true so the player can play again you could add in an if statement into the game loop script to check if if the actor is ready, I put it into the game loop script so that it will be tested all the time. Try the following:

Code: WME Script
  1. #include "scripts\base.inc"
  2.  
  3. // this script runs in an endless loop and does all the user-interface work
  4. // that needs to be periodically updated
  5. // such as the floating items captions display and positioning
  6. // and the sliding inventory window handling
  7.  
  8.  
  9.  
  10. global WinCaption;
  11. global WinMenu;
  12.  
  13. // infinite loop
  14. while(true){
  15.  
  16.   // save the active object for later
  17.   var ActObj = Game.ActiveObject;
  18.  
  19.   // THIS IS WHAT I ADDED. THE WHOLE IF STATEMENT
  20.   if(actor.Ready == true){
  21.         Game.Interactive = true;
  22.   }

Obviously where I put "THIS IS WHAT I ADDED" is what i added to the script so you know what I have done, that should make it easier to understand. Hope this helps.

Note that I haven't tested this so I don't know if it will work but logically it seems to. Also because your testing all the time if the actor is ready it could slow down the game and bring down the FPS a bit so I suggest adding in a variable that switches the if statement in the game loop script on and off. I would turn it on by adding a line to set it to true just under the Game.Interactive = false; statements in the menu script and then turn if off by setting it to false in the game loop if statement under the Game.Interactive = true; statement. Because I'm nice i have added it for you.

Code: WME Script
  1. #include "scripts\base.inc"
  2.  
  3. global MenuObject;
  4.  
  5. ////////////////////////////////////////////////////////////////////////////////
  6. on "Take"
  7. {
  8.   this.Close();
  9.   if(MenuObject!=null)
  10.   {
  11.     if(MenuObject.CanHandleEvent("Take")){
  12.                 MenuObject.ApplyEvent("Take");
  13.                 Game.Interactive = false; // THIS IS WHAT I ADDED
  14.                      interactiveCheck = true; // THIS IS THE VARIABLE I WAS TALKING ABOUT
  15.     }else actor.Talk("I can't take this.");
  16.   }
  17.   MenuObject = null;
  18. }
  19.  
  20.  
  21. ////////////////////////////////////////////////////////////////////////////////
  22. on "LookAt"
  23. {
  24.   this.Close();
  25.   if(MenuObject!=null)
  26.   {
  27.     if(MenuObject.CanHandleEvent("LookAt")){
  28.                 MenuObject.ApplyEvent("LookAt");
  29.                 Game.Interactive = false; // THIS IS WHAT I ADDED
  30.                      interactiveCheck = true; // THIS IS THE VARIABLE I WAS TALKING ABOUT
  31.     }else actor.Talk("I don't know what to say about it.");
  32.   }
  33.   MenuObject = null;
  34. }
  35.  
  36.  
  37. ////////////////////////////////////////////////////////////////////////////////
  38. on "Talk"
  39. {
  40.   this.Close();
  41.   if(MenuObject!=null)
  42.   {
  43.     if(MenuObject.CanHandleEvent("Talk")){
  44.                 MenuObject.ApplyEvent("Talk");
  45.                 Game.Interactive = false; // THIS IS WHAT I ADDED
  46.                      interactiveCheck = true; // THIS IS THE VARIABLE I WAS TALKING ABOUT
  47.     }else actor.Talk("Can't talk to this.");
  48.   }
  49.   MenuObject = null;
  50. }

After you have done that you just need to add the global variable to the if statement in the game loop script where we test if the actor is ready. See the following

Code: WME Script
  1. #include "scripts\base.inc"
  2.  
  3. // this script runs in an endless loop and does all the user-interface work
  4. // that needs to be periodically updated
  5. // such as the floating items captions display and positioning
  6. // and the sliding inventory window handling
  7.  
  8.  
  9.  
  10. global WinCaption;
  11. global WinMenu;
  12.  
  13. // infinite loop
  14. while(true){
  15.  
  16.   // save the active object for later
  17.   var ActObj = Game.ActiveObject;
  18.  
  19.   // THIS IS WHAT I ADDED. THE WHOLE IF STATEMENT
  20.  
  21.   if(interactiveCheck == true){
  22.      if(actor.Ready == true){
  23.         Game.Interactive = true;
  24.           interactiveCheck = false;
  25.      }
  26.    }

There you go. Let me know if it works. Also add into you base script the global variable for your switch/checker. In my case I would add: global interactiveCheck;

Cheers ::beer
Myles Blasonato.
« Last Edit: January 03, 2009, 06:20:05 AM by mylesb »
Logged
Lead Game Designer, Royal Wins.
@mylesblasonato
@royalwins
http://au.linkedin.com/pub/myles-blasonato/26/600/a38

Erwin_Br

  • Lurker
  • *
  • Karma: 0
  • Offline Offline
  • Posts: 14
    • View Profile
Re: How to ALWAYS set Game.Interactive to false when actor performs action?
« Reply #8 on: January 02, 2009, 03:36:14 PM »

Yay! It works like a charm!

Thanks very much for the very detailed and clear explanation.  ::thumbup
Logged

Jyujinkai

  • Global Moderator
  • Frequent poster
  • *
  • Karma: 1
  • Offline Offline
  • Posts: 352
    • View Profile
    • Jyujinkai's WME Development Blog
Re: How to ALWAYS set Game.Interactive to false when actor performs action?
« Reply #9 on: January 02, 2009, 03:55:02 PM »

@mylesb

Edited your post to change the code blocks to use the SCRIPT formatting functions of the site.

Please see:- Posting Code Snipits @ WME Forums
Logged
<Antoine de Saint-Exupéry> In any thing at all, perfection is finally attained not when there is no longer anything to add, but when there is no longer anything to take away...
<Carl Sagan> If you want to make a apple pie from scratch. You must first... invent the universe

mylesblasonato

  • Developer
  • Frequent poster
  • ****
  • Karma: 0
  • Offline Offline
  • Gender: Male
  • Posts: 265
  • "Give up is to fail as sacrifice is to succeed"
    • View Profile
    • Royal Wins
Re: How to ALWAYS set Game.Interactive to false when actor performs action?
« Reply #10 on: January 03, 2009, 06:14:32 AM »

Hey great it works  :)
Sorry I didn't know there was a function for posting scripts, I will keep it in mind for next time.

Cheers ::beer
Myles Blasonato.
Logged
Lead Game Designer, Royal Wins.
@mylesblasonato
@royalwins
http://au.linkedin.com/pub/myles-blasonato/26/600/a38
 

Page created in 0.105 seconds with 21 queries.