diff --git a/source/games/duke/src/game.cpp b/source/games/duke/src/game.cpp index 688e67cb5..5f8402919 100644 --- a/source/games/duke/src/game.cpp +++ b/source/games/duke/src/game.cpp @@ -383,6 +383,7 @@ void GameInterface::app_init() ud.cameraactor = nullptr; moves.Push({}); // make sure the first entry in 'moves' is a null move. actions.Push({}); // make sure the first entry in 'actions' is a null action. + ais.Push({}); // make sure the first entry in 'actions' is a null action. if (fileSystem.FileExists("DUKESW.BIN")) g_gameType |= GAMEFLAG_SHAREWARE; diff --git a/source/games/duke/src/gamedef.cpp b/source/games/duke/src/gamedef.cpp index 0bb8a4f38..45928b5c0 100644 --- a/source/games/duke/src/gamedef.cpp +++ b/source/games/duke/src/gamedef.cpp @@ -1118,28 +1118,25 @@ int ConCompiler::parsecommand() warningcount++; Printf(TEXTCOLOR_RED " * WARNING.(%s, line %d) Duplicate ai '%s' ignored.\n", fn, line_number, parselabel.GetChars()); } - else appendlabeladdress(LABEL_AI); + else appendlabelvalue(LABEL_AI, ais.Size()); - for (j = 0; j < 3; j++) + ActorAI& ai = ais[ais.Reserve(1)]; + ai.name = parselabel.GetChars(); + ai.move = ai.action = ai.moveflags = 0; + if (keyword() >= 0) break; + transnum(LABEL_ACTION); + ai.action = popscriptvalue(); + if (keyword() >= 0) return 0; + transnum(LABEL_MOVE); + ai.move = popscriptvalue(); + if (keyword() >= 0) return 0; + k = 0; + while (keyword() == -1) { - if (keyword() >= 0) break; - if (j == 2) - { - k = 0; - while (keyword() == -1) - { - transnum(LABEL_DEFINE); - k |= popscriptvalue(); - } - appendscriptvalue(k); - return 0; - } - else transnum(j==0? LABEL_ACTION : LABEL_MOVE); - } - for (k = j; k < 3; k++) - { - appendscriptvalue(0); + transnum(LABEL_DEFINE); + k |= popscriptvalue(); } + ai.moveflags = k; } return 0; diff --git a/source/games/duke/src/gameexec.cpp b/source/games/duke/src/gameexec.cpp index 8a833bd38..072890e31 100644 --- a/source/games/duke/src/gameexec.cpp +++ b/source/games/duke/src/gameexec.cpp @@ -1552,16 +1552,19 @@ int ParseState::parse(void) } break; case concmd_ai: + { insptr++; - g_t[5] = *insptr; - g_ac->curAction = &actions[ScriptCode[g_t[5]]]; // Action - g_ac->curMove = &moves[ScriptCode[g_t[5] + 1]]; // move - g_ac->spr.hitag = ScriptCode[g_t[5] + 2]; // Ai + auto ai = &ais[*insptr]; + g_ac->curAI = ai->name; + g_ac->curAction = &actions[ai->action]; + g_ac->curMove = &moves[ai->move]; + g_ac->spr.hitag = ai->moveflags; g_t[0] = g_t[2] = g_t[3] = 0; if (g_ac->spr.hitag & random_angle) g_ac->spr.Angles.Yaw = randomAngle(); insptr++; break; + } case concmd_action: insptr++; g_t[2] = 0; @@ -1908,7 +1911,7 @@ int ParseState::parse(void) break; case concmd_ifai: insptr++; - parseifelse(g_t[5] == *insptr); + parseifelse(g_ac->curAI == ais[*insptr].name); break; case concmd_ifaction: insptr++; diff --git a/source/games/duke/src/savegame.cpp b/source/games/duke/src/savegame.cpp index 99a8fe4ac..a63bf525e 100644 --- a/source/games/duke/src/savegame.cpp +++ b/source/games/duke/src/savegame.cpp @@ -319,7 +319,8 @@ void DDukeActor::Serialize(FSerializer& arc) ("flags2", flags2) ("flags3", flags3) ("curmove", curMove) - ("curaction", curAction); + ("curaction", curAction) + ("curai", curAI); } diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h index 98dba5bc1..0c6890b5c 100644 --- a/source/games/duke/src/types.h +++ b/source/games/duke/src/types.h @@ -40,8 +40,17 @@ struct ActorAction int16_t delay; }; +struct ActorAI +{ + FName name; + uint32_t move; + uint32_t action; + int moveflags; +}; + inline TArray moves; inline TArray actions; +inline TArray ais; struct ActorInfo { @@ -91,6 +100,7 @@ public: DVector3 temp_pos, temp_pos2; ActorMove* curMove; ActorAction* curAction; + FName curAI; // no need to store the pointer here. TObjPtr temp_actor, seek_actor;