Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - bx83

#121
What is easy to do eEventRestoreGame? 5 lines of code or a more prosaic thing with bits all over the project?
#122
eEventRestoreGame will trigger *after* the restore game function is finished - this is useful since normally you have to wait for the function containing the RestoreGameSlot() to finish, meaning you can't check the end result without a switch.
But why not eEventSavedGame? This would be perfect for a savegame rather than uses of switches and timers to generally guess when it's over.
#123
Here is a working, scrollable save-game system if anyone is interested. There are 25 save-slots prepared.



code:

GlobalScript.asc
Code: ags
/////////////////////////////////////////
// save/load game with screenshot code //
/////////////////////////////////////////

DynamicSprite *buttonSavePic1;
DynamicSprite *buttonSavePic2;
...
DynamicSprite *buttonSavePic24;
DynamicSprite *buttonSavePic25;

void SetSavePicToButton(Button *butSave, Button *butLoad, Label *label, DynamicSprite *pic, int save_id) {
  if (pic != null) {
    label.Text=Game.GetSaveSlotDescription(save_id);
    butSave.NormalGraphic = pic.Graphic;
    butSave.Visible=true;
    RefreshGameSlots=0;
  } else {
    String filename = String.Format("$SAVEGAMEDIR$/agssave.%03d.lociv", save_id);
    if (File.Exists(filename)) {
      RefreshGameSlots=save_id;
    }   
  }
}

function PrepareSaveGUI_Display(Button *saveSlotFrame, Button *butLoad, DynamicSprite *pic, int save_id)
{
  if (pic != null) {
    saveSlotFrame.NormalGraphic = pic.Graphic;
    saveSlotFrame.Visible=true;
  }  
  if (File.Exists(String.Format("$SAVEGAMEDIR$/agssave.%03d.lociv",save_id))) { 
    butLoad.Clickable=true;      //clickable
    butLoad.NormalGraphic=2644;  //bright blue
    butLoad.TextColor=51199;     //normal light
    RefreshGameSlots=0;
  } else { 
    butLoad.Clickable=false;     //not clickable
    butLoad.NormalGraphic=9780;  //greyed out
    butLoad.TextColor=33808;     //dark
  }
}

function PrepareSaveGUI(int slot)
{
  if (InStartupMenu) {    
    buttonSave1.Clickable=false;    //not clickable
    buttonSave2.Clickable=false;
    ...
    buttonSave24.Clickable=false;
    buttonSave25.Clickable=false;
	
    buttonSave1.NormalGraphic=9780; //greyed out
    buttonSave2.NormalGraphic=9780;
    ...
    buttonSave24.NormalGraphic=9780;
    buttonSave25.NormalGraphic=9780;
    
    buttonSave1.TextColor=33808;  //dark
    buttonSave2.TextColor=33808;
    ...
    buttonSave24.TextColor=33808;  
    buttonSave25.TextColor=33808; 
	
  } else {
    buttonSave1.Clickable=true;    //clickable
    buttonSave2.Clickable=true;
    ...
    buttonSave24.Clickable=true;
    buttonSave25.Clickable=true;
    
    buttonSave1.NormalGraphic=2644; //bright blue
    buttonSave2.NormalGraphic=2644;
    ...
    buttonSave24.TextColor=51199;
    buttonSave25.TextColor=51199;
  }  
  
  buttonSavePic1 = DynamicSprite.CreateFromSaveGame(1, 171, 96);
  buttonSavePic2 = DynamicSprite.CreateFromSaveGame(2, 171, 96);
  ...
  buttonSavePic24 = DynamicSprite.CreateFromSaveGame(24, 171, 96);
  buttonSavePic25 = DynamicSprite.CreateFromSaveGame(25, 171, 96);
  
  SetSavePicToButton(buttonSaveSlot1, buttonLoad1, LabelDescr1, buttonSavePic1, 1);
  SetSavePicToButton(buttonSaveSlot2, buttonLoad2, LabelDescr2, buttonSavePic2, 2);
  ...
  SetSavePicToButton(buttonSaveSlot24, buttonLoad24, LabelDescr24, buttonSavePic24, 24);
  SetSavePicToButton(buttonSaveSlot25, buttonLoad25, LabelDescr25, buttonSavePic25, 25);
  
  PrepareSaveGUI_Display(buttonSaveSlot1, buttonLoad1, buttonSavePic1, 1);
  PrepareSaveGUI_Display(buttonSaveSlot2, buttonLoad2, buttonSavePic2, 2);
  ...
  PrepareSaveGUI_Display(buttonSaveSlot24, buttonLoad24, buttonSavePic24, 24);
  PrepareSaveGUI_Display(buttonSaveSlot25, buttonLoad25, buttonSavePic25, 25);
}

function SaveTheGame(int slot, String desc)
{
  SaveGameSlot(slot, desc);
}

function LoadTheGame(int slot)
{
  RestoreCheck=true;
  RestoreSlotNm=slot;
}

void OnSaveButtonClick(Button *butSave, Button *butLoad, Label *label, DynamicSprite *pic, int save_id) {
  gSaveLoad.Visible=false;
  
  DateTime *dt = DateTime.Now;
  String month=String.Format("%02d",dt.Month);
  switch(month) {
    case "01": month="JAN"; break;
    case "02": month="FEB"; break;
    case "03": month="MAR"; break;
    case "04": month="APR"; break;
    case "05": month="MAY"; break;
    case "06": month="JUN"; break;
    case "07": month="JUL"; break;
    case "08": month="AUG"; break;
    case "09": month="SEP"; break;
    case "10": month="OCT"; break;
    case "11": month="NOV"; break;
    case "12": month="DEC"; break;
  }
  
  String SaveDesc=String.Format("#%d %02d:%02d %02d-%03s-%02d", save_id, dt.Hour, dt.Minute, dt.DayOfMonth, month, dt.Year);
  SaveGameSlot(save_id, SaveDesc);
  
  aCameraSnap.Play(eAudioPriorityNormal, eOnce);
  pic = DynamicSprite.CreateFromSaveGame(save_id, 171, 96);
  Wait(GetGameSpeed()*1);
  gSaveLoad.Visible=true;
  
  if (pic!= null) {
    butSave.NormalGraphic = pic.Graphic;
    butSave.Visible=true;
    butLoad.Visible=true;
    label.Text=Game.GetSaveSlotDescription(save_id);
  }
 
  RefreshGameSlots=save_id;
}

//all the different buttonSave_OnClicks:
function buttonSave1_OnClick(GUIControl *control, MouseButton button)
{
  if (buttonSavePic1!=null) buttonSavePic1.Delete(); 
  buttonSavePic1= DynamicSprite.CreateFromSaveGame(1, 171, 96);
  OnSaveButtonClick(buttonSaveSlot1, buttonLoad1, LabelDescr1, buttonSavePic1, 1);
}

function buttonSave2_OnClick(GUIControl *control, MouseButton button)
{
  if (buttonSavePic2!=null) buttonSavePic2.Delete(); 
  buttonSavePic2= DynamicSprite.CreateFromSaveGame(2, 171, 96);
  OnSaveButtonClick(buttonSaveSlot2, buttonLoad2, LabelDescr2, buttonSavePic2, 2);
}

...

function buttonSave24_OnClick(GUIControl *control, MouseButton button)
{
  if (buttonSavePic24!=null) buttonSavePic24.Delete(); 
  buttonSavePic24= DynamicSprite.CreateFromSaveGame(24, 171, 96);
  OnSaveButtonClick(buttonSaveSlot24, buttonLoad24, LabelDescr24, buttonSavePic24, 24);
}

function buttonSave25_OnClick(GUIControl *control, MouseButton button)
{
  if (buttonSavePic25!=null) buttonSavePic25.Delete(); 
  buttonSavePic25= DynamicSprite.CreateFromSaveGame(25, 171, 96);
  OnSaveButtonClick(buttonSaveSlot25, buttonLoad25, LabelDescr25, buttonSavePic25, 25);
}

// LOAD  gSaveLoaad load button functions
function buttonLoad1_OnClick(GUIControl *control, MouseButton button)
{
  LoadTheGame(1);
}
function buttonLoad2_OnClick(GUIControl *control, MouseButton button)
{
  LoadTheGame(2);
}
...
function buttonLoad24_OnClick(GUIControl *control, MouseButton button)
{
  LoadTheGame(24);
}
function buttonLoad25_OnClick(GUIControl *control, MouseButton button)
{
  LoadTheGame(25);
}

...

function repeatedly_execute()
{
...
  if (RefreshGameSlots!=0) {
    PrepareSaveGUI(RefreshGameSlots);
  }

  if (RestoreCheck) {
    if (gSaveLoad.Visible) {
      gSaveLoad.Visible=false;
    } else {
      RestoreGameSlot(RestoreSlotNm);
      RestoreSlotNm=0;
      RestoreCheck=false;
    }
  }
...
}


Anyone questons, code reducing or anything else welcome :)
#124
I have gSaveLoad, which contains my 'portraits' of nine savegames. My total game window is only 1366x768 so it's hard or impossible to fit more (not to mention I have to add all 9 game controls manually, but that's another story, I'll go through your suggested code once I have this down).

So I will have to, I imagine:
-change gSaveLoad to gSaveCanvas, make it's 840x2000, add the extra savegame 'portraits', and make it's ZOrder=10
-make a new GUI, and use it to replace the smaller window (previous gSaveLoad), make it's ZOrder=9
-somehow figure out how to place one GUI on to another (presumably make them both visible, and then use the gSaveCanvas.Y and a scroll thing on the left to 'scroll' it up and down with the mouse wheel)
-???
-done

Does this sound accurate? How will the smaller border of the (new) gSaveLoad 'cover' the larger borders of gSaveCanvas if they're just one on top of the other?

#125
So a separate gGUI-2 for the scrollable canvas with ZOffset=10, and a gGUI-1 with offset=9 to display the scrollable canvas on? Just wondering how to get a GUI the correct size.
#126
Meh, I'm of the Lucasarts school: single storyline, unfolding linearly. But indeed you're right, there's more than one way to skin a cat.
#127
There’s a text list box with limited functionality, but I was wondering if there’s a scrollable canvas that I can put button and graphics on? For my graphical save games list.
#128
I had a tester tell me that you can only save 50 games - is this true?
I don't know why anyone would need more than.... 1 save game (for an adventure game)... but each to his own.
#129
Solved!
I just had to change

if (gFloatingText.X+gFloatingText.Width)>SCREEN_WIDTH) {
to
if (mouse.x+gFloatingText.Width)>SCREEN_WIDTH) {

to make it dynamic. Thank you so much :D
#130
I've got the following code:

Code: ags

function repeatedly_execute_always()
{  

...

  int gFloatingText_X=0;
  int gFloatingText_Y=0;
  
  // Position the floating text
  if (ConversationIsOn) {
    gFloatingText.X = 0;
    gFloatingText.Y = 120;
  } else {
    if (mouse.Mode==eModeInteract) {
      if ((gFloatingText.X+gFloatingText.Width)>SCREEN_WIDTH) {
        Display("changing x for interact...");
        gFloatingText_X = mouse.x - 64 - 5 - gFloatingText.Width;   //past right-hand edge
        Display("changed x for interact, it is now %d",gFloatingText_X);
        gFloatingText_Y = mouse.y-30;      
      } else {
        gFloatingText_X = mouse.x+17;   
        gFloatingText_Y = mouse.y-30;      
      }
    } else {
      if ((gFloatingText.X+gFloatingText.Width)>SCREEN_WIDTH) {       //<--THIS CODE BLOCK RUNS.....
        Display("changing x for any mode but interact...");
        gFloatingText_X = mouse.x - 64 - gFloatingText.Width;  //past right-hand edge
        Display("TEMP VAR changed x for any mode but interact, it is now %d",gFloatingText_X);
        Display("1 gfloatingtext x is %d",gFloatingText_X);
        gFloatingText_Y = mouse.y-18;
      } else {
        gFloatingText_X = mouse.x;
        gFloatingText_Y = mouse.y-18;
      }
    }
  }
  if ((gFloatingText.X+gFloatingText.Width)>SCREEN_WIDTH) Display("BEFORE ASSIGNMENT TO .X gfloatingtext x is %d from %d",gFloatingText_X,  gFloatingText.X);
  
  gFloatingText.X=gFloatingText_X;
  gFloatingText.Y=gFloatingText_Y;
  
  if ((gFloatingText.X+gFloatingText.Width)>SCREEN_WIDTH) Display("MIDDLE gfloatingtext x is %d from %d",gFloatingText_X, gFloatingText.X);

...


It's godawful, and part of positioning the gFloatingText window on the right or left side of mouse curspr depending on if it's off the right-edge of the screen; this window acts as vessel for some text that displays the Name/'Description' of what's at mouse.x,mouse.y
go here for more context and pictures: https://www.adventuregamestudio.co.uk/forums/index.php?topic=59107.0

The important point about this code is: the gFloatingText window doesn't have it's .X/.Y pos controlled by anything else; yet it keeps resetting, and seemingly setting things on the other side of assignment.

So:
I've searched the code; none of it has 'gFloatingText.X=' in it, except code which isn't run.
I've checked if it's some sort of scoping thing (ie. it will remember the value in an IF statement, but will lose it and go back to before once this branch ends), but it doesn't seem to be.

The Variables are:
gFloatingText_X is a temp int var, declared outside the major block of code, so to hold the new value until it's assigned to gFloatingText.X
gFloatingText.X, which is the top-left-corner 'x' coordinate of a GUI
SCREEN_WIDTH is a #define for the number 1366
ConversationIsOn which is always 'false' for this example

The example OUTPUT is:
changing x for any mode but interact...
TEMP VAR changed x for any mode but interact, it is now 1064.  <--- not yet, this is only for temp variable gFloatingText_X
1 gfloatingtext x is 1064.    <-- text has now flipped to left side of mouse, as it should, because there's no room left on the right
BEFORE ASSIGNMENT TO .X gfloatingtext x is 1064 from 1255   <-- temp variable is new 1064, the .X GUI coordinate is 1255
MIDDLE gfloating text is 1255 from 1255. <-- both .X and _X are now what .X was 1 line ago, even though it was on the left side of assignment....wtf

How it should go:
gFloatingText.X=5;
---> it's now equal to 5, for now and forever until it's assigned a new value.
Why is this happening?

Please feel free to throw any help at this, or choose from the following:
a) 'bx83, you've missed out a semi-colon/mistaken X for Y/have this line assigning the var incorrectly like *right there* on the screen! *rolls eyes*'
b) 'I recognise this from the SetFloatingText function https://www.adventuregamestudio.co.uk/forums/index.php?topic=59107.0, and it's all to do with a component I set up deep in the system to always have gFloatingText.X=mouse.x, or some clever binding you've never heard of'
c) 'I am fascinated by this bug and will add it to the engine 3.5.0.31' (unlikely)

I'm stumped.
#131
Snarky, okay no worries. I'll keep in touch, atm just hacking-away all last known errors before release.
#132
I have a problem that when I set a bubble with SayAtBubble(), it's x/y coords are totally static. If the speech bubble is placed directly above the head of a character, and it turns out it's 5 lines long, it will continue to go down the screen and obscure the character's head.

How would I alter things? eg:

Code: ags
SayAtBubble(talk_x, talk_y-(bubbleSprite.GetNumberOfLines*8), "&777 line");   //will push the speech bubble up by number of lines used in speechbubble * 8 pixels for each


Basically, I am wondering how I would alter SayAtBubble so that the bubble's tail, *NOT* the upper-left corner, is used to position it; though obviously this is very difficult, I just want to know where I would get the variable controlling number of text lines so I can do it sort-of automatically.
#133
It's me again.
I'm using AGS 3.5.0.31 (p9)
Have Underwater working; Fakescreen not working.
I have an animated object which will not distort as the background is doing with Underwater.
No matter the combinations of src/dest backgrounds, or my baseline (=0 seems to work best), it will won't work - object remains undistorted.
I have background 0 (main), background 1 (copy of bg0, working space), and a spare bakcground 2 (used for something else, plain white image on it).
I also have a walkbehind on background 0, if this is significant.
Also: Underwater is above Fakscreen in the script list (though I doubt this matters).

Can anyone help? What am I doing wrong with Fakescreen that I'm not with Underwater?
#134
Thank you :)
#135
Does Remote or anyone know how to change the icons from standard AGS by doing something *other* than re-compiling the MacOS engine from scratch?
#136
I renamed it LoCI.app, works fine.
#137
TheVolumeRemote, could you produce a version of the wrapper for AGS 3.5.0.31 / 3.5.0-p9?

(my game is p9, currently seems to work with p7, but testing might produce a crash)
#138
Okay - do some of the requirements use GUIs and screen interactions? I was just trying to figure out how to do it manually.
Could you explain?
#139
There's really nobody who can shed some light on this?
#140
And cleaned up code:

Code: ags

  InventoryItem *a;
  InventoryItem *b;
  
  //use i on j
  for (int i=0;i<=Game.InventoryItemCount;i++) {
    a = invCustomInv.ItemAtIndex[i];
    
    for (int j=0;j<=Game.InventoryItemCount;j++) {
      b = invCustomInv.ItemAtIndex[j];

      player.ActiveInventory=a;
      Display("player.ActiveInventory.Name is %s while i is %d",player.ActiveInventory.Name, i);
      
      Display("combining object index %s (%d/%d) with %s (%d/%d)",a.Name, i, Game.InventoryItemCount, b.Name, j, Game.InventoryItemCount);
      
      Display("modeusinv interaction with %s is %d",b.Name, b.IsInteractionAvailable(eModeUseinv));
      b.RunInteraction(eModeUseinv);
    }
  }


...and nothing happens at b.RunInteraction (though interaction is available).
SMF spam blocked by CleanTalk