HLFX.Ru Forum
профиль •  правила •  регистрация •  календарь •  народ •  FAQ •  поиск •  новое •  сутки •  главная •  выход  
HLFX.Ru Forum HLFX.Ru Forum > Теория и практика > Half-Life SDK > Решил добавить в мод новых монстров.
Скачал гонома с сдкопфора но он глючный!
  Предыдущая тема   Следующая тема
Автор
Тема Новая тема    Ответить
SteamPlay43
Житель форума

Группа: Неопытный
Дата регистрации: May 2012
Проживает: Барнаул
Сообщений: 273
Возраст: 26

Рейтинг



Решил добавить в мод новых монстров.

Вообщем гоном вместо проигрывания звуков атаки руками проигрывает звук выкидывания кровяного шара!

C++ Source Code:
1
//=========================================================
2
// Opposing Forces Monster Gonome
3
//
4
// Made by Demiurge
5
//
6
//FGD monster_gonome
7
//=========================================================
8
//=========================================================
9
// gonome - big hypermutated zombie.
10
//=========================================================
11
 
12
#include	"extdll.h"
13
#include	"util.h"
14
#include	"cbase.h"
15
#include	"monsters.h"
16
#include	"schedule.h"
17
#include	"nodes.h"
18
#include	"effects.h"
19
#include	"decals.h"
20
#include	"soundent.h"
21
#include	"game.h"
22
 
23
#define		GONOME_SPRINT_DIST	256
24
 
25
int			   iGonomeSpitSprite;
26
 
27
 
28
//=========================================================
29
// monster-specific schedule types
30
//=========================================================
31
enum
32
{
33
  SCHED_GONOME_SMELLFOOD = LAST_COMMON_SCHEDULE + 1,
34
  SCHED_GONOME_EAT,
35
  SCHED_GONOME_SNIFF_AND_EAT,
36
  SCHED_GONOME_WALLOW,
37
};
38
 
39
//=========================================================
40
// monster-specific tasks
41
//=========================================================
42
enum
43
{
44
  TASK_GONOME_SMELLFOOD = LAST_COMMON_SCHEDULE + 1,
45
};
46
 
47
//=========================================================
48
// Gonome's spit projectile
49
//=========================================================
50
class CGonomeSpit : public CBaseEntity
51
{
52
public:
53
  void Spawn( void );
54
 
55
  static void Shoot( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity );
56
  void Touch( CBaseEntity *pOther );
57
  void EXPORT Animate( void );
58
 
59
  virtual int		Save( CSave &save );
60
  virtual int		Restore( CRestore &restore );
61
  static	TYPEDESCRIPTION m_SaveData[];
62
 
63
  int  m_maxFrame;
64
};
65
 
66
LINK_ENTITY_TO_CLASS( gonomespit, CGonomeSpit );
67
 
68
TYPEDESCRIPTION	CGonomeSpit::m_SaveData[] =
69
{
70
  DEFINE_FIELD( CGonomeSpit, m_maxFrame, FIELD_INTEGER ),
71
};
72
 
73
IMPLEMENT_SAVERESTORE( CGonomeSpit, CBaseEntity );
74
 
75
void CGonomeSpit:: Spawn( void )
76
{
77
  pev->movetype = MOVETYPE_FLY;
78
  pev->classname = MAKE_STRING( "gonomespit" );
79
 
80
  pev->solid = SOLID_BBOX;
81
  pev->rendermode = kRenderTransAlpha;
82
  pev->renderamt = 255;
83
 
84
  SET_MODEL(ENT(pev), "sprites/blood_chnk.spr");
85
  pev->frame = 0;
86
  pev->scale = 0.5;
87
 
88
  UTIL_SetSize( pev, Vector( 0, 0, 0), Vector(0, 0, 0) );
89
 
90
  m_maxFrame = (float) MODEL_FRAMES( pev->modelindex ) - 1;
91
}
92
 
93
void CGonomeSpit::Animate( void )
94
{
95
  pev->nextthink = gpGlobals->time + 0.1;
96
 
97
  if ( pev->frame++ )
98
  {
99
    if ( pev->frame > m_maxFrame )
100
    {
101
      pev->frame = 0;
102
    }
103
  }
104
}
105
 
106
void CGonomeSpit::Shoot( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity )
107
{
108
  CGonomeSpit *pGSpit = GetClassPtr( (CGonomeSpit *)NULL );
109
  pGSpit->Spawn();
110
 
111
  UTIL_SetOrigin( pGSpit->pev, vecStart );
112
  pGSpit->pev->velocity = vecVelocity;
113
  pGSpit->pev->owner = ENT(pevOwner);
114
 
115
  pGSpit->SetThink ( Animate );
116
  pGSpit->pev->nextthink = gpGlobals->time + 0.1;
117
}
118
 
119
void CGonomeSpit :: Touch ( CBaseEntity *pOther )
120
{
121
  TraceResult tr;
122
  int		iPitch;
123
 
124
  // splat sound
125
  iPitch = RANDOM_FLOAT( 90, 110 );
126
 
127
  switch ( RANDOM_LONG( 0, 1 ) )
128
  {
129
  case 0:
130
      EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "bullchicken/bc_spithit1.wav", 1, ATTN_NORM, 0, iPitch );
131
    break;
132
  case 1:
133
      EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "bullchicken/bc_spithit2.wav", 1, ATTN_NORM, 0, iPitch );
134
    break;
135
  }
136
 
137
  if ( !pOther->pev->takedamage )
138
  {
139
 
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));
143
 
144
    // make some flecks
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 )
157
    MESSAGE_END();
158
  }
159
  else
160
  {
161
    pOther->TakeDamage ( pev, pev, gSkillData.gonomeDmgGuts, DMG_GENERIC );
162
  }
163
 
164
  SetThink ( SUB_Remove );
165
  pev->nextthink = gpGlobals->time;
166
}
167
 
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 )
188
 
189
#define GONOME_FLINCH_DELAY			2		// at most one flinch every n secs
190
 
191
class CGonome : public CBaseMonster
192
{
193
public:
194
  void Spawn( void );
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 );
208
  void RunAI( void );
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 );
215
 
216
  int	Save( CSave &save );
217
  int Restore( CRestore &restore );
218
 
219
  CUSTOM_SCHEDULES;
220
  static TYPEDESCRIPTION m_SaveData[];
221
 
222
  BOOL m_fCanThreatDisplay;// this is so the gonome only does the "I see a headcrab!" dance one time.
223
 
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;
227
};
228
LINK_ENTITY_TO_CLASS( monster_gonome, CGonome );
229
 
230
TYPEDESCRIPTION	CGonome::m_SaveData[] =
231
{
232
  DEFINE_FIELD( CGonome, m_fCanThreatDisplay, FIELD_BOOLEAN ),
233
  DEFINE_FIELD( CGonome, m_flLastHurtTime, FIELD_TIME ),
234
  DEFINE_FIELD( CGonome, m_flNextSpitTime, FIELD_TIME ),
235
};
236
 
237
IMPLEMENT_SAVERESTORE( CGonome, CBaseMonster );
238
 
239
//=========================================================
240
// IgnoreConditions
241
//=========================================================
242
int CGonome::IgnoreConditions ( void )
243
{
244
  int iIgnore = CBaseMonster::IgnoreConditions();
245
 
246
  if ((m_Activity == ACT_MELEE_ATTACK1) || (m_Activity == ACT_MELEE_ATTACK1))
247
  {
248
#if 0
249
    if (pev->health < 20)
250
      iIgnore |= (bits_COND_LIGHT_DAMAGE|bits_COND_HEAVY_DAMAGE);
251
    else
252
#endif
253
    if (m_flNextFlinch >= gpGlobals->time)
254
      iIgnore |= (bits_COND_LIGHT_DAMAGE|bits_COND_HEAVY_DAMAGE);
255
  }
256
 
257
  if ((m_Activity == ACT_SMALL_FLINCH) || (m_Activity == ACT_BIG_FLINCH))
258
  {
259
    if (m_flNextFlinch < gpGlobals->time)
260
      m_flNextFlinch = gpGlobals->time + GONOME_FLINCH_DELAY;
261
  }
262
 
263
  return iIgnore;
264
 
265
}
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 )
271
{
272
  return CBaseMonster :: IRelationship ( pTarget );
273
}
274
 
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 )
280
{
281
  float flDist;
282
  Vector vecApex;
283
 
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 )
287
  {
288
    flDist = ( pev->origin - m_hEnemy->pev->origin ).Length2D();
289
 
290
    if ( flDist > GONOME_SPRINT_DIST )
291
    {
292
      flDist = ( pev->origin - m_Route[ m_iRouteIndex ].vecLocation ).Length2D();// reusing flDist.
293
 
294
      if ( FTriangulate( pev->origin, m_Route[ m_iRouteIndex ].vecLocation, flDist * 0.5, m_hEnemy, &vecApex ) )
295
      {
296
        InsertWaypoint( vecApex, bits_MF_TO_DETOUR | bits_MF_DONT_SIMPLIFY );
297
      }
298
    }
299
  }
300
 
301
  return CBaseMonster :: TakeDamage ( pevInflictor, pevAttacker, flDamage, bitsDamageType );
302
}
303
 
304
//=========================================================
305
// CheckRangeAttack1
306
//=========================================================
307
BOOL CGonome :: CheckRangeAttack1 ( float flDot, float flDist )
308
{
309
  if ( IsMoving() && flDist >= 512 )
310
  {
311
    // gonome will far too far behind if he stops running to spit at this distance from the enemy.
312
    return FALSE;
313
  }
314
 
315
  if ( flDist > 64 && flDist <= 784 && flDot >= 0.5 && gpGlobals->time >= m_flNextSpitTime )
316
  {
317
 
318
    if ( IsMoving() )
319
    {
320
      // don't spit again for a long time, resume chasing enemy.
321
      m_flNextSpitTime = gpGlobals->time + 5;
322
    }
323
    else
324
    {
325
      // not moving, so spit again pretty soon.
326
      m_flNextSpitTime = gpGlobals->time + 0.5;
327
    }
328
 
329
    return TRUE;
330
  }
331
 
332
  return FALSE;
333
 
334
}
335
 
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 )
342
{
343
  return	bits_SOUND_WORLD	|
344
  bits_SOUND_COMBAT	|
345
  bits_SOUND_CARCASS	|
346
  bits_SOUND_MEAT		|
347
  bits_SOUND_GARBAGE	|
348
  bits_SOUND_PLAYER;
349
}
350
 
351
//=========================================================
352
// Classify - indicates this monster's place in the
353
// relationship table.
354
//=========================================================
355
int	CGonome :: Classify ( void )
356
{
357
  return	CLASS_ALIEN_MONSTER;
358
}
359
 
360
//=========================================================
361
// IdleSound
362
//=========================================================
363
#define GONOME_ATTN_IDLE	(float)1.5
364
void CGonome :: IdleSound ( void )
365
{
366
  switch ( RANDOM_LONG(0,2) )
367
  {
368
  case 0:
369
      EMIT_SOUND( ENT(pev), CHAN_VOICE, "gonome/gonome_idle1.wav", 1, GONOME_ATTN_IDLE );
370
    break;
371
  case 1:
372
      EMIT_SOUND( ENT(pev), CHAN_VOICE, "gonome/gonome_idle2.wav", 1, GONOME_ATTN_IDLE );
373
    break;
374
  case 2:
375
      EMIT_SOUND( ENT(pev), CHAN_VOICE, "gonome/gonome_idle3.wav", 1, GONOME_ATTN_IDLE );
376
    break;
377
  }
378
}
379
 
380
//=========================================================
381
// PainSound
382
//=========================================================
383
void CGonome :: PainSound ( void )
384
{
385
  int iPitch = RANDOM_LONG( 85, 120 );
386
 
387
  switch ( RANDOM_LONG(0,3) )
388
  {
389
  case 0:
390
      EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "gonome/gonome_pain1.wav", 1, ATTN_NORM, 0, iPitch );
391
    break;
392
  case 1:
393
      EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "gonome/gonome_pain2.wav", 1, ATTN_NORM, 0, iPitch );
394
    break;
395
  case 2:
396
      EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "gonome/gonome_pain3.wav", 1, ATTN_NORM, 0, iPitch );
397
    break;
398
  case 3:
399
      EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "gonome/gonome_pain4.wav", 1, ATTN_NORM, 0, iPitch );
400
    break;
401
  }
402
}
403
 
404
//=========================================================
405
// AlertSound
406
//=========================================================
407
void CGonome :: AlertSound ( void )
408
{
409
  int iPitch = RANDOM_LONG( 140, 160 );
410
 
411
  switch ( RANDOM_LONG ( 0, 2  ) )
412
  {
413
  case 0:
414
      EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "gonome/gonome_idle1.wav", 1, ATTN_NORM, 0, iPitch );
415
    break;
416
  case 1:
417
      EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "gonome/gonome_idle2.wav", 1, ATTN_NORM, 0, iPitch );
418
    break;
419
  case 2:
420
      EMIT_SOUND_DYN( ENT(pev), CHAN_VOICE, "gonome/gonome_idle3.wav", 1, ATTN_NORM, 0, iPitch );
421
    break;
422
  }
423
}
424
 
425
//=========================================================
426
// SetYawSpeed - allows each sequence to have a different
427
// turn rate associated with it.
428
//=========================================================
429
void CGonome :: SetYawSpeed ( void )
430
{
431
  int ys;
432
 
433
  ys = 0;
434
 
435
  switch ( m_Activity )
436
  {
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;
441
  default:
442
      ys = 120;
443
    break;
444
  }
445
 
446
  pev->yaw_speed = ys;
447
}
448
 
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 )
454
{
455
  switch( pEvent->event )
456
  {
457
  case GONOMEE_AE_GUTS1:
458
    {
459
 
460
      Vector	vecSpitOffset;
461
      Vector  vecGunPos, vecGunDir;
462
 
463
      UTIL_MakeVectors ( pev->angles );
464
 
465
      GetAttachment ( 0, vecGunPos, vecGunDir );
466
 
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
475
      MESSAGE_END();
476
 
477
    }
478
    break;
479
 
480
  case GONOMEE_AE_GUTS2:
481
    {
482
      Vector	vecSpitOffset;
483
      Vector	vecSpitDir;
484
      Vector  vecGunPos, vecGunDir;
485
      Vector	vecDirToEnemy;
486
 
487
      UTIL_MakeAimVectors ( pev->angles );
488
 
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();
492
 
493
 
494
      // do stuff for this event.
495
        AttackSound();
496
      GetAttachment ( 0, vecGunPos, vecGunDir );
497
 
498
      CGonomeSpit::Shoot( pev, vecGunPos, vecDirToEnemy * 900 ); //.\Profilehl/hl.dll m_vecEnemyLKP
499
    }
500
    break;
501
 
502
  case GONOMEE_AE_BITE1:
503
    case GONOMEE_AE_BITE2:
504
      case GONOMEE_AE_BITE3:
505
        case GONOMEE_AE_BITE4:
506
          {
507
            // SOUND HERE!
508
            CBaseEntity *pHurt = CheckTraceHullAttack( 70, gSkillData.gonomeDmgOneBite, DMG_SLASH );
509
 
510
      if ( pHurt )
511
      {
512
        pHurt->pev->velocity = pHurt->pev->velocity - gpGlobals->v_forward * 100;
513
        pHurt->pev->velocity = pHurt->pev->velocity + gpGlobals->v_up * 100;
514
      }
515
    }
516
    break;
517
 
518
  case GONOMEE_AE_SLASH1:
519
    {
520
      CBaseEntity *pHurt = CheckTraceHullAttack( 70, gSkillData.gonomeDmgOneSlash, DMG_SLASH );
521
      if ( pHurt )
522
      {
523
        if ( pHurt->pev->flags & (FL_MONSTER|FL_CLIENT) )
524
        {
525
          pHurt->pev->punchangle.z = -18;
526
          pHurt->pev->punchangle.x = 5;
527
          pHurt->pev->velocity = pHurt->pev->velocity - gpGlobals->v_right * 100;
528
        }
529
 
530
        if (RANDOM_LONG(0,1))
531
          AttackSound();
532
      }
533
    }
534
    break;
535
  case GONOMEE_AE_SLASH2:
536
    {
537
      CBaseEntity *pHurt = CheckTraceHullAttack( 70, gSkillData.gonomeDmgOneSlash, DMG_SLASH );
538
      if ( pHurt )
539
      {
540
        if ( pHurt->pev->flags & (FL_MONSTER|FL_CLIENT) )
541
        {
542
          pHurt->pev->punchangle.z = 18;
543
          pHurt->pev->punchangle.x = 5;
544
          pHurt->pev->velocity = pHurt->pev->velocity + gpGlobals->v_right * 100;
545
        }
546
      }
547
 
548
      if (RANDOM_LONG(0,1))
549
        AttackSound();
550
    }
551
    break;
552
 
553
  default:
554
      CBaseMonster::HandleAnimEvent( pEvent );
555
  }
556
}
557
 
558
//=========================================================
559
// Spawn
560
//=========================================================
561
void CGonome :: Spawn()
562
{
563
  Precache( );
564
 
565
  SET_MODEL(ENT(pev), "models/gonome.mdl");
566
  UTIL_SetSize( pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX );
567
 
568
  pev->solid			= SOLID_SLIDEBOX;
569
  pev->movetype		= MOVETYPE_STEP;
570
  m_bloodColor		= BLOOD_COLOR_GREEN;
571
  pev->effects		= 0;
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;
576
 
577
  m_fCanThreatDisplay	= TRUE;
578
  m_flNextSpitTime = gpGlobals->time;
579
 
580
  MonsterInit();
581
}
582
 
583
//=========================================================
584
// Precache - precaches all resources this monster needs
585
//=========================================================
586
void CGonome :: Precache()
587
{
588
  PRECACHE_MODEL("models/gonome.mdl");
589
 
590
  PRECACHE_MODEL("sprites/blood_chnk.spr");// spit projectile.
591
 
592
  iGonomeSpitSprite = PRECACHE_MODEL("sprites/blood_tinyspit.spr");// client side spittle.
593
 
594
  PRECACHE_SOUND("zombie/claw_miss2.wav");// because we use the basemonster SWIPE animation event
595
 
596
  PRECACHE_SOUND("gonome/gonome_melee1.wav");
597
  PRECACHE_SOUND("gonome/gonome_melee2.wav");
598
 
599
  PRECACHE_SOUND("gonome/gonome_death2.wav");
600
  PRECACHE_SOUND("gonome/gonome_death3.wav");
601
  PRECACHE_SOUND("gonome/gonome_death4.wav");
602
 
603
  PRECACHE_SOUND("gonome/gonome_idle1.wav");
604
  PRECACHE_SOUND("gonome/gonome_idle2.wav");
605
  PRECACHE_SOUND("gonome/gonome_idle3.wav");
606
 
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");
611
 
612
  PRECACHE_SOUND("gonome/gonome_jumpattack.wav");
613
 
614
  PRECACHE_SOUND("gonome/gonome_run.wav");
615
  PRECACHE_SOUND("gonome/gonome_eat.wav");
616
 
617
  PRECACHE_SOUND("bullchicken/bc_spithit1.wav");
618
  PRECACHE_SOUND("bullchicken/bc_spithit2.wav");
619
 
620
  PRECACHE_SOUND("bullchicken/bc_attack1.wav");
621
  PRECACHE_SOUND("bullchicken/bc_attack2.wav");
622
  PRECACHE_SOUND("bullchicken/bc_attack3.wav");
623
 
624
}
625
 
626
//=========================================================
627
// DeathSound
628
//=========================================================
629
void CGonome :: DeathSound ( void )
630
{
631
  switch ( RANDOM_LONG(0,2) )
632
  {
633
  case 0:
634
      EMIT_SOUND( ENT(pev), CHAN_VOICE, "gonome/gonome_death2.wav", 1, ATTN_NORM );
635
    break;
636
  case 1:
637
      EMIT_SOUND( ENT(pev), CHAN_VOICE, "gonome/gonome_death3.wav", 1, ATTN_NORM );
638
    break;
639
  case 2:
640
      EMIT_SOUND( ENT(pev), CHAN_VOICE, "gonome/gonome_death4.wav", 1, ATTN_NORM );
641
    break;
642
  }
643
}
644
 
645
//=========================================================
646
// AttackSound
647
//=========================================================
648
void CGonome :: AttackSound ( void )
649
{
650
  switch ( RANDOM_LONG(0,2) )
651
  {
652
  case 0:
653
      EMIT_SOUND( ENT(pev), CHAN_WEAPON, "bullchicken/bc_attack1.wav", 1, ATTN_NORM );
654
    break;
655
  case 1:
656
      EMIT_SOUND( ENT(pev), CHAN_WEAPON, "bullchicken/bc_attack2.wav", 1, ATTN_NORM );
657
    break;
658
  case 2:
659
      EMIT_SOUND( ENT(pev), CHAN_WEAPON, "bullchicken/bc_attack3.wav", 1, ATTN_NORM );
660
    break;
661
  }
662
}
663
 
664
 
665
//========================================================
666
// RunAI - overridden for gonome because there are things
667
// that need to be checked every think.
668
//========================================================
669
void CGonome :: RunAI ( void )
670
{
671
  // first, do base class stuff
672
  CBaseMonster :: RunAI();
673
 
674
  if ( m_hEnemy != NULL && m_Activity == ACT_RUN )
675
  {
676
    // chasing enemy. Sprint for last bit
677
    if ( (pev->origin - m_hEnemy->pev->origin).Length2D() < GONOME_SPRINT_DIST )
678
    {
679
      pev->framerate = 1.25;
680
    }
681
  }
682
 
683
}
684
 
685
//========================================================
686
// AI Schedules Specific to this monster
687
//=========================================================
688
 
689
// primary range attack
690
Task_t	tlGonomeRangeAttack1[] =
691
{
692
  { TASK_STOP_MOVING,			0				},
693
  { TASK_FACE_IDEAL,			(float)0		},
694
  { TASK_RANGE_ATTACK1,		(float)0		},
695
  { TASK_SET_ACTIVITY,		(float)ACT_IDLE	},
696
};
697
 
698
Schedule_t	slGonomeRangeAttack1[] =
699
{
700
  {
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,
708
    0,
709
    "Gonome Range Attack1"
710
  },
711
};
712
 
713
// Chase enemy schedule
714
Task_t tlGonomeChaseEnemy1[] =
715
{
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					},
720
};
721
 
722
Schedule_t slGonomeChaseEnemy[] =
723
{
724
  {
725
    tlGonomeChaseEnemy1,
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,
735
 
736
    bits_SOUND_DANGER			|
737
    bits_SOUND_MEAT,
738
    "Gonome Chase Enemy"
739
  },
740
};
741
 
742
 
743
// gonome walks to something tasty and eats it.
744
Task_t tlGonomeEat[] =
745
{
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				},
760
};
761
 
762
Schedule_t slGonomeEat[] =
763
{
764
  {
765
    tlGonomeEat,
766
    ARRAYSIZE( tlGonomeEat ),
767
    bits_COND_LIGHT_DAMAGE	|
768
    bits_COND_HEAVY_DAMAGE	|
769
    bits_COND_NEW_ENEMY	,
770
 
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.
773
    bits_SOUND_MEAT			|
774
    bits_SOUND_CARCASS,
775
    "GonomeEat"
776
  }
777
};
778
 
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[] =
782
{
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				},
798
};
799
 
800
Schedule_t slGonomeSniffAndEat[] =
801
{
802
  {
803
    tlGonomeSniffAndEat,
804
    ARRAYSIZE( tlGonomeSniffAndEat ),
805
    bits_COND_LIGHT_DAMAGE	|
806
    bits_COND_HEAVY_DAMAGE	|
807
    bits_COND_NEW_ENEMY	,
808
 
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.
811
    bits_SOUND_MEAT			|
812
    bits_SOUND_CARCASS,
813
    "GonomeSniffAndEat"
814
  }
815
};
816
 
817
// gonome does this to stinky things.
818
Task_t tlGonomeWallow[] =
819
{
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				},
832
};
833
 
834
Schedule_t slGonomeWallow[] =
835
{
836
  {
837
    tlGonomeWallow,
838
    ARRAYSIZE( tlGonomeWallow ),
839
    bits_COND_LIGHT_DAMAGE	|
840
    bits_COND_HEAVY_DAMAGE	|
841
    bits_COND_NEW_ENEMY	,
842
 
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.
845
    bits_SOUND_GARBAGE,
846
 
847
    "GonomeWallow"
848
  }
849
};
850
 
851
DEFINE_CUSTOM_SCHEDULES( CGonome )
852
{
853
  slGonomeRangeAttack1,
854
  slGonomeChaseEnemy,
855
  slGonomeEat,
856
  slGonomeSniffAndEat,
857
  slGonomeWallow
858
};
859
 
860
IMPLEMENT_CUSTOM_SCHEDULES( CGonome, CBaseMonster );
861
 
862
//=========================================================
863
// GetSchedule
864
//=========================================================
865
Schedule_t *CGonome :: GetSchedule( void )
866
{
867
  switch	( m_MonsterState )
868
  {
869
  case MONSTERSTATE_ALERT:
870
    {
871
 
872
      if ( HasConditions(bits_COND_SMELL_FOOD) )
873
      {
874
        CSound		*pSound;
875
 
876
        pSound = PBestScent();
877
 
878
        if ( pSound && (!FInViewCone ( &pSound->m_vecOrigin ) || !FVisible ( pSound->m_vecOrigin )) )
879
        {
880
          // scent is behind or occluded
881
          return GetScheduleOfType( SCHED_GONOME_SNIFF_AND_EAT );
882
        }
883
 
884
        // food is right out in the open. Just go get it.
885
        return GetScheduleOfType( SCHED_GONOME_EAT );
886
      }
887
 
888
      if ( HasConditions(bits_COND_SMELL) )
889
      {
890
        // there's something stinky.
891
        CSound		*pSound;
892
 
893
        pSound = PBestScent();
894
        if ( pSound )
895
          return GetScheduleOfType( SCHED_GONOME_WALLOW);
896
      }
897
 
898
      break;
899
    }
900
  case MONSTERSTATE_COMBAT:
901
    {
902
      // dead enemy
903
      if ( HasConditions( bits_COND_ENEMY_DEAD ) )
904
      {
905
        // call base class, all code to handle dead enemies is centralized there.
906
        return CBaseMonster :: GetSchedule();
907
      }
908
 
909
      if ( HasConditions(bits_COND_NEW_ENEMY) )
910
      {
911
        if ( m_fCanThreatDisplay && IRelationship( m_hEnemy ) == R_HT )
912
        {
913
          return GetScheduleOfType ( SCHED_WAKE_ANGRY );
914
        }
915
      }
916
 
917
      if ( HasConditions(bits_COND_SMELL_FOOD) )
918
      {
919
        CSound		*pSound;
920
 
921
        pSound = PBestScent();
922
 
923
        if ( pSound && (!FInViewCone ( &pSound->m_vecOrigin ) || !FVisible ( pSound->m_vecOrigin )) )
924
        {
925
          // scent is behind or occluded
926
          return GetScheduleOfType( SCHED_GONOME_SNIFF_AND_EAT );
927
        }
928
 
929
        // food is right out in the open. Just go get it.
930
        return GetScheduleOfType( SCHED_GONOME_EAT );
931
      }
932
 
933
      if ( HasConditions( bits_COND_CAN_RANGE_ATTACK1 ) )
934
      {
935
        return GetScheduleOfType ( SCHED_RANGE_ATTACK1 );
936
      }
937
 
938
      if ( HasConditions( bits_COND_CAN_MELEE_ATTACK1 ) )
939
      {
940
        return GetScheduleOfType ( SCHED_MELEE_ATTACK1 );
941
      }
942
 
943
      if ( HasConditions( bits_COND_CAN_MELEE_ATTACK2 ) )
944
      {
945
        return GetScheduleOfType ( SCHED_MELEE_ATTACK2 );
946
      }
947
 
948
      return GetScheduleOfType ( SCHED_CHASE_ENEMY );
949
 
950
      break;
951
    }
952
  }
953
 
954
  return CBaseMonster :: GetSchedule();
955
}
956
 
957
//=========================================================
958
// GetScheduleOfType
959
//=========================================================
960
Schedule_t* CGonome :: GetScheduleOfType ( int Type )
961
{
962
  switch	( Type )
963
  {
964
  case SCHED_RANGE_ATTACK1:
965
      return &slGonomeRangeAttack1[ 0 ];
966
    break;
967
  case SCHED_GONOME_EAT:
968
      return &slGonomeEat[ 0 ];
969
    break;
970
  case SCHED_GONOME_SNIFF_AND_EAT:
971
      return &slGonomeSniffAndEat[ 0 ];
972
    break;
973
  case SCHED_GONOME_WALLOW:
974
      return &slGonomeWallow[ 0 ];
975
    break;
976
  case SCHED_CHASE_ENEMY:
977
      return &slGonomeChaseEnemy[ 0 ];
978
    break;
979
  }
980
 
981
  return CBaseMonster :: GetScheduleOfType ( Type );
982
}
983
 
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 )
992
{
993
  m_iTaskStatus = TASKSTATUS_RUNNING;
994
 
995
  switch ( pTask->iTask )
996
  {
997
  case TASK_MELEE_ATTACK2:
998
    {
999
      switch ( RANDOM_LONG ( 0, 1 ) )
1000
      {
1001
      case 0:
1002
          EMIT_SOUND( ENT(pev), CHAN_VOICE, "gonome/gonome_melee1.wav", 1, ATTN_NORM );
1003
        break;
1004
      case 1:
1005
          EMIT_SOUND( ENT(pev), CHAN_VOICE, "gonome/gonome_melee2.wav", 1, ATTN_NORM );
1006
        break;
1007
      }
1008
 
1009
      CBaseMonster :: StartTask ( pTask );
1010
      break;
1011
    }
1012
  case TASK_GET_PATH_TO_ENEMY:
1013
    {
1014
      if ( BuildRoute ( m_hEnemy->pev->origin, bits_MF_TO_ENEMY, m_hEnemy ) )
1015
      {
1016
        m_iTaskStatus = TASKSTATUS_COMPLETE;
1017
      }
1018
      else
1019
      {
1020
        ALERT ( at_aiconsole, "GetPathToEnemy failed!!\n" );
1021
        TaskFail();
1022
      }
1023
      break;
1024
    }
1025
  default:
1026
    {
1027
      CBaseMonster :: StartTask ( pTask );
1028
      break;
1029
    }
1030
  }
1031
}
1032
 
1033
//=========================================================
1034
// RunTask
1035
//=========================================================
1036
void CGonome :: RunTask ( Task_t *pTask )
1037
{
1038
  {
1039
    CBaseMonster :: RunTask( pTask );
1040
  }
1041
}
1042
 
1043
 
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 )
1050
{
1051
  int	iConditions;
1052
 
1053
  iConditions = IScheduleFlags();
1054
 
1055
  m_IdealMonsterState = CBaseMonster :: GetIdealState();
1056
 
1057
  return m_IdealMonsterState;
1058
}

За это сообщение SteamPlay43 получил предупреждение за оверквотинг

Сообщить модератору | | IP: Записан
Сообщение: 121940

Старое сообщение 22-06-2013 18:16
- За что?
Half
Частый гость

Дата регистрации: Jun 2013
Проживает: г. Новосибирск
Сообщений: 85
Возраст: 29

Рейтинг



SteamPlay43
Ну ты даёшь! Где же ты такое нашёл?
Взял бы лучше какого-нибудь монстра (бульскуида) и на его основе сделал бы себе Гонома, ПитДрона или ещё чего-нибудь этакого... глюков меньше будет©.

__________________
Пруха длится всего 5 минут.

Сообщить модератору | | IP: Записан
Сообщение: 121942

Старое сообщение 22-06-2013 18:41
- За что?
SteamPlay43
Житель форума

Группа: Неопытный
Дата регистрации: May 2012
Проживает: Барнаул
Сообщений: 273
Возраст: 26

Рейтинг



Вообщем кому лень читать код вот он

Вложение: gonome.zip (6.8 кб)
Этот файл был скачан 181 раз.

Сообщить модератору | | IP: Записан
Сообщение: 122000

Старое сообщение 23-06-2013 13:47
- За что?
SteamPlay43
Житель форума

Группа: Неопытный
Дата регистрации: May 2012
Проживает: Барнаул
Сообщений: 273
Возраст: 26

Рейтинг



Half Спасибо за совет! Взял переделал буллскюида! Получился идеальный гоном убивающий хедкрабов)

Сообщить модератору | | IP: Записан
Сообщение: 122198

Старое сообщение 28-06-2013 22:09
- За что?
Half
Частый гость

Дата регистрации: Jun 2013
Проживает: г. Новосибирск
Сообщений: 85
Возраст: 29

Рейтинг



SteamPlay43[b]

Цитата:
SteamPlay43 писал:
[B]Получился идеальный гоном убивающий хедкрабов)

А этот гоном, он своих хавает?
Хотя, нормальный вышел у тебя Гоном, лучше старого! Хэдкрабов не любит и своих жрёт.
Цитата:
SteamPlay43 писал:
гоном убивающий хедкрабов

Чтобы исправить это, не обязательно быть супер программистом. Достаточно того, что ты знаешь английский:
C++ Source Code:
1
if ( m_hEnemy != NULL )
2
{
3
  if ( FClassnameIs( m_hEnemy->pev, "monster_headcrab" ) )
4
  {
5
    // (Unless after a tasty headcrab)
6
    iIgnore = bits_COND_SMELL | bits_COND_SMELL_FOOD;
7
  }
8
}

Разберись-ка с этой строчкой.
+Ты ведь смотрел в шедули? "SCHED_SQUID_SEECRAB"

П.С. Какая классификация твоего Гонома?

__________________
Пруха длится всего 5 минут.

Отредактировано Half 29-06-2013 в 01:52

Сообщить модератору | | IP: Записан
Сообщение: 122201

Старое сообщение 29-06-2013 01:39
- За что?
Тема: (Опционально)
Ваш ответ:



Переводчик транслита


[проверить длину сообщения]
Опции: Автоматическое формирование ссылок: автоматически добавлять [url] и [/url] вокруг интернет адресов.
Уведомление по E-Mail: отправить вам уведомление, если кто-то ответил в тему (только для зарегистрированных пользователей).
Отключить смайлики в сообщении: не преобразовывать текстовые смайлики в картинки.
Показать подпись: добавить вашу подпись в конец сообщения (только зарегистрированные пользователи могут иметь подписи).

Временная зона GMT. Текущее время 12:56. Новая тема    Ответить
  Предыдущая тема   Следующая тема
HLFX.Ru Forum HLFX.Ru Forum > Теория и практика > Half-Life SDK > Решил добавить в мод новых монстров.
Скачал гонома с сдкопфора но он глючный!
Версия для печати | Отправить тему по E-Mail | Подписаться на эту тему

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

Правила Форума:
Вы not можете создавать новые темы
Вы not можете отвечать в темы
Вы not можете прикреплять вложения
Вы not можете редактировать ваши сообщения
HTML Код ВЫКЛ
vB Код ВКЛ
Смайлики ВКЛ
[IMG] Код ВКЛ
 

< Обратная связь - HLFX.ru >

На основе vBulletin
Авторское право © 2000 - 2002, Jelsoft Enterprises Limited.
Дизайн и программирование: Crystice Softworks © 2005 - 2024