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

#141
The Rumpus Room / Re: What grinds my gears!
Thu 22/06/2023 07:53:05
Every single use of the term "AI" lately. (roll)

I'm also slightly miffed about having to root for Mark Zuckerberg of all people, due to the upcoming cage match against the dumbest person alive.
#142
That's fine, I was referring to the function's name not the event's. You still didn't add eAnywhere though, line 57 in that snippet needs to be
Code: ags
  oStalagmiteTip.Move(oStalagmiteTip.X, 1000, eNoBlock, eAnywhere);
#143
Indeed, and it's room_RepExec instead of repeatedly_execute for room scripts.
#144
1. please do not quote the entire post; you can click the Reply button at the bottom.

2. in my code, oStalactite is an Object, not a Character. Please show your code and error messages as they appear, ideally verbatim.

3. once again: the code might not work as-is and is primarily meant to show a way how this can be done in general; there's no way around studying the manual and familiarizing yourself with the AGS scripting language.
#145
Just put
Code: ags
  game.narrator_speech = -1;

in game_start (or the first room's room_Load).

Regarding the syntax error in Display(&1 "Bla bla bla"): Display is a function that expects a string as first argument. You can't just put arbitrary characters in between the parens. The &1 belongs at the start of the string, exactly as with the Say command.
#146
EDIT:
Disregard my post; Display() supports voice speech out of the box. By calling game.narrator_speech = -1;, the game will use voice files starting with NARR.

---

You probably need a custom function for this.

Code: ags
void Narrate(int cue, String text) {
  AudioChannel* ch = Game.PlayVoiceClip(cNar, cue);
  Display(text);
  if (ch != null) ch.Stop();
}

Add this to the Global header to be able to call the function from room scripts:
Code: ags
import void Narrate(int cue, String text);

Now call it like this: Narrate(1, "King Graham finally got rid of Cedric.");

Edit:
& is the bitwise and operator, it does not really do anything here.
Edit 2: NPE fix
#147
First of all, you don't need to use a (global) character for everything. Rooms have (local) objects, so unless you need walking animations, those are fine.

Next, you can do a simple coordinate check. Since the tentacles only move sideways, you only need to compare the x coordinates of the tentacle and the stalactite.

Again inside repeatedly_execute:

Code: ags
  int dist = cTentacle.x - (oStalactite.X + Game.SpriteWidth[oStalactite.Graphic] / 2);
  if (dist < 0) dist = -dist;
  if (dist < 20 && oStalactite.Y == 123) { // adjust these numbers, replace 123 with proper Y coordinate
    oStalactiteTip.Move(oStalactiteTip.X, 10000, eNoBlock);
  }
  // tip reaches water
  if (oStalactiteTip.Y >= 250) {
    oStalactite.StopMoving();
    oStalactite.Visible = false;
  }
Objects are positioned using their bottom left corner, so we add half the sprite width to get to the center and compare that to the tentacle by checking whether the difference is below a threshold.

As for the piece breaking off, just start with the stalactite already in pieces. This way you simply need to move the tip object down and not replace anything.

(once again the code might now work as-is and is primarily meant to show a way how this can be done in general)
#148
Sorry, JavaScript-Brain :)
Glad it's working now.
#149
Just for reference, the original code is a very bad way to do this but could've been fixed by wrapping the strings in GetTranslation() calls.
#150
Yeah, I typed this up pretty quickly. Try this version:

Code: ags
  if (IsTimerExpired(1)) {
    int newX, diff;
    do {
      newX = Random(160) + 40; // range 40 - 200
      diff = newX - cSeaMonster.x; if (diff < 0) diff = -diff;
    } while (diff < 30); // move by at least 30 pixels
    cSeaMonster.Move(newX, cSeaMonster.y, eNoBlock, eAnywhere);
    SetTimer(1, (Math.Random(5) + 5) * GetGameSpeed()); // 5 - 10 seconds
  }

Edit: code fixed (for good, I hope)
#151
Make it a single button, then use the coordinates to figure out which square was clicked.

Code: ags
function btnGrid_OnClick(GUIControl* control, MouseButton button) {
  if (button != eMouseLeft) return;
  int x = mouse.x - control.OwningGUI.X - control.X;
  int y = mouse.y - control.OwningGUI.Y - control.Y;

  int border = 5;
  int size = 10;
  int gap = 3;
  int columns = 9;

  int col = (x - border - gap / 2) / (size + gap);
  int row = (y - border - gap / 2) / (size + gap);
  int n = row * columns + col;
  // check n against next id in sequence, ...
}
#152
First of all, put this in repeatedly_execute_always:

Code: ags
  cTentacle.x = cSeaMonster.x - 47;
  cSecondTentacle.x = cSeaMonster.x + 57;

This way you don't have to worry about the tentacles at all.

Now implement a timer, like
Code: ags
  if (IsTimerExpired(1)) {
    int newX = cSeaMonster.x;
    // move at least by 30 pixels
    while (newX - SeaMonster.x < 30 || SeaMonster.x - newX < 30) {
      newX = Math.Random(160) + 40; // range 40 - 200
    }
    cSeaMonster.Move(newX, cSeaMonster.y, eNoBlock, eAnywhere);
    SetTimer((Math.Random(5) + 5) * GetGameSpeed()); // 5 - 10 seconds
  }

This code goes inside Room_RepExec, and you need to kick it off by calling SetTimer(1, 1); in room_Load.
#153
You seem to have solved this on your own, but "resizing the walkable area" sounds kinda off.
To use a different size for the entire area, simply enable scaling, then set both factors to the same number.

Alternatively, put something like this in room_Load
Code: ags
  player.ManualScaling = true;
  player.Scaling = 130;
#154
You don't need to put the code inside the dialog script:

Code: ags
function cNpc_Talk() {
  cNpc.LockView(NPC_ARMONTABLE);
  cNpc.Animate(..., eBlock, ...);
  dNpc1.Start(); // start dialog
}

To make them turn back:
Code: ags
// inside Room_RepExec
  if (cNpc.View == NPC_ARMONTABLE) {
    cNpc.Animate(..., eBlock, eBackwards, ...);
    cNpc.UnlockView();
  }
#155
Not sure how my code (or previous versions) could've caused that error, it probably stems from accidentally using player.IsCollidingWithObject(i) I guess.

Anyway, glad it works :)
#156
This should work:

Code: ags
// above rep_exe
AudioChannel* objCollision;

void roomCollisions() {
  if (objCollision == null || !objCollision.IsPlaying) {
    bool playIt;
    for (int i = 0; i < Room.ObjectCount; i++) {
      if (player.IsCollidingWithObject(object[i])) playIt = true;
    }
    if (playIt) objCollision = aBang.Play();
  }
}

  // inside rep_exe
  if (player.Room >= 3 and player.Room <= 7) roomCollisions();
#157
To my knowledge AGS does not automatically change cursors, no. The original default game set the mouse mode to eModeInteract and changed the cursor to a pointer when you opened the inventory, IIRC.

Default inventory click handling requires the mouse mode to be eModeInteract to be able to pick an item, which is probably due to the fact that early was AGS was heavily modelled after the Sierra multi-cursor GUI.

Many templates override default inventory click handling, which is probably why you never had to switch the mode in your previous games.
#158
Here's code that fixes these broken links:

Code: javascript
  document.querySelectorAll("a.bbc_link").forEach(a =>  {
    const parts = a.href.split(/\/\/\//);
    if (parts.length > 1) a.href="//" + parts[1];
  });
#159
For reference:

Your initial code was using two identically named but separate variables, changing the room one didn't affect the one local to the global script.
As a rule in general, a variable is only ever declared once.

Also note that depending on your circumstances it might be preferable to use the Global Variables node in the project tree.
#160
SetCharacterView is not only the wrong command but also from the obsolete API. Are you using a really old version of AGS still?

You're supposed to do for instance

Code: ags
  player.SpeechView = -1;
SMF spam blocked by CleanTalk