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

#81
The .Draw() call goes into room_RepExec; other than that I don't see an error.
The SetViewScreen command expects x, y, width and height, so setting all to 100 should work.
#82
@RootBound

The signature of the SetCamera method is
Code: ags
  void Mode7.SetCamera(float x, float y, float z, float xa, float ya, float focal_length)

x,y,z is the position, so y should be greater than 0 or the camera is inside the plane.

xa and ya are the camera angles, i.e. xa determines the direction the camera is facing, ya is the up/down angle afaik.
xa can be anything from 0 to 2 * Pi, but values outside that range should wrap around. ya is supposed to be something like -0.1 for instance, i.e. the camera is slightly looking down.

The last value is the focal length, essentially a zoom factor. Try values like 35.0.
#83
Advanced Technical Forum / Re: Windows 11
Wed 30/08/2023 15:40:43
Win 11 Pro 22H2, Geforce GTX 1660 Super

I downloaded the Demo version from the website and gave it a try (AGS 3.21).

-In windowed mode I couldn't move the game's mouse cursor at all.
-In x2 fullscreen I could play fine using either DirectDraw5 or DirectX9. The latter mode didn't properly capture the mouse though; the windows mouse cursor appeared above the game in addition to the in-game mouse cursor.

I tried an old 3.21 game of mine and couldn't play it at all. It refused to open fullscreen (resolution isn't supported), probably because it's a 16bit game, and in windowed mode I couldn't move the in-game mouse.
Changing the color depth to 32bit fixed both issues.

So no green stripes here at any point, but anything less than 32bit seems to cause a bunch of issues if the engine is an older one.

I never had any issues with newer versions of AGS; I've been using Win 11 for at least a year now and never had any problems with 3.5 or 3.6.
#84
Yeah, I was afraid that was the case. I might add support for that at some point.
#85
You need a second function and call it like this:
Code: ags
oConversation.playVoiceClipOnFrame(0, 2, cMei, 1);

Also note that in general, if
Code: ags
oConversation.playAudioClipOnFrame(0, 2, Game.PlayVoiceClip(cMei, 1));
worked, it still wouldn't do what you want.

You wouldn't schedule the Game.PlayVoiceClip call at all, rather it would run as soon as AGS hits that line. Next it would call oConversation.playAudioClipOnFrame and pass the *return value* of the Game.PlayVoiceClip call as third parameter.

There are scripting languages where stuff like this is possible, but for this you need the ability to pass functions as parameters.
Then you could do
Code: ags
oConversation.runFunctionOnFrame(0, 2, function () { Game.PlayVoiceClip(cMei, 1); });
Unfortunately, this fantastic technique is not supported (yet?).
#86
You can use this: http://khris.ddns.net/agsfont/

First, select a TTF or OTF font, then adjust the outline to your liking.
Finally, download the wfn files and overwrite the ones in your game folder.
#87
The Rumpus Room / Re: What grinds my gears!
Thu 24/08/2023 13:28:43
I hate setting up multiple monitors on Windows.
Currently I can choose between
a) a correct projection menu but I don't see anything on my monitor after turning on the PC until the lock screen
b) everything is as its supposed to be, except the goddamn projection menu, which labels my monitor as external / secondary screen despite it being identified as display #1 as of nvidia's hardware numbering and Windows itself(!)

Look at this shit (click for full size):
#88
Quote from: heltenjon on Tue 22/08/2023 14:37:51You could add another if statement to the top of your code to check if the player already has the drink. Then make the reply "I already got a drink". Check for the drink before you check for the coin. (You can solve this in multiple ways, depending on what player response you want.)

Sorry, but I don't think this is a good approach. First of all, if the player can lose the drink, this check will no longer work as intended. Granted, if they cannot lose the drink before leaving the area with the machine forever, this will work, but this is error prone in general and should be avoided.

I always try to mimic real life: a vending machine IRL has no idea whether you already possess a drink or not, and it shouldn't prevent you from getting another one anyway.
Just simulate an actual vending machine: you insert a coin and you get a drink. If the coin can get stuck, add a variable for this and keep track of that, too.
If you want to limit the player to a single drink, just don't give them more than one coin. If they have more than one coin but getting two drinks would lead to a dead end, consider your approach. Can they maybe get back the coin(s) somehow? (This has the added benefit of making the player feel less like being guided along a narrow path towards the "correct" solution.)

I'm also not too fond of using the inventory as a substitute for variables, tbh. My rule of thumb is always: implement everything in a future-proof way. Any future change to the game design, UI, etc. should require as little changes as possible to existing code.
#89
Exactly. If you need to store more complex information, you need to carefully think about the kind of information and which variable type is needed.

For instance if you have three lockers and one of them contains an object at random, using one bool for each locker is a bad idea because not only do you need to handle three variables, but at least in theory more than one can be true, which clashes with the concept of only one of them containing the object.
In this case you would use an integer variable, where a value of 1 means the object is in the first locker, and so on. After the player removes the object, you simply change the value to 0. This greatly reduces the possibility for logic errors in your game.
#90
Can you be more specific about the gap? Why can't you temporarily use a view without the gap? Or remove it altogether?
#91
You can start here:
https://www.adventuregamestudio.co.uk/wiki/Scripting,_Code_%26_Interaction#Working_with_variables:_the_basics

You should also take a look at the Global Variables pane in the editor, there you can create global ones without scripting.
For instance the simplest one is a bool, which can only be true or false.

Say you create a bool called "room2_light" and set its initial value to false. You can now solve a previously impossible problem: changing the state of another room as opposed to the current one.

In you first room, when the player interacts with a light switch, put
Code: ags
  room2_light = true;
inside the function.

In room 2 you can now check this variable when the player enters (before fadein) and preprare the room accordingly:
Code: ags
  if (room2_light == true) {
    // switch background
    // turn on hotspots and objects otherwise in darkness
    // etc.
  }
  else if (room2_light == false) {
    // make room dark again
  }

Note the double == to compare a variable to a value; a single = is used to change the value.


(for the sake of completeness: toggling a bool is done like room2_light = !room2_light; and you can use the shorter if (room2_light) and just an else to check for the two cases)
#92
Quote from: PEd1 on Mon 21/08/2023 18:29:42Ah, ok, so something I did not realize is that NPCs have their own inventories that AGS keeps track of?

All characters work the same under the hood. They all have the same properties. You can switch the player to command another character at any point.

In general, whenever you need your game to remember something, the answer is: variables. Here you can use the built-in inventory array of the NPC to store which items they already received from you, but if you want to store other information to look up later, you will need a variable (or many of them). It's never too early to learn this concept.
#93
Store the initial mouse coordinates when the button is held down. When the button is released, compare the current coordinates to the stored ones and only process it as click if they're the same.
#94
You need a 2D rotation matrix:



Code: ags
int[] RotatedPoint(int xi, int yi, int deg) {
  float x = IntToFloat(xi);
  float y = IntToFloat(yi);
  float r = Maths.DegreesToRadians(deg);
  float c = Math.Cos(r), s = Math.Sin(r); // cosine and sine
  int r[] = new int[2];
  // matrix times vector
  r[0] = FloatToInt(c * x - s * y, eRoundNearest);
  r[1] = FloatToInt(s * x + c * y, eRoundNearest);
  return r;
}

This function rotates a 2D point around the origin, so if your square is supposed to rotate around its center, you need to subtract half the side length from your coordinates before calling it, then add it back.

Example code:
Code: ags
  // square size s
  // shift origin to square's center
  x -= s / 2;
  y -= s / 2;
  int p[] = RotatedPoint(x, y, 5); // 5 degrees clockwise
  // shift origin back to top left
  x = p[0] + s / 2;
  y = p[1] + s / 2;
#95
One thing that can cause the animation not to play is having SetBackgroundFrame() in your room script.
#96
Regarding the puzzle you can probably shorten your code considerably if you use an array of bools, a single rectangular hotspot covering the entire keypad and nine non-clickable objects.

Code: ags
bool lit[9];

function hKeypad_Interact() {
  int xo = 123, yo = 45; // coordinates of top left corner of top left button
  int w = 20, h = 15; // width and height of a button
  int xg = 5, yg = 5; // gap between buttons

  int x = (mouse.x - xo);
  int y = (mouse.y - yo);
  if (x % (w + xg) > w || y % (h + yg) > h) return; // clicked in between buttons
  int bi = (y / (h + yg)) * 3 + (x / (x + xg)); // should be 0-8
  
  // flip clicked and neighboring bools
  for (int i = 0; i < 9; i++) {
    if (i == bi || i + 3 == bi || i - 3 == bi || i % 3 == 0 && i + 1 == bi || i % 3 == 2 && i - 1 == bi) lit[i] == !lit[i];
  }

  // update button objects visibility
  for (int i = 0; i < 9; i++) object[i + 2].Visible == lit[i]; // first button object has ID 2, etc.
}
#97
This is possible in a bunch of languages like PHP or JavaScript where you can declare an empty array by assigning [].
It doesn't seem to be possible in C++ though.

Since inventory items start at ID 1 anyway, inventory[0] seems to be a dummy item. Why not define the array with a length of 1 then, if no items exist?

And if you create items programmatically, there should still be a global array where you can iterate over all items, so I don't think inventory[] is going to disappear?
#98
Alternatively, AGS should always declare an inventory array. If there are no inventory items, simply make it empty.
#99
Sure, but Gal explains in the first post why this is cumbersome because his views have so many frames. That's why he wants to do it via script.
#100
I'll leave it here as example code for similar stuff, but you can do the same like this:

Code: ags
  ViewFrame* vf = Game.GetViewFrame(EGYPTRUN1, 0, 127); // 0 is the loop
  vf.LinkedAudio = aGUNSHOT1;
SMF spam blocked by CleanTalk