Ejemplo n.º 1
0
ALERROR CEffectCreator::OnCreateFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc)

//	OnCreateFromXML
//
//	Load from XML. This is only called if we go through the EffectType path
//	(as opposed to plain Effect).

	{
	ALERROR error;

	//	Basic info

	m_sUNID = strFromInt(GetUNID(), FALSE);
	m_dwSoundUNID = pDesc->GetAttributeInteger(SOUND_ATTRIB);
	m_iSound = -1;

	//	Allow our subclass to initialize based on the effect
	//	(We know we have one because we couldn't have gotten this far
	//	without one. See CreateTypeFromXML.)

	CXMLElement *pEffect = pDesc->GetContentElementByTag(EFFECT_TAG);
	ASSERT(pEffect);

	if (pEffect->GetContentElementCount() == 1)
		error = OnEffectCreateFromXML(Ctx, pEffect->GetContentElement(0), m_sUNID);
	else
		error = OnEffectCreateFromXML(Ctx, pEffect, m_sUNID);

	if (error)
		return error;

	//	Load damage descriptors

	CXMLElement *pDamageDesc = pDesc->GetContentElementByTag(DAMAGE_TAG);
	if (pDamageDesc)
		{
		m_pDamage = new CWeaponFireDesc;

		CString sUNID = strPatternSubst(CONSTLIT("%d/d"), GetUNID());
		if (error = m_pDamage->InitFromXML(Ctx, pDamageDesc, sUNID, true))
			return error;
		}
	
	return NOERROR;
	}
Ejemplo n.º 2
0
void CEffectCreator::InitPainterParameters (CCreatePainterCtx &Ctx, IEffectPainter *pPainter)

//	InitPainterParameters
//
//	Initialize painter parameters

	{
	SEventHandlerDesc Event;
	if (FindEventHandlerEffectType(evtGetParameters, &Event))
		{
		CCodeChainCtx CCCtx;

		CCCtx.SaveAndDefineDataVar(Ctx.GetData());

		ICCItem *pResult = CCCtx.Run(Event);
		if (pResult->IsError())
			::kernelDebugLogMessage(CONSTLIT("EffectType %x GetParameters: %s"), GetUNID(), (LPSTR)pResult->GetStringValue());
		else if (pResult->IsSymbolTable())
			{
			int i;
			CCSymbolTable *pTable = (CCSymbolTable *)pResult;

			for (i = 0; i < pTable->GetCount(); i++)
				{
				CString sParam = pTable->GetKey(i);
				ICCItem *pValue = pTable->GetElement(i);
				CEffectParamDesc Value;

				if (pValue->IsNil())
					Value.InitNull();
				else if (pValue->IsInteger())
					Value.InitInteger(pValue->GetIntegerValue());
				else if (pValue->IsIdentifier())
					{
					CString sValue = pValue->GetStringValue();
					char *pPos = sValue.GetASCIIZPointer();

					//	If this is a color, parse it

					if (*pPos == '#')
						Value.InitColor(::LoadRGBColor(sValue));

					//	Otherwise, a string

					else
						Value.InitString(sValue);
					}

				pPainter->SetParam(Ctx, sParam, Value);
				}
			}
		else
			::kernelDebugLogMessage(CONSTLIT("EffectType %x GetParameters: Expected struct result."), GetUNID());

		CCCtx.Discard(pResult);
		}
	}
Ejemplo n.º 3
0
ALERROR CItemTable::OnBindDesign (SDesignLoadCtx &Ctx)

//	OnBindDesign
//
//	Load design references

	{
	ALERROR error;

	if (m_pGenerator)
		{
		if (error = m_pGenerator->OnDesignLoadComplete(Ctx))
			{
			Ctx.sError = strPatternSubst(CONSTLIT("ItemTable (%x): %s"), GetUNID(), Ctx.sError);
			return error;
			}
		}

	return NOERROR;
	}
Ejemplo n.º 4
0
ALERROR CItemTable::OnCreateFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc)

//	OnCreateFromXML
//
//	Create from XML descriptor

	{
	ALERROR error;

	CXMLElement *pElement = pDesc->GetContentElement(0);
	if (pElement)
		{
		if (error = IItemGenerator::CreateFromXML(Ctx, pElement, &m_pGenerator))
			{
			Ctx.sError = strPatternSubst(CONSTLIT("ItemTable (%x): %s"), GetUNID(), Ctx.sError);
			return error;
			}
		}

	return NOERROR;
	}
ALERROR CEnergyFieldType::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_bAltHitEffect = bAltEffect;
		else
			m_bAltHitEffect = strEquals(pDesc->GetTag(), SHIP_ENERGY_FIELD_TYPE_TAG);
		}
	else
		m_bAltHitEffect = false;

	//	Rotation

	m_bRotateWithShip = !pDesc->GetAttributeBool(IGNORE_SHIP_ROTATION_ATTRIB);

	//	Damage adjustment

	LoadDamageAdj(pDesc, ABSORB_ADJ_ATTRIB, m_iAbsorbAdj);

	//	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_bHasOnUpdateEvent = FindEventHandler(ON_UPDATE_EVENT);

	//	Done

	return NOERROR;
	}
Ejemplo n.º 6
0
ALERROR CEffectCreator::OnCreateFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc)

//	OnCreateFromXML
//
//	Load from XML. This is only called if we go through the EffectType path
//	(as opposed to plain Effect types).

	{
	ALERROR error;

	//	Basic info

	m_sUNID = strFromInt(GetUNID(), false);

	if (error = InitBasicsFromXML(Ctx, pDesc))
		return error;

	//	Allow our subclass to initialize based on the effect
	//	(We know we have one because we couldn't have gotten this far
	//	without one. See CreateTypeFromXML.)

	CXMLElement *pEffect = pDesc->GetContentElementByTag(EFFECT_TAG);
	ASSERT(pEffect);

	//	Continue

	if (pEffect->GetContentElementCount() == 1)
		{
		CXMLElement *pEffectDesc = pEffect->GetContentElement(0);

		//	Load events for this effect, in case they're here.

		CXMLElement *pEventsDesc = pEffectDesc->GetContentElementByTag(EVENTS_TAG);
		if (pEventsDesc)
			{
			if (error = m_Events.InitFromXML(Ctx, pEventsDesc))
				return error;
			}

		//	Load the single effect

		error = OnEffectCreateFromXML(Ctx, pEffectDesc, m_sUNID);
		}
	else
		error = OnEffectCreateFromXML(Ctx, pEffect, m_sUNID);

	if (error)
		return error;

	//	Load damage descriptors

	CXMLElement *pDamageDesc = pDesc->GetContentElementByTag(DAMAGE_TAG);
	if (pDamageDesc)
		{
		m_pDamage = new CWeaponFireDesc;

		CString sUNID = strPatternSubst(CONSTLIT("%d/d"), GetUNID());
		if (error = m_pDamage->InitFromXML(Ctx, pDamageDesc, sUNID, true))
			return error;
		}
	
	return NOERROR;
	}
Ejemplo n.º 7
0
ALERROR CSystemMap::AddFixedTopology (CTopology &Topology, CString *retsError)

//	AddFixedTopology
//
//	Adds all the nodes in its fixed topology

	{
	ALERROR error;
	int i;

	//	If we already added this map, then we're done

	if (m_bAdded)
		return NOERROR;

	//	Mark this map as added so we don't recurse back here when we
	//	process all the Uses statments.

	m_bAdded = true;

	//	Load all the maps that this map requires

	for (i = 0; i < m_Uses.GetCount(); i++)
		{
		if (error = m_Uses[i]->AddFixedTopology(Topology, retsError))
			return error;
		}

	//	Iterate over all creators and execute them

	CTopologyNodeList NodesAdded;
	STopologyCreateCtx Ctx;
	Ctx.pMap = GetDisplayMap();
	Ctx.pNodesAdded = &NodesAdded;

	//	We need to include any maps that we use.

	Ctx.Tables.Insert(&m_FixedTopology);
	for (i = 0; i < m_Uses.GetCount(); i++)
		Ctx.Tables.Insert(&m_Uses[i]->m_FixedTopology);

	for (i = 0; i < m_Creators.GetCount(); i++)
		{
		if (error = ExecuteCreator(Ctx, Topology, m_Creators[i]))
			{
			*retsError = strPatternSubst(CONSTLIT("SystemMap (%x): %s"), GetUNID(), Ctx.sError);
			return error;
			}
		}

	//	Add any additional nodes marked as "root" (this is here only for backwards compatibility)
	//	NOTE: This call only worries about the first table (Ctx.Tables[0])

	if (error = Topology.AddTopology(Ctx))
		{
		*retsError = strPatternSubst(CONSTLIT("SystemMap (%x): %s"), GetUNID(), Ctx.sError);
		return error;
		}

	//	Apply any topology processors (in order) on all the newly added nodes

	for (i = 0; i < m_Processors.GetCount(); i++)
		{
		//	Make a copy of the node list because each call will destroy it

		CTopologyNodeList NodeList = NodesAdded;

		//	Process

		if (error = m_Processors[i]->Process(this, Topology, NodeList, retsError))
			{
			*retsError = strPatternSubst(CONSTLIT("SystemMap (%x): %s"), GetUNID(), *retsError);
			return error;
			}
		}

	//	Make sure every node added has a system UNID

	for (i = 0; i < NodesAdded.GetCount(); i++)
		if (NodesAdded[i]->GetSystemDescUNID() == 0)
			{
			*retsError = strPatternSubst(CONSTLIT("SystemMap (%x): NodeID %s: No system specified"), GetUNID(), NodesAdded[i]->GetID());
			return ERR_FAIL;
			}

	return NOERROR;
	}
Ejemplo n.º 8
0
ALERROR CSystemMap::OnCreateFromXML (SDesignLoadCtx &Ctx, CXMLElement *pDesc)

//	OnCreateFromXML

	{
	ALERROR error;
	int i;

	//	Load some basic info

	m_sName = pDesc->GetAttribute(NAME_ATTRIB);
	m_dwBackgroundImage = pDesc->GetAttributeInteger(BACKGROUND_IMAGE_ATTRIB);
	if (error = m_pPrimaryMap.LoadUNID(Ctx, pDesc->GetAttribute(PRIMARY_MAP_ATTRIB)))
		return error;

	m_bStartingMap = pDesc->GetAttributeBool(STARTING_MAP_ATTRIB);

	//	If we have a primary map, then add it to the Uses list.

	if (m_pPrimaryMap.GetUNID() != 0)
		m_Uses.Insert(m_pPrimaryMap);

	//	Scale information

	m_iInitialScale = pDesc->GetAttributeIntegerBounded(INITIAL_SCALE_ATTRIB, 10, 1000, 100);
	m_iMaxScale = pDesc->GetAttributeIntegerBounded(MAX_SCALE_ATTRIB, 100, 1000, 200);
	m_iMinScale = pDesc->GetAttributeIntegerBounded(MIN_SCALE_ATTRIB, 10, 100, 50);

	//	Generate an UNID

	CString sUNID = strPatternSubst(CONSTLIT("%d"), GetUNID());

	//	Keep track of root nodes

	TArray<CString> RootNodes;

	//	Iterate over all child elements and process them

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

		if (strEquals(pItem->GetTag(), TOPOLOGY_CREATOR_TAG)
				|| strEquals(pItem->GetTag(), ROOT_NODE_TAG))
			{
			m_Creators.Insert(pItem->OrphanCopy());

			if (strEquals(pItem->GetTag(), ROOT_NODE_TAG))
				RootNodes.Insert(pItem->GetAttribute(ID_ATTRIB));
			}
		else if (strEquals(pItem->GetTag(), TOPOLOGY_PROCESSOR_TAG))
			{
			ITopologyProcessor *pNewProc;
			CString sProcessorUNID = strPatternSubst(CONSTLIT("%d:p%d"), GetUNID(), m_Processors.GetCount());

			if (error = ITopologyProcessor::CreateFromXMLAsGroup(Ctx, pItem, sProcessorUNID, &pNewProc))
				return error;

			m_Processors.Insert(pNewProc);
			}
		else if (strEquals(pItem->GetTag(), SYSTEM_TOPOLOGY_TAG))
			{
			if (error = m_FixedTopology.LoadFromXML(Ctx, pItem, this, sUNID, true))
				return error;
			}
		else if (strEquals(pItem->GetTag(), USES_TAG))
			{
			CSystemMapRef *pRef = m_Uses.Insert();

			if (error = pRef->LoadUNID(Ctx, pItem->GetAttribute(UNID_ATTRIB)))
				return error;
			}
		else
			{
			//	If it's none of the above, see if it is a node descriptor

			if (error = m_FixedTopology.LoadNodeFromXML(Ctx, pItem, this, sUNID))
				return error;
			}
		}

	//	Mark all the root nodes.
	//
	//	We need to do this for backwards compatibility because the old technique
	//	of having a root node with [Prev] for a stargate requires this. This was
	//	used by Huaramarca.

	for (i = 0; i < RootNodes.GetCount(); i++)
		if (error = m_FixedTopology.AddRootNode(Ctx, RootNodes[i]))
			return error;

	//	Init

	m_bAdded = false;

	//	Debug info

	m_bDebugShowAttributes = pDesc->GetAttributeBool(DEBUG_SHOW_ATTRIBUTES_ATTRIB);

	return NOERROR;
	}
Ejemplo n.º 9
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;
	}