diff --git a/code/game/actor.cpp b/code/game/actor.cpp index 2e83976c..49539f0d 100644 --- a/code/game/actor.cpp +++ b/code/game/actor.cpp @@ -2487,8 +2487,54 @@ CLASS_DECLARATION( SimpleActor, Actor, "Actor" ) }; Actor::GlobalFuncs_t Actor::GlobalFuncs[ MAX_GLOBAL_FUNCS ]; -const_str Actor::m_csThinkNames[ MAX_GLOBAL_FUNCS ]; -const_str Actor::m_csThinkStateNames[ MAX_THINKMAP ]; +const_str Actor::m_csThinkNames[ MAX_GLOBAL_FUNCS ] = { + STRING_VOID, + STRING_TURRET, + STRING_COVER, + STRING_PATROL, + STRING_RUNNER, + STRING_PAIN, + STRING_KILLED, + STRING_MOVETO, + STRING_IDLE, + STRING_CURIOUS, + STRING_DISGUISE_SALUTE, + STRING_DISGUISE_SENTRY, + STRING_DISGUISE_OFFICER, + STRING_DISGUISE_ROVER, + STRING_DISGUISE_NONE, + STRING_ALARM, + STRING_GRENADE, + STRING_MACHINEGUNNER, + STRING_DOG_IDLE, + STRING_DOG_ATTACK, + STRING_DOG_CURIOUS, + STRING_DOG_GRENADE, + STRING_ANIM, + STRING_ANIM_CURIOUS, + STRING_AIM, + STRING_BALCONY_IDLE, + STRING_BALCONY_CURIOUS, + STRING_BALCONY_ATTACK, + STRING_BALCONY_DISGUISE, + STRING_BALCONY_GRENADE, + STRING_BALCONY_PAIN, + STRING_BALCONY_KILLED, + STRING_WEAPONLESS, + STRING_NOCLIP, + STRING_DEAD +}; +const_str Actor::m_csThinkStateNames[ MAX_THINKMAP ] = { + STRING_VOID, + STRING_IDLE, + STRING_PAIN, + STRING_KILLED, + STRING_ATTACK, + STRING_CURIOUS, + STRING_DISGUISE, + STRING_GRENADE, + STRING_NOCLIP +}; Actor::Actor() { @@ -2511,9 +2557,9 @@ Actor::Actor() setSolidType( SOLID_BBOX ); m_fFov = 90.0f; takedamage = DAMAGE_AIM; - m_fFov = cos( 0.78f ); + m_fFovDot = cos( 0.78f ); m_eAnimMode = 0; - m_eEmotionMode = 0; + m_eEmotionMode = EMOTION_NONE; m_bDoPhysics = true; path_failed_time = 0; health = 100; @@ -2545,7 +2591,7 @@ Actor::Actor() VectorClear2D( obstacle_vel ); m_bLockThinkState = false; InitThinkStates(); - SetThinkState(THINKSTATE_IDLE, 0 ); + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); m_fMinDistance = 128; m_fMinDistanceSquared = 128 * 128; m_fMaxDistance = 1024; @@ -2585,7 +2631,7 @@ Actor::Actor() m_bNoSurprise = false; memset( &m_pPotentialCoverNode, 0, sizeof( m_pPotentialCoverNode ) ); m_iPotentialCoverCount = 0; - m_pCoverNode = 0; + m_pCoverNode = NULL; m_csSpecialAttack = 0; m_sCurrentPathNodeIndex = -1; m_iDisguiseLevel = 1; @@ -2621,7 +2667,7 @@ Actor::Actor() m_bEnableEnemy = true; m_bDesiredEnableEnemy = true; m_bEnablePain = true; - m_bAnimScriptSet = 0; + m_bAnimScriptSet = false; m_AnimMode = 0; m_csAnimName = STRING_EMPTY; m_csSayAnim = STRING_EMPTY; @@ -2770,16 +2816,14 @@ void Actor::AimAt if( ev->IsVectorAt( 1 ) ) { Vector orig = ev->GetVector(1); - //FIXME: possible inline func /0 if (m_aimNode) { - if (m_aimNode->IsSubclassOfAnimate()) + if (m_aimNode->IsSubclassOfTempWaypoint()) { delete m_aimNode; } m_aimNode = NULL; } - // 0/ TempWaypoint * twp = new TempWaypoint; m_aimNode = twp; m_aimNode->setOrigin(orig); @@ -2787,16 +2831,14 @@ void Actor::AimAt else { Listener *l = ev->GetListener(1); - //FIXME: possible inline func /0 if (m_aimNode) { - if (m_aimNode->IsSubclassOfAnimate()) + if (m_aimNode->IsSubclassOfTempWaypoint()) { delete m_aimNode; } m_aimNode = NULL; } - // 0/ if (l) { if (!checkInheritance(&SimpleEntity::ClassInfo, l->classinfo())) @@ -2810,8 +2852,8 @@ void Actor::AimAt } } - //FIXME: macro THINKSTATE_something - SetThinkIdle( m_aimNode != NULL ? 24 : 8); + + SetThinkIdle( m_aimNode != NULL ? THINK_AIM : THINK_IDLE); } void Actor::DefaultRestart @@ -2854,7 +2896,6 @@ void Actor::BeginState ) { - m_Think[ m_ThinkLevel ] = m_ThinkMap[ m_ThinkState ]; GlobalFuncs_t *func = &GlobalFuncs[ m_Think[ m_ThinkLevel ] ]; @@ -2873,7 +2914,7 @@ void Actor::EndState { GlobalFuncs_t *func = &GlobalFuncs[ m_Think[ level ] ]; - m_Think[ level ] = 0; + m_Think[ level ] = THINK_VOID; if( func->EndState ) ( this->*func->EndState )(); @@ -2911,29 +2952,28 @@ void Actor::InitThinkStates { for (size_t i = 0; i < MAX_THINKMAP; i++) { - m_ThinkMap[i] = 0; + m_ThinkMap[i] = THINK_VOID; } for (size_t i = 0; i < MAX_THINKSTATES; i++) { - m_Think[i] = 0; - m_ThinkStates[i++] = 0; + m_Think[i] = THINK_VOID; + m_ThinkStates[i] = THINKSTATE_VOID; } m_bDirtyThinkState = false; - //FIXME: create proper macros - m_ThinkMap[0] = 0; - m_ThinkMap[1] = 8; - m_ThinkMap[2] = 5; - m_ThinkMap[3] = 6; - m_ThinkMap[4] = 1; - m_ThinkMap[5] = 9; - m_ThinkMap[6] = 10; - m_ThinkMap[7] = 16; - m_ThinkMap[8] = 33; + m_ThinkMap[THINKSTATE_VOID] = THINK_VOID; + m_ThinkMap[THINKSTATE_IDLE] = THINK_IDLE; + m_ThinkMap[THINKSTATE_PAIN] = THINK_PAIN; + m_ThinkMap[THINKSTATE_KILLED] = THINK_KILLED; + m_ThinkMap[THINKSTATE_ATTACK] = THINK_TURRET; + m_ThinkMap[THINKSTATE_CURIOUS] = THINK_CURIOUS; + m_ThinkMap[THINKSTATE_DISGUISE] = THINKSTATE_DISGUISE; + m_ThinkMap[THINKSTATE_GRENADE] = THINK_GRENADE; + m_ThinkMap[THINKSTATE_NOCLIP] = THINK_NOCLIP; - m_ThinkLevel = 0; - m_ThinkState = 0; + m_ThinkLevel = THINKLEVEL_NORMAL; + m_ThinkState = THINKSTATE_VOID; } @@ -2997,8 +3037,7 @@ bool Actor::RequireThink ) { - G_GetEntity(0); - if( g_entities[ 0 ].entity ) + if(G_GetEntity(0)) return ( level.inttime < edict->r.lastNetTime + 60000 ); else return false; @@ -3029,7 +3068,7 @@ void Actor::UpdateEnemyInternal if (m_Enemy != m_PotentialEnemies.GetCurrentEnemy()) SetEnemy(m_PotentialEnemies.GetCurrentEnemy(), false); - m_fNoticeTimeScale = (level.inttime - m_iEnemyCheckTime) * 0.0001 + m_fNoticeTimeScale; + m_fNoticeTimeScale = (level.inttime - m_iEnemyCheckTime) / 10000 + m_fNoticeTimeScale; if (m_fNoticeTimeScale > m_fMaxNoticeTimeScale) m_fNoticeTimeScale = m_fMaxNoticeTimeScale; @@ -3107,8 +3146,8 @@ void Actor::SetEnemyPos { mTargetPos.z += 88; } - //FIXME: Virtual function call here. - if (mTargetPos.z - m_Enemy->eyeposition.z < 128) + + if (mTargetPos.z - m_Enemy->EyePosition().z < 128) { mTargetPos.z -= 16; } @@ -3127,9 +3166,9 @@ void Actor::ResetBodyQueue { //do nothing. } - - //FIXME: linker err - //mCurBody = 0; + //mBodyQueue + //this resets curBody, but all the magic happens in AddToBodyQue + mCurBody = 0; } void Actor::AddToBodyQue @@ -3138,16 +3177,17 @@ void Actor::AddToBodyQue ) { - //FIXME: wrong notation, maybe mBodyQueu + mCurBody ? - /* - if (mBodyQueue[4*mCurBody+3]) + SafePtr lastActor = mBodyQueue[mCurBody + 3]; + + if (lastActor) { Event ev(EV_Remove); - PostEvent(ev, 0, 0); + lastActor->PostEvent(ev, 0); } - mBodyQueue[4 * mCurBody] = this; + + mBodyQueue[mCurBody] = this; mCurBody = (mCurBody + 1) % 5; - */ + } Vector Actor::GetAntiBunchPoint @@ -3212,7 +3252,7 @@ const char *Actor::DumpCallTrace Vector vPlayer = vec_zero; char szFile[64]; int i2; - int i1; + //int i1; int i; char szTemp[65536]; char szTemp2[1024]; @@ -3331,41 +3371,39 @@ void Actor::Init GlobalFuncs[i].PathnodeClaimRevoked = NULL; } - GlobalFuncs[0].IsState = &Actor::IsVoidState; - - //FIXME: create enum - InitTurret(&GlobalFuncs[1]); - InitCover(&GlobalFuncs[2]); - InitPatrol(&GlobalFuncs[3]); - InitRunner(&GlobalFuncs[4]); - InitPain(&GlobalFuncs[5]); - InitKilled(&GlobalFuncs[6]); - InitIdle(&GlobalFuncs[8]); - InitCurious(&GlobalFuncs[9]); - InitDisguiseSalute(&GlobalFuncs[10]); - InitDisguiseSentry(&GlobalFuncs[11]); - InitDisguiseOfficer(&GlobalFuncs[12]); - InitDisguiseRover(&GlobalFuncs[13]); - InitDisguiseNone(&GlobalFuncs[14]); - InitAlarm(&GlobalFuncs[15]); - InitGrenade(&GlobalFuncs[16]); - InitMachineGunner(&GlobalFuncs[17]); - InitDogIdle(&GlobalFuncs[18]); - InitDogAttack(&GlobalFuncs[19]); - InitDogCurious(&GlobalFuncs[20]); - InitAnim(&GlobalFuncs[22]); - InitAnimCurious(&GlobalFuncs[23]); - InitAim(&GlobalFuncs[24]); - InitBalconyIdle(&GlobalFuncs[25]); - InitBalconyCurious(&GlobalFuncs[26]); - InitBalconyAttack(&GlobalFuncs[27]); - InitBalconyDisguise(&GlobalFuncs[28]); - InitBalconyGrenade(&GlobalFuncs[29]); - InitBalconyPain(&GlobalFuncs[30]); - InitBalconyKilled(&GlobalFuncs[31]); - InitWeaponless(&GlobalFuncs[32]); - InitNoClip(&GlobalFuncs[33]); - InitDead(&GlobalFuncs[34]); + InitVoid(&GlobalFuncs[THINK_VOID]); + InitTurret(&GlobalFuncs[THINK_TURRET]); + InitCover(&GlobalFuncs[THINK_COVER]); + InitPatrol(&GlobalFuncs[THINK_PATROL]); + InitRunner(&GlobalFuncs[THINK_RUNNER]); + InitPain(&GlobalFuncs[THINK_PAIN]); + InitKilled(&GlobalFuncs[THINK_KILLED]); + InitIdle(&GlobalFuncs[THINK_IDLE]); + InitCurious(&GlobalFuncs[THINK_CURIOUS]); + InitDisguiseSalute(&GlobalFuncs[THINK_DISGUISE_SALUTE]); + InitDisguiseSentry(&GlobalFuncs[THINK_DISGUISE_SENTRY]); + InitDisguiseOfficer(&GlobalFuncs[THINK_DISGUISE_OFFICER]); + InitDisguiseRover(&GlobalFuncs[THINK_DISGUISE_ROVER]); + InitDisguiseNone(&GlobalFuncs[THINK_DISGUISE_NONE]); + InitAlarm(&GlobalFuncs[THINK_ALARM]); + InitGrenade(&GlobalFuncs[THINK_GRENADE]); + InitMachineGunner(&GlobalFuncs[THINK_MACHINEGUNNER]); + InitDogIdle(&GlobalFuncs[THINK_DOG_IDLE]); + InitDogAttack(&GlobalFuncs[THINK_DOG_ATTACK]); + InitDogCurious(&GlobalFuncs[THINK_DOG_CURIOUS]); + InitAnim(&GlobalFuncs[THINK_ANIM]); + InitAnimCurious(&GlobalFuncs[THINK_ANIM_CURIOUS]); + InitAim(&GlobalFuncs[THINK_AIM]); + InitBalconyIdle(&GlobalFuncs[THINK_BALCONY_IDLE]); + InitBalconyCurious(&GlobalFuncs[THINK_BALCONY_CURIOUS]); + InitBalconyAttack(&GlobalFuncs[THINK_BALCONY_ATTACK]); + InitBalconyDisguise(&GlobalFuncs[THINK_BALCONY_DISGUISE]); + InitBalconyGrenade(&GlobalFuncs[THINK_BALCONY_GRENADE]); + InitBalconyPain(&GlobalFuncs[THINK_BALCONY_PAIN]); + InitBalconyKilled(&GlobalFuncs[THINK_BALCONY_KILLED]); + InitWeaponless(&GlobalFuncs[THINK_WEAPONLESS]); + InitNoClip(&GlobalFuncs[THINK_NOCLIP]); + InitDead(&GlobalFuncs[THINK_DEAD]); AddWaitTill(STRING_TRIGGER); AddWaitTill(STRING_MOVE); @@ -3502,6 +3540,14 @@ void Actor::FixAIParameters } } + +/* +=============== +Actor::AttackEntryAnimation + +Returns true if actor stands/draws his weapon. +=============== +*/ bool Actor::AttackEntryAnimation ( void @@ -3510,33 +3556,32 @@ bool Actor::AttackEntryAnimation { if (m_Enemy) { - //FIXME: macro + if (level.inttime >= level.m_iAttackEntryAnimTime + 3000) { float distSq = (m_Enemy->origin - origin).lengthXY(true); - //FIXME: macro - if (m_bNoSurprise || distSq >= 65536) //2 power 16 + + if (m_bNoSurprise || distSq >= 65536) //256 sq { - if (distSq > 1048576 && !(rand() & 3))//2 power 20 + if (distSq > 1048576 && !(rand() & 3))//1024 sq { if (m_pNextSquadMate != this) { for (auto pSquadMate = m_pNextSquadMate; true; pSquadMate->m_pNextSquadMate) { - if (m_fInterval*m_fInterval*4 > (pSquadMate->origin - origin).lengthSquared()) + if (Square(m_fInterval) * 4 > (pSquadMate->origin - origin).lengthSquared()) { break; } if (pSquadMate == this) { + //FIXME: macro if (m_bNewEnemy) - { - //FIXME: macro Anim_Say(STRING_ANIM_SAY_SIGHTED_SCR, 200, false); - m_bNoSurprise = true; - m_bNewEnemy = false; - return false; - } + + m_bNoSurprise = true; + m_bNewEnemy = false; + return false; } } vec2_t vDelta; @@ -3544,9 +3589,7 @@ bool Actor::AttackEntryAnimation vDelta[1] = m_Enemy->origin.y - origin.y; if (vDelta[0] != 0 || vDelta[1] != 0) { - //continue here - m_YawAchieved = false; - m_DesiredYaw = vectoyaw(vDelta); + SetDesiredYawDir(vDelta); } SetDesiredLookDir(m_Enemy->origin - origin); @@ -3565,29 +3608,27 @@ bool Actor::AttackEntryAnimation else { //FIXME: macro - if (rand() > distSq * 0.0026041667) + if ( rand() / 0x17F > distSq ) { //FIXME: macro m_eNextAnimMode = 1; m_csNextAnimString = STRING_ANIM_STANDSHOCK_SCR; m_bNextForceStart = true; - this->m_bNoSurprise = true; - this->m_bNewEnemy = false; + m_bNoSurprise = true; + m_bNewEnemy = false; return true; } } } + //FIXME: macro if (m_bNewEnemy) - { - //FIXME: macro Anim_Say(STRING_ANIM_SAY_SIGHTED_SCR, 200, false); - m_bNoSurprise = true; - m_bNewEnemy = false; - return false; - } + + m_bNoSurprise = true; + m_bNewEnemy = false; } return false; @@ -3599,27 +3640,27 @@ void Actor::CheckForThinkStateTransition ) { - if (!CheckForTransition(0, THINKSTATE_GRENADE)) + if (!CheckForTransition(THINKSTATE_GRENADE, THINKLEVEL_NORMAL)) { if (!m_bEnableEnemy) { - CheckForTransition(0, THINKSTATE_IDLE); + CheckForTransition(THINKSTATE_IDLE, THINKLEVEL_NORMAL); } else { - if (!CheckForTransition(0, THINKSTATE_ATTACK)) + if (!CheckForTransition(THINKSTATE_ATTACK, THINKLEVEL_NORMAL)) { - if (!CheckForTransition(0, THINKSTATE_DISGUISE)) + if (!CheckForTransition(THINKSTATE_DISGUISE, THINKLEVEL_NORMAL)) { - if (CheckForTransition(0, THINKSTATE_CURIOUS)) + if (CheckForTransition(THINKSTATE_CURIOUS, THINKLEVEL_NORMAL)) { m_pszDebugState = "from_sight"; } else { - CheckForTransition(0, THINKSTATE_IDLE); + CheckForTransition(THINKSTATE_IDLE, THINKLEVEL_NORMAL); } } } @@ -3642,7 +3683,7 @@ bool Actor::CheckForTransition if( func->PassesTransitionConditions && ( this->*( func->PassesTransitionConditions ) )() ) { - SetThinkState( state, 0 ); + SetThinkState( state, THINKLEVEL_NORMAL); return true; } } @@ -3767,14 +3808,9 @@ bool Actor::PassesTransitionConditions_Curious return true; } - if(EnemyIsDisguised()) - { - SetCuriousAnimHint(6); - return true; - } - - if( m_PotentialEnemies.GetCurrentVisibility() <= 0.999f ) + if(m_Enemy && !EnemyIsDisguised() && m_PotentialEnemies.GetCurrentVisibility() <= 0.999f ) { + //THINKSTATE_CURIOUS SetCuriousAnimHint(6); return true; } @@ -3823,11 +3859,11 @@ void Actor::UpdateEnableEnemy else { //FIXME: macros - if ((m_ThinkStates[0] - 4) <= 2) + if (m_ThinkStates[0] <= THINKSTATE_DISGUISE) { - SetThinkState(THINKSTATE_IDLE, 0); + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); } - SetEnemy(NULL, 0); + SetEnemy(NULL, false); } } } @@ -3841,11 +3877,11 @@ void Actor::ThinkStateTransitions int newThinkLevel; int newThinkState; - GlobalFuncs_t *func;// = &GlobalFuncs[m_Think[m_ThinkLevel]]; + //GlobalFuncs_t *func;// = &GlobalFuncs[m_Think[m_ThinkLevel]]; - for (newThinkLevel = MAX_THINKSTATES -1; newThinkLevel >=0 ; newThinkLevel--) + for (newThinkLevel = MAX_THINKSTATES -1; newThinkLevel >= 0 ; newThinkLevel--) { - newThinkState = m_ThinkMap[newThinkLevel]; + newThinkState = m_ThinkStates[newThinkLevel]; if (newThinkState) { break; @@ -3859,12 +3895,12 @@ void Actor::ThinkStateTransitions m_ThinkLevel = newThinkLevel; m_ThinkState = newThinkState; m_Think[newThinkLevel] = m_ThinkMap[newThinkState]; - return; + } + else + { + RestartState(); } - func = &GlobalFuncs[m_ThinkMap[newThinkState]]; - if (func->RestartState) - (this->*func->RestartState)(); } else { @@ -3872,7 +3908,7 @@ void Actor::ThinkStateTransitions { for (int i = 0 ; i < newThinkLevel; i++) { - if (!m_ThinkStates[i]) + if (m_ThinkStates[i] == THINKSTATE_VOID) EndState(i); } } @@ -3885,38 +3921,41 @@ void Actor::ThinkStateTransitions m_Think[newThinkLevel] = m_ThinkMap[m_ThinkState]; BeginState(); - return; } - EndState(m_ThinkLevel); - - if (newThinkLevel == this->m_ThinkLevel) + else { - m_ThinkState = m_ThinkStates[newThinkLevel]; - m_Think[newThinkLevel] = m_ThinkMap[m_ThinkState]; + EndState(m_ThinkLevel); - BeginState(); - return; + if (newThinkLevel == m_ThinkLevel) + { + m_ThinkState = m_ThinkStates[newThinkLevel]; + m_Think[newThinkLevel] = m_ThinkMap[m_ThinkState]; + + BeginState(); + } + else + { + m_ThinkLevel = newThinkLevel; + m_ThinkState = newThinkState = m_ThinkStates[newThinkLevel]; + + + if (m_Think[newThinkLevel] != m_ThinkMap[newThinkState]) + { + EndState(newThinkLevel); + + + m_Think[newThinkLevel] = m_ThinkMap[newThinkState]; + + BeginState(); + } + else + { + ResumeState(); + } + } } - m_ThinkLevel = newThinkLevel; - m_ThinkState = m_ThinkStates[newThinkLevel]; - - if (m_Think[newThinkLevel] != m_ThinkMap[m_ThinkState]) - { - EndState(newThinkLevel); - - - m_Think[m_ThinkLevel] = m_ThinkMap[m_ThinkState]; - - BeginState(); - return; - - } - - func = &GlobalFuncs[m_ThinkMap[newThinkState]]; - if (func->ResumeState) - (this->*func->ResumeState)(); } } @@ -4087,7 +4126,7 @@ void Actor::UpdateSayAnim ) { - if ((m_ThinkState) > 3) + if (m_ThinkState > THINKSTATE_KILLED) { int animnum = gi.Anim_NumForName(edict->tiki, Director.GetString(m_csSayAnim).c_str()); if (animnum == -1) @@ -4098,7 +4137,7 @@ void Actor::UpdateSayAnim if (flags & ANIM_TOGGLEBIT) { - if (m_ThinkState != 4 && m_ThinkState != 7) + if (m_ThinkState != THINKSTATE_ATTACK && m_ThinkState != THINKSTATE_GRENADE) { ChangeActionAnim(); if (flags & ANIM_NOACTION) @@ -4131,7 +4170,7 @@ void Actor::UpdateSayAnim return; } } - else if (m_bNextLevelSayAnim == 2 || m_ThinkState != 4 && m_ThinkState != 7) + else if (m_bNextLevelSayAnim == 2 || m_ThinkState != THINKSTATE_ATTACK && m_ThinkState != THINKSTATE_GRENADE) { ChangeSayAnim(); m_bSayAnimSet = true; @@ -4156,7 +4195,7 @@ void Actor::UpdateUpperAnim int animnum = gi.Anim_NumForName(edict->tiki, Director.GetString(m_csUpperAnim).c_str()); if (animnum != -1) { - if (m_ThinkState == 4 || m_ThinkState == 7 || m_ThinkState == 3 || m_ThinkState == 2) + if (IsAttackState(m_ThinkState) || IsGrenadeState(m_ThinkState) || IsKilledState(m_ThinkState) || IsPainState(m_ThinkState)) { if (!m_bActionAnimSet) { @@ -4234,7 +4273,7 @@ void Actor::UpdateAnim fAnimTime = AnimTime(slot); fAnimWeight = edict->s.frameInfo[slot].weight; //FIXME: macro - if ((int)time & 0x7F800000 == 0x7F800000) + if ((((int)time) & 0x7F800000) == 0x7F800000) { Com_Printf("ent %i, targetname '%s', anim '%s', slot %i, fAnimTime %f, fAnimWeight %f\n", entnum, @@ -4260,19 +4299,22 @@ void Actor::UpdateAnim } void Actor::StoppedWaitFor - ( +( const_str name, bool bDeleting - ) +) { + g_iInThinks++; GlobalFuncs_t *func = &GlobalFuncs[m_Think[m_ThinkLevel]]; if (func->FinishedAnimation) + { (this->*func->FinishedAnimation)(); + } - g_iInThinks ^= 1;//toggle + g_iInThinks--; } bool Actor::ValidGrenadePath @@ -4411,7 +4453,7 @@ Vector Actor::CalcThrowVelocity ) { - //FIXME: needs revivsion + variable names + Vector ret; Vector vDelta; float v10; // ST0C_4 @@ -4552,7 +4594,7 @@ bool Actor::CanTossGrenadeThroughHint { float fGravity = 0.8 * sv_gravity->value; - float fAngle, fTemp, fTemp2, fTemp3, fTemp4, fVelVert, fVelHorz, fRange, fRangeSquared, fDist, fDistSquared, fHeight; + float fAngle, fTemp, fTemp2, fTemp3, fTemp4, /*fVelVert, fVelHorz,*/ fRange, fRangeSquared, fDist, fDistSquared, fHeight; bool bSuccess = false; Vector vDelta, vHintDelta; @@ -5020,13 +5062,13 @@ void Actor::Think { int v1, v2, v3, tempHistory,ohIndex; - m_bAnimating = 0; + m_bAnimating = false; if (g_ai->integer && m_bDoAI && edict->tiki) { Director.iPaused++; - //FIXME: name history calculation variables. + v1 = level.inttime; v2 = v1 / 125; v3 = v1 / 125; @@ -5052,7 +5094,7 @@ void Actor::Think { Com_Printf("(entnum %d, radnum %d) is going solid after not getting stuck in the player\n", entnum, radnum); setSolidType(SOLID_BBOX); - m_bNoPlayerCollision = 0; + m_bNoPlayerCollision = false; } } m_eNextAnimMode = -1; @@ -5069,12 +5111,12 @@ void Actor::Think } else { - //FIXME: possible macros/enums - if ((m_ThinkStates[0] - 4) <= 2) + + if (m_ThinkStates[THINKLEVEL_NORMAL] <= THINKSTATE_DISGUISE) { - SetThinkState(THINKSTATE_IDLE, 0); + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); } - SetEnemy(0, 0); + SetEnemy(NULL, false); } } @@ -5086,7 +5128,7 @@ void Actor::Think if (m_bBecomeRunner) { parm.movefail = false; - if (m_ThinkMap[1] != 4 && m_ThinkMap[1] != 3) + if (m_ThinkMap[THINKSTATE_IDLE] != THINK_RUNNER && m_ThinkMap[THINKSTATE_IDLE] != THINK_PATROL) { parm.movefail = true; } @@ -5119,7 +5161,7 @@ void Actor::PostThink CheckUnregister(); if (bDontFaceWall) { - if (!m_pTurnEntity || m_ThinkState != 1) + if (!m_pTurnEntity || m_ThinkState != THINKSTATE_IDLE) { DontFaceWall(); } @@ -5319,8 +5361,8 @@ void Actor::DoFailSafeMove VectorCopy(dest, m_NoClipDest); - //FIXME: macros - SetThinkState(8, 3); + + SetThinkState(THINKSTATE_NOCLIP, THINKLEVEL_NOCLIP); } void Actor::TouchStuff @@ -5640,10 +5682,10 @@ void Actor::EventShareGrenade { Vector dist = pSquadMate->origin - origin; float distSq = dist * dist; - //FIXME: where did that constant come from? + if (distSq < 589824) { - //FIXME: where did that constant come from? + if (DoesTheoreticPathExist(pSquadMate->origin, 1536)) { pSquadMate->SetGrenade(m_pGrenade); @@ -5716,7 +5758,7 @@ void Actor::DefaultReceiveAIEvent FootstepSound(event_origin, fDistSquared, fMaxDistSquared, originator); break; case AI_EVENT_GRENADE: - Actor::GrenadeNotification(originator); + GrenadeNotification(originator); break; default: { @@ -5775,7 +5817,7 @@ void Actor::CuriousSound int iPriority; if (m_bEnableEnemy) { - if (m_ThinkStates[0] == 1 || m_ThinkStates[0] == 5) + if (m_ThinkStates[THINKLEVEL_NORMAL] == THINKSTATE_IDLE || m_ThinkStates[THINKLEVEL_NORMAL] == THINKSTATE_CURIOUS) { //FIXME: name variables. if (fMaxDistSquared != 0.0) @@ -5825,8 +5867,8 @@ void Actor::CuriousSound SetEnemyPos(sound_origin); - SetThinkState(THINKSTATE_NONE, m_ThinkLevel); - SetThinkState(THINKSTATE_CURIOUS, 0); + SetThinkState(THINKSTATE_VOID, m_ThinkLevel); + SetThinkState(THINKSTATE_CURIOUS, THINKLEVEL_NORMAL); m_pszDebugState = (char *)G_AIEventStringFromType(iType); } @@ -5897,7 +5939,7 @@ void Actor::WeaponSound { Actor *pAOwner = (Actor *)pOwner; //FIXME: macro - if (originator->IsSubclassOfWeapon() && pAOwner->m_Think[0] == 17) + if (originator->IsSubclassOfWeapon() && pAOwner->m_Think[0] == THINK_MACHINEGUNNER) { Weapon *pWOriginator = (Weapon *)originator; if (pWOriginator->aim_target) @@ -6034,11 +6076,55 @@ void Actor::VoiceSound ) { - if (iType != 4 && iType != 5 && iType != 6 && iType != 4) + bool bFriendly; + //FIXME: macros + if (m_ThinkStates[0] != THINKSTATE_IDLE && m_ThinkStates[0] != THINKSTATE_CURIOUS || !m_bEnableEnemy) + return; + + bFriendly = m_Team == TEAM_GERMAN; + + if (iType <= 5) { + assert(iType == 4); } - // FIXME: stub - STUB(); + else + { + assert(iType <= 7); + + if (iType == 6) + { + bFriendly = m_Team == TEAM_AMERICAN; + } + } + + if (bFriendly) + { + if (IsSquadMate((Sentient *)originator)) + { + return; + } + + if (originator == m_Enemy) + { + if (EnemyInFOV(0) && CanSeeEnemy(0)) + { + return; + } + } + else + { + if (InFOV(originator->centroid, m_fFov, m_fFovDot) + && gi.AreasConnected(edict->r.areanum, originator->edict->r.areanum)) + { + if (CanSeeFrom(EyePosition(), originator)) + { + return; + } + } + } + } + + CuriousSound(iType, sound_origin, fDistSquared, fMaxDistSquared); } void Actor::GrenadeNotification @@ -6194,41 +6280,28 @@ void Actor::RaiseAlertnessForEventType ) { - //FIXME: inunderstandable variables - long double v2,v3,v4,v8; + float fAmount; + switch (iType) { case AI_EVENT_WEAPON_FIRE: - v2 = 0.2; - goto ACTOREVENTLABEL_3; + fAmount = 0.2; case AI_EVENT_WEAPON_IMPACT: - v2 = 0.1; - goto ACTOREVENTLABEL_3; + fAmount = 0.1; case AI_EVENT_EXPLOSION: - v2 = 0.40000001; - goto ACTOREVENTLABEL_3; + fAmount = 0.4; case AI_EVENT_AMERICAN_VOICE: case AI_EVENT_AMERICAN_URGENT: - if (m_Team) + if (m_Team == TEAM_AMERICAN) return; - v2 = 0.25; - goto ACTOREVENTLABEL_3; + fAmount = 0.25; case AI_EVENT_MISC: - v2 = 0.02; - goto ACTOREVENTLABEL_3; + fAmount = 0.02; case AI_EVENT_MISC_LOUD: case AI_EVENT_FOOTSTEP: - v2 = 0.050000001; - goto ACTOREVENTLABEL_3; + fAmount = 0.05; case AI_EVENT_GRENADE: - v2 = 0.039999999; - ACTOREVENTLABEL_3: - v8 = m_fNoticeTimeScale; - v3 = v2; - v4 = v8 * 0.66666669; - if (v3 <= v4) - v4 = v3; - m_fNoticeTimeScale = v8 - v4; + fAmount = 0.04; break; case AI_EVENT_GERMAN_VOICE: case AI_EVENT_GERMAN_URGENT: @@ -6238,6 +6311,7 @@ void Actor::RaiseAlertnessForEventType } default: assert(0); + return; /* useless assert if (!dword_39A90C) { @@ -6259,6 +6333,7 @@ void Actor::RaiseAlertnessForEventType }*/ break; } + RaiseAlertness(fAmount); } void Actor::RaiseAlertness @@ -6267,13 +6342,11 @@ void Actor::RaiseAlertness ) { - //FIXME: inunderstandable variable - float v2; // fst7 + float fMaxAmount; - v2 = m_fNoticeTimeScale * 0.66666669; - if (fAmount <= v2) - v2 = fAmount; - m_fNoticeTimeScale -= v2; + fMaxAmount = m_fNoticeTimeScale * 2/3; + + m_fNoticeTimeScale -= fAmount <= fMaxAmount ? fAmount : fAmount; } bool Actor::CanSee @@ -6294,7 +6367,7 @@ bool Actor::CanSee m_iEnemyCheckTime = level.inttime; m_iLastEnemyVisibleTime = level.inttime; } - //FIXME: possible macro + if (canSee != m_bEnemyVisible) { m_bEnemyVisible = true; @@ -6303,7 +6376,7 @@ bool Actor::CanSee if (fov != 0) { - //FIXME: possible macro + m_iEnemyFovCheckTime = level.inttime; if (canSee != m_bEnemyInFOV) { @@ -6589,12 +6662,12 @@ void Actor::ShowInfo bEntinfoInit = true; } - fMinDot = 0.89999998; + fMinDot = 0.9f; fMaxDist = g_entinfo_max->value; if (m_ThinkState == THINKSTATE_KILLED) { - fMinDot = 0.99000001; + fMinDot = 0.99f; fMaxDist = 512; } @@ -6686,7 +6759,7 @@ void Actor::ShowInfo 1.0, 1065353216, "%s", - Director.GetString(m_csThinkStateNames[m_ThinkState]).c_str()); + ThinkStateName().c_str()); } @@ -6697,7 +6770,7 @@ void Actor::ShowInfo str sAnimThreadFile = m_pAnimThread ? m_pAnimThread->FileName() : "(null)"; - + G_DebugString( a, 1.0, @@ -6705,7 +6778,7 @@ void Actor::ShowInfo 1.0, 1065353216, "%s:%s:%i - %s", - Director.GetString(m_csThinkNames[m_Think[m_ThinkLevel]]).c_str(), + ThinkName().c_str(), m_pszDebugState, m_State, sAnimThreadFile.c_str()); @@ -6768,10 +6841,8 @@ void Actor::DefaultPain ) { - //FIXME: macros - m_ThinkMap[2] = 5; - if (m_ThinkState == THINKSTATE_PAIN) - m_bDirtyThinkState = true; + SetThink(THINKSTATE_PAIN, THINK_PAIN); + HandlePain(ev); } @@ -6793,7 +6864,7 @@ void Actor::HandlePain } ExecuteScript(&e1); - SetThinkState(THINKSTATE_PAIN, 1); + SetThinkState(THINKSTATE_PAIN, THINKLEVEL_PAIN); RaiseAlertness(0.5); @@ -6810,7 +6881,7 @@ void Actor::HandlePain { SetEnemyPos(ent->origin); m_pszDebugState = "from_pain"; - SetThinkState(THINKSTATE_CURIOUS, 0); + SetThinkState(THINKSTATE_CURIOUS, THINKLEVEL_NORMAL); } } Unregister(STRING_PAIN); @@ -6838,15 +6909,11 @@ void Actor::DefaultKilled ) { - //FIXME: macros ClearStates(); - m_ThinkMap[3] = 6; + SetThink(THINKSTATE_KILLED, THINK_KILLED); - if (m_ThinkState == THINKSTATE_KILLED) - m_bDirtyThinkState = true; - - Actor::HandleKilled(ev, bPlayDeathAnim); + HandleKilled(ev, bPlayDeathAnim); } void Actor::HandleKilled @@ -6870,15 +6937,13 @@ void Actor::HandleKilled } else { - //FIXME: macros - m_ThinkMap[3] = 34; - if (m_ThinkState == THINKSTATE_KILLED) - m_bDirtyThinkState = true; + SetThink(THINKSTATE_KILLED, THINK_DEAD); } ClearThinkStates(); - - SetThinkState(THINKSTATE_KILLED, 2); + + //FIXME: macros + SetThinkState(THINKSTATE_KILLED, THINKLEVEL_KILLED); Unregister(STRING_DEATH); Unregister(STRING_PAIN); @@ -7289,9 +7354,7 @@ void Actor::NoPoint ) { - m_vLUpperArmDesiredAngles[0] = 0; - m_vLUpperArmDesiredAngles[1] = 0; - m_vLUpperArmDesiredAngles[2] = 0; + VectorClear(m_vLUpperArmDesiredAngles); } void Actor::IdlePoint @@ -7469,7 +7532,7 @@ void Actor::IdleTurn { if (m_pTurnEntity) { - for (int i = 0; i >= 1; i++) + for (int i = 0; i <= 1; i++) { if (m_pTurnEntity == this) { @@ -7482,8 +7545,7 @@ void Actor::IdleTurn facedir[1] = m_pTurnEntity->centroid[1] - origin[1]; if (facedir[0] != 0 || facedir[1] != 0) { - m_YawAchieved = false; - m_DesiredYaw = vectoyaw(facedir); + SetDesiredYawDir(facedir); } float error = m_DesiredYaw - angles[1]; @@ -7501,15 +7563,15 @@ void Actor::IdleTurn return; } - - if (Director.iPaused-- == 1) + Director.iPaused--; + if (Director.iPaused == 1) { Director.ExecuteRunning(); } Unregister(STRING_TURNDONE); Director.iPaused++; - //FIXME: what ?? it was m_pTurnEntity == m_pTurnEntity + if (m_pTurnEntity == NULL) { break; @@ -7577,24 +7639,42 @@ void Actor::LookAround ) { - vec3_t vDest, vAngle; + Vector vDest, vAngle; float fModTime; if (level.inttime >= m_iNextLookTime) { + fModTime = level.time; + vAngle = angles; + vAngle.y += fFovAdd * (2*(fModTime * 0.125 - floor(fModTime * 0.125)) - 1.0); + vAngle.x += (noise1(fModTime * 1.005309626678312 + entnum) + 1.0) * 15.0; + + AngleVectors(vAngle, vDest, NULL, NULL); + + vDest += EyePosition() * 1024; + trace_t trace = G_Trace(EyePosition(), vec_zero, vec_zero, vDest, this, 25, qfalse, "Actor::LookAround"); + if (trace.fraction > 0.125) + { + SetDesiredYawDest(trace.endpos); + m_iNextLookTime = level.inttime + rand() % 500 + 750; + } + else + { + m_bHasDesiredLookDest = false; + m_iNextLookTime = level.inttime + 187; + } } + if (m_bHasDesiredLookDest) { - + SetDesiredLookDir(m_vDesiredLookDest - EyePosition()); } else { m_bHasDesiredLookAngles = false; } - // FIXME: stub - STUB(); } bool Actor::SoundSayAnim @@ -7617,7 +7697,7 @@ bool Actor::SoundSayAnim Director.GetString(name).c_str(), edict->tiki->a->name); - Sound(Director.GetString(name), 0,0,0,0,0,0, 1,1); + Sound(Director.GetString(name), 0, 0, 0, NULL, 0, 0, 1, 1); return true; } @@ -7782,7 +7862,7 @@ void Actor::EventIdleSayAnim } } - else if (m_bLevelSayAnim == true) + else if (m_bLevelSayAnim == 1) { AnimFinished(m_iSaySlot, true); } @@ -7821,7 +7901,7 @@ void Actor::EventSayAnim } } - else if (m_bLevelSayAnim == true) + else if (m_bLevelSayAnim == 1) { AnimFinished(m_iSaySlot, true); } @@ -7954,14 +8034,14 @@ void Actor::EventSetActionAnim m_fAimLimit_down = ev->GetFloat(2); if (m_fAimLimit_down > 0) { - m_fAimLimit_down = -0.001; + m_fAimLimit_down = -0.001f; ScriptError("Positive lower_limit not allowed"); } m_fAimLimit_up = ev->GetFloat(3); if (m_fAimLimit_up <= 0) { - m_fAimLimit_up = 0.001; + m_fAimLimit_up = 0.001f; ScriptError("Negative upper_limit not allowed"); } @@ -7972,25 +8052,23 @@ void Actor::EventSetActionAnim ScriptException::next_bIsForAnim = 1; ScriptError("unknown animation '%s' in '%s'", Director.GetString(anim).c_str(), edict->tiki->a->name); } - //FIXME: repeated 3 times for no reason ? - /* - const_str anim2 = ev->GetConstString(2); - int animnum2 = gi.Anim_NumForName(edict->tiki, Director.GetString(anim2)); - if (animnum2 == -1) - { - ScriptException::next_bIsForAnim = 1; - ScriptError("unknown animation '%s' in '%s'", Director.GetString(anim2), edict->tiki->a->name); - } + const_str anim2 = ev->GetConstString(2); + int animnum2 = gi.Anim_NumForName(edict->tiki, Director.GetString(anim2)); + if (animnum2 == -1) + { + ScriptException::next_bIsForAnim = 1; + ScriptError("unknown animation '%s' in '%s'", Director.GetString(anim2), edict->tiki->a->name); + } - const_str anim3 = ev->GetConstString(3); - int animnum3 = gi.Anim_NumForName(edict->tiki, Director.GetString(anim3)); - if (animnum3 == -1) - { - ScriptException::next_bIsForAnim = 1; - ScriptError("unknown animation '%s' in '%s'", Director.GetString(anim3), edict->tiki->a->name); - } - */ + const_str anim3 = ev->GetConstString(3); + int animnum3 = gi.Anim_NumForName(edict->tiki, Director.GetString(anim3)); + if (animnum3 == -1) + { + ScriptException::next_bIsForAnim = 1; + ScriptError("unknown animation '%s' in '%s'", Director.GetString(anim3), edict->tiki->a->name); + } + parm.upperfail = qtrue; if (!m_bLevelActionAnim) { @@ -7998,10 +8076,10 @@ void Actor::EventSetActionAnim m_bAimAnimSet = true; m_bActionAnimSet = true; UpdateAim(); - //FIXME: 3 calls on same animnum ?? weird. + StartAimAnimSlot(0, animnum); - StartAimAnimSlot(1, animnum); - StartAimAnimSlot(2, animnum); + StartAimAnimSlot(1, anim2); + StartAimAnimSlot(2, anim3); m_iActionSlot = GetActionSlot(0); parm.upperfail = qfalse; } @@ -8349,7 +8427,7 @@ void Actor::MovePath if (ai_debugpath->integer) { - ; + Vector pos, dest; pos = origin; pos.z += 32; @@ -8361,10 +8439,8 @@ void Actor::MovePath { pos = current_path->point; pos.z += 32; - dest = m_Path.CurrentDelta(); - dest += origin; - //FIXME: not sure. - dest.x -= 32; + + dest = m_Path.NextNode()->point; dest.z += 32; G_DebugLine(pos, dest, 0, 1, 0, 1); } @@ -8785,7 +8861,7 @@ void Actor::UpdateAngles if (!m_YawAchieved) { - + error = m_DesiredYaw - angles[1]; if (error <= 180) { @@ -8849,6 +8925,7 @@ void Actor::AimAtAimNode SetDesiredLookDir( vDir ); m_DesiredGunDir[ 0 ] = 360.0f - vDir.toPitch(); m_DesiredGunDir[ 1 ] = vDir.toYaw(); + m_DesiredGunDir[ 2 ] = 0; m_YawAchieved = false; m_DesiredYaw = vDir.toYaw(); @@ -8901,7 +8978,7 @@ void Actor::FaceMotion delta.copyTo(dir); } } - if (m_ThinkState == 1) + if (m_ThinkState == THINKSTATE_IDLE) { IdleLook(dir); } @@ -8916,7 +8993,7 @@ void Actor::FaceMotion m_YawAchieved = false; m_DesiredYaw = vectoyaw(dir); } - else if (m_ThinkState == 1 && m_pLookEntity) + else if (m_ThinkState == THINKSTATE_IDLE && m_pLookEntity) { LookAtLookEntity(); } @@ -8932,28 +9009,71 @@ void Actor::FaceDirectionDuringMotion ) { - m_bHasDesiredLookAngles = true; - + float yaw; - vectoangles(vLook, m_DesiredLookAngles); + SetDesiredLookDir(vLook); - m_DesiredLookAngles[0] = AngleNormalize180(m_DesiredLookAngles[0]); - m_DesiredLookAngles[1] = AngleNormalize180(m_DesiredLookAngles[1] = angles[1]); if (velocity[0] != 0 || velocity[1] != 0) { - if (velocity[1] == 0) + float fMagsSquared = VectorLength2DSquared(vLook) * Square(velocity[1]) + Square(velocity[0]); + float fDot = DotProduct2D(velocity, vLook); + float fDotSquared = Square(fDot); + + if (velocity[1] == 0 && velocity[0] == 0) { - if (velocity[0] == 0) + yaw = 0; + } + else + { + yaw = atan2(velocity[1], velocity[0]) * 180 / M_PI; + } + + if (yaw < 0) + { + yaw += 360; + } + + float fYaw2; + if (fMagsSquared * 0.5 < fDotSquared) + { + if (fDot >= 0) { + fYaw2 = yaw; + } + else if (yaw - 180 >= 0) + { + fYaw2 = yaw - 180; + } + else + { + fYaw2 = yaw - 180 + 360; } } + else + { + if (vLook[0] * velocity[1] <= vLook[1] * velocity[0]) + { + fYaw2 = yaw - 270; + } + else + { + fYaw2 = yaw - 90; + } + + if (fYaw2 < 0) + { + fYaw2 += 360; + } + } + + SetDesiredYaw(fYaw2); + } + else + { + SetDesiredYawDir(vLook); } - m_YawAchieved = false; - m_DesiredYaw = vectoyaw(vLook); - // FIXME: stub - STUB(); } float Actor::PathDistanceAlongVector @@ -9046,11 +9166,391 @@ void Actor::UpdateBoneControllers ) { - Vector torsoAngles, headAngles, LocalLookAngles; - float min_accel_change, max_accel_change, max_change, error, yawError, pitchError, torsoYawError, tolerable_error; + Vector torsoAngles, headAngles, LocalLookAngles, vec1, vLookDest, vec2, vLookDir, lineVec, eyePosition; + float /*min_accel_change, max_accel_change, max_change, yawError, tolerable_error,*/ error, pitchError, torsoYawError, fAlpha; - // FIXME: stub - STUB(); + if (m_bHasDesiredLookAngles) + { + if (g_showlookat->integer == entnum || g_showlookat->integer == -1) + { + float myAxis[3][3], lookAxis[3][3]; + orientation_t tag_or; + GetRawTag("eyes bone", &tag_or); + + AnglesToAxis(angles, myAxis); + + vec1 = origin; + + for (int i = 0; i < 3; i++) + { + //sizeof(orientation_t); + VectorMA(vec1, tag_or.origin[i], myAxis[i], vec1); + + } + + + if (m_bHasDesiredLookDest) + { + vLookDest = m_vDesiredLookDest; + } + else if (m_pLookEntity) + { + if (m_pLookEntity->IsSubclassOfSentient()) + { + vLookDest = ((Sentient *)m_pLookEntity.Pointer())->EyePosition(); + } + else + { + vLookDest = m_pLookEntity->centroid; + } + } + else + { + vLookDest = vec_zero; + } + + + AnglesToAxis(angles + m_DesiredLookAngles, lookAxis); + + vec2 = vLookDest - vec1; + + VectorNormalize(vec2); + + float fDist = (vec2 - lookAxis[0]).length(); + if (fDist >= 0.1) + { + lineVec = Vector(128, 0, 0); + for (int i = 0; i < 3; i++) + { + VectorMA(vec1, lineVec[i], lookAxis[i], vLookDir); + } + + } + else + { + vLookDir = vLookDest; + + if (fDist >= 0.04) + { + fAlpha = ((0.1 - fDist) / 0.06); + } + else + { + fAlpha = 1; + } + + G_DebugLine(vLookDest + Vector( 8, 8, 8), vLookDest + Vector( 8, 8, -8), 0, 0, fAlpha, fAlpha); + G_DebugLine(vLookDest + Vector( 8, -8, 8), vLookDest + Vector( 8, -8, -8), 0, 0, fAlpha, fAlpha); + G_DebugLine(vLookDest + Vector(-8, 8, 8), vLookDest + Vector(-8, 8, -8), 0, 0, fAlpha, fAlpha); + G_DebugLine(vLookDest + Vector( 8, 8, 8), vLookDest + Vector( 8, -8, 8), 0, 0, fAlpha, fAlpha); + G_DebugLine(vLookDest + Vector(-8, 8, -8), vLookDest + Vector(-8, -8, -8), 0, 0, fAlpha, fAlpha); + G_DebugLine(vLookDest + Vector( 8, 8, 8), vLookDest + Vector(-8, 8, 8), 0, 0, fAlpha, fAlpha); + G_DebugLine(vLookDest + Vector( 8, 8, -8), vLookDest + Vector(-8, 8, -8), 0, 0, fAlpha, fAlpha); + G_DebugLine(vLookDest + Vector( 8, -8, 8), vLookDest + Vector(-8, -8, 8), 0, 0, fAlpha, fAlpha); + G_DebugLine(vLookDest + Vector( 8, -8, -8), vLookDest + Vector(-8, -8, -8), 0, 0, fAlpha, fAlpha); + } + + G_DebugLine(vec1, vLookDir, 0, 0, 1, 1); + + + for (int i = 0; i < 3; i++) + { + //sizeof(orientation_t); + VectorMA(vLookDir, Vector(0, 0, -2)[i], lookAxis[i], vLookDir); + VectorMA(vec1, Vector(0, 0, -2)[i], lookAxis[i], vec1); + + } + + G_DebugLine(vec1, vLookDir, 0, 0, 1, 1); + + + for (int i = 0; i < 3; i++) + { + //sizeof(orientation_t); + VectorMA(vLookDir, Vector(0, 2, 0)[i], lookAxis[i], vLookDir); + VectorMA(vec1, Vector(0, 2, 0)[i], lookAxis[i], vec1); + + } + + G_DebugLine(vec1, vLookDir, 0, 0, 1, 1); + + } + + + LocalLookAngles = m_DesiredLookAngles; + + eyePosition = vec_zero; + VectorClear(edict->s.eyeVector); + LocalLookAngles.AngleVectorsLeft(&eyePosition, NULL, NULL); + VectorCopy(eyePosition, edict->s.eyeVector); + + } + else + { + VectorClear(edict->s.eyeVector); + + LocalLookAngles = vec_zero; + } + + headAngles = GetControllerAngles(HEAD_TAG); + torsoAngles = GetControllerAngles(TORSO_TAG); + + + torsoYawError = LocalLookAngles[1] - torsoAngles[1]; + error = torsoYawError - headAngles[1]; + + pitchError = LocalLookAngles[0] - headAngles[0]; + + if (torsoYawError <= 180) + { + if (torsoYawError < -180.0) + torsoYawError += 360; + } + else + { + torsoYawError -= 360; + } + + if (torsoYawError >= 0.0) + { + if (error < -120.0) + error += 360.0; + } + else if (error > 120.0) + { + error -= 360.0; + } + + float fErr1, fErr2, fAng1, fAng2, fAng3, fFrameTorsoDist, fAng4, fAng5, fAng6, fAng7; + float fAng8, fAng9, fAng10; + if (m_iLookFlags) + { + fAng6 = error; + } + else + { + if (error <= 25.0) + { + if (error >= -25.0) + { + fErr1 = 0.0; + //goto LABEL_15; + } + else + { + fErr1 = (error + 25.0) * 0.2; + } + } + else + { + fErr1 = (error - 25.0) * 0.2; + } + + fErr2 = error + headAngles[1]; + + fAng1 = -torsoAngles[1]; + + if (fErr2 > fAng1) + { + fErr2 = -torsoAngles[1]; + fAng1 = error + headAngles[1]; + } + + if (fErr2 <= error) + { + fAng2 = fAng1; + if (error <= fAng1) + fAng2 = error; + } + else + { + fAng2 = fErr2; + } + + + fAng3 = m_fTorsoCurrentTurnSpeed + level.frametime * 15.0; + + if (fAng2 <= fAng3) + { + fAng3 = fAng2; + if (fAng2 < m_fTorsoCurrentTurnSpeed - level.frametime * 15.0) + fAng3 = m_fTorsoCurrentTurnSpeed + level.frametime * 15.0; + } + + fFrameTorsoDist = level.frametime * m_fTorsoMaxTurnSpeed; + + if(-fFrameTorsoDist <= fAng3) + { + fAng4 = fFrameTorsoDist; + if (fAng3 <= fFrameTorsoDist) + fAng4 = fAng3; + } + else + { + fAng4 = -fFrameTorsoDist; + } + + torsoAngles[1] += fAng4; + if (torsoAngles[1] <= 30.0) + { + if (torsoAngles[1] >= -30.0) + { + fAng5 = fAng4; + } + else + { + torsoAngles[1] = -30.0; + fAng5 = fAng4 - (torsoAngles[1] + 30.0); + } + } + else + { + torsoAngles[1] = 30.0; + fAng5 = fAng4 - (torsoAngles[1] - 30.0); + } + + m_fTorsoCurrentTurnSpeed = fAng5; + + torsoAngles[0] = 0.0; + torsoAngles[2] = 0.0; + SetControllerAngles(TORSO_TAG, torsoAngles); + + fAng6 = error - fAng5; + } + + if (fAng6 > 15.0) + { + fAng7 = (fAng6 - 15.0) * 4.0 * level.frametime; + } + else if (-15.0 > fAng6) + { + fAng7 = (fAng6 + 15.0) * 4.0 * level.frametime; + } + else + { + fAng7 = 0.0; + } + + fAng8 = fAng6; + fAng9 = -headAngles[1]; + + if (fAng8 > fAng9) + { + fAng8 = -headAngles[1]; + fAng9 = fAng6; + } + + if (fAng8 > fAng7) + { + fAng7 = fAng8; + } + else if (fAng7 > fAng9) + { + fAng7 = fAng9; + } + + if (-(level.frametime * m_fHeadMaxTurnSpeed) <= fAng7) + { + fAng10 = (level.frametime * m_fHeadMaxTurnSpeed); + if (fAng7 <= fAng10) + fAng10 = fAng7; + } + else + { + fAng10 = -(level.frametime * m_fHeadMaxTurnSpeed); + } + + headAngles[1] += fAng10; + if (headAngles[1] > 60) + { + headAngles[1] = 60; + } + else if (headAngles[1] < -60) + { + headAngles[1] = -60; + } + + float fAng11, fAng12, fAng13; + + fAng11 = fabs(LocalLookAngles[0]); + + if (fAng11 > 15) + { + fAng11 = 15; + } + + if (pitchError > fAng11) + { + fAng12 = 0.2 * (pitchError - fAng11); + } + else if (-fAng11 > pitchError) + { + fAng12 = 0.2 * (pitchError + fAng11); + } + else + { + fAng12 = 0; + } + + + if (-(level.frametime * m_fHeadMaxTurnSpeed) <= fAng12) + { + fAng13 = (level.frametime * m_fHeadMaxTurnSpeed); + if (fAng12 <= fAng13) + fAng13 = fAng12; + } + else + { + fAng13 = -(level.frametime * m_fHeadMaxTurnSpeed); + } + + headAngles[0] += fAng13; + + if (headAngles[0] > 35.0) + headAngles[0] = 35.0; + else if (headAngles[0] < -35.0) + headAngles[0] = -35.0; + + headAngles[2] = 0.0; + + if (m_iLookFlags) + { + headAngles[0] *= 0.5; + headAngles[1] *= 0.5; + } + + SetControllerAngles(HEAD_TAG, headAngles); + + + Vector armAngles = GetControllerAngles(ARMS_TAG); + + float fAng14 = m_vLUpperArmDesiredAngles[1] - armAngles[1]; + + if (fAng14 <= 180.0) + { + if (fAng14 < -180.0) + fAng14 += 360.0; + } + else + { + fAng14 -= 360.0; + } + + float fAng15; + + if (-(level.frametime * m_fLUpperArmTurnSpeed) <= fAng14) + { + fAng15 = (level.frametime * m_fLUpperArmTurnSpeed); + if (fAng14 <= fAng15) + fAng15 = fAng14; + } + else + { + fAng15 = -(level.frametime * m_fLUpperArmTurnSpeed); + } + + + SetControllerAngles(ARMS_TAG, Vector(m_vLUpperArmDesiredAngles[0], fAng15 + armAngles[1], 0)); } void Actor::ReadyToFire @@ -9065,7 +9565,7 @@ void Actor::ReadyToFire if (weap) ready = weap->ReadyToFire(FIRE_PRIMARY, true); else - ready = 0; + ready = false; ev->AddInteger(ready); } @@ -9075,12 +9575,12 @@ void Actor::GetLocalYawFromVector ) { - long double yaw; + float yaw; Vector vec; vec = ev->GetVector(1); - yaw = vectoyaw(vec) + 180.0; - AngleSubtract(yaw, angles[1]); + yaw = vectoyaw(vec) + 180.0f; + yaw = AngleSubtract(yaw, angles[1]); ev->AddFloat(yaw); } @@ -9142,7 +9642,7 @@ void Actor::NextPatrolCurrentNode ) { - if (this->m_bScriptGoalValid) + if (m_bScriptGoalValid) { m_bScriptGoalValid = m_patrolCurrentNode->origin != m_vScriptGoal; } @@ -9461,9 +9961,9 @@ bool Actor::MoveToPatrolCurrentNode else m_bHasDesiredLookAngles = false; } - m_Dest[0] = m_patrolCurrentNode->origin[0]; - m_Dest[1] = m_patrolCurrentNode->origin[1]; - m_Dest[2] = m_patrolCurrentNode->origin[2]; + + SetDest(m_patrolCurrentNode->origin); + if (m_fMoveDoneRadiusSquared == 0.0 || m_patrolCurrentNode->Next()) return false; Vector delta = m_patrolCurrentNode->origin - origin; @@ -9475,14 +9975,12 @@ bool Actor::MoveToPatrolCurrentNode m_patrolCurrentNode->origin, "Actor::MoveToPatrolCurrentNode", 0, - 0, + NULL, 0); if (!PathExists()) { - if (m_pLookEntity) - LookAtLookEntity(); - else - m_bHasDesiredLookAngles = false; + IdleLook(); + Anim_Idle(); parm.movefail = qtrue; return false; @@ -9492,12 +9990,12 @@ bool Actor::MoveToPatrolCurrentNode const_str csAnimString; if (PatrolNextNodeExists()) { - csAnimString = this->m_csPatrolCurrentAnim; + csAnimString = m_csPatrolCurrentAnim; m_eNextAnimMode = 2; } else { - csAnimString = this->m_csPatrolCurrentAnim; + csAnimString = m_csPatrolCurrentAnim; m_eNextAnimMode = 3; } m_csNextAnimString = csAnimString; @@ -9507,10 +10005,7 @@ bool Actor::MoveToPatrolCurrentNode else { Anim_Stand(); - if (m_pLookEntity) - LookAtLookEntity(); - else - m_bHasDesiredLookAngles = false; + IdleLook(); } if (m_fMoveDoneRadiusSquared == 0) @@ -9531,10 +10026,7 @@ bool Actor::MoveToPatrolCurrentNode } - if (m_pLookEntity) - LookAtLookEntity(); - else - m_bHasDesiredLookAngles = false; + IdleLook(); Anim_Idle(); return false; } @@ -9636,7 +10128,7 @@ int Actor::GetThinkType int result = 0; while (m_csThinkNames[result] != csName) { - if (++result > 34) + if (++result > MAX_GLOBAL_FUNCS - 1) { ScriptError("unknown think type '%s'", Director.GetString(csName).c_str()); } @@ -9662,44 +10154,37 @@ void Actor::SetThinkIdle ) { - //FIXME: macros int think_curious; switch (think_idle) { - case 3: - case 4: + case THINK_PATROL: + case THINK_RUNNER: m_bBecomeRunner = true; - think_curious = 9; + think_curious = THINK_CURIOUS; break; - case 17: - think_curious = 17; + case THINK_MACHINEGUNNER: + think_curious = THINK_MACHINEGUNNER; break; - case 18: - think_curious = 20; - m_ThinkMap[7] = 20; - if (m_ThinkState == 7) - m_bDirtyThinkState = true; + case THINK_DOG_IDLE: + think_curious = THINK_DOG_CURIOUS; + SetThink(THINKSTATE_GRENADE, think_curious); break; - case 22: - think_curious = 23; + case THINK_ANIM: + think_curious = THINK_ANIM_CURIOUS; break; - case 25: - think_curious = 26; + case THINK_BALCONY_IDLE: + think_curious = THINK_BALCONY_CURIOUS; break; default: - think_curious = 9; + think_curious = THINK_CURIOUS; break; } - m_ThinkMap[1] = think_idle; - if (m_ThinkState == 1) - m_bDirtyThinkState = true; + SetThink(THINKSTATE_IDLE, think_idle); - m_ThinkMap[5] = think_curious; - if (m_ThinkState == 5) - m_bDirtyThinkState = true; + SetThink(THINKSTATE_CURIOUS, think_curious); } void Actor::SetThinkState @@ -9709,11 +10194,10 @@ void Actor::SetThinkState ) { - //FIXME: macros if (state == THINKSTATE_ATTACK) { m_csIdleMood = STRING_NERVOUS; - if (m_ThinkMap[4] != 15 && m_ThinkMap[4] != 32 && m_ThinkMap[4] != 19 && !GetWeapon(WEAPON_MAIN)) + if (m_ThinkMap[THINKSTATE_ATTACK] != THINK_ALARM && m_ThinkMap[THINKSTATE_ATTACK] != THINK_WEAPONLESS && m_ThinkMap[THINKSTATE_ATTACK] != THINK_DOG_ATTACK && !GetWeapon(WEAPON_MAIN)) { Com_Printf( "^~^~^ LD ERROR: (entnum %i, radnum %i, targetname '%s'): forcing weaponless attack state.\n" @@ -9721,15 +10205,13 @@ void Actor::SetThinkState entnum, radnum, targetname.c_str()); - m_ThinkMap[4] = 32; - if (m_ThinkState == THINKSTATE_ATTACK) - m_bDirtyThinkState = true; + SetThink(THINKSTATE_ATTACK, THINK_WEAPONLESS); } } m_ThinkStates[level] = state; - if (m_ThinkLevel > level) + if (level >= m_ThinkLevel) { m_bDirtyThinkState = true; } @@ -9742,7 +10224,7 @@ void Actor::EndCurrentThinkState ) { - SetThinkState(THINKSTATE_NONE, m_ThinkState); + SetThinkState(THINKSTATE_VOID, m_ThinkLevel); } void Actor::ClearThinkStates @@ -9753,7 +10235,7 @@ void Actor::ClearThinkStates { for (int i = 0; i <= MAX_THINKSTATES-1; i++) { - SetThinkState(THINKSTATE_NONE, i); + SetThinkState(THINKSTATE_VOID, i); } } @@ -9826,7 +10308,7 @@ void Actor::EventSetTypeIdle int think = GetThinkType(ev->GetConstString(1)); if (!Actor::GlobalFuncs[think].IsState(THINKSTATE_IDLE)) { - SetThinkIdle(8); + SetThinkIdle(THINK_IDLE); ScriptError("Invalid idle think '%s'", Director.GetString(m_csThinkNames[think]).c_str()); } @@ -9839,8 +10321,8 @@ void Actor::EventGetTypeIdle ) { - //FIXME: helpful to understand thinkmaps - ev->AddConstString(m_csThinkNames[m_ThinkMap[1]]); + + ev->AddConstString(m_csThinkNames[m_ThinkMap[THINKSTATE_IDLE]]); } void Actor::EventSetTypeAttack @@ -9852,18 +10334,12 @@ void Actor::EventSetTypeAttack int think = GetThinkType(ev->GetConstString(1)); if (!Actor::GlobalFuncs[think].IsState(THINKSTATE_ATTACK)) { - m_ThinkMap[THINKSTATE_ATTACK] = 1; - if (m_ThinkState == THINKSTATE_ATTACK) - { - m_bDirtyThinkState = true; - } + SetThink(THINKSTATE_ATTACK, THINK_TURRET); + ScriptError("Invalid attack think '%s'", Director.GetString(m_csThinkNames[think]).c_str()); } - m_ThinkMap[THINKSTATE_ATTACK] = think; - if (m_ThinkState == THINKSTATE_ATTACK) - { - m_bDirtyThinkState = true; - } + + SetThink(THINKSTATE_ATTACK, think); } void Actor::EventGetTypeAttack @@ -9872,8 +10348,8 @@ void Actor::EventGetTypeAttack ) { - //FIXME: helpful to understand thinkmaps - ev->AddConstString(m_csThinkNames[m_ThinkMap[4]]); + + ev->AddConstString(m_csThinkNames[m_ThinkMap[THINKSTATE_ATTACK]]); } void Actor::EventSetTypeDisguise @@ -9885,18 +10361,12 @@ void Actor::EventSetTypeDisguise int think = GetThinkType(ev->GetConstString(1)); if (!Actor::GlobalFuncs[think].IsState(THINKSTATE_DISGUISE)) { - m_ThinkMap[THINKSTATE_DISGUISE] = 10; - if (m_ThinkState == THINKSTATE_DISGUISE) - { - m_bDirtyThinkState = true; - } + SetThink(THINKSTATE_DISGUISE, THINK_DISGUISE_SALUTE); + ScriptError("Invalid disguise think '%s'", Director.GetString(m_csThinkNames[think]).c_str()); } - m_ThinkMap[THINKSTATE_DISGUISE] = think; - if (m_ThinkState == THINKSTATE_DISGUISE) - { - m_bDirtyThinkState = true; - } + + SetThink(THINKSTATE_DISGUISE, think); } void Actor::EventGetTypeDisguise @@ -9905,7 +10375,7 @@ void Actor::EventGetTypeDisguise ) { - ev->AddConstString(m_csThinkNames[m_ThinkMap[6]]); + ev->AddConstString(m_csThinkNames[m_ThinkMap[THINKSTATE_DISGUISE]]); } void Actor::EventSetDisguiseLevel @@ -9937,26 +10407,16 @@ void Actor::EventSetTypeGrenade ) { - //FIXME: not sure of m_ThinkMap[THINKSTATE_GRENADE] + int think = GetThinkType(ev->GetConstString(1)); if (!(&GlobalFuncs[think])->IsState(THINKSTATE_GRENADE)) { - //FIXME: macro - m_ThinkMap[THINKSTATE_GRENADE] = 16; - if (m_ThinkState == THINKSTATE_GRENADE) - { - m_bDirtyThinkState = true; - } - ; + SetThink(THINKSTATE_GRENADE, THINK_GRENADE); + ScriptError("Invalid grenade think '%s'", Director.GetString(m_csThinkNames[m_ThinkMap[THINKSTATE_GRENADE]]).c_str()); } - m_ThinkMap[THINKSTATE_GRENADE] = think; - - if (m_ThinkState == THINKSTATE_GRENADE) - { - m_bDirtyThinkState = true; - } + SetThink(THINKSTATE_GRENADE, think); } void Actor::EventGetTypeGrenade @@ -10299,7 +10759,7 @@ str Actor::ThinkName ) const { - return Director.GetString( m_Think[ m_ThinkLevel ] ); + return Director.GetString( m_csThinkNames[ m_Think[ m_ThinkLevel ] ] ); } str Actor::ThinkStateName @@ -10308,7 +10768,7 @@ str Actor::ThinkStateName ) const { - return Director.GetString( m_ThinkState ); + return Director.GetString( m_csThinkStateNames[ m_ThinkState ] ); } void Actor::EventSetTurret @@ -10339,7 +10799,7 @@ void Actor::EventEnableEnemy ) { - m_bDesiredEnableEnemy = ev->GetInteger(1) != true; + m_bDesiredEnableEnemy = ev->GetBoolean(1); } void Actor::EventEnablePain @@ -10348,7 +10808,7 @@ void Actor::EventEnablePain ) { - m_bEnablePain = ev->GetInteger(1) != true; + m_bEnablePain = ev->GetBoolean(1); } void Actor::EventActivate @@ -10404,8 +10864,8 @@ void Actor::EventAnimScript //FIXME: macro m_AnimMode = 1; - //FIXME: macro: THINKSTATE_* - SetThinkIdle(22); + + SetThinkIdle(THINK_ANIM); } void Actor::EventAnimScript_Scripted @@ -10420,8 +10880,8 @@ void Actor::EventAnimScript_Scripted //FIXME: macro m_AnimMode = 5; - //FIXME: macro: THINKSTATE_* - SetThinkIdle(22); + + SetThinkIdle(THINK_ANIM); } void Actor::EventAnimScript_Noclip @@ -10435,8 +10895,8 @@ void Actor::EventAnimScript_Noclip //FIXME: macro m_AnimMode = 6; - //FIXME: macro: THINKSTATE_* - SetThinkIdle(22); + + SetThinkIdle(THINK_ANIM); } void Actor::EventReload_mg42 @@ -10887,7 +11347,7 @@ qboolean Actor::setModel ) { - qboolean bSuccess; + //qboolean bSuccess; str name, tempstr; if (model != NULL) @@ -11005,7 +11465,7 @@ void Actor::EventGetMaxNoticeTimeScale ) { - //FIXME: *100 ? + ev->AddFloat(m_fMaxNoticeTimeScale * 100); } @@ -11209,7 +11669,7 @@ void Actor::EventCanMoveTo { for (auto pSquadMate = m_pNextSquadMate; pSquadMate != this ; pSquadMate = pSquadMate->m_pNextSquadMate) { - float v27, v29, v30, v32, v33, v34, v35, v37, v38, v45, v44; + float v27, v29, v30, v32, v33, v34, v35, v37, v38; if (pSquadMate->IsSubclassOfActor()) { Sentient *pEnemy = pSquadMate->m_Enemy; @@ -11235,8 +11695,8 @@ void Actor::EventCanMoveTo v33 = v32 * origin[0]; v34 = v27 * v32 - v30 * v29; v35 = v33 - v29 * origin[1] - v34; - v37 = v32 * v44; - v38 = v37 - v29 * v45 - v34; + v37 = v32 * vDest[0]; + v38 = v37 - v29 * vDest[1] - v34; // check if they both have different sign. if (((int)v38 ^ (int)v35) < 0) @@ -11297,8 +11757,6 @@ void Actor::EventIntervalDir ) { - Vector dir; - dir = m_vIntervalDir; //FIXME: macro if (level.inttime >= m_iIntervalDirTime + 250) { @@ -11313,7 +11771,7 @@ void Actor::EventIntervalDir } } } - //FIXME: not sure if i should add dir or m_vIntervalDir + ev->AddVector(m_vIntervalDir); } @@ -11852,9 +12310,9 @@ void Actor::DontFaceWall ) { - PathNode *pNode; + //PathNode *pNode; vec2_t vDelta; - float fErrorLerp, fEyeRadius, fCosAngle, fSinAngle, fAngle, fAngleRad, fTime; + float /*fErrorLerp,*/ fEyeRadius, fCosAngle, fSinAngle, fAngle, fAngleRad, fTime; Vector start; Vector end; @@ -12013,13 +12471,9 @@ void Actor::ClearStates ) { - for (int i = 0; i <= MAX_THINKMAP; i++) + for (int i = 0; i < MAX_THINKMAP; i++) { - m_ThinkMap[i] = 0; - if (m_ThinkState == i) - { - m_bDirtyThinkState = true; - } + SetThink(i, THINK_VOID); } } @@ -12062,7 +12516,7 @@ void Actor::BecomeCorpse edict->s.renderfx &= ~RF_SHADOW; - PostEvent(e1, 20, 0); + PostEvent(e1, 20); } void Actor::PathnodeClaimRevoked @@ -12207,7 +12661,7 @@ bool Actor::CalcFallPath { float startTime, animTime, startDeltaTime, nextTime; vec3_t vAbsDelta, vRelDelta, pos[200]; - int anim, loop, currentPos, i; + int anim, loop, /*currentPos,*/ i; mmove_t mm; SetMoveInfo(&mm); @@ -12220,7 +12674,7 @@ bool Actor::CalcFallPath anim = gi.Anim_NumForName(edict->tiki, "death_balcony_intro"); animTime = gi.Anim_Time(edict->tiki, anim); - startTime = 0.64999998; + startTime = 0.65F; i = 0; while (true) @@ -12237,13 +12691,13 @@ bool Actor::CalcFallPath if (mm.hit_obstacle) { - for (int i = 0.64999998; i < startTime; i = nextTime) + for (int j = 0.64999998; j < animTime; j = nextTime) { - nextTime = i + level.frametime; - if (nextTime >= startTime - 0.0099999998) - nextTime = startTime; - startDeltaTime = i; - (gi.Anim_DeltaOverTime)( + nextTime = j + level.frametime; + if (nextTime >= animTime - 0.0099999998) + nextTime = animTime; + startDeltaTime = j; + gi.Anim_DeltaOverTime( edict->tiki, anim, startDeltaTime, @@ -12288,7 +12742,7 @@ bool Actor::CalcFallPath if (m_fBalconyHeight > origin[2] - pos[i][2]) return false; - m_pFallPath = (FallPath *)gi.Malloc(sizeof(FallPath) * i); + m_pFallPath = (FallPath *)gi.Malloc((sizeof(FallPath::pos)) * i + (sizeof(FallPath) - sizeof(FallPath::pos))); m_pFallPath->length = i; @@ -12319,6 +12773,7 @@ bool Actor::CalcFallPath } return false; } + return false; } @@ -12449,8 +12904,8 @@ void Actor::DumpAnimInfo Animate::DumpAnimInfo(); Vector desiredLook = m_bHasDesiredLookAngles ? m_DesiredLookAngles : vec_zero; //FIXME: macros: bones - Vector head = GetControllerAngles(0); - Vector torso = GetControllerAngles(1); + Vector head = GetControllerAngles(HEAD_TAG); + Vector torso = GetControllerAngles(TORSO_TAG); MPrintf("Desired look yaw: %.1f, pitch: %.1f. Head yaw: %.1f, pitch %.1f. Torso yaw: %.1f, pitch: %.1f\n", desiredLook.x, desiredLook.y, diff --git a/code/game/actor.h b/code/game/actor.h index a197cdf9..4af72962 100644 --- a/code/game/actor.h +++ b/code/game/actor.h @@ -62,9 +62,9 @@ extern Event EV_Actor_DeathEmbalm; // Bones used by actor -#define ACTOR_MOUTH_TAG 0 -#define ACTOR_HEAD_TAG 1 -#define ACTOR_TORSO_TAG 2 +//#define ACTOR_MOUTH_TAG 0 +#define ACTOR_HEAD_TAG 0 +#define ACTOR_TORSO_TAG 1 // Dialog stuff @@ -90,25 +90,25 @@ typedef struct } DialogParm_t; typedef struct DialogNode_s - { - char alias_name[ MAX_ALIAS_NAME_LENGTH ]; +{ + char alias_name[MAX_ALIAS_NAME_LENGTH]; int random_flag; int number_of_parms; float random_percent; - DialogParm_t parms[ MAX_DIALOG_PARMS ]; - struct DialogNode_s *next; - } DialogNode_t; + DialogParm_t parms[MAX_DIALOG_PARMS]; + struct DialogNode_s *next; +} DialogNode_t; typedef enum - { - IS_INANIMATE, +{ + IS_INANIMATE, IS_MONSTER, IS_ENEMY, IS_CIVILIAN, IS_FRIEND, - IS_ANIMAL, + IS_ANIMAL, NUM_ACTORTYPES - } actortype_t; +} actortype_t; // Stimuli types @@ -236,6 +236,20 @@ typedef enum AI_GREN_KICK } eGrenadeTossMode; +typedef enum +{ + AI_GRENSTATE_FLEE, + AI_GRENSTATE_THROW_ACQUIRE, + AI_GRENSTATE_THROW, + AI_GRENSTATE_KICK_ACQUIRE, + AI_GRENSTATE_KICK, + AI_GRENSTATE_MARTYR_ACQUIRE, + AI_GRENSTATE_MARTYR, + AI_GRENSTATE_UNK, + AI_GRENSTATE_FLEE_SUCCESS, //fled the grenade succesfully, i'm safe + AI_GRENSTATE_FLEE_FAIL, //failed to flee, I'm gonna get hurt or die :'( +} eGrenadeState; + typedef struct { byte length; byte currentPos; @@ -244,7 +258,7 @@ typedef struct { vec3_t pos[ 1 ]; } FallPath; -#define THINKSTATE_NONE 0 +#define THINKSTATE_VOID 0 #define THINKSTATE_IDLE 1 #define THINKSTATE_PAIN 2 #define THINKSTATE_KILLED 3 @@ -267,6 +281,53 @@ typedef struct { #define AI_EVENT_FOOTSTEP 10 #define AI_EVENT_GRENADE 11 +enum thinkNums +{ + THINK_VOID, + THINK_TURRET, + THINK_COVER, + THINK_PATROL, + THINK_RUNNER, + THINK_PAIN, + THINK_KILLED, + THINK_MOVETO, + THINK_IDLE, + THINK_CURIOUS, + THINK_DISGUISE_SALUTE, + THINK_DISGUISE_SENTRY, + THINK_DISGUISE_OFFICER, + THINK_DISGUISE_ROVER, + THINK_DISGUISE_NONE, + THINK_ALARM, + THINK_GRENADE, + THINK_MACHINEGUNNER, + THINK_DOG_IDLE, + THINK_DOG_ATTACK, + THINK_DOG_CURIOUS, + THINK_DOG_GRENADE, + THINK_ANIM, + THINK_ANIM_CURIOUS, + THINK_AIM, + THINK_BALCONY_IDLE, + THINK_BALCONY_CURIOUS, + THINK_BALCONY_ATTACK, + THINK_BALCONY_DISGUISE, + THINK_BALCONY_GRENADE, + THINK_BALCONY_PAIN, + THINK_BALCONY_KILLED, + THINK_WEAPONLESS, + THINK_NOCLIP, + THINK_DEAD +}; + +enum thinkLevelNums +{ + THINKLEVEL_NORMAL, + THINKLEVEL_PAIN, + THINKLEVEL_KILLED, + THINKLEVEL_NOCLIP +}; + class Actor; typedef SafePtr ActorPtr; @@ -392,7 +453,7 @@ public: SafePtr m_pGrenade; Vector m_vGrenadePos; int m_iFirstGrenadeTime; - int m_eGrenadeState; + eGrenadeState m_eGrenadeState; eGrenadeTossMode m_eGrenadeMode; Vector m_vGrenadeVel; Vector m_vKickDir; @@ -467,7 +528,7 @@ protected: public: Actor(); - virtual void setContentsSolid( void ); + virtual void setContentsSolid( void ) override; void InitThinkStates( void ); void UpdateEyeOrigin( void ); bool RequireThink( void ); @@ -479,7 +540,7 @@ public: void AddToBodyQue( void ); Vector GetAntiBunchPoint( void ); static void InitVoid( GlobalFuncs_t *func ); - virtual const char *DumpCallTrace( const char *pszFmt, ... ) const; + virtual const char *DumpCallTrace( const char *pszFmt, ... ) const override; static void Init( void ); void FixAIParameters( void ); bool AttackEntryAnimation( void ); @@ -595,7 +656,7 @@ public: void Grenade_EventFire( Event *ev ); void GenericGrenadeTossThink( void ); static void InitGrenade( GlobalFuncs_t *func ); - bool Grenade_Acquire( int eNextState, const_str csReturnAnim ); + bool Grenade_Acquire( eGrenadeState eNextState, const_str csReturnAnim ); void Grenade_Flee( void ); void Grenade_ThrowAcquire( void ); void Grenade_Throw( void ); @@ -1202,7 +1263,7 @@ inline void Actor::Archive arc.ArchiveSafePointer( &m_pGrenade); arc.ArchiveVector( &m_vGrenadePos); arc.ArchiveInteger( &m_iFirstGrenadeTime); - arc.ArchiveInteger( &m_eGrenadeState); + ArchiveEnum( m_eGrenadeState, eGrenadeState ); ArchiveEnum( m_eGrenadeMode, eGrenadeTossMode ); arc.ArchiveVector( &m_vGrenadeVel); arc.ArchiveVector( &m_vKickDir); diff --git a/code/game/actor_alarm.cpp b/code/game/actor_alarm.cpp index e7fc7933..1a64e38e 100644 --- a/code/game/actor_alarm.cpp +++ b/code/game/actor_alarm.cpp @@ -135,7 +135,7 @@ void Actor::State_Alarm_Idle { AimAtAimNode(); - SetThink( 4, THINKSTATE_IDLE ); + SetThink(THINKSTATE_ATTACK, THINK_TURRET); } void Actor::Think_Alarm diff --git a/code/game/actor_anim.cpp b/code/game/actor_anim.cpp index e45edcaf..07479cd9 100644 --- a/code/game/actor_anim.cpp +++ b/code/game/actor_anim.cpp @@ -96,7 +96,7 @@ void Actor::FinishedAnimation_Anim if (m_bNoIdleAfterAnim) m_csAnimScript = STRING_ANIM_CONTINUE_LAST_ANIM_SCR; else - SetThinkIdle(8); + SetThinkIdle(THINK_IDLE); Unregister(STRING_ANIMDONE); } } diff --git a/code/game/actor_animapi.cpp b/code/game/actor_animapi.cpp index 47db205b..9ec0bec7 100644 --- a/code/game/actor_animapi.cpp +++ b/code/game/actor_animapi.cpp @@ -55,7 +55,7 @@ void SimpleActor::Anim_Attack { m_eNextAnimMode = 1; - m_csNextAnimString = 0; + m_csNextAnimString = NULL; m_NextAnimLabel = m_AttackHandler; m_bNextForceStart = false; } @@ -350,11 +350,11 @@ void SimpleActor::Anim_RunToInOpen void SimpleActor::Anim_Emotion ( - int eEmotionMode + eEmotionMode eEmotMode ) { - m_eEmotionMode = eEmotionMode; + m_eEmotionMode = eEmotMode; } void SimpleActor::Anim_Say diff --git a/code/game/actor_balcony.cpp b/code/game/actor_balcony.cpp index fe378141..e4ddc0ff 100644 --- a/code/game/actor_balcony.cpp +++ b/code/game/actor_balcony.cpp @@ -122,7 +122,7 @@ void Actor::Pain_Balcony ) { - SetThink( THINKSTATE_PAIN, 30 ); + SetThink( THINKSTATE_PAIN, THINK_BALCONY_PAIN); HandlePain( ev ); } @@ -134,7 +134,7 @@ void Actor::Killed_Balcony { ClearStates(); - SetThink( THINKSTATE_KILLED, 31 ); + SetThink( THINKSTATE_KILLED, THINK_BALCONY_KILLED); HandleKilled( ev, true ); if( !bPlayDeathAnim ) @@ -229,7 +229,7 @@ void Actor::Think_BalconyAttack if( !m_Enemy ) { - SetThinkState( THINKSTATE_IDLE, 0 ); + SetThinkState( THINKSTATE_IDLE, THINKLEVEL_NORMAL); IdleThink(); return; } @@ -246,7 +246,7 @@ void Actor::Think_BalconyAttack m_pszDebugState = "shoot"; State_Balcony_Shoot(); } - else if( m_State = 200 ) + else if( m_State == 200 ) { m_pszDebugState = "findenemy"; State_Balcony_FindEnemy(); @@ -266,7 +266,7 @@ void Actor::FinishedAnimation_BalconyAttack ) { - if( m_State = 202 ) + if( m_State == 202 ) State_Balcony_PostShoot(); } @@ -312,7 +312,7 @@ void Actor::Think_BalconyKilled Unregister( STRING_ANIMDONE ); - if( m_State = 805 ) + if( m_State == 805 ) { m_pszDebugState = "end"; } @@ -328,7 +328,7 @@ void Actor::Think_BalconyKilled m_bNextForceStart = true; m_eNextAnimMode = 7; m_pszDebugState = "begin"; - m_csNextAnimString = 270; + m_csNextAnimString = STRING_ANIM_NO_KILLED_SCR; ChangeMotionAnim(); animnum = gi.Anim_NumForName( edict->tiki, "death_balcony_intro" ); NewAnim( animnum ); @@ -354,6 +354,7 @@ void Actor::Think_BalconyKilled case 804: m_pszDebugState = "outtro"; Anim_FullBody( STRING_DEATH_BALCONY_OUTTRO, 1 ); + break; case 806: m_pszDebugState = "normal"; Anim_Killed(); @@ -367,25 +368,22 @@ void Actor::Think_BalconyKilled if( m_State >= 800 ) { - if( m_State <= 801 ) + 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 ) + else if (m_pFallPath->currentPos >= m_pFallPath->loop) { m_State = 802; m_iStateTime = level.inttime; - return; } } - else + else if( m_State == 802 ) { - if( m_State == 802 && m_pFallPath->currentPos >= m_pFallPath->length ) + if (m_pFallPath->currentPos >= m_pFallPath->length) { m_State = 803; m_iStateTime = level.inttime; diff --git a/code/game/actor_cover.cpp b/code/game/actor_cover.cpp index d1ef00b3..3f80f9ae 100644 --- a/code/game/actor_cover.cpp +++ b/code/game/actor_cover.cpp @@ -161,7 +161,7 @@ void Actor::State_Cover_FindCover { if( !m_iPotentialCoverCount ) { - SetThink( THINKSTATE_ATTACK, 1 ); + SetThink( THINKSTATE_ATTACK, THINK_TURRET ); } } } @@ -490,7 +490,7 @@ void Actor::State_Cover_Shoot if( level.inttime > m_iStateTime + 10000 ) { gi.Cvar_Set( "g_monitornum", va( "%i", entnum ) ); - assert( "!anim/shoot.scr took over 10 seconds" ); + assert( !"anim/shoot.scr took over 10 seconds" ); Com_Error( ERR_DROP, "anim/shoot.scr took over 10 seconds, entnum = %i, targetname = %s", entnum, targetname.c_str() ); } } @@ -577,7 +577,7 @@ __setpath: else { m_bTurretNoInitialCover = true; - SetThink( THINKSTATE_ATTACK, 1 ); + SetThink( THINKSTATE_ATTACK, THINK_TURRET ); } return; @@ -679,7 +679,7 @@ void Actor::State_Cover_FakeEnemy if( level.inttime >= m_iStateTime ) { - SetThinkState( THINKSTATE_IDLE, 0 ); + SetThinkState( THINKSTATE_IDLE, THINKLEVEL_NORMAL); } } diff --git a/code/game/actor_curious.cpp b/code/game/actor_curious.cpp index bf3d276e..80c5600d 100644 --- a/code/game/actor_curious.cpp +++ b/code/game/actor_curious.cpp @@ -51,7 +51,7 @@ void Actor::Begin_Curious DoForceActivate(); m_csMood = STRING_CURIOUS; - Anim_Emotion(10); + Anim_Emotion(EMOTION_CURIOUS); if (level.inttime > level.m_iCuriousVoiceTime + 3000) { @@ -76,7 +76,7 @@ void Actor::Begin_Curious if (m_bScriptGoalValid) { SetPath( - this->m_vScriptGoal, + m_vScriptGoal, "", 0, NULL, @@ -92,19 +92,30 @@ void Actor::Begin_Curious if (!m_bScriptGoalValid) { + //check if last enemy pos is within leash area (distance to m_vHome is <= m_fLeash) vDelta = m_vLastEnemyPos - m_vHome; if (vDelta.lengthSquared() <= m_fLeashSquared) { + //it's within leash area, go check it. SetPath(m_vLastEnemyPos, "", 0, NULL, 0.0); } else { + //it's NOT within leash area, + + //am I within leash area ? if ((origin - m_vHome).lengthSquared() <= m_fLeashSquared) { + //I'm inside leash area, + //Try to go towards enemy as much as possible without leaving leash area. + //vDest = vHome + U * leash + //U = unit vector of vDelta. SetPath(vDelta * sqrt(m_fLeashSquared / vDelta.lengthSquared()) + m_vHome, "", 0, NULL, 0.0); } else { + //I'm outside leash area, + //go to enemy, it doesn't matter. SetPath(m_vLastEnemyPos, "", 0, NULL, 0.0); } } @@ -121,8 +132,7 @@ void Actor::Begin_Curious VectorSub2D(m_vLastEnemyPos, origin, vDel); if (vDel[0] != 0 || vDel[1] != 0) { - m_YawAchieved = false; - m_DesiredYaw = vectoyaw(vDel); + SetDesiredYawDir(vDel); } m_eNextAnimMode = 1; m_csNextAnimString = STRING_ANIM_SURPRISE_SCR; @@ -171,8 +181,231 @@ void Actor::Think_Curious ) { - // FIXME: stub - STUB(); + //horrible function! + if (RequireThink()) + { + UpdateEyeOrigin(); + NoPoint(); + UpdateEnemy(100); + + if(m_State == 1101) + { + ContinueAnimation(); + //LABEL_16: + CheckForThinkStateTransition(); + PostThink(true); + return; + } + + m_bLockThinkState = false; + + if (!PathExists() || PathComplete()) + { + //v1 = &this->baseSimpleActor.baseSentient.m_Enemy; + //goto LABEL_6; + + ClearPath(); + Anim_Stand(); + LookAtCuriosity(); + + if (!m_Enemy || EnemyIsDisguised()) + { + if (level.inttime > m_iCuriousTime + 500) + { + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); + m_iCuriousTime = 0; + } + } + CheckForThinkStateTransition(); + PostThink(true); + return; + } + + if (m_Enemy || CanSeeEnemy(100)) + { + ClearPath(); + Anim_Stand(); + LookAtCuriosity(); + if (!m_Enemy || EnemyIsDisguised()) + { + if (level.inttime > m_iCuriousTime + 500) + { + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); + m_iCuriousTime = 0; + } + } + CheckForThinkStateTransition(); + PostThink(true); + return; + } + else + { + if (m_iCuriousLevel <= 5) + { + if (!InFOV(m_vLastEnemyPos, m_fFov, m_fFovDot)) + { + + if ((m_bScriptGoalValid || CanMovePathWithLeash()) + && MoveOnPathWithSquad()) + { + if (PatrolNextNodeExists()) + { + m_eNextAnimMode = 2; + } + else + { + //v11 = SimpleActor::GetRunAnim(this); + m_eNextAnimMode = 3; + } + m_csNextAnimString = GetRunAnim(); + m_bNextForceStart = false; + + FaceMotion(); + } + else + { + Anim_Stand(); + } + + if (level.inttime >= m_iNextWatchStepTime + && velocity.lengthSquared() >= 4.0) + { + SetDesiredLookDir(velocity); + + m_iNextWatchStepTime = level.inttime + (rand() & 0x1FF) + 500; + } + else + { + LookAtCuriosity(); + } + CheckForThinkStateTransition(); + PostThink(true); + return; + } + else + { + + Vector vEnd = EyePosition() - m_vLastEnemyPos; + VectorNormalizeFast(vEnd); + + vEnd += m_vLastEnemyPos; + if (!G_SightTrace(EyePosition(), vec_zero, vec_zero, vEnd, this, NULL, 33819417, qfalse, "Actor::Think_Curious")) + { + if ((m_bScriptGoalValid || CanMovePathWithLeash()) + && MoveOnPathWithSquad()) + { + if (PatrolNextNodeExists()) + { + m_eNextAnimMode = 2; + } + else + { + //v11 = SimpleActor::GetRunAnim(this); + m_eNextAnimMode = 3; + } + m_csNextAnimString = GetRunAnim(); + m_bNextForceStart = false; + + FaceMotion(); + } + else + { + Anim_Stand(); + } + + if (level.inttime >= m_iNextWatchStepTime + && velocity.lengthSquared() >= 4.0) + { + SetDesiredLookDir(velocity); + + m_iNextWatchStepTime = level.inttime + (rand() & 0x1FF) + 500; + } + else + { + LookAtCuriosity(); + } + CheckForThinkStateTransition(); + PostThink(true); + return; + } + else + { + + ClearPath(); + Anim_Stand(); + LookAtCuriosity(); + if (!m_Enemy || EnemyIsDisguised()) + { + if (level.inttime > m_iCuriousTime + 500) + { + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); + m_iCuriousTime = 0; + } + } + CheckForThinkStateTransition(); + PostThink(true); + return; + } + } + } + else + { + if ((PathGoal()-origin).lengthSquared() >= 2304) + { + if ((m_bScriptGoalValid || CanMovePathWithLeash()) + && MoveOnPathWithSquad()) + { + if (PatrolNextNodeExists()) + { + m_eNextAnimMode = 2; + } + else + { + //v11 = SimpleActor::GetRunAnim(this); + m_eNextAnimMode = 3; + } + m_csNextAnimString = GetRunAnim(); + m_bNextForceStart = false; + + FaceMotion(); + } + else + { + Anim_Stand(); + } + + if (level.inttime >= m_iNextWatchStepTime + && velocity.lengthSquared() >= 4.0) + { + SetDesiredLookDir(velocity); + + m_iNextWatchStepTime = level.inttime + (rand() & 0x1FF) + 500; + } + else + { + LookAtCuriosity(); + } + CheckForThinkStateTransition(); + PostThink(true); + return; + } + } + ClearPath(); + Anim_Stand(); + LookAtCuriosity(); + if (!m_Enemy || EnemyIsDisguised()) + { + if (level.inttime > m_iCuriousTime + 500) + { + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); + m_iCuriousTime = 0; + } + } + CheckForThinkStateTransition(); + PostThink(true); + return; + } + } } void Actor::FinishedAnimation_Curious @@ -254,7 +487,7 @@ void Actor::TimeOutCurious { if (level.inttime > m_iCuriousTime + 500) { - SetThinkState(1, 0); + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); m_iCuriousTime = 0; } } diff --git a/code/game/actor_disguise_common.cpp b/code/game/actor_disguise_common.cpp index ec193653..63932848 100644 --- a/code/game/actor_disguise_common.cpp +++ b/code/game/actor_disguise_common.cpp @@ -66,7 +66,7 @@ void Actor::State_Disguise_Wait } else { - SetThinkState(1, 0); + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); } } } @@ -85,7 +85,7 @@ void Actor::State_Disguise_Papers m_bNextForceStart = false; if (m_iEnemyShowPapersTime < m_Enemy->m_ShowPapersTime) { - if (level.m_iPapersLevel < this->m_iDisguiseLevel) + if (level.m_iPapersLevel < m_iDisguiseLevel) { m_State = 5; } @@ -158,7 +158,7 @@ void Actor::State_Disguise_Enemy if (level.inttime > m_iStateTime + 3000 && !m_Enemy->IsSubclassOfActor()) { - SetThinkState(4, 0); + SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL); } } @@ -174,7 +174,7 @@ void Actor::State_Disguise_Halt if (level.inttime > m_iStateTime + 1500 && !m_Enemy->IsSubclassOfActor()) { - SetThinkState(4, 0); + SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL); } } @@ -190,8 +190,8 @@ void Actor::State_Disguise_Accept if (level.inttime > m_iStateTime + 3000 ) { - SetThinkState(1, 0); - SetThink(6, 10); + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); + SetThink(THINKSTATE_DISGUISE, THINK_DISGUISE_SALUTE); } } @@ -207,6 +207,6 @@ void Actor::State_Disguise_Deny if (level.inttime > m_iStateTime + 3000) { - SetThinkState(1, 0); + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); } } diff --git a/code/game/actor_disguise_officier.cpp b/code/game/actor_disguise_officier.cpp index 39591a4b..49c082d3 100644 --- a/code/game/actor_disguise_officier.cpp +++ b/code/game/actor_disguise_officier.cpp @@ -91,12 +91,12 @@ void Actor::Begin_DisguiseOfficer } else { - SetThinkState(4, 0); + SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL); } } else { - SetThinkState(1, 0); + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); } } @@ -160,7 +160,7 @@ void Actor::Think_DisguiseOfficer if (!m_Enemy) { - SetThinkState(1, 0); + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); return; } if (!EnemyIsDisguised() && !(m_Enemy->IsSubclassOfActor()) && m_State != 3) @@ -170,7 +170,7 @@ void Actor::Think_DisguiseOfficer } if (level.m_bAlarm) { - SetThinkState(4, 0); + SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL); return; } vec2_t vDelta; @@ -260,7 +260,7 @@ void Actor::Think_DisguiseOfficer State_Disguise_Fake_Papers(); } } - CheckForTransition(7, 0); + CheckForTransition(THINKSTATE_GRENADE, 0); PostThink(true); } } diff --git a/code/game/actor_disguise_rover.cpp b/code/game/actor_disguise_rover.cpp index 8cc40e50..93c3c2c6 100644 --- a/code/game/actor_disguise_rover.cpp +++ b/code/game/actor_disguise_rover.cpp @@ -92,12 +92,12 @@ void Actor::Begin_DisguiseRover } else { - SetThinkState(4, 0); + SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL); } } else { - SetThinkState(1, 0); + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); } } @@ -134,6 +134,81 @@ void Actor::Think_DisguiseRover ) { - // FIXME: stub - STUB(); + if (!RequireThink()) + { + return; + } + UpdateEyeOrigin(); + NoPoint(); + ContinueAnimation(); + UpdateEnemy(1500); + + assert(m_Enemy != NULL); + + if (!m_Enemy) + { + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); + return; + } + + if (!EnemyIsDisguised() && !m_Enemy->IsSubclassOfActor() && m_State != 3) + { + m_State = 3; + m_iStateTime = level.inttime; + } + + if (level.m_bAlarm) + { + SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL); + return; + } + + { + vec2_t facedir; + facedir[0] = m_Enemy->origin[0] - origin[0]; + facedir[1] = m_Enemy->origin[1] - origin[1]; + if (facedir[0] != 0 || facedir[1] != 0) + { + m_YawAchieved = false; + m_DesiredYaw = vectoyaw(facedir); + } + + } + + SetDesiredLookDir(m_Enemy->origin - origin); + + if (m_State == 2) + { + m_pszDebugState = "accept"; + State_Disguise_Accept(); + } + else if(m_State > 2) + { + if (m_State == 3) + { + m_pszDebugState = "enemy"; + State_Disguise_Enemy(); + } + else if (m_State == 4) + { + m_pszDebugState = "halt"; + State_Disguise_Halt(); + } + else + { + assert(!"invalid think state"); + } + } + else if (m_State == 1) + { + m_pszDebugState = "papers"; + State_Disguise_Papers(); + } + else + { + assert(!"invalid think state"); + } + + CheckForTransition(THINKSTATE_GRENADE, 0); + PostThink(true); } diff --git a/code/game/actor_disguise_salute.cpp b/code/game/actor_disguise_salute.cpp index 1a8e515e..88f56f5d 100644 --- a/code/game/actor_disguise_salute.cpp +++ b/code/game/actor_disguise_salute.cpp @@ -94,12 +94,12 @@ void Actor::Begin_DisguiseSalute } else { - SetThinkState(4, 0); + SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL); } } else { - SetThinkState(1, 0); + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); } } @@ -136,8 +136,39 @@ void Actor::Think_DisguiseSalute ) { - // FIXME: stub - STUB(); + NoPoint(); + ContinueAnimation(); + UpdateEnemy(2000); + + assert(m_Enemy != NULL); + + if (m_Enemy) + { + if (!EnemyIsDisguised() && !m_Enemy->IsSubclassOfActor() && level.m_bAlarm) + { + { + vec2_t facedir; + facedir[0] = m_Enemy->origin[0] - origin[0]; + facedir[1] = m_Enemy->origin[1] - origin[1]; + if (facedir[0] != 0 || facedir[1] != 0) + { + SetDesiredYawDir(facedir); + } + + } + SetDesiredLookDir(m_Enemy->origin - origin); + + PostThink(true); + } + else + { + SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL); + } + } + else + { + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); + } } void Actor::FinishedAnimation_DisguiseSalute @@ -146,5 +177,5 @@ void Actor::FinishedAnimation_DisguiseSalute ) { - SetThinkState(1, 0); + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); } diff --git a/code/game/actor_disguise_sentry.cpp b/code/game/actor_disguise_sentry.cpp index a315b1ff..0af318c1 100644 --- a/code/game/actor_disguise_sentry.cpp +++ b/code/game/actor_disguise_sentry.cpp @@ -93,12 +93,12 @@ void Actor::Begin_DisguiseSentry } else { - SetThinkState(4, 0); + SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL); } } else { - SetThinkState(1, 0); + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); } } @@ -135,6 +135,80 @@ void Actor::Think_DisguiseSentry ) { - // FIXME: stub - STUB(); + if (RequireThink()) + { + UpdateEyeOrigin(); + NoPoint(); + ContinueAnimation(); + UpdateEnemy(1500); + + assert(m_Enemy != NULL); + + if (!m_Enemy) + { + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); + return; + } + if (!EnemyIsDisguised() && !m_Enemy->IsSubclassOfActor() && m_State != 3) + { + m_State = 3; + m_iStateTime = level.inttime; + } + + if (level.m_bAlarm) + { + SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL); + } + else + { + + { + vec2_t facedir; + facedir[0] = m_Enemy->origin[0] - origin[0]; + facedir[1] = m_Enemy->origin[1] - origin[1]; + if (facedir[0] != 0 || facedir[1] != 0) + { + m_YawAchieved = false; + m_DesiredYaw = vectoyaw(facedir); + } + + } + + SetDesiredLookDir(m_Enemy->origin - origin); + + switch (m_State) + { + case 0: + m_pszDebugState = "wait"; + State_Disguise_Wait(); + break; + case 1: + m_pszDebugState = "papers"; + State_Disguise_Papers(); + break; + case 2: + m_pszDebugState = "accept"; + State_Disguise_Accept(); + break; + case 3: + m_pszDebugState = "enemy"; + State_Disguise_Enemy(); + break; + case 4: + m_pszDebugState = "halt"; + State_Disguise_Halt(); + break; + case 5: + m_pszDebugState = "deny"; + State_Disguise_Deny(); + break; + default: + Com_Printf("Actor::Think_DisguiseSentry: invalid think state %i\n", m_State); + assert(!"invalid think state"); + break; + } + CheckForTransition(THINKSTATE_GRENADE, 0); + PostThink(true); + } + } } diff --git a/code/game/actor_dog.cpp b/code/game/actor_dog.cpp index 4555314e..24917a44 100644 --- a/code/game/actor_dog.cpp +++ b/code/game/actor_dog.cpp @@ -78,6 +78,7 @@ void Actor::End_Dog ) { + ; } void Actor::Think_Dog_Idle @@ -106,8 +107,72 @@ void Actor::Think_Dog_Attack ) { - // FIXME: stub - STUB(); + if (!RequireThink()) + { + return; + } + + UpdateEyeOrigin(); + m_pszDebugState = "Dog_Attack"; + + if (m_Enemy && !(m_Enemy->IsSubclassOfActor())) + { + + SetPath(m_Enemy->origin, "", 0, NULL, 0.0); + if (PathExists()) + { + vec2_t delta; + VectorSub2D(m_Enemy->origin, origin, delta); + + if (VectorLength2DSquared(delta) >= 8000) + { + FaceMotion(); + m_csNextAnimString = STRING_ANIM_DOG_CHASE_SCR; + m_eNextAnimMode = 2; + } + else + { + { + vec2_t facedir; + facedir[0] = m_Enemy->origin[0] - origin[0]; + facedir[1] = m_Enemy->origin[1] - origin[1]; + if (facedir[0] != 0 || facedir[1] != 0) + { + m_YawAchieved = false; + m_DesiredYaw = vectoyaw(facedir); + } + + } + SetDesiredLookDir(m_Enemy->origin - origin); + m_eNextAnimMode = 1; + m_csNextAnimString = STRING_ANIM_DOG_ATTACK_SCR; + } + m_bNextForceStart = false; + CheckForThinkStateTransition(); + PostThink(false); + return; + } + + { + vec2_t facedir; + facedir[0] = m_Enemy->origin[0] - origin[0]; + facedir[1] = m_Enemy->origin[1] - origin[1]; + if (facedir[0] != 0 || facedir[1] != 0) + { + SetDesiredYawDir(facedir); + } + + } + SetDesiredLookDir(m_Enemy->origin - origin); + } + m_bNextForceStart = false; + m_eNextAnimMode = 1; + m_csNextAnimString = STRING_ANIM_DOG_CURIOUS_SCR; + m_State = 20; + m_iStateTime = level.inttime; + + CheckForThinkStateTransition(); + PostThink(false); } void Actor::Think_Dog_Curious @@ -128,8 +193,7 @@ void Actor::Think_Dog_Curious if (vDelta[0] != 0 || vDelta[1] != 0) { - m_YawAchieved = false; - m_DesiredYaw = vectoyaw(vDelta); + SetDesiredYawDir(vDelta); } SetDesiredLookDir(m_Enemy->origin - origin); diff --git a/code/game/actor_grenade.cpp b/code/game/actor_grenade.cpp index 5b7dd3ee..b0b5e83a 100644 --- a/code/game/actor_grenade.cpp +++ b/code/game/actor_grenade.cpp @@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // actor_grenade.cpp #include "actor.h" +#include "weaputils.h" void Actor::InitGrenade ( @@ -42,14 +43,75 @@ void Actor::InitGrenade bool Actor::Grenade_Acquire ( - int eNextState, + eGrenadeState eNextState, const_str csReturnAnim ) { - // FIXME: stub - STUB(); - return false; + bool bRetVal = false; + Vector vDest; + if (m_bGrenadeBounced) + { + bRetVal = true; + vDest = origin - m_vGrenadePos; + vDest = vDest * 16 + m_vGrenadePos; + SetPath(vDest, "", 0, NULL, 0.0); + } + if (PathExists()) + { + if (PathComplete()) + { + m_bHasDesiredLookAngles = false; + if (m_pGrenade->velocity.lengthXY(true) >= 1024) + { + Anim_Stand(); + } + else + { + m_pGrenade->velocity = vec_zero; + + m_eNextAnimMode = 1; + m_eGrenadeState = eNextState; + m_bNextForceStart = false; + m_csNextAnimString = csReturnAnim; + } + } + else + { + Anim_RunToCasual(3); + + vec2_t delta; + VectorSub2D(origin, m_vGrenadePos, delta); + + if (VectorLength2DSquared(delta) > 1024.0) + { + FaceMotion(); + } + else + { + { + vec2_t facedir; + facedir[0] = m_vGrenadePos[0] - origin[0]; + facedir[1] = m_vGrenadePos[1] - origin[1]; + if (facedir[0] != 0 || facedir[1] != 0) + { + m_YawAchieved = false; + m_DesiredYaw = vectoyaw(facedir); + } + + } + } + } + } + else + { + m_bGrenadeBounced = true; + m_eGrenadeState = AI_GRENSTATE_FLEE; + Grenade_Flee(); + bRetVal = false; + } + + return bRetVal; } void Actor::Grenade_Flee @@ -58,8 +120,90 @@ void Actor::Grenade_Flee ) { - // FIXME: stub - STUB(); + float origin_ratio; + float fMinCloseDistSquared; + float fCosAngle; + float fSinAngle; + float fAngle; + vec2_t vDirAway; + vec2_t vDirPreferred; + + if (m_bGrenadeBounced) + { + fAngle = (rand() - 0x3FFFFFFF) * -0.00000000146291807926716; + + fSinAngle = sin(fAngle); + fCosAngle = cos(fAngle); + + VectorSub2D(origin, m_vGrenadePos, vDirAway); + + vDirPreferred[0] = vDirAway[0] * fCosAngle - fSinAngle * vDirAway[1]; + vDirPreferred[1] = vDirAway[0] * fSinAngle + vDirAway[1] * fCosAngle; + + FindPathAway(m_vGrenadePos, vDirPreferred, 512); + + if (PathExists() && !PathComplete()) + { + fMinCloseDistSquared = VectorLength2DSquared(vDirAway) * 0.63999999; + + if (fMinCloseDistSquared < 1024) + fMinCloseDistSquared = 0; + + vec2_t grenade_offset; + for (auto current_node = CurrentPathNode(); current_node >= LastPathNode(); current_node--) + { + VectorSub2D(m_vGrenadePos, current_node->point, grenade_offset); + if (current_node->dist > 0 && DotProduct2D(grenade_offset, current_node->dir) <= current_node->dist) + { + if (Square(CrossProduct2D(grenade_offset, current_node->dir)) < fMinCloseDistSquared) + { + ClearPath(); + break; + } + } + } + } + m_bGrenadeBounced = false; + } + + if (PathExists() && !PathComplete()) + { + Sentient *pOwner = NULL; + if (m_pGrenade && m_pGrenade->IsSubclassOfProjectile()) + pOwner = ((Projectile *)m_pGrenade.Pointer())->GetOwner(); + + if (pOwner && pOwner->m_Team == m_Team) + Anim_RunTo(3); + else + Anim_RunToFlee(3); + FaceMotion(); + } + else + { + + if ((origin - m_vGrenadePos).lengthXY(true) >= 100352 + || !G_SightTrace( + centroid, + vec_zero, + vec_zero, + m_vGrenadePos, + this, + m_pGrenade, + 33819417, + 0, + "Actor::Grenade_Flee")) + { + m_eGrenadeState = AI_GRENSTATE_FLEE_SUCCESS; + Anim_Attack(); + AimAtAimNode(); + } + else + { + m_bHasDesiredLookAngles = false; + m_eGrenadeState = AI_GRENSTATE_FLEE_FAIL; + Anim_Cower(); + } + } } void Actor::Grenade_ThrowAcquire @@ -68,7 +212,7 @@ void Actor::Grenade_ThrowAcquire ) { - if (!Grenade_Acquire(2, STRING_ANIM_GRENADERETURN_SCR) + if (!Grenade_Acquire(AI_GRENSTATE_THROW, STRING_ANIM_GRENADERETURN_SCR) && !CanGetGrenadeFromAToB( m_vGrenadePos, m_vLastEnemyPos, @@ -77,7 +221,7 @@ void Actor::Grenade_ThrowAcquire &m_eGrenadeMode)) { m_bGrenadeBounced = true; - m_eGrenadeState = 0; + m_eGrenadeState = AI_GRENSTATE_FLEE; Grenade_Flee(); } } @@ -102,27 +246,22 @@ void Actor::Grenade_KickAcquire { Vector vFace = vec_zero; - if (!Actor::Grenade_Acquire(4, STRING_ANIM_GRENADEKICK_SCR)) + if (!Grenade_Acquire(AI_GRENSTATE_KICK, STRING_ANIM_GRENADEKICK_SCR)) { VectorSub2D(m_vGrenadePos, origin, vFace); if (CanKickGrenade(m_vGrenadePos, m_vLastEnemyPos, vFace, &m_vGrenadeVel)) { - - m_vKickDir[0] = m_vGrenadeVel[0]; - m_vKickDir[1] = m_vGrenadeVel[1]; - m_vKickDir[2] = 0.0; + m_vKickDir = Vector(m_vGrenadeVel[0], m_vGrenadeVel[1], 0); VectorNormalizeFast(m_vKickDir); } else { m_bGrenadeBounced = true; - m_eGrenadeState = 0; + m_eGrenadeState = AI_GRENSTATE_FLEE; Grenade_Flee(); } } - // FIXME: stub - STUB(); } void Actor::Grenade_Kick @@ -141,8 +280,61 @@ void Actor::Grenade_MartyrAcquire ) { - // FIXME: stub - STUB(); + Vector vDest; + if (m_bGrenadeBounced) + { + m_bGrenadeBounced = false; + + vDest = origin - m_vGrenadePos; + VectorNormalizeFast(vDest); + + vDest = vDest * 88 + m_vGrenadePos; + + SetPath(vDest, "", 0, NULL, 0.0); + } + + if (PathExists()) + { + if (PathComplete()) + { + m_bHasDesiredLookAngles = false; + + vDest = vec_zero; + m_pGrenade->velocity = vec_zero; + + //weird ? m_pGrenade->velocity is vec_zero ??? + if (m_pGrenade->velocity.lengthXY(true) < 1024) + { + m_pGrenade->velocity = vec_zero; + + m_eGrenadeState = AI_GRENSTATE_MARTYR; + m_iStateTime = level.inttime; + Grenade_Martyr(); + } + } + else + { + Anim_RunToCasual(3); + m_csPathGoalEndAnimScript = STRING_ANIM_GRENADEMARTYR_SCR; + if ((origin-m_vGrenadePos).lengthXY(true) > 16384) + { + FaceMotion(); + } + else + { + if (m_vGrenadePos - origin != vec_zero) + { + SetDesiredYawDir(m_vGrenadePos - origin); + } + } + } + } + else + { + m_bGrenadeBounced = true; + m_eGrenadeState = AI_GRENSTATE_FLEE; + Grenade_Flee(); + } } void Actor::Grenade_Martyr @@ -151,8 +343,17 @@ void Actor::Grenade_Martyr ) { - // FIXME: stub - STUB(); + if (m_pGrenade && level.inttime >= (m_iStateTime + 1000) - 0.5) + { + Projectile *m_pPGrenade = (Projectile *)m_pGrenade.Pointer(); + + m_pPGrenade->m_bHurtOwnerOnly = true; + m_pPGrenade->owner = entnum; + + } + + m_bHasDesiredLookAngles = false; + ContinueAnimation(); } void Actor::Grenade_Wait @@ -180,9 +381,9 @@ void Actor::Grenade_NextThinkState { if (m_Enemy && !(m_Enemy->IsSubclassOfActor())) - SetThinkState(4, 0); + SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL); else - SetThinkState(1, 0); + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); } void Actor::Grenade_EventAttach @@ -191,8 +392,35 @@ void Actor::Grenade_EventAttach ) { - // FIXME: stub - STUB(); + if (m_pGrenade) + { + eGrenadeTossMode eMode; + Vector vVel; + int tagnum = gi.Tag_NumForName(edict->tiki, "tag_weapon_right"); + if (tagnum >= 0) + { + vVel = vec_zero; + m_pGrenade->attach( + entnum, + tagnum, + qtrue, + vec3_origin); + } + m_pGrenade->avelocity = vec3_origin; + + if (CanGetGrenadeFromAToB( + origin, + m_vLastEnemyPos, + true, + &vVel, + &eMode)) + { + m_vGrenadeVel = vVel; + m_eGrenadeMode = eMode; + } + + SetDesiredYawDir(m_vGrenadeVel); + } } void Actor::Grenade_EventDetach @@ -201,8 +429,16 @@ void Actor::Grenade_EventDetach ) { - // FIXME: stub - STUB(); + if (m_pGrenade) + { + m_pGrenade->detach(); + m_pGrenade->setOrigin(GrenadeThrowPoint(origin, orientation[0], m_eGrenadeMode == AI_GREN_KICK ? STRING_ANIM_GRENADEKICK_SCR : STRING_ANIM_GRENADERETURN_SCR)); + m_pGrenade->velocity = m_vGrenadeVel; + + m_pGrenade->edict->r.ownerNum = edict->s.number; + m_pGrenade->groundentity = NULL; + + } } void Actor::Begin_Grenade @@ -211,8 +447,126 @@ void Actor::Begin_Grenade ) { - // FIXME: stub - STUB(); + m_pGrenade->enemy; + DoForceActivate(); + m_csMood = STRING_ALERT; + m_csIdleMood = STRING_NERVOUS; + + if (m_pGrenade) + { + if (m_pGrenade->enemy) + { + m_eGrenadeState = AI_GRENSTATE_FLEE; + //LABEL_4: + Grenade_Flee(); + return; + } + + if (m_pGrenade->edict->r.ownerNum == entnum) + { + m_eGrenadeState = AI_GRENSTATE_FLEE; + Grenade_Flee(); + return; + } + bool bHasThrowTarget = true; + float fDistSquared; + Vector vDelta; + if (!m_Enemy) + { + Sentient *pEnemy = (Sentient *)G_GetEntity(m_pGrenade->edict->r.ownerNum); + + if (pEnemy && pEnemy->m_Team != m_Team) + { + SetEnemyPos(pEnemy->origin); + } + else + { + bHasThrowTarget = false; + } + } + if (!bHasThrowTarget) + { + m_eGrenadeState = AI_GRENSTATE_FLEE; + Grenade_Flee(); + return; + } + vDelta = m_vGrenadePos - origin; + vDelta.z = 0; + fDistSquared = vDelta.lengthXY(true); + if (fDistSquared >= 65536) + { + m_eGrenadeState = AI_GRENSTATE_FLEE; + Grenade_Flee(); + return; + } + + if (fDistSquared > 16384 && GrenadeWillHurtTeamAt(m_vGrenadePos)) + { + m_pGrenade->enemy = this; + + m_eGrenadeState = AI_GRENSTATE_MARTYR_ACQUIRE; + Grenade_MartyrAcquire(); + return; + } + + if (GrenadeWillHurtTeamAt(m_vLastEnemyPos)) + { + m_eGrenadeState = AI_GRENSTATE_FLEE; + Grenade_Flee(); + return; + } + + if (CanKickGrenade(m_vGrenadePos, m_vLastEnemyPos, vDelta, &m_vGrenadeVel)) + { + m_eGrenadeMode = AI_GREN_KICK; + + m_vKickDir = Vector(m_vGrenadeVel[0], m_vGrenadeVel[1], 0); + VectorNormalizeFast(m_vKickDir); + + m_pGrenade->enemy = this; + + m_eGrenadeState = AI_GRENSTATE_KICK_ACQUIRE; + PostponeEvent(EV_Projectile_Explode, 0.25); + Grenade_KickAcquire(); + return; + } + + if (!CanGetGrenadeFromAToB(m_vGrenadePos, m_vLastEnemyPos, true, &m_vGrenadeVel, &m_eGrenadeMode)) + { + m_eGrenadeState = AI_GRENSTATE_FLEE; + Grenade_Flee(); + return; + } + + m_pGrenade->enemy = this; + + m_eGrenadeState = AI_GRENSTATE_THROW_ACQUIRE; + PostponeEvent(EV_Projectile_Explode, 0.75); + if (!Grenade_Acquire(AI_GRENSTATE_THROW, STRING_ANIM_GRENADERETURN_SCR) + && !Actor::CanGetGrenadeFromAToB(m_vGrenadePos, m_vLastEnemyPos, true, &m_vGrenadeVel, &m_eGrenadeMode)) + { + m_bGrenadeBounced = true; + m_eGrenadeState = AI_GRENSTATE_FLEE; + Grenade_Flee(); + return; + } + } + else + { + if (m_Enemy && !m_Enemy->IsSubclassOfActor()) + { + SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_NORMAL); + } + else if (m_Team == TEAM_AMERICAN) + { + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); + } + else + { + if (!IsTeamMate((Sentient*)G_GetEntity(0))) + ForceAttackPlayer(); + } + } } void Actor::End_Grenade @@ -242,8 +596,104 @@ void Actor::Think_Grenade ) { - // FIXME: stub - STUB(); + if (m_bEnableEnemy) + UpdateEnemy(200); + m_pszDebugState = ""; + NoPoint(); + + if (level.inttime - m_iFirstGrenadeTime > 8000) + { + Anim_Stand(); + Grenade_NextThinkState(); + PostThink(false); + return; + } + + if (!m_pGrenade) + { + if (m_eGrenadeState && m_eGrenadeState != AI_GRENSTATE_FLEE_FAIL) + { + //weird ? no such thing as 8 ? + if (m_eGrenadeMode == 8) + Anim_Attack(); + else + Anim_Stand(); + Grenade_NextThinkState(); + } + else + { + m_pszDebugState = "Wait"; + Grenade_Wait(); + } + PostThink(false); + return; + } + + switch (m_eGrenadeState) + { + case AI_GRENSTATE_FLEE: + case AI_GRENSTATE_FLEE_SUCCESS: + case AI_GRENSTATE_FLEE_FAIL: + m_pszDebugState = "RunAway"; + Grenade_Flee(); + PostThink(false); + return; + case AI_GRENSTATE_THROW_ACQUIRE: + m_pszDebugState = "ThrowAcquire"; + Grenade_ThrowAcquire(); + PostThink(false); + return; + case AI_GRENSTATE_THROW: + m_pszDebugState = "Throw"; + Grenade_Throw(); + PostThink(false); + return; + case AI_GRENSTATE_KICK_ACQUIRE: + m_pszDebugState = "KickAcquire"; + Grenade_KickAcquire(); + PostThink(false); + return; + case AI_GRENSTATE_KICK: + m_pszDebugState = "Kick"; + m_bHasDesiredLookAngles = false; + ContinueAnimation(); + PostThink(false); + return; + case AI_GRENSTATE_MARTYR_ACQUIRE: + m_pszDebugState = "MartyrAcquire"; + Grenade_MartyrAcquire(); + PostThink(false); + return; + case AI_GRENSTATE_MARTYR: + m_pszDebugState = "Martyr"; + Grenade_Martyr(); + PostThink(false); + return; + default: + m_pszDebugState = "***Invalid***"; + /* useless assert + if ( !dword_39AC88 ) + { + strcpy(v4, \"invalid grenade state\"\n\tMessage: "); + memset(&s, 0, 0x3FDFu); + v2 = DumpCallTrace( + "thinkstate = %i", + m_State); + Q_strcat(v4, 0x4000, v2); + v3 = MyAssertHandler(v4, "fgame/actor_grenade.cpp", 762, 0); + if ( v3 < 0 ) + { + dword_39ACFC = 1; + } + else if ( v3 > 0 ) + { + __debugbreak(); + } + } + */ + PostThink(false); + return; + } } void Actor::FinishedAnimation_Grenade @@ -254,16 +704,16 @@ void Actor::FinishedAnimation_Grenade { switch (m_eGrenadeState) { - case 0: - case 1: - case 3: - case 5: - case 6: - case 8: - case 9: + case AI_GRENSTATE_FLEE: + case AI_GRENSTATE_THROW_ACQUIRE: + case AI_GRENSTATE_KICK_ACQUIRE: + case AI_GRENSTATE_MARTYR_ACQUIRE: + case AI_GRENSTATE_MARTYR: + case AI_GRENSTATE_FLEE_SUCCESS: + case AI_GRENSTATE_FLEE_FAIL: return; - case 2: - case 4: + case AI_GRENSTATE_THROW: + case AI_GRENSTATE_KICK: Grenade_NextThinkState(); break; default: diff --git a/code/game/actor_machinegunner.cpp b/code/game/actor_machinegunner.cpp index 2f1dd4f5..29049891 100644 --- a/code/game/actor_machinegunner.cpp +++ b/code/game/actor_machinegunner.cpp @@ -25,6 +25,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "actor.h" #include "weapturret.h" +extern Vector MINS; +extern Vector MAXS; + void Actor::InitMachineGunner ( GlobalFuncs_t *func @@ -44,8 +47,46 @@ void Actor::Begin_MachineGunner ) { - // FIXME: stub - STUB(); + m_csMood = STRING_ALERT; + m_csIdleMood = STRING_NERVOUS; + + if (m_pTurret) + { + Sentient *pOwner; + m_pTurret->m_bHadOwner = true; + pOwner = m_pTurret->GetOwner(); + if (pOwner) + { + Com_Printf( + "^~^~^ Actor (entnum %d, radnum %d, targetname '%s') cannot use turret (entnum %d, radnum %d, targetname '%s')" + " since it is already being used by Actor (entnum %d, radnum %d, targetname '%s')\n", + entnum, + radnum, + targetname.c_str(), + m_pTurret->entnum, + m_pTurret->radnum, + m_pTurret->TargetName().c_str(), + pOwner->entnum, + pOwner->radnum, + pOwner->TargetName().c_str()); + } + else + { + Holster(); + + m_pTurret->TurretBeginUsed(this); + m_State = 1200; + m_iStateTime = level.inttime; + } + } + else + { + Com_Printf( + "^~^~^ Actor (entnum %d, radnum %d, targetname '%s') has no turret specified\n", + entnum, + radnum, + targetname.c_str()); + } } void Actor::End_MachineGunner ( @@ -53,7 +94,7 @@ void Actor::End_MachineGunner ) { - if (!Sentient::GetWeapon(WEAPON_MAIN)) + if (!GetWeapon(WEAPON_MAIN)) giveItem("models/weapons/mp40.tik"); Unholster(); @@ -71,36 +112,217 @@ void Actor::BecomeTurretGuy ) { - SetThinkIdle(8); + SetThinkIdle(THINK_IDLE); - SetThink(THINKSTATE_ATTACK, 1); - SetThink(THINKSTATE_DISGUISE, 10); - SetThink(THINKSTATE_GRENADE, 16); + SetThink(THINKSTATE_ATTACK, THINK_TURRET); + SetThink(THINKSTATE_DISGUISE, THINK_DISGUISE_SALUTE); + SetThink(THINKSTATE_GRENADE, THINK_GRENADE); - if (m_Think[m_ThinkLevel] == 1 && Turret_DecideToSelectState()) + if (CurrentThink() == THINK_IDLE && Turret_DecideToSelectState()) { m_State = 100; m_iStateTime = level.inttime; } } + void Actor::Think_MachineGunner ( void ) { - // FIXME: stub - STUB(); + if (RequireThink()) + { + if (m_pTurret && m_pTurret->GetOwner() == this && !m_bNoPlayerCollision) + { + if (!m_bEnableEnemy) + { + ThinkHoldGun(); + return; + } + + if (level.inttime < m_iEnemyCheckTime + 200) + { + ThinkHoldGun(); + return; + } + + m_iEnemyCheckTime = level.inttime; + + if (m_pTurret->CanTarget(G_GetEntity(0)->centroid)) + { + ThinkHoldGun(); + return; + } + if (!m_pGrenade || m_fGrenadeAwareness < rand() * 0.000000046566129) + { + if (!G_SightTrace( + EyePosition(), + vec_zero, + vec_zero, + G_GetEntity(0)->centroid, + this, + G_GetEntity(0), + 33819417, + qfalse, + "Actor::Think_MachineGunner")) + { + ThinkHoldGun(); + return; + } + if (m_ThinkStates[0] != THINKSTATE_IDLE) + { + BecomeTurretGuy(); + return; + } + + if (m_Enemy && !m_Enemy->IsSubclassOfActor() && !EnemyIsDisguised() && m_PotentialEnemies.GetCurrentVisibility() >= 1) + { + BecomeTurretGuy(); + return; + } + + if (!m_Enemy || !m_Enemy->IsSubclassOfActor() || EnemyIsDisguised() || m_PotentialEnemies.GetCurrentVisibility() > 1) + { + ThinkHoldGun(); + return; + } + + SetCuriousAnimHint(6); + } + } + BecomeTurretGuy(); + } } + void Actor::ThinkHoldGun ( void ) { - // FIXME: stub - STUB(); + Vector end; + trace_t trace; + float temp; + float temp2; + float machine_gunner_hands_up_stand; + float heightDiff; + float right; + vec3_t newOrigin; + Vector offset; + Vector start; + vec3_t new_angles; + Vector vForward; + + UpdateEyeOrigin(); + m_pszDebugState = ""; + if (m_State == 1200) + { + if (m_pTurret->IsFiring()) + { + if (m_pTurret->aim_target == G_GetEntity(0)) + { + m_bNoSurprise = true; + } + m_csNextAnimString = STRING_ANIM_MG42_SHOOT_SCR; + } + else + { + m_csNextAnimString = STRING_ANIM_MG42_IDLE_SCR; + } + } + else + { + m_csNextAnimString = STRING_ANIM_MG42_RELOAD_SCR; + m_bAnimScriptSet = false; + } + m_eNextAnimMode = 8; + m_bNextForceStart = false; + + CheckUnregister(); + + m_YawAchieved = true; + + setAngles(Vector(0,m_pTurret->angles[1],0)); + + vForward = Vector(m_pTurret->orientation[0]) * -39 + m_pTurret->origin; + + if (m_State == 1201) + { + heightDiff = 71.6; + } + else + { + heightDiff = 71.8; + } + + machine_gunner_hands_up_stand = origin[2] - (m_pTurret->origin[2] - heightDiff); + + + if (machine_gunner_hands_up_stand < 0) + { + if (m_State == 1201) + { + temp = (machine_gunner_hands_up_stand - m_pTurret->origin[2]) / 39; + if (temp >= -1.0 && temp <= 1.0) + { + right = atan2(temp / sqrt(temp*-temp + 1), 1) * 180 / M_PI; + m_pTurret->setAngles(Vector(right, m_pTurret->angles[1], m_pTurret->angles[2])); + } + } + else + { + m_fCrouchWeight = machine_gunner_hands_up_stand / 17.1; + if (m_fCrouchWeight < -1.0) + { + m_fCrouchWeight = -1.0; + } + + } + temp2 = m_fCrouchWeight * 2.6; + offset.x = (-(-9.3*m_fCrouchWeight + 23.4)) * orientation[0][0] + vForward.x; + offset.y = (-(-9.3*m_fCrouchWeight + 23.4)) * orientation[0][0] + vForward.y; + } + else + { + m_fCrouchWeight = machine_gunner_hands_up_stand / (heightDiff - 38.7); + if (m_fCrouchWeight > 1.0) + { + m_fCrouchWeight = 1.0; + } + + temp2 = m_fCrouchWeight * -1.6; + offset.x = (-(-3*m_fCrouchWeight + 23.4)) * orientation[0][0] + vForward.x; + offset.y = (-(-3*m_fCrouchWeight + 23.4)) * orientation[0][0] + vForward.y; + } + + start.x = (temp2 + 10.3) * orientation[1][0] + offset.x; + start.y = (temp2 + 10.3) * orientation[1][1] + offset.y; + + if (m_fCrouchWeight >= 0.5) + m_csCurrentPosition = STRING_CROUCH; + else + m_csCurrentPosition = STRING_STAND; + + UpdateAimMotion(); + UpdateAnim(); + start.z = origin.z + 18.0; + + end = start; + end.z = origin.z - 94.0; + + trace = G_Trace(start, MINS, MAXS, end, this, 1107437825, qfalse, "Actor::ThinkHoldGun"); + + if (trace.fraction != 1.0 && !trace.startsolid && !trace.allsolid && trace.ent) + SafeSetOrigin(trace.endpos); + + velocity = vec_zero; + + UpdateBoneControllers(); + UpdateFootsteps(); + } + void Actor::FinishedAnimation_MachineGunner ( void diff --git a/code/game/actor_noclip.cpp b/code/game/actor_noclip.cpp index 3d1eed1c..35203f8b 100644 --- a/code/game/actor_noclip.cpp +++ b/code/game/actor_noclip.cpp @@ -49,6 +49,74 @@ void Actor::Think_NoClip ) { - // FIXME: stub - STUB(); + //FIXME: not sure of naming + bool done = false; + Vector newOrigin = vec_zero; + Vector total_offset; + Vector total_offset_unit; + float total_dist; + vec3_t frame_offset; + float frame_dist; + + m_pszDebugState = ""; + + if (m_eNextAnimMode < 0) + { + m_bNextForceStart = false; + m_csNextAnimString = NULL; + + m_eNextAnimMode = m_eAnimMode; + + + m_NextAnimLabel = m_Anim; + } + + CheckUnregister(); + UpdateAngles(); + UpdateAnim(); + + total_offset = m_NoClipDest - origin; + total_dist = VectorNormalize2(total_offset, total_offset_unit); + + frame_dist = level.frametime * m_maxspeed; + + if (frame_dist >= frame_delta.lengthSquared()) + { + frame_dist = frame_delta.lengthSquared(); + } + + if (frame_dist < total_dist) + { + newOrigin = total_offset_unit * frame_dist + origin; + + } + else + { + done = true; + newOrigin = m_NoClipDest; + } + + SafeSetOrigin(newOrigin); + + velocity = total_offset_unit / level.frametime; + + if (velocity.lengthSquared() < 1) + { + done = true; + velocity = vec_zero; + } + groundentity = NULL; + + if (done) + { + Com_Printf( + "(entnum %d, radnum %d) failsafe finished\n", + entnum, + radnum); + EndCurrentThinkState(); + } + + UpdateBoneControllers(); + UpdateFootsteps(); + } diff --git a/code/game/actor_patrol.cpp b/code/game/actor_patrol.cpp index 6a493bb7..bd876f1d 100644 --- a/code/game/actor_patrol.cpp +++ b/code/game/actor_patrol.cpp @@ -56,8 +56,8 @@ void Actor::End_Patrol ) { - // FIXME: stub - STUB(); + + parm.movefail = true; } void Actor::Resume_Patrol @@ -66,7 +66,7 @@ void Actor::Resume_Patrol ) { - parm.movefail = true; + ; } void Actor::Think_Patrol @@ -99,7 +99,7 @@ void Actor::Think_Patrol } else { - SetThinkIdle(8); + SetThinkIdle(THINK_IDLE); m_bScriptGoalValid = false; } parm.movedone = true; diff --git a/code/game/actor_runner.cpp b/code/game/actor_runner.cpp index ec4eb458..8b8355d6 100644 --- a/code/game/actor_runner.cpp +++ b/code/game/actor_runner.cpp @@ -96,7 +96,7 @@ void Actor::Think_Runner } else { - SetThinkIdle(8); + SetThinkIdle(THINK_IDLE); m_bScriptGoalValid = false; } diff --git a/code/game/actor_turret.cpp b/code/game/actor_turret.cpp index da0faa25..9840c5e4 100644 --- a/code/game/actor_turret.cpp +++ b/code/game/actor_turret.cpp @@ -111,18 +111,232 @@ void Actor::Think_Turret { - //FIXME: weird, appears to be looping here ? O.o - if (!RequireThink()) + + if (RequireThink()) { - return; + UpdateEyeOrigin(); + NoPoint(); + UpdateEnemy(200); + + if (m_Enemy && m_State == 110) + { + if (!m_bTurretNoInitialCover) + { + if (Turret_TryToBecomeCoverGuy()) + { + m_pszDebugState = "CoverInstead"; + CheckUnregister(); + UpdateAngles(); + DoMove(); + UpdateBoneControllers(); + UpdateFootsteps(); + return; + } + } + m_bTurretNoInitialCover = false; + + Turret_SelectState(); + + if (m_State == 100 && !CanSeeEnemy(0)) + { + SetEnemyPos(m_Enemy->origin); + AimAtEnemyBehavior(); + m_State = 113; + m_iStateTime = level.inttime; + } + + SetLeashHome(origin); + + if (level.inttime < m_iEnemyChangeTime + 200) + { + if (AttackEntryAnimation()) + { + m_State = 108; + m_bLockThinkState = true; + m_iStateTime = level.inttime; + } + } + } + + if (level.inttime > m_iStateTime + 3000) + Turret_SelectState(); + + if (m_State == 108) + { + m_pszDebugState = "IntroAnim"; + AimAtAimNode(); + ContinueAnimation(); + } + else + { + m_bLockThinkState = false; + if (!m_Enemy && m_State != 109 && m_State != 104) + { + m_State = 109; + m_iStateTime = level.inttime + ((rand() + 0xFA) & 0x7FF); + } + if (!m_Enemy) + { + if (m_State != 109) + { + if (m_State != 104 + || (origin - m_vHome).lengthXY(true) <= 0.64f * m_fLeashSquared + 64.0f + || !State_Turret_RunHome(false) ) + { + m_pszDebugState = "Idle"; + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); + IdleThink(); + } + else + { + m_pszDebugState = "Idle->RunHome"; + PostThink(true); + } + return; + } + } + if (m_Enemy && m_State == 109) + { + Actor::SetEnemyPos(m_Enemy->origin); + AimAtEnemyBehavior(); + m_State = 113; + m_iStateTime = level.inttime; + } + + if (Turret_DecideToSelectState()) + Turret_SelectState(); + + switch (m_State) + { + case 100: + m_pszDebugState = "Combat"; + State_Turret_Combat(); + break; + case 101: + m_pszDebugState = "Reacquire"; + State_Turret_Reacquire(); + break; + case 102: + m_pszDebugState = "TakeSniperNode"; + if (!PathExists() || PathComplete()) + { + AimAtEnemyBehavior(); + m_State = 103; + m_iStateTime = level.inttime; + } + else + { + FaceMotion(); + Anim_RunToDanger(3); + } + break; + case 103: + m_pszDebugState = "SniperNode"; + State_Turret_SniperNode(); + break; + case 104: + m_pszDebugState = "RunHome"; + State_Turret_RunHome(true); + break; + case 105: + m_pszDebugState = "RunAway"; + State_Turret_RunAway(); + break; + case 106: + m_pszDebugState = "Charge"; + State_Turret_Charge(); + break; + case 107: + m_pszDebugState = "Grenade"; + GenericGrenadeTossThink(); + break; + case 109: + m_pszDebugState = "FakeEnemy"; + State_Turret_FakeEnemy(); + break; + case 111: + m_pszDebugState = "BecomeCover"; + ContinueAnimation(); + break; + case 112: + m_pszDebugState = "Wait"; + State_Turret_Wait(); + break; + case 113: + m_pszDebugState = "Retarget_Sniper_Node"; + State_Turret_Retarget_Sniper_Node(); + break; + case 114: + m_pszDebugState = "Retarget_Step_Side_Small"; + State_Turret_Retarget_Step_Side_Small(); + break; + case 115: + m_pszDebugState = "Retarget_Path_Exact"; + AimAtEnemyBehavior(); + SetPathWithLeash(m_vLastEnemyPos, "", 0); + if (!ShortenPathToAttack(128.0f)) + { + Turret_NextRetarget(); + } + else + { + ShortenPathToAvoidSquadMates(); + if (PathExists()) + { + m_State = 101; + m_iStateTime = level.inttime; + } + else + { + Turret_NextRetarget(); + } + } + case 116: + m_pszDebugState = "Retarget_Path_Near"; + AimAtEnemyBehavior(); + FindPathNearWithLeash(m_vLastEnemyPos, m_fMinDistanceSquared); + if (ShortenPathToAttack(128.0f)) + { + m_State = 101; + m_iStateTime = level.inttime; + } + else + { + Turret_NextRetarget(); + } + break; + case 117: + m_pszDebugState = "Retarget_Step_Side_Medium"; + State_Turret_Retarget_Step_Side_Medium(); + break; + case 118: + m_pszDebugState = "Retarget_Step_Side_Large"; + State_Turret_Retarget_Step_Side_Large(); + break; + case 119: + m_pszDebugState = "Retarget_Step_Face_Medium"; + State_Turret_Retarget_Step_Face_Medium(); + break; + case 120: + m_pszDebugState = "Retarget_Step_Face_Large"; + State_Turret_Retarget_Step_Face_Large(); + break; + default: + Com_Printf("Actor::Think_Turret: invalid think state %i\n", m_State); + assert(!"invalid think state"); + break; + } + CheckForTransition(THINKSTATE_GRENADE, THINKLEVEL_NORMAL); + } + if (m_State == 112) + { + PostThink(false); + } + else + { + PostThink(true); + } } - - UpdateEyeOrigin(); - NoPoint(); - UpdateEnemy(200); - - // FIXME: stub - STUB(); } void Actor::FinishedAnimation_Turret @@ -157,7 +371,7 @@ void Actor::ReceiveAIEvent_Turret { m_State = 111; m_iStateTime = level.inttime; - SetThink(4, 2); + SetThink(THINKSTATE_ATTACK, THINK_COVER); } else if (pCoverNode) { @@ -280,14 +494,11 @@ void Actor::Turret_SelectState SetPath(m_vHome, "", 0, NULL, 0.0); ShortenPathToAvoidSquadMates(); - if (PathExists()) + if (PathExists() && !PathComplete()) { - if (!PathComplete()) - { - m_State = 104; - m_iStateTime = level.inttime; - return; - } + m_State = 104; + m_iStateTime = level.inttime; + return; } else { @@ -343,8 +554,8 @@ void Actor::Turret_SelectState if (DecideToThrowGrenade(m_Enemy->velocity + m_vLastEnemyPos, &m_vGrenadeVel, &m_eGrenadeMode)) { m_bNextForceStart = false; - m_YawAchieved = false; - m_DesiredYaw = vectoyaw(this->m_vGrenadeVel); + SetDesiredYawDir(m_vGrenadeVel); + m_eNextAnimMode = 1; m_State = 107; m_csNextAnimString = (m_eGrenadeMode == AI_GREN_TOSS_ROLL) ? STRING_ANIM_GRENADETOSS_SCR : STRING_ANIM_GRENADETHROW_SCR; @@ -380,13 +591,13 @@ bool Actor::Turret_TryToBecomeCoverGuy ) { - auto pCoverNode = this->m_pCoverNode; + auto pCoverNode = m_pCoverNode; Cover_FindCover(true); if (m_pCoverNode) { m_State = 111; m_iStateTime = level.inttime; - SetThink(4, 2); + SetThink(THINKSTATE_ATTACK, THINK_COVER); return true; } else @@ -644,7 +855,7 @@ bool Actor::State_Turret_RunHome { - SetPath(this->m_vHome, "", 0, NULL, 0.0); + SetPath(m_vHome, "", 0, NULL, 0.0); ShortenPathToAvoidSquadMates(); if (!PathExists() || PathComplete()) { @@ -700,7 +911,7 @@ void Actor::State_Turret_Charge ) { - SetPathWithLeash(this->m_vLastEnemyPos, "", 0); + SetPathWithLeash(m_vLastEnemyPos, "", 0); ShortenPathToAvoidSquadMates(); if (!PathExists()) { @@ -766,7 +977,7 @@ void Actor::State_Turret_FakeEnemy AimAtAimNode(); Anim_Aim(); if (level.inttime >= m_iStateTime) - SetThinkState(THINKSTATE_IDLE, 0); + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); } void Actor::State_Turret_Wait @@ -787,7 +998,7 @@ void Actor::State_Turret_Wait { m_State = 111; m_iStateTime = level.inttime; - SetThink(THINKSTATE_ATTACK, 2); + SetThink(THINKSTATE_ATTACK, THINK_COVER); bSmth = true; } else @@ -816,7 +1027,7 @@ void Actor::State_Turret_Wait { if (level.inttime >= m_iLastFaceDecideTime + 1500) { - this->m_iLastFaceDecideTime = level.inttime + (rand() & 0x1FF); + m_iLastFaceDecideTime = level.inttime + (rand() & 0x1FF); @@ -869,17 +1080,8 @@ void Actor::State_Turret_Retarget_Sniper_Node pSniperNode->Claim(this); m_State = 102; m_iStateTime = level.inttime; - if (PathExists() && !PathComplete()) - { - FaceMotion(); - Anim_RunToDanger(3); - } - else - { - AimAtEnemyBehavior(); - m_State = 103; - m_iStateTime = level.inttime; - } + + State_Turret_TakeSniperNode(); } else if (bTryAgain) { diff --git a/code/game/actor_weaponless.cpp b/code/game/actor_weaponless.cpp index ac6bcbab..b9aa68f0 100644 --- a/code/game/actor_weaponless.cpp +++ b/code/game/actor_weaponless.cpp @@ -61,6 +61,7 @@ void Actor::Begin_Weaponless } } m_State = 900; + m_iStateTime = level.inttime; } void Actor::Suspend_Weaponless @@ -100,7 +101,7 @@ void Actor::Think_Weaponless m_bLockThinkState = false; if (!m_Enemy) { - SetThinkState(1, 0); + SetThinkState(THINKSTATE_IDLE, THINKLEVEL_NORMAL); IdleThink(); return; } @@ -136,11 +137,11 @@ void Actor::Think_Weaponless } */ } - CheckForTransition(7, 0); + CheckForTransition(THINKSTATE_GRENADE, 0); } PostThink(true); if (GetWeapon(WEAPON_MAIN)) - SetThink(4, 1); + SetThink(THINKSTATE_ATTACK, THINK_TURRET); } } @@ -183,12 +184,11 @@ void Actor::State_Weaponless_Normal AimAtAimNode(); Anim_Stand(); - if (level.inttime >= this->m_iStateTime) + if (level.inttime >= m_iStateTime) { if (DecideToThrowGrenade(m_Enemy->velocity + m_Enemy->origin, &m_vGrenadeVel, &m_eGrenadeMode)) { - m_YawAchieved = false; - m_DesiredYaw = vectoyaw(m_vGrenadeVel); + SetDesiredYawDir(m_vGrenadeVel); m_State = 901; m_eNextAnimMode = 1; diff --git a/code/game/actorenemy.cpp b/code/game/actorenemy.cpp index b238fae3..435ec08a 100644 --- a/code/game/actorenemy.cpp +++ b/code/game/actorenemy.cpp @@ -29,7 +29,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ActorEnemy::ActorEnemy() { - //no need + m_pEnemy = NULL; + m_vLastKnownPos = vec_zero; } ActorEnemy::~ActorEnemy() @@ -81,8 +82,12 @@ int ActorEnemy::UpdateThreat ) { + //FIXME: macro static float fRangeThreatSquared[15]; static int iWeaponThreat[7][5]; + int iWeapon; + int iZone; + Vector vDelta; m_iThreat = 0; m_fCurrentRangeSquared = 1e38; @@ -94,10 +99,138 @@ int ActorEnemy::UpdateThreat if (m_bVisible == true) m_iThreat = 10500; + vDelta = m_pEnemy->origin - pSelf->origin; + m_fCurrentRangeSquared = vDelta.lengthSquared(); - // FIXME: stub - STUB(); - return NULL; + if (m_fCurrentRangeSquared >= 65536.0) + { + if (m_fCurrentRangeSquared >= 589824.0) + { + if (m_fCurrentRangeSquared >= 1638400.0) + { + if (m_fCurrentRangeSquared >= 4194304.0) + iZone = 4; + else + iZone = 3; + } + else + { + iZone = 2; + } + } + else + { + iZone = 1; + } + } + else + { + iZone = 0; + } + + Weapon *pEnemyWeapon = m_pEnemy->GetActiveWeapon(WEAPON_MAIN); + iWeapon = 0; + + if (pEnemyWeapon) + { + int iWeapClass = pEnemyWeapon->GetWeaponClass(); + if (iWeapClass & WEAPON_CLASS_PISTOL) + { + iWeapon = 1; + } + else if (iWeapClass & WEAPON_CLASS_RIFLE) + { + iWeapon = 2; + } + else if (iWeapClass & WEAPON_CLASS_SMG) + { + iWeapon = 3; + } + else if (iWeapClass & WEAPON_CLASS_MG) + { + iWeapon = 4; + } + else if(iWeapClass & WEAPON_CLASS_GRENADE) + { + iWeapon = 5; + } + else + { + iWeapon = 6; + } + } + + int i=0; + if (m_fCurrentRangeSquared > 4194304) + { + for (; i < 15 && fRangeThreatSquared[i] > m_fCurrentRangeSquared; i++) + { + } + } + + m_iThreat += iWeaponThreat[iZone][iWeapon] + m_pEnemy->m_iThreatBias + i; + + float fMinSafeDistSquared = 1.21 * pSelf->m_fMinDistanceSquared + 16384; + + if (m_fCurrentRangeSquared < fMinSafeDistSquared) + { + m_iThreat -= (sqrt(m_fCurrentRangeSquared / fMinSafeDistSquared) * 500) + 500; + } + + Vector vLine = m_vLastKnownPos - pSelf->origin; + float fDot = DotProduct2D(vLine, m_vLastKnownPos); + for (Sentient *pSquadMate = m_pEnemy->m_pNextSquadMate; pSquadMate != m_pEnemy; pSquadMate = pSquadMate->m_pNextSquadMate) + { + if (fDot > DotProduct2D(vLine, pSquadMate->origin)) + { + m_iThreat -= 4; + } + } + + Actor *pAEnemy = (Actor *)m_pEnemy.Pointer(); + if (pAEnemy->IsSubclassOfActor() && pAEnemy->m_ThinkState == THINKSTATE_PAIN) + { + m_iThreat -= 2; + } + + fDot = Vector::Dot(vDelta, pSelf->orientation[0]); + if (fDot <= 0 ) + { + if (m_fCurrentRangeSquared * 0.5 > Square(fDot)) + { + m_iThreat++; + } + } + else + { + if (m_fCurrentRangeSquared * 0.5 >= Square(fDot)) + { + if (m_fCurrentRangeSquared * 0.5 > Square(fDot)) + { + m_iThreat++; + } + } + } + int iEnemyDiscount = m_pEnemy->m_iAttackerCount; + + if (m_pEnemy == pSelf->m_Enemy) + { + iEnemyDiscount -= 2; + if (level.inttime < pSelf->m_iEnemyChangeTime + 1000) + m_iThreat += 5; + } + + if (iEnemyDiscount > 4) + iEnemyDiscount = 4; + m_iThreat -= iEnemyDiscount; + + if (m_pEnemy == pSelf->m_pLastAttacker) + { + m_iThreat += 5; + } + if (m_pEnemy == pSelf->m_FavoriteEnemy) + m_iThreat += 250; + return m_iThreat; } Sentient *ActorEnemy::GetEnemy @@ -224,9 +357,41 @@ ActorEnemy *ActorEnemySet::AddPotentialEnemy ) { - // FIXME: stub - STUB(); - return NULL; + ActorEnemy NewEnemy; + + if (pEnemy->IsDead() || pEnemy->m_iThreatBias == THREATBIAS_IGNOREME) + { + return NULL; + } + + for (int i = 0; i < m_Enemies.NumObjects(); i++) + { + ActorEnemy *pActorEnemy = &m_Enemies[i]; + if (pActorEnemy->m_pEnemy == pEnemy) + { + pActorEnemy->m_iAddTime = level.inttime; + return pActorEnemy; + } + } + + NewEnemy.m_fVisibility = 0.0; + NewEnemy.m_fTotalVisibility = 0.0; + NewEnemy.m_iAddTime = level.inttime; + NewEnemy.m_fLastLookTime = level.time; + NewEnemy.m_iThreat = 0; + + NewEnemy.m_pEnemy = pEnemy; + + NewEnemy.m_fCurrentRangeSquared = 1e38; + + NewEnemy.m_iLastSightChangeTime = 0; + NewEnemy.m_vLastKnownPos = vec_zero; + + NewEnemy.m_bVisible = false; + + + + return &m_Enemies[m_Enemies.AddObject(NewEnemy)-1]; } void ActorEnemySet::FlagBadEnemy @@ -235,8 +400,37 @@ void ActorEnemySet::FlagBadEnemy ) { - // FIXME: stub - STUB(); + ActorEnemy *pActorEnemy; + for (int i = 0; i < m_Enemies.NumObjects(); i++) + { + pActorEnemy = &m_Enemies[i]; + if (pActorEnemy->m_pEnemy == pEnemy) + { + break; + } + + if (i+1 == m_Enemies.NumObjects()) + return; + } + + pActorEnemy->m_iThreat = 0; + pActorEnemy->m_fVisibility = 0.0; + pActorEnemy->m_fTotalVisibility = 0.0; + pActorEnemy->m_fLastLookTime = level.time; + + pActorEnemy->m_bVisible = false; + pActorEnemy->m_iLastSightChangeTime = level.inttime; + + if (pEnemy == m_pCurrentEnemy) + { + if (m_pCurrentEnemy) + { + delete m_pCurrentEnemy; + m_pCurrentEnemy = NULL; + } + m_fCurrentVisibility = 0.0; + m_iCurrentThreat = 0; + } } void ActorEnemySet::CheckEnemies @@ -245,8 +439,148 @@ void ActorEnemySet::CheckEnemies ) { - // FIXME: stub - STUB(); + float fRangeSquared; + bool bVisible; + bool bInFovAndRange = false; + int nChecked; + int iThreat; + float fVisibility; + + ActorEnemy *pActorEnemy; + for (int i = 1; i < m_Enemies.NumObjects();i++) + { + pActorEnemy = &m_Enemies[i]; + if (!pActorEnemy->m_pEnemy + || pActorEnemy->m_pEnemy->m_Team != pSelf->m_Team + || pActorEnemy->m_pEnemy->IsDead() + || level.inttime > pActorEnemy->m_iAddTime + 10000 + || pActorEnemy->m_pEnemy->m_iThreatBias == THREATBIAS_IGNOREME) + { + m_Enemies.RemoveObjectAt(i); + i--; + } + } + if (!m_Enemies.NumObjects()) + { + m_iCurrentThreat = 0; + if (m_pCurrentEnemy) + { + delete m_pCurrentEnemy; + m_pCurrentEnemy = NULL; + } + } + else + { + for (int i = 0; !bInFovAndRange && i < m_Enemies.NumObjects(); i++) + { + m_iCheckCount++; + if (m_iCheckCount > m_Enemies.NumObjects()) + m_iCheckCount = 1; + + pActorEnemy = &m_Enemies[m_iCheckCount-1]; + + fVisibility = pActorEnemy->UpdateVisibility(pSelf, &bInFovAndRange, &bVisible); + if (fVisibility <= 0.0) + { + if (pActorEnemy->m_pEnemy == m_pCurrentEnemy) + { + m_iCurrentThreat = 0; + if (m_pCurrentEnemy) + { + delete m_pCurrentEnemy; + m_pCurrentEnemy = NULL; + } + m_fCurrentVisibility = 0.0; + } + } + else + { + if (fVisibility < m_fCurrentVisibility) + { + if (pActorEnemy->m_pEnemy == m_pCurrentEnemy) + { + m_iCurrentThreat = 0; + if (m_pCurrentEnemy) + { + delete m_pCurrentEnemy; + m_pCurrentEnemy = NULL; + } + m_fCurrentVisibility = fVisibility; + } + } + else + { + m_pCurrentEnemy = pActorEnemy->m_pEnemy; + } + + if (g_showawareness->integer) + { + Com_Printf( + "ent #%3i: enemy #%i: awareness = %5.1f%%, threat = %i\n", + pSelf->entnum, + pActorEnemy->m_pEnemy->entnum, + (fVisibility * 100.0), + 0); + } + } + + if (bVisible) + { + if (!pActorEnemy->m_bVisible) + { + pActorEnemy->m_bVisible = true; + pActorEnemy->m_iLastSightChangeTime = level.inttime; + } + pActorEnemy->m_vLastKnownPos = pActorEnemy->m_pEnemy->origin; + } + else if (pActorEnemy->m_bVisible) + { + pActorEnemy->m_bVisible = false; + pActorEnemy->m_iLastSightChangeTime = level.inttime; + } + } + + if (m_pCurrentEnemy && m_pCurrentEnemy->IsDead()) + { + if (m_pCurrentEnemy) + { + delete m_pCurrentEnemy; + m_pCurrentEnemy = NULL; + } + m_iCurrentThreat = 0; + m_fCurrentVisibility = 0.0; + } + + m_iCurrentThreat = 0; + + fRangeSquared = 1e37; + + if (m_fCurrentVisibility >= 1) + { + for (int i = 0;i < m_Enemies.NumObjects(); i++) + { + pActorEnemy = &m_Enemies[i]; + pActorEnemy->UpdateThreat(pSelf); + if (m_iCurrentThreat < pActorEnemy->m_iThreat || m_iCheckCount == pActorEnemy->m_iThreat && fRangeSquared > pActorEnemy->m_fCurrentRangeSquared) + { + m_iCurrentThreat = pActorEnemy->m_iThreat; + m_pCurrentEnemy = pActorEnemy->m_pEnemy; + fRangeSquared = pActorEnemy->m_fCurrentRangeSquared; + } + } + } + + if ((!m_pCurrentEnemy || !m_pCurrentEnemy->m_bIsDisguised) && m_iCurrentThreat <= 0) + { + if (m_pCurrentEnemy) + { + delete m_pCurrentEnemy; + m_pCurrentEnemy = NULL; + } + m_iCurrentThreat = 0; + m_fCurrentVisibility = 0.0; + } + } } Sentient *ActorEnemySet::GetCurrentEnemy @@ -282,7 +616,7 @@ qboolean ActorEnemySet::IsEnemyConfirmed ) const { - // FIXME: stub + // not found in ida STUB(); return false; } @@ -293,8 +627,15 @@ bool ActorEnemySet::HasAlternateEnemy ) const { - // FIXME: stub - STUB(); + ActorEnemy *pActorEnemy; + for (int i = 0; i < m_Enemies.NumObjects(); i++) + { + pActorEnemy = &m_Enemies[i]; + if (pActorEnemy->m_pEnemy != m_pCurrentEnemy) + { + return true; + } + } return false; } @@ -304,8 +645,15 @@ void ActorEnemySet::RemoveAll ) { - // FIXME: stub - STUB(); + m_Enemies.ClearObjectList(); + m_iCheckCount = 0; + if (m_pCurrentEnemy) + { + delete m_pCurrentEnemy; + m_pCurrentEnemy = NULL; + } + m_fCurrentVisibility = 0.0; + m_iCurrentThreat = 0; } void ActorEnemySet::ConfirmEnemy @@ -315,8 +663,20 @@ void ActorEnemySet::ConfirmEnemy ) { - // FIXME: stub - STUB(); + pSelf->m_bEnemyIsDisguised = false; + ActorEnemy *pActorEnemy = ActorEnemySet::AddPotentialEnemy(pEnemy); + if (pActorEnemy) + { + pActorEnemy->m_fVisibility = 1.0; + pActorEnemy->m_fTotalVisibility = 1.0; + pActorEnemy->m_vLastKnownPos = pEnemy->origin; + if (m_fCurrentVisibility < 1.0) + { + m_iCurrentThreat = pActorEnemy->UpdateThreat(pSelf); + m_fCurrentVisibility = 1.0; + m_pCurrentEnemy = pEnemy; + } + } } void ActorEnemySet::ConfirmEnemyIfCanSeeSharerOrEnemy @@ -327,8 +687,33 @@ void ActorEnemySet::ConfirmEnemyIfCanSeeSharerOrEnemy ) { - // FIXME: stub - STUB(); + pSelf->m_bEnemyIsDisguised = false; + ActorEnemy *pActorEnemy = ActorEnemySet::AddPotentialEnemy(pEnemy); + if (pActorEnemy) + { + if (pActorEnemy->m_fTotalVisibility > 0) + { + pActorEnemy->m_vLastKnownPos = pEnemy->origin; + return; + } + if (!pActorEnemy->m_bVisible) + { + if (!pSelf->CanSee( + pSharer, + pSelf->m_bSilent ? 1119092736 : NULL, + 0.828 * world->farplane_distance)) + return; + } + pActorEnemy->m_fVisibility = 1.0; + pActorEnemy->m_fTotalVisibility = 1.0; + pActorEnemy->m_vLastKnownPos = pEnemy->origin; + if (m_fCurrentVisibility < 1.0) + { + m_iCurrentThreat = pActorEnemy->UpdateThreat(pSelf); + m_fCurrentVisibility = 1.0; + m_pCurrentEnemy = pEnemy; + } + } } bool ActorEnemySet::CaresAboutPerfectInfo @@ -337,7 +722,13 @@ bool ActorEnemySet::CaresAboutPerfectInfo ) { - // FIXME: stub - STUB(); + ActorEnemy *pActorEnemy = ActorEnemySet::AddPotentialEnemy(pEnemy); + if (pActorEnemy) + { + if (pActorEnemy->m_fTotalVisibility < 1.0 || (pEnemy->origin - pActorEnemy->m_vLastKnownPos).lengthSquared() > 262144) + { + return true; + } + } return false; } diff --git a/code/game/actorenemy.h b/code/game/actorenemy.h index 65e7e471..292f3147 100644 --- a/code/game/actorenemy.h +++ b/code/game/actorenemy.h @@ -22,6 +22,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // actorenemy.h +#ifndef __ACTORENEMY_H__ +#define __ACTORENEMY_H__ + #include "g_local.h" class Actor; @@ -116,3 +119,5 @@ inline void ActorEnemySet::Archive arc.ArchiveFloat( &m_fCurrentVisibility ); arc.ArchiveInteger( &m_iCurrentThreat ); } + +#endif /* actorenemy.h */ \ No newline at end of file diff --git a/code/game/actorpath.cpp b/code/game/actorpath.cpp index b5aae8dd..1e6332fb 100644 --- a/code/game/actorpath.cpp +++ b/code/game/actorpath.cpp @@ -63,7 +63,7 @@ bool ActorPath::DoesTheoreticPathExist float maxPath, float *vLeashHome, float fLeashDistSquared - ) const + ) { return PathSearch::FindPath( start, end, ent, maxPath, NULL, 0, m_FallHeight ) != 0; diff --git a/code/game/actorpath.h b/code/game/actorpath.h index 91005e86..709a1a67 100644 --- a/code/game/actorpath.h +++ b/code/game/actorpath.h @@ -55,7 +55,7 @@ public: ~ActorPath(); void Clear( void ); - bool DoesTheoreticPathExist( float *start, float *end, class SimpleActor *ent, float maxPath, float *vLeashHome, float fLeashDistSquared ) const; + bool DoesTheoreticPathExist( float *start, float *end, class SimpleActor *ent, float maxPath, float *vLeashHome, float fLeashDistSquared ); void FindPath( float *start, float *end, Entity *ent, float maxPath, float *vLeashHome, float fLeashDistSquared ); void FindPathAway( float *start, float *avoid, float *vPreferredDir, Entity *ent, float fMinSafeDist, float *vLeashHome, float fLeashDistSquared ); void FindPathNear( float *start, float *nearby, Entity *ent, float maxPath, float fRadiusSquared, float *vLeashHome, float fLeashDistSquared ); diff --git a/code/game/g_client.cpp b/code/game/g_client.cpp index bc773fcf..6c83b880 100644 --- a/code/game/g_client.cpp +++ b/code/game/g_client.cpp @@ -957,6 +957,7 @@ void G_ClientBegin( gentity_t *ent, usercmd_t *cmd ) if( ent->inuse && ent->entity ) { + VectorClear(ent->client->cmd_angles); // the client has cleared the client side viewangles upon // connecting to the server, which is different than the // state when the game is saved, so we need to compensate diff --git a/code/game/game.cpp b/code/game/game.cpp index d275a5a5..223b5eb7 100644 --- a/code/game/game.cpp +++ b/code/game/game.cpp @@ -464,23 +464,52 @@ SimpleEntity *G_FindTarget( SimpleEntity *ent, const char *name ) SimpleEntity *G_FindRandomSimpleTarget( const char *name ) { - SimpleEntity *found = NULL, *ent = NULL; + SimpleEntity *found = NULL, *ent = world; + int nFound = 0; + if (name && *name) { - while (1) + while (true) { ent = world->GetNextEntity(name, ent); if (!ent) { break; } - rand(); - found = ent; + + if (++nFound * rand() <= 0x7FFF) + { + found = ent; + } } } return found; } +Entity *G_FindRandomTarget( const char *name ) +{ + SimpleEntity *found = NULL, *ent = world; + int nFound = 0; + + if (name && *name) + { + while (true) + { + ent = world->GetNextEntity(name, ent); + if (!ent) + { + break; + } + + if (ent->IsSubclassOfEntity() && ++nFound * rand() <= 0x7FFF) + { + found = ent; + } + } + } + return (Entity *)found; +} + void G_TouchTriggers( Entity *ent ) { int i; diff --git a/code/game/game.h b/code/game/game.h index a7d13621..6acb5e00 100644 --- a/code/game/game.h +++ b/code/game/game.h @@ -141,6 +141,14 @@ SimpleEntity *G_FindRandomSimpleTarget( const char *name ); +/* G_FindRandomSimpleTarget +* +* Find a random entity with the specified targetname. +*/ +Entity *G_FindRandomTarget( + const char *name +); + /* G_GetClientNumber * * Gets the specified client number from an entity. diff --git a/code/game/level.cpp b/code/game/level.cpp index f0ceee8b..49ca4c62 100644 --- a/code/game/level.cpp +++ b/code/game/level.cpp @@ -1095,7 +1095,7 @@ void Level::CleanUp( qboolean samemap, qboolean resetConfigStrings ) // Reset the boss health cvar gi.Cvar_Set( "bosshealth", "0" ); - // FIXME: Actor::ResetBodyQueue(); + Actor::ResetBodyQueue(); if( world ) { world->FreeTargetList(); diff --git a/code/game/player.cpp b/code/game/player.cpp index a2e43b60..aec5bcdf 100644 --- a/code/game/player.cpp +++ b/code/game/player.cpp @@ -7206,7 +7206,7 @@ void Player::Think { Actor *act = ( Actor * )pSent; - if( pSent->m_Enemy == this && act->m_ThinkStates[ 0 ] == THINKSTATE_ATTACK ) + if( pSent->m_Enemy == this && act->IsAttacking()) { m_bIsDisguised = false; break; diff --git a/code/game/sentient.cpp b/code/game/sentient.cpp index acc670b5..4be391c3 100644 --- a/code/game/sentient.cpp +++ b/code/game/sentient.cpp @@ -4256,7 +4256,7 @@ void Sentient::EventSetThreatBias if( !Q_stricmp( sBias, "ignoreme" ) ) { - m_iThreatBias = 0xFFFFE4C7; + m_iThreatBias = THREATBIAS_IGNOREME; return; } } @@ -4560,7 +4560,7 @@ void Sentient::UpdateFootsteps iAnimFlags |= gi.Anim_Flags(edict->tiki, iAnimNum); } } - + //FIXME: macros if ((iAnimFlags & 0xC00) != 3072) { diff --git a/code/game/sentient.h b/code/game/sentient.h index e8b128f5..9e4fcb28 100644 --- a/code/game/sentient.h +++ b/code/game/sentient.h @@ -87,6 +87,7 @@ class Item; class InventoryItem; class Ammo; class Vehicle; +class VehicleTank; class TurretGun; #define MAX_ACTIVE_WEAPONS NUM_ACTIVE_WEAPONS @@ -95,6 +96,8 @@ class TurretGun; #define TEAM_GERMAN 0 #define TEAM_AMERICAN 1 +#define THREATBIAS_IGNOREME 0xFFFFE4C7 + typedef SafePtr< Weapon > WeaponPtr; class ActiveWeapon : public Class @@ -342,9 +345,9 @@ class Sentient : public Animate void PutawayWeapon( Event *ev ); void WeaponCommand( Event *ev ); - + VehicleTank *GetVehicleTank( void ); - + void UpdateFootsteps( void ); void SetMaxMouthAngle( Event *ev ); diff --git a/code/game/simpleactor.cpp b/code/game/simpleactor.cpp index ff7db66c..23d54ec2 100644 --- a/code/game/simpleactor.cpp +++ b/code/game/simpleactor.cpp @@ -22,7 +22,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // simpleactor.cpp: Base class for character AI -#include "simpleactor.h" +#include "actor.h" +#include "bg_local.h" CLASS_DECLARATION( Sentient, SimpleActor, NULL ) { @@ -38,13 +39,13 @@ SimpleActor::SimpleActor() m_AnimMotionHigh = true; m_DesiredGunDir = vec_zero; - m_eEmotionMode = 1; + m_eEmotionMode = EMOTION_NEUTRAL; m_eNextAnimMode = -1; m_fPathGoalTime = 0.0f; m_csPathGoalEndAnimScript = STRING_EMPTY; - m_AnimActionHigh = 1; - m_AnimDialogHigh = 1; + m_AnimActionHigh = true; + m_AnimDialogHigh = true; m_fAimLimit_up = 60.0f; m_fAimLimit_down = -60.0f; @@ -142,7 +143,8 @@ void SimpleActor::Archive Director.ArchiveString( arc, m_csMood ); Director.ArchiveString( arc, m_csIdleMood ); - arc.ArchiveInteger( &m_eEmotionMode ); + + ArchiveEnum(m_eEmotionMode, eEmotionMode); arc.ArchiveFloat( &m_fAimLimit_up ); arc.ArchiveFloat( &m_fAimLimit_down ); @@ -238,7 +240,7 @@ void SimpleActor::StopAnimating { int index = 0; - groundplane.normal[ slot ] = 0; + m_weightType[ slot ] = 0; DoExitCommands( slot ); if( edict->s.frameInfo[ slot ].index || gi.TIKI_NumAnims( edict->tiki ) <= 1 ) @@ -273,7 +275,7 @@ bool SimpleActor::CanTarget { OVERLOADED_ERROR(); - return 0; + return false; } bool SimpleActor::IsImmortal @@ -283,7 +285,7 @@ bool SimpleActor::IsImmortal { OVERLOADED_ERROR(); - return 0; + return false; } bool SimpleActor::DoesTheoreticPathExist @@ -293,7 +295,7 @@ bool SimpleActor::DoesTheoreticPathExist ) { - return m_Path.DoesTheoreticPathExist( origin, vDestPos, this, fMaxPath, 0, 0 ); + return m_Path.DoesTheoreticPathExist( origin, vDestPos, this, fMaxPath, NULL, 0 ); } void SimpleActor::SetPath @@ -306,8 +308,50 @@ void SimpleActor::SetPath ) { - // FIXME: stub - STUB(); + if (!PathExists() + || ((level.inttime >= m_Path.Time() + iMaxDirtyTime + || m_Path.Complete(origin)) && m_Path.LastNode()->point != vDestPos) + ) + { + m_Path.FindPath(origin, + vDestPos, + this, + 0.0, + vLeashHome, + fLeashDistSquared); + + if (!m_Path.LastNode()) + { + if (g_patherror->integer) + { + if (description) + { + int thinkState = ((Actor *)this)->m_ThinkState; + if (g_patherror->integer == 1 || g_patherror->integer == 2 && (thinkState == THINKSTATE_IDLE || thinkState == THINKSTATE_CURIOUS)) + { + if (m_bPathErrorTime + 5000 < level.inttime) + { + m_bPathErrorTime = level.inttime; + Com_Printf( + "^~^~^ Path not found in '%s' for (entnum %d, radnum %d, targetname '%s') from (%f %f %f) to (%f %f %f)\n", + description, + entnum, + radnum, + targetname.c_str(), + origin.x, + origin.y, + origin.z, + vDestPos.x, + vDestPos.y, + vDestPos.z + ); + Com_Printf("Reason: %s\n", PathSearch::last_error); + } + } + } + } + } + } } void SimpleActor::SetPath @@ -318,8 +362,29 @@ void SimpleActor::SetPath ) { - // FIXME: stub - STUB(); + if (pDestNode) + { + SetPath( + pDestNode->origin, + description, + iMaxDirtyTime, + NULL, + 0.0); + } + else + { + if (m_bPathErrorTime + 5000 < level.inttime) + { + m_bPathErrorTime = level.inttime; + Com_Printf( + "^~^~^ No destination node specified for '%s' at (%f %f %f)\n", + targetname.c_str(), + origin.x, + origin.y, + origin.z); + } + ClearPath(); + } } void SimpleActor::SetPathWithinDistance @@ -331,20 +396,60 @@ void SimpleActor::SetPathWithinDistance ) { - // FIXME: stub - STUB(); + if (!PathExists() + || ((level.inttime >= m_Path.Time() + iMaxDirtyTime + || m_Path.Complete(origin)) && m_Path.LastNode()->point != vDestPos) + ) + { + m_Path.FindPath(origin, + vDestPos, + this, + fMaxPath, + NULL, + 0); + + if (!m_Path.LastNode()) + { + if (g_patherror->integer) + { + if (description) + { + int thinkState = ((Actor *)this)->m_ThinkState; + if (g_patherror->integer == 1 || g_patherror->integer == 2 && (thinkState == THINKSTATE_IDLE || thinkState == THINKSTATE_CURIOUS)) + { + if (m_bPathErrorTime + 5000 < level.inttime) + { + m_bPathErrorTime = level.inttime; + Com_Printf( + "^~^~^ Path not found in '%s' for '%s' from (%f %f %f) to (%f %f %f)\n", + description, + targetname.c_str(), + origin.x, + origin.y, + origin.z, + vDestPos.x, + vDestPos.y, + vDestPos.z); + Com_Printf("Reason: %s\n", PathSearch::last_error); + } + } + } + } + } + } } void SimpleActor::FindPathAway ( - vec3_t vAwayFrom, - vec3_t vDirPreferred, + vec_t *vAwayFrom, + vec_t *vDirPreferred, float fMinSafeDist ) { - // FIXME: stub - STUB(); + m_Path.FindPathAway(origin, vAwayFrom, vDirPreferred, this, fMinSafeDist, NULL, 0); + + ShortenPathToAvoidSquadMates(); } void SimpleActor::ClearPath @@ -353,8 +458,7 @@ void SimpleActor::ClearPath ) { - // FIXME: stub - STUB(); + m_Path.Clear(); } bool SimpleActor::PathComplete @@ -396,6 +500,13 @@ bool SimpleActor::PathAvoidsSquadMates ) const { + if (ai_pathchecktime->value <= 0.0) + return true; + + if ((G_GetEntity(0)->origin - origin).lengthXY(true) > Square(ai_pathcheckdist->value)) + { + return true; + } // FIXME: stub STUB(); return false; @@ -407,8 +518,44 @@ void SimpleActor::ShortenPathToAvoidSquadMates ) { - // FIXME: stub - STUB(); + if (PathExists() && !PathComplete()) + { + Vector vBuddyPos; + Vector vDelta; + do + { + Actor *pSquadMate = (Actor *)m_pNextSquadMate.Pointer(); + if (pSquadMate == this) + { + break; + } + + while (true) + { + vBuddyPos = pSquadMate->origin; + if (pSquadMate->IsSubclassOfActor() && pSquadMate->PathExists()) + { + vBuddyPos = pSquadMate->LastPathNode()->point; + } + vDelta.x = LastPathNode()->point[0] - vBuddyPos.x; + if (vDelta.x >= -15.0 && vDelta.x <= 15.0) + { + vDelta.y = LastPathNode()->point[1] - vBuddyPos.y; + vDelta.z = LastPathNode()->point[2] - vBuddyPos.z; + + if (vDelta.y >= -15.0 && vDelta.y <= 15.0 && vDelta.z >= 0.0 && vDelta.z <= 94.0) + break; + } + pSquadMate = (Actor *)pSquadMate->m_pNextSquadMate.Pointer(); + if (pSquadMate == this) + { + return; + } + } + m_Path.Shorten(45.0); + + } while (PathExists()); + } } PathInfo *SimpleActor::CurrentPathNode @@ -480,8 +627,7 @@ void SimpleActor::SetDest ) { - // FIXME: stub - STUB(); + VectorCopy(m_Dest, dest); } void SimpleActor::StopTurning @@ -490,7 +636,7 @@ void SimpleActor::StopTurning ) { - // FIXME: stub + // not found in ida STUB(); } @@ -520,8 +666,8 @@ void SimpleActor::SetDesiredYawDest ) { - // FIXME: stub - STUB(); + m_bHasDesiredLookDest = true; + VectorCopy(vec, m_vDesiredLookDest); } void SimpleActor::UpdateEmotion @@ -530,8 +676,27 @@ void SimpleActor::UpdateEmotion ) { - // FIXME: stub - STUB(); + int anim; + if (IsDead()) + { + m_eEmotionMode = EMOTION_DEAD; + } + + anim = GetEmotionAnim(); + + if (anim == -1) + { + Com_Printf( + "Failed to set emotion for (entnum %d, radnum %d, targetname '%s'\n", + entnum, + radnum, + targetname.c_str()); + } + else + { + m_bSayAnimSet = true; + StartSayAnimSlot(anim); + } } int SimpleActor::GetEmotionAnim @@ -540,9 +705,99 @@ int SimpleActor::GetEmotionAnim ) { - // FIXME: stub - STUB(); - return 0; + char *emotionanim = NULL; + int anim; + + if (m_eEmotionMode) + { + switch (m_eEmotionMode) + { + case EMOTION_NEUTRAL: + case EMOTION_AIMING: + emotionanim = "facial_idle_neutral"; + case EMOTION_WORRY: + emotionanim = "facial_idle_worry"; + case EMOTION_PANIC: + emotionanim = "facial_idle_panic"; + case EMOTION_FEAR: + emotionanim = "facial_idle_fear"; + case EMOTION_DISGUST: + emotionanim = "facial_idle_disgust"; + case EMOTION_ANGER: + emotionanim = "facial_idle_anger"; + case EMOTION_DETERMINED: + case EMOTION_CURIOUS: + emotionanim = "facial_idle_determined"; + case EMOTION_DEAD: + emotionanim = "facial_idle_dead"; + default: + assert(!"Unknown value for m_EmotionMode"); + /* + *useless assert + if (dword_39AFB8) + return -1; + v8 = 16308; + qmemcpy(&v11, "\"Unknown value for m_EmotionMode in SimpleActor::GetEmotionAnim\"\n\tMessage: ", 0x4Cu); + v9 = &v13; + if (&v13 & 4) + { + v9 = &v14; + v8 = 16304; + v13 = 0; + } + memset32(v9, dword_39AFB8, v8 >> 2); + v10 = (*(this->baseSentient.baseAnimate.baseEntity.baseSimple.baseListener.baseClass.vftable + 87))( + this, + &nullStr); + Q_strcat(&v11, 0x4000, v10); + v5 = MyAssertHandler(&v11, "fgame/simpleactor.cpp", 1529, 0); + if (v5 >= 0) + goto LABEL_9; + dword_39AFB8 = 1;*/ + return -1; + break; + } + } + else + { + if (m_csMood == STRING_NERVOUS) + { + emotionanim = "facial_idle_determined"; + } + else if (m_csMood <= STRING_NERVOUS) + { + if (m_csMood != STRING_BORED) + { + assert(!"Unknown value for m_csMood"); + return -1; + } + + emotionanim = "facial_idle_neutral"; + } + else if (m_csMood == STRING_CURIOUS) + { + emotionanim = "facial_idle_determined"; + } + else if (m_csMood != STRING_ALERT) + { + assert(!"Unknown value for m_csMood"); + return -1; + } + } + + if (emotionanim == NULL) + { + emotionanim = "facial_idle_anger"; + assert(!"Unexpected behaviour in SimpleActor::GetEmotionAnim"); + } + + anim = gi.Anim_NumForName(edict->tiki, emotionanim); + if (anim == -1) + Com_Printf( + "^~^~^ SimpleActor::GetEmotionAnim: unknown animation '%s' in '%s'\n", + emotionanim, + edict->tiki->a->name); + return anim; } int SimpleActor::GetMotionSlot @@ -575,7 +830,7 @@ int SimpleActor::GetSaySlot ) { - return m_AnimDialogHigh ? 12 : 11; + return m_AnimDialogHigh ? 13 : 12; } void SimpleActor::StartCrossBlendAnimSlot @@ -584,8 +839,21 @@ void SimpleActor::StartCrossBlendAnimSlot ) { - // FIXME: stub - STUB(); + if (m_weightType[slot] == 1) + { + m_weightType[slot] = 4; + } + else + { + if (m_weightType[slot] < 1) + return; + if (m_weightType[slot] == 6) + m_weightType[slot] = 5; + else + m_weightType[slot] = 3; + } + m_weightCrossBlend[slot] = 1.0; + m_weightBase[slot] = edict->s.frameInfo[slot].weight; } void SimpleActor::StartMotionAnimSlot @@ -596,8 +864,18 @@ void SimpleActor::StartMotionAnimSlot ) { - // FIXME: stub - STUB(); + int iSlot = GetMotionSlot(slot); + + m_weightCrossBlend[iSlot] = 0.0; + m_weightType[iSlot] = 1; + m_weightBase[iSlot] = weight; + + NewAnim(anim, iSlot, 1.0); + animFlags[iSlot] |= ANIM_NOACTION; + + SetTime(iSlot, 0.0); + + UpdateNormalAnimSlot(iSlot); } void SimpleActor::StartAimMotionAnimSlot @@ -607,8 +885,17 @@ void SimpleActor::StartAimMotionAnimSlot ) { - // FIXME: stub - STUB(); + int iSlot = GetMotionSlot(slot); + + m_weightCrossBlend[iSlot] = 0.0; + m_weightType[iSlot] = 1; + + NewAnim(anim, iSlot, 1.0); + animFlags[iSlot] |= ANIM_NOACTION; + + SetTime(iSlot, 0.0); + + UpdateNormalAnimSlot(iSlot); } void SimpleActor::StartActionAnimSlot @@ -617,8 +904,17 @@ void SimpleActor::StartActionAnimSlot ) { - // FIXME: stub - STUB(); + int iSlot = GetActionSlot(0); + + m_weightCrossBlend[iSlot] = 0.0; + m_weightType[iSlot] = 2; + m_weightBase[iSlot] = 1.0; + + NewAnim(anim, iSlot, 1.0); + + SetTime(iSlot, 0.0); + + UpdateNormalAnimSlot(iSlot); } void SimpleActor::StartSayAnimSlot @@ -627,8 +923,17 @@ void SimpleActor::StartSayAnimSlot ) { - // FIXME: stub - STUB(); + int iSlot = GetSaySlot(); + + m_weightCrossBlend[iSlot] = 0.0; + m_weightType[iSlot] = 6; + m_weightBase[iSlot] = 1.0; + + NewAnim(anim, iSlot, 1.0); + animFlags[iSlot] |= ANIM_NOACTION; + + SetTime(iSlot, 0.0); + UpdateSayAnimSlot(); } void SimpleActor::StartAimAnimSlot @@ -638,8 +943,16 @@ void SimpleActor::StartAimAnimSlot ) { - // FIXME: stub - STUB(); + int iSlot = GetActionSlot(slot); + + m_weightCrossBlend[iSlot] = 0.0; + m_weightType[iSlot] = 7; + + NewAnim(anim, iSlot, 1.0); + + SetTime(iSlot, 0.0); + + UpdateNormalAnimSlot(iSlot); } void SimpleActor::SetBlendedWeight @@ -648,8 +961,18 @@ void SimpleActor::SetBlendedWeight ) { - // FIXME: stub - STUB(); + m_bUpdateAnimDoneFlags |= 1 << slot; + if (m_weightCrossBlend[slot] < 1.0) + { + edict->s.frameInfo[slot].weight = (3.0 - m_weightCrossBlend[slot] - m_weightCrossBlend[slot]) + * Square(m_weightCrossBlend[slot]) + * m_weightBase[slot]; + } + else + { + m_weightCrossBlend[slot] = 1.0; + edict->s.frameInfo[slot].weight = m_weightBase[slot]; + } } void SimpleActor::EventSetAnimLength @@ -658,8 +981,48 @@ void SimpleActor::EventSetAnimLength ) { - // FIXME: stub - STUB(); + int slot; + float length; + + if (ev->NumArgs() != 1) + { + ScriptError("bad number of arguments"); + } + + length = ev->GetFloat(1); + + if (length <= 0) + { + ScriptError("Positive lengths only allowed"); + } + + if (m_bMotionAnimSet) + { + ScriptError("Must set anim before length"); + } + + slot = GetMotionSlot(0); + + if (animFlags[slot] & ANIM_LOOP) + { + gi.Anim_Frametime(edict->tiki, edict->s.frameInfo[slot].index); + + animFlags[slot] = (animFlags[slot] | ANIM_NODELTA) & ~ANIM_FINISHED; + + animtimes[slot] = Square(gi.Anim_NumFrames(edict->tiki, edict->s.frameInfo[slot].index) - 1); + + SetOnceType(slot); + } + + SetSyncTime(0); + + if (length > animtimes[slot]) + { + ScriptError("cannot lengthen animation which has length %f", animtimes[slot]); + } + + animtimes[slot] = length; + animFlags[slot] = (animFlags[slot] | ANIM_NODELTA) & ~ANIM_FINISHED; } void SimpleActor::UpdateNormalAnimSlot @@ -668,8 +1031,9 @@ void SimpleActor::UpdateNormalAnimSlot ) { - // FIXME: stub - STUB(); + m_weightCrossBlend[slot] += m_fCrossblendTime == 0.0 ? 1.0 : level.frametime / m_fCrossblendTime; + + SetBlendedWeight(slot); } void SimpleActor::UpdateCrossBlendAnimSlot @@ -678,8 +1042,17 @@ void SimpleActor::UpdateCrossBlendAnimSlot ) { - // FIXME: stub - STUB(); + m_weightCrossBlend[slot] -= m_fCrossblendTime == 0.0 ? 1.0 : level.frametime / m_fCrossblendTime; + + if (m_weightCrossBlend[slot] > 0.0) + { + SetBlendedWeight(slot); + } + else + { + m_weightType[slot] = 8; + edict->s.frameInfo[slot].weight = 0.0; + } } void SimpleActor::UpdateCrossBlendDialogAnimSlot @@ -688,8 +1061,17 @@ void SimpleActor::UpdateCrossBlendDialogAnimSlot ) { - // FIXME: stub - STUB(); + m_weightCrossBlend[slot] -= m_iSaySlot < 0 ? level.frametime + level.frametime : level.frametime / 0.1; + + if (m_weightCrossBlend[slot] > 0.0) + { + SetBlendedWeight(slot); + } + else + { + m_weightType[slot] = 8; + edict->s.frameInfo[slot].weight = 0.0; + } } void SimpleActor::UpdateSayAnimSlot @@ -698,8 +1080,9 @@ void SimpleActor::UpdateSayAnimSlot ) { - // FIXME: stub - STUB(); + m_weightCrossBlend[slot] += m_iSaySlot < 0 ? level.frametime + level.frametime : level.frametime / 0.1; + + SetBlendedWeight(slot); } void SimpleActor::UpdateLastFrameSlot @@ -708,8 +1091,19 @@ void SimpleActor::UpdateLastFrameSlot ) { - // FIXME: stub - STUB(); + m_weightType[slot] = 0; + DoExitCommands(slot); + + if (edict->s.frameInfo[slot].index || gi.TIKI_NumAnims(edict->tiki) <= 1) + edict->s.frameInfo[slot].index = 0; + else + edict->s.frameInfo[slot].index = 1; + + animFlags[slot] = ANIM_PAUSED | ANIM_NOEXIT | ANIM_NODELTA | ANIM_LOOP; + + edict->s.frameInfo[slot].weight = 0.0; + + animFlags[slot] = (animFlags[slot] | ANIM_NODELTA) & ~ANIM_FINISHED; } void SimpleActor::UpdateAnimSlot @@ -718,8 +1112,32 @@ void SimpleActor::UpdateAnimSlot ) { - // FIXME: stub - STUB(); + switch (m_weightType[slot]) + { + case 0: + return; + break; + case 1: + case 2: + case 7: + UpdateNormalAnimSlot(slot); + break; + case 3: + case 4: + UpdateCrossBlendAnimSlot(slot); + break; + case 5: + UpdateCrossBlendDialogAnimSlot(slot); + break; + case 6: + UpdateSayAnimSlot(slot); + break; + case 8: + UpdateLastFrameSlot(slot); + default: + assert(!"impleActor::UpdateAnimSlot: Bad weight type."); + break; + } } void SimpleActor::StopAllAnimating @@ -728,8 +1146,12 @@ void SimpleActor::StopAllAnimating ) { - // FIXME: stub - STUB(); + SetSyncTime(0); + + for (int slot = 0; slot < MAX_FRAMEINFOS; slot++) + { + UpdateLastFrameSlot(slot); + } } void SimpleActor::ChangeMotionAnim @@ -738,8 +1160,32 @@ void SimpleActor::ChangeMotionAnim ) { - // FIXME: stub - STUB(); + int lastMotionSlot; + int firstMotionSlot; + int iSlot; + int i; + + m_bMotionAnimSet = false; + m_iMotionSlot = -1; + m_bLevelMotionAnim = false; + + if (m_ChangeMotionAnimIndex != level.frame_skel_index) + { + m_ChangeMotionAnimIndex = level.frame_skel_index; + + MPrintf("Swapping motion channels....\n"); + for (iSlot = GetMotionSlot(0), i = 0; i < 3; i++, iSlot++) + { + StartCrossBlendAnimSlot(iSlot); + } + m_AnimDialogHigh ^= 1; // toggle + + } + + for (iSlot = GetMotionSlot(0), i = 0; i < 3; i++, iSlot++) + { + StopAnimating(iSlot); + } } void SimpleActor::ChangeActionAnim @@ -748,8 +1194,32 @@ void SimpleActor::ChangeActionAnim ) { - // FIXME: stub - STUB(); + int iSlot; + int i; + + m_bAimAnimSet = false; + m_bActionAnimSet = false; + m_iActionSlot = -1; + m_bLevelActionAnim = false; + + + if (m_ChangeActionAnimIndex != level.frame_skel_index) + { + m_ChangeActionAnimIndex = level.frame_skel_index; + + MPrintf("Swapping action channels....\n"); + for (iSlot = GetActionSlot(0), i = 0; i < 3; i++, iSlot++) + { + animFlags[iSlot] |= ANIM_NOACTION; + StartCrossBlendAnimSlot(iSlot); + } + m_AnimDialogHigh ^= 1; // toggle + } + + for (iSlot = GetActionSlot(0), i = 0; i < 3; i++, iSlot++) + { + StopAnimating(iSlot); + } } void SimpleActor::ChangeSayAnim @@ -758,8 +1228,27 @@ void SimpleActor::ChangeSayAnim ) { - // FIXME: stub - STUB(); + int iSlot; + + m_bSayAnimSet = false; + m_bLevelSayAnim = false; + m_iVoiceTime = level.inttime; + m_iSaySlot = -1; + + if (m_ChangeSayAnimIndex != level.frame_skel_index) + { + m_ChangeSayAnimIndex = level.frame_skel_index; + + MPrintf("Swapping dialog channel....\n"); + + iSlot = GetSaySlot(); + StartCrossBlendAnimSlot(iSlot); + + m_AnimDialogHigh ^= 1; // toggle + } + + iSlot = GetSaySlot(); + StopAnimating(iSlot); } void SimpleActor::UpdateAim @@ -768,8 +1257,53 @@ void SimpleActor::UpdateAim ) { - // FIXME: stub - STUB(); + float dir; + + int aimForwardSlot; + int aimUpSlot; + int aimDownSlot; + + if (m_bAimAnimSet) + { + aimForwardSlot = GetActionSlot(0); + aimUpSlot = aimForwardSlot + 1; + aimDownSlot = aimForwardSlot + 2; + + dir = -m_DesiredGunDir[0]; + if (dir <= 180 && dir < -180) + { + dir += 360; + } + else + { + dir -= 360; + } + float factor; + if (dir < 0) + { + if (dir < m_fAimLimit_down) + dir = m_fAimLimit_down; + + factor = dir / m_fAimLimit_down; + + m_weightBase[aimForwardSlot] = 0; + m_weightBase[aimUpSlot] = 1 - factor; + m_weightBase[aimDownSlot] = factor; + } + else + { + if (dir < m_fAimLimit_up) + dir = m_fAimLimit_up; + + factor = dir / m_fAimLimit_up; + + m_weightBase[aimForwardSlot] = factor; + m_weightBase[aimUpSlot] = 1 - factor; + m_weightBase[aimDownSlot] = 0; + + } + SetControllerAngles(TORSO_TAG, vec_origin); + } } void SimpleActor::UpdateAimMotion @@ -778,8 +1312,20 @@ void SimpleActor::UpdateAimMotion ) { - // FIXME: stub - STUB(); + int slot = GetMotionSlot(0); + + if (m_fCrouchWeight < 0.0) + { + m_weightBase[slot] = 0.0; + m_weightBase[slot + 1] = m_fCrouchWeight + 1.0; + m_weightBase[slot + 2] = -m_fCrouchWeight; + } + else + { + m_weightBase[slot] = m_fCrouchWeight; + m_weightBase[slot + 1] = 1.0 - m_fCrouchWeight; + m_weightBase[slot + 2] = 0.0; + } } void SimpleActor::EventAIOn @@ -788,8 +1334,7 @@ void SimpleActor::EventAIOn ) { - // FIXME: stub - STUB(); + m_bDoAI = true; } void SimpleActor::EventAIOff @@ -798,8 +1343,7 @@ void SimpleActor::EventAIOff ) { - // FIXME: stub - STUB(); + m_bDoAI = false; } void SimpleActor::EventGetWeaponGroup @@ -808,8 +1352,13 @@ void SimpleActor::EventGetWeaponGroup ) { - // FIXME: stub - STUB(); + Weapon *weapon = GetActiveWeapon(WEAPON_MAIN); + const_str csWeaponGroup = weapon->GetWeaponGroup(); + if (csWeaponGroup == STRING_NONE) + { + csWeaponGroup = STRING_UNARMED; + } + ev->AddConstString(csWeaponGroup); } void SimpleActor::EventGetWeaponType @@ -818,8 +1367,65 @@ void SimpleActor::EventGetWeaponType ) { - // FIXME: stub - STUB(); + Weapon *weapon; + const_str csWeaponType; + + if (!m_pTurret) + { + weapon = GetActiveWeapon(WEAPON_MAIN); + } + + if (!weapon) + { + csWeaponType = STRING_RIFLE; + } + else + { + int iWeaponClass = weapon->GetWeaponClass(); + + switch (iWeaponClass) + { + case WEAPON_CLASS_PISTOL: + csWeaponType = STRING_PISTOL; + break; + case WEAPON_CLASS_RIFLE: + csWeaponType = STRING_RIFLE; + break; + case WEAPON_CLASS_SMG: + csWeaponType = STRING_SMG; + break; + case WEAPON_CLASS_MG: + csWeaponType = STRING_MG; + break; + case WEAPON_CLASS_GRENADE: + csWeaponType = STRING_GRENADE; + break; + case WEAPON_CLASS_HEAVY: + csWeaponType = STRING_HEAVY; + break; + case WEAPON_CLASS_CANNON: + csWeaponType = STRING_CANNON; + break; + case WEAPON_CLASS_ITEM: + csWeaponType = STRING_ITEM; + break; + case WEAPON_CLASS_ITEM2: + csWeaponType = STRING_ITEM2; + break; + case WEAPON_CLASS_ITEM3: + csWeaponType = STRING_ITEM3; + break; + case WEAPON_CLASS_ITEM4: + csWeaponType = STRING_ITEM4; + break; + default: + csWeaponType = STRING_EMPTY; + break; + } + + } + + ev->AddConstString(csWeaponType); } void SimpleActor::EventGetPainHandler @@ -828,8 +1434,11 @@ void SimpleActor::EventGetPainHandler ) { - // FIXME: stub - STUB(); + ScriptVariable var; + + m_PainHandler.GetScriptValue(&var); + + ev->AddValue(var); } void SimpleActor::EventSetPainHandler @@ -838,8 +1447,17 @@ void SimpleActor::EventSetPainHandler ) { - // FIXME: stub - STUB(); + if (ev->IsFromScript()) + { + ScriptVariable var = ev->GetValue(1); + + m_PainHandler.SetScript(var); + } + else + { + str varString = ev->GetString(1); + m_PainHandler.SetScript(varString); + } } void SimpleActor::EventGetDeathHandler @@ -848,8 +1466,11 @@ void SimpleActor::EventGetDeathHandler ) { - // FIXME: stub - STUB(); + ScriptVariable var; + + m_DeathHandler.GetScriptValue(&var); + + ev->AddValue(var); } void SimpleActor::EventSetDeathHandler @@ -858,8 +1479,17 @@ void SimpleActor::EventSetDeathHandler ) { - // FIXME: stub - STUB(); + if (ev->IsFromScript()) + { + ScriptVariable var = ev->GetValue(1); + + m_DeathHandler.SetScript(var); + } + else + { + str varString = ev->GetString(1); + m_DeathHandler.SetScript(varString); + } } void SimpleActor::EventGetAttackHandler @@ -868,8 +1498,11 @@ void SimpleActor::EventGetAttackHandler ) { - // FIXME: stub - STUB(); + ScriptVariable var; + + m_AttackHandler.GetScriptValue(&var); + + ev->AddValue(var); } void SimpleActor::EventSetAttackHandler @@ -878,8 +1511,17 @@ void SimpleActor::EventSetAttackHandler ) { - // FIXME: stub - STUB(); + if (ev->IsFromScript()) + { + ScriptVariable var = ev->GetValue(1); + + m_AttackHandler.SetScript(var); + } + else + { + str varString = ev->GetString(1); + m_AttackHandler.SetScript(varString); + } } void SimpleActor::EventGetSniperHandler @@ -888,8 +1530,11 @@ void SimpleActor::EventGetSniperHandler ) { - // FIXME: stub - STUB(); + ScriptVariable var; + + m_SniperHandler.GetScriptValue(&var); + + ev->AddValue(var); } void SimpleActor::EventSetSniperHandler @@ -898,8 +1543,17 @@ void SimpleActor::EventSetSniperHandler ) { - // FIXME: stub - STUB(); + if (ev->IsFromScript()) + { + ScriptVariable var = ev->GetValue(1); + + m_SniperHandler.SetScript(var); + } + else + { + str varString = ev->GetString(1); + m_SniperHandler.SetScript(varString); + } } void SimpleActor::EventSetCrossblendTime @@ -908,8 +1562,7 @@ void SimpleActor::EventSetCrossblendTime ) { - // FIXME: stub - STUB(); + m_fCrossblendTime = ev->GetFloat(1); } void SimpleActor::EventGetCrossblendTime @@ -918,8 +1571,7 @@ void SimpleActor::EventGetCrossblendTime ) { - // FIXME: stub - STUB(); + ev->AddFloat(m_fCrossblendTime); } void SimpleActor::EventSetEmotion @@ -928,8 +1580,45 @@ void SimpleActor::EventSetEmotion ) { - // FIXME: stub - STUB(); + switch (ev->GetConstString(1)) + { + case STRING_EMOTION_NONE: + m_eEmotionMode = EMOTION_NONE; + break; + case STRING_EMOTION_NEUTRAL: + m_eEmotionMode = EMOTION_NEUTRAL; + break; + case STRING_EMOTION_WORRY: + m_eEmotionMode = EMOTION_WORRY; + break; + case STRING_EMOTION_PANIC: + m_eEmotionMode = EMOTION_PANIC; + break; + case STRING_EMOTION_FEAR: + m_eEmotionMode = EMOTION_FEAR; + break; + case STRING_EMOTION_DISGUST: + m_eEmotionMode = EMOTION_DISGUST; + break; + case STRING_EMOTION_ANGER: + m_eEmotionMode = EMOTION_ANGER; + break; + case STRING_EMOTION_AIMING: + m_eEmotionMode = EMOTION_AIMING; + break; + case STRING_EMOTION_DETERMINED: + m_eEmotionMode = EMOTION_DETERMINED; + break; + case STRING_EMOTION_DEAD: + m_eEmotionMode = EMOTION_DEAD; + break; + case STRING_EMOTION_CURIOUS: + m_eEmotionMode = EMOTION_CURIOUS; + break; + default: + assert(!"Unknown emotion mode specified in script."); + break; + } } void SimpleActor::EventGetPosition @@ -938,8 +1627,7 @@ void SimpleActor::EventGetPosition ) { - // FIXME: stub - STUB(); + ev->AddConstString(m_csCurrentPosition); } void SimpleActor::EventSetPosition @@ -948,8 +1636,7 @@ void SimpleActor::EventSetPosition ) { - // FIXME: stub - STUB(); + m_csCurrentPosition = ev->GetConstString(1); } void SimpleActor::EventGetAnimMode @@ -958,7 +1645,7 @@ void SimpleActor::EventGetAnimMode ) { - // FIXME: stub + // not found in ida STUB(); } @@ -968,7 +1655,7 @@ void SimpleActor::EventSetAnimMode ) { - // FIXME: stub + // not found in ida STUB(); } @@ -978,8 +1665,7 @@ void SimpleActor::EventSetAnimFinal ) { - // FIXME: stub - STUB(); + ScriptError("animfinal is obsolete"); } void SimpleActor::DesiredAnimation @@ -989,7 +1675,7 @@ void SimpleActor::DesiredAnimation ) { - // FIXME: stub + // not found in ida STUB(); } @@ -1000,7 +1686,7 @@ void SimpleActor::StartAnimation ) { - // FIXME: stub + // not found in ida STUB(); } @@ -1011,7 +1697,7 @@ void SimpleActor::DesiredAnimation ) { - // FIXME: stub + // not found in ida STUB(); } @@ -1022,7 +1708,7 @@ void SimpleActor::StartAnimation ) { - // FIXME: stub + // not found in ida STUB(); } @@ -1032,7 +1718,7 @@ void SimpleActor::ContinueAnimationAllowNoPath ) { - // FIXME: stub + // not found in ida STUB(); } @@ -1042,8 +1728,19 @@ void SimpleActor::ContinueAnimation ) { - // FIXME: stub - STUB(); + if (m_eNextAnimMode < 0) + { + m_bNextForceStart = false; + m_csNextAnimString = NULL; + m_eNextAnimMode = m_eAnimMode; + m_NextAnimLabel = m_Anim; + } + + if (m_eAnimMode <= 3 && !PathExists()) + { + assert(!"ContinueAnimation() called on a pathed animation, but no path exists"); + Anim_Stand(); + } } void SimpleActor::SetPathGoalEndAnim @@ -1052,8 +1749,7 @@ void SimpleActor::SetPathGoalEndAnim ) { - // FIXME: stub - STUB(); + m_csPathGoalEndAnimScript = csEndAnim; } bool SimpleActor::UpdateSelectedAnimation @@ -1062,8 +1758,50 @@ bool SimpleActor::UpdateSelectedAnimation ) { - // FIXME: stub - STUB(); + + if (m_csNextAnimString == NULL) + { + if (!m_bNextForceStart && m_pAnimThread == NULL && m_eAnimMode == m_eNextAnimMode && m_Anim == m_NextAnimLabel) + { + m_bStartPathGoalEndAnim = false; + m_eNextAnimMode = -1; + return false; + } + else + { + m_Anim = m_NextAnimLabel; + //LABEL_7: + m_eAnimMode = m_eNextAnimMode; + if (m_eNextAnimMode != 3) + SetPathGoalEndAnim(STRING_EMPTY); + m_bStartPathGoalEndAnim = false; + m_eNextAnimMode = -1; + return true; + } + } + else if (m_bNextForceStart || m_pAnimThread != NULL || m_eAnimMode != m_eNextAnimMode || (m_fPathGoalTime <= level.time && !m_Anim.IsFile(m_csNextAnimString))) + { + m_Anim.TrySetScript(Director.GetString(m_csNextAnimString)); + m_eAnimMode = m_eNextAnimMode; + if (m_eNextAnimMode != 3) + SetPathGoalEndAnim(STRING_EMPTY); + m_bStartPathGoalEndAnim = false; + m_eNextAnimMode = -1; + return true; + } + else + { + m_eNextAnimMode = -1; + if (m_bStartPathGoalEndAnim) + { + m_bStartPathGoalEndAnim = false; + if (!m_Anim.IsFile(m_csPathGoalEndAnimScript)) + { + m_Anim.TrySetScript(Director.GetString(m_csPathGoalEndAnimScript)); + return true; + } + } + } return false; } @@ -1074,5 +1812,6 @@ const char *SimpleActor::DumpCallTrace ) const { + OVERLOADED_ERROR(); return "overloaded version should always get called"; } diff --git a/code/game/simpleactor.h b/code/game/simpleactor.h index 9d2568fe..65201df0 100644 --- a/code/game/simpleactor.h +++ b/code/game/simpleactor.h @@ -22,6 +22,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // simpleactor.h: Base class for character AI. +#ifndef __SIMPLEACTOR_H__ +#define __SIMPLEACTOR_H__ + #include "weapon.h" #include "sentient.h" #include "container.h" @@ -31,6 +34,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "characterstate.h" #include "actorpath.h" +enum eEmotionMode { + EMOTION_NONE, + EMOTION_NEUTRAL, + EMOTION_WORRY, + EMOTION_PANIC, + EMOTION_FEAR, + EMOTION_DISGUST, + EMOTION_ANGER, + EMOTION_AIMING, + EMOTION_DETERMINED, + EMOTION_DEAD, + EMOTION_CURIOUS +}; class SimpleActor; typedef SafePtr SimpleActorPtr; @@ -66,7 +82,7 @@ public: Vector watch_offset; bool m_bThink; int m_PainTime; - int m_eEmotionMode; + eEmotionMode m_eEmotionMode; float m_fAimLimit_up; float m_fAimLimit_down; int m_ChangeMotionAnimIndex; @@ -129,7 +145,7 @@ public: void SetPath( Vector vDestPos, const char *description, int iMaxDirtyTime, float *vLeashHome, float fLeashDistSquared ); void SetPath( SimpleEntity *pDestNode, char *description, int iMaxDirtyTime ); void SetPathWithinDistance( Vector vDestPos, char *description, float fMaxPath, int iMaxDirtyTime ); - void FindPathAway( vec3_t vAwayFrom, vec3_t vDirPreferred, float fMinSafeDist ); + void FindPathAway( vec_t *vAwayFrom, vec_t *vDirPreferred, float fMinSafeDist ); void ClearPath( void ); bool PathComplete( void ) const; bool PathExists( void ) const; @@ -232,8 +248,10 @@ public: void Anim_RunToDive( int eAnimMode ); void Anim_RunToFlee( int eAnimMode ); void Anim_RunToInOpen( int eAnimMode ); - void Anim_Emotion( int eEmotionMode ); + void Anim_Emotion( eEmotionMode eEmotMode ); void Anim_Say( const_str csSayAnimScript, int iMinTimeSinceLastSay, bool bCanInterrupt ); void Anim_FullBody( const_str csFullBodyAnim, int eAnimMode ); virtual const char *DumpCallTrace( const char *pszFmt, ... ) const; }; + +#endif /* simpleactor.h */ \ No newline at end of file diff --git a/code/globalcpp/g_spawn.cpp b/code/globalcpp/g_spawn.cpp index ffb3e6ee..901c4b71 100644 --- a/code/globalcpp/g_spawn.cpp +++ b/code/globalcpp/g_spawn.cpp @@ -422,10 +422,11 @@ Listener *SpawnArgs::SpawnInternal( void ) } } - if( g_spawnai->integer ) + if( !g_spawnai->integer ) { value = getArg( "classname", NULL ); + //dont spawn ai_* if g_spawnai is 0 if( value ) { if( !Q_stricmpn( value, "ai_", 3 ) ) diff --git a/code/globalcpp/gamescript.cpp b/code/globalcpp/gamescript.cpp index df4285fe..91d9ab48 100644 --- a/code/globalcpp/gamescript.cpp +++ b/code/globalcpp/gamescript.cpp @@ -1068,7 +1068,12 @@ void ScriptThreadLabel::GetScriptValue(ScriptVariable *var) bool ScriptThreadLabel::IsSet( void ) { - return m_Script != NULL ? true : false; + return m_Script != NULL; +} + +bool ScriptThreadLabel::IsFile(const_str filename) +{ + return m_Script && m_Script->ConstFilename() == filename && m_Label == STRING_EMPTY; } void ScriptThreadLabel::Archive( Archiver& arc ) diff --git a/code/globalcpp/gamescript.h b/code/globalcpp/gamescript.h index f86c92db..d970f7d9 100644 --- a/code/globalcpp/gamescript.h +++ b/code/globalcpp/gamescript.h @@ -171,11 +171,25 @@ public: bool TrySetScript( const_str label ); bool TrySetScript( const char *label ); + bool IsSet(void); + bool IsFile(const_str filename); + void GetScriptValue(ScriptVariable *var); - bool IsSet( void ); void Archive( Archiver& arc ); + + friend bool operator==(const ScriptThreadLabel& a, const ScriptThreadLabel& b); }; + +inline bool operator== +( + const ScriptThreadLabel& a, + const ScriptThreadLabel& b + ) +{ + return a.m_Label == b.m_Label && a.m_Script == b.m_Script; +} + #endif diff --git a/code/qcommon/q_math.c b/code/qcommon/q_math.c index 1adf3a4b..99e21edd 100644 --- a/code/qcommon/q_math.c +++ b/code/qcommon/q_math.c @@ -924,6 +924,61 @@ float LerpAngle (float from, float to, float frac) { return a; } +static float fNoise1Arr[514]; +static int iNoise1Arr[256]; + +static void init(void) +{ + //This is an ugly func I wont bother variable naming. + int i; + for (i = 0; i < 256; i++) + { + iNoise1Arr[i] = i; + fNoise1Arr[i] = (rand() % 512 - 256) * 0.00390625; + } + int v21, v22; + for (int j = i - 1; j; iNoise1Arr[v22 % 256] = v21) + { + v21 = iNoise1Arr[j]; + v22 = rand(); + iNoise1Arr[j--] = iNoise1Arr[v22 % 256]; + } + + for (size_t k = 0; k < 258; k++) + { + fNoise1Arr[k + 256] = fNoise1Arr[k]; + } + +} +static int start = 1; + +float noise1(float arg) +{ + /* + * This is an ugly func I wont bother variable naming. + *vec_t vec; + float u, t, sx, rx1, rx0; + int bx0;*/ + + + if (start) + { + init(); + start = 0; + } + + double v1; // st7 + int v2; // eax + double v3; // st7 + float v5; // [esp+4h] [ebp+4h] + + v1 = arg + 4096.0; + v2 = (unsigned __int8)(signed __int64)v1; + v3 = v1 - (double)(signed int)(signed __int64)v1; + v5 = v3 * fNoise1Arr[iNoise1Arr[v2]]; + return ((v3 - 1.0) * fNoise1Arr[iNoise1Arr[(unsigned __int8)(v2 + 1)]] - v5) * ((3.0 - (v3 + v3)) * (v3 * v3)) + + v5; +} /* ================ diff --git a/code/qcommon/q_shared.h b/code/qcommon/q_shared.h index 6421ad7c..dc1d04ef 100644 --- a/code/qcommon/q_shared.h +++ b/code/qcommon/q_shared.h @@ -794,6 +794,8 @@ float erandom( float mean ); void vectoangles( const vec3_t value1, vec3_t angles ); void VectorToAngles( const vec3_t vec, vec3_t angles ); void AnglesToAxis( const vec3_t angles, vec3_t axis[3] ); +static void init( void ); +float noise1(float arg); void R_ConcatRotations( float in1[ 3 ][ 3 ], float in2[ 3 ][ 3 ], float out[ 3 ][ 3 ] ); void R_ConcatTransforms( float in1[ 3 ][ 4 ], float in2[ 3 ][ 4 ], float out[ 3 ][ 4 ] ); diff --git a/code/qcommon/qcommon.h b/code/qcommon/qcommon.h index 38e93ddc..336ea371 100644 --- a/code/qcommon/qcommon.h +++ b/code/qcommon/qcommon.h @@ -166,9 +166,9 @@ typedef enum { } netadrtype_t; typedef enum { -// NS_MASTER, - NS_SERVER, - NS_CLIENT + //NS_MASTER, + NS_CLIENT, + NS_SERVER } netsrc_t; typedef struct {