/* ================ Bot_ScriptChange ================ */ void Bot_ScriptChange(bot_state_t *bs, int newScriptNum) { bot_script_status_t statusBackup; bs->script.callIndex++; // backup the current scripting statusBackup = bs->script.status; // set the new script to this cast, and reset script status bs->script.status.stackHead = 0; bs->script.status.stackChangeTime = level.time; bs->script.status.eventIndex = newScriptNum; bs->script.status.id = statusBackup.id + 1; // first call bs->script.flags |= BSFL_FIRST_CALL; Bot_ScriptLog_Entry(bs, qfalse, Bot_LineText(bs->script.data->events[bs->script.status.eventIndex].text), "** NEW EVENT **\r\n"); // try and run the script, if it doesn't finish, then abort the current script (discard backup) if (Bot_ScriptRun(bs, qtrue)) { // completed successfully bs->script.status.stackHead = statusBackup.stackHead; bs->script.status.stackChangeTime = statusBackup.stackChangeTime; bs->script.status.eventIndex = statusBackup.eventIndex; bs->script.status.id = statusBackup.id; // bs->script.flags &= ~BSFL_FIRST_CALL; // returned to previous event if (statusBackup.eventIndex > -1) { Bot_ScriptLog_Entry(bs, qfalse, Bot_LineText(bs->script.data->events[statusBackup.eventIndex].text), "**RESUMED**\r\n"); } } else { // still running, previous script is terminated if (statusBackup.eventIndex > -1 && statusBackup.eventIndex != bs->script.status.eventIndex) { Bot_ScriptLog_Entry(bs, qfalse, Bot_LineText(bs->script.data->events[statusBackup.eventIndex].text), "**TERMINATED**\r\n"); } } }
/* ============= Bot_ScriptRun returns qtrue if the script completed ============= */ qboolean Bot_ScriptRun(bot_state_t * bs, qboolean force) { bot_script_stack_t *stack; bot_script_stack_item_t *item; int oldScriptId; if(!bs->script.data) { return qtrue; } // turn off flags that get set each frame while they are active bs->script.frameFlags = 0; if(bs->script.status.eventIndex < 0) { return qtrue; } if(!bs->script.data->events) { bs->script.status.eventIndex = -1; return qtrue; } if(!force && (bs->script.pauseTime >= level.time)) { return qtrue; } stack = &bs->script.data->events[bs->script.status.eventIndex].stack; if(!stack->numItems) { bs->script.status.eventIndex = -1; return qtrue; } while(bs->script.status.stackHead < stack->numItems) { item = &bs->script.data->items[stack->startIndex + bs->script.status.stackHead]; bs->script.status.currentItem = item; // if(bs->script.flags & BSFL_FIRST_CALL) { Bot_ScriptLog_Entry(bs, qtrue, Bot_LineText(bs->script.data->events[bs->script.status.eventIndex].text), ""); } // oldScriptId = bs->script.status.id; // // Mad Doc - TDf if(G_IsSinglePlayerGame()) { if(bot_debug.integer) { trap_SendServerCommand(0, va("botdebugprint %i \"Line: %i %s %s\"", bs->client, Bot_Script_GetCurrentLine(bs), item->action->actionString, item->params)); } } if(!item->action->actionFunc(bs, item->params)) { bs->script.flags &= ~BSFL_FIRST_CALL; return qfalse; } // if our script changed, stop execution if(oldScriptId != bs->script.status.id) { return qfalse; } // move to the next action in the script bs->script.status.stackHead++; // record the time that this new item became active bs->script.status.stackChangeTime = level.time; // reset misc stuff bs->script.flags |= BSFL_FIRST_CALL; } Bot_ScriptLog_Entry(bs, qtrue, Bot_LineText(bs->script.data->events[bs->script.status.eventIndex].text), "** FINISHED **"); bs->script.status.eventIndex = -1; return qtrue; }