random music with ClientSetMusic method

Discussions about Coding and Scripting
Post Reply
User avatar
UTPe
Masterful
Posts: 584
Joined: Sun Jul 12, 2009 7:10 pm
Personal rank: Dude
Location: Trieste, Italy
Contact:

random music with ClientSetMusic method

Post by UTPe »

Hello,
I'm editing an existing mutator (just a single class) to build a kind of simple LobbyMusic mutator, that shutdowns map music and starts a new music when game ends and mapvote shows up.
this is the working code for a single music:

Code: Select all

class LobbyMusic extends Mutator;

#exec NEW MUSICFACTORY FILE=Music\song1.wav NAME=song1

var bool LobbyMusicIsOn;

function PostBeginPlay()
{
	SetTimer(4.0,true);
}

function bool AlwaysKeep(Actor Other)
{
	if (NextMutator != None)
		return (NextMutator.AlwaysKeep(Other));

	return false;
}

function Timer()
{
   if (Level.Game.bGameEnded)
	{
		if (LobbyMusicIsOn == False)
		{
			ShutDownLevelMusic();
			LobbyMusicIsOn=True;
		}
	}
}

function ShutDownLevelMusic()
{
   local Pawn A;

   A = Level.PawnList;
   While (A != None)
   {
      if (A.IsA('PlayerPawn'))
         PlayerPawn(A).ClientSetMusic(Music'song1', 0, 255, MTRAN_Fade);
      A = A.nextPawn;
   }
}

defaultproperties
{
   LobbyMusicIsOn=False
}
Then I tried to add more than a single background music in order to have random music when game ends, but in this case I have problems while compiling.
I'm not a programmer with a good knowledge of UnrealScript so I can't understand the type of error. This is the code:

Code: Select all

class LobbyMusic extends Mutator;

// #exec NEW MUSICFACTORY FILE=Music\song1.wav NAME=song1

#exec NEW MUSICFACTORY FILE=Music\song0.wav NAME=song0
#exec NEW MUSICFACTORY FILE=Music\song1.wav NAME=song1
#exec NEW MUSICFACTORY FILE=Music\song2.wav NAME=song2
#exec NEW MUSICFACTORY FILE=Music\song3.wav NAME=song3

var bool LobbyMusicIsOn;
var int cSong;
const nSongs = 4;
var string sSongs[4];

sSongs[0]=song0;
sSongs[0]=song1;
sSongs[0]=song2;
sSongs[0]=song3;

function PostBeginPlay()
{
	SetTimer(4.0,true);
}

function bool AlwaysKeep(Actor Other)
{
	if (NextMutator != None)
		return (NextMutator.AlwaysKeep(Other));

	return false;
}

function Timer()
{
   if (Level.Game.bGameEnded)
	{
		if (LobbyMusicIsOn == False)
		{
			ShutDownLevelMusic();
			LobbyMusicIsOn=True;
		}
	}
}

function ShutDownLevelMusic()
{
   local Pawn A;

   A = Level.PawnList;
   While (A != None)
   {
      if (A.IsA('PlayerPawn'))
         // PlayerPawn(A).ClientSetMusic(Music'song1', 0, 255, MTRAN_Fade);
	 cSong = rand(nSongs);
         PlayerPawn(A).ClientSetMusic(sSongs[cSong], 0, 255, MTRAN_Fade);

      A = A.nextPawn;
   }
}

defaultproperties
{
   LobbyMusicIsOn=False
}
I would need a little help. thanks in advance.

cheers,
Pietro
Personal map database: http://www.ut99maps.net

"These are the days that we will return to one day in the future only in memories." (The Midnight)
User avatar
Barbie
Godlike
Posts: 2808
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: random music with ClientSetMusic method

Post by Barbie »

Code: Select all

sSongs[0]=song0;
sSongs[0]=song1;
sSongs[0]=song2;
sSongs[0]=song3;
That should go into some function, for example into PostBeginPlay(). Also it should be like

Code: Select all

sSongs[0]=song0;
sSongs[1]=song1;
sSongs[2]=song2;
sSongs[3]=song3;
Also the declaration var string sSongs[4] should be of type "Music" if you want to use it in Class'PlayerPawn'.ClientSetMusic(). But then WAV files do not fit, IMO you have to use UMX files.


"function AlwaysKeep" can be removed, it does nothing other than its parent function:

Code: Select all

function bool AlwaysKeep(Actor Other)
{
	if (NextMutator != None)
		return (NextMutator.AlwaysKeep(Other));

	return false;
}

Here you have an error in defining a block. Instead of

Code: Select all

While (A != None)
  {
    if (A.IsA('PlayerPawn'))
      // PlayerPawn(A).ClientSetMusic(Music'song1', 0, 255, MTRAN_Fade);
      cSong = rand(nSongs);
    PlayerPawn(A).ClientSetMusic(sSongs[cSong], 0, 255, MTRAN_Fade);
    A = A.nextPawn;
  }
you should use

Code: Select all

While (A != None)
  {
    if (A.IsA('PlayerPawn'))
    {
      // PlayerPawn(A).ClientSetMusic(Music'song1', 0, 255, MTRAN_Fade);
      cSong = rand(nSongs);
      PlayerPawn(A).ClientSetMusic(sSongs[cSong], 0, 255, MTRAN_Fade);
    }
    A = A.nextPawn;
  }
Do you see the difference?
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
UTPe
Masterful
Posts: 584
Joined: Sun Jul 12, 2009 7:10 pm
Personal rank: Dude
Location: Trieste, Italy
Contact:

Re: random music with ClientSetMusic method

Post by UTPe »

Hello Barbie, thanks for your comments.
yeah, I noticed soon some errors I've made just after having posted the code (i.e. the multiple [0] index and the type of data for sSongs variable).
thanks for the correction about the function AlwaysKeep (I didn't touch this part of the code) and yes, I can see the difference about nextPawn method (this is called anyway but the music is changed only if the object is a PlayerPawn).
sorry but I'm not a coder, I don't know UnrealScript and I have some problems when I put my hands in code.

ok, I've corrected class code but mutator doesn't work anyway: the map music is shut down but new music is not played.
Attachments
source_code.zip
(698.44 KiB) Downloaded 3 times
Personal map database: http://www.ut99maps.net

"These are the days that we will return to one day in the future only in memories." (The Midnight)
User avatar
Barbie
Godlike
Posts: 2808
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: random music with ClientSetMusic method

Post by Barbie »

UTPe wrote: Tue Sep 12, 2023 10:54 am ok, I've corrected class code but mutator doesn't work anyway: the map music is shut down but new music is not played.
Ofc the clients need the music - either you can convert WAV into UMX and put the UMX files into server's "ServerPackages" or even the mutator itself.
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
UTPe
Masterful
Posts: 584
Joined: Sun Jul 12, 2009 7:10 pm
Personal rank: Dude
Location: Trieste, Italy
Contact:

Re: random music with ClientSetMusic method

Post by UTPe »

this mutator was not meant to work in this way.
as I wrote above, the first version of the mutator, that with a single .wav music file, worked well (i compiled a .wav file present in the Music subfolder in the final .u package and the music played well on the server). with the clients, I share only the mutator (LobbyMusic.u package, i.e. ServerPackages=LobbyMusic), which contains the music (no external .umx files needed)

this is the line of code in the fisrt (working) version of the mutator:

Code: Select all

PlayerPawn(A).ClientSetMusic(Music'song1', 0, 255, MTRAN_Fade);
this is the same line in the second (not working) version (random music):

Code: Select all

PlayerPawn(A).ClientSetMusic(sSongs[cSong], 0, 255, MTRAN_Fade);
where sSongs[cSong] gets one of these values specified in the .ini config file:

Code: Select all

[LobbyMusic.LobbyMusic]
sSongs[0]=song0
sSongs[1]=song1
sSongs[2]=song2
sSongs[3]=song3
the grammar Music'song1' is not equal to song1 ...might this be the problem ?
when I'm on server, I can notice well that the music fade process is executed but the new music is not played, as it's not present or can't be found by engine (sorry but I can not explain better than this)
Personal map database: http://www.ut99maps.net

"These are the days that we will return to one day in the future only in memories." (The Midnight)
User avatar
sektor2111
Godlike
Posts: 6413
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: random music with ClientSetMusic method

Post by sektor2111 »

I think the function for music would need to be "simulated" and probably declared in replication and maybe the song as well. When this is called (mutator running in server), I think client doesn't know what server does and... server won't run any music after all, this is all client side stuff. Me one I would use it like I did with lightning things in the past. Spawning a "notifier" for each player and notifier goes active only in client picking a music from what server says... or simply dealing itself with one from internal assets.
Deal #2 - I'm not sure if importing a WAV generates an UMX and not just a sound which is UAX. UMX types (even if are added as U packages) I think have other importing formats, perhaps what you imported is UAX - sound type, not music type. I might be wrong here, but I would not do it this way. If you check in Editor Importing Music section from Browser, it doesn't include WAV (I think not even in 469d_RC2 - here is image from there)
MusicImport.PNG
And then ? And then my importing directives would be different. Creating first required UMX files and then importing them in mutator's package using said "EXEC" directives but claiming as music packages mutator itself, not other files.
Look what I got in Editor when I tried a WAV import in music browser - 469d RC2

Code: Select all

Log: FactoryCreateBinary: Music with MusicFactory (0 0 c:\Documents and Settings\Nelson\My Documents\Downloads\On_TV_-_Just_A_Dream.wav)
DevMusic: Prepare loading music: Music On_TV_-_Just_A_Dream.OnTVJADrm
DevMusic: Load music: Music On_TV_-_Just_A_Dream.OnTVJADrm
DevMusic: Failed loading music: Music On_TV_-_Just_A_Dream.OnTVJADrm
See "failed" word ? It's a clear NO WAY.

By example, this is something like importing some packages in main package which will have all assets embedded without to use any more those "source" packages. These source packages can be any UT known type. You can go this way with UMX files that are verified first.

Code: Select all

....
#exec obj load file=..\System\PupaerUT.u package=P_ICREDONE(REX) group=Creatures
#exec obj load file=..\System\Ns_Lamps.u package=P_ICREDONE(REX) group=Lampons
....
Deal #3
The other way would be looking at code from "MusicEvent" stock actor. This is a mapping actor but it might be done a clone that spawns on demand and running certain track embedded - here I think replication might need to be used - I did not fully test these because I really don't have any music running from UT just external devs with my favorites songs more or less adjusted (normalized, spam silence deleted, etc.)
User avatar
Barbie
Godlike
Posts: 2808
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: random music with ClientSetMusic method

Post by Barbie »

sektor2111 wrote: Tue Sep 12, 2023 6:57 pm Deal #2 - I'm not sure if importing a WAV generates an UMX and not just a sound which is UAX.
See what Wormbo has written in Wiki:
Wormbo: I just found out you could import music into .U files with this line in a .UC file:

Code: Select all

#exec NEW MUSICFACTORY FILE="..." NAME="..."
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
sektor2111
Godlike
Posts: 6413
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: random music with ClientSetMusic method

Post by sektor2111 »

In order to believe what wiki was talking at random, I would like to do an experiment/check/verification.
If package with music is being compiled there are certain things to do:
- Open UCC.LOG for figuring "warnings" - a warning means the most of time a screwed up package;
- Open said package in Editor and... try play music/sound whatever Texture examination if all import is normal.
If music doesn't play, it might be missing from mutator's structure or it is badly messed up. Me one I tried to import said wav and I got nothing else than a failure.
Why not just doing required UMX files and importing them as internal assets after checking them ? What does it hurt at this point ?
In 469 you can use even OGG files which are not a big deal after all, I had such files since years.

EDIT:Oh Yeaaah... sure it "works"...
After generating an U package having 20 MB, I loaded supposed music (imported as WAV by the way) and... I got the best of silence :ironic: .
like this:

Code: Select all

Log: Loading class from D:\Editor\UnrealTournament\System\MusicTest.u...
DevAudio: Galaxy SetViewport: U2Viewport0
DevMusic: Load music: Music MusicTest.TestMe
Warning: glxLoadMusic(&Mem, GLX_LOADFROMMEMORY ) failed: 15
Package has only spam data because right now I think UT doesn't import as MUSIC anything else than it can process, the rest it's a cheap fake story. Entertaining thing it's that UCC.Log did not say anything bad at this point, but compiled package it's just a big garbage-can which is very successful - like a real star :lol2: .

Code: Select all

Log: Save=83.574012
Log: Moving 'Save.tmp' to 'MusicTest.u'
Log: Success - 0 error(s), 0 warnings
My conclusion from my end: In UT a WAV file won't generate Music, only required formats that are known as resources.
Post Reply