Example of MP3 use with the trigger_mp3 entity

 
 
 
 
Now that we have our functions ready to use we can give as example a new trigger entity that will start the playing of a single mp3 or an array of mp3 just as the trigger_cdaudio.
 
We are going to add this in the trigger.cpp source file
 
First we create a new class :
 
//======================================================
// trigger_mp3 -play or stop a mp3 file or an array of mp3
//======================================================
class CTriggerMP3 : public CBaseTrigger//derive from this class
{
public:
void Spawn( void );
virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );//can be used or called as target
void Touch ( CBaseEntity *pOther );//start if the player cross the trigger
void KeyValue( KeyValueData *pkvd );//retrieve the values set in the map
void LaunchMP3( void );// start the process
void EXPORT HandlePlay( void );//will handle the playing of the mp3 file array, it will be called every two seconds to check
 
int PlayedTrack;//current mp3
BOOL Done;
char MP3_path[128];
};
 
LINK_ENTITY_TO_CLASS( trigger_mp3, CTriggerMP3 );
 
 
void CTriggerMP3 :: Spawn( void )
{
InitTrigger();
pev->iuser1 = 0;
//Hack to be able to save the values in the entvars of the trigger_mp3 entity
//StartTrack = pev->body
//EndTrack = pev->skin
//LoopTo = pev->effects
//Volume = pev->health
//Single = pev->sequence


//PlayedTrack = pev->iuser1
}
 
void CTriggerMP3 :: Touch ( CBaseEntity *pOther )
{
if ( !pOther->IsPlayer() )
{// only the player can trigger
return;
}
 
if ( !(pev->iuser3) )//we can trigger only once
{
LaunchMP3();
}
pev->iuser3 = 1;
}
 
void CTriggerMP3 :: Use ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
LaunchMP3();
}
 
//Now we retrieve the value taht we ca set in the map for this entity
void CTriggerMP3 :: KeyValue( KeyValueData *pkvd )
{
if (FStrEq(pkvd->szKeyName, "starttrack"))//the track to play first as integer
{
pev->body = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "single"))//number of the track that will be played only
{
pev->sequence = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "endtrack"))//last track to play
{
pev->skin = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "loopto"))//number of track to go back after the last one
{
pev->effects = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "dossiermod"))//path of the folder where are the mp3
{
pev->message = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "volume"))//volume that will be set
{
pev->health = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "priority"))//flag if this track must be played at once
{
pev->iuser2 = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else
CBaseTrigger::KeyValue( pkvd );
}
 
//Prepare the mp3 playing process
void CTriggerMP3 :: LaunchMP3( void )
{
//Definition of the mp3 path available (mod folder name/mp3folder name)
//for example : MyMod/mp3
if ( pev->sequence != 0 )//if we are in Single mode(only one track)
{
PlayedTrack = pev->sequence;//set the actual track
}
else
{
PlayedTrack = pev->body;
}
//ALERT(at_console, "MP3 Folder %s\n", STRING(pev->message));
pev->iuser1 = PlayedTrack;//save the actual track
SetThink( HandlePlay);//start the mp3 playing
pev->nextthink = gpGlobals->time + 1.0;
}
 
 
//It will be launched every 2 seconds
void CTriggerMP3 :: HandlePlay( void )
{
PlayedTrack = pev->iuser1;//to retreive to value
 
//Now we build the complete path with the folder path and the track name , there are 10 tracks available :
//From track0.mp3 to track9.mp3
 
if ( PlayedTrack == 0 )
{
strcpy(MP3_path, STRING(pev->message));//copy the folder path in the buffer
strcat(MP3_path, "/track0.mp3");//add the name path in the buffer
}
else if ( PlayedTrack == 1 )
{
strcpy(MP3_path, STRING(pev->message));
strcat(MP3_path, "/track1.mp3");
}
else if ( PlayedTrack == 2 )
{
strcpy(MP3_path, STRING(pev->message));
strcat(MP3_path, "/track2.mp3");
}
else if ( PlayedTrack == 3 )
{
strcpy(MP3_path, STRING(pev->message));
strcat(MP3_path, "/track3.mp3");
}
else if ( PlayedTrack == 4 )
{
strcpy(MP3_path, STRING(pev->message));
strcat(MP3_path, "/track4.mp3");
}
else if ( PlayedTrack == 5 )
{
strcpy(MP3_path, STRING(pev->message));
strcat(MP3_path, "/track5.mp3");
}
else if ( PlayedTrack == 6 )
{
strcpy(MP3_path, STRING(pev->message));
strcat(MP3_path, "/track6.mp3");
}
else if ( PlayedTrack == 7 )
{
strcpy(MP3_path, STRING(pev->message));
strcat(MP3_path, "/track7.mp3");
}
else if ( PlayedTrack == 8 )
{
strcpy(MP3_path, STRING(pev->message));
strcat(MP3_path, "/track8.mp3");
}
else if ( PlayedTrack == 9 )
{
strcpy(MP3_path, STRING(pev->message));
strcat(MP3_path, "/track9.mp3");
}
//ALERT(at_console, "Piste MP3 %s\n", MP3_path);
 
int ReadState = UTIL_PlayMP3( MP3_actuel, pev->health, 0, pev->iuser2);
if ( !ReadState )//the function a returned 0 because there was no file there
{
ALERT(at_console, "No MP3 at this path");
}
 
else if ( ReadState != 2 )// there is a mp3 playing and no priority set, or no mp3 at the path
{
if ( PlayedTrack == pev->skin )//if we are at the endtrack
{
PlayedTrack = pev->effects;//we go to the loopto track
}
else
{
PlayedTrack++;//we go to the next track
}
pev->iuser1 = PlayedTrack;//save the current track
}
if ( !(pev->sequence) )//if we have to play an array of tracks (Single = 0)
{
pev->nextthink = gpGlobals->time + 2.0; //next think in 2 seconds
}
}