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

#41
You can use a sine wave for this:

Code: ags
float angle;

function repeatedly_execute_always {
  angle += 0.03;
  if (angle > Maths.PI * 2.0) angle -= Maths.PI * 2.0;
  oHoverboard.Y = 120 + FloatToInt(Maths.Sin(angle) * 10.0, eRoundNearest);
}

(Just add this to your room script and adjust the object's script name and initial y coordinate of 120.)
#42
The error is "unexpected end of file", not line.

Anyway, you forgot a closing ) in line 18.

Code: ags
// Dialog script file 
@S // Dialog startup entry point
return 
@1
 cKaren.SayBubble("Morning Chief!");
 cRubin.SayBubble("Good morning Karen.");
 cKaren.SayBubble("I hope you feel well.");
 cRubin.SayBubble("Thanks Karen. I feel ok. You wanted to talk about something?");
 cKaren.SayBubble("Yes, about the promotion you promised me.");
 cRubin.SpeechView = 12;
 cRubin.SayBubble("You are right, but I need another favor first. Since Harlin Sway died during a ...");
 cRubin.SpeechView = 9;
 cKaren.SayBubble("Well, good. But you will promote me right?.");
 cRubin.SayBubble("You can count on it.");
 cKaren.SayBubble("I should be on my way then!");
 cRubin.SayBubble("Alright.");
option-off 1
option-on 2
return
@2
 cKaren.SayBubble("Can I have the case file?");
 cRubin.SayBubble("yes. Her it is");
option-off 2
return
@3
 cKaren.SayBubble("See you Chief."); 
 cRubin.SayBubble("See you Karen");
stop
#43
Here's how to get the perspective corrected distance in pixels between two characters:

Code: ags
int DistanceFrom(this Character*, Character* other) {
  float dx = IntToFloat(this.x - other.x), dy = IntToFloat(this.y - other.y) * 1.5; // account for foreshortening
  return FloatToInt(Maths.Sqrt(dx * dx + dy * dy), eRoundNearest);
}

I'm assuming the main issue is that you're calling the FollowCharacter command more than once or something like that.
Code: ags
bool enemy_is_following;

function Room_RepExec() {
  if (!enemy_is_following && cEnemy.DistanceFrom(player) < 50) {
    cEnemy.FollowCharacter(player);
    enemy_is_following = true;
  }
}

And like CW says, please always post your own attempt; this is helpful for us because among other things we can judge how much assistance you need based on what you tried.
#44
Quote from: trevbot on Thu 17/04/2025 08:45:58Would I want to call this from the click event that opens the restore GUI?

...yes, but that is kind of the wrong question. The correct way to use the function is to go to wherever you've put
Code: ags
  gRestoreGame.Visible = true;
and instead call
Code: ags
  show_restore_game_dialog();

The BASS template (and others) have a bunch of convenience functions. If you got rid of all of them, you'd end up with having to manually add
Code: ags
  lstRestoreGamesList.FillSaveGameList();
  TwoClickHandler.Close();
  mouse.UseModeGraphic(eModeWalkto);
  gRestoreGame.Visible = true;
each time you want to let the user load a game.

The custom function show_restore_game_dialog (and also open_gui) was added by the creator(s) of the template so you don't have to deal with all that. You just add your button or your keyboard shortcut, call show_restore_game_dialog() in the handler code and that's it.
#45
This function is a custom one, not one of the engine ones like repeatedly_execute(). It is thus never called by the engine.
In the Sierra template it is called when you click the restore game button, and in on_key_press when a F7 keypress is handled:

Code: ags
function btnIconLoad_Click(GUIControl *control, MouseButton button)
{
  show_restore_game_dialog();
}

You can find these spots by right clicking the declaration and selecting "Find all usages".
#46
Provided you've used mostly standard events, the main thing you need to import from the BASS template is the on_mouse_click function.
If you set it up so that a left click checks GetlocationType() and runs the interact event on hotspots and objects and the talk to event on characters, you're probably 90% there.
The Useinv event shouldn't really need any work at all, you'll only need the BASS inv GUI. You can however alter the existing Sierra GUI for that. Remove the buttons that switch cursor modes and replace them with an inv window.
#47
General Discussion / Re: Trumpmageddon
Wed 16/04/2025 00:58:24
They also deported a 19-year old without priors or tattoos who wasn't on their list. One ICE agent just said "take him anyway" and off he went to the torture prison in another country.

It's also extremely irritating to see how conservatives keep framing the backlash as wanting "terrorists to roam free" or whatever when the actual objections are about something else entirely: the erosion of due process and the black-bagging of completely innocent people. It's insane to see how bloodthirsty morons keep defending Trump instead of realizing that they or one of their loved ones could literally be next and that's it for them, gone. No lawyer, no judge, nothing. You don't even get to return from the death camp after your government officially acknowledged it made a mistake because the fascist who rules the other country doesn't want to "smuggle terrorists into the U.S.".
Makes you want to scream.

The only tiny sliver of hope is that since the floodgates have so thoroughly burst already, since it's happening in bright daylight and out in the open, that maybe, just maybe, enough people will realize in time what is happening.
#48
Use debugging: add a GUI that is always visible, put a label on it, then put a suitable line in repeatedly_execute.

Like
Code: ags
function repeatedly_execute_always() {
  lblDebug.Text = String.Format("X difference is: %d", oAttackRIGHT.X - (oLaserRIGHT.X + 75));
}

This should read "X difference is 0" at some point.

Some unrelated tips regarding your code:
Spoiler
1.
oLaserLEFT.Visible == true
is an expression that is evaluated to the exact same value as
oLaserLEFT.Visible

That's because "false == true" is false, and "true == true" is true. So you can just get rid of the "== true" part.

2. Instead of assigning a random value to L, then using three if lines for the delays of 1, 2 or 3 seconds, you can simply do:
  SetTimer(3, (Random(2) + 1) * GetGameSpeed());

First add one to the random value to shift the range from 0-2 to 1-3. Then multiply by 40 / the game's FPS value to get to actual seconds. Any literal number in your code can be replaced with a mathematical expression, and those in turn can contain function calls that return numbers.

3. The code where you position the attack objects and start their times repeats verbatim in your code. You should move it to a custom function and call the function instead. This drastically reduces the possibility of typos and makes your code easier to adjust/fix because you only have to do it in one place.
[close]
#49
The lines also have to be indented correctly for this to work:
Code: ags
  if (game.score >= 10) {
    player.ChangeRoom(X);
  } else {
stop
  }

stop is a dialog script command and therefore the only line that cannot be indented. All others have to be indented by at least one space.
#51
I didn't though.

And in no way did I want to encourage anybody to delete their image files after importing them; it was only supposed to emphasize the fact that they are not required to edit or run a game.

I was under the impression that OP thought they had to keep the files around locally on their computer or "crash the system" so I wanted to drive home that's absolutely not the case.
#52
Once you import a sprite, it ends up in a file called acsprset.spr and the external file is no longer needed. It can in theory be deleted. Room backgrounds are stored in the *.crm files.
Both sprites and room backgrounds can even be exported to the hard drive, should you lose the original image file.

I'm not 100% sure about audio files but afaik these get copied into the AudioCache folder in your game folder.

In general, all files needed to compile/run the game are kept inside the game's folder.

Which means while I wouldn't recommend keeping the game folder itself on removable storage, it's perfectly fine to do that with all external resources.
#53
Right, I'm not sure rep_ex_always runs during dialogs. You'll probably have to turn on the respective option in General Settings / Dialog for that but I'm too lazy to check this myself.

Anyway, I'd use a different approach. Speech animation is hard-coded by AGS to either use a loop's frames in order or to use specific frames for specific letters.
To achieve a custom animation, you need to use SayBackground(). Something like this:

Code: ags
function Skitt_Shocked(String message) {
  Overlay* skitt_speech = cSkitt.SayBackground(message);
  cSkitt.LockView(SKITT_SHOCKED);
  cSkitt.Animate(cSkitt.Loop, 2, eOnce, eBlock);
  cSkitt.LockView(SKITT_TALK);
  cSkitt.Animate(cSkitt.Loop, 2, eRepeat, eNoBlock);
  while (skitt_speech.IsValid) Wait(1);
  cSkitt.UnlockView();
}

In your dialog script, use
Code: ags
  Skitt_Shocked("Waaaaaaaah!");
#54
The Animate call is non-blocking but you have a .Say() immediately after that. How exactly does that play out in-game?
Which frames are used when the character says "Waaaaaaaah!"?

Also, a better way to approach this might be for you to describe the desired goal, because this sounds suspiciously like an xy problem.
#55
Again, please mention the template. If it's the Sierra template, you can click on the arrow button below the inventory items to deselect the current item.
By scroll bar, did you mean the icon bar up top?
#56
Please always mention which game template you've used, that makes questions like this easier to answer.

My guess is you're using the Sierra template, and clicking one of the two load game buttons on the GUIs will ultimately call this function:
Code: ags
function show_restore_game_dialog()
{
  lstRestoreGamesList.FillSaveGameList();
  open_gui(gRestoreGame);
}

Your room hotspot/object should also call this function. Calling a custom global function from a room script requires importing it; this can be achieved by adding this line to the Global Script's header:

Code: ags
import function show_restore_game_dialog();

Now you can use this line in your room script:
Code: ags
  show_restore_game_dialog();

To disable a key in a specific room, you can also intercept the key press event. Add this to the room script:

Code: ags
function on_key_press(eKeyCode keycode, int mod)
{
  // disable global Escape handling
  if (keycode == eKeyEscape)
  {
    ClaimEvent(); // stop AGS from calling any global on_key_press functions
  }
}

--

It might not be obvious why doing all of this is preferable, so I'll briefly explain:

Should you ever have to adjust the code that prepares and displays the load game GUI, you can still do it in a single place and won't have to worry about remembering all the various places in your scripts where you might have put a bunch of identical lines.

Disabling the key is done completely locally, and the global script remains untouched. This is always preferable for room-specific code, because again, any future changes will not affect any other rooms or global behavior unintentionally.
#57
First of all, this:
Code: ags
  if (GetLocationType(mouse.x,mouse.y) > 0) {

might cause issues. Afaik, enum values start at 1 by default, so unless set to 0 by the engine explicitly, eLocationNothing might have a value > 0.
To be safe, change this to
Code: ags
  if (GetLocationType(mouse.x,mouse.y) != eLocationNothing) {

Next, the exit arrow stuff doesn't require code in every room if you use a hotspot custom property. Global behavior should never be implemented on a per-room basis, that's just loads of duplicate code. If you use a second property to store the room number the exit is leading to, you don't even need to have event functions for the exit hotspots, just some global code that detects a click on an exit.

Anyway, as far as I can tell you're using just eModeInteract and eModeUseinv and keep changing the cursor sprite.
This approach is fine but could be streamlined a great deal.
For instance the cursor sprite can simply be changed by using Mouse.ChangeModeGraphic(CursorMode, int slot); there's no need to set up custom cursors just to use their assigned sprite.
#58
I was only checking the downloads because of this post:

https://www.adventuregamestudio.co.uk/forums/beginners-technical-questions/just-starting/msg636682660/#msg636682660

Anyway, the downloads are working fine now so it seems to be resolved.
#59
The HandleCursor function tracks changes in LocationType. Each time the mouse leaves or enters an active area, the relevant block is triggered and changes the cursor accordingly.

For a first-person game that doesn't use eModeWalkto, the code needs to be adjusted accordingly.

You said the cursor is supposed to be a hand over objects and the like, and a pointer sprite is used for walking around. How did you implement room changes? Because if room exits are hotspots, how does the game differentiate between exits and other hotspots? And which event are you using to process clicks? AnyClick? Or Interact?
#60
Not saying this isn't a bug, but please post line 483 and surrounding ones.
SMF spam blocked by CleanTalk