const char *CAI_GlobalNamespace::IdToSymbol( int symbolID ) const { AssertMsg( AI_IdIsGlobal( symbolID ), ("Local symbol ID passed to CAI_GlobalNamespace::IdToSymbol()") ); if ( symbolID == -1 ) return "<<null>>"; return (const_cast<CStringRegistry *>(m_pSymbols))->GetStringText( symbolID ); }
void CAI_GlobalNamespace::AddSymbol( const char *pszSymbol, int symbolID ) { AssertMsg( symbolID != -1, "Invalid symbol id passed to CAI_GlobalNamespace::AddSymbol()" ); if (symbolID == -1 ) return; AssertMsg( AI_IdIsGlobal( symbolID ), ("Local symbol ID passed to CAI_GlobalNamespace::AddSymbol()") ); AssertMsg( !IdToSymbol( symbolID ) , ("Duplicate symbol ID passed to CAI_GlobalNamespace::AddSymbol()") ); AssertMsg( SymbolToId( pszSymbol ) == -1, ("Duplicate symbol passed to CAI_GlobalNamespace::AddSymbol()") ); m_pSymbols->AddString( pszSymbol, symbolID ); if ( m_NextGlobalBase < symbolID + 1 ) m_NextGlobalBase = symbolID + 1; }
int CAI_LocalIdSpace::GlobalToLocal( int globalID ) const { if ( globalID == -1 ) return -1; AssertMsg( AI_IdIsGlobal( globalID ), ("Local symbol ID passed to CAI_LocalIdSpace::GlobalToLocal()") ); const CAI_LocalIdSpace *pCurrentMap = this; do { if ( pCurrentMap->IsLocalBaseSet() && globalID >= pCurrentMap->GetGlobalBase() && globalID <= pCurrentMap->GetGlobalTop() ) return ( globalID - pCurrentMap->GetGlobalBase() + pCurrentMap->GetLocalBase() ); pCurrentMap = pCurrentMap->m_pParentIDSpace; } while ( pCurrentMap != NULL ); // AssertMsg( 0, ("Invalid ID passed to CAI_LocalIdSpace::GlobalToLocal()") ); return -1; }
bool CAI_SchedulesManager::LoadSchedulesFromBuffer( const char *prefix, char *pfile, CAI_ClassScheduleIdSpace *pIdSpace ) { char token[1024]; char save_token[1024]; pfile = engine->COM_ParseFile(pfile, token); while (!stricmp("Schedule",token)) { pfile = engine->COM_ParseFile(pfile, token); // ----------------------------- // Check for duplicate schedule // ----------------------------- if (GetScheduleByName(token)) { Msg("ERROR: file contains a schedule (%s) that has already been defined!\n",token); Msg(" Aborting schedule load.\n"); Assert(0); return false; } int scheduleID = CAI_BaseNPC::GetScheduleID(token); if (scheduleID == -1) { Msg( "ERROR: LoadSchd (%s): Unknown schedule type (%s)\n", prefix, token); // FIXME: .sch's not being in code/perforce makes it hard to share branches between developers // for now, just stop processing this entities schedules if one is found that isn't in the schedule registry break; // return false; } CAI_Schedule *new_schedule = CreateSchedule(token,scheduleID); pfile = engine->COM_ParseFile(pfile, token); if (stricmp(token,"Tasks")) { Msg( "ERROR: LoadSchd (%s): (%s) Malformed AI Schedule. Expecting 'Tasks' keyword.\n",prefix,new_schedule->GetName()); Assert(0); return false; } // ========================== // Now read in the tasks // ========================== // Store in temp array until number of tasks is known Task_t tempTask[50]; int taskNum = 0; pfile = engine->COM_ParseFile(pfile, token); while ((token[0]!=NULL) && (stricmp("Interrupts",token))) { // Convert generic ID to sub-class specific enum int taskID = CAI_BaseNPC::GetTaskID(token); tempTask[taskNum].iTask = (pIdSpace) ? pIdSpace->TaskGlobalToLocal(taskID) : AI_RemapFromGlobal( taskID ); // If not a valid condition, send a warning message if (tempTask[taskNum].iTask == -1) { Msg( "ERROR: LoadSchd (%s): (%s) Unknown task %s!\n", prefix,new_schedule->GetName(), token); Assert(0); return false; } Assert( AI_IdIsLocal( tempTask[taskNum].iTask ) ); // Read in the task argument pfile = engine->COM_ParseFile(pfile, token); if (!stricmp("Activity",token)) { // Skip the ";", but make sure it's present pfile = engine->COM_ParseFile(pfile, token); if (stricmp(token,":")) { Msg( "ERROR: LoadSchd (%s): (%s) Malformed AI Schedule. Expecting ':' after type 'ACTIVITY.\n",prefix,new_schedule->GetName()); Assert(0); return false; } // Load the activity and make sure its valid pfile = engine->COM_ParseFile(pfile, token); tempTask[taskNum].flTaskData = CAI_BaseNPC::GetActivityID(token); if (tempTask[taskNum].flTaskData == -1) { Msg( "ERROR: LoadSchd (%s): (%s) Unknown activity %s!\n", prefix,new_schedule->GetName(), token); Assert(0); return false; } } else if (!stricmp("Task",token)) { // Skip the ";", but make sure it's present pfile = engine->COM_ParseFile(pfile, token); if (stricmp(token,":")) { Msg( "ERROR: LoadSchd (%s): (%s) Malformed AI Schedule. Expecting ':' after type 'ACTIVITY.\n",prefix,new_schedule->GetName()); Assert(0); return false; } // Load the activity and make sure its valid pfile = engine->COM_ParseFile(pfile, token); // Convert generic ID to sub-class specific enum int taskID = CAI_BaseNPC::GetTaskID(token); tempTask[taskNum].flTaskData = (pIdSpace) ? pIdSpace->TaskGlobalToLocal(taskID) : AI_RemapFromGlobal( taskID ); if (tempTask[taskNum].flTaskData == -1) { Msg( "ERROR: LoadSchd (%s): (%s) Unknown task %s!\n", prefix,new_schedule->GetName(), token); Assert(0); return false; } } else if (!stricmp("Schedule",token)) { // Skip the ";", but make sure it's present pfile = engine->COM_ParseFile(pfile, token); if (stricmp(token,":")) { Msg( "ERROR: LoadSchd (%s): (%s) Malformed AI Schedule. Expecting ':' after type 'ACTIVITY.\n",prefix,new_schedule->GetName()); Assert(0); return false; } // Load the schedule and make sure its valid pfile = engine->COM_ParseFile(pfile, token); // Convert generic ID to sub-class specific enum int schedID = CAI_BaseNPC::GetScheduleID(token); tempTask[taskNum].flTaskData = (pIdSpace) ? pIdSpace->ScheduleGlobalToLocal(schedID) : AI_RemapFromGlobal( schedID ); if (tempTask[taskNum].flTaskData == -1) { Msg( "ERROR: LoadSchd %d (%s): (%s) Unknown shedule %s!\n", __LINE__, prefix,new_schedule->GetName(), token); Assert(0); return false; } } else if (!stricmp("State",token)) { // Skip the ";", but make sure it's present pfile = engine->COM_ParseFile(pfile, token); if (stricmp(token,":")) { Msg( "ERROR: LoadSchd (%s): (%s) Malformed AI Schedule. Expecting ':' after type 'STATE.\n",prefix,new_schedule->GetName()); Assert(0); return false; } // Load the activity and make sure its valid pfile = engine->COM_ParseFile(pfile, token); tempTask[taskNum].flTaskData = CAI_SchedulesManager::GetStateID(token); if (tempTask[taskNum].flTaskData == -1) { Msg( "ERROR: LoadSchd %d (%s): (%s) Unknown shedule %s!\n", __LINE__, prefix,new_schedule->GetName(), token); Assert(0); return false; } } else if (!stricmp("Memory",token)) { // Skip the ";", but make sure it's present pfile = engine->COM_ParseFile(pfile, token); if (stricmp(token,":")) { Msg( "ERROR: LoadSchd (%s): (%s) Malformed AI Schedule. Expecting ':' after type 'STATE.\n",prefix,new_schedule->GetName()); Assert(0); return false; } // Load the activity and make sure its valid pfile = engine->COM_ParseFile(pfile, token); tempTask[taskNum].flTaskData = CAI_SchedulesManager::GetMemoryID(token); if (tempTask[taskNum].flTaskData == -1) { Msg( "ERROR: LoadSchd %d (%s): (%s) Unknown shedule %s!\n", __LINE__, prefix,new_schedule->GetName(), token); Assert(0); return false; } } else if (!stricmp("Path",token)) { // Skip the ";", but make sure it's present pfile = engine->COM_ParseFile(pfile, token); if (stricmp(token,":")) { Msg( "ERROR: LoadSchd (%s): (%s) Malformed AI Schedule. Expecting ':' after type 'PATH.\n",prefix,new_schedule->GetName()); Assert(0); return false; } // Load the activity and make sure its valid pfile = engine->COM_ParseFile(pfile, token); tempTask[taskNum].flTaskData = CAI_SchedulesManager::GetPathID( token ); if (tempTask[taskNum].flTaskData == -1) { Msg( "ERROR: LoadSchd (%s): (%s) Unknown path type %s!\n", prefix,new_schedule->GetName(), token); Assert(0); return false; } } else if (!stricmp("Goal",token)) { // Skip the ";", but make sure it's present pfile = engine->COM_ParseFile(pfile, token); if (stricmp(token,":")) { Msg( "ERROR: LoadSchd (%s): (%s) Malformed AI Schedule. Expecting ':' after type 'GOAL.\n",prefix,new_schedule->GetName()); Assert(0); return false; } // Load the activity and make sure its valid pfile = engine->COM_ParseFile(pfile, token); tempTask[taskNum].flTaskData = CAI_SchedulesManager::GetGoalID( token ); if (tempTask[taskNum].flTaskData == -1) { Msg( "ERROR: LoadSchd (%s): (%s) Unknown goal type %s!\n", prefix,new_schedule->GetName(), token); Assert(0); return false; } } else if ( !stricmp( "HintFlags",token ) ) { // Skip the ":", but make sure it's present pfile = engine->COM_ParseFile(pfile, token); if (stricmp(token,":")) { Msg( "ERROR: LoadSchd (%s): (%s) Malformed AI Schedule. Expecting ':' after type 'HINTFLAG'\n",prefix,new_schedule->GetName()); Assert(0); return false; } // Load the flags and make sure they are valid pfile = engine->COM_ParseFile( pfile, token ); tempTask[taskNum].flTaskData = CAI_Hint::GetFlags( token ); if (tempTask[taskNum].flTaskData == -1) { Msg( "ERROR: LoadSchd (%s): (%s) Unknown hint flag type %s!\n", prefix,new_schedule->GetName(), token); Assert(0); return false; } } else if (!stricmp("Interrupts",token) || !strnicmp("TASK_",token,5) ) { // a parse error. Interrupts is the next section, TASK_ is probably the next task, missing task argument? Warning( "ERROR: LoadSchd (%s): (%s) Bad syntax at task #%d (wasn't expecting %s)\n", prefix, new_schedule->GetName(), taskNum, token); Assert(0); return false; } else { tempTask[taskNum].flTaskData = atof(token); } taskNum++; // Read the next token Q_strncpy(save_token,token,sizeof(save_token)); pfile = engine->COM_ParseFile(pfile, token); // Check for malformed task argument type if (!stricmp(token,":")) { Msg( "ERROR: LoadSchd (%s): Schedule (%s),\n Task (%s), has a malformed AI Task Argument = (%s)\n", prefix,new_schedule->GetName(),taskID,save_token); Assert(0); return false; } } // Now copy the tasks into the new schedule new_schedule->m_iNumTasks = taskNum; new_schedule->m_pTaskList = new Task_t[taskNum]; for (int i=0;i<taskNum;i++) { new_schedule->m_pTaskList[i].iTask = tempTask[i].iTask; new_schedule->m_pTaskList[i].flTaskData = tempTask[i].flTaskData; Assert( AI_IdIsLocal( new_schedule->m_pTaskList[i].iTask ) ); } // ========================== // Now read in the interrupts // ========================== pfile = engine->COM_ParseFile(pfile, token); while ((token[0]!=NULL) && (stricmp("Schedule",token))) { // Convert generic ID to sub-class specific enum int condID = CAI_BaseNPC::GetConditionID(token); // If not a valid condition, send a warning message if (condID == -1) { Msg( "ERROR: LoadSchd (%s): Schedule (%s), Unknown condition %s!\n", prefix,new_schedule->GetName(),token); Assert(0); } // Otherwise, add to this schedules list of conditions else { int interrupt = AI_RemapFromGlobal(condID); Assert( AI_IdIsGlobal( condID ) && interrupt >= 0 && interrupt < MAX_CONDITIONS ); new_schedule->m_InterruptMask.SetBit(interrupt); } // Read the next token pfile = engine->COM_ParseFile(pfile, token); } } return true; }