//========================================================= // MakeMonster- this is the code that drops the monster //========================================================= void CMonsterMaker::MakeMonster( void ) { if ( m_iMaxLiveChildren > 0 && m_cLiveChildren >= m_iMaxLiveChildren ) {// not allowed to make a new one yet. Too many live ones out right now. return; } if ( !m_flGround ) { // set altitude. Now that I'm activated, any breakables, etc should be out from under me. TraceResult tr; UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() - Vector ( 0, 0, 2048 ), ignore_monsters, ENT(pev), &tr ); m_flGround = tr.vecEndPos.z; } Vector mins = GetAbsOrigin() - Vector( 34, 34, 0 ); Vector maxs = GetAbsOrigin() + Vector( 34, 34, 0 ); maxs.z = GetAbsOrigin().z; mins.z = m_flGround; CBaseEntity *pList[2]; int count = UTIL_EntitiesInBox( pList, 2, mins, maxs, FL_CLIENT|FL_MONSTER ); if ( count ) { // don't build a stack of monsters! return; } CBaseEntity* pEntity = CBaseEntity::Create( STRING( m_iszMonsterClassname ), GetAbsOrigin(), GetAbsAngles(), nullptr, false ); if( !pEntity ) { ALERT( at_console, "NULL Ent in MonsterMaker!\n" ); return; } // If I have a target, fire! if ( HasTarget() ) { // delay already overloaded for this entity, so can't call SUB_UseTargets() FireTargets( GetTarget(), this, this, USE_TOGGLE, 0 ); } pEntity->SetAbsOrigin( GetAbsOrigin() ); pEntity->SetAbsAngles( GetAbsAngles() ); pEntity->GetSpawnFlags() |= SF_MONSTER_FALL_TO_GROUND; // Children hit monsterclip brushes if ( GetSpawnFlags().Any(SF_MONSTERMAKER_MONSTERCLIP ) ) pEntity->GetSpawnFlags() |= SF_MONSTER_HITMONSTERCLIP; DispatchSpawn( pEntity->edict() ); pEntity->SetOwner( this ); if ( HasNetName() ) { // if I have a netname (overloaded), give the child monster that name as a targetname pEntity->SetTargetname( GetNetName() ); } m_cLiveChildren++;// count this monster m_cNumMonsters--; if ( m_cNumMonsters == 0 ) { // Disable this forever. Don't kill it because it still gets death notices SetThink( NULL ); SetUse( NULL ); } }
void CNPC_BigMomma::StartTask( const Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_CHECK_NODE_PROXIMITY: { } break; case TASK_FIND_NODE: { CBaseEntity *pTarget = GetTarget(); if ( !HasMemory( bits_MEMORY_ADVANCE_NODE ) ) { if ( pTarget ) m_iszTarget = pTarget->m_target; } NodeStart( m_iszTarget ); TaskComplete(); //Msg( "BM: Found node %s\n", STRING( m_iszTarget ) ); } break; case TASK_NODE_DELAY: m_nodeTime = gpGlobals->curtime + pTask->flTaskData; TaskComplete(); //Msg( "BM: FAIL! Delay %.2f\n", pTask->flTaskData ); break; case TASK_PROCESS_NODE: //Msg( "BM: Reached node %s\n", STRING( m_iszTarget ) ); NodeReach(); TaskComplete(); break; case TASK_PLAY_NODE_PRESEQUENCE: case TASK_PLAY_NODE_SEQUENCE: { const char *pSequence = NULL; int iSequence; if ( pTask->iTask == TASK_PLAY_NODE_SEQUENCE ) pSequence = GetNodeSequence(); else pSequence = GetNodePresequence(); //Msg( "BM: Playing node sequence %s\n", pSequence ); if ( pSequence ) //ugh { iSequence = LookupSequence( pSequence ); if ( iSequence != -1 ) { SetIdealActivity( ACT_DO_NOT_DISTURB ); SetSequence( iSequence ); SetCycle( 0.0f ); ResetSequenceInfo(); //Msg( "BM: Sequence %s %f\n", GetNodeSequence(), gpGlobals->curtime ); return; } } TaskComplete(); } break; case TASK_NODE_YAW: GetMotor()->SetIdealYaw( GetNodeYaw() ); TaskComplete(); break; case TASK_WAIT_NODE: m_flWait = gpGlobals->curtime + GetNodeDelay(); /*if ( GetTarget() && GetTarget()->GetSpawnFlags() & SF_INFOBM_WAIT ) Msg( "BM: Wait at node %s forever\n", STRING( m_iszTarget) ); else Msg( "BM: Wait at node %s for %.2f\n", STRING( m_iszTarget ), GetNodeDelay() );*/ break; case TASK_MOVE_TO_NODE_RANGE: { CBaseEntity *pTarget = GetTarget(); if ( !pTarget ) TaskFail( FAIL_NO_TARGET ); else { if ( ( pTarget->GetAbsOrigin() - GetAbsOrigin() ).Length() < GetNodeRange() ) TaskComplete(); else { Activity act = ACT_WALK; if ( pTarget->GetSpawnFlags() & SF_INFOBM_RUN ) act = ACT_RUN; AI_NavGoal_t goal( GOALTYPE_TARGETENT, vec3_origin, act ); if ( !GetNavigator()->SetGoal( goal ) ) { TaskFail( NO_TASK_FAILURE ); } } } } //Msg( "BM: Moving to node %s\n", STRING( m_iszTarget ) ); break; case TASK_MELEE_ATTACK1: { // Play an attack sound here CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), "BigMomma.Attack" ); BaseClass::StartTask( pTask ); } break; default: BaseClass::StartTask( pTask ); break; } }
void CBasePlayer::PreThink() { const int buttonsChanged = ( m_afButtonLast ^ GetButtons().Get() ); // These buttons have changed this frame // Debounced button codes for pressed/released // UNDONE: Do we need auto-repeat? m_afButtonPressed = buttonsChanged & GetButtons().Get(); // The changed ones still down are "pressed" m_afButtonReleased = buttonsChanged & ( ~GetButtons().Get() ); // The ones not down are "released" g_pGameRules->PlayerThink( this ); bool bCheckVehicles = true; #if USE_ANGELSCRIPT uint32_t uiFlags = PreThinkFlag::NONE; CallGlobalEvent( g_PlayerPreThinkEvent, CallFlag::NONE, this, &uiFlags ); bCheckVehicles = !( uiFlags & PreThinkFlag::SKIP_VEHICLES ); #endif if( g_fGameOver ) return; // intermission or finale UTIL_MakeVectors( GetViewAngle() ); // is this still used? ItemPreFrame(); WaterMove(); if( g_pGameRules && g_pGameRules->FAllowFlashlight() ) m_iHideHUD &= ~HIDEHUD_FLASHLIGHT; else m_iHideHUD |= HIDEHUD_FLASHLIGHT; // JOHN: checks if new client data (for HUD and view control) needs to be sent to the client UpdateClientData(); CheckTimeBasedDamage(); CheckSuitUpdate(); // Observer Button Handling if( IsObserver() ) { Observer_HandleButtons(); Observer_CheckTarget(); Observer_CheckProperties(); SetImpulse( 0 ); return; } if( GetDeadFlag() >= DEAD_DYING ) { PlayerDeathThink(); return; } // So the correct flags get sent to client asap. // if( m_afPhysicsFlags & PFLAG_ONTRAIN ) GetFlags() |= FL_ONTRAIN; else GetFlags().ClearFlags( FL_ONTRAIN ); if( bCheckVehicles ) { #if USE_OPFOR //We're on a rope. - Solokiller if( m_afPhysicsFlags & PFLAG_ONROPE && m_pRope ) { SetAbsVelocity( g_vecZero ); const Vector vecAttachPos = m_pRope->GetAttachedObjectsPosition(); SetAbsOrigin( vecAttachPos ); Vector vecForce; /* //TODO: This causes sideways acceleration that doesn't occur in Op4. - Solokiller //TODO: should be IN_MOVERIGHT and IN_MOVELEFT - Solokiller if( GetButtons().Any( IN_DUCK ) ) { vecForce.x = gpGlobals->v_right.x; vecForce.y = gpGlobals->v_right.y; vecForce.z = 0; m_pRope->ApplyForceFromPlayer( vecForce ); } if( GetButtons().Any( IN_JUMP ) ) { vecForce.x = -gpGlobals->v_right.x; vecForce.y = -gpGlobals->v_right.y; vecForce.z = 0; m_pRope->ApplyForceFromPlayer( vecForce ); } */ //Determine if any force should be applied to the rope, or if we should move around. - Solokiller if( GetButtons().Any( IN_BACK | IN_FORWARD ) ) { if( ( gpGlobals->v_forward.x * gpGlobals->v_forward.x + gpGlobals->v_forward.y * gpGlobals->v_forward.y - gpGlobals->v_forward.z * gpGlobals->v_forward.z ) <= 0.0 ) { if( m_bIsClimbing ) { const float flDelta = gpGlobals->time - m_flLastClimbTime; m_flLastClimbTime = gpGlobals->time; if( GetButtons().Any( IN_FORWARD ) ) { if( gpGlobals->v_forward.z < 0.0 ) { if( !m_pRope->MoveDown( flDelta ) ) { //Let go of the rope, detach. - Solokiller SetMoveType( MOVETYPE_WALK ); SetSolidType( SOLID_SLIDEBOX ); m_afPhysicsFlags &= ~PFLAG_ONROPE; m_pRope->DetachObject(); m_pRope = nullptr; m_bIsClimbing = false; } } else { m_pRope->MoveUp( flDelta ); } } if( GetButtons().Any( IN_BACK ) ) { if( gpGlobals->v_forward.z < 0.0 ) { m_pRope->MoveUp( flDelta ); } else if( !m_pRope->MoveDown( flDelta ) ) { //Let go of the rope, detach. - Solokiller SetMoveType( MOVETYPE_WALK ); SetSolidType( SOLID_SLIDEBOX ); m_afPhysicsFlags &= ~PFLAG_ONROPE; m_pRope->DetachObject(); m_pRope = nullptr; m_bIsClimbing = false; } } } else { m_bIsClimbing = true; m_flLastClimbTime = gpGlobals->time; } } else { vecForce.x = gpGlobals->v_forward.x; vecForce.y = gpGlobals->v_forward.y; vecForce.z = 0.0; if( GetButtons().Any( IN_BACK ) ) { vecForce.x = -gpGlobals->v_forward.x; vecForce.y = -gpGlobals->v_forward.y; vecForce.z = 0; } m_pRope->ApplyForceFromPlayer( vecForce ); m_bIsClimbing = false; } } else { m_bIsClimbing = false; } if( m_afButtonPressed & IN_JUMP ) { //We've jumped off the rope, give us some momentum - Solokiller SetMoveType( MOVETYPE_WALK ); SetSolidType( SOLID_SLIDEBOX ); this->m_afPhysicsFlags &= ~PFLAG_ONROPE; Vector vecDir = gpGlobals->v_up * 165.0 + gpGlobals->v_forward * 150.0; Vector vecVelocity = m_pRope->GetAttachedObjectsVelocity() * 2; vecVelocity.NormalizeInPlace(); vecVelocity = vecVelocity * 200; SetAbsVelocity( vecVelocity + vecDir ); m_pRope->DetachObject(); m_pRope = nullptr; m_bIsClimbing = false; } return; } #endif // Train speed control if( m_afPhysicsFlags & PFLAG_ONTRAIN ) { CBaseEntity *pTrain = GetGroundEntity(); //To match original behavior, Instance returns the world if entity is null - Solokiller if( !pTrain ) pTrain = CWorld::GetInstance(); float vel; if( !pTrain ) { TraceResult trainTrace; // Maybe this is on the other side of a level transition UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + Vector( 0, 0, -38 ), ignore_monsters, ENT( pev ), &trainTrace ); // HACKHACK - Just look for the func_tracktrain classname if( trainTrace.flFraction != 1.0 && trainTrace.pHit ) pTrain = CBaseEntity::Instance( trainTrace.pHit ); if( !pTrain || !( pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE ) || !pTrain->OnControls( this ) ) { //ALERT( at_error, "In train mode with no train!\n" ); m_afPhysicsFlags &= ~PFLAG_ONTRAIN; m_iTrain = TRAIN_NEW | TRAIN_OFF; return; } } else if( !GetFlags().Any( FL_ONGROUND ) || pTrain->GetSpawnFlags().Any( SF_TRACKTRAIN_NOCONTROL ) || ( GetButtons().Any( IN_MOVELEFT | IN_MOVERIGHT ) ) ) { // Turn off the train if you jump, strafe, or the train controls go dead m_afPhysicsFlags &= ~PFLAG_ONTRAIN; m_iTrain = TRAIN_NEW | TRAIN_OFF; return; } SetAbsVelocity( g_vecZero ); vel = 0; if( m_afButtonPressed & IN_FORWARD ) { vel = 1; pTrain->Use( this, this, USE_SET, ( float ) vel ); } else if( m_afButtonPressed & IN_BACK ) { vel = -1; pTrain->Use( this, this, USE_SET, ( float ) vel ); } if( vel ) { m_iTrain = TrainSpeed( pTrain->GetSpeed(), pTrain->GetImpulse() ); m_iTrain |= TRAIN_ACTIVE | TRAIN_NEW; } } else if( m_iTrain & TRAIN_ACTIVE ) m_iTrain = TRAIN_NEW; // turn off train } if( GetButtons().Any( IN_JUMP ) ) { // If on a ladder, jump off the ladder // else Jump Jump(); } // If trying to duck, already ducked, or in the process of ducking if( GetButtons().Any( IN_DUCK ) || GetFlags().Any( FL_DUCKING ) || ( m_afPhysicsFlags & PFLAG_DUCKING ) ) Duck(); if( !GetFlags().Any( FL_ONGROUND ) ) { m_flFallVelocity = -GetAbsVelocity().z; } // StudioFrameAdvance( );//!!!HACKHACK!!! Can't be hit by traceline when not animating? // Clear out ladder pointer m_hEnemy = NULL; if( m_afPhysicsFlags & PFLAG_ONBARNACLE ) { SetAbsVelocity( g_vecZero ); } }