コード例 #1
1
ALERROR CDesignCollection::AddDynamicType (SExtensionDesc *pExtension, DWORD dwUNID, const CString &sSource, bool bNewGame, CString *retsError)

//	AddDynamicType
//
//	Adds a dynamic type at runtime

	{
	ALERROR error;

	//	If we're pass game-create, the UNID must not already exist

	if (!bNewGame && FindEntry(dwUNID))
		{
		if (retsError)
			*retsError = strPatternSubst(CONSTLIT("Type already exists: %x"), dwUNID);
		return ERR_FAIL;
		}

	//	Add it to the dynamics table

	CDesignType *pType;
	if (error = m_DynamicTypes.DefineType(pExtension, dwUNID, sSource, &pType, retsError))
		return error;

	//	Make sure that the type can be created at this point.
	//	For example, we can't create SystemMap types after the game has started.

	switch (pType->GetType())
		{
		case designAdventureDesc:
		case designGlobals:
		case designImage:
		case designSound:
		case designEconomyType:
		case designTemplateType:
			{
			m_DynamicTypes.Delete(dwUNID);
			if (retsError)
				*retsError = CONSTLIT("Dynamic design type not supported.");
			return ERR_FAIL;
			}

		case designSystemType:
		case designSystemTable:
		case designSystemMap:
			{
			if (!bNewGame)
				{
				m_DynamicTypes.Delete(dwUNID);
				if (retsError)
					*retsError = CONSTLIT("Dynamic design type not supported after new game created.");
				return ERR_FAIL;
				}
			}
		}

	//	Since we've already bound, we need to simulate that here (although we
	//	[obviously] don't allow existing types to bind to dynamic types).
	//
	//	We start by adding the type to the AllTypes list

	m_AllTypes.AddOrReplaceEntry(pType);

	//	If this is new game time, then it means that we are inside of BindDesign. In
	//	that case, we don't do anything more (since BindDesign will take care of
	//	it).

	if (!bNewGame)
		{
		//	Next we add it to the specific type tables

		m_ByType[pType->GetType()].AddEntry(pType);

		//	Bind

		SDesignLoadCtx Ctx;
		Ctx.pExtension = pExtension;
		Ctx.bNewGame = bNewGame;

		if (error = pType->PrepareBindDesign(Ctx))
			{
			m_AllTypes.Delete(dwUNID);
			m_ByType[pType->GetType()].Delete(dwUNID);
			m_DynamicTypes.Delete(dwUNID);
			if (retsError)
				*retsError = Ctx.sError;
			return error;
			}

		if (error = pType->BindDesign(Ctx))
			{
			m_AllTypes.Delete(dwUNID);
			m_ByType[pType->GetType()].Delete(dwUNID);
			m_DynamicTypes.Delete(dwUNID);
			if (retsError)
				*retsError = Ctx.sError;
			return error;
			}

		//	Cache some global events

		CacheGlobalEvents(pType);

		//	Done binding

		if (error = pType->FinishBindDesign(Ctx))
			{
			m_AllTypes.Delete(dwUNID);
			m_ByType[pType->GetType()].Delete(dwUNID);
			m_DynamicTypes.Delete(dwUNID);
			if (retsError)
				*retsError = Ctx.sError;
			return error;
			}
		}

	return NOERROR;
	}
コード例 #2
0
ALERROR CDesignCollection::CreateTemplateTypes (SDesignLoadCtx &Ctx)

//	CreateTemplateTypes
//
//	This is called inside of BindDesign to create all template types

	{
	ALERROR error;
	int i;

	//	Create an appropriate context for running code

	CCodeChainCtx CCCtx;

	//	Loop over all active types looking for templates.
	//	NOTE: We cannot use the type-specific arrays because they have not been
	//	set up yet (remember that we are inside of BindDesign).

	for (i = 0; i < m_AllTypes.GetCount(); i++)
		{
		CDesignType *pTemplate = m_AllTypes.GetEntry(i);
		if (pTemplate->GetType() != designTemplateType)
			continue;

		//	Get the function to generate the type source

		CString sSource;
		SEventHandlerDesc Event;
		if (pTemplate->FindEventHandler(GET_TYPE_SOURCE_EVENT, &Event))
			{
			ICCItem *pResult = CCCtx.Run(Event);
			if (pResult->IsError())
				{
				Ctx.sError = strPatternSubst(CONSTLIT("GetTypeSource (%x): %s"), pTemplate->GetUNID(), pResult->GetStringValue());
				return ERR_FAIL;
				}
			else if (pResult->IsNil())
				sSource = NULL_STR;
			else
				sSource = pResult->GetStringValue();

			CCCtx.Discard(pResult);
			}

		//	Define the type

		if (!sSource.IsBlank())
			{
			if (error = AddDynamicType(pTemplate->GetExtension(), pTemplate->GetUNID(), sSource, true, &Ctx.sError))
				return error;
			}
		}

	return NOERROR;
	}
コード例 #3
0
ファイル: CSpaceObjectTrade.cpp プロジェクト: bmer/Mammoth
bool CSpaceObject::GetArmorRepairPrice (const CItem &Item, int iHPToRepair, DWORD dwFlags, int *retiPrice)

//	GetArmorRepairPrice
//
//	Returns the price to repair the given number of HP for the given armor item.

	{
	if (IsAbandoned())
		return false;

	//	See if we have an override

	CTradingDesc *pTradeOverride = GetTradeDescOverride();
	if (pTradeOverride && pTradeOverride->GetArmorRepairPrice(this, Item, iHPToRepair, dwFlags, retiPrice))
		return true;

	//	Otherwise, ask our design type

	CDesignType *pType = GetType();
	if (pType == NULL)
		return false;

	CTradingDesc *pTrade = pType->GetTradingDesc();
	if (pTrade && pTrade->GetArmorRepairPrice(this, Item, iHPToRepair, dwFlags, retiPrice))
		return true;

	//	For compatibility, any ship prior to version 23 has a default.
	//	[For API Version 23 and above, ships must have a <Trade> descriptor.]

	if (pType->GetAPIVersion() < 23
			&& pType->GetType() == designShipClass)
		{
		if (retiPrice)
			*retiPrice = CTradingDesc::CalcPriceForService(serviceRepairArmor, this, Item, iHPToRepair, dwFlags);

		return true;
		}

	//	Otherwise, we do not repair

	return false;
	}
コード例 #4
0
CAdventureDesc *CDesignCollection::FindAdventureForExtension (DWORD dwUNID) const

//	FindAdventureForExtension
//
//	Returns the adventure desc that belongs to the given extension.
//	(Or NULL if not found).

	{
	int i;

	SExtensionDesc *pExtension = FindExtension(dwUNID);
	if (pExtension == NULL || pExtension->iType != extAdventure)
		return NULL;

	for (i = 0; i < pExtension->Table.GetCount(); i++)
		{
		CDesignType *pType = pExtension->Table.GetEntry(i);
		if (pType->GetType() ==	designAdventureDesc)
			return CAdventureDesc::AsType(pType);
		}

	return NULL;
	}
コード例 #5
0
ファイル: ItemTable.cpp プロジェクト: bmer/Transmuter
void OutputByShipClass (SItemTableCtx &Ctx, const SItemTypeList &ItemList, bool bShowUsage)
	{
	int i, j;

	//	Make a map of ship classes for each item

	TSortMap<DWORD, TArray<CShipClass *>> ItemToShipClass;
	for (i = 0; i < g_pUniverse->GetShipClassCount(); i++)
		{
		CShipClass *pClass = g_pUniverse->GetShipClass(i);

		//	Skip non-generic ones

		if (!pClass->HasLiteralAttribute(CONSTLIT("genericClass")))
			continue;

		//	Add the list of types used by the ship

		TSortMap<DWORD, bool> TypesUsed;
		pClass->AddTypesUsed(&TypesUsed);

		//	For each item type, add it to the map

		for (j = 0; j < TypesUsed.GetCount(); j++)
			{
			CDesignType *pType = g_pUniverse->FindDesignType(TypesUsed.GetKey(j));
			if (pType && pType->GetType() == designItemType)
				{
				TArray<CShipClass *> *pList = ItemToShipClass.SetAt(pType->GetUNID());
				pList->Insert(pClass);
				}
			}
		}

	//	If we want to show usage, then we print each item along with the 
	//	ship classes using each item.

	if (bShowUsage)
		{
		for (i = 0; i < ItemList.GetCount(); i++)
			{
			CItemType *pType = ItemList[i];
			printf("%s\n", (LPSTR)pType->GetNounPhrase());

			TArray<CShipClass *> *pList = ItemToShipClass.SetAt(pType->GetUNID());
			for (j = 0; j < pList->GetCount(); j++)
				printf("\t%s\n", (LPSTR)pList->GetAt(j)->GetName());

			if (pList->GetCount() == 0)
				printf("\t(none)\n");

			printf("\n");
			}
		}

	//	Otherwise we categorize by ship class

	else
		{
		//	Now make a list of all ship classes that have our items

		SByShipClassTypeList ByShipClassTable;
		for (i = 0; i < ItemList.GetCount(); i++)
			{
			const CString &sKey = ItemList.GetKey(i);
			CItemType *pType = ItemList[i];

			//	Loop over all ship classes

			TArray<CShipClass *> *pList = ItemToShipClass.SetAt(pType->GetUNID());
			for (j = 0; j < pList->GetCount(); j++)
				{
				CString sClassName = pList->GetAt(j)->GetName();

				bool bNew;
				SShipClassEntry *pEntry = ByShipClassTable.SetAt(sClassName, &bNew);
				if (bNew)
					pEntry->sShipClassName = sClassName;

				pEntry->ItemTable.Insert(sKey, pType);
				}

			//	If no ship class

			if (pList->GetCount() == 0)
				{
				bool bNew;
				SShipClassEntry *pEntry = ByShipClassTable.SetAt(CONSTLIT("(none)"), &bNew);
				if (bNew)
					pEntry->sShipClassName = CONSTLIT("(none)");

				pEntry->ItemTable.Insert(sKey, pType);
				}
			}

		//	Now loop over all attributes

		for (i = 0; i < ByShipClassTable.GetCount(); i++)
			{
			const SShipClassEntry &Entry = ByShipClassTable[i];
			printf("%s\n\n", Entry.sShipClassName.GetASCIIZPointer());

			OutputHeader(Ctx);
			OutputTable(Ctx, Entry.ItemTable);
			printf("\n");
			}
		}
	}
コード例 #6
0
CWeaponFireDesc *CWeaponFireDesc::FindWeaponFireDescFromFullUNID (const CString &sUNID)

//	FindWeaponFireDesc
//
//	Finds the descriptor by name

	{
	char *pPos = sUNID.GetPointer();

	//	Get the UNID of the type

	DWORD dwUNID = (DWORD)strParseInt(pPos, 0, &pPos);
	if (dwUNID == 0)
		return NULL;

	//	Get the type

	CDesignType *pType = g_pUniverse->FindDesignType(dwUNID);
	if (pType == NULL)
		return NULL;

	//	If this is an item, then it must be a weapon

	if (pType->GetType() == designItemType)
		{
		CItemType *pItemType = CItemType::AsType(pType);
		ASSERT(pItemType);

		CDeviceClass *pDevice = pItemType->GetDeviceClass();
		if (pDevice == NULL)
			return NULL;

		CWeaponClass *pClass = pDevice->AsWeaponClass();
		if (pClass == NULL)
			return NULL;

		//	Get the ordinal

		ASSERT(*pPos == '/');
		pPos++;
		int iOrdinal = strParseInt(pPos, 0, &pPos);

		//	Get the weapon fire desc of the ordinal

		CWeaponFireDesc *pDesc = pClass->GetVariant(iOrdinal);
		if (pDesc == NULL)
			return NULL;

		//	Continue parsing

		return pDesc->FindWeaponFireDesc(CString(pPos));
		}

	//	If this is an effect, then get it from that

	else if (pType->GetType() == designEffectType)
		{
		CEffectCreator *pEffectType = CEffectCreator::AsType(pType);
		ASSERT(pEffectType);

		//	Expect /d

		ASSERT(*pPos == '/');
		pPos++;
		ASSERT(*pPos == 'd');
		pPos++;

		CWeaponFireDesc *pDesc = pEffectType->GetDamageDesc();
		if (pDesc == NULL)
			return NULL;

		//	Continue parsing

		return pDesc->FindWeaponFireDesc(CString(pPos));
		}

	//	Otherwise, we don't know

	else
		return NULL;
	}
コード例 #7
0
void GenerateImageChart (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	int i;

	enum OrderTypes
		{
		orderSmallest = 1,
		orderLargest = 2,
		orderName = 3,
		orderLevel = 4,
		orderSovereign = 5,
		orderManufacturer = 6,
		};

	//	Item criteria

	bool bHasItemCriteria;
	CString sCriteria;
	CItemCriteria ItemCriteria;
	if (bHasItemCriteria = pCmdLine->FindAttribute(CONSTLIT("itemCriteria"), &sCriteria))
		CItem::ParseCriteria(sCriteria, &ItemCriteria);
	else
		CItem::InitCriteriaAll(&ItemCriteria);

	//	Get the criteria from the command line.

	CDesignTypeCriteria Criteria;
	if (pCmdLine->FindAttribute(CONSTLIT("criteria"), &sCriteria))
		{
		if (CDesignTypeCriteria::ParseCriteria(sCriteria, &Criteria) != NOERROR)
			{
			printf("ERROR: Unable to parse criteria.\n");
			return;
			}
		}
	else if (bHasItemCriteria)
		{
		if (CDesignTypeCriteria::ParseCriteria(CONSTLIT("i"), &Criteria) != NOERROR)
			{
			printf("ERROR: Unable to parse criteria.\n");
			return;
			}
		}
	else
		{
		printf("ERROR: Expected criteria.\n");
		return;
		}

	bool bAll = pCmdLine->GetAttributeBool(CONSTLIT("all"));

	//	Options

	bool bTextBoxesOnly = pCmdLine->GetAttributeBool(CONSTLIT("textBoxesOnly"));
	bool bFieldUNID = pCmdLine->GetAttributeBool(CONSTLIT("unid"));

	//	Figure out what order we want

	CString sOrder = pCmdLine->GetAttribute(CONSTLIT("sort"));
	int iOrder;
	if (strEquals(sOrder, CONSTLIT("smallest")))
		iOrder = orderSmallest;
	else if (strEquals(sOrder, CONSTLIT("largest")))
		iOrder = orderLargest;
	else if (strEquals(sOrder, CONSTLIT("level")))
		iOrder = orderLevel;
	else if (strEquals(sOrder, CONSTLIT("sovereign")))
		iOrder = orderSovereign;
	else if (strEquals(sOrder, CONSTLIT("manufacturer")))
		iOrder = orderManufacturer;
	else
		iOrder = orderName;

	bool b3DGrid = pCmdLine->GetAttributeBool(CONSTLIT("3DGrid"));
	bool bDockingPorts = pCmdLine->GetAttributeBool(CONSTLIT("portPos"));
	bool bDevicePos = pCmdLine->GetAttributeBool(CONSTLIT("devicePos"));

	//	Image size

	int cxDesiredWidth;
	if (pCmdLine->FindAttributeInteger(CONSTLIT("width"), &cxDesiredWidth))
		cxDesiredWidth = Max(512, cxDesiredWidth);
	else
		cxDesiredWidth = 1280;

	//	Spacing

	int cxSpacing = pCmdLine->GetAttributeInteger(CONSTLIT("xSpacing"));
	int cxExtraMargin = pCmdLine->GetAttributeInteger(CONSTLIT("xMargin"));
	int cxImageMargin = 2 * pCmdLine->GetAttributeInteger(CONSTLIT("xImageMargin"));

	//	Font for text

	CString sTypeface;
	int iSize;
	bool bBold;
	bool bItalic;

	if (!CG16bitFont::ParseFontDesc(pCmdLine->GetAttribute(CONSTLIT("font")),
			&sTypeface,
			&iSize,
			&bBold,
			&bItalic))
		{
		sTypeface = CONSTLIT("Arial");
		iSize = 10;
		bBold = false;
		bItalic = false;
		}

	CG16bitFont NameFont;
	NameFont.Create(sTypeface, -PointsToPixels(iSize), bBold, bItalic);
	CG32bitPixel rgbNameColor = CG32bitPixel(255, 255, 255);

	//	Rotation

	int iRotation = pCmdLine->GetAttributeInteger(CONSTLIT("rotation"));

	//	Output file

	CString sFilespec = pCmdLine->GetAttribute(CONSTLIT("output"));
	if (!sFilespec.IsBlank())
		sFilespec = pathAddExtensionIfNecessary(sFilespec, CONSTLIT(".bmp"));

	//	Generate a sorted table of types

	TSortMap<CString, SEntryDesc> Table;
	for (i = 0; i < Universe.GetDesignTypeCount(); i++)
		{
		CDesignType *pType = Universe.GetDesignType(i);
		SEntryDesc NewEntry;

		//	Make sure we match the criteria

		if (!pType->MatchesCriteria(Criteria))
			continue;

		//	Figure stuff stuff out based on the specific design type

		switch (pType->GetType())
			{
			case designItemType:
				{
				CItemType *pItemType = CItemType::AsType(pType);
				CItem Item(pItemType, 1);

				//	Skip if not in item criteria

				if (!Item.MatchesCriteria(ItemCriteria))
					continue;

				//	Skip virtual classes

				if (pItemType->IsVirtual())
					continue;

				//	Initialize the entry

				NewEntry.pType = pType;
				NewEntry.sName = pItemType->GetNounPhrase(0);
				NewEntry.pImage = &pItemType->GetImage();
				NewEntry.iSize = RectWidth(NewEntry.pImage->GetImageRect());
				break;
				}

			case designShipClass:
				{
				CShipClass *pClass = CShipClass::AsType(pType);

				//	Skip non-generic classess

				if (!bAll && !pClass->HasLiteralAttribute(CONSTLIT("genericClass")))
					continue;

				//	Initialize the entry

				NewEntry.pType = pType;
				NewEntry.sName = pClass->GetNounPhrase(0);
				NewEntry.iSize = RectWidth(pClass->GetImage().GetImageRect());
				NewEntry.pImage = &pClass->GetImage();
				NewEntry.iRotation = pClass->Angle2Direction(iRotation);
				NewEntry.sSovereignName = (pClass->GetDefaultSovereign() ? pClass->GetDefaultSovereign()->GetTypeNounPhrase() : NULL_STR);
				break;
				}

			case designStationType:
				{
				CStationType *pStationType = CStationType::AsType(pType);

				//	Skip generic classes

				if (!bAll && !pStationType->HasLiteralAttribute(CONSTLIT("generic")))
					continue;

				NewEntry.pType = pType;
				NewEntry.sName = pStationType->GetNounPhrase(0);
				NewEntry.iSize = pStationType->GetSize();
				NewEntry.sSovereignName = (pStationType->GetSovereign() ? pStationType->GetSovereign()->GetTypeNounPhrase() : NULL_STR);

				InitStationTypeImage(NewEntry, pStationType);

				break;
				}

			default:
				//	Don't know how to handle this type
				continue;
				break;
			}

		//	Adjust name

		if (bFieldUNID)
			NewEntry.sName = strPatternSubst(CONSTLIT("%s (%x)"), NewEntry.sName, NewEntry.pType->GetUNID());

		//	Compute the sort key

		char szBuffer[1024];
		switch (iOrder)
			{
			case orderLargest:
				wsprintf(szBuffer, "%09d%s%x",
						1000000 - NewEntry.iSize,
						NewEntry.sName.GetASCIIZPointer(),
						pType->GetUNID());
				break;

			case orderLevel:
				wsprintf(szBuffer, "%09d%s%x",
						pType->GetLevel(),
						NewEntry.sName.GetASCIIZPointer(),
						pType->GetUNID());
				break;

			case orderSmallest:
				wsprintf(szBuffer, "%09d%s%x",
						NewEntry.iSize,
						NewEntry.sName.GetASCIIZPointer(),
						pType->GetUNID());
				break;

			case orderSovereign:
				wsprintf(szBuffer, "%s|%s|%x", NewEntry.sSovereignName.GetASCIIZPointer(), NewEntry.sName.GetASCIIZPointer(), pType->GetUNID());
				NewEntry.sCategorize = NewEntry.sSovereignName;
				break;

			case orderManufacturer:
				{
				CString sManufacturer = NewEntry.pType->GetPropertyString(CONSTLIT("manufacturer"));
				wsprintf(szBuffer, "%s|%s|%x", sManufacturer.GetASCIIZPointer(), NewEntry.sName.GetASCIIZPointer(), pType->GetUNID());
				NewEntry.sCategorize = sManufacturer;
				break;
				}

			default:
				wsprintf(szBuffer, "%s%x", NewEntry.sName.GetASCIIZPointer(), pType->GetUNID());
				break;
			}

		//	Add to list

		Table.Insert(CString(szBuffer), NewEntry);
		}

	//	Allocate an arranger that tracks where to paint each world.

	CImageArranger Arranger;

	//	Settings for the overall arrangement

	CImageArranger::SArrangeDesc Desc;
	Desc.cxDesiredWidth = Max(512, cxDesiredWidth - (2 * (cxSpacing + cxExtraMargin)));
	Desc.cxSpacing = cxSpacing;
	Desc.cxExtraMargin = cxExtraMargin;
	Desc.pHeader = &NameFont;

	//	Generate a table of cells for the arranger

	TArray<CCompositeImageSelector> Selectors;
	Selectors.InsertEmpty(Table.GetCount());

	CString sLastCategory;
	TArray<CImageArranger::SCellDesc> Cells;
	for (i = 0; i < Table.GetCount(); i++)
		{
		SEntryDesc &Entry = Table[i];

		CImageArranger::SCellDesc *pNewCell = Cells.Insert();
		pNewCell->cxWidth = (Entry.pImage ? RectWidth(Entry.pImage->GetImageRect()) : 0) + cxImageMargin;
		pNewCell->cyHeight = (Entry.pImage ? RectHeight(Entry.pImage->GetImageRect()) : 0) + cxImageMargin;
		pNewCell->sText = Entry.sName;

		if (!strEquals(sLastCategory, Entry.sCategorize))
			{
			sLastCategory = Entry.sCategorize;
			pNewCell->bStartNewRow = true;
			}
		}

	//	Arrange

	Arranger.ArrangeByRow(Desc, Cells);

	//	Create a large image

	CG32bitImage Output;
	int cxWidth = Max(cxDesiredWidth, Arranger.GetWidth());
	int cyHeight = Arranger.GetHeight();
	Output.Create(cxWidth, cyHeight);
	printf("Creating %dx%d image.\n", cxWidth, cyHeight);

	//	Paint the images

	for (i = 0; i < Table.GetCount(); i++)
		{
		SEntryDesc &Entry = Table[i];

		int x = Arranger.GetX(i);
		int y = Arranger.GetY(i);

		//	Paint

		if (x != -1)
			{
			int xCenter = x + (Arranger.GetWidth(i) / 2);
			int yCenter = y + (Arranger.GetHeight(i) / 2);

			int xOffset;
			int yOffset;
			Entry.pImage->GetImageOffset(0, Entry.iRotation, &xOffset, &yOffset);
			int cxImage = RectWidth(Entry.pImage->GetImageRect());
			int cyImage = RectHeight(Entry.pImage->GetImageRect());

			//	Paint image

			if (!bTextBoxesOnly && Entry.pImage)
				{
				Entry.pImage->PaintImageUL(Output,
						x + (Arranger.GetWidth(i) - cxImage) / 2,
						y + (Arranger.GetHeight(i) - cyImage) / 2,
						0,
						Entry.iRotation);
				}

			//	Paint type specific stuff

			switch (Entry.pType->GetType())
				{
				case designStationType:
					{
					CStationType *pStationType = CStationType::AsType(Entry.pType);
                    int xStationCenter = xCenter - xOffset;
                    int yStationCenter = yCenter - yOffset;

					if (bDockingPorts)
						pStationType->PaintDockPortPositions(Output, xStationCenter, yStationCenter);

					if (bDevicePos)
						pStationType->PaintDevicePositions(Output, xStationCenter, yStationCenter);

                    //  If we have docking or device positions, mark the center of the station

                    if (bDockingPorts || bDevicePos)
                        {
                        const int LINE_HALF_LENGTH = 24;
                        const CG32bitPixel RGB_CENTER_CROSS(255, 255, 0);
                        Output.DrawLine(xStationCenter - LINE_HALF_LENGTH, yStationCenter, xStationCenter + LINE_HALF_LENGTH, yStationCenter, 1, RGB_CENTER_CROSS);
                        Output.DrawLine(xStationCenter, yStationCenter - LINE_HALF_LENGTH, xStationCenter, yStationCenter + LINE_HALF_LENGTH, 1, RGB_CENTER_CROSS);
                        }
					break;
					}
				}

			//	Paint the 3D grid, if necessary

			if (b3DGrid)
				{
				int iScale = Entry.pImage->GetImageViewportSize();
				Metric rMaxRadius = g_KlicksPerPixel * cxImage * 0.5;
				const Metric rGridSize = LIGHT_SECOND;

				Metric rRadius;
				for (rRadius = rGridSize; rRadius <= rMaxRadius; rRadius += rGridSize)
					{
					int iRadius = (int)((rRadius / g_KlicksPerPixel) + 0.5);
					const int iGridAngle = 8;
					int iPrevAngle = 0;
					int iAngle;
					for (iAngle = iGridAngle; iAngle <= 360; iAngle += iGridAngle)
						{
						int xFrom, yFrom;
						C3DConversion::CalcCoord(iScale, iPrevAngle, iRadius, 0, &xFrom, &yFrom);

						int xTo, yTo;
						C3DConversion::CalcCoord(iScale, iAngle, iRadius, 0, &xTo, &yTo);

						Output.DrawLine(xFrom + xCenter, yFrom + yCenter, xTo + xCenter, yTo + yCenter, 1, CG32bitPixel(255, 255, 0));

						iPrevAngle = iAngle;
						}
					}
				}

			//	Paint name

			int xText = Arranger.GetTextX(i);
			int yText = Arranger.GetTextY(i);
			if (xText != -1)
				{
				if (bTextBoxesOnly)
					Output.Fill(xText, yText, Arranger.GetTextWidth(i), Arranger.GetTextHeight(i), 0xffff);

				if (!bTextBoxesOnly)
					{
					Output.FillColumn(xCenter,
							y + Arranger.GetHeight(i),
							yText - (y + Arranger.GetHeight(i)),
							rgbNameColor);

					NameFont.DrawText(Output,
							xText,
							yText,
							rgbNameColor,
							Entry.sName);
					}
				}
			}
		}

	//	Write to file or clipboard

	OutputImage(Output, sFilespec);
	}
コード例 #8
0
ファイル: Stats.cpp プロジェクト: AvanWolf/Transcendence
void GenerateTypeIslands (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	int i, j;

	bool bExcludeImages = true;

	printf("TYPE ISLANDS\n");
	printf("------------\n\n");

	//	Make a list of default types

#if 0
	g_DefaultTypes.SetAt(0x00001001, true);	//	independent sovereign
	g_DefaultTypes.SetAt(0x00001002, true);	//	Commonwealth sovereign
	g_DefaultTypes.SetAt(0x00001003, true);	//	independent sovereign
	g_DefaultTypes.SetAt(0x00001007, true);	//	ares sovereign
	g_DefaultTypes.SetAt(0x0000100c, true);	//	sung slavers sovereign
	g_DefaultTypes.SetAt(0x0000100f, true);	//	auton sovereign
	g_DefaultTypes.SetAt(0x00001011, true);	//	corporate hierarchy
	g_DefaultTypes.SetAt(0x00004027, true);	//	container of frozen supplies
	g_DefaultTypes.SetAt(0x0000402c, true);	//	pteracnium ore
	g_DefaultTypes.SetAt(0x000040ae, true);	//	helium3 reactor assembly
	g_DefaultTypes.SetAt(0x000040af, true);	//	pteracnium fuel
	g_DefaultTypes.SetAt(0x000040ca, true);	//	lancer cannon
	g_DefaultTypes.SetAt(0x000040e2, true);	//	worldship armor
	g_DefaultTypes.SetAt(0x00004100, true);	//	xenotite ore
	g_DefaultTypes.SetAt(0x00004109, true);	//	SN2500 reactor
	g_DefaultTypes.SetAt(0x00004167, true);	//	tetramite ore
	g_DefaultTypes.SetAt(0x00005004, true);	//	wreck ejecta
	g_DefaultTypes.SetAt(0x0000500c, true);	//	blast explosion 2
	g_DefaultTypes.SetAt(0x0000500d, true);	//	blast explosion 3
	g_DefaultTypes.SetAt(0x0000500e, true);	//	blast explosion 4
	g_DefaultTypes.SetAt(0x0000500f, true);	//	thermo explosion 1
	g_DefaultTypes.SetAt(0x00005011, true);	//	thermo explosion 3
	g_DefaultTypes.SetAt(0x00005012, true);	//	thermo explosion 4
	g_DefaultTypes.SetAt(0x00009004, true);	//	shield effect
	g_DefaultTypes.SetAt(0x00009007, true);	//	explosion effect
	g_DefaultTypes.SetAt(0x0000900a, true);	//	fire effect
	g_DefaultTypes.SetAt(0x0000A003, true);	//	dsAbandonedStation
	g_DefaultTypes.SetAt(0x0000a017, true);	//	dock screen?

	g_DefaultTypes.SetAt(0x001a200c, true);	//	wreck of the CSC Europa
	g_DefaultTypes.SetAt(0x001a200e, true);	//	sandstorm wreck
	g_DefaultTypes.SetAt(0x001c1002, true);	//	ares sect in Heretic
	g_DefaultTypes.SetAt(0x08020102, true);	//	huari empire sovereign
	g_DefaultTypes.SetAt(0x08040140, true);	//	gaian processor station
#endif

	//	Create a reverse index of all type dependencies

	ReverseIndexMap ReverseIndex;
	for (i = 0; i < Universe.GetDesignTypeCount(); i++)
		{
		CDesignType *pType = Universe.GetDesignType(i);

		//	Get the list of UNIDs that this type uses

		TSortMap<DWORD, bool> TypesUsed;
		pType->AddTypesUsed(&TypesUsed);
		for (j = 0; j < TypesUsed.GetCount(); j++)
			{
			CDesignType *pRequired = Universe.FindDesignType(TypesUsed.GetKey(j));
			if (pRequired == NULL)
				continue;

			//	Add to reverse index

			TArray<DWORD> *pList = ReverseIndex.SetAt(pRequired->GetUNID());
			pList->Insert(pType->GetUNID());
			}
		}

	//	We create a list of islands. In each island, all the types refer to
	//	each other and don't refer to types on any other island.

	TArray<IslandMap> AllIslands;

	//	Loop over all types and add them to an island.

	for (i = 0; i < Universe.GetDesignTypeCount(); i++)
		{
		CDesignType *pType = Universe.GetDesignType(i);

		//	Exclude images

		if (bExcludeImages && pType->GetType() == designImage)
			continue;

		if (pType->GetType() == designShipTable)
			continue;

		//	Exclude default types

		if (g_DefaultTypes.Find(pType->GetUNID()))
			continue;

		//	If this type is already on one of the islands, then we skip it.

#if 0
		bool bFound = false;
		for (j = 0; j < AllIslands.GetCount(); j++)
			if (AllIslands[j].Find(pType->GetUNID()))
				{
				bFound = true;
				break;
				}

		if (bFound)
			continue;
#endif 

		//	Since this type is not on any island, we add start a new island and
		//	add all related types to it.

		IslandMap *pIsland = AllIslands.Insert();
		AddTypeToIsland(Universe, ReverseIndex, pIsland, pType);

		//	Print

		printf("ISLAND %s\n", (char *)GetTypeDesc(pType));

		for (j = 0; j < pIsland->GetCount(); j++)
			{
			CDesignType *pType = Universe.FindDesignType(pIsland->GetKey(j));
			if (pType == NULL)
				continue;

			printf("%s\n", (char *)GetTypeDesc(pType));
			}

		printf("\n");
		}
	}
コード例 #9
0
ファイル: CSpaceObjectTrade.cpp プロジェクト: bmer/Mammoth
int CSpaceObject::GetSellPrice (const CItem &Item, DWORD dwFlags)

//	GetSellPrice
//
//	Returns the price at which the station will sell the given
//	item. Returns 0 if the station cannot or will not sell the
//	item.

	{
	bool bHasTradeDirective = false;
	int iPrice = -1;

	if (IsAbandoned())
		return false;

	//	See if we have an override price

	CTradingDesc *pTradeOverride = GetTradeDescOverride();
	if (pTradeOverride)
		{
		pTradeOverride->Sells(this, Item, dwFlags, &iPrice);
		bHasTradeDirective = true;
		}

	//	See if our type has a price

	CDesignType *pType = GetType();
	if (iPrice == -1)
		{
		CTradingDesc *pTrade = (pType ? pType->GetTradingDesc() : NULL);
		if (pTrade)
			{
			pTrade->Sells(this, Item, dwFlags, &iPrice);
			bHasTradeDirective = true;
			}
		}

	//	If we still have no price, then try to figure out a default.

	if (iPrice == -1)
		{
		//	If we have Trade directives and they specify no price, then we can't
		//	sell any.

		if (bHasTradeDirective)
			return 0;

		//	For compatibility, any ship prior to version 23 has a default.
		//	[For API Version 23 and above, ships must have a <Trade> descriptor.]

		else if (pType 
				&& pType->GetAPIVersion() < 23
				&& pType->GetType() == designShipClass)
			iPrice = CTradingDesc::CalcPriceForService(serviceSell, this, Item, 1, dwFlags);

		//	Otherwise, get the price from the item itself

		else
			iPrice = (int)GetDefaultEconomy()->Exchange(Item.GetCurrencyType(), Item.GetTradePrice(this));
		}

	//	If we don't have any of the item, then we don't sell any

	if (!(dwFlags & CTradingDesc::FLAG_NO_INVENTORY_CHECK))
		{
		CItemListManipulator ItemList(GetItemList());
		if (!ItemList.SetCursorAtItem(Item))
			return 0;
		}

	//	Return the price

	return iPrice;
	}
コード例 #10
0
ファイル: CSpaceObjectTrade.cpp プロジェクト: bmer/Mammoth
bool CSpaceObject::GetRefuelItemAndPrice (CSpaceObject *pObjToRefuel, CItemType **retpItemType, int *retiPrice)

//	GetRefuelItemAndPrice
//
//	Returns the appropriate item to use for refueling (based on the trading
//	directives).

	{
	int i;

	if (IsAbandoned())
		return false;

	//	See if we have an override

	CTradingDesc *pTradeOverride = GetTradeDescOverride();
	if (pTradeOverride && pTradeOverride->GetRefuelItemAndPrice(this, pObjToRefuel, 0, retpItemType, retiPrice))
		return true;

	//	Otherwise, ask our design type

	CDesignType *pType = GetType();
	if (pType == NULL)
		return false;

	CTradingDesc *pTrade = pType->GetTradingDesc();
	if (pTrade && pTrade->GetRefuelItemAndPrice(this, pObjToRefuel, 0, retpItemType, retiPrice))
		return true;

	//	For compatibility, any ship prior to version 23 has a default.
	//	[For API Version 23 and above, ships must have a <Trade> descriptor.]

	if (pType->GetAPIVersion() < 23
			&& pType->GetType() == designShipClass)
		{
		//	Get the ship

		CShip *pShipToRefuel = pObjToRefuel->AsShip();
		if (pShipToRefuel == NULL)
			return false;

		//	Find the highest-level item that can be used by the ship

		int iBestLevel = 0;
		int iBestPrice = 0;
		CItemType *pBestItem = NULL;

		for (i = 0; i < g_pUniverse->GetItemTypeCount(); i++)
			{
			CItemType *pType = g_pUniverse->GetItemType(i);
			CItem Item(pType, 1);

			if (pShipToRefuel->IsFuelCompatible(Item))
				{
				if (pBestItem == NULL || pType->GetLevel() > iBestPrice)
					{
					//	Compute the price, because if we don't sell it, then we
					//	skip it.
					//
					//	NOTE: Unlike selling, we allow 0 prices because some 
					//	stations give fuel for free.

					int iPrice = CTradingDesc::CalcPriceForService(serviceRefuel, this, Item, 1, 0);
					if (iPrice >= 0)
						{
						pBestItem = pType;
						iBestLevel = pType->GetLevel();
						iBestPrice = iPrice;
						}
					}
				}
			}

		if (pBestItem == NULL)
			return false;

		//	Done

		if (retpItemType)
			*retpItemType = pBestItem;

		if (retiPrice)
			*retiPrice = iBestPrice;

		return true;
		}

	//	Otherwise, we do not refuel

	return false;
	}
コード例 #11
0
ALERROR CDesignCollection::BindDesign (SDesignLoadCtx &Ctx)

//	BindDesign
//
//	Bind the design collection so that design types point the appropriate
//	pointers by UNID

	{
	ALERROR error;
	int i, j;

	//	Unbind everything

	for (i = 0; i < m_AllTypes.GetCount(); i++)
		m_AllTypes.GetEntry(i)->UnbindDesign();
	m_AllTypes.DeleteAll();

	//	Reset the bind tables

	for (i = 0; i < designCount; i++)
		m_ByType[i].DeleteAll();

	//	We start with all the base types

	for (i = 0; i < m_Base.GetCount(); i++)
		m_AllTypes.AddEntry(m_Base.GetEntry(i));

	//	Start with base topology

	m_pTopology = &m_BaseTopology;
	m_pAdventureExtension = NULL;

	//	Now add all enabled extensions

	for (i = 0; i < GetExtensionCount(); i++)
		{
		SExtensionDesc *pExtension = GetExtension(i);

		if (pExtension->bEnabled)
			{
			//	Add design elements in extension

			for (j = 0; j < pExtension->Table.GetCount(); j++)
				{
				CDesignType *pEntry = pExtension->Table.GetEntry(j);
				m_AllTypes.AddOrReplaceEntry(pEntry);
				}

			//	Handle adventure extensions

			if (pExtension->iType == extAdventure)
				{
				//	Keep track of extension

				m_pAdventureExtension = pExtension;

				//	Add topology

				m_pTopology = &pExtension->Topology;
				}
			}
		else
			{
			if (pExtension->iType == extAdventure)
				{
				DWORD dwCoverImage = 0;

				//	Adventure desc elements are added even if not enabled

				for (j = 0; j < pExtension->Table.GetCount(); j++)
					{
					CDesignType *pEntry = pExtension->Table.GetEntry(j);
					if (pEntry->GetType() == designAdventureDesc)
						{
						m_AllTypes.AddOrReplaceEntry(pEntry);

						//	Get the cover image used by the adventure, because
						//	we need to load that too.

						CAdventureDesc *pDesc = CAdventureDesc::AsType(pEntry);
						dwCoverImage = pDesc->GetBackgroundUNID();
						}
					}

				//	Make sure we load the cover image

				if (dwCoverImage)
					{
					for (j = 0; j < pExtension->Table.GetCount(); j++)
						{
						CDesignType *pEntry = pExtension->Table.GetEntry(j);
						if (pEntry->GetUNID() == dwCoverImage)
							m_AllTypes.AddOrReplaceEntry(pEntry);
						}
					}
				}
			}
		}

	//	If this is a new game, then create all the Template types

	if (Ctx.bNewGame)
		{
		m_DynamicUNIDs.DeleteAll();
		m_DynamicTypes.DeleteAll();

		if (error = FireOnGlobalTypesInit(Ctx))
			return error;

		if (error = CreateTemplateTypes(Ctx))
			return error;
		}

	//	Add all the dynamic types. These came either from the saved game file or
	//	from the Template types above.

	for (i = 0; i < m_DynamicTypes.GetCount(); i++)
		m_AllTypes.AddOrReplaceEntry(m_DynamicTypes.GetType(i));

	//	Initialize the byType lists

	for (i = 0; i < m_AllTypes.GetCount(); i++)
		{
		CDesignType *pEntry = m_AllTypes.GetEntry(i);
		m_ByType[pEntry->GetType()].AddEntry(pEntry);
		}

	//	Set our adventure desc as current; since adventure descs are always 
	//	loaded this is the only thing that we can use to tell if we should
	//	call global events.
	//
	//	This must happen after Unbind (because that clears it) and before
	//	PrepareBindDesign.
	//
	//	NOTE: m_pAdventureDesc can be NULL (e.g., in the intro screen).

	if (m_pAdventureDesc)
		m_pAdventureDesc->SetCurrentAdventure();

	//	Cache a map between currency name and economy type
	//	We need to do this before Bind because some types will lookup
	//	a currency name during Bind.

	m_EconomyIndex.DeleteAll();
	for (i = 0; i < GetCount(designEconomyType); i++)
		{
		CEconomyType *pEcon = CEconomyType::AsType(GetEntry(designEconomyType, i));
		const CString &sName = pEcon->GetSID();

		bool bUnique;
		CEconomyType **ppDest = m_EconomyIndex.SetAt(sName, &bUnique);
		if (!bUnique)
			return pEcon->ComposeLoadError(Ctx, CONSTLIT("Currency ID must be unique"));

		*ppDest = pEcon;
		}

	//	Prepare to bind. This is used by design elements
	//	that need two passes to bind.

	for (i = 0; i < m_AllTypes.GetCount(); i++)
		{
		CDesignType *pEntry = m_AllTypes.GetEntry(i);
		if (error = pEntry->PrepareBindDesign(Ctx))
			return error;
		}

	//	Now call Bind on all active design entries

	for (i = 0; i < evtCount; i++)
		m_EventsCache[i]->DeleteAll();

	for (i = 0; i < m_AllTypes.GetCount(); i++)
		{
		CDesignType *pEntry = m_AllTypes.GetEntry(i);
		if (error = pEntry->BindDesign(Ctx))
			return error;

		//	Cache some global events. We keep track of the global events for
		//	all types so that we can access them faster.

		CacheGlobalEvents(pEntry);
		}

	//	Finish binding. This pass is used by design elements
	//	that need to do stuff after all designs are bound.

	for (i = 0; i < m_AllTypes.GetCount(); i++)
		{
		CDesignType *pEntry = m_AllTypes.GetEntry(i);
		if (error = pEntry->FinishBindDesign(Ctx))
			return error;
		}

	return NOERROR;
	}
コード例 #12
0
ファイル: CDesignCollection.cpp プロジェクト: bmer/Mammoth
ALERROR CDesignCollection::BindDesign (const TArray<CExtension *> &BindOrder, bool bNewGame, bool bNoResources, CString *retsError)

//	BindDesign
//
//	Binds the design collection to the set of design types in the given list of
//	extensions.

	{
	DEBUG_TRY

	ALERROR error;
	int i;

	//	Unbind everything

	DEBUG_TRY

	CShipClass::UnbindGlobal();

	for (i = 0; i < m_AllTypes.GetCount(); i++)
		m_AllTypes.GetEntry(i)->UnbindDesign();
	m_AllTypes.DeleteAll();

	DEBUG_CATCH_MSG("Crash unbinding types.");

	//	Reset the bind tables

	for (i = 0; i < designCount; i++)
		m_ByType[i].DeleteAll();

	m_CreatedTypes.DeleteAll(true);
	m_OverrideTypes.DeleteAll();

	//	Reset

	m_pTopology = NULL;
	m_pAdventureExtension = NULL;

	//	Create a design load context

	SDesignLoadCtx Ctx;
	Ctx.bBindAsNewGame = bNewGame;
	Ctx.bNoResources = bNoResources;

	//	Loop over the bind list in order and add appropriate types to m_AllTypes
	//	(The order guarantees that the proper types override)

	for (i = 0; i < BindOrder.GetCount(); i++)
		{
		CExtension *pExtension = BindOrder[i];

		try {

		const CDesignTable &Types = pExtension->GetDesignTypes();

#ifdef DEBUG_BIND
		::OutputDebugString(strPatternSubst(CONSTLIT("EXTENSION %s\n"), pExtension->GetName()));
		for (int j = 0; j < Types.GetCount(); j++)
			{
			::OutputDebugString(strPatternSubst(CONSTLIT("%08x: %s\n"), Types.GetEntry(j)->GetUNID(), Types.GetEntry(j)->GetTypeName()));
			}
#endif

		//	Run globals for the extension

		if (error = pExtension->ExecuteGlobals(Ctx))
			{
			*retsError = Ctx.sError;
			return error;
			}

		//	Add the types

		m_AllTypes.Merge(Types, &m_OverrideTypes);

		//	If this is the adventure, then remember it

		if (pExtension->GetType() == extAdventure)
			{
			m_pAdventureExtension = pExtension;
			m_pAdventureDesc = pExtension->GetAdventureDesc();
			}

		//	If this is an adventure or the base extension then take the 
		//	topology.

		if (pExtension->GetType() == extAdventure || pExtension->GetType() == extBase)
			m_pTopology = &pExtension->GetTopology();

		} catch (...)
			{
			::kernelDebugLogMessage("Crash processing extension:");
			CExtension::DebugDump(pExtension, true);
			throw;
			}
		}

	//	If this is a new game, then create all the Template types

	if (bNewGame)
		{
		DEBUG_TRY

		m_DynamicUNIDs.DeleteAll();
		m_DynamicTypes.DeleteAll();

		if (error = FireOnGlobalTypesInit(Ctx))
			{
			*retsError = Ctx.sError;
			return error;
			}

		if (error = CreateTemplateTypes(Ctx))
			{
			*retsError = Ctx.sError;
			return error;
			}

		DEBUG_CATCH_MSG("Crash defining dynamic types.");
		}

	//	Add all the dynamic types. These came either from the saved game file or
	//	from the Template types above.

	m_AllTypes.Merge(m_DynamicTypes, &m_OverrideTypes);

	//	Now resolve all overrides and inheritance

	if (error = ResolveOverrides(Ctx))
		{
		*retsError = Ctx.sError;
		return error;
		}

	//	Initialize the byType lists

	DEBUG_TRY
	for (i = 0; i < m_AllTypes.GetCount(); i++)
		{
		CDesignType *pEntry = m_AllTypes.GetEntry(i);
		m_ByType[pEntry->GetType()].AddEntry(pEntry);
		}
	DEBUG_CATCH_MSG("Crash initializing byType lists.");

	//	Set our adventure desc as current; since adventure descs are always 
	//	loaded this is the only thing that we can use to tell if we should
	//	call global events.
	//
	//	This must happen after Unbind (because that clears it) and before
	//	PrepareBindDesign.
	//
	//	NOTE: m_pAdventureDesc can be NULL (e.g., in the intro screen).

	DEBUG_TRY
	if (m_pAdventureDesc)
		m_pAdventureDesc->SetCurrentAdventure();
	DEBUG_CATCH_MSG("Crash setting current adventure.");

	//	Cache a map between currency name and economy type
	//	We need to do this before Bind because some types will lookup
	//	a currency name during Bind.

	DEBUG_TRY
	m_EconomyIndex.DeleteAll();
	for (i = 0; i < GetCount(designEconomyType); i++)
		{
		CEconomyType *pEcon = CEconomyType::AsType(GetEntry(designEconomyType, i));
		const CString &sName = pEcon->GetSID();

		bool bUnique;
		CEconomyType **ppDest = m_EconomyIndex.SetAt(sName, &bUnique);
		if (!bUnique)
			{
			pEcon->ComposeLoadError(Ctx, CONSTLIT("Currency ID must be unique"));
			*retsError = Ctx.sError;
			return ERR_FAIL;
			}

		*ppDest = pEcon;
		}
	DEBUG_CATCH_MSG("Crash initializing economies.");

	//	Prepare to bind. This is used by design elements that need two passes
	//	to bind. We also use it to set up the inheritence hierarchy, which means
	//	that we rely on the map from UNID to valid design type (m_AllTypes)

	m_DisplayAttribs.DeleteAll();

	DEBUG_TRY
	for (i = 0; i < m_AllTypes.GetCount(); i++)
		{
		CDesignType *pEntry = m_AllTypes.GetEntry(i);
		if (error = pEntry->PrepareBindDesign(Ctx))
			{
			*retsError = Ctx.sError;
			return error;
			}

		//	We take this opportunity to build a list of display attributes
		//	defined by each type.

		const CDisplayAttributeDefinitions &Attribs = pEntry->GetDisplayAttributes();
		if (!Attribs.IsEmpty())
			m_DisplayAttribs.Append(Attribs);
		}
	DEBUG_CATCH_MSG("Crash in PrepareBind.");

	//	Now call Bind on all active design entries

	for (i = 0; i < evtCount; i++)
		m_EventsCache[i]->DeleteAll();

	DEBUG_TRY
	for (i = 0; i < m_AllTypes.GetCount(); i++)
		{
		CDesignType *pEntry = m_AllTypes.GetEntry(i);
		if (error = pEntry->BindDesign(Ctx))
			{
			*retsError = Ctx.sError;
			return error;
			}

		//	Cache some global events. We keep track of the global events for
		//	all types so that we can access them faster.

		CacheGlobalEvents(pEntry);
		}
	DEBUG_CATCH_MSG("Crash in BindDesign.");

	//	Finish binding. This pass is used by design elements
	//	that need to do stuff after all designs are bound.

	DEBUG_TRY
	for (i = 0; i < m_AllTypes.GetCount(); i++)
		{
		CDesignType *pEntry = m_AllTypes.GetEntry(i);
		if (error = pEntry->FinishBindDesign(Ctx))
			{
			*retsError = Ctx.sError;
			return error;
			}
		}
	DEBUG_CATCH_MSG("Crash in FinishBind.");

	//	Remember what we bound

	m_BoundExtensions = BindOrder;

	return NOERROR;

	DEBUG_CATCH
	}
コード例 #13
0
ALERROR CDesignCollection::BindDesign (SDesignLoadCtx &Ctx)

//	BindDesign
//
//	Bind the design collection so that design types point the appropriate
//	pointers by UNID

	{
	ALERROR error;
	int i, j;

	//	Reset the bind tables

	m_AllTypes.RemoveAll();
	for (i = 0; i < designCount; i++)
		m_ByType[i].RemoveAll();

	//	We start with all the base types

	for (i = 0; i < m_Base.GetCount(); i++)
		m_AllTypes.AddEntry(m_Base.GetEntry(i));

	//	Start with base topology

	m_pTopology = &m_BaseTopology;
	m_pAdventureExtension = NULL;

	//	Now add all enabled extensions

	for (i = 0; i < GetExtensionCount(); i++)
		{
		SExtensionDesc *pExtension = GetExtension(i);

		if (pExtension->bEnabled)
			{
			//	Add design elements in extension

			for (j = 0; j < pExtension->Table.GetCount(); j++)
				m_AllTypes.AddOrReplaceEntry(pExtension->Table.GetEntry(j));

			//	Handle adventure extensions

			if (pExtension->iType == extAdventure)
				{
				//	Keep track of extension

				m_pAdventureExtension = pExtension;

				//	Add topology

				m_pTopology = &pExtension->Topology;
				}
			}
		else
			{
			if (pExtension->iType == extAdventure)
				{
				//	Adventure desc elements are added even if not enabled

				for (j = 0; j < pExtension->Table.GetCount(); j++)
					{
					CDesignType *pEntry = pExtension->Table.GetEntry(j);
					if (pEntry->GetType() == designAdventureDesc)
						m_AllTypes.AddOrReplaceEntry(pEntry);
					}
				}
			}
		}

	//	Initialize the byType lists

	for (i = 0; i < m_AllTypes.GetCount(); i++)
		{
		CDesignType *pEntry = m_AllTypes.GetEntry(i);
		m_ByType[pEntry->GetType()].AddEntry(pEntry);
		}

	//	Now call Bind on all active design entries

	for (i = 0; i < m_AllTypes.GetCount(); i++)
		{
		CDesignType *pEntry = m_AllTypes.GetEntry(i);
		if (error = pEntry->BindDesign(Ctx))
			return error;
		}

	//	Check to make sure we have at least one topology node

	if (m_pTopology->GetRootNodeCount() == 0)
		{
		Ctx.sError = CONSTLIT("No topology nodes found");
		return ERR_FAIL;
		}

	return NOERROR;
	}