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

#181
I'd use 1280x720. People still have laptops that have native resolutions smaller than 1080p, but 720p should be fine for everybody.
That way the game size is roughly halved on top.

As for the GUIs, I personally dislike hand-drawn GUIs even with a hand-drawn game. I usually wouldn't mix pixel sizes but Whispers of a Machine pulls it off really great imo:

Spoiler
[close]
#182
Those are view names so you don't have to use the numbers in your script. When you create a new view in the project tree, you're asked to rename the view. You can also change the name at any time in the properties.

You're correct though, you only need a different loop to switch the sprites.

Given your code it should probably be:

Code: ags
function oJouer_AnyClick()
{
  int loop = 0; // default
  if (Game.TranslationFilename == "English") loop = 5;
  oJouer.SetView(95); // you can use the view's name instead of 95 here
  oJouer.Animate(loop, 3, eOnce);
  aZik01.Stop();
  player.ChangeRoom(102, 129, 171, eDirectionDown);
}
#183
It should work like this:

Code: ags
  int new_game_view = BTNNEWGAME;
  int load_view = BTNLOAD;
  // ...
  if (Game.TranslationFilename == "English") {
    new_game_view = BTNNEWGAMEENG;
    load_view = BTNLOADENG;
    // ...
  }
  btnNewGame.Animate(new_game_view, ...);
  btnLoad.Animate(load_view, ...);

Wait, you're using Room Objects? The basic idea is the same though. You don't change the sprites of the view but create a 2nd view containing the translated sprites and use that for the animation.
#184
You might want to check these coordinates though; this code will make the NPC move twice, then never again.

Code: ags
  // inside room_RepExec
  if (!cPopper.Moving)
  {
    if (cPopper.x == 409 && cPopper.y == 153) cPopper.Walk (218, 157);
    else                                      cPopper.Walk (181, 349);
  }

Provided that the NPC starts the game at 409,153 (or is sent there in a some other function), this code will kick in and send them to 218, 157. As soon as they reach that point, the code will kick in again and send them to 181, 349. As soon as they reach those coordinates, the code will keep sending the NPC to 181, 349 where they already are.

If you want the NPC to walk back and forth, you need to send them to the original coords in the else clause.
#185
You create a new TextWindow GUI and assign border sprites. Afaik dialogs use Game.NormalFont.
Then you enter the ID of the text window GUI in General Settings -> Dialogs -> Use GUI for Dialog options

For more advanced customization, see here: https://adventuregamestudio.github.io/ags-manual/CustomDialogOptions.html#custom-dialog-options-rendering

(Also, no offense, but all of this is explained in the manual. You should really read it from top to bottom at least once. ;))
#186
No, the automatic calling of unhandled_event only happens if there's no function linked to the event.
#187
If you assign a function to that event, IsInteractionAvailable(eModeUseinv) will be true.

In your handler function you need to check player.ActiveInventory and call your custom function in the else clause (you have to make it global for that, i.e. import it in the global header).

Code: ags
function hGriffoBarra_Useinv() {
  if (player.ActiveInventory == iExclusiveItem) {
    // ...
  }
  else MyUnhandled();
}
#188
On imgur, after uploading, right-click the image and select "copy image link".

#189
You need to put this in the room script:

Code: ags
function on_mouse_click(MouseButton button)
{
  if (button == eMouseLeft && cChar1.View == 167) // using the view's name is preferable
  {
    ClaimEvent(); // don't run global on_mouse_click after this
    cChar1.UnlockView();
  }
}

Note that AGS supports idle views, and more importantly: do not lock the view to view 1, unlocking it is enough to return to default behavior.
You lock the view to perform a specific animation, then unlock when the animation is done.
#190
You probably have tons of duplicate code that way; you need to refactor your functions. If you find yourself copy-pasting large portions of code, you're on the wrong track.

Here's the approach I'd use, just for hotspots:

Code: ags
// always put code like this in its own function. If you made a mistake you fix one spot, not dozens
String Article(int genero) {
  if (genero == 1) return "ese";
  if (genero == 2) return "esa";
  if (genero == 3) return "esos";
  return "esas";
}

// core method: choose random message based on location type and cursor mode
void SayRandomMessage(String location, LocationType lt, CursorMode mode) {
  String message[6];
  if (mode == eModeLookat) {
    // ...
  }
  else if (mode == eModeTalkto) {
    if (lt == eLocationCharacter) {
      message[0] = "¿Qué puedo decirle a %s que tenga sentido?";
      message[1] = "No quiero hablar con %s, creo no me va a ayudar.";
      // ...
    }
    else message[0] = "Talking to inanimate objects? Nah.";
  }
  int ri;
  do { ri = Random(5); } while (message[ri] == null);
  player.Say(String.Format(message[ri], location));
}

// this doesn't have to be a separate function but I like to keep on_mouse_click as short and readable as possible
void UnhandledH(this Hotspot*, CursorMode mode) {
  String location = String.Format("%s %s", Article(this.GetProperty("generoNumero")), this.Name);
  // code to properly approach a hotspot goes here ;)
  SayRandomMessage(location, eLocationHotspot, mode);
}

And in on_mouse_click / eMouseLeft:
Code: ags
    int mx = mouse.x, my = mouse.y; // store in variables so the coords don't change
    LocationType lt = GetLocationType(mx, my);
    if (lt == eLocationHotspot) {
      Hotspot* h = Hotspot.GetAtScreenXY(mx, my); // now it's basically 100% guaranteed that h isn't null
      if (h.IsInteractionAvailabe(mouse.Mode)) h.RunInteraction(mouse.Mode);
      else h.UnhandledH(mouse.Mode);
    }
#191
Quote from: PERXEO on Mon 17/04/2023 15:29:17But while the player character walks towards that point, if we move the cursor and interfere with it, the value of locname changes, because another unhandled event fires.
No, that is absolutely not what's happening. unhandled_event doesn't fire because you're hovering the mouse over the player. It's repeatedly_execute(_always) that changes the label.

However: by default, when you click with an "active" cursor mode (look, interact, talk) on some hotspot while no related event is assigned, nothing happens at all. The player doesn't walk anywhere (unless you have a walk to point assigned to the hotspot I guess). At this point, AGS calls unhandled_event. Once.

There is no short answer to this problem because it depends on your game design.
We need to clarify how you want interactions to work in general.

Which template are you using?
Is the player always supposed to approach the hotspot, even if an "unhandled" action was picked? If so, how is that implemented? And is the approach going to be blocking, or can it be cancelled by clicking elsewhere?
Also, afaik, at this point the interaction isn't unhandled already, because what is making the player move there?
#192
Exactly, I can see no scenario where you would update a verb line inside unhandled_event.

The problem you describe is caused by the player being clickable and thus getting detected by Game.GetLocationName(), it's completely unrelated to unhandled_event.

What is extra confusing here is that you seem to understand exactly how unhandled_event is supposed to be used:
QuoteI have a code snippet for unhandled_events, which I want to use to give special responses to certain unhandled events.
then turn around and suddenly want to use it for a completely different, unrelated and unsuitable purpose...?
#193
The first problem is easily solved, just use
Code: ags
  else if (button == eMouseRight || button == eMouseRightInv)

As for the other two, eModeUseinv requires an active inventory item. If player.ActiveInventory is null, AGS simply ignores your setting the mode to that.
However it's pointless to switch to that mode as soon as the player opens the inventory anyway. eModeUseinv is not the mode you use to pick an item, it's the mode used when an already active item is used with something else.
My code expects the game to use eModeInteract to pick an item from the inventory, so that's the mode you should switch to when the player opens it.
#194
Just in case a situation arises where one has to use multiple GUIs:
if they have consecutive numbers, you can simply do
Code: ags
  for (int i = 6; i <= 12; i++) gui[i].Visible = false;
to turn them all off before turning on the one related to the button.
#195
Sorry, I should've thought of that way earlier. My code only works when you turn on custom inv click handling, but that means you now have to handle an interact click manually, too:

Code: ags
  if (button == eMouseLeftInv) {
    one = inventory[game.inv_activated];
    if (player.ActiveInventory == null) {
      // interacting with an item makes it active, this should also set the mouse mode to eModeUseinv
      if (mouse.Mode == eModeInteract) player.ActiveInventory = one;
      else one.RunInteraction(mouse.Mode); // other modes
    }
    else if (mouse.Mode == eModeUseinv) {
      two = player.ActiveInventory;
      if (!Combine()) one.RunInteraction(eModeUseinv);
    }
  }

If you want the player to be able to interact with an inventory item (like turning on a flashlight for instance), you need to use a different cursor mode to make the item active, like eModePointer
#196
This setting does not concern buttons, it's for handling the clicks you make on inventory items inside an InvWindow.
My code deals with the player combining an item with another item, which is why I check for the mouse mode being eModeUseinv.

I don't know what your button does. Also, why does it start with a "g" like a GUI? You should use "btn" instead.
#197
Yes, setting this to true means that AGS should call on_mouse_click passing eMouseLeftInv as button if you left click on an inventory item.
If that doesn't work, there's a bunch of possible reasons.

1. the inv GUI is covered by something else (which is transparent though)
2. the inv GUI isn't set to clickable
3. the inv window's itemwidth/itemheight is too small and you're clicking outside the item
#198
You probably need to turn on custom inventory click handling in General Settings
#199
Right, remove "function":

Code: ags
bool Combine() {

However you need to add code in there, like

Code: ags
bool Combine() {
  if (IsItems(iLicuadora, iNaranja)) { // el orden no importa aqui 
    player.LoseInventory(iLicuadora);
    player.LoseInventory(iNaranja);
    player.AddInventory(iJugo);
    player.Say("blah");
    return true;
  }
  return false;
}
#200
Lines 1-12 go into the Global script. Either at the top or above the on_mouse_click function (or anywhere in between, but outside any function).
Then you extend the Combine function by handling all the possible combinations that actually work. For each successful combination, make sure to "return true;" eventually.

Lines 15-21 go inside the on_mouse_click function. By default it has if blocks for eMouseLeft and eMouseRight. Just add the eMouseLeftInv code below (you can always check the indentation of my snippets, I always write my code with indentation that already matches the place where it's supposed to be pasted).

 The Combine line is complete, here's the longer version:

Code: ags
      if (Combine() == false) {
        one.RunInteraction(eModeUseinv);
      }

It means: if Combine() returns false because the player tried to combine two items that don't actually combine, fall back to default behavior (i.e. run the clicked item's eModeUseinv handler).
SMF spam blocked by CleanTalk