|
Danke schon mal für die Antwort. Also das Model ist nicht von mir ,ich kenne mich damit nicht aus. Das hat ein Kumpel mal gemacht. Auch in monster coding habe ich noch nicht viel erfahrung darum habe ich für mein erstes Monster das Headcrab kopiert und geändert. Ich habe die Animationen deshalb erst mal so gelassen und es geht auch. Das vieh läuft auf mich zu und springt mich an. Ich kann es auch töten aber der Wolf mich nicht. Egal wie oft der mich anspringt ich verliere keine Energie.
Ich habe hier mal den Code :
//========================================================= // headcrab2.cpp - NEU1 = WOLF Monster //=========================================================
#include "extdll.h" #include "util.h" #include "cbase.h" #include "monsters.h" #include "schedule.h"
//========================================================= // Monster's Anim Events Go Here //========================================================= #define HC_AE_JUMPATTACK ( 2 )
Task_t tlHCRangeAttack12[] = { { TASK_STOP_MOVING, (float)0 }, { TASK_FACE_IDEAL, (float)0 }, { TASK_RANGE_ATTACK1, (float)0 }, { TASK_SET_ACTIVITY, (float)ACT_IDLE }, { TASK_FACE_IDEAL, (float)0 }, { TASK_WAIT_RANDOM, (float)0.5 }, };
Schedule_t slHCRangeAttack12[] = { { tlHCRangeAttack12, ARRAYSIZE ( tlHCRangeAttack12 ), bits_COND_ENEMY_OCCLUDED | bits_COND_NO_AMMO_LOADED, 0, "HCRangeAttack1" }, };
Task_t tlHCRangeAttack1Fast2[] = { { TASK_STOP_MOVING, (float)0 }, { TASK_FACE_IDEAL, (float)0 }, { TASK_RANGE_ATTACK1, (float)0 }, { TASK_SET_ACTIVITY, (float)ACT_IDLE }, };
Schedule_t slHCRangeAttack1Fast2[] = { { tlHCRangeAttack1Fast2, ARRAYSIZE ( tlHCRangeAttack1Fast2 ), bits_COND_ENEMY_OCCLUDED | bits_COND_NO_AMMO_LOADED, 0, "HCRAFast" }, };
class CHeadCrab2 : public CBaseMonster { public: void Spawn( void ); void Precache( void ); void RunTask ( Task_t *pTask ); void StartTask ( Task_t *pTask ); void SetYawSpeed ( void ); void EXPORT LeapTouch ( CBaseEntity *pOther ); Vector Center( void ); Vector BodyTarget( const Vector &posSrc ); void PainSound( void ); void DeathSound( void ); void IdleSound( void ); void AlertSound( void ); void PrescheduleThink( void ); int Classify ( void ); void HandleAnimEvent( MonsterEvent_t *pEvent ); BOOL CheckRangeAttack1 ( float flDot, float flDist ); BOOL CheckRangeAttack2 ( float flDot, float flDist ); int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType );
virtual float GetDamageAmount( void ) { return gSkillData.headcrab2DmgBite; } virtual int GetVoicePitch( void ) { return 100; } virtual float GetSoundVolue( void ) { return 1.0; } Schedule_t* GetScheduleOfType ( int Type );
CUSTOM_SCHEDULES;
static const char *pIdleSounds[]; static const char *pAlertSounds[]; static const char *pPainSounds[]; static const char *pAttackSounds[]; static const char *pDeathSounds[]; static const char *pBiteSounds[]; }; LINK_ENTITY_TO_CLASS( monster_wolf, CHeadCrab2 );
DEFINE_CUSTOM_SCHEDULES( CHeadCrab2 ) { slHCRangeAttack12, slHCRangeAttack1Fast2, };
IMPLEMENT_CUSTOM_SCHEDULES( CHeadCrab2, CBaseMonster );
const char *CHeadCrab2::pIdleSounds[] = { "headcrab/hc_idle1.wav", "headcrab/hc_idle2.wav", "headcrab/hc_idle3.wav", }; const char *CHeadCrab2::pAlertSounds[] = { "headcrab/hc_alert1.wav", }; const char *CHeadCrab2::pPainSounds[] = { "headcrab/hc_pain1.wav", "headcrab/hc_pain2.wav", "headcrab/hc_pain3.wav", }; const char *CHeadCrab2::pAttackSounds[] = { "headcrab/hc_attack1.wav", "headcrab/hc_attack2.wav", "headcrab/hc_attack3.wav", };
const char *CHeadCrab2::pDeathSounds[] = { "headcrab/hc_die1.wav", "headcrab/hc_die2.wav", };
const char *CHeadCrab2::pBiteSounds[] = { "headcrab/hc_headbite.wav", };
//========================================================= // Classify - indicates this monster's place in the // relationship table. //========================================================= int CHeadCrab2 :: Classify ( void ) { return CLASS_ALIEN_PREY; }
//========================================================= // Center - returns the real center of the headcrab. The // bounding box is much larger than the actual creature so // this is needed for targeting //========================================================= Vector CHeadCrab2 :: Center ( void ) { return Vector( pev->origin.x, pev->origin.y, pev->origin.z + 6 ); }
Vector CHeadCrab2 :: BodyTarget( const Vector &posSrc ) { return Center( ); }
//========================================================= // SetYawSpeed - allows each sequence to have a different // turn rate associated with it. //========================================================= void CHeadCrab2 :: SetYawSpeed ( void ) { int ys;
switch ( m_Activity ) { case ACT_IDLE: ys = 30; break; case ACT_RUN: case ACT_WALK: ys = 20; break; case ACT_TURN_LEFT: case ACT_TURN_RIGHT: ys = 60; break; case ACT_RANGE_ATTACK1: ys = 30; break; default: ys = 30; break; }
pev->yaw_speed = ys; }
//========================================================= // HandleAnimEvent - catches the monster-specific messages // that occur when tagged animation frames are played. //========================================================= void CHeadCrab2 :: HandleAnimEvent( MonsterEvent_t *pEvent ) { switch( pEvent->event ) { case HC_AE_JUMPATTACK: { ClearBits( pev->flags, FL_ONGROUND );
UTIL_SetOrigin (pev, pev->origin + Vector ( 0 , 0 , 1) );// take him off ground so engine doesn't instantly reset onground UTIL_MakeVectors ( pev->angles );
Vector vecJumpDir; if (m_hEnemy != NULL) { float gravity = CVAR_GET_FLOAT( "sv_gravity" ); if (gravity <= 1) gravity = 1;
// How fast does the headcrab need to travel to reach that height given gravity? float height = (m_hEnemy->pev->origin.z + m_hEnemy->pev->view_ofs.z - pev->origin.z); if (height < 16) height = 16; float speed = sqrt( 2 * gravity * height ); float time = speed / gravity;
// Scale the sideways velocity to get there at the right time vecJumpDir = (m_hEnemy->pev->origin + m_hEnemy->pev->view_ofs - pev->origin); vecJumpDir = vecJumpDir * ( 1.0 / time );
// Speed to offset gravity at the desired height vecJumpDir.z = speed;
// Don't jump too far/fast float distance = vecJumpDir.Length(); if (distance > 650) { vecJumpDir = vecJumpDir * ( 650.0 / distance ); } } else { // jump hop, don't care where vecJumpDir = Vector( gpGlobals->v_forward.x, gpGlobals->v_forward.y, gpGlobals->v_up.z ) * 350; }
int iSound = RANDOM_LONG(0,2); if ( iSound != 0 ) EMIT_SOUND_DYN( edict(), CHAN_VOICE, pAttackSounds[iSound], GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch() );
pev->velocity = vecJumpDir; m_flNextAttack = gpGlobals->time + 2; } break;
default: CBaseMonster::HandleAnimEvent( pEvent ); break; } }
//========================================================= // Spawn //========================================================= void CHeadCrab2 :: Spawn() { Precache( );
SET_MODEL(ENT(pev), "models/wolf.mdl"); // UTIL_SetSize(pev, Vector(-12, -12, 0), Vector(12, 12, 24)); // Alt UTIL_SetSize( pev, Vector( -32, -32, 0 ), Vector( 32, 32, 64 ) );
pev->solid = SOLID_SLIDEBOX; pev->movetype = MOVETYPE_STEP; m_bloodColor = BLOOD_COLOR_RED; pev->effects = 0; pev->health = gSkillData.headcrab2Health; pev->view_ofs = Vector ( 0, 0, 20 );// position of the eyes relative to monster's origin. pev->yaw_speed = 5;//!!! should we put this in the monster's changeanim function since turn rates may vary with state/anim? m_flFieldOfView = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result ) m_MonsterState = MONSTERSTATE_NONE;
MonsterInit(); }
//========================================================= // Precache - precaches all resources this monster needs //========================================================= void CHeadCrab2 :: Precache() { PRECACHE_SOUND_ARRAY(pIdleSounds); PRECACHE_SOUND_ARRAY(pAlertSounds); PRECACHE_SOUND_ARRAY(pPainSounds); PRECACHE_SOUND_ARRAY(pAttackSounds); PRECACHE_SOUND_ARRAY(pDeathSounds); PRECACHE_SOUND_ARRAY(pBiteSounds);
PRECACHE_MODEL("models/wolf.mdl"); }
//========================================================= // RunTask //========================================================= void CHeadCrab2 :: RunTask ( Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_RANGE_ATTACK1: case TASK_RANGE_ATTACK2: { if ( m_fSequenceFinished ) { TaskComplete(); SetTouch( NULL ); m_IdealActivity = ACT_IDLE; } break; } default: { CBaseMonster :: RunTask(pTask); } } }
//========================================================= // LeapTouch - this is the headcrab's touch function when it // is in the air //========================================================= void CHeadCrab2 :: LeapTouch ( CBaseEntity *pOther ) { if ( !pOther->pev->takedamage ) { return; }
if ( pOther->Classify() == Classify() ) { return; }
// Don't hit if back on ground if ( !FBitSet( pev->flags, FL_ONGROUND ) ) { EMIT_SOUND_DYN( edict(), CHAN_WEAPON, RANDOM_SOUND_ARRAY(pBiteSounds), GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch() ); pOther->TakeDamage( pev, pev, GetDamageAmount(), DMG_SLASH ); //pev, pev, }
SetTouch( NULL ); }
//========================================================= // PrescheduleThink //========================================================= void CHeadCrab2 :: PrescheduleThink ( void ) { // make the crab coo a little bit in combat state if ( m_MonsterState == MONSTERSTATE_COMBAT && RANDOM_FLOAT( 0, 5 ) < 0.1 ) { IdleSound(); } }
void CHeadCrab2 :: StartTask ( Task_t *pTask ) { m_iTaskStatus = TASKSTATUS_RUNNING;
switch ( pTask->iTask ) { case TASK_RANGE_ATTACK1: { EMIT_SOUND_DYN( edict(), CHAN_WEAPON, pAttackSounds[0], GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch() ); m_IdealActivity = ACT_RANGE_ATTACK1; SetTouch ( LeapTouch ); break; } default: { CBaseMonster :: StartTask( pTask ); } } }
//========================================================= // CheckRangeAttack1 //========================================================= BOOL CHeadCrab2 :: CheckRangeAttack1 ( float flDot, float flDist ) { if ( FBitSet( pev->flags, FL_ONGROUND ) && flDist <= 256 && flDot >= 0.65 ) // 256 && flDot >= 0.65 { return TRUE; } return FALSE; }
//========================================================= // CheckRangeAttack2 //========================================================= BOOL CHeadCrab2 :: CheckRangeAttack2 ( float flDot, float flDist ) { return FALSE; // BUGBUG: Why is this code here? There is no ACT_RANGE_ATTACK2 animation. I've disabled it for now. #if 0 if ( FBitSet( pev->flags, FL_ONGROUND ) && flDist > 64 && flDist <= 85 && flDot >= 0.7 ) // 256 && flDot >= 0.5 { return TRUE; } return FALSE; #endif }
int CHeadCrab2 :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) { // Don't take any acid damage -- BigMomma's mortar is acid if ( bitsDamageType & DMG_ACID ) flDamage = 0;
return CBaseMonster::TakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType ); }
//========================================================= // IdleSound //========================================================= #define CRAB_ATTN_IDLE (float)1.5 void CHeadCrab2 :: IdleSound ( void ) { EMIT_SOUND_DYN( edict(), CHAN_VOICE, RANDOM_SOUND_ARRAY(pIdleSounds), GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch() ); }
//========================================================= // AlertSound //========================================================= void CHeadCrab2 :: AlertSound ( void ) { EMIT_SOUND_DYN( edict(), CHAN_VOICE, RANDOM_SOUND_ARRAY(pAlertSounds), GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch() ); }
//========================================================= // AlertSound //========================================================= void CHeadCrab2 :: PainSound ( void ) { EMIT_SOUND_DYN( edict(), CHAN_VOICE, RANDOM_SOUND_ARRAY(pPainSounds), GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch() ); }
//========================================================= // DeathSound //========================================================= void CHeadCrab2 :: DeathSound ( void ) { EMIT_SOUND_DYN( edict(), CHAN_VOICE, RANDOM_SOUND_ARRAY(pDeathSounds), GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch() ); }
Schedule_t* CHeadCrab2 :: GetScheduleOfType ( int Type ) { switch ( Type ) { case SCHED_RANGE_ATTACK1: { return &slHCRangeAttack12[ 0 ]; } break; }
return CBaseMonster::GetScheduleOfType( Type ); }
Währe nett wenn du mir sagen kannst wie ich das in ordnung bringe und auch wie man mit den Anim Events umgeht. Bei den waffen musste ich ja nur den Namen der Animation schreiben ,aber das hier ist noch neu für mich. Schon mal danke für die Mühe.
--
|