Статистика по очкам ( Общая )
Казалось бы тема наследования классов давно избита, ан нет всё ещё существуют вопросы, правда про чуть боле сложное наследование.
И снова наследование классов :)
Казалось бы тема наследования классов давно избита, ан нет всё ещё существуют вопросы, правда про чуть боле сложное наследование.
Автор / ы урока : Тренсфер Просмотров : 1295 ( +1 ) Скачиваний : 0 Прислал / (а) : Streit Дата создания : 07.04.2011 20:52:51 Источник : http://www.trensfer.narod.ru Рейтинг : ( 0 ) Поделиться :
Имеются следующие переводы : |
русский |
Казалось бы тема наследования классов давно избита, ан нет всё ещё существуют вопросы, правда про чуть боле сложное наследование. Конечно можно написать например нового монстра с нуля, но для этого придётся переписывать весь его искуственный интеллект, но это уже ещё сложнее чем наследование и весь кодинг превратится в замену ключевых слов. Зачем же изобретать деревянный велосипед? Безусловно продумывание своих новых монстров полезно, но не в этой ситуации, когда готовый код уже есть. На это раз я приведу пример на более сложное наследование, в нём мы будем заменять не отношения монстра, а его модели и звуки, тем самым мы получим "почти" нового монстра. Взять например охранницу Azure Sheep это почти полноценный монстр. Почему почти? Потому что он сделан на основе поведения барни но имеет совершенно другую модель и звуки. Если заменить модель можно заменив лишь две строчки в программном коде, то со звуками уже будет проблема Но не будет же баринель разговаривать голосом барни (как в Heavily Armed ). Поэтому надо ещё менять методы класса барни где хранятся звуки, но я думаю вы и без меня поняли . Больше не буду тянуть и выкладываю код, как сделать подружку барни.
В конец barney.cpp вставим код наследованный от кода барни:
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 вставим в конец файла фразы баринели :
// 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
@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. Trigger_PlayerFreeez - Trigger_PlayerFreeez (остановка игрока) 3. Цвет спрайтов HUD - Итак, как же сменить цвет спрайтов в HUD-системе 4. субтитры из паранойи - субтитры из паранойи. 5. Создание сценариев - Для создания сценариев (aka скриптов) в Half-Life существуют две энтити: scripted_sequence и scripted_sentence. Первая отвечает за движения, выполняемые монстром/персонажем, будь то ходьба, бег, нажатие кнопки, тряска автомата с газировкой или почёсывание подбородка. Вторая служит для того, чтобы персонаж произнес какую-то фразу. При этом его голова повернётся в сторону слушателя, и рот будет открываться в соответствии с амплитудой звука.
Вы не можете комментировать, т.к. вы не зарегистрированы.