Ghoul [BB]
МРАЗЬ ОПАСНАЯ
Дата регистрации : Jan 2006
Проживает : ...и прожигает...
Сообщений : 2567
Рейтинг
[кратко]
Пользователи:
2.6 (9 )
Нарушения:
-10.0 (? )
Сообщения:
0.3 (Метки )
Регистрация:
9.9
Sentry Turret: последние штрихи
Настал тот долгожданный день, когда я ПРАКТИЧЕСКИ закончил клепание кода для размещаемых игроком стационарных пушек.
Осталось самая малость, а именно ваша помошь в 2 вещах:
1. Правильное определение ОВНЕРА для туррели. У меня этого не получилось сделать....
2. Правильный спавн этой пушки и ее размещение на земле.. (отчего-то она иногда проваливается в пол или уходит в стены)
В общем, братцы, хелпните старому Мертвяку-Тульскому-Оружейнику!
КОД ТУРРЕЛИ:
==================================
C++ Source Code:
8 #define TURRET_TURNRATE 30// angles per 0.1 second
9 #define TURRET_MAXWAIT 15// seconds turret will stay active w/o a target
21 class CBaseTurret : public CBaseMonster
25 virtual int Classify(void );
26 int BloodColor( void ) { return DONT_BLEED; }
27 void GibMonster( void ) {}
29 void EXPORT ActiveThink(void );
30 void EXPORT SearchThink(void );
31 void EXPORT AutoSearchThink(void );
32 void EXPORT TurretDeath(void );
34 void EXPORT Deploy(void );
35 void EXPORT Initialize(void );
36 virtual void Ping(void );
39 void SetTurretAnim(TURRET_ANIM anim);
41 virtual void Shoot(Vector &vecSrc, Vector &vecDirToEnemy) { };
46 int m_iBaseTurnRate;// angles per second
47 float m_fTurnRate;// actual turn rate
50 Vector m_vecLastSight;
51 float m_flLastSight; // Last time we saw a target
52 float m_flMaxWait; // Max time to seach w/o a target
56 Vector m_vecCurAngles;
57 Vector m_vecGoalAngles;
64 void CBaseTurret::Spawn()
66 pev->nextthink = gpGlobals->time + 1;
67 pev->movetype = MOVETYPE_BOUNCE;
70 pev->solid = SOLID_SLIDEBOX;
71 pev->takedamage = DAMAGE_AIM;
80 SetBoneController(0, 0);
81 SetBoneController(1, 0);
82 m_flFieldOfView = VIEW_FIELD_FULL;
85 m_hOwner = Instance(pev->owner);
88 void CBaseTurret::Initialize(void )
91 SetBoneController( 0, 0 );
92 SetBoneController( 1, 0 );
93 if (m_iBaseTurnRate == 0) m_iBaseTurnRate = TURRET_TURNRATE;
94 if (m_flMaxWait == 0) m_flMaxWait = TURRET_MAXWAIT;
95 m_flStartYaw = pev->angles.y;
97 m_vecGoalAngles.x = 0;
99 m_flLastSight = gpGlobals->time + m_flMaxWait;
100 SetThink(AutoSearchThink);
101 pev->nextthink = gpGlobals->time + .1;
104 void CBaseTurret::Ping( void )
106 if ( gpGlobals->time >= m_flPingTime )
108 EMIT_SOUND(ENT(pev), CHAN_ITEM, "turret/tu_ping.wav" , 1, ATTN_NORM);
109 m_flPingTime = gpGlobals->time + 1;
113 void CBaseTurret::ActiveThink(void )
115 // CBaseEntity *pOther = NULL;
118 Vector vecDirToEnemy;
120 pev->nextthink = gpGlobals->time + 0.1;
121 StudioFrameAdvance( );
124 if ( pev->owner && pOther->edict() == pev->owner )
127 m_flLastSight = gpGlobals->time + m_flMaxWait;
128 SetThink(SearchThink);
133 if ((!m_iOn) || (m_hEnemy == NULL))
136 m_flLastSight = gpGlobals->time + m_flMaxWait;
137 SetThink(SearchThink);
141 // if it's dead, look for something new
142 if ( !m_hEnemy->IsAlive() )
146 m_flLastSight = gpGlobals->time;
150 if (gpGlobals->time > m_flLastSight)
153 m_flLastSight = gpGlobals->time + m_flMaxWait;
154 SetThink(SearchThink);
160 Vector vecMid = pev->origin + pev->view_ofs;
161 Vector vecMidEnemy = m_hEnemy->BodyTarget( vecMid );
162 // Look for our current enemy
163 int fEnemyVisible = FBoxVisible(pev, m_hEnemy->pev, vecMidEnemy );
164 vecDirToEnemy = vecMidEnemy - vecMid; // calculate dir and dist to enemy
165 float flDistToEnemy = vecDirToEnemy.Length();
166 Vector vec = UTIL_VecToAngles(vecMidEnemy - vecMid);
168 // Current enmey is not visible.
169 if (!fEnemyVisible || (flDistToEnemy > 8192))
172 m_flLastSight = gpGlobals->time;
175 // Should we look for a new target?
176 if (gpGlobals->time > m_flLastSight)
179 m_flLastSight = gpGlobals->time + m_flMaxWait;
180 SetThink(SearchThink);
187 m_vecLastSight = vecMidEnemy;
189 UTIL_MakeAimVectors(m_vecCurAngles);
191 Vector vecLOS = vecDirToEnemy;
192 vecLOS = vecLOS.Normalize();
194 // Is the Gun looking at the target
195 if (DotProduct(vecLOS, gpGlobals->v_forward) <= 0.866) // 30 degree slop
202 Vector vecSrc, vecAng;
203 GetAttachment( 0, vecSrc, vecAng );
204 Shoot(vecSrc, gpGlobals->v_forward );
208 SetTurretAnim(TURRET_ANIM_SPIN);
227 else if (vec.x < m_iMinPitch)
230 m_vecGoalAngles.y = vec.y;
231 m_vecGoalAngles.x = vec.x;
236 void CBaseTurret::Deploy(void )
238 pev->nextthink = gpGlobals->time + 0.1;
239 StudioFrameAdvance( );
241 if (pev->sequence != TURRET_ANIM_DEPLOY)
244 SetTurretAnim(TURRET_ANIM_DEPLOY);
245 SUB_UseTargets( this , USE_ON, 0 );
248 if (m_fSequenceFinished)
250 pev->maxs.z = m_iDeployHeight;
251 pev->mins.z = -m_iDeployHeight;
252 UTIL_SetSize(pev, pev->mins, pev->maxs);
254 m_vecCurAngles.x = 0;
256 SetTurretAnim(TURRET_ANIM_SPIN);
258 SetThink(SearchThink);
261 m_flLastSight = gpGlobals->time + m_flMaxWait;
264 void CBaseTurret::SetTurretAnim(TURRET_ANIM anim)
266 if (pev->sequence != anim)
270 case TURRET_ANIM_FIRE:
271 case TURRET_ANIM_SPIN:
272 if (pev->sequence != TURRET_ANIM_FIRE && pev->sequence != TURRET_ANIM_SPIN)
282 pev->sequence = anim;
283 ResetSequenceInfo( );
287 case TURRET_ANIM_RETIRE:
289 pev->framerate = -1.0;
291 case TURRET_ANIM_DIE:
292 pev->framerate = 1.0;
298 void CBaseTurret::SearchThink(void )
301 SetTurretAnim(TURRET_ANIM_SPIN);
302 StudioFrameAdvance( );
303 pev->nextthink = gpGlobals->time + 0.1;
307 // If we have a target and we're still healthy
308 if (m_hEnemy != NULL)
310 if (!m_hEnemy->IsAlive() )
311 m_hEnemy = NULL;// Dead enemy forces a search for new one
315 if (m_hEnemy == NULL)
318 m_hEnemy = BestVisibleEnemy();
321 if (m_hEnemy != NULL)
324 SetThink(ActiveThink);
328 // generic hunt for new victims
329 m_vecGoalAngles.y = (m_vecGoalAngles.y + 0.1 * m_fTurnRate);
330 if (m_vecGoalAngles.y >= 360)
331 m_vecGoalAngles.y -= 360;
336 void CBaseTurret::AutoSearchThink(void )
339 StudioFrameAdvance( );
340 pev->nextthink = gpGlobals->time + 0.3;
342 // If we have a target and we're still healthy
343 if (m_hEnemy != NULL)
345 if (!m_hEnemy->IsAlive() || m_hEnemy->edict() == pev->owner)
346 m_hEnemy = NULL;// Dead enemy forces a search for new one
350 if (m_hEnemy == NULL)
353 m_hEnemy = BestVisibleEnemy();
356 if (m_hEnemy != NULL)
360 void CBaseTurret ::TurretDeath( void )
362 BOOL iActive = FALSE;
363 StudioFrameAdvance( );
365 if (pev->deadflag != DEAD_DEAD)
367 pev->deadflag = DEAD_DEAD;
368 SetTurretAnim(TURRET_ANIM_DIE);
371 PLAYBACK_EVENT_FULL( FEV_GLOBAL, edict(), g_sExplosion, 0.0, (float *)&pev->origin, (float *)&pev->velocity, 0.0, 0.0, 0, EXPLOSION_TURRET, 0, 0 );
373 if (m_hOwner != NULL)
374 RadiusDamage ( pev, m_hOwner->pev, pev->dmg, CLASS_NONE, DMG_BLAST );
376 RadiusDamage ( pev, pev, pev->dmg, CLASS_NONE, DMG_BLAST );
378 if (m_hOwner != NULL)
379 pev->owner = m_hOwner->edict();
386 int CBaseTurret::MoveTurret(void )
391 if (m_vecCurAngles.x != m_vecGoalAngles.x)
393 float flDir = m_vecGoalAngles.x > m_vecCurAngles.x ? 1 : -1 ;
395 m_vecCurAngles.x += 0.1 * m_fTurnRate * flDir;
397 // if we started below the goal, and now we're past, peg to goal
400 if (m_vecCurAngles.x > m_vecGoalAngles.x)
401 m_vecCurAngles.x = m_vecGoalAngles.x;
405 if (m_vecCurAngles.x < m_vecGoalAngles.x)
406 m_vecCurAngles.x = m_vecGoalAngles.x;
409 SetBoneController(1, -m_vecCurAngles.x);
413 if (m_vecCurAngles.y != m_vecGoalAngles.y)
415 float flDir = m_vecGoalAngles.y > m_vecCurAngles.y ? 1 : -1 ;
416 float flDist = fabs(m_vecGoalAngles.y - m_vecCurAngles.y);
420 flDist = 360 - flDist;
425 if (m_fTurnRate < m_iBaseTurnRate * 10)
427 m_fTurnRate += m_iBaseTurnRate;
430 else if (m_fTurnRate > 45)
432 m_fTurnRate -= m_iBaseTurnRate;
436 m_fTurnRate += m_iBaseTurnRate;
439 m_vecCurAngles.y += 0.1 * m_fTurnRate * flDir;
441 if (m_vecCurAngles.y < 0)
442 m_vecCurAngles.y += 360;
443 else if (m_vecCurAngles.y >= 360)
444 m_vecCurAngles.y -= 360;
446 if (flDist < (0.05 * m_iBaseTurnRate))
447 m_vecCurAngles.y = m_vecGoalAngles.y;
449 SetBoneController(0, m_vecCurAngles.y - pev->angles.y );
454 m_fTurnRate = m_iBaseTurnRate;
459 int CBaseTurret::Classify ( void )
461 return CLASS_MACHINE;
466 //=========================================================
467 // Sentry Turret - 9MM Minigun
468 //=========================================================
469 class CSentry : public CBaseTurret
473 void Shoot(Vector &vecSrc, Vector &vecDirToEnemy);
474 int TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType);
476 LINK_ENTITY_TO_CLASS( monster_sentry, CSentry );
480 CBaseTurret::Spawn();
481 SET_MODEL(ENT(pev), "models/turret_sentry.mdl" );
484 m_HackedGunPos = Vector(0,0,48);
485 pev->view_ofs.z = 48;
487 m_iRetractHeight = 64;
488 m_iDeployHeight = 64;
490 UTIL_SetSize(pev, Vector(-16, -16, 0), Vector(16, 16, 32));
491 SetThink(Initialize);
492 pev->nextthink = gpGlobals->time + 1;
495 void CSentry::Shoot(Vector &vecSrc, Vector &vecDirToEnemy)
497 if ( gpGlobals->time >= m_flShootTime )
499 SetTurretAnim(TURRET_ANIM_FIRE);
500 FireBullets( 3, vecSrc, vecDirToEnemy, VECTOR_CONE_8DEGREES, 8192, BULLET_MONSTER_9MM, 1 );
502 EMIT_SOUND(ENT(pev), CHAN_WEAPON, "weapons/mp5_fire.wav" , 1, ATTN_LOW_HIGH);
503 m_flShootTime = gpGlobals->time + 1;
507 int CSentry::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType)
509 if ( bitsDamageType & DMG_BLIND)
512 if ( bitsDamageType & DMG_KNOCKFORVARD)
515 if ( bitsDamageType & DMG_NERVEGAS)
518 switch ( RANDOM_LONG( 0, 2 ) )
520 case 0: EMIT_SOUND(ENT(pev), CHAN_BODY, "weapons/ric1.wav" , 1, ATTN_NORM); break ;
521 case 1: EMIT_SOUND(ENT(pev), CHAN_BODY, "weapons/ric2.wav" , 1, ATTN_NORM); break ;
522 case 2: EMIT_SOUND(ENT(pev), CHAN_BODY, "weapons/ric3.wav" , 1, ATTN_NORM); break ;
529 pev->nextthink = gpGlobals->time + 0.1;
532 pev->health -= flDamage;
534 if (pev->health <= 0)
537 pev->takedamage = DAMAGE_NO;
538 pev->dmgtime = gpGlobals->time;
540 SetThink(TurretDeath);
541 SUB_UseTargets( this , USE_ON, 0 );
542 pev->nextthink = gpGlobals->time + 0.1;
А это кусок первичной атаки для оружия. Спавн пушки.
Я еще не решил, как именно создавать:
1. Либо рядом с игроком, примерно как сейчас и ли в ТФК,
2. Либо как в Анриале - кидаем из оружия диск и спавним в том месте пушку...
Итак, сама атака:
=========================================
C++ Source Code:
1 void CCrowbar::SecondaryAttack()
3 UTIL_MakeVectors( m_pPlayer->pev->v_angle );
5 Vector trace_origin = m_pPlayer->pev->origin;
7 if (m_pPlayer->pev->flags & FL_DUCKING)
8 trace_origin = trace_origin - (VEC_HULL_MIN - VEC_DUCK_HULL_MIN);
10 UTIL_TraceLine(trace_origin + gpGlobals->v_forward * 20, trace_origin + gpGlobals->v_forward * 150, dont_ignore_monsters, NULL, &tr );
12 if (tr.fAllSolid == 0 && tr.fStartSolid == 0 && tr.flFraction > 0.25)
14 SendWeaponAnim(CROWBAR_ATTACK1HIT);
15 m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
17 CBaseEntity::Create( "monster_sentry" , tr.vecEndPos, m_pPlayer->pev->v_angle + gpGlobals->v_forward * 200 + m_pPlayer->pev->velocity, m_pPlayer->edict() );
19 m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.5;
20 m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.5;
Сообщить модератору | | IP: Записан
Сообщение: 2720