mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-17 19:23:51 +02:00
All Doom 3 AI is now native.
This commit is contained in:
+171
-3
@@ -138,6 +138,9 @@ idAI::idAI
|
||||
=====================
|
||||
*/
|
||||
idAI::idAI() {
|
||||
nativeAIObject = NULL;
|
||||
nativeAIObjectName.Clear();
|
||||
|
||||
aas = NULL;
|
||||
travelFlags = TFL_WALK | TFL_AIR;
|
||||
|
||||
@@ -244,6 +247,7 @@ idAI::~idAI
|
||||
=====================
|
||||
*/
|
||||
idAI::~idAI() {
|
||||
ShutdownNativeAIObject();
|
||||
delete projectileClipModel;
|
||||
DeconstructScriptObject();
|
||||
scriptObject.Free();
|
||||
@@ -548,6 +552,9 @@ void idAI::Restore(idRestoreGame* savefile) {
|
||||
// Link the script variables back to the scriptobject
|
||||
LinkScriptVariables();
|
||||
|
||||
// Recreate the native state-machine object from the entityDef/spawnArg.
|
||||
InitNativeAIObject();
|
||||
|
||||
if (restorePhysics) {
|
||||
RestorePhysics(&physicsObj);
|
||||
}
|
||||
@@ -793,6 +800,9 @@ void idAI::Spawn(void) {
|
||||
|
||||
// init the move variables
|
||||
StopMove(MOVE_STATUS_DONE);
|
||||
|
||||
// create the optional native state-machine object after idAI native fields are ready
|
||||
InitNativeAIObject();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1074,12 +1084,165 @@ void idAI::LinkScriptVariables(void) {
|
||||
AI_PUSHED.LinkTo(scriptObject, "AI_PUSHED");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
NativeAIObjectNameMatches
|
||||
=====================
|
||||
*/
|
||||
static bool NativeAIObjectNameMatches( const char* requestedName, const char* scriptObjectName, const char* cppObjectName ) {
|
||||
if ( !requestedName || !requestedName[0] ) {
|
||||
return false;
|
||||
}
|
||||
return ( !idStr::Icmp( requestedName, scriptObjectName ) || !idStr::Icmp( requestedName, cppObjectName ) );
|
||||
}
|
||||
|
||||
#define CREATE_NATIVE_AI_OBJECT( scriptObjectName, cppObjectType ) \
|
||||
if ( NativeAIObjectNameMatches( nativeObjectName, scriptObjectName, #cppObjectType ) ) { return new cppObjectType(); }
|
||||
|
||||
/*
|
||||
=====================
|
||||
idAI::CreateNativeAIObject
|
||||
|
||||
Creates the native replacement object named by the entityDef/spawnArg "nativeobject" key.
|
||||
The key may use either the original DoomScript object name, such as "monster_demon_imp",
|
||||
or the generated native C++ type name, such as "rvmMonsterDemonImp".
|
||||
=====================
|
||||
*/
|
||||
rvmAIObject* idAI::CreateNativeAIObject( const char* nativeObjectName ) {
|
||||
if ( !nativeObjectName || !nativeObjectName[0] ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CREATE_NATIVE_AI_OBJECT( "ai", rvmAIObject );
|
||||
CREATE_NATIVE_AI_OBJECT( "character", rvmCharacter );
|
||||
CREATE_NATIVE_AI_OBJECT( "ai_character_prone", rvmAICharacterProne );
|
||||
CREATE_NATIVE_AI_OBJECT( "char_sentry", rvmCharSentry );
|
||||
CREATE_NATIVE_AI_OBJECT( "follower", rvmFollower );
|
||||
CREATE_NATIVE_AI_OBJECT( "ai_alphalabs2_scientist1", rvmAIAlphaLabs2Scientist1 );
|
||||
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_base", rvmMonsterBase );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_zombie_base", rvmMonsterZombieBase );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_zombie", rvmMonsterZombie );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_zombie_bernie", rvmMonsterZombieBernie );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_zombie_morgue", rvmMonsterZombieMorgue );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_zombie_sawyer", rvmMonsterZombieSawyer );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_zombie_commando_tentacle", rvmMonsterZombieCommandoTentacle );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_zombie_commando_cgun", rvmMonsterZombieCommandoCGun );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_zombie_security_pistol", rvmMonsterZombieSecurityPistol );
|
||||
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_demon_pinky", rvmMonsterDemonPinky );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_demon_imp", rvmMonsterDemonImp );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_demon_vulgar", rvmMonsterDemonVulgar );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_demon_revenant", rvmMonsterDemonRevenant );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_demon_hellknight", rvmMonsterDemonHellknight );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_demon_maggot", rvmMonsterDemonMaggot );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_demon_cherub", rvmMonsterDemonCherub );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_demon_trite", rvmMonsterDemonTrite );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_demon_wraith", rvmMonsterDemonWraith );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_demon_mancubus", rvmMonsterDemonMancubus );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_demon_archvile", rvmMonsterDemonArchvile );
|
||||
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_flying_cacodemon", rvmMonsterFlyingCacodemon );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_flying_lostsoul", rvmMonsterFlyingLostsoul );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_turret", rvmMonsterTurret );
|
||||
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_boss_cyberdemon", rvmMonsterBossCyberdemon );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_boss_vagary", rvmMonsterBossVagary );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_boss_sabaoth", rvmMonsterBossSabaoth );
|
||||
CREATE_NATIVE_AI_OBJECT( "seeker_base", rvmSeekerBase );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_boss_guardian_spawner", rvmMonsterBossGuardianSpawner );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_boss_guardian", rvmMonsterBossGuardian );
|
||||
CREATE_NATIVE_AI_OBJECT( "monster_boss_guardian_seeker", rvmMonsterBossGuardianSeeker );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#undef CREATE_NATIVE_AI_OBJECT
|
||||
|
||||
/*
|
||||
=====================
|
||||
idAI::ShutdownNativeAIObject
|
||||
=====================
|
||||
*/
|
||||
void idAI::ShutdownNativeAIObject( void ) {
|
||||
if ( nativeAIObject ) {
|
||||
nativeAIObject->Destroy();
|
||||
delete nativeAIObject;
|
||||
nativeAIObject = NULL;
|
||||
}
|
||||
nativeAIObjectName.Clear();
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idAI::InitNativeAIObject
|
||||
|
||||
The entityDef owns selection through "nativeobject". Empty, "0", or "false" means
|
||||
keep the old DoomScript VM path. "1" or "true" means use the existing "scriptobject"
|
||||
name as the native object selector, which is convenient while converting decls.
|
||||
=====================
|
||||
*/
|
||||
void idAI::InitNativeAIObject( void ) {
|
||||
ShutdownNativeAIObject();
|
||||
|
||||
idStr requestedNativeObject;
|
||||
spawnArgs.GetString( "nativeobject", "", requestedNativeObject );
|
||||
if ( !requestedNativeObject.Length() || !idStr::Icmp( requestedNativeObject.c_str(), "0" ) || !idStr::Icmp( requestedNativeObject.c_str(), "false" ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !idStr::Icmp( requestedNativeObject.c_str(), "1" ) || !idStr::Icmp( requestedNativeObject.c_str(), "true" ) ) {
|
||||
spawnArgs.GetString( "scriptobject", "", requestedNativeObject );
|
||||
}
|
||||
|
||||
if ( !requestedNativeObject.Length() ) {
|
||||
gameLocal.Warning( "%s has nativeobject set, but no native object or scriptobject name was provided", name.c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
nativeAIObject = CreateNativeAIObject( requestedNativeObject.c_str() );
|
||||
if ( !nativeAIObject ) {
|
||||
gameLocal.Warning( "%s has unknown nativeobject '%s'; falling back to DoomScript object '%s'", name.c_str(), requestedNativeObject.c_str(), spawnArgs.GetString( "scriptobject", "" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
nativeAIObjectName = requestedNativeObject;
|
||||
nativeAIObject->Init( this );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idAI::GetNativeAIObject
|
||||
=====================
|
||||
*/
|
||||
rvmAIObject* idAI::GetNativeAIObject( void ) const {
|
||||
return nativeAIObject;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idAI::GetNativeAIObjectName
|
||||
=====================
|
||||
*/
|
||||
const char* idAI::GetNativeAIObjectName( void ) const {
|
||||
return nativeAIObjectName.c_str();
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
idAI::UpdateAIScript
|
||||
=====================
|
||||
*/
|
||||
void idAI::UpdateAIScript(void) {
|
||||
if (nativeAIObject) {
|
||||
nativeAIObject->Update();
|
||||
|
||||
// clear the hit enemy flag so we catch the next time we hit someone
|
||||
AI_HIT_ENEMY = false;
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateScript();
|
||||
|
||||
// clear the hit enemy flag so we catch the next time we hit someone
|
||||
@@ -3338,9 +3501,14 @@ void idAI::Killed(idEntity* inflictor, idEntity* attacker, int damage, const idV
|
||||
|
||||
restartParticles = false;
|
||||
|
||||
state = GetScriptFunction("state_Killed");
|
||||
SetState(state);
|
||||
SetWaitState("");
|
||||
if (nativeAIObject) {
|
||||
nativeAIObject->SetState("state_Killed");
|
||||
}
|
||||
else {
|
||||
state = GetScriptFunction("state_Killed");
|
||||
SetState(state);
|
||||
SetWaitState("");
|
||||
}
|
||||
|
||||
const idKeyValue* kv = spawnArgs.MatchPrefix("def_drops", NULL);
|
||||
while (kv) {
|
||||
|
||||
Reference in New Issue
Block a user