Регистрация - или - Войти
Ultimate AttackUltimate Attack

Мод о судьбе оперативника Black Ops...

24/06/2004
The Citizen ReturnsThe Citizen Returns

First Person Shooter...

24/06/2014

Казалось бы тема наследования классов давно избита, ан нет всё ещё существуют вопросы, правда про чуть боле сложное наследование.


  • Описание
  • КАК УСТАНОВИТЬ

И снова наследование классов :)

Казалось бы тема наследования классов давно избита, ан нет всё ещё существуют вопросы, правда про чуть боле сложное наследование.


Автор / ы урока : Тренсфер
Просмотров : 465 ( +1 )
Скачиваний : 0
Прислал / (а) : Streit
Дата создания : 07.04.2011 17:52:51
Источник : http://www.trensfer.narod.ru
Рейтинг :
 ( 0 ) 
Поделиться :


Имеются следующие переводы : | русский |

Казалось бы тема наследования классов давно избита, ан нет всё ещё существуют вопросы, правда про чуть боле сложное наследование. Конечно можно написать например нового монстра с нуля, но для этого придётся переписывать весь его искуственный интеллект, но это уже ещё сложнее чем наследование и весь кодинг превратится в замену ключевых слов. Зачем же изобретать деревянный велосипед? Безусловно продумывание своих новых монстров полезно, но не в этой ситуации, когда готовый код уже есть. На это раз я приведу пример на более сложное наследование, в нём мы будем заменять не отношения монстра, а его модели и звуки, тем самым мы получим "почти" нового монстра. Взять например охранницу Azure Sheep это почти полноценный монстр. Почему почти? Потому что он сделан на основе поведения барни но имеет совершенно другую модель и звуки. Если заменить модель можно заменив лишь две строчки в программном коде, то со звуками уже будет проблема Но не будет же баринель разговаривать голосом барни (как в Heavily Armed ). Поэтому надо ещё менять методы класса барни где хранятся звуки, но я думаю вы и без меня поняли . Больше не буду тянуть и выкладываю код, как сделать подружку барни. В конец barney.cpp вставим код наследованный от кода барни:

Code:

class CBarniel: public CBarney//Наследуем класс
{
   public:
   void Spawn( void );
   void Precache( void );
   int Classify ( void );
   void BarneyFirePistol ( void );
   void TalkInit();
   void PainSound ( void );
   void DeathSound ( void );
   void DeclineFollowing( void );
   void AlertSound( void );
   int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType);
   Schedule_t *GetSchedule ( void );
};

LINK_ENTITY_TO_CLASS( monster_barniel, CBarniel);

int CBarniel :: Classify ( void )
{
   return CLASS_PLAYER_ALLY;
}

void CBarniel :: BarneyFirePistol ( void )
{
   Vector vecShootOrigin;
   UTIL_MakeVectors(pev->angles);
   vecShootOrigin = pev->origin + Vector( 0, 0, 55 );
   Vector vecShootDir = ShootAtEnemy( vecShootOrigin );
   Vector angDir = UTIL_VecToAngles( vecShootDir );
   SetBlending( 0, angDir.x );
   pev->effects = EF_MUZZLEFLASH;
   FireBullets(1, vecShootOrigin, vecShootDir, VECTOR_CONE_2DEGREES, 1024, BULLET_MONSTER_9MM );
   int pitchShift = RANDOM_LONG( 0, 20 );

   if ( pitchShift > 10 )
     pitchShift = 0;
   else
     pitchShift -= 5;

   EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "barniel/bn_attack2.wav", 1, ATTN_NORM, 0, 100 + pitchShift );
   CSoundEnt::InsertSound ( bits_SOUND_COMBAT, pev->origin, 384, 0.3 );
   m_cAmmoLoaded--;
}

void CBarniel :: Spawn()
{
   Precache( );

   if (pev->model)
     SET_MODEL(ENT(pev), STRING(pev->model));
   else
     SET_MODEL(ENT(pev), "models/Barniel.mdl");

   UTIL_SetSize(pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX);
   pev->solid = SOLID_SLIDEBOX;
   pev->movetype = MOVETYPE_STEP;
   m_bloodColor = BLOOD_COLOR_RED;
   pev->health = gSkillData.barneyHealth;
   pev->view_ofs = Vector ( 0, 0, 50 );
   m_flFieldOfView = VIEW_FIELD_WIDE;
   m_MonsterState = MONSTERSTATE_NONE;
   pev->body = 0;
   m_fGunDrawn = FALSE;
   m_afCapability = bits_CAP_HEAR | bits_CAP_TURN_HEAD | bits_CAP_DOORS_GROUP;
   MonsterInit();
   SetUse( FollowerUse );
}

void CBarniel :: Precache()
{
   if (pev->model)
     PRECACHE_MODEL((char*)STRING(pev->model));
   else
     PRECACHE_MODEL("models/Barniel.mdl");

   PRECACHE_SOUND("barniel/bn_attack1.wav" );
   PRECACHE_SOUND("barniel/bn_attack2.wav" );
   PRECACHE_SOUND("barney/ba_attack2.wav" );
   PRECACHE_SOUND("barniel/bn_pain1.wav");
   PRECACHE_SOUND("barniel/bn_die1.wav");
   TalkInit();
   CTalkMonster::Precache();
}

void CBarniel :: TalkInit()
{
   CTalkMonster::TalkInit();
   m_szGrp[TLK_ANSWER] = "BN_ANSWER";
   m_szGrp[TLK_QUESTION] = "BN_QUESTION";
   m_szGrp[TLK_IDLE] = "BN_IDLE";
   m_szGrp[TLK_STARE] = "BN_STARE";
   m_szGrp[TLK_USE] = "BN_OK";
   m_szGrp[TLK_UNUSE] = "BN_WAIT";
   m_szGrp[TLK_STOP] = "BN_STOP";
   m_szGrp[TLK_NOSHOOT] = "BN_SCARED";
   m_szGrp[TLK_HELLO] = "BN_HELLO";
   m_szGrp[TLK_PLHURT1] = "!BN_CUREA";
   m_szGrp[TLK_PLHURT2] = "!BN_CUREB";
   m_szGrp[TLK_PLHURT3] = "!BN_CUREC";
   m_szGrp[TLK_PHELLO] = NULL;
   m_szGrp[TLK_PIDLE] = NULL;
   m_szGrp[TLK_PQUESTION] = "BN_PQUEST";
   m_szGrp[TLK_SMELL] = "BN_SMELL";
   m_szGrp[TLK_WOUND] = "BN_WOUND";
   m_szGrp[TLK_MORTAL] = "BN_MORTAL";
   m_voicePitch = 100;
}

void CBarniel :: PainSound ( void )
{
   if (gpGlobals->time < m_painTime)
     return;
   m_painTime = gpGlobals->time + RANDOM_FLOAT(0.5, 0.75);
   EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "barniel/bn_pain1.wav", 1, ATTN_NORM, 0, GetVoicePitch());
}

void CBarniel :: DeathSound ( void )
{
   EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "barniel/bn_die1.wav", 1, ATTN_NORM, 0, GetVoicePitch()); //ea?aou caoe
}

void CBarniel :: AlertSound( void )
{
   if ( m_hEnemy != NULL )
   {
     if ( FOkToSpeak() )
     {
       PlaySentence( "BN_ATTACK", RANDOM_FLOAT(2.8, 3.2), VOL_NORM, ATTN_IDLE );
     }
   }
}

int CBarniel :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType)
{
   int ret = CTalkMonster::TakeDamage(pevInflictor, pevAttacker, flDamage, bitsDamageType);
   if ( !IsAlive() || pev->deadflag == DEAD_DYING )
     return ret;
   if ( m_MonsterState != MONSTERSTATE_PRONE && (pevAttacker->flags & FL_CLIENT) )
   {
     m_flPlayerDamage += flDamage;
     if ( m_hEnemy == NULL )
     {
       if ( (m_afMemory & bits_MEMORY_SUSPICIOUS) || IsFacing( pevAttacker, pev->origin ) )
       {
         PlaySentence( "BN_MAD", 4, VOL_NORM, ATTN_NORM );
         Remember( bits_MEMORY_PROVOKED );
         StopFollowing( TRUE );
       }
       else
       {
         PlaySentence( "BN_SHOT", 4, VOL_NORM, ATTN_NORM );
         Remember( bits_MEMORY_SUSPICIOUS );
       }
     }
     else if ( !(m_hEnemy->IsPlayer()) && pev->deadflag == DEAD_NO )
     {
       PlaySentence( "BN_SHOT", 4, VOL_NORM, ATTN_NORM );
     }
   }
   return ret;
}

Schedule_t *CBarniel :: GetSchedule ( void )
{
   if ( HasConditions( bits_COND_HEAR_SOUND ) )
   {
     CSound *pSound;
     pSound = PBestSound();
     ASSERT( pSound != NULL );
     if ( pSound && (pSound->m_iType & bits_SOUND_DANGER) )
       return GetScheduleOfType( SCHED_TAKE_COVER_FROM_BEST_SOUND );
   }
   if ( HasConditions( bits_COND_ENEMY_DEAD ) && FOkToSpeak() )
   {
     PlaySentence( "BN_KILL", 4, VOL_NORM, ATTN_NORM );
   }
   switch( m_MonsterState )
   {
     case MONSTERSTATE_COMBAT:
     {
       if ( HasConditions( bits_COND_ENEMY_DEAD ) )
       {
         return CBaseMonster :: GetSchedule();
       }
       if ( HasConditions( bits_COND_NEW_ENEMY ) && HasConditions( bits_COND_LIGHT_DAMAGE) )
         return GetScheduleOfType( SCHED_SMALL_FLINCH );
       if (!m_fGunDrawn )
         return GetScheduleOfType( SCHED_ARM_WEAPON );
       if ( HasConditions( bits_COND_HEAVY_DAMAGE ) )
         return GetScheduleOfType( SCHED_TAKE_COVER_FROM_ENEMY );
     }
     break;
     case MONSTERSTATE_ALERT:
     case MONSTERSTATE_IDLE:
       if ( HasConditions(bits_COND_LIGHT_DAMAGE | bits_COND_HEAVY_DAMAGE))
       {
         return GetScheduleOfType( SCHED_SMALL_FLINCH );
       }
       if ( m_hEnemy == NULL && IsFollowing() )
       {
         if ( !m_hTargetEnt->IsAlive() )
         {
           StopFollowing( FALSE );
           break;
         }
         else
         {
           if ( HasConditions( bits_COND_CLIENT_PUSH ) )
           {
             return GetScheduleOfType( SCHED_MOVE_AWAY_FOLLOW );
           }
           return GetScheduleOfType( SCHED_TARGET_FACE );
         }
       }
       if ( HasConditions( bits_COND_CLIENT_PUSH ) )
       {
         return GetScheduleOfType( SCHED_MOVE_AWAY );
       }
       TrySmellTalk();
       break;
   }
   return CTalkMonster::GetSchedule();
}

void CBarniel::DeclineFollowing( void )
{
   PlaySentence( "BN_POK", 2, VOL_NORM, ATTN_NORM );
}

Но это ещё не всё в sound\sentences.txt вставим в конец файла фразы баринели :

Code:

// BARNIEL (Female barniel) uses the sound files barniel for now

BN_VAR0 barniel/hevno
BN_VAR1 barniel/seeya

// Barniel is triggered to not follow player
BN_NOFOLLOW0 barniel/seelater

// Barniel is going to use a retina scanner
BN_RETINA0 barniel/yessir

BN_HISTOP1 barniel/humm, waitin
BN_SLEEP1 barniel/bn_die1

// If you use Barniel before the disaster
BN_POK0 barniel/bn_post

// Hello Barniel sentences before the disaster
BN_PHELLO0 barniel/hi

// Idle Barniel sentences before the disaster
BN_PIDLE0 barniel/badfeeling
BN_PIDLE1 barniel/movietv

// Question Barniel sentences before the disaster
BN_PQUEST0 barniel/thinking
BN_PQUEST0 barniel/whatsgoingon

BN_OK0 barniel/teamup1
BN_OK1 barniel/teamup2

BN_WAIT0 barniel/waitin

BN_HELLO0 barniel/hi

BN_QUESTION0 barniel/drinktopside
BN_QUESTION1 barniel/rightway
BN_QUESTION2 barniel/thinking
BN_QUESTION3 barniel/slimything
BN_QUESTION4 barniel/whatsgoingon

BN_ANSWER0 barniel/yessir
BN_ANSWER1 barniel/dontagree
BN_ANSWER2 barniel/humm
BN_ANSWER3 barniel/nosir
BN_ANSWER4 barniel/dontknow
BN_ANSWER5 barniel/bequiet

// player is staring at barniel
BN_STARE0 barniel/yessir
BN_STARE1 barniel/aimforhead
BN_STARE2 barniel/badfeeling

BN_IDLE0 barniel/movietv
BN_IDLE1 barniel/badfeeling
BN_IDLE2 barniel/aimforhead

BN_ATTACK0 barniel/diegreenthing
BN_ATTACK1 barniel/aimforhead
BN_ATTACK2 barniel/bn_attack1
BN_ATTACK3 barniel/openfire

BN_HEAR0 barniel/hearsomething

BN_SMELL0 barniel/somethingmoves

BN_CUREA barniel/youneedmedic
BN_CUREB barniel/youneedmedic
BN_CUREC barniel/youneedmedic

BN_SCARED0 barniel/bn_whatyou
BN_SCARED1 barniel/bn_dontdothat

BN_WOUND0 barniel/imhit
BN_WOUND1 barniel/hitbad
BN_MORTAL0 barniel/hitbad

//If you shoot barniel:
BN_SHOT0 barniel/bn_carefull
BN_SHOT1 barniel/bn_dontdothat
BN_SHOT2 barniel/bn_becarefull
BN_SHOT3 barniel/bn_whatyou
BN_SHOT4 barniel/bn_friends

//When barniel's really pissed at you:
BN_MAD0 barniel/bn_stepoff
BN_MAD1 barniel/bn_iwish
BN_MAD2 barniel/bn_uwish
BN_MAD3 barniel/bn_somuch
BN_MAD4 barniel/bn_endline
BN_MAD5 barniel/bn_dontmake
BN_MAD6 barniel/bn_tomb

//When barniel's killed something
BN_KILL0 barniel/bn_gotone
BN_KILL1 barniel/bn_another
BN_KILL2 barniel/bn_onelessh
BN_KILL3 barniel/bn_seethat
BN_KILL4 barniel/bn_close
BN_KILL5 barniel/bn_firepl
BN_KILL6 barniel/bn_bring

// if barniel can't follow you
BN_STOP0 barniel/stop1

В halflife.fgd добавим:

Code:

@PointClass base(Monster,TalkMonster, Sequence) size(-16 -16 0, 16 16 72) studio () = monster_barniel : "Barney" [ model(studio) : "Model" ]
Баринель готова, я специально оставил функцию int CBarniel

Classify ( void ) на тот случай если вы решите сделать злую баринель.



Похожие1. Исходный код ножа - weapon_knife (Нож) с двумя режимами атаки: Slash и Stab.
2. Исходный код снайперки - weapon_sniperrifle с оптическим прицелом
3. Новые типы патронов - Каждый хоть раз добавлял в Хл новое оружие но ему не нравилось, что оно или слишком мощно стреляет или слишком слабо.
4. Монстры по сети - Для создания кооперативного мода или просто для включения монстров в сетевой игре
5. Цвет HUD - Цвет HUD
6. Тряска игрока от наносимого урона - Вы хотите cделать чтобы игроков трясло от урона?
7. Наследование классов в С++ - В этом туторе я попытаюсь кратко рассказать про наследование классов в С++
8. Создание сценариев - Для создания сценариев (aka скриптов) в Half-Life существуют две энтити: scripted_sequence и scripted_sentence. Первая отвечает за движения, выполняемые монстром/персонажем, будь то ходьба, бег, нажатие кнопки, тряска автомата с газировкой или почёсывание подбородка. Вторая служит для того, чтобы персонаж произнес какую-то фразу. При этом его голова повернётся в сторону слушателя, и рот будет открываться в соответствии с амплитудой звука.
9. Изменение цвета HUD'а(полное)! - Изменение цвета HUD'а(полное)! Но прицелы придётся переделывать вам самим! Сдесь я перевевёл туториал с twhl.info на русский язык!
Вы не можете комментировать, т.к. вы не зарегистрированы.
    Momiji as Gloria DMC4
    Dead Or Alive 5 Last RoundMomiji as Gloria DMC4
    Rachel as Trish DMC4
    Dead Or Alive 5 Last RoundRachel as Trish DMC4
    Lady DMC4 Mod Pack
    Dead Or Alive 5 Last RoundLady DMC4 Mod Pack
    Hello Kitty Outfit Mod Pack
    Dead Or Alive 5 Last RoundHello Kitty Outfit Mod Pack

Время --------- ___ALL___ --------- : 0.28429 секунд