SUnlock::SUnlock(XmlNodeRef node, int rank)
{
	m_name[0] = '\0';
	m_rank = rank;
	m_reincarnation = 0;
	m_unlocked = false;
	m_type = eUT_Invalid;

	DesignerWarning(strcmpi(node->getTag(), "unlock") == 0 || strcmpi(node->getTag(), "allow") == 0, "expect tag of unlock or allow at %d", node->getLine());

	const char * theName = node->getAttr("name");
	const char * theType = node->getAttr("type");
	const char * theReincarnationLevel = node->getAttr("reincarnation");

	// These pointers should always be valid... if an attribute isn't found, getAttr returns a pointer to an empty string [TF]
	assert (theName && theType);

	if (theType && theType[0] != '\0')
	{
		m_type = SUnlock::GetUnlockTypeFromName(theType);
		cry_strcpy(m_name, theName);

		bool expectName = (m_type == eUT_Loadout || m_type == eUT_Weapon || m_type == eUT_Attachment || m_type == eUT_Playlist || m_type == eUT_CreateCustomClass);
		bool gotName = (theName[0] != '\0');

		if (expectName != gotName && m_type != eUT_Invalid) // If it's invalid, we'll already have displayed a warning...
		{
			GameWarning("[PROGRESSION] An unlock of type '%s' %s have a name but XML says name='%s'", theType, expectName ? "should" : "shouldn't", theName);
		}
	}
	else
	{
		GameWarning("[PROGRESSION] XML node contains an 'unlock' tag with no type (name='%s')", theName);
	}

	if (theReincarnationLevel != NULL && theReincarnationLevel[0] != '\0')
	{
		m_reincarnation = atoi(theReincarnationLevel);
		CPlayerProgression *pPlayerProgression = CPlayerProgression::GetInstance();
		DesignerWarning(m_reincarnation > 0 && m_reincarnation < pPlayerProgression->GetMaxReincarnations()+1, "Unlock %s reincarnation parameter is outside of the range 0 - %d", theName, pPlayerProgression->GetMaxReincarnations()+1);
	}
}
示例#2
0
bool CAutoTester::GetParam(const char **str, char outName[], int inNameMaxSize, char outValue[], int inValueMaxSize, char breakAtChar)
{
	bool success=false;
	int nameLength;
	int valueLength;

	assert(str);
	assert(outName);
	assert(outValue);

	outName[0]=0;
	outValue[0]=0;

	// Get Name
	if (*str)
	{
		nameLength=cry_copyStringUntilFindChar(outName, *str, inNameMaxSize, ':');

		if (nameLength)
		{
			*str += nameLength;

			valueLength=cry_copyStringUntilFindChar(outValue, *str, inValueMaxSize, breakAtChar);
			success=true;

			// Get Value
			if (valueLength)
			{
				*str+= valueLength;
			}
			else
			{
				*str = NULL;
			}
		}
		else
		{
			DesignerWarning (outName[0] == '\0', "Syntax error in auto tester initialization string: found '%s' at end of string, expected 'key:value' format", outName);
		}
	}

	if (success)
	{
		CryLogAlways ("CAutoTester::GetParam found parameter called '%s' with value '%s'", outName, outValue);
	}
	else
	{
		CryLogAlways ("CAutoTester::GetParam found no more parameters");
	}

	return success;
}
//---------------------------------------
void CAreaAnnouncer::LoadAnnouncementArea(const IEntity* pEntity, const char* areaName)
{
	TAudioSignalID signal[AREA_ANNOUNCERS];

	stack_string signalName;
	for(int i = 0; i < AREA_ANNOUNCERS; i++)
	{
		signalName.Format("%s_%d", areaName, i + 1);
		signal[i] = g_pGame->GetGameAudio()->GetSignalID(signalName.c_str(), false);
	}

#if !defined(_RELEASE)
	if(aa_debug)
	{
		CryLogAlways("[AA] Found area '%s' with Signals %d, %d", areaName, signal[0], signal[1]);
	}
#endif

	if(signal[0] != INVALID_AUDIOSIGNAL_ID && signal[1] != INVALID_AUDIOSIGNAL_ID)
	{
		SAnnouncementArea area;
		area.m_areaProxyId = pEntity->GetId();
		COMPILE_TIME_ASSERT(sizeof(area.m_signal) == sizeof(signal));
		memcpy(area.m_signal, signal, sizeof(area.m_signal));

#if !defined(_RELEASE)
		cry_strncpy(&area.m_name[0], areaName, SAnnouncementArea::k_maxNameLength);
#endif

		DesignerWarning(m_areaList.size() < k_maxAnnouncementAreas, "Too many AreaAnnouncer area boxes loaded");
		if(m_areaList.size() < k_maxAnnouncementAreas)
		{
			m_areaList.push_back(area);
		}
	}

#if !defined(_RELEASE)
	//Found one signal but not both
	if(signal[0] != signal[1] && (signal[0] == INVALID_AUDIOSIGNAL_ID || signal[1] == INVALID_AUDIOSIGNAL_ID))
	{
#if defined(USER_benp)
		CRY_ASSERT_MESSAGE(0, ("'%s' only has signal for 1 team!", areaName));
#endif
		CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "'%s' only has signal for 1 team!", areaName);
	}
#endif

}
void CPlayerPlugin_InteractiveEntityMonitor::Register( IEntity* pEntity, uint8 initialFlags )
{
	if(!pEntity)
		return;

	const EntityId entityId = pEntity->GetId();

	//Make sure we aren't registering twice
	InteractiveEntityList::iterator iter = m_interactiveEntityList.begin();
	InteractiveEntityList::iterator end = m_interactiveEntityList.end();
	while(iter != end)
	{
		if(iter->first == entityId)
		{
#ifndef _RELEASE
			CryLog("[ERROR] InteractiveEntityMonitor. Registering the same entity twice: '%s'. Tell Gary (Really this time).", pEntity->GetName());
			DesignerWarning(false, "InteractiveEntityMonitor. Registering the same entity twice: '%s'. Tell Gary (Really this time).", pEntity->GetName());
#endif //_RELEASE
			//Don't crash
			return;
		}
		++iter;
	}

#ifndef _RELEASE
	m_debugMap[pEntity->GetId()] = pEntity->GetName();
#endif //_RELEASE

	m_interactiveEntityList.push_back( InteractiveEntityStatus(entityId, initialFlags) );

	//Check if it should already be on
	if(m_bEnabled && GetOwnerPlayer()->GetEntity()->GetWorldPos().GetSquaredDistance2D(pEntity->GetWorldPos()) < g_pGameCVars->g_highlightingMovementDistanceToUpdateSquared)
	{
		if(IEntityRenderProxy* pRenderProxy = static_cast<IEntityRenderProxy *>(pEntity->GetProxy(ENTITY_PROXY_RENDER)))
		{
			if( (initialFlags & EIES_ShootToInteract) == 0 )
			{
				pRenderProxy->SetHUDSilhouettesParams(m_silhouetteInteractColor.r, m_silhouetteInteractColor.g, m_silhouetteInteractColor.b, m_silhouetteInteractColor.a);
			}
			else
			{
				pRenderProxy->SetHUDSilhouettesParams(m_silhouetteShootColor.r, m_silhouetteShootColor.g, m_silhouetteShootColor.b, m_silhouetteShootColor.a);
			}
		}
	}
}
示例#5
0
void CLedgeManagerEdit::RegisterLedge( EntityId entityId, const SLedgeMarker* pMarkersArray, const uint32 markerCount, ELedgeFlagBitfield ledgeInFlags, ELedgeFlagBitfield ledgeOutFlags, float ledgeCornerMaxAngle, float ledgeCornerEndAdjustAmount )
{
	if (markerCount == 0)
		return;

	TLedgeObjectsEditorContainer::iterator ledgeIt = std::find(m_ledgeObjects.begin(), m_ledgeObjects.end(), entityId);
	const bool notRegistered = ledgeIt == m_ledgeObjects.end();

	if (notRegistered)
	{
		if ( m_ledgeObjects.size() == m_ledgeObjects.max_size() )
		{
			DesignerWarning( true, "Exceeding maximum ledge count, %d! Not possible to register this ledge in the manager", MAX_LEDGE_ENTITIES);
			return;
		}
		m_ledgeObjects.push_back( SLedgeObjectEditor() );
	}

	SLedgeObjectEditor& ledgeObject = notRegistered ? m_ledgeObjects.back() : *ledgeIt;
	
	ledgeObject.m_entityId = entityId;
	ledgeObject.m_ledgeFlags[LedgeSide_In] = ledgeInFlags;
	ledgeObject.m_ledgeFlags[LedgeSide_Out] = ledgeOutFlags;
	ledgeObject.m_ledgeCornerMaxAngle = ledgeCornerMaxAngle;
	ledgeObject.m_ledgeCornerEndAdjustAmount = ledgeCornerEndAdjustAmount;

	if (ledgeObject.m_markers.size() != markerCount)
	{
		ledgeObject.m_markers.resize(markerCount);
	}
	
	for (uint32 markerIdx = 0; markerIdx < markerCount; ++markerIdx)
	{
		ledgeObject.m_markers[markerIdx] = pMarkersArray[markerIdx];
	}
}
void CPlayerPlugin_InteractiveEntityMonitor::Update( const float dt )
{
	m_timeUntilRefresh -= dt;

#ifndef _RELEASE
	//Verify entity integrity
	InteractiveEntityDebugMap::iterator mapIter = m_debugMap.begin();
	InteractiveEntityDebugMap::iterator mapEnd = m_debugMap.end();
	while(mapIter != mapEnd)
	{
		if(!gEnv->pEntitySystem->GetEntity(mapIter->first))
		{
			CryLog("[ERROR] InteractiveEntityMonitor. About to crash. Registered entity no longer exists: '%s'. Tell Gary (Really this time).", mapIter->second.c_str());
			DesignerWarning(false, "[ERROR] InteractiveEntityMonitor. About to crash. Registered entity no longer exists: '%s'. Tell Gary (Really this time).", mapIter->second.c_str());
		}

		++mapIter;
	}
#endif //_RELEASE

	IEntitySystem* pEntitySys = gEnv->pEntitySystem;
	const Vec3& playerPos = GetOwnerPlayer()->GetEntity()->GetWorldTM().GetColumn3();
	if(m_bEnabled && (m_timeUntilRefresh < 0.f || playerPos.GetSquaredDistance2D(m_playerPrevPos) > g_pGameCVars->g_highlightingMovementDistanceToUpdateSquared))
	{
		for(InteractiveEntityList::iterator it = m_interactiveEntityList.begin(); it!=m_interactiveEntityList.end(); )
		{
			const EntityId entityId = it->first;
			IEntity* pEntity = pEntitySys->GetEntity(entityId);
			if(!pEntity)
			{
				it=m_interactiveEntityList.erase(it);
				continue;
			}

			if (IEntityRenderProxy* pRenderProxy = static_cast<IEntityRenderProxy *>(pEntity->GetProxy(ENTITY_PROXY_RENDER)))
			{
				const Vec3& entityPos = pEntity->GetWorldTM().GetColumn3();
				const float distSq = entityPos.GetSquaredDistance2D(playerPos);

				const bool withinHighlightDistance = distSq <= g_pGameCVars->g_highlightingMaxDistanceToHighlightSquared;
				if( withinHighlightDistance )
				{
					// Apply intensity fade over outer half distance
					float alpha = distSq * 2.0f - g_pGameCVars->g_highlightingMaxDistanceToHighlightSquared;
					alpha *= __fres(g_pGameCVars->g_highlightingMaxDistanceToHighlightSquared);
					alpha = 1.0f - clamp(alpha, 0.0f, 1.0f);

					if( (it->second & EIES_ShootToInteract) == 0 )
					{
						pRenderProxy->SetHUDSilhouettesParams(m_silhouetteInteractColor.r*alpha, m_silhouetteInteractColor.g*alpha, m_silhouetteInteractColor.b*alpha, m_silhouetteInteractColor.a*alpha);
					}
					else
					{
						pRenderProxy->SetHUDSilhouettesParams(m_silhouetteShootColor.r*alpha, m_silhouetteShootColor.g*alpha, m_silhouetteShootColor.b*alpha, m_silhouetteShootColor.a*alpha);
					}
					it->second |= EIES_Highlighted;
				}
				else if( it->second & EIES_Highlighted )
				{
					pRenderProxy->SetHUDSilhouettesParams(0.f, 0.f, 0.f, 0.f);
					it->second &= ~EIES_Highlighted;
				}
			}

			++it;
		}

		m_playerPrevPos = playerPos;
		m_timeUntilRefresh = g_pGameCVars->g_highlightingTimeBetweenForcedRefresh;
	}
}
void CTeamVisualizationManager::InitTeamVisualizationData( XmlNodeRef xmlNode )
{
	if(m_teamVisualizationPartsMap.empty())
	{
		IMaterialManager *pMaterialManager = gEnv->p3DEngine->GetMaterialManager();

		// Parse Team vis data and add to m_teamVisualizationPartsMap; 
		XmlNodeRef pPlayerTeamVisualization = xmlNode->findChild("PlayerTeamVisualization");
		DesignerWarning(pPlayerTeamVisualization, "expected to find <PlayerTeamVisualization> </PlayerTeamVisualization>, not found");
		if(pPlayerTeamVisualization)
		{
			Crc32Gen* pCRCGen = gEnv->pSystem->GetCrc32Gen();

			// Grab each model setup node
			const int modelCount = pPlayerTeamVisualization->getChildCount();
			for(int i = 0; i < modelCount; ++i)
			{
				XmlNodeRef pModelSetup = pPlayerTeamVisualization->getChild(i);
				if(pModelSetup)
				{
					// Friendly 
					XmlNodeRef friendlyNode = pModelSetup->findChild("Friendly");
					DesignerWarning(friendlyNode, "missing <Friendly> </Friendly> tags in model setup <%d> - PlayerTeamVisualization.xml", i);
					if(friendlyNode)
					{
						// Hostile
						XmlNodeRef hostileNode = pModelSetup->findChild("Hostile");
						DesignerWarning(hostileNode, "missing <Hostile> </Hostile> tags in model setup <%d> - PlayerTeamVisualization.xml", i);
						if(hostileNode)
						{

							XmlNodeRef attachmentsNode = pModelSetup->findChild("BodyAttachments");
							const int numAttachments = attachmentsNode->getChildCount();
							DesignerWarning(attachmentsNode && numAttachments > 0, "missing <BodyAttachments> </bodyAttachments> tags in model setup <%d> or no child <BodyAttachment> elements - PlayerTeamVisualization.xml", i);
							if(attachmentsNode && numAttachments > 0)
							{
								const char* pModelName = pModelSetup->getAttr("name");
								DesignerWarning(pModelName && pModelName[0], "missing <Model> tag - or <Model name=""> attribute invalid - in model setup <%d> - PlayerTeamVisualization.xml", i);
								if(pModelName && pModelName[0])
								{
									// Add new + Fill in details
									TModelNameCRC modelNameCRC = pCRCGen->GetCRC32Lowercase(pModelName); 
									CRY_ASSERT(m_teamVisualizationPartsMap.find(modelNameCRC) == m_teamVisualizationPartsMap.end());
									m_teamVisualizationPartsMap[modelNameCRC] = SModelMaterialSetup(); 
									SModelMaterialSetup& newConfig = m_teamVisualizationPartsMap[modelNameCRC];

									// Get materials
									newConfig.SetMaterial(eMI_AliveFriendly, pMaterialManager->LoadMaterial(friendlyNode->getAttr("MaterialName")));
									newConfig.SetMaterial(eMI_AliveHostile, pMaterialManager->LoadMaterial(hostileNode->getAttr("MaterialName")));

									// Hostile
									XmlNodeRef deadFriendlyNode = pModelSetup->findChild("DeadFriendly");
									DesignerWarning(deadFriendlyNode, "missing <DeadFriendly> </DeadFriendly> tags in model setup <%d> - PlayerTeamVisualization.xml", i);
									if(deadFriendlyNode)
									{
										newConfig.SetMaterial(eMI_DeadFriendly, pMaterialManager->LoadMaterial(deadFriendlyNode->getAttr("MaterialName")));
									}

									XmlNodeRef deadHostileNode = pModelSetup->findChild("DeadHostile");
									DesignerWarning(deadHostileNode, "missing <deadHostileNode> </deadHostileNode> tags in model setup <%d> - PlayerTeamVisualization.xml", i);
									if(deadHostileNode)
									{
										newConfig.SetMaterial(eMI_DeadHostile, pMaterialManager->LoadMaterial(deadHostileNode->getAttr("MaterialName")));
									}

									// Attachments
									newConfig.m_attachments.reserve(numAttachments);
									for(int j = 0; j < numAttachments; ++j)
									{
										XmlNodeRef attachmentNode = attachmentsNode->getChild(j);
										newConfig.m_attachments.push_back(pCRCGen->GetCRC32Lowercase(attachmentNode->getAttr("name")));
									}	
									continue;
								}	
							}
						}
					}
				}
			}
		}
	}
}
示例#8
0
void CAutoTester::Start(const char *stateSetup, const char *outputPath, bool quitWhenDone)
{
	// If the string has any '#' characters in it (the "new" seperator) then we'll split the string up at those characters...
	// If not, we'll use '!' (the "old" seperator)
	char breakAtChar = strchr(stateSetup, '#') ? '#' : '!';

	CryLogAlways("CAutoTester::Start() stateSetup=\"%s\" outputPath=\"%s\" seperator=\"%c\"", stateSetup, outputPath, breakAtChar);
	assert(!m_started);
	m_started=true;
	
	m_outputPath=outputPath;
	m_quitWhenDone = quitWhenDone;

	const char *str=stateSetup;

	// .dll hell stops simple access to memReplay functionality so can't look for running -memReplay
	// memReplay commands all early exit if they fail anyways
	gEnv->pConsole->ExecuteString("memReplayDumpSymbols");

#define MAX_TOKEN_LEN 128

	char tokenName[MAX_TOKEN_LEN];
	char valueName[MAX_TOKEN_LEN];
	bool success;

	memset(&m_stateData, 0, sizeof(m_stateData));

	success = GetParam(&str, tokenName, MAX_TOKEN_LEN, valueName, MAX_TOKEN_LEN, breakAtChar);

	assert (m_state == ATEST_STATE_NONE);

	if (success && stricmp(tokenName, "state") == 0)
	{
		m_state = FindStateFromStr(valueName);
		cry_strncpy(m_includeThisInFileName, valueName, sizeof(m_includeThisInFileName));

		CryLogAlways("CAutoTester::Start initializing state (name='%s', id=%d, %s)", valueName, m_state, (m_state == ATEST_STATE_NONE) ? "invalid" : "valid");
		DesignerWarning (m_state != ATEST_STATE_NONE, "'%s' is not the name of an auto-test state", valueName);

		// If anything needs to default to something non-zero, set it here... 
		switch (m_state)
		{
			case ATEST_STATE_TEST_PERFORMANCE:
				m_stateData.testPerformance.m_subState = CAutoTester::k_testPerformance_substate_ingame;
				break;
		}

		// Read each parameter...
		while (GetParam(&str, tokenName, MAX_TOKEN_LEN, valueName, MAX_TOKEN_LEN, breakAtChar))
		{
			bool paramUsed = false;

			if (stricmp(tokenName, "outputName") == 0)
			{
				cry_strncpy(m_includeThisInFileName, valueName, sizeof(m_includeThisInFileName));
				CryLogAlways("CAutoTester::Start has set output name to '%s'", m_includeThisInFileName);
				m_createVerboseFilename=false;
				paramUsed = true;
			}
			else
			{
				switch (m_state)
				{
				case ATEST_STATE_TEST_NUM_CLIENTS:
					if (stricmp(tokenName, "timeToRun") == 0)
					{
						m_stateData.testNumClients.m_timeOut = (float)atof(valueName);
						paramUsed = true;
					}
					else if (stricmp(tokenName, "numClients") == 0)
					{
						m_stateData.testNumClients.m_numClientsExpected = atoi(valueName);
						paramUsed = true;
					}
					break;

				case ATEST_STATE_TEST_NUM_CLIENTS_LEVEL_ROTATE:
					if (stricmp(tokenName, "timeToRunEachLevel") == 0)
					{
						m_stateData.testNumClientsRotate.m_levelTimeOut = (float)atof(valueName);
						paramUsed = true;
					}
					else if (stricmp(tokenName, "numClients") == 0)
					{
						m_stateData.testNumClientsRotate.m_numClientsExpected = atoi(valueName);
						paramUsed = true;
					}
					else if (stricmp(tokenName, "timeToRunFirstLevel") == 0)
					{														 
						m_stateData.testNumClientsRotate.m_firstLevelTimeOut = (float)atof(valueName);
						paramUsed = true;
					}
					break;

#if ENABLE_FEATURE_TESTER
				case ATEST_STATE_TEST_FEATURES:
					if (stricmp(tokenName, "rules") == 0)
					{
						CryLogAlways ("CAutoTester::Start executing 'sv_gamerules %s'", valueName);
						gEnv->pConsole->ExecuteString(string().Format("sv_gamerules %s", valueName));
						paramUsed = true;
					}
					else if (stricmp(tokenName, "level") == 0)
					{
						IGameRulesSystem * gameRulesSystem = gEnv->pGame->GetIGameFramework()->GetIGameRulesSystem();
						const char * sv_gamerules = gEnv->pConsole->GetCVar("sv_gamerules")->GetString();
						const char * fullGameRulesName = gameRulesSystem->GetGameRulesName(sv_gamerules);
						bool isMultiPlayerMode = (fullGameRulesName && strcmp(fullGameRulesName, "SinglePlayer") != 0);
						const char * additionalParams = isMultiPlayerMode ? " s nb" : "";
						if (gEnv->bMultiplayer != isMultiPlayerMode)
						{
							GameWarning("Auto-tester is loading '%s' in mode '%s' while environment is set up for %s", valueName, sv_gamerules, gEnv->bMultiplayer ? "multi-player" : "single-player");
						}
						CryLogAlways ("CAutoTester::Start executing 'map %s%s' (mode is '%s' i.e. '%s' so isMultiPlayer=%d)", valueName, additionalParams, sv_gamerules, fullGameRulesName, isMultiPlayerMode);
						if (isMultiPlayerMode)
						{
							gEnv->pConsole->ExecuteString("net_setonlinemode lan");
						}
						gEnv->pConsole->ExecuteString(string().Format("map %s%s", valueName, additionalParams));
						paramUsed = true;
					}
					else if (stricmp(tokenName, "set") == 0)
					{
						cry_strncpy(m_stateData.testRunFeatureTests.m_setNames, valueName, sizeof(m_stateData.testRunFeatureTests.m_setNames));
						paramUsed = true;
					}
					else if (stricmp(tokenName, "file") == 0)
					{
						cry_strncpy(m_stateData.testRunFeatureTests.m_loadFileName, valueName, sizeof(m_stateData.testRunFeatureTests.m_loadFileName));
						paramUsed = true;
					}
					break;
#endif

				case ATEST_STATE_TEST_PERFORMANCE:
					if (stricmp(tokenName, "configFile") == 0)
					{
						cry_strncpy(m_stateData.testPerformance.m_configFile, valueName, 256);
						//m_stateData.testPerformance.m_configFile = valueName;
						CryLogAlways ("CAutoTester::Start configFile set '%s'", valueName);
						paramUsed = true;
					}
					else if (stricmp(tokenName, "timeToRun") == 0)
					{
						m_stateData.testPerformance.m_timeOut = (float)atof(valueName);
						paramUsed = true;
					}
					else if (stricmp(tokenName, "delayToStart") == 0)
					{
						m_stateData.testPerformance.m_delayToStart = (float)atof(valueName);
						paramUsed = true;
					}
					break;
				}

				DesignerWarning(paramUsed, "Unexpected key/value pair '%s'='%s' in %s setup string!", tokenName, valueName, s_autoTesterStateNames[m_state]);
			}
		}

		// All parameters have been read... now finish initialization
		switch (m_state)
		{
		case ATEST_STATE_TEST_NUM_CLIENTS_LEVEL_ROTATE:
			{
				if (m_stateData.testNumClientsRotate.m_firstLevelTimeOut == 0)
				{
					CryLogAlways("no timeToRunFirstLevel set, setting to timeToRunEachLevel=%d", (int)m_stateData.testNumClientsRotate.m_levelTimeOut);
					m_stateData.testNumClientsRotate.m_firstLevelTimeOut = m_stateData.testNumClientsRotate.m_levelTimeOut;
				}

				float timeSeconds=gEnv->pTimer->GetFrameStartTime().GetSeconds();
				m_stateData.testNumClientsRotate.m_nextTimeOut = timeSeconds + m_stateData.testNumClientsRotate.m_firstLevelTimeOut;

				// level rotation is setup with +sv_levelrotation levelrotation.xml and also -root to override looking in the profile dir






				gEnv->pConsole->ExecuteString("g_nextlevel");	// has to be a better way of doing this

				break;
			}

		case ATEST_STATE_TEST_FEATURES:
#if ENABLE_FEATURE_TESTER
			m_writeResultsCompleteTestCasePass = true;

			if (m_stateData.testRunFeatureTests.m_loadFileName[0])
			{
				gEnv->pConsole->ExecuteString(string().Format("ft_load %s", m_stateData.testRunFeatureTests.m_loadFileName));
			}

			if (m_stateData.testRunFeatureTests.m_setNames[0])
			{
				CFeatureTester::GetInstance()->InformAutoTesterOfResults(this);
				gEnv->pConsole->ExecuteString(string().Format("ft_runAll %s", m_stateData.testRunFeatureTests.m_setNames));
			}
#else
			DesignerWarning(false, "Feature tester is not included in this build!");
#endif
			break;
		}
	}
	else
	{
		CRY_ASSERT_MESSAGE(0, string().Format("CAutoTester::Start() failed to find state at start in %s", stateSetup));
	}

	// TODO will maybe need to load in the existing file if we want all tests in the same file... junit/bamboo should cope with each test in a different file?
}