Exemplo n.º 1
0
ALERROR CConquerNodesProc::LoadNodeWeightTable (SDesignLoadCtx &Ctx, CXMLElement *pDesc, TArray<SNodeWeight> *retTable)

//	LoadNodeWeightTable
//
//	Loads a node criteria/weight table

	{
	ALERROR error;
	int i;

	//	OK if NULL; it means the element is missing

	if (pDesc == NULL)
		return NOERROR;

	//	Load

	for (i = 0; i < pDesc->GetContentElementCount(); i++)
		{
		CXMLElement *pChanceXML = pDesc->GetContentElement(i);
		SNodeWeight *pChance = retTable->Insert();

		if (error = CTopologyNode::ParseCriteria(pChanceXML->GetAttribute(CRITERIA_ATTRIB),
				&pChance->Criteria,
				&Ctx.sError))
			return error;

		pChance->iWeight = pChanceXML->GetAttributeIntegerBounded(WEIGHT_ATTRIB, 0, -1, 1);
		pChance->iSuccessChance = pChanceXML->GetAttributeIntegerBounded(SUCCESS_CHANCE_ATTRIB, 0, 100, 100);
		}

	return NOERROR;
	}
Exemplo n.º 2
0
ALERROR CGroupOfDeviceGenerators::LoadFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc)

//	LoadFromXML
//
//	Load from XML

	{
	int i;
	ALERROR error;

	m_Count.LoadFromXML(pDesc->GetAttribute(COUNT_ATTRIB));
	if (m_Count.IsEmpty())
		m_Count.SetConstant(1);

	//	Load either a <DeviceSlot> element or another device generator.

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

		if (strEquals(pEntry->GetTag(), DEVICE_SLOT_TAG))
			{
			SSlotDesc *pSlotDesc = m_SlotDesc.Insert();

			CItem::ParseCriteria(pEntry->GetAttribute(CRITERIA_ATTRIB), &pSlotDesc->Criteria);

			if (error = IDeviceGenerator::InitDeviceDescFromXML(Ctx, pEntry, &pSlotDesc->DefaultDesc))
				return error;

			pSlotDesc->iMaxCount = pEntry->GetAttributeIntegerBounded(MAX_COUNT_ATTRIB, 0, -1, -1);
			}
		else
			{
			SEntry *pTableEntry = m_Table.Insert();

			pTableEntry->iChance = pEntry->GetAttributeIntegerBounded(CHANCE_ATTRIB, 0, -1, 100);
			if (error = IDeviceGenerator::CreateFromXML(Ctx, pEntry, &pTableEntry->pDevice))
				{
				pTableEntry->pDevice = NULL;
				return error;
				}
			}
		}

	return NOERROR;
	}
Exemplo n.º 3
0
ALERROR CIntegralRotationDesc::InitFromXML (SDesignLoadCtx &Ctx, const CString &sUNID, CXMLElement *pDesc)

//	InitFromXML
//
//	Initialize from an XML descriptor

	{
	//	If we have a Maneuver element, then use that (and ignore other attributes)

	CXMLElement *pManeuver = pDesc->GetContentElementByTag(MANEUVER_TAG);
	if (pManeuver)
		{
		m_iManeuverability = 0;
		m_iCount = pManeuver->GetAttributeIntegerBounded(ROTATION_COUNT_ATTRIB, 1, -1, STD_ROTATION_COUNT);

		//	Max rotation rate is in degrees per tick. Later we convert that to rotation frames per tick
		//	(but not until we figure out the number of rotation frames).

		m_rDegreesPerTick = pManeuver->GetAttributeDoubleBounded(MAX_ROTATION_RATE_ATTRIB, 0.01, -1.0, 360.0 / STD_ROTATION_COUNT);

		//	Also convert rotation acceleration

		m_rAccelPerTick = pManeuver->GetAttributeDoubleBounded(ROTATION_ACCEL_ATTRIB, 0.01, -1.0, m_rDegreesPerTick);
		m_rAccelPerTickStop = pManeuver->GetAttributeDoubleBounded(ROTATION_STOP_ACCEL_ATTRIB, 0.01, -1.0, m_rAccelPerTick);
		}

	//	Otherwise we look for attributes on the root (this is backwards compatible
	//	with version prior to API 20

	else
		{
		m_iCount = pDesc->GetAttributeIntegerBounded(ROTATION_COUNT_ATTRIB, 1, -1, STD_ROTATION_COUNT);

		//	The original maneuverability value is the number of half-ticks that 
		//	we take per rotation frame.
		//
		//	NOTE: For compatibility we don't allow maneuverability less than 2, which was the 
		//	limit using the old method (1 tick delay).

		m_iManeuverability = pDesc->GetAttributeIntegerBounded(MANEUVER_ATTRIB, 2, -1, 2);

		//	Convert that to degrees per tick

		m_rDegreesPerTick = (m_iCount > 0 ? (STD_SECONDS_PER_UPDATE * 360.0) / (m_iCount * m_iManeuverability) : 0.0);

		//	Default acceleration is equal to rotation rate

		m_rAccelPerTick = m_rDegreesPerTick;
		m_rAccelPerTickStop = m_rDegreesPerTick;
		}

	return NOERROR;
	}
ALERROR CTableEntry::InitFromXML (SDesignLoadCtx &Ctx, CIDCounter &IDGen, CXMLElement *pDesc)

//	InitFromXML
//
//	Initialize from XML

	{
	ALERROR error;
	int i;

	m_dwID = IDGen.GetID();

	//	Load each sub-entry in turn

	int iCount = pDesc->GetContentElementCount();
	if (iCount == 0)
		return NOERROR;

	m_iTotalChance = 0;
	m_Table.InsertEmpty(iCount);
	for (i = 0; i < iCount; i++)
		{
		CXMLElement *pItem = pDesc->GetContentElement(i);

		if (error = CCompositeImageDesc::InitEntryFromXML(Ctx, pItem, IDGen, &m_Table[i].pImage))
			return error;

		//	Load the chance

		m_Table[i].iChance = pItem->GetAttributeIntegerBounded(CHANCE_ATTRIB, 0, -1, 1);
		m_iTotalChance += m_Table[i].iChance;
		}

	//	Done

	return NOERROR;
	}
Exemplo n.º 5
0
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;
	}
Exemplo n.º 6
0
bool IDockScreenDisplay::GetDisplayOptions (SInitCtx &Ctx, SDisplayOptions *retOptions, CString *retsError)

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

	{
	//	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 = 482;
		}

	//	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)
		return true;

	//	Read from the element

	retOptions->sDataFrom = pOptions->GetAttribute(DATA_FROM_ATTRIB);
	retOptions->sItemCriteria = pOptions->GetAttribute(LIST_ATTRIB);
	retOptions->sCode = pOptions->GetContentText(0);
	retOptions->sInitialItemCode = pOptions->GetAttribute(INITIAL_ITEM_ATTRIB);
	retOptions->sRowHeightCode = pOptions->GetAttribute(ROW_HEIGHT_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;
	}
Exemplo n.º 7
0
void GenerateEffectImage (CUniverse &Universe, CXMLElement *pCmdLine)
	{
	CString sError;
	int i, j;

	//	Input file

	CString sInput = pCmdLine->GetAttribute(CONSTLIT("input"));
	if (sInput.IsBlank())
		{
		printf("Input file required.\n");
		return;
		}

	//	Output file (optional)

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

	//	Load a resource file so that we can create a design load context

	CResourceDb Resources(CONSTLIT("Transcendence"));
	if (Resources.Open(DFOPEN_FLAG_READ_ONLY, &sError) != NOERROR)
		{
		printf("%s\n", (LPSTR)sError);
		return;
		}

	CExternalEntityTable *pEntities;
	if (Resources.LoadEntities(&sError, &pEntities) != NOERROR)
		{
		printf("%s\n", sError.GetASCIIZPointer());
		return;
		}

	//	Generate a list of effect render structures

	TArray<SEffectRender> Effects;

	//	Load the input file

	CFileReadBlock InputFile(sInput);
	if (InputFile.Open() != NOERROR)
		{
		printf("Unable to open input file: %s\n", sInput.GetASCIIZPointer());
		return;
		}

	//	Parse the file

	CXMLElement *pRenderFile;
	if (CXMLElement::ParseXML(&InputFile, pEntities, &pRenderFile, &sError) != NOERROR)
		{
		printf("%s\n", sError.GetASCIIZPointer());
		return;
		}

	//	Keep track of the max cell size and frame count

	int cxCellWidth = 0;
	int cyCellHeight = 0;
	int iCellsPerEffect = 1;

	//	Generate structures

	SDesignLoadCtx LoadCtx;
	LoadCtx.sResDb = Resources.GetFilespec();
	LoadCtx.pResDb = &Resources;
	LoadCtx.bNoVersionCheck = true;

	for (i = 0; i < pRenderFile->GetContentElementCount(); i++)
		{
		CXMLElement *pRender = pRenderFile->GetContentElement(i);
		CXMLElement *pEffectDesc = pRender->GetContentElementByTag(CONSTLIT("Effect"));
		if (pEffectDesc == NULL)
			{
			printf("<Effect> tag required.\n");
			return;
			}

		SEffectRender *pEffect = Effects.Insert();

		//	Parse the effect

		if (pEffect->pEffectCreator.LoadEffect(LoadCtx, CONSTLIT("none"), pEffectDesc, NULL_STR) != NOERROR)
			{
			printf("%s\n", LoadCtx.sError.GetASCIIZPointer());
			return;
			}

		//	Bind

		if (pEffect->pEffectCreator.Bind(LoadCtx) != NOERROR)
			{
			printf("%s\n", LoadCtx.sError.GetASCIIZPointer());
			return;
			}

		//	Create a painter

		pEffect->pPainter = pEffect->pEffectCreator->CreatePainter();
		if (pEffect->pPainter == NULL)
			{
			printf("Unable to create painter.\n");
			return;
			}

		//	Render specs

		int cyHeight = pRender->GetAttributeIntegerBounded(CONSTLIT("height"), 0, -1, 128);
		int cxWidth = pRender->GetAttributeIntegerBounded(CONSTLIT("width"), 0, -1, 128);

		cxCellWidth = Max(cxCellWidth, cxWidth);
		cyCellHeight = Max(cyCellHeight, cyHeight);

		//	Figure out how many animation cells

		pEffect->iLifetime = Max(1, pEffect->pEffectCreator->GetLifetime());
		iCellsPerEffect = Max(iCellsPerEffect, pEffect->iLifetime);
		}

	//	Create the resulting image

	CImageGrid Output;
	Output.Create(iCellsPerEffect * Effects.GetCount(), cxCellWidth, cyCellHeight);

	//	Paint

	for (i = 0; i < Effects.GetCount(); i++)
		{
		SEffectRender *pEffect = &Effects[i];

		SViewportPaintCtx Ctx;

		for (j = 0; j < pEffect->iLifetime; j++)
			{
			int x, y;
			Output.GetCellCenter(i * iCellsPerEffect + j, &x, &y);

			//	Create a context

			Ctx.iTick = j;

			//	Paint the effect

			pEffect->pPainter->Paint(Output.GetImage(), x, y, Ctx);

			//	Update

			pEffect->pPainter->OnUpdate();
			}
		}

	//	Output

	OutputImage(Output.GetImage(), sFilespec);
	}
Exemplo n.º 8
0
void CDockingPorts::InitPortsFromXML (CSpaceObject *pOwner, CXMLElement *pElement)

//	InitPortsFromXML
//
//	InitPortsFromXML 

	{
	int i;

	//	See if we've got a special element with docking port geometry

	CXMLElement *pDockingPorts = pElement->GetContentElementByTag(DOCKING_PORTS_TAG);
	if (pDockingPorts)
		{
		//	Initialize max dist
		//	NOTE: pOwner can be NULL because sometimes we init ports from a ship class 
		//	(without an object).

		int iDefaultDist = Max(DEFAULT_DOCK_DISTANCE_LS, (pOwner ? 8 + (int)((pOwner->GetBoundsRadius() / LIGHT_SECOND) + 0.5) : 0));
		m_iMaxDist = pDockingPorts->GetAttributeIntegerBounded(MAX_DIST_ATTRIB, 1, -1, iDefaultDist);


		//	If we have sub-elements then these are port definitions.

		m_iPortCount = pDockingPorts->GetContentElementCount();
		if (m_iPortCount > 0)
			{
			m_pPort = new SDockingPort[m_iPortCount];

			for (i = 0; i < m_iPortCount; i++)
				{
				CXMLElement *pPort = pDockingPorts->GetContentElement(i);
				CVector vDockPos((pPort->GetAttributeInteger(X_ATTRIB) * g_KlicksPerPixel),
						(pPort->GetAttributeInteger(Y_ATTRIB) * g_KlicksPerPixel));

				m_pPort[i].vPos = vDockPos;

				if (pPort->FindAttributeInteger(ROTATION_ATTRIB, &m_pPort[i].iRotation))
					m_pPort[i].iRotation = (m_pPort[i].iRotation % 360);
				else
					m_pPort[i].iRotation = (VectorToPolar(vDockPos) + 180) % 360;

				if (pPort->GetAttributeBool(BRING_TO_FRONT_ATTRIB))
					m_pPort[i].iLayer = plBringToFront;
				else if (pPort->GetAttributeBool(SEND_TO_BACK_ATTRIB))
					m_pPort[i].iLayer = plSendToBack;
				}
			}

		//	Otherwise, we expect a port count and radius

		else if ((m_iPortCount = pDockingPorts->GetAttributeIntegerBounded(PORT_COUNT_ATTRIB, 0, -1, 0)) > 0)
			{
			int iRadius = pDockingPorts->GetAttributeIntegerBounded(PORT_RADIUS_ATTRIB, 0, -1, DEFAULT_PORT_POS_RADIUS);
			int iAngle = 360 / m_iPortCount;

			//	We need the image scale to adjust coordinates

			int iScale = (pOwner ? pOwner->GetImage().GetImageViewportSize() : 512);

			//	Initialize ports

			m_pPort = new SDockingPort[m_iPortCount];
			for (i = 0; i < m_iPortCount; i++)
				{
				C3DConversion::CalcCoord(iScale, i * iAngle, iRadius, 0, &m_pPort[i].vPos);
				m_pPort[i].iRotation = ((i * iAngle) + 180) % 360;
				}
			}

		//	Otherwise, no ports

		else
			{
			m_iPortCount = 0;
			m_pPort = NULL;
			}
		}

	//	Otherwise, initialize ports based on a count

	else
		InitPorts(pOwner,
				pElement->GetAttributeInteger(DOCKING_PORTS_ATTRIB),
				64 * g_KlicksPerPixel);
	}
Exemplo n.º 9
0
void CDockingPorts::InitPortsFromXML (CSpaceObject *pOwner, CXMLElement *pElement)

//	InitPortsFromXML
//
//	InitPortsFromXML 

	{
	int i;

	//	See if we've got a special element with docking port geometry

	CXMLElement *pDockingPorts = pElement->GetContentElementByTag(DOCKING_PORTS_TAG);
	if (pDockingPorts)
		{
		//	Initialize max dist

		m_iMaxDist = pDockingPorts->GetAttributeIntegerBounded(MAX_DIST_ATTRIB, 1, -1, DEFAULT_DOCK_DISTANCE_LS);

		//	If we have sub-elements then these are port definitions.

		m_iPortCount = pDockingPorts->GetContentElementCount();
		if (m_iPortCount > 0)
			{
			m_pPort = new DockingPort[m_iPortCount];

			for (i = 0; i < m_iPortCount; i++)
				{
				CXMLElement *pPort = pDockingPorts->GetContentElement(i);
				CVector vDockPos((pPort->GetAttributeInteger(X_ATTRIB) * g_KlicksPerPixel),
						(pPort->GetAttributeInteger(Y_ATTRIB) * g_KlicksPerPixel));

				m_pPort[i].iStatus = psEmpty;
				m_pPort[i].pObj = NULL;
				m_pPort[i].vPos = vDockPos;

				if (pPort->FindAttributeInteger(ROTATION_ATTRIB, &m_pPort[i].iRotation))
					m_pPort[i].iRotation = (m_pPort[i].iRotation % 360);
				else
					m_pPort[i].iRotation = (VectorToPolar(vDockPos) + 180) % 360;
				}
			}

		//	Otherwise, we expect a port count and radius

		else if ((m_iPortCount = pDockingPorts->GetAttributeIntegerBounded(PORT_COUNT_ATTRIB, 0, -1, 0)) > 0)
			{
			m_pPort = new DockingPort[m_iPortCount];
			
			int iRadius = pDockingPorts->GetAttributeIntegerBounded(PORT_RADIUS_ATTRIB, 0, -1, DEFAULT_PORT_POS_RADIUS);
			Metric rRadius = g_KlicksPerPixel * iRadius;

			int iAngle = 360 / m_iPortCount;
			for (i = 0; i < m_iPortCount; i++)
				{
				m_pPort[i].iStatus = psEmpty;
				m_pPort[i].pObj = NULL;
				m_pPort[i].vPos = PolarToVector(i * iAngle, rRadius);
				m_pPort[i].iRotation = ((i * iAngle) + 180) % 360;
				}
			}

		//	Otherwise, no ports

		else
			{
			m_iPortCount = 0;
			m_pPort = NULL;
			}
		}

	//	Otherwise, initialize ports based on a count

	else
		InitPorts(pOwner,
				pElement->GetAttributeInteger(DOCKING_PORTS_ATTRIB),
				64 * g_KlicksPerPixel);
	}
Exemplo n.º 10
0
ALERROR CConquerNodesProc::OnInitFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc, const CString &sUNID)

//	OnInitFromXML
//
//	Initialize from XML element

	{
	ALERROR error;
	int i;

	//	Initialize criteria

	CTopologyNode::ParseCriteria(NULL, &m_Criteria);

	//	Loop over all elements

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

		//	If we have a criteria, parse it and remember it
		//	(Note: If multiple criteria are found, we take the latest one).

		if (strEquals(pItem->GetTag(), CRITERIA_TAG))
			{
			//	Parse the filter

			if (error = CTopologyNode::ParseCriteria(pItem, &m_Criteria, &Ctx.sError))
				return error;
			}

		//	Otherwise, treat it as a conqueror definition and insert it in the list

		else
			{
			CString sNewUNID = strPatternSubst(CONSTLIT("%s/%d"), sUNID, m_Conquerors.GetCount());
			SConqueror *pConqueror = m_Conquerors.Insert();

			//	Get some properties

			pConqueror->iSeedChance = pItem->GetAttributeIntegerBounded(SEED_CHANCE_ATTRIB, 1, 100, 1);
			pConqueror->iMaxSeeds = pItem->GetAttributeIntegerBounded(MAX_SEEDS_ATTRIB, 1, -1, 1);
			pConqueror->iExpandChance = pItem->GetAttributeIntegerBounded(EXPAND_CHANCE_ATTRIB, 1, 100, 1);
			pConqueror->iMaxNodes = pItem->GetAttributeIntegerBounded(MAX_NODES_ATTRIB, 1, -1, 1);

			//	Get the seed and expand probabilities

			if (error = LoadNodeWeightTable(Ctx, pItem->GetContentElementByTag(SEED_CHANCE_TAG), &pConqueror->Seed))
				return error;

			if (error = LoadNodeWeightTable(Ctx, pItem->GetContentElementByTag(EXPAND_CHANCE_TAG), &pConqueror->Expand))
				return error;

			//	Get the processor itself

			CXMLElement *pProcXML = pItem->GetContentElementByTag(PROCESSOR_TAG);
			if (pProcXML)
				{

				if (error = ITopologyProcessor::CreateFromXMLAsGroup(Ctx, pProcXML, sNewUNID, &pConqueror->pProc))
					return error;
				}
			else
				{
				Ctx.sError = CONSTLIT("<Processor> element not found in <ConquerNodes>");
				return ERR_FAIL;
				}
			}
		}

	return NOERROR;
	}
Exemplo n.º 11
0
ALERROR COverlayType::OnCreateFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc)

//	OnCreateFromXML
//
//	Create from XML

	{
	ALERROR error;

	//	Effect

	CXMLElement *pEffect = pDesc->GetContentElementByTag(EFFECT_TAG);
	if (pEffect)
		{
		if (error = CEffectCreator::CreateFromXML(Ctx, 
				pEffect, 
				strPatternSubst(CONSTLIT("%d:e"), GetUNID()), 
				&m_pEffect))
			{
			Ctx.sError = strPatternSubst(CONSTLIT("energy field %x: Unable to load effect"), GetUNID());
			return error;
			}
		}

	pEffect = pDesc->GetContentElementByTag(HIT_EFFECT_TAG);
	if (pEffect == NULL)
		pEffect = pDesc->GetContentElementByTag(EFFECT_WHEN_HIT_TAG);

	if (pEffect)
		{
		if (error = CEffectCreator::CreateFromXML(Ctx, 
				pEffect, 
				strPatternSubst(CONSTLIT("%d:h"), GetUNID()), 
				&m_pHitEffect))
			{
			Ctx.sError = strPatternSubst(CONSTLIT("energy field %x: Unable to load hit effect"), GetUNID());
			return error;
			}

		//	For compatibility with previous versions, if we're using the old
		//	<ShipEnergyFieldType> then altEffect defaults to TRUE. Otherwise, for new
		//	<OverlayType> altEffect defaults to false.

		bool bAltEffect;
		if (pEffect->FindAttributeBool(ALT_EFFECT_ATTRIB, &bAltEffect))
			m_fAltHitEffect = bAltEffect;
		else
			m_fAltHitEffect = strEquals(pDesc->GetTag(), SHIP_ENERGY_FIELD_TYPE_TAG);
		}
	else
		m_fAltHitEffect = false;

	//	Rotation

	m_fRotateWithShip = !pDesc->GetAttributeBool(IGNORE_SHIP_ROTATION_ATTRIB);

	//	Damage adjustment

	int iAbsorbCount;
	LoadDamageAdj(pDesc, ABSORB_ADJ_ATTRIB, m_iAbsorbAdj, &iAbsorbCount);

	//	Bonus adjustment

	LoadDamageAdj(pDesc, BONUS_ADJ_ATTRIB, m_iBonusAdj);

	//	Load the weapon suppress

	if (error = m_WeaponSuppress.InitFromXML(pDesc->GetAttribute(WEAPON_SUPPRESS_ATTRIB)))
		{
		Ctx.sError = CONSTLIT("Unable to load weapon suppress attribute");
		return error;
		}

	//	Keep track of the events that we have

	m_fHasOnUpdateEvent = FindEventHandler(ON_UPDATE_EVENT);

	//	Are we a field/shield overlay (or part of hull)?
	//	By default, we are a shield overlay if we absorb damage.

	bool bValue;
	if (pDesc->FindAttributeBool(SHIELD_OVERLAY_ATTRIB, &bValue))
		m_fShieldOverlay = bValue;
	else
		m_fShieldOverlay = (iAbsorbCount > 0);

	//	Counter

	CXMLElement *pCounter = pDesc->GetContentElementByTag(COUNTER_TAG);
	if (pCounter)
		{
		CString sStyle = pCounter->GetAttribute(STYLE_ATTRIB);
		if (strEquals(sStyle, COUNTER_PROGRESS))
			m_iCounterType = counterProgress;
		else if (strEquals(sStyle, COUNTER_RADIUS))
			m_iCounterType = counterRadius;
		else
			{
			Ctx.sError = strPatternSubst(CONSTLIT("Unknown counter style: %s"), sStyle);
			return ERR_FAIL;
			}

		m_sCounterLabel = pCounter->GetAttribute(LABEL_ATTRIB);
		m_iCounterMax = pCounter->GetAttributeIntegerBounded(MAX_ATTRIB, 0, -1, 100);
		m_wCounterColor = ::LoadRGBColor(pCounter->GetAttribute(COLOR_ATTRIB));
		}
	else
		{
		m_iCounterType = counterNone;
		m_iCounterMax = 0;
		m_wCounterColor = 0;
		}

	//	Options

	m_fDisarmShip = pDesc->GetAttributeBool(DISARM_ATTRIB);
	m_fParalyzeShip = pDesc->GetAttributeBool(PARALYZE_ATTRIB);
	m_fDisableShipScreen = pDesc->GetAttributeBool(DISABLE_SHIP_SCREEN_ATTRIB);
	m_fSpinShip = pDesc->GetAttributeBool(SPIN_ATTRIB);

	int iDrag;
	if (pDesc->FindAttributeInteger(DRAG_ATTRIB, &iDrag))
		m_rDrag = Min(Max(0, iDrag), 100) / 100.0;
	else
		m_rDrag = 1.0;

	//	Done

	return NOERROR;
	}