Форумы на Наша-Life
Home user CP  
Календарь событий Найти других пользователей Часто задаваемые Вопросы Поиск  
Автор
Тема
Создать Новую Тему    Ответить
Barnacle
(Монтировкой не бить!)

Зарегистрирован: Jun 2008
Проживает: Российская Федерация/Кемеровская обл./Юрга
Написал: 7106 сообщений

Оценка: 83 Votes 83 чел.

Developer Старожил Юморист 
Новая музыкальная entity.
Сообщение #1090184
Решил поделиться. В общем, задолбало ковыряться в навороченном ambient_generic и периодически что-либо ломать своими "фиксами". Ну и индекс надоело искать, из-за которого после загрузки сохранения звук начинает играть на стороне клиента и не приостанавливается. И дабы не переписывать сам ambient_generic и этим не сломать ненароком что-нибудь ещё, написал простую "энтитю" как раз для глобальной музыки.

Энтитя управляется через инпуты, есть флаг повтора. У фейдеров и питчера для лупа есть ограничения: сделано специально, чтобы не чудить уж слишком сильно с кодом повтора. Луп, увы, нормально работает только с wav: GetSoundDuration() как-то по кривому высчитывает длину mp3. Но, в принципе, не беда... Valve и так забивает в последнее время на mp3 и засовывает музыку в wav.

Цитата:
//--------------ЗАО Барнакл инкорпорейтед ЛТД 1990-2990-------------
// Purpose: Music entity.
// Пёрпос: Музыка.
//-----------------------------------------------------------------------------
#include "cbase.h"
#include "soundenvelope.h"

// memdbgon must be the last include file in a .cpp file!!!
// МЕМДБГОН ДОЛЖЕН БЫТЬ ПОСЛЕДНИМ ИНКЛУДОМ В СИПИПИ ФАЙЛЕ АААААААА!!!11111111
#include "tier0/memdbgon.h"

#define ENVELOPE_CONTROLLER (CSoundEnvelopeController::GetController())
#define MUSIC_LOOP 0x0001

class CMusic : public CPointEntity
{
DECLARE_CLASS( CMusic, CPointEntity );

public:
DECLARE_DATADESC();

string_t m_musicFileName;
bool m_bActive;
bool m_bPaused;
CSoundPatch *m_sndMusic;
float m_flStartTime;
float m_flDuration;
float m_flVolume;
float m_flPitch;

float m_flPassed;
float m_flPointer;
float m_flRemainingTime;

void Precache( void );
void Spawn( void );
void ToggleMusic();
void Think();
void PauseResumeToggle();
void UpdateOnRemove();

void InputEnable( inputdata_t &inputdata );
void InputDisable( inputdata_t &inputdata );
void InputToggle( inputdata_t &inputdata );
void InputPauseResume( inputdata_t &inputdata );
void InputVolume( inputdata_t &inputdata );
void InputFadeIn( inputdata_t &inputdata );
void InputFadeOut( inputdata_t &inputdata );
void InputPitch( inputdata_t &inputdata );
};

BEGIN_DATADESC( CMusic )
DEFINE_KEYFIELD( m_musicFileName, FIELD_SOUNDNAME, "musicfile" ),
DEFINE_FIELD( m_bActive, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bPaused, FIELD_BOOLEAN ),
DEFINE_SOUNDPATCH( m_sndMusic ),
DEFINE_FIELD( m_flStartTime, FIELD_TIME ),
DEFINE_FIELD( m_flDuration, FIELD_TIME ),
DEFINE_FIELD( m_flPassed, FIELD_TIME ),
DEFINE_FIELD( m_flRemainingTime, FIELD_TIME ),
DEFINE_FIELD( m_flVolume, FIELD_FLOAT ),
DEFINE_FIELD( m_flPitch, FIELD_FLOAT ),

DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
DEFINE_INPUTFUNC( FIELD_VOID, "Toggle", InputToggle ),
DEFINE_INPUTFUNC( FIELD_VOID, "PauseResume", InputPauseResume ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "Volume", InputVolume ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "FadeIn", InputFadeIn ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "FadeOut", InputFadeOut ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "Pitch", InputPitch ),
END_DATADESC()

LINK_ENTITY_TO_CLASS( music, CMusic );

//-----------------------------------------------------------------------------
// Purpose: Precaching
// Пёрпос: прекэш
//-----------------------------------------------------------------------------
void CMusic::Precache()
{
BaseClass::Precache();
char *szSoundFile = (char *)STRING( m_musicFileName );
if ( m_musicFileName != NULL_STRING && strlen( szSoundFile ) > 1 )
{
if (*szSoundFile != '!')
{
PrecacheScriptSound(szSoundFile);
}
}
}

//-----------------------------------------------------------------------------
// Purpose: spawn
// Пёрпос: спаун
//-----------------------------------------------------------------------------
void CMusic::Spawn( void )
{
Precache();
SetSolid( SOLID_NONE );
SetMoveType( MOVETYPE_NONE );

m_bActive = false;
m_bPaused = false;
m_flVolume = 1.0f;
m_flPitch = 100;
}

//-----------------------------------------------------------------------------
// Purpose: Enable Input
// Пёрпос: инпут-включатель.
//-----------------------------------------------------------------------------
void CMusic::InputEnable( inputdata_t &inputdata )
{
if( !m_bActive )
{
m_bActive = true;
ToggleMusic();
}
}

//-----------------------------------------------------------------------------
// Purpose: Disable Input
// Пёрпос: инпут-выключатель.
//-----------------------------------------------------------------------------
void CMusic::InputDisable( inputdata_t &inputdata )
{
if( m_bActive )
{
m_bActive = false;
ToggleMusic();
}
}

//-----------------------------------------------------------------------------
// Purpose: Toggle Input. Stopping play.
// Пёрпос: инпут-переключатель состояния (вкл\выкл). Не ставит на паузу.
//-----------------------------------------------------------------------------
void CMusic::InputToggle( inputdata_t &inputdata )
{
if( m_bActive ) m_bActive = false;
else m_bActive = true;

ToggleMusic();
}

//-----------------------------------------------------------------------------
// Purpose: main function
// Пёрпос: главная функция.
//-----------------------------------------------------------------------------
void CMusic::ToggleMusic()
{
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
if ( m_bActive && pPlayer )
{
EmitSound_t es;
es.m_nChannel = CHAN_STATIC;
es.m_pSoundName = (char *)STRING( m_musicFileName );
es.m_SoundLevel = SNDLVL_GUNFIRE;
es.m_nFlags = SND_SHOULDPAUSE;

CBaseEntity *pSoundEntity;
pSoundEntity = pPlayer;

m_flStartTime = gpGlobals->curtime;

if ( m_spawnflags & MUSIC_LOOP )
{
m_flPointer = gpGlobals->curtime;
m_flPassed = 0;
}

CSingleUserRecipientFilter filter( pPlayer );
m_sndMusic = ENVELOPE_CONTROLLER.SoundCreate( filter, 0 , es );

m_flDuration = enginesound->GetSoundDuration( STRING( ENVELOPE_CONTROLLER.SoundGetName( m_sndMusic ) ) ) ;

if ( m_sndMusic )
{
ENVELOPE_CONTROLLER.Play( m_sndMusic, m_flVolume, m_flPitch, m_flStartTime );
}

SetNextThink( m_flStartTime + m_flDuration + 0.1);

DevMsg( "m_flStartTime: %.2f\n", m_flStartTime);
DevMsg( "m_flDuration: %.2f\n", m_flDuration);
DevMsg( "m_flStartTime + m_flDuration: %.2f\n", m_flStartTime + m_flDuration);
}
else if ( !m_bActive )
{
if ( m_sndMusic != NULL )
{
ENVELOPE_CONTROLLER.SoundDestroy( m_sndMusic );
m_sndMusic, m_flStartTime, m_flPointer, m_flPassed, m_flRemainingTime = NULL;
m_flVolume = 1.0f;
}
}
}

//-----------------------------------------------------------------------------
// Purpose:
// Пёрпос: если loop - перезапустить, если нет - выключить.
//-----------------------------------------------------------------------------
void CMusic::Think()
{
BaseClass::Think();

if ( m_spawnflags & MUSIC_LOOP )
ToggleMusic();
else
{
m_bActive = false;
m_sndMusic, m_flStartTime, m_flPointer, m_flPassed, m_flRemainingTime = NULL;
}

m_flPointer = gpGlobals->curtime;
m_flPassed = 0;
}

//-----------------------------------------------------------------------------
// Purpose: Input Pause\Resume
// Пёрпос: инпут пауза
//-----------------------------------------------------------------------------
void CMusic::InputPauseResume( inputdata_t &inputdata )
{
if ( m_sndMusic )
{
if( !m_bPaused ) m_bPaused = true;
else m_bPaused = false;
PauseResumeToggle();
}
}

//-----------------------------------------------------------------------------
// Purpose:
// Пёрпос: функция паузы
//-----------------------------------------------------------------------------
void CMusic::PauseResumeToggle()
{
if( m_bPaused )
{
ENVELOPE_CONTROLLER.SoundChangeVolume( m_sndMusic, 0.0f, 0.1f);
SetNextThink(0);

if ( m_spawnflags & MUSIC_LOOP )
{
m_flPassed += gpGlobals->curtime - m_flPointer;
m_flRemainingTime = m_flDuration - m_flPassed;

DevMsg( "m_flRemainingTime: %.2f\n", m_flRemainingTime);
DevMsg( "m_flPassed: %.2f\n", m_flPassed);
}
}
else
{
ENVELOPE_CONTROLLER.SoundChangeVolume( m_sndMusic, m_flVolume, 0.1f);

if ( m_spawnflags & MUSIC_LOOP )
{
m_flPointer = gpGlobals->curtime;
SetNextThink( gpGlobals->curtime + m_flRemainingTime );

DevMsg( "curtime: %.2f\n", gpGlobals->curtime );
DevMsg( "NextThink: %.2f\n", gpGlobals->curtime + m_flRemainingTime );
}
}
}

//-----------------------------------------------------------------------------
// Purpose:
// Пёрпос: инпут громкость. диапазон 0.0 - 1.0
//-----------------------------------------------------------------------------
void CMusic::InputVolume( inputdata_t &inputdata )
{
if ( m_sndMusic )
{
if( inputdata.value.Float() <= 0 )
{
m_bPaused = true;
PauseResumeToggle();
}
else if ( inputdata.value.Float() > 1 )
{
m_flVolume = 1.0f;

if( m_bPaused )
{
m_bPaused = false;
PauseResumeToggle();
}
else
ENVELOPE_CONTROLLER.SoundChangeVolume( m_sndMusic, m_flVolume, 0.1f );
}
else
{
m_flVolume = inputdata.value.Float();

if( m_bPaused )
{
m_bPaused = false;
PauseResumeToggle();
}
else
ENVELOPE_CONTROLLER.SoundChangeVolume( m_sndMusic, m_flVolume, 0.1f);
}
}
}

//-----------------------------------------------------------------------------
// Purpose:
// Пёрпос:
//-----------------------------------------------------------------------------
void CMusic::InputFadeIn( inputdata_t &inputdata )
{
if ( m_sndMusic )
{
//Не работает, если на паузе.
// Use "InputVolume 0.1" before calling this, when paused.
if(!m_bPaused && m_spawnflags & MUSIC_LOOP)
ENVELOPE_CONTROLLER.SoundChangeVolume( m_sndMusic, 1.0f, inputdata.value.Float() );
else if(!(m_spawnflags & MUSIC_LOOP))
{
m_bPaused = false;
ENVELOPE_CONTROLLER.SoundChangeVolume( m_sndMusic, 1.0f, inputdata.value.Float() );
}
}
}

//-----------------------------------------------------------------------------
// Purpose:
// Пёрпос:
//-----------------------------------------------------------------------------
void CMusic::InputFadeOut( inputdata_t &inputdata )
{
if ( m_sndMusic )
{
if ( m_spawnflags & MUSIC_LOOP )
{
//Не останавливает музыку и не опускает значение ниже 0.1
ENVELOPE_CONTROLLER.SoundChangeVolume( m_sndMusic, 0.1, inputdata.value.Float() );
}
else
{
ENVELOPE_CONTROLLER.SoundChangeVolume( m_sndMusic, 0.0, inputdata.value.Float() );
m_bPaused = true;
}
}
}

//-----------------------------------------------------------------------------
// Purpose:
// Пёрпос: питч. не работает с зацикленными треками.
//-----------------------------------------------------------------------------
void CMusic::InputPitch( inputdata_t &inputdata )
{
if ( m_sndMusic && !(m_spawnflags & MUSIC_LOOP) )
{
m_flPitch = inputdata.value.Float();
ENVELOPE_CONTROLLER.SoundChangePitch( m_sndMusic, m_flPitch, 0.1f);
}
}

//-----------------------------------------------------------------------------
// Purpose:
// Пёрпос:
//-----------------------------------------------------------------------------
void CMusic::UpdateOnRemove( void )
{
BaseClass::UpdateOnRemove();
if ( m_bActive )
{
m_bActive = false;
ToggleMusic();
}
}

Цитата:
//--------------ЗАО Барнакл инкорпорейтед ЛТД 1990-2990-------------
// Purpose: Music entity.
// Пёрпос: Музыка.
//-----------------------------------------------------------------------------

@include "base.fgd"

@PointClass base(Targetname) iconsprite("editor/ambient_generic.vmt") sphere() = music : "Music Entity \ Музыка."
[
musicfile(sound) : "Sound Name" : "" : "Song name \ Имя файла."

input Enable(void) : "Enable \ Включить."
input Disable(void) : "Disable \ Выключить."
input Toggle(void) : "Toggle entity state \ Переключить состояние музыки (вкл\выкл)."
input PauseResume(void) : "Pause-Resume Toggle \ Приостановить."
input Volume(integer) : "Volume \ Громкость."
input FadeIn(integer) : "FadeIn \ Усиление."
input FadeOut(integer) : "FadeOut \ Затухание."
input Pitch(integer) : "Pitch \ Питч."

spawnflags(flags) =
[
1: "Loop - Музыка зациклена" : 0
]
]


В скрипте достаточно указать:
Цитата:
"demo_song0"
{
"soundlevel" "0"
"wave" "*#music/demo.wav"
}

* - stream.
# - без dsp.
Прикрепленный файл: music.rar
Файл был скачан 18 раз(а).

Поправил Barnacle 23-07-2013 в 14:03

Old Post 23-07-2013 12:22
Barnacle отсутствует Посмотреть данные 'Barnacle' Отправить Приватное Сообщение для 'Barnacle' Найти другие сообщения 'Barnacle' Добавить Barnacle в Список Друзей
Править/Удалить Сообщение Ответить с Цитированием
Все время в GMT . Сейчас 14:02.
Создать Новую Тему    Ответить

Быстрый ответ
Ваше Имя:
Хотите Зарегистрироваться?
Ваш Пароль:
Забыли свой Пароль?
Вы можете оставлять свои комментарии анонимно, просто введя свои имя и оставив пустым поле пароля.
Ваш ответ:

[проверить размер]
[транслит в win] | [?]
[русская клавиатура]

Дополнительно: Подтверждение по E-Mail


Быстрый переход:
 
Оцените эту Тему:
 

Правила форума:
Создание Тем не разрешено
Создание Сообщений разрешено
Создавать Вложения не разрешено
Редактирование Сообщений не разрешено
Коды HTML запрещены
Коды форума разрешены
Смайлики разрешены
Коды [IMG] запрещены