예제 #1
0
파일: ai_script.c 프로젝트: morsik/warpig
/*
================
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");
		}
	}
}
예제 #2
0
/*
=============
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;
}