How to play sound files with python?

ah... how can I play a sound only for the player (e.g. pPlayer)?
 
I'm not sure if this will work in your situation, but you could try CyInterface.addMessage() and pass "" for szString while disabling everything else. As long as it doesn't display an empty line at the top of the screen for the empty string passed to it. It should work OK.
 
I guess that you have some event which could happen for any player, and you have made this event play a sound, but this sound plays even when the event happens for an AI, or some other human during MP. So you want the sound to play only when the event happens for the active player. Can you add "if iPlayer == gc.getActivePlayer().getID()" ?
 
So you want the sound to play only when the event happens for the active player.

No, only the player who has fired a special event shall hear the sound. Your condition would not change the sound behavior. It does not matter which player is active.

General Tso's solution came into my mind, but there should be an empty line at the top of the screen. I should test it and report back.
 
You did not get it. ;) It does not matter who is triggering the event, everybody will hear the sound since the sound itself will not be fired for the triggering player only. The code above is playing the sound for ALL players. Only the message could work, not tested yet.
 
Where are you triggering the sound? Are you sure you are only triggering it on the PC of the player you want to hear it?
 
??? No, that's exactly the point. I WANT it triggering only on the pc of the player, not on other pcs. But there seems to be no simple sound command for that without using a message snippet.

I guess my English is too bad to explain. :-/

CyInterface().playGeneralSound("AS2D_PEACE")
will play the sound for all players not only for the triggering one. I have tested it. When the AI is triggering, I will also hear the sound (and all other human players in multiplayer games).
 
What I'm asking is where is the above Python code? In an event? If so, which one? Be very, very specific. Maybe show more than one line of code for context. :p
 
Does it matter? def onBuildingBuilt(self, argsList) for example.

If pPlayer has built a wonder, pPlayer shall hear a sound - and nobody else.

or

If pPlayer has built a wonder, only pPlayer and all players who already have met pPlayer shall hear the sound.


Do you get it? The code above plays sound - for all players. Therefore it does not matter where this code is written in.

This is no problem for singleplayer games.

PHP:
			pPlayer = gc.getPlayer(pCity.plot().getOwner())
			for iPlayerLoop in xrange(gc.getMAX_CIV_PLAYERS()):

				pPlayerAnthem = gc.getPlayer(iPlayerLoop)
				iPlayerAnthem = pPlayerAnthem.getID()
				iTeamAnthem = pPlayerAnthem.getTeam()

				if pPlayerAnthem.isHuman() and gc.getTeam(pPlayer.getTeam()).isHasMet(iTeamAnthem):

But in multiplayer... all human players would hear the sound, no matter if all of them have met the builder of the wonder.

Also, with this code and with two human players, you would hear the sound twice (and so on).

Because the code above plays the sound for all players.
 
Do you understand that onBuildingBuilt is fired on every PC--regardless of who built the building? Unless your event handler compares the owner of the city that built the building against the active player, you will play the sound on every PC.

This is why I'm asking for the whole function--not just the part that plays the sound. I see nothing in your latest code that checks for the active player--the one sitting at the PC. This code will run on every PC which causes everyone to hear the sound.

You probably want something along these lines:

Code:
pActivePlayer = gc.getActivePlayer()
if gc.getTeam(pActivePlayer.getTeam()).isHasMet(pCity.getTeam()):
    # play the sound

The active player is always human (AIAutoPlay notwithstanding) so there's no need for a check for that here.
 
Won't this play the sound for ALL players if only ONE human player has met the builder?

The command itself has no "play sound X for player Y", it's just "play sound X".#

Other commands are more specific, for example:

PHP:
CyInterface().addMessage(pPlayer.getID(), True, 20, strMessage, "", 0, gc.getBuildingInfo(pB).getButton(), ColorTypes(8), pIndCity.getX(), pIndCity.getY(), True, True)

Will message pPlayer but no other players.


For better understanding:

PHP:
CyInterface().playGeneralSound("AS2D_PEACE")
is comparable to
PHP:
CyInterface().addImmediateMessage( szTitle , None)
which is messaging ALL players.
 
Sorry, but ... can you add "if iPlayer == gc.getActivePlayer().getID()" ?

As EF has pointed out, onBuildingBuilt is fired on all PC's when the active player builds the building. However, on all the other PC's, this if statement will evaluate false and no sound will be played. I know you don't believe me, but could you try it?

In the OP, you did not mention the part about playing the sound on PC's of other players who have met the building player; but once you believe me that getActivePlayer is needed, then you can probably add an "or" clause to the above to see if the player on this PC has met the active player.
 
I'd bet $5 that addImmediateMessage() shows only for the active player. This function and playGeneralSound() do not send network messages to the other players. They operate only on the PC where they run. The problem you're having which davidallen and I keep reiterating is that you are running this code on every PC.

In order to limit who hears it to a single player, you must compare the player against the active player as we has shown. Think of it like this: you gather a large group of people and say, "if your name is Bob, raise your hand." Everyone will follow your instructions (run the code), but only those that match the criteria (if check) will take the action (play the sound).

I really don't know how I can be any more clear than this. Please, just try it as we've written.
 
This now WAS clear. :) I have tried it out and it works like a charm. Thank you both. There was a barrier in my brain. :)

PHP:
			pActivePlayer = gc.getActivePlayer()
			if gc.getTeam(pActivePlayer.getTeam()).isHasMet(pPlayer.getTeam()):

is perfect. :)
 
Do you know a difference between CyAudioGame().Play2DSound and CyInterface().playGeneralSound?
 
I would expect Play2DSound() to take an x and y coordinate pair just as Play3DSound() takes x, y, and z. I have no idea if the docs are bad or BTS is just that lame. If the former, this allows you to place a sound on the map so it gets louder as you scroll the screen to have that tile in the center of the screen, just as you hear jungle sounds when you scroll jungle tiles into view, etc.
 
Play2DSound() takes an Audio 2D Script (defined in Audio2DScripts.xml).

Play3DSound() takes an Audio 3D Script (defined in Audio3DScripts.xml) and the NiPoint3 coordinates of a plot (pPlot.getPoint()).

That's the only difference- according to the API.
 
Back
Top Bottom