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

#241
@Snarky The bubble will burst in the NFT sense. Those are still around, but the public doesn't care.

Sure, text and image generation is here to stay*, but OpenAI isn't heading for a self-aware computer program.
Everybody will realize that the people hyping AI are simply stupid and something else will be all the rage, like 8K monitors or whatever.


*It's (illegal) plagiarism on a massive scale, and the quality is getting worse and worse because it's already taking in its own slop. Companies also will have to start charging for image generation and the like, so MAYBE it will actually go away in the sense that it simply stops being useful.
#242
Here's another great facet of image generating algorithms:

Where Facebook's AI Slop Comes From

I'm also really looking forward to this bubble of diarrhea finally bursting, which can't take much longer. The energy cost is astronomical, meaning these fucking "AI" companies are destroying the planet at a much more rapid pace than ever before and the worst thing about this BS is that there's not even a payday at the end of this. Not even for the psychopathic CEOs.
#243
The Rumpus Room / Re: What grinds my gears!
Sat 03/08/2024 10:10:40
I got a phishing mail from a GMail account. Reporting the GMail user and domains for abuse turns out to be difficult / impossible though.

The abuse form on the domain provider's website has a mandatory checkmark where I'm supposed to authorize them to share my contact details with the domain owner. WTF. No.
I sent them an email instead with the subject "Phishing hosted on multiple of your domains" and listed the domains.
About a minute later I received an automated reply that said
QuoteYour message was not recognized as message about abuse.
Please add more information to your abuse report: domain name(s), type of abuse.

Reporting the Gmail address also turns out to be impossible: after clicking through various "help" pages on Google's website they tell me I'm supposed to open the mail on the Gmail website, then click on "Report this email" or whatever. There's just a slight problem: I received the phishing mail on a non-gmail address. Turns out there's no way to report malicious GMail accounts.
#244
A semi-transparent overlay will affect anything below it, whether it's an object or the room background.

Which means you basically need to paint a lighter version of the background so that darkening it via a shadow overlay will essentially darken it back to the lower lightness you want.

It's also possible to only darken the object but this requires using DynamicSprites and CopyTransparencyMask().
The idea is to create a dynamic sprite from the object sprite, draw the shadow on top using a Y offset based on the object's Y coordinate, then make the background transparent again by calling CopyTransparencyMask(OBJECT_SPRITE_SLOT).
Finally, you set the resulting DynamicSprite's .Graphic as the object's.
This has to be done inside repeatedly_execute, obviously, since the object is moving.

Code: ags
#define PIANO_SLOT 123

DynamicSprite* pianoSprite;

function room_Load() {
  pianoSprite = DynamicSprite.CreateFromExistingSprite(PIANO_SLOT);
  oPiano.Graphic = pianoSprite.Graphic;
}

function room_RepExec() {
  DrawingSurface* ds = pianoSprite.GetDrawingSurface();
  ds.Clear(COLOR_TRANSPARENT);
  ds.DrawImage(0, 0, PIANO_SLOT);
  bool mask_needed;
  if (oPiano.Y > 120 && oPiano < 170) {
    ds.DrawImage(0, 160 - oPiano.Y, SHADOW_SLOT);
    mask_needed = true;
  }
  ds.Release();
  if (mask_needed) oPiano.CopyTransparencyMask(PIANO_SLOT);
}

As the object moves down, the overlay is drawn further and further up, which causes it to remain static relative to the room.
#245
Quote from: lapsking on Thu 01/08/2024 15:21:52by the way, in the beginning I said there are different workarounds for each of these blocking/non blocking problems, I suggested a straightforward solution for general use if possible

And I tried to address specifically that by pointing out that there is no easy solve (= straightforward solution for general use) here.
In general you always have to do 1. start [thing] 2. check in repeatedly_execute if [thing] has ended.
And this is not going to change unless AGS Script starts supporting something like Promises.

#246
Yeah, there's a lot of really old, hard-coded behavior in AGS.

Especially the blocking thing can be frustrating, but there's no easy solution for that. You need blocking commands or basic beginner scripts are impossible. However blocking also blocks stuff, which can get in the way of other things.

The fading can be solved with custom code and a black GUI, this way you can make it non-blocking. However this means other commands might now run too soon.

In short: this is unlikely to be "solved" in AGS 4, because there's nothing to solve here. You simply need to learn how to write code for an event-based engine.
#247
@lapsking I saw you asking about non-blocking code in the AGS 4 thread.

The solution is indeed to simply append "_always" to the repeatedly_execute function's name.
This is basically a bug in my module and I've updated the download accordingly.
#248
@Akril15

This is a bug in the module.

Line 144 is this:
Code: ags
static void Mirrors2::NewMirror( Object* mask,  //set to null if no mask

This means it is valid to pass "null" as the first parameter. However as soon as you create a second mirror with no object anywhere in your game, the module mistakenly thinks you're reusing the object, and there's additional bugs further down where the modules assumes that mask is always != null.

If you always pass an object as first parameter, the module also wrongly assumes you're reusing an object if it has the same ID as a previous mirror's mask object. That's because the module stores a pointer to the room object, which is just a pointer to "object[1]" for instance; an array which gets reused for the new room's objects.

The Demo game happens to use object #0 in the harbor room and objects #1, #2 and #3 in the crystals room, which is how the bug was accidentally avoided.

To fix the bug, find line 135:
Code: ags
    if (data[i].mask == mask)

Change it to:
Code: ags
    if (mask != null && data[i].mask == mask && data[i].room == player.Room)
#249
Just in general, please always describe what the actual result is, as opposed to what you expected.

From your code it looks like you simply forgot to call player.ChangeView().

Code: ags
  // after player.StopMoving();
  if (speed == 5) player.ChangeView(PLAYER_WALK);
  else player.ChangeView(PLAYER_RUN);
#250
I wrote this from memory so I didn't realize the CopyTransparencyMask() method requires a slot.

Regarding your code, I assume you put this in a function? Which one?
Also, the error is the dreaded non-specific 0xC0000005 one, not sure what's causing this.
#251
As for the distance question, the approach primarily depends on the perspective of your graphics. Is it top-down? Sideview? In-between?

Collision checks in a 2D game are usually done via hitboxes; each game loop you calculate a rectangle for the sword based on the player's position, direction they're facing in and animation frame.
The same is done for the enemy's body.
Next you do a rectangle vs rectangle check and if they overlap, you process the hit.

I'd use a struct like:
Code: ags
managed struct Rectangle {
  int x1, y1, x2, y2;
  import boolean Overlaps(Rectangle* other);
};

The function looks like this:
Code: ags
boolean Rectangle::Overlaps(Rectangle* other) {
  if (this.x1 > other.x2 || this.x2 < other.x1) return false;
  if (this.y1 > other.y2 || this.y2 < other.y1) return false;
  return true;
}

You can now use that like:
Code: ags
#define ENEMY_COUNT 10

Rectangle* playerSword;
Rectangle* enemies[ENEMY_COUNT];

void game_start() {
  playerSword = new Rectangle;
  for (int i = 0; i < ENEMY_COUNT; i++) enemies[i] = new Rectangle;
}

void UpdateHitboxes() {
  // very rough example code
  playerSword.x1 = player.x + 5;
  enemy[0].x1 = cEnemy1.x - 10;
  // ...
}

void CheckCollisions() {
  for (int i = 0; i < ENEMY_COUNT; i++) {
    if (playerSword.Overlaps(enemies[i])) {
      // enemy #i just got hit
    }
  }
}
#252
So this is happening to only one beta tester? Not the others?

From the module's code and the fact that you're only using one mirror per room, I don't see what could cause this error.
An easy way to cause the error is to create two mirrors and pass the same object as the first parameter.
But you're not doing that in the code you posted.
#253
It looks like you need to do the following:

First, import a png that has a part of the walkable area (any color for the area, everything else transparent) to define the shape. Repeat for every part of the walkable area.

In game,
1. create a dynamic sprite (1) from the imported shape sprite
2. create a second dynamic sprite (2) and fill it with DrawingColor [AreaNumber] by drawing a rectangle to it
3. use CopyTransparencyMask to copy the transparency from (1) to (2)
4. get the drawing surface for the walkable areas, clear it, then draw sprite (2) to it

You obviously do this in a custom function, passing the area number i.e. color and sprite slot into it.
#254
Just to make sure: you're using AGS 4, right?
#255
You don't have to export functions (only variables), and you can organize stuff with structs.

Example module code:

Code: ags
// header
struct Roger {
  import static void handleInteract();
};

// main module script

static void Roger::handleInteract() {
  Display("Interacting with NPC1");
}

In the global script you can now do
Code: ags
function cRoger_Interact(Character *theCharacter, CursorMode mode)
{
  Roger.handleInteract();
}
#256
The Crop command's 3rd and 4th parameters are width and height, not x2 and y2.
I.e. you need to remove " + spacex" when you pass the width.

As for looping, replace "spacex += 1;" with:
Code: ags
  spacex = (spacex + 1) % (Game.SpriteWidth[946] - Game.SpriteWidth[948]);

The mod operator calculates the reminder, meaning it's the shorter way of doing:
Code: ags
  spacex++;
  if (spacex == SMALLEST_INVALID_VALUE) spacex = 0;

Btw: you can do this without cropping / copying the transparency mask: put the room background including holes for the windows in a sprite, then simply draw the stars followed by the room sprite to the room background's DrawingSurface.
#257
Please always post the actual code you have.

The following works fine for me:
Code: ags
  gDraggable.Visible = true;
  WaitMouseKey(1000);
  gDraggable.Visible = false;

I can simply click anywhere and the GUI disappears again.

To have the GUI stay on the screen until it is clicked, you need to use on_event:
Code: ags
void on_event(EventType event, int data) {
  if (event == eEventGUIMouseDown && data == gDraggable.ID) gDraggable.Visible = false;
}
#258
#259
You can simply put a bunch of player.Say("..."); commands in your script instead of using a dialog.

You can also use a custom property; add one for rooms to the schema (type: String, name: description).
Then add a new script above the two-click handler one:
Code: ags
function on_mouse_click(MouseButton which)
{
  if (GetLocationType(mouse.x,mouse.y) == eLocationNothing && which == eMouseRight) {
    ClaimEvent();
    player.Say(Room.GetTextProperty("description"));
  }
}

This way you won't have to paste this function into each new room.
#260
Hey, it's pretty simple actually :)

Just redownload the module.
I've added two commands:

Code: ags
  MusicPlayer.Shuffle(bool shuffle); // true / false to turn shuffle on / off
  MusicPlayer.Next(); // skip to next track
SMF spam blocked by CleanTalk