コード例 #1
0
ファイル: CTopologyNode.cpp プロジェクト: bmer/Mammoth
ALERROR CTopologyNode::InitFromSystemXML (CXMLElement *pSystem, CString *retsError)

//	InitFromSystemXML
//
//	Initializes the system information based on an XML element.
//	NOTE: We assume the universe is fully bound at this point.

	{
	ALERROR error;
	CString sSystemUNID = pSystem->GetAttribute(UNID_ATTRIB);
	DWORD dwUNID = strToInt(sSystemUNID, 0, NULL);

	//	If the system node contains a table of different system types, then
	//	remember the root node because some of the system information (such as the
	//	name) may be there.

	CXMLElement *pSystemParent = NULL;

	//	If there is no UNID attribute then it means that the system
	//	is randomly determined based on a table

	if (dwUNID == 0 && pSystem->GetContentElementCount() == 1)
		{
		CXMLElement *pTableElement = pSystem->GetContentElement(0);
		if (pTableElement == NULL)
			{
			ASSERT(false);
			return ERR_FAIL;
			}

		CRandomEntryResults System;
		if (error = CRandomEntryGenerator::Generate(pTableElement, System))
			{
			*retsError = strPatternSubst(CONSTLIT("Topology %s: Unable to generate random system UNID"), m_sID);
			return ERR_FAIL;
			}

		if (System.GetCount() != 1)
			{
			*retsError = strPatternSubst(CONSTLIT("Topology %s: Table generated no systems"), m_sID);
			return ERR_FAIL;
			}

		pSystemParent = pSystem;
		pSystem = System.GetResult(0);
		dwUNID = pSystem->GetAttributeInteger(UNID_ATTRIB);
		}

	//	Set the system UNID

	if (dwUNID != 0)
		m_SystemUNID = dwUNID;

	//	Get the system type

	CSystemType *pSystemType = g_pUniverse->FindSystemType(m_SystemUNID);

	//	Set the name of the system

	CString sName;
	if (!pSystem->FindAttribute(NAME_ATTRIB, &sName))
		if (pSystemParent)
			sName = pSystemParent->GetAttribute(NAME_ATTRIB);

	if (!sName.IsBlank())
		SetName(sName);

	//	Set the level

	int iLevel = 0;
	if (!pSystem->FindAttributeInteger(LEVEL_ATTRIB, &iLevel))
		if (pSystemParent)
			iLevel = pSystemParent->GetAttributeInteger(LEVEL_ATTRIB);

	if (iLevel > 0)
		SetLevel(iLevel);

	if (GetLevel() == 0)
		SetLevel(1);

	//	Add variants for the system

	CString sVariant;
	if (pSystem->FindAttribute(VARIANT_ATTRIB, &sVariant))
		AddVariantLabel(sVariant);

	if (pSystemParent && pSystemParent->FindAttribute(VARIANT_ATTRIB, &sVariant))
		AddVariantLabel(sVariant);

	//	Add attributes for the node/system

	CString sAttribs;
	if (pSystem->FindAttribute(ATTRIBUTES_ATTRIB, &sAttribs))
		AddAttributes(sAttribs);

	if (pSystemParent && pSystemParent->FindAttribute(ATTRIBUTES_ATTRIB, &sAttribs))
		AddAttributes(sAttribs);

	if (pSystemType && !pSystemType->GetAttributes().IsBlank())
		AddAttributes(pSystemType->GetAttributes());

	return NOERROR;
	}
コード例 #2
0
ファイル: CTopologyNode.cpp プロジェクト: bmer/Mammoth
ALERROR CTopologyNode::ParseCriteria (CXMLElement *pCrit, SCriteria *retCrit, CString *retsError)

//	ParseCriteria
//
//	Parses an XML element into a criteria desc

	{
	int i;

	retCrit->iChance = 100;
	retCrit->iMaxInterNodeDist = -1;
	retCrit->iMinInterNodeDist = 0;
	retCrit->iMaxStargates = -1;
	retCrit->iMinStargates = 0;

	if (pCrit)
		{
		for (i = 0; i < pCrit->GetContentElementCount(); i++)
			{
			CXMLElement *pItem = pCrit->GetContentElement(i);

			if (strEquals(pItem->GetTag(), ATTRIBUTES_TAG))
				{
				CString sCriteria = pItem->GetAttribute(CRITERIA_ATTRIB);
				ParseCriteriaInt(sCriteria, retCrit);
				}
			else if (strEquals(pItem->GetTag(), CHANCE_TAG))
				{
				retCrit->iChance = pItem->GetAttributeIntegerBounded(CHANCE_ATTRIB, 0, 100, 100);
				}
			else if (strEquals(pItem->GetTag(), DISTANCE_BETWEEN_NODES_TAG))
				{
				retCrit->iMinInterNodeDist = pItem->GetAttributeIntegerBounded(MIN_ATTRIB, 0, -1, 0);
				retCrit->iMaxInterNodeDist = pItem->GetAttributeIntegerBounded(MAX_ATTRIB, 0, -1, -1);
				}
			else if (strEquals(pItem->GetTag(), DISTANCE_TO_TAG))
				{
				SDistanceTo *pDistTo = retCrit->DistanceTo.Insert();
				pDistTo->iMinDist = pItem->GetAttributeIntegerBounded(MIN_ATTRIB, 0, -1, 0);
				pDistTo->iMaxDist = pItem->GetAttributeIntegerBounded(MAX_ATTRIB, 0, -1, -1);

				CString sCriteria;
				if (pItem->FindAttribute(CRITERIA_ATTRIB, &sCriteria))
					{
					SCriteria Criteria;
					if (ParseCriteriaInt(sCriteria, &Criteria) != NOERROR)
						{
						*retsError = strPatternSubst(CONSTLIT("Unable to parse criteria: %s"), sCriteria);
						return ERR_FAIL;
						}

					pDistTo->AttribsRequired = Criteria.AttribsRequired;
					pDistTo->AttribsNotAllowed = Criteria.AttribsNotAllowed;
					}
				else
					pDistTo->sNodeID = pItem->GetAttribute(NODE_ID_ATTRIB);
				}
			else if (strEquals(pItem->GetTag(), STARGATE_COUNT_TAG))
				{
				retCrit->iMinStargates = pItem->GetAttributeIntegerBounded(MIN_ATTRIB, 0, -1, 0);
				retCrit->iMaxStargates = pItem->GetAttributeIntegerBounded(MAX_ATTRIB, 0, -1, -1);
				}
			else
				{
				*retsError = strPatternSubst(CONSTLIT("Unknown criteria element: %s"), pItem->GetTag());
				return ERR_FAIL;
				}
			}
		}

	return NOERROR;
	}
コード例 #3
0
ファイル: main.cpp プロジェクト: Arkheias/Transcendence
ALERROR WriteModule (CTDBCompiler &Ctx, 
					 const CString &sFilename, 
					 const CString &sFolder, 
					 CDataFile &Out, 
					 int *retiModuleEntry,
					 bool bCore)
	{
	ALERROR error;
	int i;

	//	Parse the file

	CXMLElement *pModule;
	CExternalEntityTable *pEntityTable = new CExternalEntityTable;
	CFileReadBlock DataFile(pathAddComponent(Ctx.GetRootPath(), sFilename));
	CString sError;

	printf("Parsing %s...", sFilename.GetASCIIZPointer());
	if (error = CXMLElement::ParseXML(&DataFile, Ctx.GetCoreEntities(), &pModule, &sError, pEntityTable))
		{
		printf("\n");
		Ctx.ReportError(sError);
		return error;
		}

	//	If this is a core module (embedded in the root XML) then we add these
	//	entities to the core. [Ctx takes ownership.]

	if (bCore)
		Ctx.AddEntityTable(pEntityTable);

	//	Chain entity tables (so that any modules that we load get the benefit).
	//	This will chain Ctx.pCoreEntities (and restore it in the destructor).
	//
	//	NOTE: If this is a core module, then we don't do this, since we've
	//	already added the entities to the context block.

	CSaveEntitiesTable SavedEntities(Ctx, (!bCore ? pEntityTable : NULL));

	printf("done.\n");

	//	Compress if this is NOT the main file. We can't compress the
	//	main file because we sometimes need to read it partially.

	bool bCompress = (retiModuleEntry == NULL);

	//	Write the module itself

	int iEntry;
	if (error = WriteGameFile(Ctx, sFilename, bCompress, Out, &iEntry))
		return error;

	//	If the caller doesn't want the module entry, then it means that this is
	//	a module (instead of the main file). If so, add it to the resources table

	if (retiModuleEntry == NULL)
		Ctx.AddResource(sFilename, iEntry, bCompress);

	//	Store all the image resources

	if (error = WriteModuleImages(Ctx, pModule, sFolder, Out))
		return error;

	//	Store all the sound resources

	if (error = WriteModuleSounds(Ctx, pModule, sFolder, Out))
		return error;

	//	Store all modules

	if (error = WriteSubModules(Ctx, pModule, sFolder, Out))
		return error;

	//	The root module may have a TranscendenceAdventure tag with modules in it

	for (i = 0; i < pModule->GetContentElementCount(); i++)
		{
		CXMLElement *pItem = pModule->GetContentElement(i);

		if (strEquals(pItem->GetTag(), TAG_CORE_LIBRARY)
				|| strEquals(pItem->GetTag(), TAG_TRANSCENDENCE_ADVENTURE) 
				|| strEquals(pItem->GetTag(), TAG_TRANSCENDENCE_LIBRARY))
			{
			//	If we have a filename, then we need to save the target as a
			//	module.

			CString sFilename;
			if (pItem->FindAttribute(ATTRIB_FILENAME, &sFilename))
				{
				//	Write out the module, making sure to set the core flag.

				if (error = WriteModule(Ctx, sFilename, sFolder, Out, NULL, true))
					return error;

				//	We ignore any other elements.

				continue;
				}

			//	Store all the image resources

			if (error = WriteModuleImages(Ctx, pItem, sFolder, Out))
				return error;

			//	Store all the sound resources

			if (error = WriteModuleSounds(Ctx, pItem, sFolder, Out))
				return error;

			//	Modules

			if (error = WriteSubModules(Ctx, pItem, sFolder, Out))
				return error;
			}
		}

	//	Done

	if (retiModuleEntry)
		*retiModuleEntry = iEntry;

	return NOERROR;
	}
コード例 #4
0
ファイル: Devices.cpp プロジェクト: bmer/Mammoth
ALERROR CDeviceClass::InitDeviceFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc, CItemType *pType)

//	InitDeviceFromXML
//
//	Initializes the device class base

	{
	int i;
	ALERROR error;

	m_pItemType = pType;

	//	Number of slots that the device takes up (if the attribute is missing
	//	then we assume 1)

	CString sAttrib;
	if (pDesc->FindAttribute(DEVICE_SLOTS_ATTRIB, &sAttrib))
		m_iSlots = strToInt(sAttrib, 1, NULL);
	else
		m_iSlots = 1;

	//	Slot type

	CString sSlotType;
	if (pDesc->FindAttribute(CATEGORY_ATTRIB, &sSlotType) 
			|| pDesc->FindAttribute(DEVICE_SLOT_CATEGORY_ATTRIB, &sSlotType))
		{
		if (!CItemType::ParseItemCategory(sSlotType, &m_iSlotCategory))
			{
			Ctx.sError = strPatternSubst(CONSTLIT("Invalid deviceSlotCategory: %s."), sSlotType);
			return ERR_FAIL;
			}

		//	Make sure it is a valid device

		switch (m_iSlotCategory)
			{
			//	OK
			case itemcatCargoHold:
			case itemcatDrive:
			case itemcatLauncher:
			case itemcatMiscDevice:
			case itemcatReactor:
			case itemcatShields:
			case itemcatWeapon:
				break;

			default:
				{
				Ctx.sError = strPatternSubst(CONSTLIT("Not a valid device category: %s."), sSlotType);
				return ERR_FAIL;
				}
			}
		}
	else
		//	itemcatNone means use the actual item category
		m_iSlotCategory = itemcatNone;

	//	Overlay

	if (error = m_pOverlayType.LoadUNID(Ctx, pDesc->GetAttribute(OVERLAY_TYPE_ATTRIB)))
		return error;

	//	Other settings

	m_iMaxHPBonus = pDesc->GetAttributeIntegerBounded(MAX_HP_BONUS_ATTRIB, 0, -1, 150);
	m_fExternal = pDesc->GetAttributeBool(EXTERNAL_ATTRIB);

	//	Does this device enhance other items?

	CXMLElement *pEnhanceList = pDesc->GetContentElementByTag(ENHANCE_ABILITIES_TAG);
	if (pEnhanceList)
		{
		m_Enhancements.InsertEmpty(pEnhanceList->GetContentElementCount());

		for (i = 0; i < pEnhanceList->GetContentElementCount(); i++)
			{
			CXMLElement *pEnhancement = pEnhanceList->GetContentElement(i);

			m_Enhancements[i].sType = pEnhancement->GetAttribute(TYPE_ATTRIB);

			//	Load the item criteria

			CString sCriteria;
			if (!pEnhancement->FindAttribute(CRITERIA_ATTRIB, &sCriteria))
				sCriteria = CONSTLIT("*");

			CItem::ParseCriteria(sCriteria, &m_Enhancements[i].Criteria);

			//	Parse the enhancement itself

			if (error = m_Enhancements[i].Enhancement.InitFromDesc(Ctx, pEnhancement->GetAttribute(ENHANCEMENT_ATTRIB)))
				return error;
			}
		}

	return NOERROR;
	}
コード例 #5
0
ファイル: CDockPane.cpp プロジェクト: gmoromisato/Dev
ALERROR CDockPane::CreateControls (CString *retsError)

//	CreateControls
//
//	Creates controls based on the pane descriptor. We assume that m_pContainer has
//	already been created and is empty.

	{
	int i;

	//	If there is a <Controls> element then use that to figure out what to
	//	create.

	CXMLElement *pControls = m_pPaneDesc->GetContentElementByTag(CONTROLS_TAG);
	if (pControls)
		{
		for (i = 0; i < pControls->GetContentElementCount(); i++)
			{
			CXMLElement *pControlDef = pControls->GetContentElement(i);

			//	Figure out the type

			EControlTypes iType;
			if (strEquals(pControlDef->GetTag(), COUNTER_TAG))
				iType = controlCounter;
			else if (strEquals(pControlDef->GetTag(), ITEM_DISPLAY_TAG))
				iType = controlItemDisplay;
			else if (strEquals(pControlDef->GetTag(), TEXT_TAG))
				iType = controlDesc;
			else if (strEquals(pControlDef->GetTag(), TEXT_INPUT_TAG))
				iType = controlTextInput;
			else
				{
				*retsError = strPatternSubst(CONSTLIT("Unknown control element: <%s>."), pControlDef->GetTag());
				return ERR_FAIL;
				}

			//	Get the ID

			CString sID;
			if (!pControlDef->FindAttribute(ID_ATTRIB, &sID))
				{
				*retsError = strPatternSubst(CONSTLIT("Missing ID attrib for control element: <%s>."), pControlDef->GetTag());
				return ERR_FAIL;
				}

			//	Create the control

			CreateControl(iType, sID);
			}
		}

	//	Otherwise we create default controls

	else
		{
		//	Create the text description control

		CreateControl(controlDesc, DEFAULT_DESC_ID);

		//	Create counter or input fields

		if (m_pPaneDesc->GetAttributeBool(SHOW_COUNTER_ATTRIB))
			CreateControl(controlCounter, DEFAULT_COUNTER_ID);
		else if (m_pPaneDesc->GetAttributeBool(SHOW_TEXT_INPUT_ATTRIB))
			CreateControl(controlTextInput, DEFAULT_TEXT_INPUT_ID);
		}

	return NOERROR;
	}
コード例 #6
0
void InitStationTypeImage (SEntryDesc &Entry, CStationType *pStationType)
	{
	struct SSatImageDesc
		{
		const CObjectImageArray *pImage;
		CCompositeImageSelector Selector;
		int xOffset;
		int yOffset;
		};

	int i;

	SSelectorInitCtx InitCtx;
	pStationType->SetImageSelector(InitCtx, &Entry.Selector);
	const CObjectImageArray *pMainImage = &pStationType->GetImage(Entry.Selector, CCompositeImageModifiers());

	//	If we have no satellites, then we can just return the single station 
	//	image.

	CXMLElement *pSatellites = pStationType->GetSatellitesDesc();
	if (pSatellites == NULL)
		{
		Entry.pImage = pMainImage;
		return;
		}

	//	Figure out the extents of the image

	RECT rcMainImage = pMainImage->GetImageRect();
	RECT rcBounds;
	rcBounds.left = -(RectWidth(rcMainImage) / 2);
	rcBounds.top = -(RectHeight(rcMainImage) / 2);
	rcBounds.right = rcBounds.left + RectWidth(rcMainImage);
	rcBounds.bottom = rcBounds.top + RectHeight(rcMainImage);

	//	Loop over all satellites and get metrics

	TArray<SSatImageDesc> SatImages;
	for (i = 0; i < pSatellites->GetContentElementCount(); i++)
		{
		CXMLElement *pSatDesc = pSatellites->GetContentElement(i);
		if (!pSatDesc->FindAttribute(SEGMENT_ATTRIB)
				|| !strEquals(STATION_TAG, pSatDesc->GetTag()))
			continue;

		//	Get the type of the satellite

		CStationType *pSatType = g_pUniverse->FindStationType(pSatDesc->GetAttributeInteger(TYPE_ATTRIB));
		if (pSatType == NULL)
			continue;

		//	Prepare the image for the satellite

		SSatImageDesc *pSatImage = SatImages.Insert();
		pSatType->SetImageSelector(InitCtx, &pSatImage->Selector);

		//	If we have an image variant, then set it

		int iVariant;
		if (pSatDesc->FindAttributeInteger(IMAGE_VARIANT_ATTRIB, &iVariant))
			{
			IImageEntry *pRoot = pSatType->GetImage().GetRoot();
			DWORD dwID = (pRoot ? pRoot->GetID() : DEFAULT_SELECTOR_ID);

			pSatImage->Selector.DeleteAll();
			pSatImage->Selector.AddVariant(dwID, iVariant);
			}

		pSatImage->pImage = &pSatType->GetImage(pSatImage->Selector, CCompositeImageModifiers());

		//	Now get the offset

		pSatImage->xOffset = pSatDesc->GetAttributeInteger(X_OFFSET_ATTRIB);
		pSatImage->yOffset = pSatDesc->GetAttributeInteger(Y_OFFSET_ATTRIB);

		//	Compute the satellite rect

		RECT rcSatImage = pSatImage->pImage->GetImageRect();
		RECT rcSatBounds;
		rcSatBounds.left = pSatImage->xOffset - (RectWidth(rcSatImage) / 2);
		rcSatBounds.top = -pSatImage->yOffset - (RectHeight(rcSatImage) / 2);
		rcSatBounds.right = rcSatBounds.left + RectWidth(rcSatImage);
		rcSatBounds.bottom = rcSatBounds.top + RectHeight(rcSatImage);

		//	Increase the size of the bounds

		rcBounds.left = Min(rcBounds.left, rcSatBounds.left);
		rcBounds.right = Max(rcBounds.right, rcSatBounds.right);
		rcBounds.top = Min(rcBounds.top, rcSatBounds.top);
		rcBounds.bottom = Max(rcBounds.bottom, rcSatBounds.bottom);
		}

	//	If no segments, then we just return the basic image

	if (SatImages.GetCount() == 0)
		{
		Entry.pImage = pMainImage;
		return;
		}

	//	Create an image that will hold the composite

	CG32bitImage *pCompositeImage = new CG32bitImage;
	pCompositeImage->Create(RectWidth(rcBounds), RectHeight(rcBounds), CG32bitImage::alpha8, CG32bitPixel::Null());
	int xCenter = -rcBounds.left;
	int yCenter = -rcBounds.top;

	//	Paint the main image

	pMainImage->PaintImage(*pCompositeImage, xCenter, yCenter, 0, Entry.iRotation, true);

	//	Paint all the satellites

	for (i = 0; i < SatImages.GetCount(); i++)
		SatImages[i].pImage->PaintImage(*pCompositeImage, xCenter + SatImages[i].xOffset, yCenter - SatImages[i].yOffset, 0, 0, true);

	//	Now create the proper image array

	RECT rcResult;
	rcResult.left = 0;
	rcResult.top = 0;
	rcResult.right = RectWidth(rcBounds);
	rcResult.bottom = RectHeight(rcBounds);

    int xOffset = (RectWidth(rcBounds) / 2) - xCenter;
    int yOffset = (RectHeight(rcBounds) / 2) - yCenter;

	Entry.pCompositeImageArray = new CObjectImageArray;
	Entry.pCompositeImageArray->Init(pCompositeImage, rcResult, 0, 0, true, xOffset, yOffset);

	//	Done

	Entry.pImage = Entry.pCompositeImageArray;
	}
コード例 #7
0
ALERROR CDockScreenCustomList::OnInitList (SInitCtx &Ctx, CString *retsError)

//	OnInitList
//
//	Initialize list

	{
	//	Get the list element

	CXMLElement *pListData = Ctx.pDesc->GetContentElementByTag(LIST_TAG);
	if (pListData == NULL)
		return ERR_FAIL;

	//	See if we define a custom row height

	CString sRowHeight;
	if (pListData->FindAttribute(ROW_HEIGHT_ATTRIB, &sRowHeight))
		{
		CString sResult;
		if (!EvalString(sRowHeight, false, eventNone, &sResult))
			{
			*retsError = sResult;
			return ERR_FAIL;
			}

		int cyRow = strToInt(sResult, -1);
		if (cyRow > 0)
			m_pItemListControl->SetRowHeight(cyRow);
		}

	//	Get the list to show

	CCodeChain &CC = g_pUniverse->GetCC();
	ICCItem *pExp = CC.Link(pListData->GetContentText(0), 0, NULL);

	//	Evaluate the function

	CCodeChainCtx CCCtx;
	CCCtx.SetScreen(m_pDockScreen);
	CCCtx.SaveAndDefineSourceVar(m_pLocation);
	CCCtx.SaveAndDefineDataVar(m_pData);

	ICCItem *pResult = CCCtx.Run(pExp);	//	LATER:Event
	CCCtx.Discard(pExp);

	if (pResult->IsError())
		{
		*retsError = pResult->GetStringValue();
		return ERR_FAIL;
		}

	//	Set this expression as the list

	m_pItemListControl->SetList(CC, pResult);
	CCCtx.Discard(pResult);

	//	Position the cursor on the next relevant item

	SelectNextItem();

	//	Give the screen a chance to start at a different item (other
	//	than the first)

	CString sInitialItemFunc = pListData->GetAttribute(INITIAL_ITEM_ATTRIB);
	if (!sInitialItemFunc.IsBlank())
		{
		bool bMore = IsCurrentItemValid();
		while (bMore)
			{
			bool bResult;
			if (!EvalBool(sInitialItemFunc, &bResult, retsError))
				return ERR_FAIL;

			if (bResult)
				break;

			bMore = SelectNextItem();
			}
		}

	return NOERROR;
	}
コード例 #8
0
bool IDockScreenDisplay::GetDisplayOptions (SInitCtx &Ctx, SDisplayOptions *retOptions, CString *retsError)

//	GetDisplayOptions
//
//	Initializes the display options structure, which is used by list and 
//	selector displays.

	{
	DEBUG_TRY

	//	Initialize background image options

	CString sBackgroundID;
	if (Ctx.pDesc->FindAttribute(BACKGROUND_ID_ATTRIB, &sBackgroundID))
		{
		//	If the attribute exists, but is empty (or equals "none") then
		//	we don't have a background

		if (sBackgroundID.IsBlank() || strEquals(sBackgroundID, CONSTLIT("none")))
			retOptions->BackgroundDesc.iType = backgroundNone;

		else if (strEquals(sBackgroundID, TYPE_HERO))
			{
			retOptions->BackgroundDesc.iType = backgroundObjHeroImage;
			retOptions->BackgroundDesc.pObj = Ctx.pLocation;
			}

		//	If the ID is "object" then we should ask the object

		else if (strEquals(sBackgroundID, TYPE_OBJECT))
			{
			retOptions->BackgroundDesc.pObj = Ctx.pLocation;
            if (Ctx.pLocation->IsPlayer())
			    retOptions->BackgroundDesc.iType = backgroundObjSchematicImage;
            else
			    retOptions->BackgroundDesc.iType = backgroundObjHeroImage;
			}

		else if (strEquals(sBackgroundID, TYPE_SCHEMATIC))
			{
			retOptions->BackgroundDesc.iType = backgroundObjSchematicImage;
			retOptions->BackgroundDesc.pObj = Ctx.pLocation;
			}

		//	If the ID is "player" then we should ask the player ship

		else if (strEquals(sBackgroundID, DATA_FROM_PLAYER))
			{
			CSpaceObject *pPlayer = g_pUniverse->GetPlayerShip();
			if (pPlayer)
				{
				retOptions->BackgroundDesc.iType = backgroundObjSchematicImage;
				retOptions->BackgroundDesc.pObj = pPlayer;
				}
			}

		//	Otherwise, we expect an integer

		else
			{
			retOptions->BackgroundDesc.iType = backgroundImage;
			retOptions->BackgroundDesc.dwImageID = strToInt(sBackgroundID, 0);
			}
		}

	//	Initialize control rect. If we have a background, then initialize to
	//	backwards compatible position. Otherwise, we take up the full range.

	if (retOptions->BackgroundDesc.iType != backgroundDefault)
		{
		retOptions->rcControl.left = 4;
		retOptions->rcControl.top = 12;
		retOptions->rcControl.right = 548;
		retOptions->rcControl.bottom = 396;
		}
	else
		{
		retOptions->rcControl.left = 0;
		retOptions->rcControl.top = 23;
		retOptions->rcControl.right = 600;
		retOptions->rcControl.bottom = 502;
		}

	//	Get the type

	if (Ctx.pDisplayDesc
			&& Ctx.pDisplayDesc->FindAttribute(TYPE_ATTRIB, &retOptions->sType))
		NULL;
	else
		retOptions->sType = Ctx.pDesc->GetAttribute(TYPE_ATTRIB);

	//	There are a couple of different ways to get options (for backwards
	//	compatibility).

	CXMLElement *pOptions;
	if ((pOptions = Ctx.pDesc->GetContentElementByTag(LIST_OPTIONS_TAG)) == NULL
			&& (pOptions = Ctx.pDesc->GetContentElementByTag(LIST_TAG)) == NULL
			&& (pOptions = Ctx.pDisplayDesc) == NULL)
		return true;

	retOptions->pOptions = pOptions;

	//	Read from the element

	retOptions->sDataFrom = pOptions->GetAttribute(DATA_FROM_ATTRIB);
	if (!pOptions->FindAttribute(CRITERIA_ATTRIB, &retOptions->sItemCriteria))
		retOptions->sItemCriteria = pOptions->GetAttribute(LIST_ATTRIB);
	retOptions->sInitialItemCode = pOptions->GetAttribute(INITIAL_ITEM_ATTRIB);
	retOptions->sRowHeightCode = pOptions->GetAttribute(ROW_HEIGHT_ATTRIB);

	//	Init code

	CXMLElement *pInitCode = pOptions->GetContentElementByTag(ON_DISPLAY_INIT_TAG);
	if (pInitCode == NULL)
		pInitCode = pOptions;

	retOptions->sCode = pInitCode->GetContentText(0);

	//	List options

	retOptions->bNoArmorSpeedDisplay = pOptions->GetAttributeBool(NO_ARMOR_SPEED_DISPLAY_ATTRIB);
	retOptions->bActualItems = pOptions->GetAttributeBool(DISPLAY_ACTUAL_ATTRIB);
	retOptions->cxIcon = pOptions->GetAttributeIntegerBounded(ICON_WIDTH_ATTRIB, 0, -1, ICON_WIDTH);
	retOptions->cyIcon = pOptions->GetAttributeIntegerBounded(ICON_HEIGHT_ATTRIB, 0, -1, ICON_HEIGHT);
	retOptions->rIconScale = pOptions->GetAttributeDoubleBounded(ICON_SCALE_ATTRIB, 0.0, -1.0, 1.0);

    //  Selector options

    retOptions->bNoEmptySlots = pOptions->GetAttributeBool(NO_EMPTY_SLOTS_ATTRIB);
    retOptions->sSlotNameCode = pOptions->GetAttribute(SLOT_NAME_ATTRIB);

	//	See if we have control position

	if (pOptions->FindAttributeInteger(POS_X_ATTRIB, (int *)&retOptions->rcControl.left))
		{
		retOptions->rcControl.top = pOptions->GetAttributeIntegerBounded(POS_Y_ATTRIB, 0, -1);
		retOptions->rcControl.right = retOptions->rcControl.left + pOptions->GetAttributeIntegerBounded(WIDTH_ATTRIB, 0, -1);
		retOptions->rcControl.bottom = retOptions->rcControl.top + pOptions->GetAttributeIntegerBounded(HEIGHT_ATTRIB, 0, -1);
		}

	return true;

	DEBUG_CATCH
	}
コード例 #9
0
ALERROR CGameSettings::Load (const CString &sFilespec, CString *retsError)

//	Load
//
//	Load game settings from a file. If the file does not exist, then we 
//	set settings to default values

	{
	ALERROR error;
	int i;

	//	Initialize from defaults

	for (i = 0; i < OPTIONS_COUNT; i++)
		SetValue(i, CString(g_OptionData[i].pszDefaultValue, -1, true), true);

	//	Look for a file in the current directory and see if it is writable. If
	//	not, then look in AppData. We remember the place where we found a valid
	//	file as our AppData root (and we base other directories off that).

	if (pathIsWritable(sFilespec))
		{
		//	AppData is current directory
		m_sAppData = NULL_STR;
		}
	else
		{
		m_sAppData = pathAddComponent(pathGetSpecialFolder(folderAppData), TRANSCENDENCE_APP_DATA);
		if (!pathCreate(m_sAppData)
				|| !pathIsWritable(m_sAppData))
			{
			*retsError = strPatternSubst(CONSTLIT("Unable to write to AppData folder: %s"), m_sAppData);
			return ERR_FAIL;
			}
		}

	//	Settings file

	CString sSettingsFilespec = pathAddComponent(m_sAppData, sFilespec);

	//	Load XML

	CFileReadBlock DataFile(sSettingsFilespec);
	CXMLElement *pData;
	CString sError;
	if (error = CXMLElement::ParseXML(&DataFile, &pData, retsError))
		{
		//	ERR_NOTFOUND means that we couldn't find the Settings.xml
		//	file. In that case, initialize from defaults

		if (error == ERR_NOTFOUND)
			{
			LoadFromRegistry();
			m_bModified = true;
			return NOERROR;
			}

		//	Otherwise, it means that we got an error parsing the file.
		//	Return the error, but leave the settings initialized to defaults
		//	(We should be OK to continue, even with an error).

		else
			{
			m_bModified = false;
			return error;
			}
		}

	//	Initialize to unmodified (as we load settings we might change this)

	m_bModified = false;

	//	Loop over all elements

	for (i = 0; i < pData->GetContentElementCount(); i++)
		{
		CXMLElement *pItem = pData->GetContentElement(i);

		if (strEquals(pItem->GetTag(), OPTION_TAG))
			{
			int iOption = FindOptionData(pItem->GetAttribute(NAME_ATTRIB));
			if (iOption == -1)
				{
				kernelDebugLogMessage("Unknown option: %s", pItem->GetAttribute(NAME_ATTRIB));
				continue;
				}

			SetValue(iOption, pItem->GetAttribute(VALUE_ATTRIB), true);
			}
		else if (strEquals(pItem->GetTag(), KEY_MAP_TAG))
			{
			if (error = m_KeyMap.ReadFromXML(pItem))
				return error;
			}
		else if (strEquals(pItem->GetTag(), EXTENSION_FOLDER_TAG))
			{
			CString sFolder;
			if (pItem->FindAttribute(PATH_ATTRIB, &sFolder))
				m_ExtensionFolders.Insert(sFolder);
			}
		else if (strEquals(pItem->GetTag(), EXTENSIONS_TAG))
			{
			if (error = m_Extensions.ReadFromXML(pItem))
				return error;
			}
		else if (m_pExtra)
			{
			bool bModified;
			if (error = m_pExtra->OnLoadSettings(pItem, &bModified))
				return error;

			if (bModified)
				m_bModified = true;
			}
		}

	//	Done

	delete pData;

	return NOERROR;
	}