SteamPlay43
Житель форума
Группа: Неопытный
Дата регистрации: May 2012
Проживает: Барнаул
Сообщений: 273
Возраст: 26
Рейтинг
|
Решил добавить в мод новых монстров.
Вообщем гоном вместо проигрывания звуков атаки руками проигрывает звук выкидывания кровяного шара!
C++ Source Code:
1 | //========================================================= |
2 | // Opposing Forces Monster Gonome |
7 | //========================================================= |
8 | //========================================================= |
9 | // gonome - big hypermutated zombie. |
10 | //========================================================= |
23 | #define GONOME_SPRINT_DIST 256 |
28 | //========================================================= |
29 | // monster-specific schedule types |
30 | //========================================================= |
33 | SCHED_GONOME_SMELLFOOD = LAST_COMMON_SCHEDULE + 1, |
35 | SCHED_GONOME_SNIFF_AND_EAT, |
39 | //========================================================= |
40 | // monster-specific tasks |
41 | //========================================================= |
44 | TASK_GONOME_SMELLFOOD = LAST_COMMON_SCHEDULE + 1, |
47 | //========================================================= |
48 | // Gonome's spit projectile |
49 | //========================================================= |
50 | class CGonomeSpit : public CBaseEntity |
55 | static void Shoot( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity ); |
56 | void Touch( CBaseEntity *pOther ); |
57 | void EXPORT Animate( void ); |
59 | virtual int Save( CSave &save ); |
60 | virtual int Restore( CRestore &restore ); |
61 | static TYPEDESCRIPTION m_SaveData[]; |
66 | LINK_ENTITY_TO_CLASS( gonomespit, CGonomeSpit ); |
68 | TYPEDESCRIPTION CGonomeSpit::m_SaveData[] = |
70 | DEFINE_FIELD( CGonomeSpit, m_maxFrame, FIELD_INTEGER ), |
73 | IMPLEMENT_SAVERESTORE( CGonomeSpit, CBaseEntity ); |
75 | void CGonomeSpit:: Spawn( void ) |
77 | pev->movetype = MOVETYPE_FLY; |
78 | pev->classname = MAKE_STRING( "gonomespit" ); |
80 | pev->solid = SOLID_BBOX; |
81 | pev->rendermode = kRenderTransAlpha; |
84 | SET_MODEL(ENT(pev), "sprites/blood_chnk.spr"); |
88 | UTIL_SetSize( pev, Vector( 0, 0, 0), Vector(0, 0, 0) ); |
90 | m_maxFrame = (float) MODEL_FRAMES( pev->modelindex ) - 1; |
93 | void CGonomeSpit::Animate( void ) |
95 | pev->nextthink = gpGlobals->time + 0.1; |
99 | if ( pev->frame > m_maxFrame ) |
106 | void CGonomeSpit::Shoot( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity ) |
108 | CGonomeSpit *pGSpit = GetClassPtr( (CGonomeSpit *)NULL ); |
111 | UTIL_SetOrigin( pGSpit->pev, vecStart ); |
112 | pGSpit->pev->velocity = vecVelocity; |
113 | pGSpit->pev->owner = ENT(pevOwner); |
115 | pGSpit->SetThink ( Animate ); |
116 | pGSpit->pev->nextthink = gpGlobals->time + 0.1; |
119 | void CGonomeSpit :: Touch ( CBaseEntity *pOther ) |
125 | iPitch = RANDOM_FLOAT( 90, 110 ); |
127 | switch ( RANDOM_LONG( 0, 1 ) ) |
130 | EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "bullchicken/bc_spithit1.wav", 1, ATTN_NORM, 0, iPitch ); |
133 | EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "bullchicken/bc_spithit2.wav", 1, ATTN_NORM, 0, iPitch ); |
137 | if ( !pOther->pev->takedamage ) |
140 | // make a splat on the wall |
141 | UTIL_TraceLine( pev->origin, pev->origin + pev->velocity * 10, dont_ignore_monsters, ENT( pev ), &tr ); |
142 | UTIL_DecalTrace(&tr, DECAL_BLOOD2 + RANDOM_LONG(0,1)); |
145 | MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, tr.vecEndPos ); |
146 | WRITE_BYTE( TE_SPRITE_SPRAY ); |
147 | WRITE_COORD( tr.vecEndPos.x); // pos |
148 | WRITE_COORD( tr.vecEndPos.y); |
149 | WRITE_COORD( tr.vecEndPos.z); |
150 | WRITE_COORD( tr.vecPlaneNormal.x); // dir |
151 | WRITE_COORD( tr.vecPlaneNormal.y); |
152 | WRITE_COORD( tr.vecPlaneNormal.z); |
153 | WRITE_SHORT( iGonomeSpitSprite ); // model |
154 | WRITE_BYTE ( 5 ); // count |
155 | WRITE_BYTE ( 30 ); // speed |
156 | WRITE_BYTE ( 80 ); // noise ( client will divide by 100 ) |
161 | pOther->TakeDamage ( pev, pev, gSkillData.gonomeDmgGuts, DMG_GENERIC ); |
164 | SetThink ( SUB_Remove ); |
165 | pev->nextthink = gpGlobals->time; |
168 | //========================================================= |
169 | // Monster's Anim Events Go Here |
170 | //========================================================= |
171 | #define GONOMEE_AE_SLASH1 ( 1 ) // Gonome used hands (TAILWHIP) |
172 | #define GONOMEE_AE_SLASH2 ( 2 ) |
173 | #define GONOMEE_AE_GUTS1 ( 3 ) // Gonome uset guts (THROW) |
174 | #define GONOMEE_AE_GUTS2 ( 4 ) |
175 | #define GONOMEE_AE_JUMP1 ( 10 ) |
176 | #define GONOMEE_AE_JUMP2 ( 11 ) |
177 | #define GONOMEE_AE_JUMP3 ( 12 ) |
178 | #define GONOMEE_AE_JUMP4 ( 13 ) |
179 | #define GONOMEE_AE_JUMP5 ( 14 ) |
180 | #define GONOMEE_AE_JUMP6 ( 15 ) |
181 | #define GONOMEE_AE_JUMP7 ( 16 ) |
182 | #define GONOMEE_AE_JUMP8 ( 17 ) |
183 | #define GONOMEE_AE_JUMP9 ( 18 ) |
184 | #define GONOMEE_AE_BITE1 ( 19 ) // Gonome bite you |
185 | #define GONOMEE_AE_BITE2 ( 20 ) |
186 | #define GONOMEE_AE_BITE3 ( 21 ) |
187 | #define GONOMEE_AE_BITE4 ( 22 ) |
189 | #define GONOME_FLINCH_DELAY 2 // at most one flinch every n secs |
191 | class CGonome : public CBaseMonster |
195 | void Precache( void ); |
196 | void SetYawSpeed( void ); |
197 | int ISoundMask( void ); |
198 | int Classify ( void ); |
199 | void HandleAnimEvent( MonsterEvent_t *pEvent ); |
200 | void IdleSound( void ); |
201 | void PainSound( void ); |
202 | void DeathSound( void ); |
203 | void AlertSound ( void ); |
204 | void AttackSound( void ); |
205 | void StartTask ( Task_t *pTask ); |
206 | void RunTask ( Task_t *pTask ); |
207 | BOOL CheckRangeAttack1 ( float flDot, float flDist ); |
209 | Schedule_t *GetSchedule( void ); |
210 | Schedule_t *GetScheduleOfType ( int Type ); |
211 | int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ); |
212 | int IRelationship ( CBaseEntity *pTarget ); |
213 | int IgnoreConditions ( void ); |
214 | MONSTERSTATE GetIdealState ( void ); |
216 | int Save( CSave &save ); |
217 | int Restore( CRestore &restore ); |
220 | static TYPEDESCRIPTION m_SaveData[]; |
222 | BOOL m_fCanThreatDisplay;// this is so the gonome only does the "I see a headcrab!" dance one time. |
224 | float m_flLastHurtTime;// we keep track of this, because if something hurts a gonome, it will forget about its love of headcrabs for a while. |
225 | float m_flNextSpitTime;// last time the Gonome used the spit attack. |
226 | float m_flNextFlinch; |
228 | LINK_ENTITY_TO_CLASS( monster_gonome, CGonome ); |
230 | TYPEDESCRIPTION CGonome::m_SaveData[] = |
232 | DEFINE_FIELD( CGonome, m_fCanThreatDisplay, FIELD_BOOLEAN ), |
233 | DEFINE_FIELD( CGonome, m_flLastHurtTime, FIELD_TIME ), |
234 | DEFINE_FIELD( CGonome, m_flNextSpitTime, FIELD_TIME ), |
237 | IMPLEMENT_SAVERESTORE( CGonome, CBaseMonster ); |
239 | //========================================================= |
241 | //========================================================= |
242 | int CGonome::IgnoreConditions ( void ) |
244 | int iIgnore = CBaseMonster::IgnoreConditions(); |
246 | if ((m_Activity == ACT_MELEE_ATTACK1) || (m_Activity == ACT_MELEE_ATTACK1)) |
249 | if (pev->health < 20) |
250 | iIgnore |= (bits_COND_LIGHT_DAMAGE|bits_COND_HEAVY_DAMAGE); |
253 | if (m_flNextFlinch >= gpGlobals->time) |
254 | iIgnore |= (bits_COND_LIGHT_DAMAGE|bits_COND_HEAVY_DAMAGE); |
257 | if ((m_Activity == ACT_SMALL_FLINCH) || (m_Activity == ACT_BIG_FLINCH)) |
259 | if (m_flNextFlinch < gpGlobals->time) |
260 | m_flNextFlinch = gpGlobals->time + GONOME_FLINCH_DELAY; |
266 | //========================================================= |
267 | // IRelationship - overridden for gonome so that it can |
268 | // be made to ignore its love of headcrabs for a while. |
269 | //========================================================= |
270 | int CGonome::IRelationship ( CBaseEntity *pTarget ) |
272 | return CBaseMonster :: IRelationship ( pTarget ); |
275 | //========================================================= |
276 | // TakeDamage - overridden for gonome so we can keep track |
277 | // of how much time has passed since it was last injured |
278 | //========================================================= |
279 | int CGonome :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) |
284 | // if the gonome is running, has an enemy, was hurt by the enemy, hasn't been hurt in the last 3 seconds, and isn't too close to the enemy, |
285 | // it will swerve. (whew). |
286 | if ( m_hEnemy != NULL && IsMoving() && pevAttacker == m_hEnemy->pev && gpGlobals->time - m_flLastHurtTime > 3 ) |
288 | flDist = ( pev->origin - m_hEnemy->pev->origin ).Length2D(); |
290 | if ( flDist > GONOME_SPRINT_DIST ) |
292 | flDist = ( pev->origin - m_Route[ m_iRouteIndex ].vecLocation ).Length2D();// reusing flDist. |
294 | if ( FTriangulate( pev->origin, m_Route[ m_iRouteIndex ].vecLocation, flDist * 0.5, m_hEnemy, &vecApex ) ) |
296 | InsertWaypoint( vecApex, bits_MF_TO_DETOUR | bits_MF_DONT_SIMPLIFY ); |
301 | return CBaseMonster :: TakeDamage ( pevInflictor, pevAttacker, flDamage, bitsDamageType ); |
304 | //========================================================= |
306 | //========================================================= |
307 | BOOL CGonome :: CheckRangeAttack1 ( float flDot, float flDist ) |
309 | if ( IsMoving() && flDist >= 512 ) |
311 | // gonome will far too far behind if he stops running to spit at this distance from the enemy. |
315 | if ( flDist > 64 && flDist <= 784 && flDot >= 0.5 && gpGlobals->time >= m_flNextSpitTime ) |
320 | // don't spit again for a long time, resume chasing enemy. |
321 | m_flNextSpitTime = gpGlobals->time + 5; |
325 | // not moving, so spit again pretty soon. |
326 | m_flNextSpitTime = gpGlobals->time + 0.5; |
336 | //========================================================= |
337 | // ISoundMask - returns a bit mask indicating which types |
338 | // of sounds this monster regards. In the base class implementation, |
339 | // monsters care about all sounds, but no scents. |
340 | //========================================================= |
341 | int CGonome :: ISoundMask ( void ) |
343 | return bits_SOUND_WORLD | |
351 | //========================================================= |
352 | // Classify - indicates this monster's place in the |
353 | // relationship table. |
354 | //========================================================= |
355 | int CGonome :: Classify ( void ) |
357 | return CLASS_ALIEN_MONSTER; |
360 | //========================================================= |
362 | //========================================================= |
363 | #define GONOME_ATTN_IDLE (float)1.5 |
364 | void CGonome :: IdleSound ( void ) |
366 | switch ( RANDOM_LONG(0,2) ) |
369 | EMIT_SOUND( ENT(pev), CHAN_VOICE, "gonome/gonome_idle1.wav", 1, GONOME_ATTN_IDLE ); |
372 | EMIT_SOUND( ENT(pev), CHAN_VOICE, "gonome/gonome_idle2.wav", 1, GONOME_ATTN_IDLE ); |
375 | EMIT_SOUND( ENT(pev), CHAN_VOICE, "gonome/gonome_idle3.wav", 1, GONOME_ATTN_IDLE ); |
380 | //========================================================= |
382 | //========================================================= |
383 | void CGonome :: PainSound ( void ) |
385 | int iPitch = RANDOM_LONG( 85, 120 ); |
387 | switch ( RANDOM_LONG(0,3) ) |
390 | EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "gonome/gonome_pain1.wav", 1, ATTN_NORM, 0, iPitch ); |
393 | EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "gonome/gonome_pain2.wav", 1, ATTN_NORM, 0, iPitch ); |
396 | EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "gonome/gonome_pain3.wav", 1, ATTN_NORM, 0, iPitch ); |
399 | EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "gonome/gonome_pain4.wav", 1, ATTN_NORM, 0, iPitch ); |
404 | //========================================================= |
406 | //========================================================= |
407 | void CGonome :: AlertSound ( void ) |
409 | int iPitch = RANDOM_LONG( 140, 160 ); |
411 | switch ( RANDOM_LONG ( 0, 2 ) ) |
414 | EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "gonome/gonome_idle1.wav", 1, ATTN_NORM, 0, iPitch ); |
417 | EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "gonome/gonome_idle2.wav", 1, ATTN_NORM, 0, iPitch ); |
420 | EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "gonome/gonome_idle3.wav", 1, ATTN_NORM, 0, iPitch ); |
425 | //========================================================= |
426 | // SetYawSpeed - allows each sequence to have a different |
427 | // turn rate associated with it. |
428 | //========================================================= |
429 | void CGonome :: SetYawSpeed ( void ) |
435 | switch ( m_Activity ) |
437 | case ACT_WALK: ys = 120; break; |
438 | case ACT_RUN: ys = 120; break; |
439 | case ACT_IDLE: ys = 120; break; |
440 | case ACT_RANGE_ATTACK1: ys = 120; break; |
449 | //========================================================= |
450 | // HandleAnimEvent - catches the monster-specific messages |
451 | // that occur when tagged animation frames are played. |
452 | //========================================================= |
453 | void CGonome :: HandleAnimEvent( MonsterEvent_t *pEvent ) |
455 | switch( pEvent->event ) |
457 | case GONOMEE_AE_GUTS1: |
460 | Vector vecSpitOffset; |
461 | Vector vecGunPos, vecGunDir; |
463 | UTIL_MakeVectors ( pev->angles ); |
465 | GetAttachment ( 0, vecGunPos, vecGunDir ); |
467 | MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecGunPos/*vecSpitOffset*/ ); |
468 | WRITE_BYTE( TE_SPRITE ); |
469 | WRITE_COORD( pev->angles.x ); // pos |
470 | WRITE_COORD( pev->angles.y ); |
471 | WRITE_COORD( pev->angles.z ); |
472 | WRITE_SHORT( iGonomeSpitSprite ); // model |
473 | WRITE_BYTE( 6 ); // size * 10 |
474 | WRITE_BYTE( 128 ); // brightness |
480 | case GONOMEE_AE_GUTS2: |
482 | Vector vecSpitOffset; |
484 | Vector vecGunPos, vecGunDir; |
485 | Vector vecDirToEnemy; |
487 | UTIL_MakeAimVectors ( pev->angles ); |
489 | // !!!HACKHACK - the spot at which the spit originates (in front of the mouth) was measured in 3ds and hardcoded here. |
490 | // we should be able to read the position of bones at runtime for this info. |
491 | vecDirToEnemy = ( (( m_vecEnemyLKP ) - pev->origin) + gpGlobals->v_up * -96 +gpGlobals->v_right * -35 ).Normalize(); |
494 | // do stuff for this event. |
496 | GetAttachment ( 0, vecGunPos, vecGunDir ); |
498 | CGonomeSpit::Shoot( pev, vecGunPos, vecDirToEnemy * 900 ); //.\Profilehl/hl.dll m_vecEnemyLKP |
502 | case GONOMEE_AE_BITE1: |
503 | case GONOMEE_AE_BITE2: |
504 | case GONOMEE_AE_BITE3: |
505 | case GONOMEE_AE_BITE4: |
508 | CBaseEntity *pHurt = CheckTraceHullAttack( 70, gSkillData.gonomeDmgOneBite, DMG_SLASH ); |
512 | pHurt->pev->velocity = pHurt->pev->velocity - gpGlobals->v_forward * 100; |
513 | pHurt->pev->velocity = pHurt->pev->velocity + gpGlobals->v_up * 100; |
518 | case GONOMEE_AE_SLASH1: |
520 | CBaseEntity *pHurt = CheckTraceHullAttack( 70, gSkillData.gonomeDmgOneSlash, DMG_SLASH ); |
523 | if ( pHurt->pev->flags & (FL_MONSTER|FL_CLIENT) ) |
525 | pHurt->pev->punchangle.z = -18; |
526 | pHurt->pev->punchangle.x = 5; |
527 | pHurt->pev->velocity = pHurt->pev->velocity - gpGlobals->v_right * 100; |
530 | if (RANDOM_LONG(0,1)) |
535 | case GONOMEE_AE_SLASH2: |
537 | CBaseEntity *pHurt = CheckTraceHullAttack( 70, gSkillData.gonomeDmgOneSlash, DMG_SLASH ); |
540 | if ( pHurt->pev->flags & (FL_MONSTER|FL_CLIENT) ) |
542 | pHurt->pev->punchangle.z = 18; |
543 | pHurt->pev->punchangle.x = 5; |
544 | pHurt->pev->velocity = pHurt->pev->velocity + gpGlobals->v_right * 100; |
548 | if (RANDOM_LONG(0,1)) |
554 | CBaseMonster::HandleAnimEvent( pEvent ); |
558 | //========================================================= |
560 | //========================================================= |
561 | void CGonome :: Spawn() |
565 | SET_MODEL(ENT(pev), "models/gonome.mdl"); |
566 | UTIL_SetSize( pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX ); |
568 | pev->solid = SOLID_SLIDEBOX; |
569 | pev->movetype = MOVETYPE_STEP; |
570 | m_bloodColor = BLOOD_COLOR_GREEN; |
572 | pev->health = gSkillData.gonomeHealth; |
573 | pev->view_ofs = VEC_VIEW;// position of the eyes relative to monster's origin. |
574 | m_flFieldOfView = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result ) |
575 | m_MonsterState = MONSTERSTATE_NONE; |
577 | m_fCanThreatDisplay = TRUE; |
578 | m_flNextSpitTime = gpGlobals->time; |
583 | //========================================================= |
584 | // Precache - precaches all resources this monster needs |
585 | //========================================================= |
586 | void CGonome :: Precache() |
588 | PRECACHE_MODEL("models/gonome.mdl"); |
590 | PRECACHE_MODEL("sprites/blood_chnk.spr");// spit projectile. |
592 | iGonomeSpitSprite = PRECACHE_MODEL("sprites/blood_tinyspit.spr");// client side spittle. |
594 | PRECACHE_SOUND("zombie/claw_miss2.wav");// because we use the basemonster SWIPE animation event |
596 | PRECACHE_SOUND("gonome/gonome_melee1.wav"); |
597 | PRECACHE_SOUND("gonome/gonome_melee2.wav"); |
599 | PRECACHE_SOUND("gonome/gonome_death2.wav"); |
600 | PRECACHE_SOUND("gonome/gonome_death3.wav"); |
601 | PRECACHE_SOUND("gonome/gonome_death4.wav"); |
603 | PRECACHE_SOUND("gonome/gonome_idle1.wav"); |
604 | PRECACHE_SOUND("gonome/gonome_idle2.wav"); |
605 | PRECACHE_SOUND("gonome/gonome_idle3.wav"); |
607 | PRECACHE_SOUND("gonome/gonome_pain1.wav"); |
608 | PRECACHE_SOUND("gonome/gonome_pain2.wav"); |
609 | PRECACHE_SOUND("gonome/gonome_pain3.wav"); |
610 | PRECACHE_SOUND("gonome/gonome_pain4.wav"); |
612 | PRECACHE_SOUND("gonome/gonome_jumpattack.wav"); |
614 | PRECACHE_SOUND("gonome/gonome_run.wav"); |
615 | PRECACHE_SOUND("gonome/gonome_eat.wav"); |
617 | PRECACHE_SOUND("bullchicken/bc_spithit1.wav"); |
618 | PRECACHE_SOUND("bullchicken/bc_spithit2.wav"); |
620 | PRECACHE_SOUND("bullchicken/bc_attack1.wav"); |
621 | PRECACHE_SOUND("bullchicken/bc_attack2.wav"); |
622 | PRECACHE_SOUND("bullchicken/bc_attack3.wav"); |
626 | //========================================================= |
628 | //========================================================= |
629 | void CGonome :: DeathSound ( void ) |
631 | switch ( RANDOM_LONG(0,2) ) |
634 | EMIT_SOUND( ENT(pev), CHAN_VOICE, "gonome/gonome_death2.wav", 1, ATTN_NORM ); |
637 | EMIT_SOUND( ENT(pev), CHAN_VOICE, "gonome/gonome_death3.wav", 1, ATTN_NORM ); |
640 | EMIT_SOUND( ENT(pev), CHAN_VOICE, "gonome/gonome_death4.wav", 1, ATTN_NORM ); |
645 | //========================================================= |
647 | //========================================================= |
648 | void CGonome :: AttackSound ( void ) |
650 | switch ( RANDOM_LONG(0,2) ) |
653 | EMIT_SOUND( ENT(pev), CHAN_WEAPON, "bullchicken/bc_attack1.wav", 1, ATTN_NORM ); |
656 | EMIT_SOUND( ENT(pev), CHAN_WEAPON, "bullchicken/bc_attack2.wav", 1, ATTN_NORM ); |
659 | EMIT_SOUND( ENT(pev), CHAN_WEAPON, "bullchicken/bc_attack3.wav", 1, ATTN_NORM ); |
665 | //======================================================== |
666 | // RunAI - overridden for gonome because there are things |
667 | // that need to be checked every think. |
668 | //======================================================== |
669 | void CGonome :: RunAI ( void ) |
671 | // first, do base class stuff |
672 | CBaseMonster :: RunAI(); |
674 | if ( m_hEnemy != NULL && m_Activity == ACT_RUN ) |
676 | // chasing enemy. Sprint for last bit |
677 | if ( (pev->origin - m_hEnemy->pev->origin).Length2D() < GONOME_SPRINT_DIST ) |
679 | pev->framerate = 1.25; |
685 | //======================================================== |
686 | // AI Schedules Specific to this monster |
687 | //========================================================= |
689 | // primary range attack |
690 | Task_t tlGonomeRangeAttack1[] = |
692 | { TASK_STOP_MOVING, 0 }, |
693 | { TASK_FACE_IDEAL, (float)0 }, |
694 | { TASK_RANGE_ATTACK1, (float)0 }, |
695 | { TASK_SET_ACTIVITY, (float)ACT_IDLE }, |
698 | Schedule_t slGonomeRangeAttack1[] = |
701 | tlGonomeRangeAttack1, |
702 | ARRAYSIZE ( tlGonomeRangeAttack1 ), |
703 | bits_COND_NEW_ENEMY | |
704 | bits_COND_ENEMY_DEAD | |
705 | bits_COND_HEAVY_DAMAGE | |
706 | bits_COND_ENEMY_OCCLUDED | |
707 | bits_COND_NO_AMMO_LOADED, |
709 | "Gonome Range Attack1" |
713 | // Chase enemy schedule |
714 | Task_t tlGonomeChaseEnemy1[] = |
716 | { TASK_SET_FAIL_SCHEDULE, (float)SCHED_RANGE_ATTACK1 },// !!!OEM - this will stop nasty gonome oscillation. |
717 | { TASK_GET_PATH_TO_ENEMY, (float)0 }, |
718 | { TASK_RUN_PATH, (float)0 }, |
719 | { TASK_WAIT_FOR_MOVEMENT, (float)0 }, |
722 | Schedule_t slGonomeChaseEnemy[] = |
726 | ARRAYSIZE ( tlGonomeChaseEnemy1 ), |
727 | bits_COND_NEW_ENEMY | |
728 | bits_COND_ENEMY_DEAD | |
729 | bits_COND_SMELL_FOOD | |
730 | bits_COND_CAN_RANGE_ATTACK1 | |
731 | bits_COND_CAN_MELEE_ATTACK1 | |
732 | bits_COND_CAN_MELEE_ATTACK2 | |
733 | bits_COND_TASK_FAILED | |
734 | bits_COND_HEAR_SOUND, |
743 | // gonome walks to something tasty and eats it. |
744 | Task_t tlGonomeEat[] = |
746 | { TASK_STOP_MOVING, (float)0 }, |
747 | { TASK_EAT, (float)10 },// this is in case the gonome can't get to the food |
748 | { TASK_STORE_LASTPOSITION, (float)0 }, |
749 | { TASK_GET_PATH_TO_BESTSCENT, (float)0 }, |
750 | { TASK_WALK_PATH, (float)0 }, |
751 | { TASK_WAIT_FOR_MOVEMENT, (float)0 }, |
752 | { TASK_PLAY_SEQUENCE, (float)ACT_EAT }, |
753 | { TASK_PLAY_SEQUENCE, (float)ACT_EAT }, |
754 | { TASK_PLAY_SEQUENCE, (float)ACT_EAT }, |
755 | { TASK_EAT, (float)50 }, |
756 | { TASK_GET_PATH_TO_LASTPOSITION,(float)0 }, |
757 | { TASK_WALK_PATH, (float)0 }, |
758 | { TASK_WAIT_FOR_MOVEMENT, (float)0 }, |
759 | { TASK_CLEAR_LASTPOSITION, (float)0 }, |
762 | Schedule_t slGonomeEat[] = |
766 | ARRAYSIZE( tlGonomeEat ), |
767 | bits_COND_LIGHT_DAMAGE | |
768 | bits_COND_HEAVY_DAMAGE | |
769 | bits_COND_NEW_ENEMY , |
771 | // even though HEAR_SOUND/SMELL FOOD doesn't break this schedule, we need this mask |
772 | // here or the monster won't detect these sounds at ALL while running this schedule. |
779 | // this is a bit different than just Eat. We use this schedule when the food is far away, occluded, or behind |
780 | // the gonome. This schedule plays a sniff animation before going to the source of food. |
781 | Task_t tlGonomeSniffAndEat[] = |
783 | { TASK_STOP_MOVING, (float)0 }, |
784 | { TASK_EAT, (float)10 },// this is in case the gonome can't get to the food |
785 | { TASK_PLAY_SEQUENCE, (float)ACT_DETECT_SCENT }, |
786 | { TASK_STORE_LASTPOSITION, (float)0 }, |
787 | { TASK_GET_PATH_TO_BESTSCENT, (float)0 }, |
788 | { TASK_WALK_PATH, (float)0 }, |
789 | { TASK_WAIT_FOR_MOVEMENT, (float)0 }, |
790 | { TASK_PLAY_SEQUENCE, (float)ACT_EAT }, |
791 | { TASK_PLAY_SEQUENCE, (float)ACT_EAT }, |
792 | { TASK_PLAY_SEQUENCE, (float)ACT_EAT }, |
793 | { TASK_EAT, (float)50 }, |
794 | { TASK_GET_PATH_TO_LASTPOSITION,(float)0 }, |
795 | { TASK_WALK_PATH, (float)0 }, |
796 | { TASK_WAIT_FOR_MOVEMENT, (float)0 }, |
797 | { TASK_CLEAR_LASTPOSITION, (float)0 }, |
800 | Schedule_t slGonomeSniffAndEat[] = |
804 | ARRAYSIZE( tlGonomeSniffAndEat ), |
805 | bits_COND_LIGHT_DAMAGE | |
806 | bits_COND_HEAVY_DAMAGE | |
807 | bits_COND_NEW_ENEMY , |
809 | // even though HEAR_SOUND/SMELL FOOD doesn't break this schedule, we need this mask |
810 | // here or the monster won't detect these sounds at ALL while running this schedule. |
817 | // gonome does this to stinky things. |
818 | Task_t tlGonomeWallow[] = |
820 | { TASK_STOP_MOVING, (float)0 }, |
821 | { TASK_EAT, (float)10 },// this is in case the gonome can't get to the stinkiness |
822 | { TASK_STORE_LASTPOSITION, (float)0 }, |
823 | { TASK_GET_PATH_TO_BESTSCENT, (float)0 }, |
824 | { TASK_WALK_PATH, (float)0 }, |
825 | { TASK_WAIT_FOR_MOVEMENT, (float)0 }, |
826 | { TASK_PLAY_SEQUENCE, (float)ACT_INSPECT_FLOOR}, |
827 | { TASK_EAT, (float)50 },// keeps gonome from eating or sniffing anything else for a while. |
828 | { TASK_GET_PATH_TO_LASTPOSITION,(float)0 }, |
829 | { TASK_WALK_PATH, (float)0 }, |
830 | { TASK_WAIT_FOR_MOVEMENT, (float)0 }, |
831 | { TASK_CLEAR_LASTPOSITION, (float)0 }, |
834 | Schedule_t slGonomeWallow[] = |
838 | ARRAYSIZE( tlGonomeWallow ), |
839 | bits_COND_LIGHT_DAMAGE | |
840 | bits_COND_HEAVY_DAMAGE | |
841 | bits_COND_NEW_ENEMY , |
843 | // even though HEAR_SOUND/SMELL FOOD doesn't break this schedule, we need this mask |
844 | // here or the monster won't detect these sounds at ALL while running this schedule. |
851 | DEFINE_CUSTOM_SCHEDULES( CGonome ) |
853 | slGonomeRangeAttack1, |
860 | IMPLEMENT_CUSTOM_SCHEDULES( CGonome, CBaseMonster ); |
862 | //========================================================= |
864 | //========================================================= |
865 | Schedule_t *CGonome :: GetSchedule( void ) |
867 | switch ( m_MonsterState ) |
869 | case MONSTERSTATE_ALERT: |
872 | if ( HasConditions(bits_COND_SMELL_FOOD) ) |
876 | pSound = PBestScent(); |
878 | if ( pSound && (!FInViewCone ( &pSound->m_vecOrigin ) || !FVisible ( pSound->m_vecOrigin )) ) |
880 | // scent is behind or occluded |
881 | return GetScheduleOfType( SCHED_GONOME_SNIFF_AND_EAT ); |
884 | // food is right out in the open. Just go get it. |
885 | return GetScheduleOfType( SCHED_GONOME_EAT ); |
888 | if ( HasConditions(bits_COND_SMELL) ) |
890 | // there's something stinky. |
893 | pSound = PBestScent(); |
895 | return GetScheduleOfType( SCHED_GONOME_WALLOW); |
900 | case MONSTERSTATE_COMBAT: |
903 | if ( HasConditions( bits_COND_ENEMY_DEAD ) ) |
905 | // call base class, all code to handle dead enemies is centralized there. |
906 | return CBaseMonster :: GetSchedule(); |
909 | if ( HasConditions(bits_COND_NEW_ENEMY) ) |
911 | if ( m_fCanThreatDisplay && IRelationship( m_hEnemy ) == R_HT ) |
913 | return GetScheduleOfType ( SCHED_WAKE_ANGRY ); |
917 | if ( HasConditions(bits_COND_SMELL_FOOD) ) |
921 | pSound = PBestScent(); |
923 | if ( pSound && (!FInViewCone ( &pSound->m_vecOrigin ) || !FVisible ( pSound->m_vecOrigin )) ) |
925 | // scent is behind or occluded |
926 | return GetScheduleOfType( SCHED_GONOME_SNIFF_AND_EAT ); |
929 | // food is right out in the open. Just go get it. |
930 | return GetScheduleOfType( SCHED_GONOME_EAT ); |
933 | if ( HasConditions( bits_COND_CAN_RANGE_ATTACK1 ) ) |
935 | return GetScheduleOfType ( SCHED_RANGE_ATTACK1 ); |
938 | if ( HasConditions( bits_COND_CAN_MELEE_ATTACK1 ) ) |
940 | return GetScheduleOfType ( SCHED_MELEE_ATTACK1 ); |
943 | if ( HasConditions( bits_COND_CAN_MELEE_ATTACK2 ) ) |
945 | return GetScheduleOfType ( SCHED_MELEE_ATTACK2 ); |
948 | return GetScheduleOfType ( SCHED_CHASE_ENEMY ); |
954 | return CBaseMonster :: GetSchedule(); |
957 | //========================================================= |
959 | //========================================================= |
960 | Schedule_t* CGonome :: GetScheduleOfType ( int Type ) |
964 | case SCHED_RANGE_ATTACK1: |
965 | return &slGonomeRangeAttack1[ 0 ]; |
967 | case SCHED_GONOME_EAT: |
968 | return &slGonomeEat[ 0 ]; |
970 | case SCHED_GONOME_SNIFF_AND_EAT: |
971 | return &slGonomeSniffAndEat[ 0 ]; |
973 | case SCHED_GONOME_WALLOW: |
974 | return &slGonomeWallow[ 0 ]; |
976 | case SCHED_CHASE_ENEMY: |
977 | return &slGonomeChaseEnemy[ 0 ]; |
981 | return CBaseMonster :: GetScheduleOfType ( Type ); |
984 | //========================================================= |
985 | // Start task - selects the correct activity and performs |
986 | // any necessary calculations to start the next task on the |
987 | // schedule. OVERRIDDEN for gonome because it needs to |
988 | // know explicitly when the last attempt to chase the enemy |
989 | // failed, since that impacts its attack choices. |
990 | //========================================================= |
991 | void CGonome :: StartTask ( Task_t *pTask ) |
993 | m_iTaskStatus = TASKSTATUS_RUNNING; |
995 | switch ( pTask->iTask ) |
997 | case TASK_MELEE_ATTACK2: |
999 | switch ( RANDOM_LONG ( 0, 1 ) ) |
1002 | EMIT_SOUND( ENT(pev), CHAN_VOICE, "gonome/gonome_melee1.wav", 1, ATTN_NORM ); |
1005 | EMIT_SOUND( ENT(pev), CHAN_VOICE, "gonome/gonome_melee2.wav", 1, ATTN_NORM ); |
1009 | CBaseMonster :: StartTask ( pTask ); |
1012 | case TASK_GET_PATH_TO_ENEMY: |
1014 | if ( BuildRoute ( m_hEnemy->pev->origin, bits_MF_TO_ENEMY, m_hEnemy ) ) |
1016 | m_iTaskStatus = TASKSTATUS_COMPLETE; |
1020 | ALERT ( at_aiconsole, "GetPathToEnemy failed!!\n" ); |
1027 | CBaseMonster :: StartTask ( pTask ); |
1033 | //========================================================= |
1035 | //========================================================= |
1036 | void CGonome :: RunTask ( Task_t *pTask ) |
1039 | CBaseMonster :: RunTask( pTask ); |
1044 | //========================================================= |
1045 | // GetIdealState - Overridden for Gonome to deal with |
1046 | // the feature that makes it lose interest in headcrabs for |
1047 | // a while if something injures it. |
1048 | //========================================================= |
1049 | MONSTERSTATE CGonome :: GetIdealState ( void ) |
1053 | iConditions = IScheduleFlags(); |
1055 | m_IdealMonsterState = CBaseMonster :: GetIdealState(); |
1057 | return m_IdealMonsterState; |
За это сообщение SteamPlay43 получил предупреждение за оверквотинг
Сообщить модератору | | IP: Записан
Сообщение: 121940
|