/* =========================================================================== Copyright (C) 2015 the OpenMoHAA team This file is part of OpenMoHAA source code. OpenMoHAA source code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. OpenMoHAA source code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenMoHAA source code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ // actor_balcony.cpp #include "actor.h" void Actor::InitBalconyIdle ( GlobalFuncs_t *func ) { func->ThinkState = &Actor::Think_Idle; func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Idle; func->Pain = &Actor::Pain_Balcony; func->Killed = &Actor::Killed_Balcony; func->IsState = &Actor::IsIdleState; } void Actor::InitBalconyCurious ( GlobalFuncs_t *func ) { func->ThinkState = &Actor::Think_Curious; func->BeginState = &Actor::Begin_Curious; func->EndState = &Actor::End_Curious; func->ResumeState = &Actor::Resume_Curious; func->SuspendState = &Actor::Suspend_Curious; func->FinishedAnimation = &Actor::FinishedAnimation_Curious; func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Curious; func->IsState = &Actor::IsCuriousState; func->Pain = &Actor::Pain_Balcony; func->Killed = &Actor::Killed_Balcony; } void Actor::InitBalconyAttack ( GlobalFuncs_t *func ) { func->ThinkState = &Actor::Think_BalconyAttack; func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Attack; func->BeginState = &Actor::Begin_BalconyAttack; func->FinishedAnimation = &Actor::FinishedAnimation_BalconyAttack; func->Pain = &Actor::Pain_Balcony; func->Killed = &Actor::Killed_Balcony; func->IsState = &Actor::IsAttackState; func->PostShoot = &Actor::State_Balcony_PostShoot; } void Actor::InitBalconyDisguise ( GlobalFuncs_t *func ) { func->IsState = &Actor::IsDisguiseState; } void Actor::InitBalconyGrenade ( GlobalFuncs_t *func ) { func->IsState = &Actor::IsGrenadeState; } void Actor::InitBalconyPain ( GlobalFuncs_t *func ) { func->BeginState = &Actor::Begin_Pain; func->ThinkState = &Actor::Think_Pain; func->FinishedAnimation = &Actor::FinishedAnimation_Pain; func->Pain = &Actor::Pain_Balcony; func->Killed = &Actor::Killed_Balcony; func->IsState = &Actor::IsPainState; } void Actor::InitBalconyKilled ( GlobalFuncs_t *func ) { func->BeginState = &Actor::Begin_BalconyKilled; func->EndState = &Actor::End_BalconyKilled; func->ThinkState = &Actor::Think_BalconyKilled; func->FinishedAnimation = &Actor::FinishedAnimation_BalconyKilled; func->IsState = &Actor::IsKilledState; } void Actor::Pain_Balcony ( Event *ev ) { SetThink( THINKSTATE_PAIN, 30 ); HandlePain( ev ); } void Actor::Killed_Balcony ( Event *ev, bool bPlayDeathAnim ) { ClearStates(); SetThink( THINKSTATE_KILLED, 31 ); HandleKilled( ev, true ); if( !bPlayDeathAnim ) ScriptError( "cannot do 'bedead' on balcony guys" ); } void Actor::Begin_BalconyAttack ( void ) { m_State = 200; m_iStateTime = level.inttime; } void Actor::State_Balcony_PostShoot ( void ) { if( m_Enemy ) { m_State = 201; m_iStateTime = level.inttime; } } void Actor::State_Balcony_FindEnemy ( void ) { m_bHasDesiredLookAngles = false; Anim_Aim(); if( CanSeeEnemy( 200 ) ) { m_State = 201; m_iStateTime = level.inttime; } } void Actor::State_Balcony_Target ( void ) { Anim_Aim(); AimAtAimNode(); if( level.inttime > m_iStateTime + 1000 ) { if( CanSeeEnemy( 0 ) && CanShootEnemy( 0 ) ) { m_State = 202; } else { ClearPath(); m_State = 200; } m_iStateTime = level.inttime; } } void Actor::State_Balcony_Shoot ( void ) { Anim_Shoot(); AimAtAimNode(); } void Actor::Think_BalconyAttack ( void ) { if( !RequireThink() ) return; UpdateEyeOrigin(); UpdateEnemy( 500 ); if( !m_Enemy ) { SetThinkState( THINKSTATE_IDLE, 0 ); IdleThink(); return; } NoPoint(); if( m_State == 201 ) { m_pszDebugState = "target"; State_Balcony_Target(); } else if( m_State == 202 ) { m_pszDebugState = "shoot"; State_Balcony_Shoot(); } else if( m_State = 200 ) { m_pszDebugState = "findenemy"; State_Balcony_FindEnemy(); } else { Com_Printf( "Actor::Think_BalconyAttack: invalid think state %i\n", m_State ); assert( 0 ); } PostThink( true ); } void Actor::FinishedAnimation_BalconyAttack ( void ) { if( m_State = 202 ) State_Balcony_PostShoot(); } void Actor::Begin_BalconyKilled ( void ) { ClearPath(); ResetBoneControllers(); PostEvent( EV_Actor_DeathEmbalm, 0.05f ); if( CalcFallPath() ) m_State = 800; else m_State = 806; m_iStateTime = level.inttime; } void Actor::End_BalconyKilled ( void ) { if( m_pFallPath ) { delete m_pFallPath; m_pFallPath = NULL; } } void Actor::Think_BalconyKilled ( void ) { int animnum; Unregister( STRING_ANIMDONE ); if( m_State = 805 ) { m_pszDebugState = "end"; } else { NoPoint(); m_bHasDesiredLookAngles = false; m_YawAchieved = true; switch( m_State ) { case 800: m_bNextForceStart = true; m_eNextAnimMode = 7; m_pszDebugState = "begin"; m_csNextAnimString = 270; ChangeMotionAnim(); animnum = gi.Anim_NumForName( edict->tiki, "death_balcony_intro" ); NewAnim( animnum ); SetTime( m_iMotionSlot, m_pFallPath->startTime ); UpdateNormalAnimSlot( m_iMotionSlot ); m_State = 801; m_iStateTime = level.inttime; break; case 801: m_bNextForceStart = false; m_pszDebugState = "intro"; m_eNextAnimMode = 7; m_csNextAnimString = STRING_ANIM_NO_KILLED_SCR; break; case 802: m_pszDebugState = "loop"; Anim_FullBody( STRING_DEATH_BALCONY_LOOP, 7 ); break; case 803: m_State = 804; m_iStateTime = level.inttime; StopAllAnimating(); case 804: m_pszDebugState = "outtro"; Anim_FullBody( STRING_DEATH_BALCONY_OUTTRO, 1 ); case 806: m_pszDebugState = "normal"; Anim_Killed(); break; default: Com_Printf( "Actor::Think_BalconyKilled: invalid think state %i\n", m_State ); assert( 0 ); } PostThink( false ); if( m_State >= 800 ) { if( m_State <= 801 ) { if( m_pFallPath->currentPos >= m_pFallPath->length ) { m_State = 803; m_iStateTime = level.inttime; return; } if( m_pFallPath->currentPos >= m_pFallPath->loop ) { m_State = 802; m_iStateTime = level.inttime; return; } } else { if( m_State == 802 && m_pFallPath->currentPos >= m_pFallPath->length ) { m_State = 803; m_iStateTime = level.inttime; } } } } } void Actor::FinishedAnimation_BalconyKilled ( void ) { if( m_State == 804 || m_State == 806 ) { BecomeCorpse(); m_State = 805; m_iStateTime = level.inttime; } else if( m_State == 801 ) { m_State = 802; m_iStateTime = level.inttime; StopAllAnimating(); } }