void CBaseMonster::FadeMonster( void ) { StopAnimation(); pev->velocity = g_vecZero; pev->movetype = MOVETYPE_NONE; pev->avelocity = g_vecZero; pev->animtime = gpGlobals->time; pev->effects |= EF_NOINTERP; SUB_StartFadeOut(); }
void CASW_Simple_Alien::CorpseFade() { StopAnimation(); SetAbsVelocity( vec3_origin ); SetMoveType( MOVETYPE_NONE ); SetLocalAngularVelocity( vec3_angle ); m_flAnimTime = gpGlobals->curtime; AddEffects( EF_NOINTERP ); SUB_StartFadeOut(); }
void CRagGib::Spawn( const char *szModel, const Vector &vecOrigin, const Vector &vecForce, float flFadeTime = 0.0 ) { SetSolid( SOLID_BBOX ); AddSolidFlags( FSOLID_NOT_SOLID ); SetModel( szModel ); UTIL_SetSize(this, vec3_origin, vec3_origin); UTIL_SetOrigin( this, vecOrigin ); if ( !BecomeRagdollOnClient( vecForce ) ) { AddSolidFlags( FSOLID_NOT_STANDABLE ); RemoveSolidFlags( FSOLID_NOT_SOLID ); if( flFadeTime > 0.0 ) { SUB_StartFadeOut( flFadeTime ); } } }
BOOL CBaseMonster::CineCleanup() { CCineMonster *pOldCine = m_pCine; // am I linked to a cinematic? if(m_pCine) { // okay, reset me to what it thought I was before m_pCine->m_hTargetEnt = NULL; pev->movetype = m_pCine->m_saved_movetype; pev->solid = m_pCine->m_saved_solid; pev->effects = m_pCine->m_saved_effects; } else { // arg, punt pev->movetype = MOVETYPE_STEP; // this is evil pev->solid = SOLID_SLIDEBOX; } m_pCine = NULL; m_hTargetEnt = NULL; m_pGoalEnt = NULL; if(pev->deadflag == DEAD_DYING) { // last frame of death animation? pev->health = 0; pev->framerate = 0.0; pev->solid = SOLID_NOT; SetState(MONSTERSTATE_DEAD); pev->deadflag = DEAD_DEAD; UTIL_SetSize(pev, pev->mins, Vector(pev->maxs.x, pev->maxs.y, pev->mins.z + 2)); if(pOldCine && FBitSet(pOldCine->pev->spawnflags, SF_SCRIPT_LEAVECORPSE)) { SetUse(NULL); // BUGBUG -- This doesn't call Killed() SetThink(NULL); // This will probably break some stuff SetTouch(NULL); } else SUB_StartFadeOut(); // SetThink( SUB_DoNothing ); // This turns off animation & physics in case their origin ends up stuck in the world or something StopAnimation(); pev->movetype = MOVETYPE_NONE; pev->effects |= EF_NOINTERP; // Don't interpolate either, assume the corpse is positioned in its final resting place return FALSE; } // If we actually played a sequence if(pOldCine && pOldCine->m_iszPlay) { if(!(pOldCine->pev->spawnflags & SF_SCRIPT_NOSCRIPTMOVEMENT)) { // reset position Vector new_origin, new_angle; GetBonePosition(0, new_origin, new_angle); // Figure out how far they have moved // We can't really solve this problem because we can't query the movement of the origin relative // to the sequence. We can get the root bone's position as we do here, but there are // cases where the root bone is in a different relative position to the entity's origin // before/after the sequence plays. So we are stuck doing this: // !!!HACKHACK: Float the origin up and drop to floor because some sequences have // irregular motion that can't be properly accounted for. // UNDONE: THIS SHOULD ONLY HAPPEN IF WE ACTUALLY PLAYED THE SEQUENCE. Vector oldOrigin = pev->origin; // UNDONE: ugly hack. Don't move monster if they don't "seem" to move // this really needs to be done with the AX,AY,etc. flags, but that aren't consistantly // being set, so animations that really do move won't be caught. if((oldOrigin - new_origin).Length2D() < 8.0) new_origin = oldOrigin; pev->origin.x = new_origin.x; pev->origin.y = new_origin.y; pev->origin.z += 1; pev->flags |= FL_ONGROUND; int drop = DROP_TO_FLOOR(ENT(pev)); // Origin in solid? Set to org at the end of the sequence if(drop < 0) pev->origin = oldOrigin; else if(drop == 0) // Hanging in air? { pev->origin.z = new_origin.z; pev->flags &= ~FL_ONGROUND; } // else entity hit floor, leave there // pEntity->pev->origin.z = new_origin.z + 5.0; // damn, got to fix this UTIL_SetOrigin(pev, pev->origin); pev->effects |= EF_NOINTERP; } // We should have some animation to put these guys in, but for now it's idle. // Due to NOINTERP above, there won't be any blending between this anim & the sequence m_Activity = ACT_RESET; } // set them back into a normal state pev->enemy = NULL; if(pev->health > 0) m_IdealMonsterState = MONSTERSTATE_IDLE; // m_previousState; else { // Dropping out because he got killed // Can't call killed() no attacker and weirdness (late gibbing) may result m_IdealMonsterState = MONSTERSTATE_DEAD; SetConditions(bits_COND_LIGHT_DAMAGE); pev->deadflag = DEAD_DYING; FCheckAITrigger(); pev->deadflag = DEAD_NO; } // SetAnimation( m_MonsterState ); ClearBits(pev->spawnflags, SF_MONSTER_WAIT_FOR_SCRIPT); return TRUE; }
//========================================================= // RunTask //========================================================= void CBaseMonster :: RunTask ( Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_TURN_RIGHT: case TASK_TURN_LEFT: { ChangeYaw( pev->yaw_speed ); if ( FacingIdeal() ) { TaskComplete(); } break; } case TASK_PLAY_SEQUENCE_FACE_ENEMY: case TASK_PLAY_SEQUENCE_FACE_TARGET: { CBaseEntity *pTarget; if ( pTask->iTask == TASK_PLAY_SEQUENCE_FACE_TARGET ) pTarget = m_hTargetEnt; else pTarget = m_hEnemy; if ( pTarget ) { pev->ideal_yaw = UTIL_VecToYaw( pTarget->pev->origin - pev->origin ); ChangeYaw( pev->yaw_speed ); } if ( m_fSequenceFinished ) TaskComplete(); } break; case TASK_PLAY_SEQUENCE: case TASK_PLAY_ACTIVE_IDLE: { if ( m_fSequenceFinished ) { TaskComplete(); } break; } case TASK_FACE_ENEMY: { MakeIdealYaw( m_vecEnemyLKP ); ChangeYaw( pev->yaw_speed ); if ( FacingIdeal() ) { TaskComplete(); } break; } case TASK_FACE_HINTNODE: case TASK_FACE_LASTPOSITION: case TASK_FACE_TARGET: case TASK_FACE_IDEAL: case TASK_FACE_ROUTE: { ChangeYaw( pev->yaw_speed ); if ( FacingIdeal() ) { TaskComplete(); } break; } case TASK_WAIT_PVS: { if ( !FNullEnt(FIND_CLIENT_IN_PVS(edict())) ) { TaskComplete(); } break; } case TASK_WAIT_INDEFINITE: { // don't do anything. break; } case TASK_WAIT: case TASK_WAIT_RANDOM: { if ( gpGlobals->time >= m_flWaitFinished ) { TaskComplete(); } break; } case TASK_WAIT_FACE_ENEMY: { MakeIdealYaw ( m_vecEnemyLKP ); ChangeYaw( pev->yaw_speed ); if ( gpGlobals->time >= m_flWaitFinished ) { TaskComplete(); } break; } case TASK_MOVE_TO_TARGET_RANGE: { float distance; if ( m_hTargetEnt == NULL ) TaskFail(); else { distance = ( m_vecMoveGoal - pev->origin ).Length2D(); // Re-evaluate when you think your finished, or the target has moved too far if ( (distance < pTask->flData) || (m_vecMoveGoal - m_hTargetEnt->pev->origin).Length() > pTask->flData * 0.5 ) { m_vecMoveGoal = m_hTargetEnt->pev->origin; distance = ( m_vecMoveGoal - pev->origin ).Length2D(); FRefreshRoute(); } // Set the appropriate activity based on an overlapping range // overlap the range to prevent oscillation if ( distance < pTask->flData ) { TaskComplete(); RouteClear(); // Stop moving } else if ( distance < 190 && m_movementActivity != ACT_WALK ) m_movementActivity = ACT_WALK; else if ( distance >= 270 && m_movementActivity != ACT_RUN ) m_movementActivity = ACT_RUN; } break; } case TASK_WAIT_FOR_MOVEMENT: { if (MovementIsComplete()) { TaskComplete(); RouteClear(); // Stop moving } break; } case TASK_DIE: { if ( m_fSequenceFinished && pev->frame >= 255 ) { pev->deadflag = DEAD_DEAD; SetThink ( NULL ); StopAnimation(); if ( !BBoxFlat() ) { // a bit of a hack. If a corpses' bbox is positioned such that being left solid so that it can be attacked will // block the player on a slope or stairs, the corpse is made nonsolid. // pev->solid = SOLID_NOT; UTIL_SetSize ( pev, Vector ( -4, -4, 0 ), Vector ( 4, 4, 1 ) ); } else // !!!HACKHACK - put monster in a thin, wide bounding box until we fix the solid type/bounding volume problem UTIL_SetSize ( pev, Vector ( pev->mins.x, pev->mins.y, pev->mins.z ), Vector ( pev->maxs.x, pev->maxs.y, pev->mins.z + 1 ) ); if ( ShouldFadeOnDeath() ) { // this monster was created by a monstermaker... fade the corpse out. SUB_StartFadeOut(); } else { // body is gonna be around for a while, so have it stink for a bit. CSoundEnt::InsertSound ( bits_SOUND_CARCASS, pev->origin, 384, 30 ); } } break; } case TASK_RANGE_ATTACK1_NOTURN: case TASK_MELEE_ATTACK1_NOTURN: case TASK_MELEE_ATTACK2_NOTURN: case TASK_RANGE_ATTACK2_NOTURN: case TASK_RELOAD_NOTURN: { if ( m_fSequenceFinished ) { m_Activity = ACT_RESET; TaskComplete(); } break; } case TASK_RANGE_ATTACK1: case TASK_MELEE_ATTACK1: case TASK_MELEE_ATTACK2: case TASK_RANGE_ATTACK2: case TASK_SPECIAL_ATTACK1: case TASK_SPECIAL_ATTACK2: case TASK_RELOAD: { MakeIdealYaw ( m_vecEnemyLKP ); ChangeYaw ( pev->yaw_speed ); if ( m_fSequenceFinished ) { m_Activity = ACT_RESET; TaskComplete(); } break; } case TASK_SMALL_FLINCH: { if ( m_fSequenceFinished ) { TaskComplete(); } } break; case TASK_WAIT_FOR_SCRIPT: { if ( m_pCine->m_iDelay <= 0 && gpGlobals->time >= m_pCine->m_startTime ) { TaskComplete(); } break; } case TASK_PLAY_SCRIPT: { // ALERT(at_console, "Play Script\n"); if (m_fSequenceFinished) { // ALERT(at_console, "Anim Finished\n"); if (m_pCine->m_iRepeatsLeft > 0) { // ALERT(at_console, "Frame %f; Repeat %d from %f\n", pev->frame, m_pCine->m_iRepeatsLeft, m_pCine->m_fRepeatFrame); m_pCine->m_iRepeatsLeft--; pev->frame = m_pCine->m_fRepeatFrame; ResetSequenceInfo( ); } else { TaskComplete(); } } break; } } }