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

#201
You can only use object names in room scripts anyway. In the global script you can only access the current room's objects (using the object[n] array).

Also, note that if you want to initialize a property that is supposed to change during the game, putting the line in room_Load will reset the state each time the player enters the room, so you should probably use the "first time player enters room" event instead.
#202
Is other mobile stuff supposed to be able to appear behind this object? If not, just include pixels of the room background in the object's sprite.
#203
Could you upload your game sources somewhere so we can take a look? You can also send me a PM instead if you don't want to "publish" your game.
#204
I guess you're asking how to avoid a bunch of duplicate code? You can use a custom function:

Code: ags
function HookRope() {
  // combine items here
}

function iHook_Useinv() {
  if (player.ActiveInventory == iRope) HookRope();
  else ...
}

function iRope_Useinv() {
  if (player.ActiveInventory == iHook) HookRope();
  else ...
}

You could also intercept the click in on_mouse_click:
Code: ags
InventoryItem* one, two;

bool IsItems(InventoryItem* a, InventoryItem* b) { return a == one && b == two || a == two && b == one; }

bool Combine() {
  if (IsItems(iHook, iRope)) { // order doesn't matter here
    ...
    return true;
  }
  ...
  return false;
}

  // in on_mouse_click
  if (button == eMouseLeftInv) {
    if (mouse.Mode == eModeUseinv && player.ActiveInventory != null) {
      one = inventory[game.inv_activated];
      two = player.ActiveInventory;
      if (!Combine()) one.RunInteraction(eModeUseinv);
    }
  }

Edit: code fixed
#205
You can make both the GUI and button as large as the screen, then set the GUI to be fully transparent and use a PNG with an alpha channel for the button.
This way you can have a button filling the entire screen with the close-up in the center and, say, semi-transparent black borders. That way the player can simply click anywhere to close the GUI again and you don't need to worry about clicks outside the close-up.
#206
The idea that ChatGPT can help you understand AGS scripting is... curious. It's a program that strings words together based on probabilities, not a programming tutor.

Anyway, when you want a global array, you start with the top of the GlobalScript and think about a proper type, name and size.
For instance:
Code: ags
int randomFlag[10];

This gives you ten variables, randomFlag[0] to randomFlag[9]. You can now access them inside any function in the Global Script. If you also want to access them in room scripts, you need to make them actually global. First, export the variable right below the declaration. For this you only need the name. So it'll look like this:
Code: ags
int randomFlag[10];
export randomFlag; // it already exists, so we only need the name, not the type or size

Finally, we need to import it in the header. This header will end up above each room script and make the variable accessible in there. Now we do need the full information though, which simply means copy-pasting the declaration after the import keyword:
Code: ags
// script header
import int randomFlag[10];

Now let's say the first room is going to use randomFlag[0] for whatever purpose. We can now put
Code: ags
  randomFlag[0] = Random(3) + 1;
inside the linked room_FirstLoad function.

(If you only need to access the variable inside room functions though you shouldn't use a global variable for that. Just declare it at the top of the room script instead and you can use it in any function of the room script.)
#207
You can't just insert the coordinates directly, you need to calculate appropriate values and clamp them to the screen edges.
Like if you want to use an 80 x 50 pixel image, you'd use player.x - 40 for the x coordinate and player.y - 30 or something suitable like that for the y coordinate. You also need to check if the result is too small or too big because the player is close to the edge.
As in:
Code: ags
  x = player.x - 40;
  if (x < 0) x = 0;
  if (x >= 240) x = 240;
#208
You can set gender and number for each object etc. if you implement these as custom properties. Then you can use the method I described to read them and respond accordingly.

The alternative is a custom function where you pass both, like MyUnhandled(eGenderFemale, eCountOne); and to simply call that in the event function.

Afaik, most games use generic responses like "I don't see anything special" though, which will save you all this trouble.
#209
If you want individual responses, just handle the event instead. If this is about something else, please give some more information about what you're trying to achieve.

You can in theory handle all clicks in on_mouse_click yourself instead of simply calling Room.ProcessClick(), the idea is basically to use Game.GetLocationType to figure out the type, then use the according .GetAtScreenXY() function to find out the specific thing that was clicked. Now you can check .IsInteractionAvailable() and either call .RunInteraction() or a generic function. This way you know the specific thing without having to manually implement every event.
#210
You can let AGS take a screenshot and put it in the savegame, then use that image: DynamicSprite.CreateFromSaveGame

Or take a screenshot directly: DynamicSprite.CreateFromScreenShot

You can then crop the resulting sprite based on the player's position.
#212
Importing an image replaces all existing areas. You need to put both areas in the same BMP.
#213
In that case you need to show your code I guess. What have you tried to far?
#214
You should stop looking at the game that uses these old commands right now. It'll only confuse you and lead to a bunch of threads about obsolete stuff like this.

Also keep in mind that just because somebody has open-sourced their game does not mean they wrote code that is particularly good. They could've been using AGS for 20 years and use obsolete stuff a lot.

The best way to learn AGS imo is to 1) do the tutorial in the manual 2) read the scripting API section from top to bottom (multiple times) 3) browse the beginner's technical forum for interesting questions.
#215
The manual entry https://adventuregamestudio.github.io/ags-manual/Object.html#objectsolid does say
Code: ags
bool Object.Solid
but that means that .Solid is a bool property, i.e. either true or false.

Further down is a usage example which reads
Code: ags
oSmallrock.Solid = true;
#216
Afaik, the most important thing you have to do is enable the "run game loops..." option in General Settings -> Dialogs.
Otherwise, many Global script functions won't run during a dialog, since the game is effectively paused.
#217
As you found out the position doesn't matter, the script parser doesn't care about the spaces. You can even do Button*button; without any space.

I put the asterisk right after the pointer type because I'm a) declaring pointers b) might declare multiple ones.
I.e.
Code: ags
Button* b1, b2, b3;
declares three Button pointers, all of which would require an asterisk if I declared them in individual lines, so putting it at the start makes sense as opposed to Button *b1, b2, b3;
The asterisk is part of the type if you will so that's where it goes in my book.
#218
There's no simple solution I'm afraid.

You have two options:
1) keep using regions and change action_label.Text to an exit name using code
2) use hotspots instead and mark them as exits, then handle the click differently

Both methods require storing extra information. With regions you need to assign them a name manually, for instance in room_Load since they have neither descriptions nor custom properties. With hotspots you need to add a custom property like a boolean "isExit" and set that to true.

While I prefer to use regions for exits, I guess in this situation hotspots make more sense.

1. Select the hotspot in the editor. In its Properties, select Properties in the Properties section (;)) then click the ellipses button.
In the window that pops up, click the Edit Schema button and in the new window, right-click the blank table and select "Add new property...".
Name: isExit
Type: Boolean
Default value: 0
Applies To: hotspots only
Click OK, then Close.
In the current window, double-click the cell showing False to change it to True, then click Close.
(the very first and last line of step 1. need to be repeated for every exit hotspot obviously)

2. Right-click the Scripts node in the project tree and pick "New Script", enter "ExitHandler" as the name.
Double-Click "Edit Script" below its node to open the script.
Paste the following function into the script:
Code: ags
void on_mouse_click(MouseButton button) {
  int mx = mouse.x, my = mouse.y;
  Hotspot* h = Hotspot.GetAtScreenXY(mx, my);
  if (button == eMouseLeft && h != null && h.GetProperty("isExit")) {
    ClaimEvent();
    player.Walk(mx, my, eBlock);
    h.RunInteraction(eModeInteract);
  }
}

This code will make the player walk to the clicked spot blocking, then run the hotspot's interact function. Simply put your ChangeRoom line in there.
#219
You're on the right track but you don't have code that resets the text.
You need a variable that retains its value so you can track whether the mouse has moved over or away from the label since the last frame.
Here's one solution:

Code: ags
// above repeatedly_execute
bool mouseWasOverSelect; // no initial value -> false

  // inside repeatedly_execute
  GUIControl* gc = GUIControl.GetAtScreenXY(mouse.x, mouse.y);
  bool mouseIsOverSelect = gc != null && gc.AsLabel == Label3;

  if (!mouseWasOverSelect && mouseIsOverSelect) Label3.Text = "Interact";
  else if (mouseWasOverSelect && !mouseIsOverSelect) Label3.Text = "Select";

  mouseWasOverSelect = mouseIsOverSelect;
#220
If it takes almost an hour with a walkthrough, it's at least as long as Day of the Tentacle :)

Anyway, three slots sounds fine for the type of game you describe.

To do this, have each button's click
a) store the slot in a global variable
b) show a 2nd GUI with load/save/delete buttons
These buttons in turn will do the appropriate thing based on the stored slot number: 1, 2 or 3.

You can use for instance Game.GetSaveSlotDescription(1) != null to check if slot #1 exists,l then simply not display the load and delete buttons when you setup the GUI and then turn it visible.

You can use a variable to find out if the game has started yet: simply declare a bool like game_has_started, then set it to true in the first room. That way you can do if (game_has_started) during the savegame GUI setup.
SMF spam blocked by CleanTalk