Beispiel #1
0
void BattleGroundAV::EventPlayerDefendsPoint(Player* player, BG_AV_Nodes node)
{
    MANGOS_ASSERT(GetStatus() == STATUS_IN_PROGRESS);

    BattleGroundTeamIndex teamIdx = GetTeamIndexByTeamId(player->GetBGTeam());

    if (m_Nodes[node].Owner == BattleGroundAVTeamIndex(teamIdx) || m_Nodes[node].State != POINT_ASSAULTED)
        return;
    if (m_Nodes[node].TotalOwner == BG_AV_TEAM_NEUTRAL)     // initial snowfall capture
    {
        // until snowfall doesn't belong to anyone it is better handled in assault - code (best would be to have a special function
        // for neutral nodes.. but doing this just for snowfall will be a bit to much i think
        MANGOS_ASSERT(node == BG_AV_NODES_SNOWFALL_GRAVE);  // currently the only neutral grave
        EventPlayerAssaultsPoint(player, node);
        return;
    }

    DEBUG_LOG("BattleGroundAV: player defends node: %i", node);
    if (m_Nodes[node].PrevOwner != BattleGroundAVTeamIndex(teamIdx))
    {
        sLog.outError("BattleGroundAV: player defends point which doesn't belong to his team %i", node);
        return;
    }

    DefendNode(node, teamIdx);                              // set the right variables for nodeinfo
    PopulateNode(node);                                     // spawn node-creatures (defender for example)
    UpdateNodeWorldState(node);                             // send new mapicon to the player

    if (IsTower(node))
    {
        SendYell2ToAll(LANG_BG_AV_TOWER_DEFENDED, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0),
                       GetNodeName(node),
                       (teamIdx == BG_TEAM_ALLIANCE) ? LANG_BG_ALLY : LANG_BG_HORDE);
        UpdatePlayerScore(player, SCORE_TOWERS_DEFENDED, 1);
        PlaySoundToAll(BG_AV_SOUND_BOTH_TOWER_DEFEND);
    }
    else
    {
        SendYell2ToAll(LANG_BG_AV_GRAVE_DEFENDED, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0),
                       GetNodeName(node),
                       (teamIdx == BG_TEAM_ALLIANCE) ? LANG_BG_ALLY : LANG_BG_HORDE);
        UpdatePlayerScore(player, SCORE_GRAVEYARDS_DEFENDED, 1);
        // update the statistic for the defending player
        PlaySoundToAll((teamIdx == BG_TEAM_ALLIANCE) ? BG_AV_SOUND_ALLIANCE_GOOD : BG_AV_SOUND_HORDE_GOOD);
    }
}
Beispiel #2
0
void HisBase::DoInternalLoad(xmlNodePtr & node)
{
	if (node!=NULL)
	{
		if (!xmlStrcmp(node->name,GetNodeName()))
		{
			string strtemp;
			xmlChar* prop;

			if (xmlHasProp(node,BAD_CAST PROP_NAME))
			{
				prop = xmlGetProp(node,BAD_CAST PROP_NAME);
				name = (const char*)prop;
				xmlFree(prop);
			}

			if (xmlHasProp(node,BAD_CAST PROP_MODIFY_DATE))
			{
				prop = xmlGetProp(node,BAD_CAST PROP_MODIFY_DATE);
				strtemp = (const char*)prop;
				xmlFree(prop);
				DateTime::TryParse(strtemp,modifyDate);
			}

			if (xmlHasProp(node,BAD_CAST PROP_CREATE_DATE))
			{
				prop = xmlGetProp(node,BAD_CAST PROP_CREATE_DATE);
				strtemp = (const char*)prop;
				xmlFree(prop);
				DateTime::TryParse(strtemp,createDate);
			}

			if (xmlHasProp(node,BAD_CAST PROP_RECORDID))
			{
				prop = xmlGetProp(node,BAD_CAST PROP_RECORDID);
				recordId = CUUID::Parse((const char*)prop);//Converter::stoi((const char*)prop);
				xmlFree(prop);
			}

			FreeItems();
			xmlNodePtr cur = node->children;
			xmlNodePtr next;
			IHisBase *pitem = NULL;
			while(cur)
			{
				next = cur->next;
				pitem = factory->Create(cur);
				if (pitem!=NULL)
				{
					pitem->SetParent(this);
					pitem->Load();
					items.push_back(pitem);
				}
				cur = next;
			}
		}
	}
}
Beispiel #3
0
void wxTreeLayout::GetNodeSize(long id, long *x, long *y, wxDC& dc)
{
    wxString name(GetNodeName(id));
    if (name != wxT(""))
        dc.GetTextExtent(name, x, y);
    else
    {
        *x = 70; *y = 20;
    }
}
void FSequencerTrackNode::SetSectionAsKeyArea(TSharedRef<IKeyArea>& KeyArea)
{
	if( !TopLevelKeyNode.IsValid() )
	{
		bool bTopLevel = true;
		TopLevelKeyNode = MakeShareable( new FSequencerSectionKeyAreaNode( GetNodeName(), FText::GetEmpty(), nullptr, ParentTree, bTopLevel ) );
	}

	TopLevelKeyNode->AddKeyArea( KeyArea );
}
Beispiel #5
0
void wxTreeLayout::DrawNode(long id, wxDC& dc)
{
    wxChar buf[80];
    wxString name(GetNodeName(id));
    if (name != wxT(""))
        wxSprintf(buf, wxT("%s"), (const wxChar*) name);
    else
        wxSprintf(buf, wxT("<unnamed>"));

    long x = 80;
    long y = 20;
    dc.GetTextExtent(buf, &x, &y);
    dc.DrawText(buf, GetNodeX(id), (long)(GetNodeY(id) - (y/2.0)));
}
void FAnimNode_BlendListBase::GatherDebugData(FNodeDebugData& DebugData)
{
	const int NumPoses = BlendPose.Num();
	const int32 ChildIndex = GetActiveChildIndex();

	FString DebugLine = GetNodeName(DebugData);
	DebugLine += FString::Printf(TEXT("(Active: (%i/%i) BlendWeight: %.1f%% BlendTime %.3f)"), ChildIndex+1, NumPoses, BlendWeights[ChildIndex]*100.f, BlendTime[ChildIndex]);

	DebugData.AddDebugItem(DebugLine);
	
	for(int32 Pose = 0; Pose < NumPoses; ++Pose)
	{
		BlendPose[Pose].GatherDebugData(DebugData.BranchFlow(BlendWeights[Pose]));
	}
}
void UBTTaskNode::ReceivedMessage(UBrainComponent* BrainComp, const FAIMessage& Message)
{
	UBehaviorTreeComponent* OwnerComp = static_cast<UBehaviorTreeComponent*>(BrainComp);
	check(OwnerComp);
	
	const uint16 InstanceIdx = OwnerComp->FindInstanceContainingNode(this);
	if (OwnerComp->InstanceStack.IsValidIndex(InstanceIdx))
	{
		uint8* NodeMemory = GetNodeMemory<uint8>(OwnerComp->InstanceStack[InstanceIdx]);
		OnMessage(*OwnerComp, NodeMemory, Message.MessageName, Message.RequestID, Message.Status == FAIMessage::Success);
	}
	else
	{
		UE_VLOG(OwnerComp->GetOwner(), LogBehaviorTree, Warning, TEXT("UBTTaskNode::ReceivedMessage called while %s node no longer in active BT")
			, *GetNodeName());
	}
}
Beispiel #8
0
void CXML::Looop(IXMLDOMNode * pCurrentNode,HTREEITEM hParent,HTREEITEM hInsertAfter)
{
	if(!pCurrentNode)
		return;
	
	CString csText;
	GetNodeName(&pCurrentNode,csText);
	TVINSERTSTRUCT insertStruct;
	insertStruct.hParent = hParent;
	insertStruct.hInsertAfter = hInsertAfter;
	insertStruct.item.mask = TVIF_TEXT;
	insertStruct.item.pszText = (char *)(LPCTSTR)csText;
	insertStruct.item.cchTextMax = csText.GetLength();
	HTREEITEM hTreeItem = m_pTreeCtrl->InsertItem(&insertStruct);

	Looop(NextChildNode(&pCurrentNode),hTreeItem,TVI_FIRST);
	hTreeItem = m_pTreeCtrl->GetParentItem(hTreeItem);
	Looop(NextSib(&pCurrentNode),hTreeItem,TVI_LAST);
}
Beispiel #9
0
BOOL CaNodeServer::Matched (CaNodeServer* pObj, MatchObjectFlag nFlag)
{
    if (nFlag == MATCHED_NAME)
    {
        return (pObj->GetName().CompareNoCase (GetName()) == 0);
    }
    else
    {
        BOOL bOk = FALSE;
        if (pObj->GetNodeName().CompareNoCase (GetNodeName()) != 0)
            return FALSE;
        if (pObj->GetName().CompareNoCase (GetName()) != 0) // Server
            return FALSE;
        if (pObj-> IsLocalNode() != IsLocalNode())
            return FALSE;

        return TRUE;
    }
    //
    // Need the implementation ?
    ASSERT (FALSE);
    return FALSE;
}
void BattleGroundAV::EventPlayerDestroyedPoint(BG_AV_Nodes node)
{
    DEBUG_LOG("BattleGroundAV: player destroyed point node %i", node);

    MANGOS_ASSERT(m_Nodes[node].Owner != BG_AV_TEAM_NEUTRAL)
    BattleGroundTeamIndex ownerTeamIdx = BattleGroundTeamIndex(m_Nodes[node].Owner);
    Team ownerTeam = ownerTeamIdx == BG_TEAM_ALLIANCE ? ALLIANCE : HORDE;

    // despawn banner
    DestroyNode(node);
    PopulateNode(node);
    UpdateNodeWorldState(node);

    if (IsTower(node))
    {
        uint8 tmp = node - BG_AV_NODES_DUNBALDAR_SOUTH;
        // despawn marshal (one of those guys protecting the boss)
        SpawnEvent(BG_AV_MARSHAL_A_SOUTH + tmp, 0, false);

        UpdateScore(GetOtherTeamIndex(ownerTeamIdx), (-1) * BG_AV_RES_TOWER);
        RewardReputationToTeam((ownerTeam == ALLIANCE) ? BG_AV_FACTION_A : BG_AV_FACTION_H, m_RepTowerDestruction, ownerTeam);
        RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_TOWER), ownerTeam);
        SendYell2ToAll(LANG_BG_AV_TOWER_TAKEN, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0), GetNodeName(node), (ownerTeam == ALLIANCE) ? LANG_BG_ALLY : LANG_BG_HORDE);
    }
    else
    {
        SendYell2ToAll(LANG_BG_AV_GRAVE_TAKEN, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0), GetNodeName(node), (ownerTeam == ALLIANCE) ? LANG_BG_ALLY : LANG_BG_HORDE);
    }
}
void BattleGroundAV::EventPlayerDestroyedPoint(BG_AV_Nodes node)
{

    DEBUG_LOG("BattleGroundAV: player destroyed point node %i", node);

    // despawn banner
    DestroyNode(node);
    PopulateNode(node);
    UpdateNodeWorldState(node);

    uint32 owner = m_Nodes[node].Owner;
    if (IsTower(node))
    {
        uint8 tmp = node - BG_AV_NODES_DUNBALDAR_SOUTH;
        // despawn marshal (one of those guys protecting the boss)
        SpawnEvent(BG_AV_MARSHAL_A_SOUTH + tmp, 0, false);

        UpdateScore(BattleGroundTeamId(owner^0x1), (-1) * BG_AV_RES_TOWER);
        RewardReputationToTeam(BATTLEGROUND_AV, m_RepTowerDestruction, owner);
        RewardHonorToTeam(GetBonusHonorFromKill(BG_AV_KILL_TOWER), owner);
        RewardXpToTeam(0, 0.91, owner);
        SendYell2ToAll(LANG_BG_AV_TOWER_TAKEN, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0), GetNodeName(node), ( owner == BG_TEAM_ALLIANCE ) ? LANG_BG_ALLY : LANG_BG_HORDE);
    }
    else
    {
        SendYell2ToAll(LANG_BG_AV_GRAVE_TAKEN, LANG_UNIVERSAL, GetSingleCreatureGuid(BG_AV_HERALD, 0), GetNodeName(node), ( owner == BG_TEAM_ALLIANCE ) ? LANG_BG_ALLY : LANG_BG_HORDE);
    }
}
Beispiel #12
0
void DrawTree::WriteNodeText(const Link* link, ostream& os, double x, double y)	{
	os << "\\path [anchor=south east,font=\\fontsize{" << fontsize << "}{" << fontsize << "}\\selectfont,scale=" << texscale<< "]";
	// os << "\\path [anchor=west,font=\\fontsize{" << fontsize - 1 << "}{" << fontsize -1 << "}\\selectfont,scale=" << texscale<< "]";
	os << "(" << texapprox(x-0.1) << "," << texapprox(y) << ") node {" << GetNodeName(link) << " };\n";
	// os << "(" << texapprox(x-0.1) << "," << texapprox(y) << ") node {" << ((double) ((int) (10 * GetNodeVal(link)))) / 10 << " };\n";
}
Beispiel #13
0
bool ParticleRenderer::GetEmitterWorldMatrix(const PartSysEmitter* emitter, D3DMATRIX& worldMatrix) {
    D3DXMATRIX pM1;

    auto spec = emitter->GetSpec();
    auto particleSpace = spec->GetParticleSpace();
    auto emitterSpace = spec->GetSpace();
    if (particleSpace == PartSysParticleSpace::SameAsEmitter) {

        if (emitterSpace == PartSysEmitterSpace::ObjectPos || emitterSpace == PartSysEmitterSpace::ObjectYpr) {
            if (emitterSpace == PartSysEmitterSpace::ObjectYpr) {
                auto v6 = emitter->GetObjRotation() + 3.1415927f;
                D3DXMatrixRotationY(&pM1, v6);
            } else {
                D3DXMatrixIdentity(&pM1);
            }

            // SEt the translation component of the transformation matrix
            pM1._41 = emitter->GetObjPos().x;
            pM1._42 = emitter->GetObjPos().y;
            pM1._43 = emitter->GetObjPos().z;

            D3DXMatrixMultiply((D3DXMATRIX*)&worldMatrix, &pM1, (const D3DXMATRIX*)&renderStates->Get3dProjectionMatrix());
            ExtractScreenSpaceUnitVectors(worldMatrix);
            return true;
        }
        if (emitterSpace == PartSysEmitterSpace::NodePos || emitterSpace == PartSysEmitterSpace::NodeYpr) {
            auto external = IPartSysExternal::GetCurrent();

            if (emitterSpace == PartSysEmitterSpace::NodeYpr) {
                D3DXMATRIX boneMatrix;
                if (!external->GetBoneWorldMatrix(emitter->GetAttachedTo(), spec->GetNodeName(), (Matrix4x4&)boneMatrix)) {
                    // This effectively acts as a fallback if the bone doesn't exist
                    auto x = emitter->GetObjPos().x;
                    auto y = emitter->GetObjPos().y;
                    auto z = emitter->GetObjPos().z;
                    D3DXMatrixTranslation(&boneMatrix, x, y, z);
                }

                D3DXMatrixMultiply((D3DXMATRIX*) &worldMatrix, &pM1, (const D3DXMATRIX*)&renderStates->Get3dProjectionMatrix());
                ExtractScreenSpaceUnitVectors(worldMatrix);
                return true;
            }

            D3DXMATRIX boneMatrix;
            if (external->GetBoneWorldMatrix(emitter->GetAttachedTo(), spec->GetNodeName(), (Matrix4x4&)boneMatrix)) {
                auto x = boneMatrix._41;
                auto y = boneMatrix._42;
                auto z = boneMatrix._43;
                D3DXMatrixTranslation(&pM1, x, y, z); // TODO: This might not be needed...

                D3DXMatrixMultiply((D3DXMATRIX*)&worldMatrix,
                                   &pM1,
                                   (const D3DXMATRIX*)&renderStates->Get3dProjectionMatrix());

                ExtractScreenSpaceUnitVectors(worldMatrix);
                return true;
            }

            return false;
        }

        worldMatrix = renderStates->Get3dProjectionMatrix();
        ExtractScreenSpaceUnitVectors(worldMatrix);
        return true;
    }

    if (particleSpace == PartSysParticleSpace::World) {
        worldMatrix = renderStates->Get3dProjectionMatrix();
        ExtractScreenSpaceUnitVectors(worldMatrix);
        return true;
    }

    if (emitterSpace != PartSysEmitterSpace::ObjectPos && emitterSpace != PartSysEmitterSpace::ObjectYpr) {
        if (emitterSpace != PartSysEmitterSpace::NodePos && emitterSpace != PartSysEmitterSpace::NodeYpr)
            return true;

        auto external = IPartSysExternal::GetCurrent();
        D3DXMatrixIdentity(&pM1);

        if (emitterSpace == PartSysEmitterSpace::NodeYpr) {
            // Use the entire bone matrix if possible
            external->GetBoneWorldMatrix(emitter->GetAttachedTo(), spec->GetNodeName(), (Matrix4x4&)pM1);
        } else {
            // Only use the bone translation part
            D3DXMATRIX boneMatrix;
            if (!external->GetBoneWorldMatrix(emitter->GetAttachedTo(), spec->GetNodeName(), (Matrix4x4&) boneMatrix))
                return false;
            pM1._41 = boneMatrix._41;
            pM1._42 = boneMatrix._42;
            pM1._43 = boneMatrix._43;
        }
        worldMatrix = renderStates->Get3dProjectionMatrix();
        ExtractScreenSpaceUnitVectors2(pM1);
        return 1;
    }
    if (emitterSpace == PartSysEmitterSpace::ObjectYpr) {
        auto v6 = emitter->GetObjRotation() + 3.1415927f;
        D3DXMatrixRotationY(&pM1, v6);
    } else {
        D3DXMatrixIdentity(&pM1);
    }
    worldMatrix = renderStates->Get3dProjectionMatrix();
    ExtractScreenSpaceUnitVectors2(pM1);
    return true;
}
Beispiel #14
0
	bool ParticleRenderer::GetEmitterWorldMatrix(const PartSysEmitter& emitter, XMFLOAT4X4& worldMatrix) {

		auto spec = emitter.GetSpec();
		auto particleSpace = spec->GetParticleSpace();
		auto emitterSpace = spec->GetSpace();
		if (particleSpace == PartSysParticleSpace::SameAsEmitter) {

			if (emitterSpace == PartSysEmitterSpace::ObjectPos || emitterSpace == PartSysEmitterSpace::ObjectYpr) {
				XMMATRIX localMat;
				if (emitterSpace == PartSysEmitterSpace::ObjectYpr) {
					auto angle = emitter.GetObjRotation() + XM_PI;
					localMat = XMMatrixRotationY(angle);
				} else {
					localMat = XMMatrixIdentity();
				}

				// Set the translation component of the transformation matrix
				localMat.r[3] = XMVectorSet(emitter.GetObjPos().x,
					emitter.GetObjPos().y,
					emitter.GetObjPos().z,
					1
				);

				XMStoreFloat4x4(
					&worldMatrix,
					localMat * XMLoadFloat4x4(&mDevice.GetCamera().GetViewProj())
				);
				ExtractScreenSpaceUnitVectors(worldMatrix);
				return true;
			}
			if (emitterSpace == PartSysEmitterSpace::NodePos || emitterSpace == PartSysEmitterSpace::NodeYpr) {
				auto external = IPartSysExternal::GetCurrent();

				if (emitterSpace == PartSysEmitterSpace::NodeYpr) {
					XMFLOAT4X4 boneMatrix;
					if (!external->GetBoneWorldMatrix(emitter.GetAttachedTo(), spec->GetNodeName(), boneMatrix)) {
						// This effectively acts as a fallback if the bone doesn't exist
						auto x = emitter.GetObjPos().x;
						auto y = emitter.GetObjPos().y;
						auto z = emitter.GetObjPos().z;
						XMStoreFloat4x4(
							&boneMatrix, 
							XMMatrixTranslation(x, y, z)
						);
					}

					XMStoreFloat4x4(
						&worldMatrix,
						XMLoadFloat4x4(&boneMatrix) * XMLoadFloat4x4(&mDevice.GetCamera().GetViewProj())
						);
					ExtractScreenSpaceUnitVectors(worldMatrix);
					return true;
				}

				XMFLOAT4X4 boneMatrix;
				if (external->GetBoneWorldMatrix(emitter.GetAttachedTo(), spec->GetNodeName(), (Matrix4x4&)boneMatrix)) {
					auto x = boneMatrix._41;
					auto y = boneMatrix._42;
					auto z = boneMatrix._43;

					XMStoreFloat4x4(
						&worldMatrix,
						XMMatrixTranslation(x, y, z) * XMLoadFloat4x4(&mDevice.GetCamera().GetViewProj())
						);

					ExtractScreenSpaceUnitVectors(worldMatrix);
					return true;
				}

				return false;
			}

			worldMatrix = mDevice.GetCamera().GetViewProj();
			ExtractScreenSpaceUnitVectors(worldMatrix);
			return true;
		}

		if (particleSpace == PartSysParticleSpace::World) {
			worldMatrix = mDevice.GetCamera().GetViewProj();
			ExtractScreenSpaceUnitVectors(worldMatrix);
			return true;
		}

		if (emitterSpace != PartSysEmitterSpace::ObjectPos && emitterSpace != PartSysEmitterSpace::ObjectYpr) {
			if (emitterSpace != PartSysEmitterSpace::NodePos && emitterSpace != PartSysEmitterSpace::NodeYpr)
				return true;

			auto external = IPartSysExternal::GetCurrent();

			XMFLOAT4X4 boneMatrix;
			if (emitterSpace == PartSysEmitterSpace::NodeYpr) {
				// Use the entire bone matrix if possible
				external->GetBoneWorldMatrix(emitter.GetAttachedTo(), spec->GetNodeName(), boneMatrix);
			} else {
				// Only use the bone translation part
				if (!external->GetBoneWorldMatrix(emitter.GetAttachedTo(), spec->GetNodeName(), (Matrix4x4&) boneMatrix))
					return false;
				XMStoreFloat4x4(
					&boneMatrix,
					XMMatrixTranslation(boneMatrix._41, 
						boneMatrix._42,
						boneMatrix._43)
					); // TODO: This might not be needed...
			}
			worldMatrix = mDevice.GetCamera().GetViewProj();
			ExtractScreenSpaceUnitVectors2(boneMatrix);
			return true;
		}

		XMFLOAT4X4 matrix;
		if (emitterSpace == PartSysEmitterSpace::ObjectYpr) {
			auto angle = emitter.GetObjRotation() + XM_PI;
			XMStoreFloat4x4(&matrix, XMMatrixRotationY(angle));
		} else {
			XMStoreFloat4x4(&matrix, XMMatrixIdentity());
		}
		worldMatrix = mDevice.GetCamera().GetViewProj();
		ExtractScreenSpaceUnitVectors2(matrix);
		return true;
	}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : file - 
//			fIsStoring - 
//			*pIntersecting - 
//-----------------------------------------------------------------------------
void CMapPath::SerializeMAP(std::fstream& file, BOOL fIsStoring, BoundBox *pIntersecting)
{
	if( m_Nodes.Count() == 0)
		return;

	// if saving WITHIN a box, check all nodes to see if they all 
	//  fit within that box. if not, don't save ANY of the path.
	if(pIntersecting)
	{
		for(int i = 0; i < m_Nodes.Count(); i++)
		{
			if (!pIntersecting->ContainsPoint(m_Nodes[i].pos))
			{
				return;	// doesn't intersect - don't save path
			}
		}
	}


	Assert(fIsStoring);

	CString strTemp;
	MDkeyvalue kvTemp;

	// initialize nodes for saving
	for(int i = 0; i < m_Nodes.Count(); i++)
	{
		m_Nodes[i].nTargets = 0;
	}

	int iDirec = 1;
	int iCurNode = 0;
	int iMax = m_Nodes.Count()-1;
	int iName = 0;

	// resolve targets 
	int iLastNodeIndex = -1;
	BOOL bFirstPass = TRUE;

ResolveNamesAgain:
	while(1)
	{
		// store targetname
		GetNodeName(iCurNode, iName, strTemp);

		// store our name in the previous node (if not -1)
		if(iLastNodeIndex != -1)
		{
			CMapPathNode &prevNode = m_Nodes[iLastNodeIndex];
			strcpy(prevNode.szTargets[prevNode.nTargets++], strTemp);
		}

		++iName;

		iLastNodeIndex = iCurNode;

		if(iCurNode == iMax)
			break;
		iCurNode += iDirec;
	}

	if(bFirstPass && m_iDirection == dirPingpong && m_Nodes.Count() > 2)
	{
		// redo loop
		bFirstPass = FALSE;
		iDirec = -1;
		iCurNode = m_Nodes.Count()-2;
		iMax = 0;
		goto ResolveNamesAgain;
	}
	else if (m_iDirection == dirCircular)
	{
		//
		// Connect the last node to the first node.
		//
		CMapPathNode &LastNode = m_Nodes[iMax];
		GetNodeName(iCurNode, 0, strTemp);
		strcpy(LastNode.szTargets[LastNode.nTargets], strTemp);
		LastNode.nTargets++;
	}

	iDirec = 1;
	iCurNode = 0;
	iMax = m_Nodes.Count()-1;
	iName = 0;

SaveAgain:
	while(1)
	{
		file << "{" << "\r\n";

		// store name
		kvTemp.Set("classname", m_szClass);
		kvTemp.SerializeMAP(file, TRUE);

		CMapPathNode &node = m_Nodes[iCurNode];

		// store location
		strTemp.Format("%.0f %.0f %.0f", node.pos[0], node.pos[1], 
			node.pos[2]);
		kvTemp.Set("origin", strTemp);
		kvTemp.SerializeMAP(file, TRUE);

		// store targetname
		GetNodeName(iCurNode, iName, strTemp);
		kvTemp.Set("targetname", strTemp);
		kvTemp.SerializeMAP(file, TRUE);

		// store target (if not last)
		BOOL bStoreTarget = TRUE;
		if(iCurNode == iMax && m_iDirection == dirOneway)
			bStoreTarget = FALSE;

		if (bStoreTarget)
		{
			kvTemp.Set("target", (iDirec == 1) ? node.szTargets[0] : node.szTargets[1]);
			kvTemp.SerializeMAP(file, TRUE);
		}

		// other keyvalues
		WCKeyValues &kv = node.kv;
		for (int k = kv.GetFirst(); k != kv.GetInvalidIndex(); k=kv.GetNext( k ) )
		{
			MDkeyvalue &KeyValue = kv.GetKeyValue(k);
			if (KeyValue.szKey[0] != '\0')
			{
				KeyValue.SerializeMAP(file, TRUE);
			}
		}

		file << "}" << "\r\n";

		++iName;
		iLastNodeIndex = iCurNode;

		if(iCurNode == iMax)
			break;
		iCurNode += iDirec;
	}

	if(iDirec == 1 && m_iDirection == dirPingpong && m_Nodes.Count() > 2)
	{
		// redo loop
		iDirec = -1;
		iCurNode = m_Nodes.Count()-2;
		iMax = 1;
		goto SaveAgain;
	}
}