Files
DoomRTX/neo/prey/Prey/ai_possessedTommy.cpp
2026-05-05 15:01:01 -07:00

121 lines
3.4 KiB
C++

#include "precompiled.h"
#pragma hdrstop
#include "prey_local.h"
CLASS_DECLARATION( hhMonsterAI, hhPossessedTommy )
END_CLASS
// TODO: Set up a rhythmic damaging of this entity.
void hhPossessedTommy::Spawn() {
physicsObj.SetContents( CONTENTS_CORPSE | CONTENTS_MONSTERCLIP | CONTENTS_RENDERMODEL );
nextDrop = 0;
}
void hhPossessedTommy::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) {
if ( attacker->IsType( hhPlayer::Type ) ) { // Being attacked by a player, must be a spiritwalking player
if ( possessedProxy.IsValid() ) {
hhSpiritProxy *proxy = possessedProxy.GetEntity();
Hide();
proxy->SetOrigin( GetOrigin() );
proxy->SetAxis( GetAxis() );
proxy->Show();
proxy->GetPhysics()->SetContents( CONTENTS_CORPSE | CONTENTS_MONSTERCLIP | CONTENTS_RENDERMODEL );
if ( proxy->GetPlayer() ) {
proxy->GetPlayer()->Unpossess();
}
}
hhMonsterAI::Killed( inflictor, attacker, damage, dir, location );
PostEventMS( &EV_Remove, 0 );
return;
}
// OTHERWISE, KILL THIS ENTITY AND KILL THE PLAYER -- create a death proxy here, etc
hhMonsterAI::Killed( inflictor, attacker, damage, dir, location );
// Kill the player
if (possessedProxy.IsValid() ) {
if ( possessedProxy->GetPlayer() ) {
possessedProxy->GetPlayer()->PossessKilled();
}
}
}
void hhPossessedTommy::Event_Remove(void) {
if (!fl.hidden && possessedProxy.IsValid()) {
Hide();
hhSpiritProxy *proxy = possessedProxy.GetEntity();
proxy->SetOrigin( GetOrigin() );
proxy->SetAxis( GetAxis() );
proxy->Show();
proxy->GetPhysics()->SetContents( CONTENTS_CORPSE | CONTENTS_MONSTERCLIP | CONTENTS_RENDERMODEL );
if ( proxy->GetPlayer() ) {
proxy->GetPlayer()->Unpossess();
}
}
hhMonsterAI::Event_Remove();
}
void hhPossessedTommy::Think(void) {
PROFILE_SCOPE("AI", PROFMASK_NORMAL|PROFMASK_AI);
if (ai_skipThink.GetBool()) {
return;
}
hhMonsterAI::Think();
if (possessedProxy.IsValid() && gameLocal.time > nextDrop) {
hhPlayer *player = possessedProxy->GetPlayer();
if (player) {
player->SetHealth(player->GetHealth() - 1);
if (player->GetHealth() <= 0) {
Hide();
possessedProxy->SetOrigin( GetOrigin() );
possessedProxy->SetAxis( GetAxis() );
possessedProxy->Show();
possessedProxy->GetPhysics()->SetContents( CONTENTS_CORPSE | CONTENTS_MONSTERCLIP | CONTENTS_RENDERMODEL );
player->Unpossess();
player->Killed(this, this, 1, vec3_origin, INVALID_JOINT);
PostEventMS(&EV_Remove, 0);
}
}
float min = spawnArgs.GetFloat( "dda_drain_min" );
float max = spawnArgs.GetFloat( "dda_drain_max" );
nextDrop = gameLocal.time + min + (max - min) * (1.0f - gameLocal.GetDDAValue());
}
}
void hhPossessedTommy::Save( idSaveGame *savefile ) const {
possessedProxy.Save( savefile );
}
void hhPossessedTommy::Restore( idRestoreGame *savefile ) {
possessedProxy.Restore( savefile );
nextDrop = 0;
}
void hhPossessedTommy::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir, const char *damageDefName, const float damageScale, const int location ) {
hhMonsterAI::Damage( inflictor, attacker, dir, damageDefName, damageScale, location );
// Turn to a different direction
float adjust = 45.0f + (gameLocal.random.RandomFloat() * 30.0f);
if (gameLocal.random.RandomInt(100) > 50) {
adjust = -adjust;
}
gameLocal.Printf("Adjusting by %f\n", adjust);
TurnToward(current_yaw + adjust);
move.nextWanderTime = 0;
}