Custom Sounds: различия между версиями

Материал из CSM Wiki
Перейти к навигации Перейти к поиску
(Создана новая страница размером Категория:Программирование_GoldSrc = Custom sounds для монстров в VHE = Смысл тутор...)
 
 
(не показано 11 промежуточных версий 3 участников)
Строка 3: Строка 3:
 
= Custom sounds для монстров в VHE  =
 
= Custom sounds для монстров в VHE  =
  
Смысл туториала: многие новички хотят создать например, нового монстра. Для этого просто копируют zombie.cpp , а потом просто преиминовывают классы, пути к модели, звукам, но это мягко говоря - "неразумно". Вообщем не буду сильно "расходиться". Страдает оптимизация, в первую очередь и гибкость создания карты, или мода. '''Дядя Миша''' писал когда-то про наследование класов, но, но, но это тоже немного не то, что нужно новичку. Я предлагаю решить проблему так:
+
Смысл туториала: многие новички хотят создать например, нового монстра. Для этого просто копируют zombie.cpp , а потом просто преиминовывают классы, пути к модели, звукам, но это мягко говоря - "неразумно". Вообщем не буду сильно "расходиться". Страдает оптимизация, в первую очередь и гибкость создания карты, или мода.
Я буду работать на примере зомби, но так можно манипулировать со всеми монстрами.
+
Я буду работать на примере зомби, но так можно манипулировать со всеми монстрами.<br>
(Важно!!! Этот код для спирита, хотя если заменять целые похожие конструкции, то cкорей всего это будет работать и на сдк23!).
+
{{Шаблон:Внимание|Этот код для спирита, хотя если заменять целые похожие конструкции, то cкорей всего это будет работать и на сдк23!}}<br>
Допустим, новичок поменял модель своего зомби в редакторе, но возник новый вопрос: а как собственно поменять звуки?
+
Допустим, новичок поменял модель своего зомби в редакторе, но возник новый вопрос: а как собственно поменять звуки?<br>
Решение:
+
Решение:<br>
 
Открываем zombie.cpp
 
Открываем zombie.cpp
  
 
Опускаемся ниже строчки:
 
Опускаемся ниже строчки:
  
static const char *pAttackMissSounds[];
+
<source lang=cpp line>
 +
static const char *pAttackMissSounds[];
 +
</source>
  
 
И пишем:
 
И пишем:
  
//Звуки моего монстра(ов)
+
<source lang=cpp line>
static const char *pUndeadAlertSounds[];
+
//Звуки моего монстра(ов)
static const char *pUndeadAttackSounds[];
+
static const char *pUndeadAlertSounds[];
static const char *pUndeadPainSounds[];
+
static const char *pUndeadAttackSounds[];
 +
static const char *pUndeadPainSounds[];
 +
</source>
  
 
В нашем случае, пусть монстр будет называться undead. Далее спускаемся ниже строчек:
 
В нашем случае, пусть монстр будет называться undead. Далее спускаемся ниже строчек:
  
const char *CZombie::pPainSounds[] =
+
<source lang=cpp line>
{
+
const char *CZombie::pPainSounds[] =
 +
{
 
     "zombie/zo_pain1.wav",
 
     "zombie/zo_pain1.wav",
 
     "zombie/zo_pain2.wav",
 
     "zombie/zo_pain2.wav",
};
+
};
 +
</source>
  
 
И добавляем:
 
И добавляем:
  
//Собственно, сами звуки
+
<source lang=cpp line>
const char *CZombie::pUndeadAlertSounds[] = //Звуки, когда монстр вас увидит
+
//Собственно, сами звуки
{
+
const char *CZombie::pUndeadAlertSounds[] = //Звуки, когда монстр вас увидит
 +
{
 
     "undead/undead_threat1.wav",
 
     "undead/undead_threat1.wav",
 
     "undead/undead_threat2.wav",
 
     "undead/undead_threat2.wav",
 
     "undead/undead_threat3.wav",
 
     "undead/undead_threat3.wav",
};
+
};
 
   
 
   
const char *CZombie::pUndeadAttackSounds[] = //Звуки аттаки
+
const char *CZombie::pUndeadAttackSounds[] = //Звуки аттаки
{
+
{
 
     "undead/undead_striking1.wav",
 
     "undead/undead_striking1.wav",
 
     "undead/undead_striking2.wav",
 
     "undead/undead_striking2.wav",
};
+
};
 
   
 
   
const char *CZombie::pUndeadPainSounds[] = //Когда по монстру попадают
+
const char *CZombie::pUndeadPainSounds[] = //Когда по монстру попадают
{
+
{
 
     "undead/undead_ouch0.wav",
 
     "undead/undead_ouch0.wav",
 
     "undead/undead_ouch1.wav",
 
     "undead/undead_ouch1.wav",
};
+
};
 +
</source>
  
 
Далее мы должны выставить условия, при которых будет проигрываться наш звук, так вот он будет на прямую зависть от того, какую модель вы выбрали для монстра. Заменяем строки:
 
Далее мы должны выставить условия, при которых будет проигрываться наш звук, так вот он будет на прямую зависть от того, какую модель вы выбрали для монстра. Заменяем строки:
  
void CZombie :: PainSound( void )
+
<source lang=cpp line>
{
+
void CZombie :: PainSound( void )
 +
{
 
     int pitch = 95 + RANDOM_LONG(0,9);
 
     int pitch = 95 + RANDOM_LONG(0,9);
 
      
 
      
 
     if (RANDOM_LONG(0,5) < 2)
 
     if (RANDOM_LONG(0,5) < 2)
 
         EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pPainSounds[ RANDOM_LONG(0,ARRAYSIZE(pPainSounds)-1) ], 1.0, ATTN_NORM, 0, pitch );
 
         EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pPainSounds[ RANDOM_LONG(0,ARRAYSIZE(pPainSounds)-1) ], 1.0, ATTN_NORM, 0, pitch );
}
+
}
 
   
 
   
void CZombie :: AlertSound( void )
+
void CZombie :: AlertSound( void )
{
+
{
 
     int pitch = 95 + RANDOM_LONG(0,9);
 
     int pitch = 95 + RANDOM_LONG(0,9);
 
      
 
      
 
     EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pAlertSounds[ RANDOM_LONG(0,ARRAYSIZE(pAlertSounds)-1) ], 1.0, ATTN_NORM, 0, pitch );
 
     EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pAlertSounds[ RANDOM_LONG(0,ARRAYSIZE(pAlertSounds)-1) ], 1.0, ATTN_NORM, 0, pitch );
}
+
}
 
   
 
   
void CZombie :: IdleSound( void )
+
void CZombie :: IdleSound( void )
{
+
{
 
     int pitch = 95 + RANDOM_LONG(0,9);
 
     int pitch = 95 + RANDOM_LONG(0,9);
 
      
 
      
 
     // Play a random idle sound
 
     // Play a random idle sound
 
     EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pIdleSounds[ RANDOM_LONG(0,ARRAYSIZE(pIdleSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
 
     EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pIdleSounds[ RANDOM_LONG(0,ARRAYSIZE(pIdleSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
}
+
}
 
   
 
   
 
  void CZombie :: AttackSound( void )
 
  void CZombie :: AttackSound( void )
Строка 81: Строка 90:
 
     EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pAttackSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
 
     EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pAttackSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
 
  }
 
  }
 +
</source>
  
 
На:
 
На:
  
void CZombie :: PainSound( void )
+
<source lang=cpp line>
{
+
void CZombie :: PainSound( void )
 +
{
 
     int pitch = 95 + RANDOM_LONG(0,9);
 
     int pitch = 95 + RANDOM_LONG(0,9);
 
     if (RANDOM_LONG(0,5) < 2)
 
     if (RANDOM_LONG(0,5) < 2)
Строка 94: Строка 105:
 
             EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pPainSounds[ RANDOM_LONG(0,ARRAYSIZE(pPainSounds)-1) ], 1.0, ATTN_NORM, 0, pitch );
 
             EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pPainSounds[ RANDOM_LONG(0,ARRAYSIZE(pPainSounds)-1) ], 1.0, ATTN_NORM, 0, pitch );
 
     }
 
     }
}
+
}
 
   
 
   
void CZombie :: AlertSound( void )
+
void CZombie :: AlertSound( void )
{
+
{
 
     int pitch = 95 + RANDOM_LONG(0,9);
 
     int pitch = 95 + RANDOM_LONG(0,9);
 
     if ( FStrEq( STRING(pev->model), "models/undead.mdl" ) )
 
     if ( FStrEq( STRING(pev->model), "models/undead.mdl" ) )
Строка 103: Строка 114:
 
     else
 
     else
 
         EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pAlertSounds[ RANDOM_LONG(0,ARRAYSIZE(pAlertSounds)-1) ], 1.0, ATTN_NORM, 0, pitch );
 
         EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pAlertSounds[ RANDOM_LONG(0,ARRAYSIZE(pAlertSounds)-1) ], 1.0, ATTN_NORM, 0, pitch );
}
+
}
 
   
 
   
 
   
 
   
void CZombie :: IdleSound( void )
+
void CZombie :: IdleSound( void )
{
+
{
 
     int pitch = 95 + RANDOM_LONG(0,9);
 
     int pitch = 95 + RANDOM_LONG(0,9);
 
      
 
      
    // Если вы хотите изменить и звуки ожидания, то нужно вначале их идентефицировать(на примере Pain,Alert,Attack)
+
// Если вы хотите изменить и звуки ожидания, то нужно вначале их идентефицировать(на примере Pain,Alert,Attack)
 
     EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pIdleSounds[ RANDOM_LONG(0,ARRAYSIZE(pIdleSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
 
     EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pIdleSounds[ RANDOM_LONG(0,ARRAYSIZE(pIdleSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
}
+
}
 
   
 
   
void CZombie :: AttackSound( void )
+
void CZombie :: AttackSound( void )
{
+
{
 
     if ( FStrEq( STRING(pev->model), "models/undead.mdl" ) )
 
     if ( FStrEq( STRING(pev->model), "models/undead.mdl" ) )
 
         EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pUndeadAttackSounds[ RANDOM_LONG(0,ARRAYSIZE(pUndeadAttackSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
 
         EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pUndeadAttackSounds[ RANDOM_LONG(0,ARRAYSIZE(pUndeadAttackSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
 
     else
 
     else
 
         EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pAttackSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
 
         EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pAttackSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
}
+
}
 +
</source>
  
 
Мы почти завершили, осталось только выставить звуки и модель в список кэширования, и !!! если ваша модель больше или меньше стандартной, изменить "физический" ее размер, тоесть через UTIL_SetSize. Заменяем код:
 
Мы почти завершили, осталось только выставить звуки и модель в список кэширования, и !!! если ваша модель больше или меньше стандартной, изменить "физический" ее размер, тоесть через UTIL_SetSize. Заменяем код:
  
//=========================================================
+
<source lang=cpp line>
// Spawn
+
//=========================================================
//=========================================================
+
// Spawn
void CZombie :: Spawn()
+
//=========================================================
{
+
void CZombie :: Spawn()
 +
{
 
     Precache( );
 
     Precache( );
 
      
 
      
Строка 148: Строка 161:
 
      
 
      
 
     MonsterInit();
 
     MonsterInit();
}
+
}
 +
</source>
  
 
На:
 
На:
  
//=========================================================
+
<source lang=cpp line>
// Spawn
+
//=========================================================
//=========================================================
+
// Spawn
void CZombie :: Spawn()
+
//=========================================================
{
+
void CZombie :: Spawn()
 +
{
 
     Precache( );
 
     Precache( );
 
      
 
      
Строка 181: Строка 196:
 
      
 
      
 
     MonsterInit();
 
     MonsterInit();
}
+
}
 +
</source>
  
 
Осталось дело за малым, а именно прокэшировать наши ресурсы, для этого, заменяем:
 
Осталось дело за малым, а именно прокэшировать наши ресурсы, для этого, заменяем:
  
//=========================================================
+
<source lang=cpp line>
// Precache - precaches all resources this monster needs
+
//=========================================================
//=========================================================
+
// Precache - precaches all resources this monster needs
void CZombie :: Precache()
+
//=========================================================
{
+
void CZombie :: Precache()
 +
{
 
     int i;
 
     int i;
 
      
 
      
Строка 214: Строка 231:
 
     for ( i = 0; i < ARRAYSIZE( pPainSounds ); i++ )
 
     for ( i = 0; i < ARRAYSIZE( pPainSounds ); i++ )
 
         PRECACHE_SOUND((char *)pPainSounds[i]);
 
         PRECACHE_SOUND((char *)pPainSounds[i]);
}
+
}
 +
</source>
  
 
На:
 
На:
  
//=========================================================
+
<source lang=cpp line>
// Precache - precaches all resources this monster needs
+
//=========================================================
//=========================================================
+
// Precache - precaches all resources this monster needs
void CZombie :: Precache()
+
//=========================================================
{
+
void CZombie :: Precache()
 +
{
 
     int i;
 
     int i;
 
      
 
      
Строка 263: Строка 282:
 
     for ( i = 0; i < ARRAYSIZE( pAttackMissSounds ); i++ )
 
     for ( i = 0; i < ARRAYSIZE( pAttackMissSounds ); i++ )
 
         PRECACHE_SOUND((char *)pAttackMissSounds[i]);
 
         PRECACHE_SOUND((char *)pAttackMissSounds[i]);
}
+
}
 +
</source>
  
Данный способ является более гибким, чем предложил '''Дядя Миша''', и более оптимизирован.
 
 
Для большей гибкости, можно использовать еще "else if ( FStrEq( STRING(pev->model), "models/undead2.mdl" ) )" Что позволит добовлять огромное кол-во мостров одного типа.
 
Для большей гибкости, можно использовать еще "else if ( FStrEq( STRING(pev->model), "models/undead2.mdl" ) )" Что позволит добовлять огромное кол-во мостров одного типа.
 
В исходный код мы добавили максимум 1.5 кб. Теперь осталось откомпилировать, и в свойствах своего монстра поставить модель undead.mdl (undead - название модели)
 
В исходный код мы добавили максимум 1.5 кб. Теперь осталось откомпилировать, и в свойствах своего монстра поставить модель undead.mdl (undead - название модели)
Строка 274: Строка 293:
 
  model(studio) : "Model"
 
  model(studio) : "Model"
 
  ]
 
  ]
 +
 +
Автор туториала: PoD-Stas

Текущая версия на 22:05, 22 июня 2009


Custom sounds для монстров в VHE

Смысл туториала: многие новички хотят создать например, нового монстра. Для этого просто копируют zombie.cpp , а потом просто преиминовывают классы, пути к модели, звукам, но это мягко говоря - "неразумно". Вообщем не буду сильно "расходиться". Страдает оптимизация, в первую очередь и гибкость создания карты, или мода. Я буду работать на примере зомби, но так можно манипулировать со всеми монстрами.
  Warning.png Внимание: 
Допустим, новичок поменял модель своего зомби в редакторе, но возник новый вопрос: а как собственно поменять звуки?
Решение:
Открываем zombie.cpp

Опускаемся ниже строчки:

static const char *pAttackMissSounds[];

И пишем:

//Звуки моего монстра(ов)
static const char *pUndeadAlertSounds[];
static const char *pUndeadAttackSounds[];
static const char *pUndeadPainSounds[];

В нашем случае, пусть монстр будет называться undead. Далее спускаемся ниже строчек:

const char *CZombie::pPainSounds[] =
{
    "zombie/zo_pain1.wav",
    "zombie/zo_pain2.wav",
};

И добавляем:

//Собственно, сами звуки
const char *CZombie::pUndeadAlertSounds[] = //Звуки, когда монстр вас увидит
{
    "undead/undead_threat1.wav",
    "undead/undead_threat2.wav",
    "undead/undead_threat3.wav",
};
 
const char *CZombie::pUndeadAttackSounds[] = //Звуки аттаки
{
    "undead/undead_striking1.wav",
    "undead/undead_striking2.wav",
};
 
const char *CZombie::pUndeadPainSounds[] = //Когда по монстру попадают
{
    "undead/undead_ouch0.wav",
    "undead/undead_ouch1.wav",
};

Далее мы должны выставить условия, при которых будет проигрываться наш звук, так вот он будет на прямую зависть от того, какую модель вы выбрали для монстра. Заменяем строки:

void CZombie :: PainSound( void )
{
    int pitch = 95 + RANDOM_LONG(0,9);
    
    if (RANDOM_LONG(0,5) < 2)
        EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pPainSounds[ RANDOM_LONG(0,ARRAYSIZE(pPainSounds)-1) ], 1.0, ATTN_NORM, 0, pitch );
}
 
void CZombie :: AlertSound( void )
{
    int pitch = 95 + RANDOM_LONG(0,9);
    
    EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pAlertSounds[ RANDOM_LONG(0,ARRAYSIZE(pAlertSounds)-1) ], 1.0, ATTN_NORM, 0, pitch );
}
 
void CZombie :: IdleSound( void )
{
    int pitch = 95 + RANDOM_LONG(0,9);
    
    // Play a random idle sound
    EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pIdleSounds[ RANDOM_LONG(0,ARRAYSIZE(pIdleSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
}
 
 void CZombie :: AttackSound( void )
 {
    // Play a random attack sound
    EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pAttackSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
 }

На:

void CZombie :: PainSound( void )
{
    int pitch = 95 + RANDOM_LONG(0,9);
    if (RANDOM_LONG(0,5) < 2)
    {
        if ( FStrEq( STRING(pev->model), "models/undead.mdl" ) )
            EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pUndeadPainSounds[ RANDOM_LONG(0,ARRAYSIZE(pUndeadPainSounds)-1) ], 1.0, ATTN_NORM, 0, pitch );
        else
            EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pPainSounds[ RANDOM_LONG(0,ARRAYSIZE(pPainSounds)-1) ], 1.0, ATTN_NORM, 0, pitch );
    }
}
 
void CZombie :: AlertSound( void )
{
    int pitch = 95 + RANDOM_LONG(0,9);
    if ( FStrEq( STRING(pev->model), "models/undead.mdl" ) )
        EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pUndeadAlertSounds[ RANDOM_LONG(0,ARRAYSIZE(pUndeadAlertSounds)-1) ], 1.0, ATTN_NORM, 0, pitch );
    else
        EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pAlertSounds[ RANDOM_LONG(0,ARRAYSIZE(pAlertSounds)-1) ], 1.0, ATTN_NORM, 0, pitch );
}
 
 
void CZombie :: IdleSound( void )
{
    int pitch = 95 + RANDOM_LONG(0,9);
    
// Если вы хотите изменить и звуки ожидания, то нужно вначале их идентефицировать(на примере Pain,Alert,Attack)
    EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pIdleSounds[ RANDOM_LONG(0,ARRAYSIZE(pIdleSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
}
 
void CZombie :: AttackSound( void )
{
    if ( FStrEq( STRING(pev->model), "models/undead.mdl" ) )
        EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pUndeadAttackSounds[ RANDOM_LONG(0,ARRAYSIZE(pUndeadAttackSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
    else
        EMIT_SOUND_DYN ( ENT(pev), CHAN_VOICE, pAttackSounds[ RANDOM_LONG(0,ARRAYSIZE(pAttackSounds)-1) ], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5,5) );
}

Мы почти завершили, осталось только выставить звуки и модель в список кэширования, и !!! если ваша модель больше или меньше стандартной, изменить "физический" ее размер, тоесть через UTIL_SetSize. Заменяем код:

//=========================================================
// Spawn
//=========================================================
void CZombie :: Spawn()
{
    Precache( );
    
    if (pev->model)
        SET_MODEL(ENT(pev), STRING(pev->model)); //LRC
    else
        SET_MODEL(ENT(pev), "models/zombie.mdl");
    UTIL_SetSize( pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX );
    
    pev->solid    = SOLID_SLIDEBOX;
    pev->movetype    = MOVETYPE_STEP;
    m_bloodColor    = BLOOD_COLOR_GREEN;
    if (pev->health == 0)
        pev->health    = gSkillData.zombieHealth;
    pev->view_ofs    = VEC_VIEW;// position of the eyes relative to monster's origin.
    m_flFieldOfView    = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result )
    m_MonsterState    = MONSTERSTATE_NONE;
    m_afCapability    = bits_CAP_DOORS_GROUP;
    
    MonsterInit();
}

На:

//=========================================================
// Spawn
//=========================================================
void CZombie :: Spawn()
{
    Precache( );
    
    if (pev->model)
        SET_MODEL(ENT(pev), STRING(pev->model)); //LRC
    else
        SET_MODEL(ENT(pev), "models/zombie.mdl");
    
    // Размеры для вашего монстра:
    if ( FStrEq( STRING(pev->model), "models/undead.mdl" ) )
        UTIL_SetSize( pev, Vector(-18, -18, 0), Vector(18, 18, 74) );
    else
        UTIL_SetSize( pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX );
    
    pev->solid    = SOLID_SLIDEBOX;
    pev->movetype    = MOVETYPE_STEP;
    m_bloodColor    = BLOOD_COLOR_RED;
    if (pev->health == 0)
        pev->health    = gSkillData.zombieHealth;
    pev->view_ofs    = VEC_VIEW;// position of the eyes relative to monster's origin.
    m_flFieldOfView    = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result )
    m_MonsterState    = MONSTERSTATE_NONE;
    m_afCapability    = bits_CAP_DOORS_GROUP;
    
    MonsterInit();
}

Осталось дело за малым, а именно прокэшировать наши ресурсы, для этого, заменяем:

//=========================================================
// Precache - precaches all resources this monster needs
//=========================================================
void CZombie :: Precache()
{
    int i;
    
    if (pev->model)
        PRECACHE_MODEL((char*)STRING(pev->model)); //LRC
    else
        PRECACHE_MODEL("models/zombie.mdl");
    
    for ( i = 0; i < ARRAYSIZE( pAttackHitSounds ); i++ )
        PRECACHE_SOUND((char *)pAttackHitSounds[i]);
    
    for ( i = 0; i < ARRAYSIZE( pAttackMissSounds ); i++ )
        PRECACHE_SOUND((char *)pAttackMissSounds[i]);
    
    for ( i = 0; i < ARRAYSIZE( pAttackSounds ); i++ )
        PRECACHE_SOUND((char *)pAttackSounds[i]);
    
    for ( i = 0; i < ARRAYSIZE( pIdleSounds ); i++ )
        PRECACHE_SOUND((char *)pIdleSounds[i]);
    
    for ( i = 0; i < ARRAYSIZE( pAlertSounds ); i++ )
        PRECACHE_SOUND((char *)pAlertSounds[i]);
    
    for ( i = 0; i < ARRAYSIZE( pPainSounds ); i++ )
        PRECACHE_SOUND((char *)pPainSounds[i]);
}

На:

//=========================================================
// Precache - precaches all resources this monster needs
//=========================================================
void CZombie :: Precache()
{
    int i;
    
    if ( FStrEq( STRING(pev->model), "models/undead.mdl" ) )
    {
        PRECACHE_MODEL("models/undead.mdl");
        
        for ( i = 0; i < ARRAYSIZE( pUndeadAlertSounds ); i++ )
            PRECACHE_SOUND((char *)pUndeadAlertSounds[i]);
        
        for ( i = 0; i < ARRAYSIZE( pUndeadAttackSounds ); i++ )
            PRECACHE_SOUND((char *)pUndeadAttackSounds[i]);
        
        for ( i = 0; i < ARRAYSIZE( pUndeadPainSounds ); i++ )
            PRECACHE_SOUND((char *)pUndeadPainSounds[i]);
    }
    else
    {
        if (pev->model)
            PRECACHE_MODEL((char*)STRING(pev->model));
        else
            PRECACHE_MODEL("models/zombie.mdl");
        
        for ( i = 0; i < ARRAYSIZE( pAlertSounds ); i++ )
            PRECACHE_SOUND((char *)pAlertSounds[i]);
        
        for ( i = 0; i < ARRAYSIZE( pAttackSounds ); i++ )
            PRECACHE_SOUND((char *)pAttackSounds[i]);
        
        for ( i = 0; i < ARRAYSIZE( pPainSounds ); i++ )
            PRECACHE_SOUND((char *)pPainSounds[i]);
    }
    
    for ( i = 0; i < ARRAYSIZE( pIdleSounds ); i++ )
        PRECACHE_SOUND((char *)pIdleSounds[i]);
    
    for ( i = 0; i < ARRAYSIZE( pAttackHitSounds ); i++ )
        PRECACHE_SOUND((char *)pAttackHitSounds[i]);
    
    for ( i = 0; i < ARRAYSIZE( pAttackMissSounds ); i++ )
        PRECACHE_SOUND((char *)pAttackMissSounds[i]);
}

Для большей гибкости, можно использовать еще "else if ( FStrEq( STRING(pev->model), "models/undead2.mdl" ) )" Что позволит добовлять огромное кол-во мостров одного типа. В исходный код мы добавили максимум 1.5 кб. Теперь осталось откомпилировать, и в свойствах своего монстра поставить модель undead.mdl (undead - название модели) В дальнейшем я попробую реализовать еще более гибкий способ добавления звуков к вашему монстру, которые позволят всего лишь раз лезть в исходный код, для его редактирования. Если вы использовали обычный SDK, то нужно подредактировать ваш fgd, для этого нужно открыть его и в конец добавить:

@PointClass base(Monster) size(-16 -16 0, 16 16 72) studio () = monster_zombie : "Scientist Zombie" [
model(studio) : "Model"
]

Автор туториала: PoD-Stas