Jibble

Author Topic: TEMPLATE: Tumbleweed Verbs 1.3 Last update: 24th December 2019  (Read 20878 times)

Flugeldufel

  • Gary G. Gerisson
    • Flugeldufel worked on one or more games that was nominated for an AGS Award!
First of all: Thank you, abstauber for this nice template! Gefällt mir! ;)

I'm currently working on my first game and I changed some GUIs and sprites to match my taste. Among others I replaced the verbs with the ones shown in the screenshot.
Now I'm not sure, if (when I release this game sometime) I might get problems because it looks too similar to the original Thimbleweed-verbs. (although I drew them totally new for that low resolution, 320x180)

Should I change it? What do you all think?  ???



Here's a comparison of both:

mine:




Thimbleweed Park:


abstauber

  • Cavefish
  • Mittens Knight
  • still mowing the lawn
    • abstauber worked on one or more games that won an AGS Award!
    •  
    • abstauber worked on one or more games that was nominated for an AGS Award!
Wow, those graphics look really nice!

Well the button font is quite close to the one of Thimbleweed Park - I'd say if you go commercial, you might want to go for a more independet route.

But if it's freeware I don't see any issues at all - the font (also the color) fits your game perfectly (as far as I can tell from your background)

Flugeldufel

  • Gary G. Gerisson
    • Flugeldufel worked on one or more games that was nominated for an AGS Award!
Thank you very much for your feedback! And you confirmed what I already thought.
I don't know, if it's going to be freeware or commercial - it will depend on how complex the game will finally be, full length or not... We'll see. It's still at an early stage.
So I think I'll keep the sprites for now and maybe make some new ones later.

By the way, I would give the actual sprites to anyone who's interested in using them. Just let me know...

Is it possible to save more than nine games?

abstauber

  • Cavefish
  • Mittens Knight
  • still mowing the lawn
    • abstauber worked on one or more games that won an AGS Award!
    •  
    • abstauber worked on one or more games that was nominated for an AGS Award!
Yes, out of the box, you are stuck with nine games. But you can of course extend the save/load gui to your liking: you just need to add more save/load buttons and tell the optiongui script about it.

abstauber

  • Cavefish
  • Mittens Knight
  • still mowing the lawn
    • abstauber worked on one or more games that won an AGS Award!
    •  
    • abstauber worked on one or more games that was nominated for an AGS Award!
Maybe it's time to finally declare 1.2 to be stable.  (nod)

This is mainly a refactoring release, no new functions have been added so far. But internally the template has changed a lot.

- cleaned up the global script (moved the remaining GUI actions to the options menu module)
- Localisation of the GUI elements is handled a bit different internally
- It's possible to change the GUIs being used by the template
- Some more refactoring, the template throws errors if a module is missing.
- Bugfix: Option GUI wasn't translated if English is not set as default language


Hello, I'd like to report a bug.

Preferably performed in larger rooms for convenience:
* Have room 1 and room2;
* In room 2 script cutscene where player's character is walking non-blocking in After Fade-in event
Code: Adventure Game Studio
  1. player.Walk(x,y,eNoBlock);
  2. while (player.Moving) Wait(1);
  3.  
* Run the game, and when in room 1 start running with double-click;
* Immediately press Ctrl+X and change to room 2.

The player character will continue running during cutscene in another room.

Thinking about it, maybe it's enough to just run a cutscene in the same room. Guess the mistake is that character keeps running even when another Walk is called by a script command, even though it may not be required.
« Last Edit: 30 Apr 2019, 09:58 by Crimson Wizard »

abstauber

  • Cavefish
  • Mittens Knight
  • still mowing the lawn
    • abstauber worked on one or more games that won an AGS Award!
    •  
    • abstauber worked on one or more games that was nominated for an AGS Award!
Hi and thanks for the bugreport.

I think, that this is because I check the running in repexec and not repexec always. An easy thing to mitigate this for room changes would be to stop running, everytime you change a room. Also by using CTRL-X you're cheating a bit, as I'm checking for 'regular' room changes at line VerbGui.asc:2519 ;)

Running is also cancelled by every new mouseclick, so for this to happen you need to trigger a cutscene while the player is running without any other interaction or event. And the game designer would not stop the player from moving. The question is: how to detect such a cutscene.
I could use Game.InSkippableCutscene, but this would leave out unskipable cutscenes. Maybe a solution would be simply to add a StopRunning command which you would call in a cutscene

I'd love to get some more input on this.

Anyway to stop running also via CTRL-X room changes, this should do the trick
VerbGui.asc:2181
Code: [Select]
function on_event(EventType event, int data)
{
  if (event == eEventEnterRoomBeforeFadein) {
    Verbs.CheckDefaultAction();
    Verbs.UpdateActionBar();
   
    verbsData.player_is_running = false;
    player.StopMoving();
    player.SetWalkSpeed(verbsData.player_walk_x_speed,  verbsData.player_walk_y_speed);
    player.AnimationSpeed = verbsData.player_ani_speed;
  }
 
  else if (event==eEventRestoreGame) {
    //Verbs.AdjustLanguage();
    Verbs.InitGuiLanguage();
  }
}
« Last Edit: 30 Apr 2019, 11:03 by abstauber »

Hello abstauber.

After lurking here for some time now I discovered this new template and decided to register to the forum just to say THANK YOU!.
I was trying to deconstruct the included 9-Verb MI interface this afternoon, not realizing it was maintained out of AGS itself and here we are with this successor that at a first glance is a big leap forward.
Can't wait to deep dive into it tomorrow.

EDIT: I read through the documentation and tested the template and I have two questions:

1. Is there any documentation about the inner working of the translations (i.e. contributors guidelines or such) that explains how and why they are addressed in that way?

2. Given TWP and pretty all modern game are built for widescreens, isn't it better to provide a 356x200 resolution out of the box instead of sticking with good old 320x200?

Thanks for your effort (all the contributors) and I hope I'll have something to show based on your work soon!
Cheers
« Last Edit: 14 Aug 2019, 00:14 by StickGrinder »

abstauber

  • Cavefish
  • Mittens Knight
  • still mowing the lawn
    • abstauber worked on one or more games that won an AGS Award!
    •  
    • abstauber worked on one or more games that was nominated for an AGS Award!
Thanks a lot, I hope you'll have fun with AGS and the template.
I'm afraid I'm still a sucker for the old resolutions, besides there are a lot of devices out there with a non 16:9 aspect ratio out there (Macbooks, Surface devices, Phones etc). So I'd like to keep the retro standard for now :)

As for the translations:
(bottom of the page)
https://github.com/dkrey/ags_tumbleweed/blob/master/doc/9verb_intro.rst

https://github.com/dkrey/ags_tumbleweed/blob/master/doc/9verb_translation.rst

I see your point about resolution.

What's your position about derivative works? I mean, what if I commit to maintain a forked version of your Tumbleweed which defaults to widescreen devices?
Or possibly a sort of "add-on" package with pre-made WS assets?

I understand it's FOSS but I don't want to offend any unwritten rule of AGS community, nor you personally in any way.

abstauber

  • Cavefish
  • Mittens Knight
  • still mowing the lawn
    • abstauber worked on one or more games that won an AGS Award!
    •  
    • abstauber worked on one or more games that was nominated for an AGS Award!
I think nobody has a problem with keeping or maintaining forks of the template.
Yet I can't imagine that 320x200 puts anybody off because of it's aspect ratio. Changing the resolution of a gameproject should be matter of minutes and art assets have to be created anyway.

Do you intend to maintain templates for 200p, 720p and 1080p? I could image that all this work wouldn't be worth it..

First of all, my apologies for the confusion: I was actually thinking about aspect ratio, not resolution, as you correctly pointed out.

That said, my opinion is that starting widescreen right out should add to the perception of something that can fit a modern production, not just emulating the golden era. Going 16:9 was also a choice that Terrible Toybox did for the referenced game, so that it kinda feels like a game from the 90s but it leverages what devices can do now.

The very good example by Fluegeldufel some post above shows that there should be interest in widescreen games after all :)
But of course I don't think anybody will put off by this template to be 4:3! It was just to help newcomers like me hit the ground running.

But most of all: I'm totally aware that those are my speculations and perceptions, probably not even worth the proverbial 2 cents.
If you or someone else in the community see any value in contributing this, I'm happy to help. If not, I'm happy to help anyway (stopping bothering you with my blurb)!  :grin:

Thanks again for your work and kind help, this template is so much cleaner and easy to grasp than the former one to someone like me!
« Last Edit: 14 Aug 2019, 18:28 by StickGrinder »

But of course I don't think anybody will put off by this template to be 4:3! It was just to help newcomers like me hit the ground running.

To be fair, this template is not 4:3, 320x200 is actually 16:10.

Of course it may be worth to stress out (in the manual or template's documentation) that user does not have to stick to template's resolution or aspect ratio; a well made template is resolution independent (and I believe this one is).

PS. With the upcoming AGS 3.5.0 release it's even possible to change game resolution while keeping all original demo assets, because it now allows to have rooms smaller than game res and, for example, center them on wider game screen.
« Last Edit: 14 Aug 2019, 18:59 by Crimson Wizard »

To be fair, this template is not 4:3, 320x200 is actually 16:10.

One more reason to stop jabbering and leave things as they are :)
Thanks

abstauber

  • Cavefish
  • Mittens Knight
  • still mowing the lawn
    • abstauber worked on one or more games that won an AGS Award!
    •  
    • abstauber worked on one or more games that was nominated for an AGS Award!
*bump*
Just released a new version with added compatibility for AGS 3.5

Oh, and I just noticed that I am maintaining these templates for over 10 years  :shocked:

Monsieur OUXX

  • Mittens Vassal
  • Cavefish
  • Mittens Half Initiate
    • I can help with proof reading
    • I can help with translating
    • I can help with voice acting
    • Monsieur OUXX worked on one or more games that won an AGS Award!
    •  
    • Monsieur OUXX worked on one or more games that was nominated for an AGS Award!
I just noticed that I am maintaining these templates for over 10 years  :shocked:

And you're doing a great job. You've saved me tens of hours of coding, for a sexy result.

I want to report that in font "tumbletext" (and TumbleTextOutline I imagine), special character "ç" is misaligned vertically. The "c" should be aligned like a normal c, and the thingie should dangle underneath it, lower than the line. A bit like a "j".
 

Small bug report:

import InventoryItem*ItemGiven; in GlobalScript.asc should probably be removed, and the documentation PDF about using the Give verb should use  Verbs.GetItemGiven()  instead of  ItemGiven.

Details in this thread: https://www.adventuregamestudio.co.uk/forums/index.php?topic=57962.0
Fail at Floaty Rog' now!  still having to deal with what games are going through

Monsieur OUXX

  • Mittens Vassal
  • Cavefish
  • Mittens Half Initiate
    • I can help with proof reading
    • I can help with translating
    • I can help with voice acting
    • Monsieur OUXX worked on one or more games that won an AGS Award!
    •  
    • Monsieur OUXX worked on one or more games that was nominated for an AGS Award!
A minor bug in the custom dialogs : There's no "scroll to top" after selecting a dialog option. Which means that if you click on, let's say, option 5, then the next time some options are displayed they will still be scrolled down. It's a bit awkward.

I fixed it like this (by the way, somehow the RunActiveOption was filtered out for the mouse wheel scrolling but not the plain old mouse click scrolling. I changed that too)

Code: Adventure Game Studio
  1. function dialog_options_mouse_click(DialogOptionsRenderingInfo *info, MouseButton button)
  2. {
  3.  
  4.   CDG_Arrow uparrow;
  5.   CDG_Arrow downarrow;
  6.   int i;
  7.  
  8.   // Up-Arrow coordinates
  9.   uparrow.x1 = info.X + CDG_options.uparrow_xpos;
  10.   uparrow.y1 = info.Y + CDG_options.uparrow_ypos ;
  11.   uparrow.x2 = uparrow.x1 + Game.SpriteWidth[CDG_options.uparrow_img];
  12.   uparrow.y2 = uparrow.y1 + Game.SpriteHeight[CDG_options.uparrow_img];
  13.  
  14.   // Down-Arrow coordinates
  15.   downarrow.x1 = info.X + CDG_options.downarrow_xpos;
  16.   downarrow.y1 = info.Y + CDG_options.downarrow_ypos ;
  17.   downarrow.x2 = downarrow.x1 + Game.SpriteWidth[CDG_options.downarrow_img];
  18.   downarrow.y2 = downarrow.y1 + Game.SpriteHeight[CDG_options.downarrow_img];
  19.  
  20. //MODIFIED BY SEVEN CITIES - START
  21.   bool isClickScrollUp = ((mouse.x >= uparrow.x1 && mouse.y >= uparrow.y1) &&
  22.                          (mouse.x <= uparrow.x2 && mouse.y <= uparrow.y2))||
  23.                          (button == eMouseWheelNorth && CDG_options.mousewheel);
  24.        
  25.   bool isClickScrollDown = ((mouse.x >= downarrow.x1 && mouse.y >= downarrow.y1) &&
  26.                           (mouse.x <= downarrow.x2 && mouse.y <= downarrow.y2)) ||
  27.                           (button == eMouseWheelSouth && CDG_options.mousewheel);
  28. //MODIFIED BY SEVEN CITIES - END
  29.  
  30.   // scroll up
  31.   if (isClickScrollUp) {
  32.         i=0;
  33.        
  34.         while (i<CDG_options.scroll_rows)
  35.         {
  36.           if (CDG_options.scroll_from >1) CDG_options.scroll_from --;
  37.           dialog_options_render(info);          
  38.           i++;
  39.         }
  40.   }
  41.   // scroll down
  42.   else if (isClickScrollDown) {
  43.      
  44.       i=0;
  45.       while (i<CDG_options.scroll_rows)
  46.       {      
  47.         if (CDG_options.scroll_to != CDG_options.active_options_count-1) {
  48.           dialog_options_render(info);
  49.           CDG_options.scroll_from ++;
  50.         }
  51.         i++;
  52.       }
  53.   }
  54.  
  55.   info.Update();
  56.  
  57.  
  58. //MODIFIED BY SEVEN CITIES - START
  59.   //if (button != eMouseWheelSouth && button != eMouseWheelNorth) info.RunActiveOption();
  60.  
  61.   if (!isClickScrollDown && !isClickScrollUp){
  62.     CDG_options.scroll_from = 0; // Scroll to top
  63.     info.Update();
  64.     info.RunActiveOption();
  65.   }
  66.  
  67. //MODIFIED BY SEVEN CITIES - END
  68. }
  69.  
  70.  
 

Monsieur OUXX

  • Mittens Vassal
  • Cavefish
  • Mittens Half Initiate
    • I can help with proof reading
    • I can help with translating
    • I can help with voice acting
    • Monsieur OUXX worked on one or more games that won an AGS Award!
    •  
    • Monsieur OUXX worked on one or more games that was nominated for an AGS Award!
A small improvement but very convenient :

VerbsGui.ash

Code: Adventure Game Studio
  1. enum eObjectType {
  2.   eGizmo, //use this type for regular-sized objects. Usually, objects that the player could physically pick up but doesn't need.
  3.   eHeavy,  //use this type for objects that are too heavy to pickup/push/pull
  4.   eCharacter, //appropriate responses to silly attempts like "opening" a human being.
  5.   eDoor //similar to eHeavy but slightly more specific in regards to open/close/use
  6. };
  7.  
  8.   // START MODIFICATION
  9.   //import static void Unhandled(int door_script=0);
  10.   import static void Unhandled(eObjectType objType = eGizmo,  int door_script=0); //I've put the new parameter first because you use it much more often
  11.   // END
  12.  
  13.  

VerbsGui.asc
Code: Adventure Game Studio
  1. // START MODIFICATION
  2. //static void Verbs::Unhandled(int door_script)
  3. static void Verbs::Unhandled(eObjectType objType, int door_script)
  4. // END
  5. {
  6.  

Then of course don't forget to update any call to Verbs.Unhandled in the template. When in doubt use eGizmo.
And of course don't forget to add all the new strings to verbsData.unhandled_strings. To sort them easily, you may get inspiration from these values :

Your own module
Code: Adventure Game Studio
  1. bool moduleInitialized = false;
  2.  
  3.  
  4. String defaultSentence_Pull     ;
  5. String defaultSentence_Push     ;
  6. String defaultSentence_Give     ;
  7. String defaultSentence_Interact ;
  8. String defaultSentence_Look     ;
  9. String defaultSentence_PickUp   ;
  10. String defaultSentence_Talk     ;
  11. String defaultSentence_UseInv   ;
  12. String defaultSentence_Open     ;
  13. String defaultSentence_Close    ;
  14.  
  15.  
  16. function InitializeModule() {
  17.  
  18.   //unfortunately AGS script does not allow to initialize a default
  19.   //String's value at declaration. We are forced to do it here
  20.  
  21.   //universal sentences for any object in the entire game
  22.   defaultSentence_Pull     = "I can't pull that.";
  23.   defaultSentence_Push     = "I can't push that.";
  24.   defaultSentence_Give     = "That just won't work.";
  25.   defaultSentence_Interact = "I don't know what to do.";
  26.   defaultSentence_Look     = "I see nothing special about it.";
  27.   defaultSentence_PickUp   = "Why would I want to pick that up?";
  28.   defaultSentence_Talk     = "I shouldn't start talking to things.";
  29.   defaultSentence_UseInv   = "That won't work.";
  30.   defaultSentence_Open     = "I can't open that.";
  31.   defaultSentence_Close    = "I can't close that.";
  32.    
  33.   moduleInitialized = true; //make sure we don't call it again
  34. }
  35.  
  36.  
  37. //makes sure that all the relevant module stuff is initialized
  38. function checkInitialized() {
  39.    //at first call
  40.   if (!moduleInitialized)
  41.     InitializeModule();
  42.  
  43. }
  44.  
  45. String FindWontWorkSentence() {
  46.   String wontWork[10];
  47.   wontWork[0] = "That won't work.";
  48.   wontWork[1] = "I don't think that will work.";
  49.   wontWork[2] = "Nu-uh.";
  50.   wontWork[3] = "No.";
  51.   wontWork[4] = "Nope.";
  52.   wontWork[5] = "That's silly.";
  53.   wontWork[6] = "Why would I try that?";
  54.   wontWork[7] = "I'll have to think of something more useful.";
  55.   wontWork[8] = "No way.";
  56.   wontWork[9] = "I can't figure it out.";  
  57.  
  58.   return wontWork[Random(9)];
  59. }
  60.  
  61.  
  62. String FindWontGiveSentence() {
  63.   String wontGive[4];
  64.   wontGive[0] = "I'd rather keep that to myself.";
  65.   wontGive[1] = "I won't give that away.";
  66.   wontGive[2] = "Bad idea.";
  67.   wontGive[3] = "Let's keep that to myself.";
  68.  
  69.   return wontGive[Random(3)];
  70. }
  71.  
  72. String Sentence(Action_7CoG mode, eObjectType objectType) {
  73.   checkInitialized();
  74.  
  75.   String sentence = "ERROR : no sentence returned.";
  76.  
  77.   if (objectType == eGizmo) { //See the definition of "eGizmo" in the Enum declaration
  78.     if (mode == eGA_7CoG_Pull) sentence = defaultSentence_Pull;               //Pull
  79.     else if (mode == eGA_7CoG_Push) sentence = defaultSentence_Push;          //Push
  80.     else if (mode == eGA_7CoG_GiveTo) sentence = FindWontGiveSentence();          // Give
  81.     else if (mode == eGA_7CoG_Use) sentence = FindWontWorkSentence();  // Interact
  82.     else if (mode == eGA_7CoG_LookAt) sentence = defaultSentence_Look;        // Look
  83.     else if (mode == eGA_7CoG_PickUp) sentence = "I don't need that.";        // Pickup
  84.     else if (mode == eGA_7CoG_TalkTo) sentence = defaultSentence_Talk;        // Talk
  85.     else if (mode == eGA_7CoG_UseInv) sentence = FindWontWorkSentence();      // Useinv  
  86.     else if (mode == eGA_7CoG_Open) sentence = defaultSentence_Open;          // Useinv  
  87.     else if (mode == eGA_7CoG_Close) sentence = defaultSentence_Close;        // Useinv  
  88.     else sentence = String.Format("Unknown mode : %d",mode);
  89.   } else if   (objectType == eHeavy) { //See the definition of "eHeavy" in the Enum declaration
  90.     if (mode == eGA_7CoG_Pull) sentence = "It's too heavy to pull it";                  //Pull
  91.     else if (mode == eGA_7CoG_Push) sentence = "It's too heavy to push it";             //Push
  92.     else if (mode == eGA_7CoG_GiveTo) sentence = FindWontGiveSentence();                    // Give
  93.     else if (mode == eGA_7CoG_Use) sentence = "Let it be.";                        // Interact
  94.     else if (mode == eGA_7CoG_LookAt) sentence = defaultSentence_Look;                  // Look
  95.     else if (mode == eGA_7CoG_PickUp) sentence = "I can't pick up something that big!"; // Pickup
  96.     else if (mode == eGA_7CoG_TalkTo) sentence = defaultSentence_Talk;                  // Talk
  97.     else if (mode == eGA_7CoG_UseInv) sentence = defaultSentence_UseInv;                // Useinv  
  98.     else if (mode == eGA_7CoG_Open) sentence = defaultSentence_Open;                    // Useinv  
  99.     else if (mode == eGA_7CoG_Close) sentence = defaultSentence_Close;                  // Useinv  
  100.     else sentence = String.Format("Unknown mode : %d",mode);
  101.   } else if   (objectType == eCharacter) { //See the definition of "eHeavy" in the Enum declaration
  102.     if (mode == eGA_7CoG_Pull) sentence = "Violence is not a solution here.";               //Pull
  103.     else if (mode == eGA_7CoG_Push) sentence = "I don't just push people around.";          //Push
  104.     else if (mode == eGA_7CoG_GiveTo) sentence = FindWontGiveSentence();                      // Give
  105.     else if (mode == eGA_7CoG_Use) sentence = "I don't randomly touch people.";        // Interact
  106.     else if (mode == eGA_7CoG_LookAt) sentence = defaultSentence_Look;                      // Look
  107.     else if (mode == eGA_7CoG_PickUp) sentence = "Yes, why don't I just carry everybody around on my back?";      // Pickup
  108.     else if (mode == eGA_7CoG_TalkTo) sentence = defaultSentence_Talk;                      // Talk
  109.     else if (mode == eGA_7CoG_UseInv) sentence = defaultSentence_UseInv;                    // Useinv  
  110.     else if (mode == eGA_7CoG_Open) sentence = "You mean, open that person with a knife or something?";      // Useinv  
  111.     else if (mode == eGA_7CoG_Close) sentence = "That doesn't make sense.";                 // Useinv  
  112.     else sentence = String.Format("Unknown mode : %d",mode);
  113.   } else if   (objectType == eDoor) { //See the definition of "eDoor" in the Enum declaration
  114.     if (mode == eGA_7CoG_Pull) sentence = "It's too heavy to pull it";                  //Pull
  115.     else if (mode == eGA_7CoG_Push) sentence = "It's too heavy to push it";             //Push
  116.     else if (mode == eGA_7CoG_GiveTo) sentence = FindWontGiveSentence();                    // Give
  117.     else if (mode == eGA_7CoG_Use) sentence = "Let it be.";                        // Interact
  118.     else if (mode == eGA_7CoG_LookAt) sentence = defaultSentence_Look;                  // Look
  119.     else if (mode == eGA_7CoG_PickUp) sentence = "I can't pick up something that big!"; // Pickup
  120.     else if (mode == eGA_7CoG_TalkTo) sentence = defaultSentence_Talk;                  // Talk
  121.     else if (mode == eGA_7CoG_UseInv) sentence = defaultSentence_UseInv;                // Useinv  
  122.     else if (mode == eGA_7CoG_Open) sentence = defaultSentence_Open;                    // Useinv  
  123.     else if (mode == eGA_7CoG_Close) sentence = defaultSentence_Close;                  // Useinv  
  124.     else sentence = String.Format("Unknown mode : %d",mode);
  125.   } else { //the most possible generic sentences
  126.     if (mode == eGA_7CoG_Pull) sentence = defaultSentence_Pull;               //Pull
  127.     else if (mode == eGA_7CoG_Push) sentence = defaultSentence_Push;          //Push
  128.     else if (mode == eGA_7CoG_GiveTo) sentence = FindWontGiveSentence();          // Give
  129.     else if (mode == eGA_7CoG_Use) sentence = defaultSentence_Interact;  // Interact
  130.     else if (mode == eGA_7CoG_LookAt) sentence = defaultSentence_Look;        // Look
  131.     else if (mode == eGA_7CoG_PickUp) sentence = FindWontWorkSentence();      // Pickup
  132.     else if (mode == eGA_7CoG_TalkTo) sentence = defaultSentence_Talk;        // Talk
  133.     else if (mode == eGA_7CoG_UseInv) sentence = FindWontWorkSentence();      // Useinv  
  134.     else if (mode == eGA_7CoG_Open) sentence = defaultSentence_Open;          // Useinv  
  135.     else if (mode == eGA_7CoG_Close) sentence = defaultSentence_Close;        // Useinv  
  136.     else sentence = String.Format("Unknown mode : %d",mode);
  137.   }
  138.  
  139.   return sentence;
  140. }
  141.  
  142.  
  143.