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 - Crimson Wizard

#1301
It should be :
Code: ags
AudioClip *clip = System.AudioChannels[i].PlayingClip;

My typo was only in "AudioChannels" word, so I posted only that fixed part last time. But the full assignment of "clip" variable is still necessary.
#1302
Quote from: Ghostlady on Mon 27/05/2024 06:25:29Where does this part of the code go? I have it in the Repeatedly Execute function but still getting an error about nested functions.

Functions must be outside of other functions. You don't need to put anything inside "Repeatedly Execute". Just place the code into the Global Script, anywhere outside of other functions.

My code example has 2 functions: "IsAnySoundPlaying()" and "repeatedly_execute_always()". The latter is a standard function and may be already present in your Global Script. If you do already have it, then append my code from "repeatedly_execute_always" to the end of yours.
#1303
It should be
Code: ags
System.AudioChannels[i].PlayingClip;

I made a typo in my code above.

The related articles in the manual that may be used for double checking the code:
https://adventuregamestudio.github.io/ags-manual/System.html#systemaudiochannels
https://adventuregamestudio.github.io/ags-manual/AudioChannel.html
https://adventuregamestudio.github.io/ags-manual/AudioClip.html
#1304
Quote from: Ghostlady on Mon 27/05/2024 05:16:21Nested functions not supported (you may have forgotten a closing brace)

This means that you placed this whole code inside another function. Each function must be separate.
#1305
Quote from: Ghostlady on Mon 27/05/2024 03:47:26I added the second script to the global script where you stated and I get an error message:

This is some error in the Editor, but it's likely not related to the script at all. Could be a random glitch related to the open panels.

Could you try again?
#1306
Quote from: FortressCaulfield on Sun 26/05/2024 20:36:01So it converts the talk into an interact? That's annoying. Wish we had more access to core functions so we could tweak things like that.

You do have an option to fine tune the interaction behavior if you don't rely on "unhandled_event" but script your own interaction logic. Normally this is done with the help of GetLocationType and IsInteractionAvailable functions in on_mouse_click:
https://adventuregamestudio.github.io/ags-manual/Globalfunctions_General.html#getlocationtype
https://adventuregamestudio.github.io/ags-manual/Globalfunctions_General.html#isinteractionavailable

function like Object.GetAtScreenXY, and similar, can be useful in this too.

For a quick example:
Code: ags
function on_mouse_click(MouseButton button)
{
     if (button == eButtonLeft)
     {
          if (IsInteractionAvailable(mouse.x, mouse.y, mouse.Mode))
          {
              Room.ProcessClick(mouse.x, mouse.y, mouse.Mode);
          }
          else
          {
              // do your custom "unhandled interaction" handling
          }
     }
}
#1307
Quote from: Snarky on Sun 26/05/2024 06:33:50Converting the strings to and from Unicode falls outside the plugin scope, I think (I have some notion that the Windows clipboard itself is responsible for converting between compatible formats), but the plugin might either provide two versions of the Copy/Paste functions, or if there is an API for it, detect whether AGS is using Unicode mode.

I mean, you would have to convert to UTF-8 strings anyway if you want engine to understand your text, because widestring WinAPI uses Unicode-16 format.

In WinAPI utf-8 strings are called "multibyte" strings, and it provides conversion functions for getting utf-8 from widestrings.

EDIT: alternatively, there's a platform-independent way, like we have in the engine:
https://github.com/adventuregamestudio/ags/blob/860a4d1319ba76cfba1b3fdb52fcc64e1fe92d18/Common/util/string_utils.cpp#L317-L327
https://github.com/adventuregamestudio/ags/blob/860a4d1319ba76cfba1b3fdb52fcc64e1fe92d18/Common/util/utf8.h#L86
#1308
Quote from: Snarky on Sun 26/05/2024 02:43:30@Baguettator, I'm fairly sure the plugin predates Unicode support in AGS. I don't at this point know what determines how non-ASCII characters appear; I have a vague sense that it's based on the computer's language setting (codepage).

The robust solution would be an updated plugin that worked with wstrings.

If it uses ANSI functions from WinAPI, then all text is of course also stored as ANSI.

The workaround could be to add a conversion to UTF-8 strings into this plugin. Examples of this may be found in both the AGS Editor and Engine code (iirc),
This way it might also keep plugin working in both ANSI and Unicode modes, but there has to be a switch in plugin's API, or maybe plugin can get this info from the engine somehow...
#1309
Quote from: Ghostlady on Sat 25/05/2024 19:03:11I am not understanding this part of the script:

 int low_volume = 20;
        if (MusicVolumeSlider.Value < 20) // assuming you have a volume slider called "MusicVolumeSlider"
            low_volume = MusicVolumeSlider.Value;

Where is the volume slider?  Is this a global int?


This script assumes that you have created a volume slider in one of your menus, and called it "MusicVolumeSlider".
You may call it differently in your game of course.

If you do not want to create such slider, then replace this with something else, like a variable that you set when changing a volume in your menu.
#1310
TBH I'd rather suggest to go back to arrays and structs, and learn how these work, as they may be easier than doing this with a file.
#1311
The code above does not make any sense. You open the file in "Append" mode, which means that it's opened for writing at the end of existing file, but then try to read it. Of course nothing will be read.

AGS does not support opening a file in read/write mode, it's only either read or write. If you want to modify existing file after reading it, then you should first read everything from it, then open it again in write mode and overwrite the file with the modified data.

On a side note, this line:
Code: ags
palabra = String.Format("%s", f.ReadRawLineBack());
may be simplified to
Code: ags
palabra = f.ReadRawLineBack();
#1312
Quote from: Ghostlady on Sat 25/05/2024 18:06:38If I use this gui, which is the overall functional gui for both characters that drops down when rolling your mouse at the top of the screen, and add something like a Up and Down arrow or a music note and if they click on it do I need another gui with a slider?

That is a purely a question of game and gui design; for this I don't have a direct answer. You may do either, or both, as you see fit. From the script's perspective, you would need to make sure that you can read current value. If you make 2 controls, then you'll have to synchronize them somehow, like, having a global variable with this volume setting.


Quote from: Ghostlady on Sat 25/05/2024 18:06:38This would be for all sounds and music so if I use the bottom script, would I put that code in each room where I want to check for sound/music?

You only need to put this code once in the GlobalScript, and it will work for the whole game.

If, for any reason, you would like to disable this behavior for particular rooms, that may also be achieved by adding another global variable acting as a "behavior switch", and checking it prior to rest of this code in repeatedly_execute_always.
#1313
Quote from: Zrezal on Sat 25/05/2024 16:56:10The problem comes at the time of having to modify that file when I want to delete an object, it gives me an error of null referenced pointer.

You cannot write files in $DATA$ location, because that corresponds to the game package.
https://adventuregamestudio.github.io/ags-manual/File.html

If you want to write files, you will have to choose another location:
Quote$DATA$, which allows you to read files that are packaged inside the game package, originally from a directory specified in the General Settings, in the Package custom data folder(s) option, on the Compiler category. Files stored in this way can only be opened in read mode.
$INSTALLDIR$, which allows you to explicitly read files in the game installation directory.
$SAVEGAMEDIR$, which allows you to write/read files in the save game directory.
$APPDATADIR$, which allows you to write/read files to a folder on the system which is accessible by and shared by all users.

Although, I believe that in your case storing this information in variables (using structs or not) is better, because reading and writing files is slower than using variables, and also more prone to problems.
#1314
Using AudioChannel's pointer for this purpose is unreliable for multiple reasons. One of them is that AudioChannel.Volume affects only a volume of currently playing sound (or music). If player changes the slider while there's nothing playing on this channel, then nothing gets changed, and next music won't be affected. With this you would have to assign Volume each time you call Play.

Using Game.SetAudioTypeVolume is a correct way to set volume for any currently playing and future music.

For the player you may add a Slider control, and call Game.SetAudioTypeVolume when this slider changes, for example. There are of course other GUI methods, like a label with up/down or left/right arrow buttons, etc; but this is all a question of a GUI design.





In regards to lowering music's volume while a sound is playing...

If that's meant only for particular sounds, then you may write a custom function where you
a) lower music's volume
b) start the sound and save its channel in a global AudioChannel* variable
Then in "repeatedly_execute_always" check if that channel is set, and if it is no longer playing then restore music's volume to a normal value and reset the channel variable to "null".
A script example:
Code: ags
function PlaySoundAndLowerMusic(AudioClip *sound)
{
    SpecialSoundChannel = sound.Play();
    if (SpecialSoundChannel == null)
        return; // if failed to play for any reason, then stop here

    // make sure to also check the player's setting of a music's volume, otherwise we may end up
    // "lowering" it to a higher level instead
    int low_volume = 20;
    if (MusicVolumeSlider.Value < 20) // assuming you have a volume slider called "MusicVolumeSlider"
        low_volume = MusicVolumeSlider.Value;

    Game.SetAudioTypeVolume(eAudioTypeMusic, low_volume, eVolExistingAndFuture);
}

function repeatedly_execute_always()
{
    if (SpecialSoundChannel != null &&
        SpecialSoundChannel.IsPlaying)
    {
        // Restore the music's volume and reset the sound channel pointer
        Game.SetAudioTypeVolume(eAudioTypeMusic, MusicVolumeSlider.Value, eVolExistingAndFuture);
        SpecialSoundChannel = null;
    }
}


On another hand, if you want this to happen whenever any sound is playing, then, instead of having a "PlaySoundAndLowerMusic" function, you might check if any clip of type "Sound" is playing in "repeatedly_execute_always". Then it will look something like:
Code: ags
bool WasMusicLowered;

bool IsAnySoundPlaying()
{
    // we begin checking with channel 1, because channel 0 is reserved for the speech
    for (int i = 1; i < System.AudioChannelCount; i++)
    {
        AudioClip *clip = System.AudioChannel[i].PlayingClip;
        if (clip != null && clip.Type == eAudioTypeSound)
        {
            return true;
        }
    }
    return false;
}

function repeatedly_execute_always()
{
    bool any_sound_playing = IsAnySoundPlaying();
    if (!WasMusicLowered && any_sound_playing)
    {
        // make sure to also check the player's setting of a music's volume, otherwise we may end up
        // "lowering" it to a higher level instead
        int low_volume = 20;
        if (MusicVolumeSlider.Value < 20) // assuming you have a volume slider called "MusicVolumeSlider"
            low_volume = MusicVolumeSlider.Value;

        Game.SetAudioTypeVolume(eAudioTypeMusic, low_volume, eVolExistingAndFuture);
        WasMusicLowered = true;
    }
    else if (WasMusicLowered && !any_sound_playing)
    {
        // Restore the music's volume
        Game.SetAudioTypeVolume(eAudioTypeMusic, MusicVolumeSlider.Value, eVolExistingAndFuture);
        WasMusicLowered = false;
    }
}
#1315
If you need to do something on each room "enter" event, I recommend using on_event function instead:
https://adventuregamestudio.github.io/ags-manual/Globalfunctions_Event.html#on_event

But with BASS template, it needs only 1 cursor mode, so it's more convenient to simply not use a "walk to" mode at all, and use "interact" from the start.

There's a chance that above code may be not enough for you, because a cursor may switch back to "walkto" in some cases, like when deselecting an active inventory item.

Recently I fixed BASS to use Interact mode instead, that solves this problem completely, the latest source code may be found here:
https://github.com/adventuregamestudio/ags-template-source/tree/master/BASS
And template itself here:
https://github.com/adventuregamestudio/ags-templates/tree/master/Templates

If you like to see only the changes, that have to be applied to a script in the existing game:
https://github.com/adventuregamestudio/ags-template-source/commit/587f157c58fae93fa456c2c71fa741de8ac255f4
#1316
Hello.

If all of your backgrounds scale in size, then all the masks (hotspots, walkable areas, etc) must equally scale in size as well to match them.

Furthermore, if you have coordinates somewhere in script, you would have to multiply these coordinates to keep the script refer to same positions relative to the room bg.

EDIT:
Another potential issue is character walking speeds, these might have to be adjusted for the bigger rooms.
Actually, any speeds have to be scaled, since they are in pixels or pixels per game tick. For example, if you move an object step by step in script, this will have to be adjusted.
#1317
This is explained in this article in the manual:
https://adventuregamestudio.github.io/ags-manual/ImportingFunctionsAndVariables.html

Normally you should have in the global header:
Code: ags
import bool is_toast(int itemnumber);
#1318
Quote from: GooseKult on Tue 21/05/2024 15:06:35I may have figured it out, the mouse sprites get removed when you change the resolution of the game?

No, that should not happen, and I cannot recall anyone reporting a similar thing.

In regards to mouse cursor becoming invisible, something that comes to mind: if you are using "walkto" cursor mode, and set room's ShowPlayerCharacter to false, then "walkto" mode is disabled and mouse switched to the next found cursor, which may be missing a sprite. This problem was found in BASS template, for example.
#1319
Idle view works like this: it waits for IdleDelay seconds before starting, plays once, then waits for IdleDelay duration  before starting again. If you want a continuous animation, then you need to set IdleDelay to 0, but that also starts idle animation immediately when your character does not move.

If that is not what you want, you may need to script your own idle animation.
#1320
Quote from: eri0o on Mon 20/05/2024 00:18:17The point I currently am is I want to use functions from the Steam and Gog API dynamically, and I have both headers. The thing is their APIs are C++ APIs so I need to do some magic there to be able to do this and I couldn't yet figure what such magic is.

If you mean getting function pointers from dlls, that's relatively simple, but has to be done differently per platform. We use "Library" class for this in AGS:
https://github.com/adventuregamestudio/ags/blob/e4a015b53ca7b6c6b4fc633fb334c1978daba65e/Engine/util/library_windows.h#L103-L108
https://github.com/adventuregamestudio/ags/blob/e4a015b53ca7b6c6b4fc633fb334c1978daba65e/Engine/util/library_posix.h#L94-L99

SMF spam blocked by CleanTalk