Please login or register.

Login with username, password and session length
Advanced search  

News:

This forum provides RSS feed. To query recent posts use this url. More...


Pages: [1] 2  All

Author Topic: Inventory and response area always on top  (Read 14389 times)

0 Members and 1 Guest are viewing this topic.

Indra Anagram

  • Occasional poster
  • **
  • Karma: 0
  • Offline Offline
  • Gender: Male
  • Posts: 74
  • Periodical returnee
    • View Profile
Inventory and response area always on top
« on: November 13, 2017, 03:31:09 PM »

Hello, WME forum community!

I am trying to make a 2D game and my inspiration is The Cat Lady. In The Cat Lady in most scenes there is constantly inventory box on top, which changes to black rectangle for response options. I'd like to achieve following features for the inventory and response areas in my game:
1. At the bottom of screen
2. Constantly on top of the scene (see screen)



3. Become darkened and inactive during scripted behavior, some dialogues and cut-scenes (smth. like in the screen below)



4. Black rectangle background for response options - like this:



I know such things ARE possible with WME, and there is a chapter dedicated to dealing with inventory in WME documentation and Book online. However, I can't figure out how to send inventory window to the bottom of screen and keep it functional and always on top. See, like it was said in documentation, I changed Y value of WINDOW from 0 to 510 in inventory.def, but it keeps being dependable on cursor at the top of screen. If cursor moves to the bottom of screen, inventory just disappears. Changing AREA values made no good. I guess something must be altered in game_loop.script... If so, what exactly? After spending a considerable time with those scripts open in Notepad, I opened inventory.def in WindowEdit tool and tried changing several things (like setting InGame control to "True") and... nothing changed. Except inventory.def changed its structure when I reopened it in Notepad and it became very hard to read, because all lines got aligned horizontally.  ???

I am sure someone might have dealt with inventory objectives similar or close to mine, because it is typical for many adventures to have inventory and response areas at the bottom of screen and visible constantly. Could you please share your experience in that matter? Any ideas?

Big Thanks!!!
Logged
Owls are not what they seem...

Indra Anagram

  • Occasional poster
  • **
  • Karma: 0
  • Offline Offline
  • Gender: Male
  • Posts: 74
  • Periodical returnee
    • View Profile
Re: Inventory and response area always on top
« Reply #1 on: November 13, 2017, 08:46:25 PM »

Hey Muties!

It seems I've managed to solve points 1 and 2 of the "wishlist" for inventory area. Maybe... Would be great if someone more experienced confirms if this was done correctly.

First, I opened game_loop.script and set Game.InventoryVisible after "else if" to "true" (it was "false" by default):

Code: WME Script
  1.   // display the inventory window
  2.  

Second, I opened inventory.def and changed Y value from 0 to 510:

Code: WME Script
  1.   WINDOW
  2.   {
  3.     X = 0
  4.     Y = 510
  5.     WIDTH = 800
  6.     HEIGHT = 90
  7.     IMAGE = "interface\inventory.bmp"

Now the scene looks this way, with inventory always being on top (even during scripted events with no interactivity for player):



And here I'm seriously stuck... During scripted events the window stays white and I need it to:

Quote
3. Become darkened and inactive during scripted behavior, some dialogues and cut-scenes (smth. like in the screen below)

Also currently during the dialogue response options appear on top of inventory window. However, I wish there was

Quote
4. Black rectangle background for response options


Any ideas on how 3 and 4 could be achieved?

Thanks for your attention and any kind of advice!

 



Logged
Owls are not what they seem...

anarchist

  • Regular poster
  • ***
  • Karma: 5
  • Offline Offline
  • Gender: Male
  • Posts: 212
    • View Profile
Re: Inventory and response area always on top
« Reply #2 on: November 15, 2017, 04:52:01 PM »

First, since you want the inventory window to always be visible, you can completely remove the below code:

Code: WME Script
  1. // display the inventory window
  2.  

The above code is useful when you only want to display the window when the cursor moves to a particular area of the screen. But, you want it to always be visible, therefore remove the code. A programming hint: when you have if/else and they both do the same thing, you probably don't need the if/else. In your case you have an if/else if, but judging by what you want, you don't need it.

As for modifying the inventory window on the fly, take a look at the command GetInventoryWindow() to "get" the window. After you have the window in a variable, you can handle it like any other window (I have never done this so please test). I guess you can use inventoryWindow.SetImage() to change the background. I guess the same applies for responses window, where you can use Game.GetResponsesWindow().
Logged

Indra Anagram

  • Occasional poster
  • **
  • Karma: 0
  • Offline Offline
  • Gender: Male
  • Posts: 74
  • Periodical returnee
    • View Profile
Re: Inventory and response area always on top
« Reply #3 on: November 15, 2017, 07:03:01 PM »

As for modifying the inventory window on the fly, take a look at the command GetInventoryWindow() to "get" the window. After you have the window in a variable, you can handle it like any other window (I have never done this so please test). I guess you can use inventoryWindow.SetImage() to change the background. I guess the same applies for responses window, where you can use Game.GetResponsesWindow().

anarchist, great!  ::thumbup Hopefully I'll be able to figure out how to use those commands through testing)))

First, since you want the inventory window to always be visible, you can completely remove the below code

anarchist, THANK YOU for this advice! What if I place some video files between scenes? Will the inventory window still be visible then?

P.S. Please kindly view my last reply in the previous post (about scripted *cutscene*).
Logged
Owls are not what they seem...

Indra Anagram

  • Occasional poster
  • **
  • Karma: 0
  • Offline Offline
  • Gender: Male
  • Posts: 74
  • Periodical returnee
    • View Profile
Re: Inventory and response area always on top
« Reply #4 on: November 16, 2017, 08:20:31 PM »

As for modifying the inventory window on the fly, take a look at the command GetInventoryWindow() to "get" the window. After you have the window in a variable, you can handle it like any other window (I have never done this so please test). I guess you can use inventoryWindow.SetImage() to change the background. I guess the same applies for responses window, where you can use Game.GetResponsesWindow().

anarchist, I tried the commands, but since there is no information in tutorials about what exactly should be inside brackets, I inserted path to the definition file ("interface\inventory.def"), but it didn't work. What exactly should be inside? What value? And what would the code be like, if I want the inventory window dynamically change during scripted things and be replaced with response window?

About responses window...

Code: WME Script
  1.   WINDOW
  2.   {   
  3.     X = 0
  4.     Y = 510
  5.     WIDTH = 800
  6.     HEIGHT = 180
  7.     IMAGE = "interface\dialog.png"

I opened responses.def and changed Y value from 0 to 510 just like with the inventory window, however when I run the game, the background image seems to cover response options, so it is impossible to click on them.

Can't figure out what to do with this either  :P

Please help me, if you've got any idea about the values and use of GetInventoryWindow(), inventoryWindow.SetImage() and Game.GetResponsesWindow() commands.

HUGE THANKS!
Logged
Owls are not what they seem...

NAItReIN

  • Occasional poster
  • **
  • Karma: 1
  • Offline Offline
  • Posts: 69
    • View Profile
Re: Inventory and response area always on top
« Reply #5 on: November 17, 2017, 01:04:47 AM »

Hi muties,
please, download this file: https://www.dropbox.com/s/6mz8frfvo1bzs6t/IndraAnagram.rar?dl=0

I hope it will help  :)
Logged

Indra Anagram

  • Occasional poster
  • **
  • Karma: 0
  • Offline Offline
  • Gender: Male
  • Posts: 74
  • Periodical returnee
    • View Profile
Re: Inventory and response area always on top
« Reply #6 on: November 17, 2017, 09:06:35 AM »

Hi muties,
please, download this file: https://www.dropbox.com/s/6mz8frfvo1bzs6t/IndraAnagram.rar?dl=0

I hope it will help  :)

Hey NAItReIN! I am deeply sorry, but the .rar archieve cannot be opened (at least I can't do that) - "File is damaged" and "Unsupported format" messages show. Could you please re-upload it to Dropbox or make it .zip instead? THANK YOU for your reply and desire to help!
Logged
Owls are not what they seem...

NAItReIN

  • Occasional poster
  • **
  • Karma: 1
  • Offline Offline
  • Posts: 69
    • View Profile
Re: Inventory and response area always on top
« Reply #7 on: November 17, 2017, 10:00:37 AM »

Hi Indra Anagram,
here you are: https://www.dropbox.com/s/636g98o4ktdal48/IndraAnagram.zip?dl=0

I hope it will help to solve your problems.
Logged

Indra Anagram

  • Occasional poster
  • **
  • Karma: 0
  • Offline Offline
  • Gender: Male
  • Posts: 74
  • Periodical returnee
    • View Profile
Re: Inventory and response area always on top
« Reply #8 on: November 17, 2017, 04:38:53 PM »

I hope it will help to solve your problems.

It HAS solved my problems, NAItReIN! Worked like a charm. 

Now the inventory is always at the bottom of screen and whenever responses show up, the background changes!

Just like in the game that is my inspiration, yay! :)

I was thinking about anarchist's advice:

Quote
I guess you can use inventoryWindow.SetImage() to change the background.

Because I want the inventory become darkened (change background) during scripted things, I guess InventoryWindow.SetImage should be used with

Code: WME Script
  1. if (Game.Interactive = false)
  2. {
  3.  
  4. }

How do I deal with the command? Should I make it a variable? Have tried this and got nothing.

BIG THANKS to you for your kind attention and the archive!
Logged
Owls are not what they seem...

NAItReIN

  • Occasional poster
  • **
  • Karma: 1
  • Offline Offline
  • Posts: 69
    • View Profile
Re: Inventory and response area always on top
« Reply #9 on: November 17, 2017, 05:45:28 PM »

Quote
Because I want the inventory become darkened (change background) during scripted things, I guess InventoryWindow.SetImage should be used with

You can get the reference to inventory window by this way:
Code: [Select]
global WinInventoryWindow = Game.GetInventoryWindow();
But how to solve your problem? See my solution:

game.script
Code: WME Script
  1. // we need to store reference to window in global variable because we will use it in other script
  2. // inventory dark window does exist, but it is not visible
  3. global InventoryWinDark = Game.CreateWindow();
  4. InventoryWinDark.SetImage("interface\inventory_dark.sprite");
  5. InventoryWinDark.X = 0;
  6. InventoryWinDark.Y = 510;

game_loop.script
Code: WME Script
  1. #include "scripts\base.inc"
  2.  
  3. global InventoryWinDark;
  4. global WinCaption;
  5. global WinMenu;
  6.  
  7. // infinite loop
  8. while(true){
  9.  
  10.   // save the active object for later
  11.   var ActObj = Game.ActiveObject;
  12.  
  13.   // handle the standard foating caption
  14.   if(Game.Interactive && ActObj!=null)
  15.   {
  16.     if (Game.SelectedItem==null)
  17.     {
  18.       WinCaption.X = Game.MouseX;
  19.       WinCaption.Y = Game.MouseY + 20;
  20.       WinCaption.TextAlign = TAL_LEFT;
  21.       WinCaption.Text = ActObj.Caption;
  22.  
  23.       // keep the caption on screen
  24.       WinCaption.SizeToFit();
  25.       if(WinCaption.X + WinCaption.Width > Game.ScreenWidth) WinCaption.X = Game.ScreenWidth - WinCaption.Width;
  26.       if(WinCaption.Y + WinCaption.Height > Game.ScreenHeight) WinCaption.Y = Game.ScreenHeight - WinCaption.Height;
  27.       }
  28.     // handle the caption when you want to use an object with another
  29.     else {
  30.       var Item = Game.SelectedItem;
  31.  
  32.       WinCaption.X = 0;
  33.       WinCaption.Y = 580;
  34.       WinCaption.Width = Game.ScreenWidth;
  35.       WinCaption.TextAlign = TAL_CENTER;
  36.       WinCaption.Text = "Use " + Item.Caption + " with " + ActObj.Caption;
  37.     }
  38.     WinCaption.Visible = true;
  39.     WinCaption.Focus();
  40.   }
  41.   else WinCaption.Visible = false;
  42.  
  43.   // this is what we need
  44.   if(Game.Interactive==false && Game.ResponsesVisible == false)
  45.   {
  46.     WinInventoryWinDark.Visible = true;
  47.   }
  48.   else
  49.     WinInventoryWinDark.Visible = false;
  50.  
  51.   // go to sleep for 20 miliseconds to allow the engine to perform other tasks
  52.   // it is important for the "endless" scripts to call the Sleep command, otherwise the game will get stuck
  53.   Sleep(20);
  54. }

 :)
« Last Edit: November 17, 2017, 05:50:42 PM by NAItReIN »
Logged

Indra Anagram

  • Occasional poster
  • **
  • Karma: 0
  • Offline Offline
  • Gender: Male
  • Posts: 74
  • Periodical returnee
    • View Profile
Re: Inventory and response area always on top
« Reply #10 on: November 17, 2017, 07:04:06 PM »

But how to solve your problem? See my solution:

Hey NAItReIN!

Gosh, I didn't see your last reply till I refreshed the page. Have just tested your codes. Replaced "interface\inventory_dark.sprite" with the path to my own image for darkened inventory in game.script.

Code: WME Script
  1. #include "scripts\base.inc"
  2. #include "scripts\keys.inc"
  3.  
  4. // store some of the game's attributes in global variables for convenience
  5.  
  6.  
  7. // load the right-click menu
  8. global WinMenu = Game.LoadWindow("interface\menu\menu.window");
  9. WinMenu.Visible = false;
  10.  
  11. // load the "caption" window
  12. var win = Game.LoadWindow("interface\system\caption.window");
  13. global WinCaption = win.GetControl("caption");
  14.  
  15.  
  16.     // we need to store reference to window in global variable because we will use it in other script
  17.     // inventory dark window does exist, but it is not visible
  18.     global InventoryWinDark = Game.CreateWindow();
  19.     InventoryWinDark.SetImage("interface\inventory.png");
  20.     InventoryWinDark.X = 0;
  21.     InventoryWinDark.Y = 510;
  22.  
  23. global MenuObject = null;
  24.  
  25.  
  26. // load our main actor
  27. molly = Game.LoadActor("actors\molly\molly.actor");
  28. sally = Game.LoadActor("actors\sally\sally.actor");
  29. actor = molly;
  30. Game.MainObject = actor;
  31.  
  32. // run the "game loop" script
  33. Game.AttachScript("scripts\game_loop.script");
  34.  
  35.  
  36. // which scene to load?
  37.  
  38.  
  39.  
  40. ////////////////////////////////////////////////////////////////////////////////
  41. on "LeftClick"
  42. {
  43.   // what did we click?
  44.   var ActObj = Game.ActiveObject;
  45.   if(ActObj!=null)
  46.   {
  47.     // clicking an inventory item
  48.     if(ActObj.Type=="item" && Game.SelectedItem==null)
  49.     {
  50.       Game.SelectedItem = ActObj;
  51.     }
  52.     // using an inventory item on another object
  53.     else if(Game.SelectedItem != null && Game.SelectedItem!=ActObj)
  54.     {
  55.       var Item = Game.SelectedItem;
  56.       if(ActObj.CanHandleEvent(Item.Name)) ActObj.ApplyEvent(Item.Name);
  57.       else if(Item.CanHandleEvent("default-use")) Item.ApplyEvent("default-use");
  58.       else if(ActObj.CanHandleEvent("default-use")) ActObj.ApplyEvent("default-use");
  59.       else actor.Talk("I can't use these things together.");
  60.     }
  61.     // just a simple click
  62.     else ActObj.ApplyEvent("LeftClick");
  63.   }
  64.   // else propagate the LeftClick event to a scene
  65.   else
  66.   {
  67.     Scene.ApplyEvent("LeftClick");
  68.   }
  69. }
  70.  
  71.  
  72.  
  73. ////////////////////////////////////////////////////////////////////////////////
  74. on "RightClick"
  75. {
  76.   // if inventory item selected? deselect it
  77.   if (Game.SelectedItem != null){
  78.     Game.SelectedItem = null;
  79.     return;
  80.   }
  81.  
  82.   var ActObj = Game.ActiveObject;
  83.  
  84.   // is the righ-click menu visible? hide it
  85.   if(WinMenu.Visible == true) WinMenu.Visible = false;
  86.   else if(ActObj!=null)
  87.   {
  88.     // if the clicked object can handle any of the "verbs", display the right-click menu
  89.     if(ActObj.CanHandleEvent("Take") || ActObj.CanHandleEvent("Talk") || ActObj.CanHandleEvent("LookAt"))
  90.     {
  91.       // store the clicked object in a global variable MenuObject
  92.       MenuObject = Game.ActiveObject;
  93.       var Caption = WinMenu.GetControl("caption");
  94.       Caption.Text = MenuObject.Caption;
  95.  
  96.       // adjust menu's position
  97.       WinMenu.X = Game.MouseX - WinMenu.Width / 2;
  98.       if(WinMenu.X < 0) WinMenu.X = 0;
  99.       if(WinMenu.X+WinMenu.Width>Game.ScreenWidth) WinMenu.X = Game.ScreenWidth-WinMenu.Width;
  100.  
  101.       WinMenu.Y = Game.MouseY - WinMenu.Height / 2;
  102.       if(WinMenu.Y<0) WinMenu.Y = 0;
  103.       if(WinMenu.Y+WinMenu.Height>Game.ScreenHeight) WinMenu.Y = Game.ScreenHeight-WinMenu.Height;
  104.  
  105.       // and show the right-click menu
  106.       WinMenu.Visible = true;
  107.  
  108.       // stop the actor from whatever he was going to do
  109.       actor.Reset();
  110.     }
  111.     // no verbs supported, no menu is needed; just send the RightClick event to the object
  112.     else ActObj.ApplyEvent("RightClick");
  113.   }
  114. }
  115.  
  116.  
  117. ////////////////////////////////////////////////////////////////////////////////
  118. on "Keypress"
  119. {
  120.   // on Esc or F1 key
  121.   if(Keyboard.KeyCode==VK_ESCAPE || Keyboard.KeyCode==VK_F1)
  122.   {
  123.     // load and display the main menu window
  124.     WinCaption.Visible = false;
  125.     var WinMainMenu = Game.LoadWindow("interface\system\mainmenu.window");
  126.     WinMainMenu.Center();
  127.     WinMainMenu.GoSystemExclusive();
  128.     Game.UnloadObject(WinMainMenu);
  129.   }
  130. }
  131.  
  132.  
  133. ////////////////////////////////////////////////////////////////////////////////
  134. on "QuitGame"
  135. {
  136.   // on Alt+F4 (window close)
  137.   // load and display the quit confirmation window
  138.   WinCaption.Visible = false;
  139.   var WinQuit = Game.LoadWindow("interface\system\quit.window");
  140.   WinQuit.Center();
  141.   WinQuit.GoSystemExclusive();
  142.  
  143.   // and if the user selected Yes
  144.   if(WinQuit.xResult)
  145.   {
  146.     // quit the game
  147.     Game.QuitGame();
  148.   }
  149.   // otherwise just unload the quit window from memory
  150.   else Game.UnloadObject(WinQuit);
  151. }
  152.  

When I run the game the darkened background shows, alright, but it covers responses window, it seems, so no responses are visible and the game is stuck. In your demo from the today archive everything was fine. Here is what Debugging console says:

Quote
23:50:33:  Compiling script 'scripts\game_loop.script'...
23:50:33:    Error@line 46: Variable 'WinInventoryWinDark' is referenced but not defined
23:50:33:  Compiling script 'scripts\game_loop.script'...
23:50:33:    Error@line 49: Variable 'WinInventoryWinDark' is referenced but not defined

And here is how game_loop.script looks:

Code: WME Script
  1.     #include "scripts\base.inc"
  2.      
  3.     global InventoryWinDark;
  4.     global WinCaption;
  5.     global WinMenu;
  6.      
  7.     // infinite loop
  8.     while(true){
  9.      
  10.       // save the active object for later
  11.       var ActObj = Game.ActiveObject;
  12.      
  13.       // handle the standard foating caption
  14.       if(Game.Interactive && ActObj!=null)
  15.       {
  16.         if (Game.SelectedItem==null)
  17.         {
  18.           WinCaption.X = Game.MouseX;
  19.           WinCaption.Y = Game.MouseY + 20;
  20.           WinCaption.TextAlign = TAL_LEFT;
  21.           WinCaption.Text = ActObj.Caption;
  22.      
  23.           // keep the caption on screen
  24.           WinCaption.SizeToFit();
  25.           if(WinCaption.X + WinCaption.Width > Game.ScreenWidth) WinCaption.X = Game.ScreenWidth - WinCaption.Width;
  26.           if(WinCaption.Y + WinCaption.Height > Game.ScreenHeight) WinCaption.Y = Game.ScreenHeight - WinCaption.Height;
  27.           }
  28.         // handle the caption when you want to use an object with another
  29.         else {
  30.           var Item = Game.SelectedItem;
  31.      
  32.           WinCaption.X = 0;
  33.           WinCaption.Y = 580;
  34.           WinCaption.Width = Game.ScreenWidth;
  35.           WinCaption.TextAlign = TAL_CENTER;
  36.           WinCaption.Text = "Use " + Item.Caption + " with " + ActObj.Caption;
  37.         }
  38.         WinCaption.Visible = true;
  39.         WinCaption.Focus();
  40.       }
  41.       else WinCaption.Visible = false;
  42.      
  43.       // this is what we need
  44.       if(Game.Interactive==false && Game.ResponsesVisible == false)
  45.       {
  46.         WinInventoryWinDark.Visible = true;
  47.       }
  48.       else
  49.         WinInventoryWinDark.Visible = false;
  50.      
  51.       // go to sleep for 20 miliseconds to allow the engine to perform other tasks
  52.       // it is important for the "endless" scripts to call the Sleep command, otherwise the game will get stuck
  53.       Sleep(20);
  54.     }

Maybe I did something wrong with your code  :o Could you please look through the script?

Anyway, THANK YOU for your active and friendly help!
Logged
Owls are not what they seem...

Indra Anagram

  • Occasional poster
  • **
  • Karma: 0
  • Offline Offline
  • Gender: Male
  • Posts: 74
  • Periodical returnee
    • View Profile
Re: Inventory and response area always on top
« Reply #11 on: November 17, 2017, 07:27:19 PM »

Quote
23:50:33:  Compiling script 'scripts\game_loop.script'...
23:50:33:    Error@line 46: Variable 'WinInventoryWinDark' is referenced but not defined
23:50:33:  Compiling script 'scripts\game_loop.script'...
23:50:33:    Error@line 49: Variable 'WinInventoryWinDark' is referenced but not defined

NAItReIN!

I found out what was wrong in lines 46 and 49!))) Actually, the problem was in line 3.

Instead of

Code: WME Script
  1. global InventoryWinDark;

there should have been

Code: WME Script
  1. global WinInventoryWinDark;

So, now Debugging console doesn't show any error.

However, the background for the darkened inventory does cover responses window all the same. Maybe something should be corrected in responses.def?

THANKS for your attention and advice!
Logged
Owls are not what they seem...

NAItReIN

  • Occasional poster
  • **
  • Karma: 1
  • Offline Offline
  • Posts: 69
    • View Profile
Re: Inventory and response area always on top
« Reply #12 on: November 17, 2017, 08:32:38 PM »

Hello,
I am sorry I made a mistake. I tested my game and it worked well. Inventory window is always visible but when game is set to Game.Interactive = false; inventory window is covered with inventory dark. When I try to talk with oldguy in WME demo inventory window is invisible and I can see only responses window. When responses window is no visible I see inventory dark window. When dialog is gone inventory normal window is visible.
I am so sorry for my bed English  ::)
Logged

Indra Anagram

  • Occasional poster
  • **
  • Karma: 0
  • Offline Offline
  • Gender: Male
  • Posts: 74
  • Periodical returnee
    • View Profile
Re: Inventory and response area always on top
« Reply #13 on: November 17, 2017, 08:57:41 PM »

Hello,
I am sorry I made a mistake. I tested my game and it worked well. Inventory window is always visible but when game is set to Game.Interactive = false; inventory window is covered with inventory dark. When I try to talk with oldguy in WME demo inventory window is invisible and I can see only responses window. When responses window is no visible I see inventory dark window. When dialog is gone inventory normal window is visible.
I am so sorry for my bed English  ::)

Hey NAItReIN!

It's me who should apologize for being so importunate. You've showed great support to me and anyone who might encounter similar problems with the inventory and responses window customization. THANK YOU for your patience!

Can you paste the contents of inventory_dark.sprite?

This would help to identify why responses are covered with the inventory background in my game.
Logged
Owls are not what they seem...

NAItReIN

  • Occasional poster
  • **
  • Karma: 1
  • Offline Offline
  • Posts: 69
    • View Profile
Re: Inventory and response area always on top
« Reply #14 on: November 17, 2017, 09:03:52 PM »

Hello,
I am away by my notebook where I have demo prepared for you. I am going to upload it on Dropbox tomorrow and share it with you  :)
Logged
Pages: [1] 2  All
 

Page created in 0.088 seconds with 26 queries.