openmohaa/code/fgame/actor_machinegunner.cpp
2023-07-05 20:52:55 +02:00

360 lines
7.5 KiB
C++

/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// actor_machinegunner.cpp
#include "actor.h"
#include "weapturret.h"
extern Vector MINS;
extern Vector MAXS;
void Actor::InitMachineGunner
(
GlobalFuncs_t *func
)
{
func->BeginState = &Actor::Begin_MachineGunner;
func->EndState = &Actor::End_MachineGunner;
func->ThinkState = &Actor::Think_MachineGunner;
func->IsState = &Actor::IsMachineGunnerState;
func->FinishedAnimation = &Actor::FinishedAnimation_MachineGunner;
}
void Actor::Begin_MachineGunner
(
void
)
{
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);
TransitionState(1200, 0);
}
}
else
{
Com_Printf(
"^~^~^ Actor (entnum %d, radnum %d, targetname '%s') has no turret specified\n",
entnum,
radnum,
targetname.c_str());
}
}
void Actor::End_MachineGunner
(
void
)
{
if (!GetWeapon(WEAPON_MAIN))
giveItem("models/weapons/mp40.tik");
Unholster();
if (m_pTurret)
{
if (m_pTurret->GetOwner() == this)
{
m_pTurret->TurretEndUsed();
}
}
}
void Actor::BecomeTurretGuy
(
void
)
{
SetThinkIdle(THINK_IDLE);
SetThink(THINKSTATE_ATTACK, THINK_TURRET);
SetThink(THINKSTATE_DISGUISE, THINK_DISGUISE_SALUTE);
SetThink(THINKSTATE_GRENADE, THINK_GRENADE);
if (CurrentThink() == THINK_IDLE && Turret_DecideToSelectState())
{
TransitionState(100, 0);
}
}
void Actor::Think_MachineGunner
(
void
)
{
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[THINKLEVEL_NORMAL] != 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
)
{
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();
StopTurning();
setAngles(Vector(0,m_pTurret->angles[1],0));
vForward = Vector(m_pTurret->orientation[0]) * -39 + m_pTurret->origin;
if (m_State == 1201)
{
heightDiff = 71.6f;
}
else
{
heightDiff = 71.8f;
}
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
)
{
if (!m_bAnimScriptSet && m_State == 1201)
{
TransitionState(1200, 0);
Unregister(STRING_ANIMDONE);
}
}
bool Actor::MachineGunner_CanSee
(
Entity *ent,
float fov,
float vision_distance
)
{
float delta[2];
delta[0] = ent->centroid[0] - centroid[0];
delta[1] = ent->centroid[1] - centroid[1];
if ((vision_distance <= 0.0f) || (delta[0] * delta[0] + delta[1] * delta[1]) <= (vision_distance * vision_distance))
{
if (gi.AreasConnected(edict->r.areanum, ent->edict->r.areanum) &&
((fov <= 0.0f || fov >= 360.0f) ||
(FovCheck(delta, cos(fov * (0.5 * M_PI / 180.0))))))
{
return G_SightTrace(centroid,
vec_zero,
vec_zero,
ent->centroid,
m_pTurret,
ent,
MASK_CANSEE,
0,
"Actor::MachineGunner_CanSee");
}
}
return false;
}