Пример #1
0
void DThinker::RunThinkers ()
{
	int i, count;

	ThinkCycles.Reset();
	BotSupportCycles.Reset();
	BotWTG = 0;

	ThinkCycles.Clock();

	// Tick every thinker left from last time
	for (i = STAT_FIRST_THINKING; i <= MAX_STATNUM; ++i)
	{
		TickThinkers (&Thinkers[i], NULL);
	}

	// Keep ticking the fresh thinkers until there are no new ones.
	do
	{
		count = 0;
		for (i = STAT_FIRST_THINKING; i <= MAX_STATNUM; ++i)
		{
			count += TickThinkers (&FreshThinkers[i], &Thinkers[i]);
		}
	} while (count != 0);

	ThinkCycles.Unclock();
}
Пример #2
0
bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, FState **stateret)
{
	if (ActionFunc != nullptr)
	{
		ActionCycles.Clock();

		VMValue params[3] = { self, stateowner, VMValue(info) };
		// If the function returns a state, store it at *stateret.
		// If it doesn't return a state but stateret is non-nullptr, we need
		// to set *stateret to nullptr.
		if (stateret != nullptr)
		{
			*stateret = nullptr;
			if (ActionFunc->Proto == nullptr ||
				ActionFunc->Proto->ReturnTypes.Size() == 0 ||
				ActionFunc->Proto->ReturnTypes[0] != TypeState)
			{
				stateret = nullptr;
			}
		}
		try
		{
			if (stateret == nullptr)
			{
				VMCall(ActionFunc, params, ActionFunc->ImplicitArgs, nullptr, 0);
			}
			else
			{
				VMReturn ret;
				ret.PointerAt((void **)stateret);
				VMCall(ActionFunc, params, ActionFunc->ImplicitArgs, &ret, 1);
			}
		}
		catch (CVMAbortException &err)
		{
			err.MaybePrintMessage();
			const char *callinfo = "";
			if (info != nullptr && info->mStateType == STATE_Psprite)
			{
				if (stateowner->IsKindOf(NAME_Weapon) && stateowner != self) callinfo = "weapon ";
				else callinfo = "overlay ";
			}
			err.stacktrace.AppendFormat("Called from %sstate %s in %s\n", callinfo, FState::StaticGetStateName(this).GetChars(), stateowner->GetClass()->TypeName.GetChars());
			throw;
			throw;
		}

		ActionCycles.Unclock();
		return true;
	}
	else
	{
		return false;
	}
}
Пример #3
0
bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, FState **stateret)
{
	if (ActionFunc != NULL)
	{
		ActionCycles.Clock();

		static VMFrameStack stack;
		VMValue params[3] = { self, stateowner, VMValue(info, ATAG_STATEINFO) };
		// If the function returns a state, store it at *stateret.
		// If it doesn't return a state but stateret is non-NULL, we need
		// to set *stateret to NULL.
		if (stateret != NULL)
		{
			*stateret = NULL;
			if (ActionFunc->Proto == NULL ||
				ActionFunc->Proto->ReturnTypes.Size() == 0 ||
				ActionFunc->Proto->ReturnTypes[0] != TypeState)
			{
				stateret = NULL;
			}
		}
		if (stateret == NULL)
		{
			stack.Call(ActionFunc, params, countof(params), NULL, 0, NULL);
		}
		else
		{
			VMReturn ret;
			ret.PointerAt((void **)stateret);
			stack.Call(ActionFunc, params, countof(params), &ret, 1, NULL);
		}
		ActionCycles.Unclock();
		return true;
	}
	else
	{
		return false;
	}
}
Пример #4
0
//This function is called every tick (from g_game.c),
//send bots into thinking (+more).
void FCajunMaster::Main (int buf)
{
	int i;

	BotThinkCycles.Reset();

	if (consoleplayer != Net_Arbitrator || demoplayback)
		return;

	if (gamestate != GS_LEVEL)
		return;

	m_Thinking = true;

	//Think for bots.
	if (botnum)
	{
		BotThinkCycles.Clock();
		for (i = 0; i < MAXPLAYERS; i++)
		{
			if (playeringame[i] && players[i].mo && !freeze && players[i].isbot)
				Think (players[i].mo, &netcmds[i][buf]);
		}
		BotThinkCycles.Unclock();
	}

	//Add new bots?
	if (wanted_botnum > botnum && !freeze)
	{
		if (t_join == ((wanted_botnum - botnum) * SPAWN_DELAY))
		{
            if (!SpawnBot (getspawned[spawn_tries]))
				wanted_botnum--;
            spawn_tries++;
		}

		t_join--;
	}

	//Check if player should go observer. Or un observe
	if (bot_observer && !observer && !netgame)
	{
		Printf ("%s is now observer\n", players[consoleplayer].userinfo.netname);
		observer = true;
		players[consoleplayer].mo->UnlinkFromWorld ();
		players[consoleplayer].mo->flags = MF_DROPOFF|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOTDMATCH|MF_NOGRAVITY|MF_FRIENDLY;
		players[consoleplayer].mo->flags2 |= MF2_FLY;
		players[consoleplayer].mo->LinkToWorld ();
	}
	else if (!bot_observer && observer && !netgame) //Go back
	{
		Printf ("%s returned to the fray\n", players[consoleplayer].userinfo.netname);
		observer = false;
		players[consoleplayer].mo->UnlinkFromWorld ();
		players[consoleplayer].mo->flags = MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|MF_PICKUP|MF_NOTDMATCH|MF_FRIENDLY;
		players[consoleplayer].mo->flags2 &= ~MF2_FLY;
		players[consoleplayer].mo->LinkToWorld ();
	}

	m_Thinking = false;
}