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 - monkey0506

#281
I will also point out that in your scripts you need to make sure you are using the player keyword to refer to the player, not cEgo. I have seen many people use cEgo and player interchangeably. cEgo is just the default name of the first character, and can be renamed to whatever you want. player only refers to the current player character, whichever character that might be.

Code: ags
// on_mouse_click
  // ...
  else cEgo.Walk(mouse.x, mouse.y); // move the player (WRONG, this ONLY moves cEgo!)


Code: ags
// on_mouse_click
  // ...
  else player.Walk(mouse.x, mouse.y); // move the player (RIGHT, this moves the player no matter which character is being controlled)
#282
Now that I have access to it, just wanted to confirm that in the manual the page is right in the root entry, so it should be easy to find. Let us know if you have issues with updating your scripts!

#283
I sometimes forget that people have some innate fear of using pre-release versions. Unless you're very, very far along into your project, I would suggest upgrading to AGS 3.4. Make a back-up copy of your project folder first, then just open your game with 3.4. It's pretty reasonably stable lately, and we're starting to hone in on the final feature fixes for a full release.

That said, the links for the QueuedSpeech v3.5 module in the module's thread should still be valid, but you can snag it here. Note that v4 has a totally different way of doing things from v3.5, so the above code snippet won't work with older versions of the module.
#284
I believe the manual should still have the page on upgrading to AGS 3.2, which details the new audio system. PlayMusic and PlaySound have been replaced by the AudioClip.Play function. In the editor you can import your audio files and give them script names, like "aExplosion". Then you can use "aExplosion.Play();" in your script the same way you would have used PlaySound, for example.
#285
Yeah, the link in the first post was out-of-date, but I uploaded a new version a few days ago and updated the first post link as well.

Have you had a chance to test this, or were you only saying that the link was working?
#286
The key to running a queue for background speech with animations is that you don't want it to interfere with other code, and that can be a fine line to balance. For example, I recently discovered that the 8-Direction module (which is rather dated anyway) is calling UnlockView on the player character every loop that the player isn't moving. This would totally prevent you from having the player speak in the background if you were using this other module.

Inversely, if the player is talking in the background but wants to start walking around, I don't think that should be blocked (hence talking in the background and not with a normal Say command).

Not to self-promote, but I'd really recommend that you check out the QueuedSpeech module. I think you'll find it much easier than recoding all of this by yourself.

Example of my module:

Code: ags
function room_Load()
{
  QueuedSpeech.ClearQueue(); // make sure we don't have any lingering items from other rooms
  QueuedSpeech.Paused = true; // don't start talking yet!
  // fill in the background dialogue only when the room is being loaded
  cbibl.SayQueued("asdas");
  cbibl.SayQueued("asdaf");
  // ...
  cbibl.SayQueued("asdaz");
}
 
function room_RepExec()
{
  QueuedSpeech.Paused = !BISTICCIO; // if BISTICCIO is TRUE, then the background dialogue will run, if BISTICCIO is FALSE then the background dialogue will pause
}


And that's all that you have to do to set it up. Animations will play and stop automatically, the player can talk in the background without blocking, etc.
#287
You can also make use of the hidden autoptr and attribute keywords, because they're awesome:

Code: ags
// Script.ash
autoptr managed struct Point
{
    protected int x;
    protected int y;
    import attribute int X;
    import attribute int Y;
    import Point Copy();
    import void SetLocation(int x, int y);
    import void SetLocationFromPoint(Point);
    import static Point Create(int x, int y);
    import static Point CreateFromPoint(Point);
};

// Script.asc
int get_X(this Point*)
{
    return this.x;
}

void set_X(this Point*, int value)
{
    if (value < 0) AbortGame("X value cannot be negative!");
    this.x = value;
}

int get_Y(this Point*)
{
    return this.y;
}

void set_Y(this Point*, int value)
{
    if (this.y < 0) AbortGame("Y value cannot be negative!");
    this.y = value;
}

void Point::SetLocation(int x, int y)
{
    this.set_X(x); // can't call attributes directly from same script where accessors are defined
    this.set_Y(y);
}

void Point::SetLocationFromPoint(Point p)
{
    this.SetLocation(p.get_X(), p.get_Y()); // can't call attributes directly from same script where accessors are defined
}

static Point Point::Create(int x, int y)
{
    Point p = new Point;
    p.SetLocation(x, y);
    return p;
}

static Point Point::CreateFromPoint(Point p)
{
    return Point.Create(p.get_X(), p.get_Y()); // can't call attributes directly from same script where accessors are defined
}

Point Point::Copy()
{
    return Point.Create(this.x, this.y);
}

// SomeScript.asc
Point p = Point.Create(30, 40);
Point p2 = p.Copy();
p2.X += 2;
p2.Y -= 2; // and so-forth
#288
Does the ZIP format allow encryption? I know most game devs wouldn't want their resource files readily readable and/or replaceable like that. It's possible to extract the resources anyway, but at least it takes some work to do it.




UPDATE on broken USER.ico

I have been tracing this back in the code and all of the paths passed on from BuildTargetWindows to the NativeProxy are correct. The problem is that the native code is not returning an error message, which is to say that even with full, absolute paths (which I have tested as a possible fix), UpdateResource is returning true, indicating success.

For what it's worth, the code in BuildTargetWindows.UpdateWindowsEXE has not changed, nor has the native ReplaceIconFromFile function. This will require further investigation to determine why the main EXE is failing to have its icon updated.
#289
I can look into the icons, but regarding the split resource files, certain things have always been packed into the first file, such as the sprite file, which generally speaking makes up the bulk of your non-audio files. Additionally, the way the asset manager works, single files cannot be split across multiple resource files, which will also limit your minimum file size.

It might be possible to look into external compression libraries that allow split files, but that would be no small amount of work to include a relatively small feature. I would not expect this any time soon.
#290
Is simply checking the cursor mode first insufficient?

Code: ags
function hHallway_MouseMove()
{
    if (mouse.Mode != eModeUseinv)
    {
        mouse.SaveCursorUntilItLeaves();
        mouse.Mode = eModeInteract;
    }
}
#291
Bump for new version! Details in the first post.
#292
Hmm, yes, sorry about that. I created this post while I was in class and didn't have access to AGS. I forgot that since the two GfxFilter arrays are actually arrays of pointers that the individual items in the arrays also have to be initialized.

And then I keep getting segmentation faults when trying to use StrCopy on the item's char[200] arrays, although I can manually copy them in a simple for loop. It now occurs to me that AGS never did allow old-style strings as members of a struct, so I wonder if there is some underlying cause as to why it can't read the address of the array properly. In any case, I redact my proposed solution as it doesn't actually work. Sorry again for the confusion.
#293
Yeah, sorry. That was a mistake. I edited the post above.

I amended a few other things as well, such as incorrectly converting the char array into a new-style String. The above code should now work as intended.
#294
I was actually curious about doing that. Does Allegro 4 allow that to be done? I thought that it wasn't possible with A4.
#295
It depends on which version of AGS you're using, but as of the latest stable version (AGS 3.3.3), there are no pointers to custom user struct types. This is actually introduced in the up-coming version (AGS 3.4.0), but currently (AGS 3.4.0.3) you cannot have both pointers to a custom struct type and pointers within that struct. This would prevent you from having a pointer to your type (or a dynamic array of your type) while storing Strings within them.

You could use the old-style string functions like this:

Spoiler
Code: ags
// *.ash

#define LST_DX5_LIST 7
#define LST_D3D9_LIST 10

managed struct GfxFilter
{
  char name[200];
  char filter[200];
  char filter_scaling[200];
};

// NOTE: **NEVER** define struct instances in a header file!! ONLY import them! 
import GfxFilter* FiltersDX5[]; // use these as dynamic arrays, so you can get a pointer to the array
import GfxFilter* FiltersD3D9[];


Code: ags
// *.asc
// import old-style string functions
import void StrCopy(string, const string);
import int StrLen(const string);

GfxFilter* FiltersDX5[];
GfxFilter* FiltersD3D9[];
export FiltersDX5;
export FiltersD3D9;

function game_start()
{
  // initialize arrays
  FiltersDX5 = new GfxFilter[LST_DX5_LIST];
  FiltersD3D9 = new GfxFilter[LST_D3D9_LIST];
  int i;
  for (i = 0; (i < LST_DX5_LIST) || (i < LST_D3D9_LIST); i++)
  {
    if (i < LST_DX5_LIST)
    {
      FiltersDX5[i] = new GfxFilter;
    }
    if (i < LST_D3D9_LIST)
    {
      FiltersD3D9[i] = new GfxFilter;
    }
  }
  // populate array members
  String buffer;
  buffer = "SomeFilterName";
  StrCopy(FiltersDX5[0].name, buffer); // etc.
}

String CharArrayToString(const string buffer)
{
  String s = buffer;
  return s;
}

void DoSomething()
{
  String driver = ini.Read("graphics", "driver", "DX5");
  GfxFilter *filters[] = FiltersDX5;
  int aVariableArraySize = LST_DX5_LIST;
  if (driver == "D3D9")
  {
    filters = FiltersD3D9;
    aVariableArraySize = LST_D3D9_LIST;
  }
  int i = 0;
  while (i < aVariableArraySize)
  {
    String name = CharArrayToString(filters[i].name); // copy the struct member into a String to take full advantage of any new-style String functions
    lstFilter.AddItem(name);
    i++;
  }
}
[close]

That being said, if you're trying to change the graphics filter settings at run-time, just be aware that it won't work. The AGS engine currently can only change filters when the game is first launched.

Edit: Correction - The above code does not work, producing a segfault when trying to access the member arrays using StrCopy. The characters could be manually copied into the arrays, but that loses so much of the efficiency of the code that other solutions should be utilized instead.
#296
It wouldn't be faster than processing an array because all that the module is doing is processing arrays. :P

However, if you want a type-generic container class that automatically grows as needed, then this still fits that description (which is what it is designed for).
#297
As part of my on-going effort to definitively prove that there is nothing that I won't code when it comes to AGS, I made a new version of this module! ;-D And then, I decided it was crap, so I rewrote it again to be 1000% better than the aforementioned version which is now lost forever to the sands of time!

The biggest news is that this version of the module is FAST* because I can use dynamic arrays in structs now. The current limitations on managed structs led me to some suboptimal code when working with Strings, but I can pretty consistently push one million ints (the current max size for a dynamic array btw) into a Stack in a single for loop in only about 30 seconds! By way of comparison, with v1.3 I tried pushing a measly ten thousand ints into a Stack and the program froze for more than half an hour before I force-closed it with Task Manager. I can push ten thousand ints with this version in under a second.

To really optimize the speed, I made it possible to set the capacity of a Stack (setting the size of the underlying dynamic array) and avoid additional copying. Considering how much unnecessary copying was taking place in v1.3 of this module, anyone who actually used the older module should be quite happy with the improvements I've made.

Anyway, download link.

*To be fair, it's not native code "fast", but I don't think many people are going to be trying to push hundreds of thousands of items at once in a single frame of their game...
#298
Hey, this is pretty cool! :D I always felt like AGS needed some sort of TextArea control. Glad that my old idea inspired you to make this, I never noticed it.
#299
Code: ags
function oCdoor_Interact()
{
  if (Game.DoOnceOnly(oCdoor_Interact)) // oCdoor_Interact is not a String variable!
  {
    cEgo.Walk(192, 55, eBlock, eWalkableAreas);
    Display("As you move to open the door it suddenly springs open!" // MISSING closing parenthesis and semicolon!
    Display(" 'STAY BACK!' ");
    Display(" 'George! Oh thank go!' ");
    Display("It's your best friend Ken!");
    Display(" 'When I heard the ship was being invaded I fled down the hall and hid in the closet. I was afraid to come out but I'm glad to see you. We got outta here!' ");
    cEgo.AddInventory(iKen);
  }
  else
  {
    Display("TEST");
  }
}


It is telling you that an opening parenthesis was expected because oCdoor_Interact is the name of a function. In AGS there's no such thing as a function-pointer, or anything like it, so when the script parser sees a function name it expects the very next character to be the opening parenthesis.

The Game.DoOnceOnly function takes a String parameter, not a function name as a callback. You could still use the name of the function if you want, but you'll have to enclose it in double quotes ("oCdoor_Interact").

You are also missing a closing parenthesis and semicolon on the fifth line of your code snippet, as I commented on above.

Here is the amended code:

Code: ags
function oCdoor_Interact()
{
  if (Game.DoOnceOnly("oCdoor_Interact"))
  {
    cEgo.Walk(192, 55, eBlock, eWalkableAreas);
    Display("As you move to open the door it suddenly springs open!");
    Display(" 'STAY BACK!' ");
    Display(" 'George! Oh thank go!' ");
    Display("It's your best friend Ken!");
    Display(" 'When I heard the ship was being invaded I fled down the hall and hid in the closet. I was afraid to come out but I'm glad to see you. We got outta here!' ");
    cEgo.AddInventory(iKen);
  }
  else
  {
    Display("TEST");
  }
}


P.S. You can format your code for forum posts by putting it between [code] and [/code] tags.
#300
AlienCap, I must insist that you stop giving programming advice. What you are suggesting to do is wrong. This is not the proper way for things to be done in AGS: it unnecessarily clutters the repeatedly_execute function when there are specialized events, it requires additional polling of variables in memory thereby making the code less efficient, and what's more is that it doesn't even work properly.

You are attempting to use brute force to manipulate the TextBox text, but this does nothing to prevent other code from changing the property to an invalid value. So long as the length of the string is maintained then your code does not attempt to validate the text. What's more is that you are changing the length of the string inside of a loop that uses its own length as a terminating value - that's day one bad programming style. And although you're putting forward a good effort to make it look as though you're validating only the newly input bit of the string, you always begin parsing the string from the beginning, which is the least efficient way for you to parse it. You're using an integer to store a boolean value, which isn't inherently bad on its own, but especially on top of everything else it makes your code less readable. Adding to this unreadable mess, you are using the not operator on a pair of conditions instead of switching the inequality operators.

And you're missing a closing brace in your example.

STOP POSTING CODE AS "HELPFUL" ADVICE. YOU ARE WRONG.
SMF spam blocked by CleanTalk