diff --git a/src/landscape/C4MapCreatorS2.cpp b/src/landscape/C4MapCreatorS2.cpp index 68b5c5e05..037f8ede1 100644 --- a/src/landscape/C4MapCreatorS2.cpp +++ b/src/landscape/C4MapCreatorS2.cpp @@ -196,13 +196,17 @@ C4MCNode::C4MCNode(C4MCNode *pOwner) *Name=0; } -C4MCNode::C4MCNode(C4MCNode *pOwner, C4MCNode &rTemplate, bool fClone) +C4MCNode::C4MCNode(C4MCParser* pParser, C4MCNode *pOwner, C4MCNode &rTemplate, bool fClone) { + // Make sure the template is not used recursively within itself + for(C4MCNode* pParent = pOwner; pParent != NULL; pParent = pParent->Owner) + if(pParent == &rTemplate) + throw C4MCParserErr(pParser, C4MCErr_NoRecTemplate, rTemplate.Name); // set owner and stuff Reg2Owner(pOwner); // copy children from template for (C4MCNode *pChild=rTemplate.Child0; pChild; pChild=pChild->Next) - pChild->clone(this); + pChild->clone(pParser, this); // no name *Name=0; } @@ -324,7 +328,7 @@ C4MCOverlay::C4MCOverlay(C4MCNode *pOwner) : C4MCNode(pOwner) pEvaluateFunc=pDrawFunc=NULL; } -C4MCOverlay::C4MCOverlay(C4MCNode *pOwner, C4MCOverlay &rTemplate, bool fClone) : C4MCNode(pOwner, rTemplate, fClone) +C4MCOverlay::C4MCOverlay(C4MCParser* pParser, C4MCNode *pOwner, C4MCOverlay &rTemplate, bool fClone) : C4MCNode(pParser, pOwner, rTemplate, fClone) { // copy fields X=rTemplate.X; Y=rTemplate.Y; Wdt=rTemplate.Wdt; Hgt=rTemplate.Hgt; @@ -642,7 +646,7 @@ C4MCPoint::C4MCPoint(C4MCNode *pOwner) : C4MCNode(pOwner) X=Y=0; } -C4MCPoint::C4MCPoint(C4MCNode *pOwner, C4MCPoint &rTemplate, bool fClone) : C4MCNode(pOwner, rTemplate, fClone) +C4MCPoint::C4MCPoint(C4MCParser* pParser, C4MCNode *pOwner, C4MCPoint &rTemplate, bool fClone) : C4MCNode(pParser, pOwner, rTemplate, fClone) { // copy fields X=rTemplate.X; Y=rTemplate.Y; @@ -695,7 +699,7 @@ C4MCMap::C4MCMap(C4MCNode *pOwner) : C4MCOverlay(pOwner) } -C4MCMap::C4MCMap(C4MCNode *pOwner, C4MCMap &rTemplate, bool fClone) : C4MCOverlay(pOwner, rTemplate, fClone) +C4MCMap::C4MCMap(C4MCParser* pParser, C4MCNode *pOwner, C4MCMap &rTemplate, bool fClone) : C4MCOverlay(pParser, pOwner, rTemplate, fClone) { } @@ -1129,7 +1133,7 @@ void C4MCParser::ParseTo(C4MCNode *pToNode) if (SEqual(CurrTokenIdtf, C4MC_Overlay)) { // overlay: create overlay node, using default template - pNewNode = new C4MCOverlay(pToNode, MapCreator->DefaultOverlay, false); + pNewNode = new C4MCOverlay(this, pToNode, MapCreator->DefaultOverlay, false); State=PS_KEYWD1; } else if (SEqual(CurrTokenIdtf, C4MC_Point) && !pToNode->GetNodeByName(CurrTokenIdtf)) @@ -1138,7 +1142,7 @@ void C4MCParser::ParseTo(C4MCNode *pToNode) if (!pToNode->Type() == MCN_Overlay) throw C4MCParserErr(this, C4MCErr_PointOnlyOvl); // create point node, using default template - pNewNode = new C4MCPoint(pToNode, MapCreator->DefaultPoint, false); + pNewNode = new C4MCPoint(this, pToNode, MapCreator->DefaultPoint, false); State=PS_KEYWD1; } else if (SEqual(CurrTokenIdtf, C4MC_Map)) @@ -1147,7 +1151,7 @@ void C4MCParser::ParseTo(C4MCNode *pToNode) if (!pToNode->GlobalScope()) throw C4MCParserErr(this, C4MCErr_MapNoGlobal); // create map node, using default template - pNewNode = new C4MCMap(pToNode, MapCreator->DefaultMap, false); + pNewNode = new C4MCMap(this, pToNode, MapCreator->DefaultMap, false); State=PS_KEYWD1; } else @@ -1229,7 +1233,7 @@ void C4MCParser::ParseTo(C4MCNode *pToNode) { case MCN_Overlay: // create overlay - pNewNode=new C4MCOverlay(pToNode, *((C4MCOverlay *) pCpyNode), false); + pNewNode=new C4MCOverlay(this, pToNode, *((C4MCOverlay *) pCpyNode), false); break; case MCN_Map: // maps not allowed diff --git a/src/landscape/C4MapCreatorS2.h b/src/landscape/C4MapCreatorS2.h index 3a2e8614c..a95803052 100644 --- a/src/landscape/C4MapCreatorS2.h +++ b/src/landscape/C4MapCreatorS2.h @@ -63,6 +63,7 @@ #define C4MCErr_AlgoNotFound "algorithm '%s' not found" #define C4MCErr_SFuncNotFound "script func '%s' not found in scenario script" #define C4MCErr_PointOnlyOvl "point only allowed in overlays" +#define C4MCErr_NoRecTemplate "cannot use template '%s' within itself" // predef class C4MCCallbackArray; @@ -156,10 +157,10 @@ public: public: C4MCNode(C4MCNode *pOwner=NULL); // constructor - C4MCNode(C4MCNode *pOwner, C4MCNode &rTemplate, bool fClone); // constructor using template + C4MCNode(C4MCParser* pParser, C4MCNode *pOwner, C4MCNode &rTemplate, bool fClone); // constructor using template virtual ~C4MCNode(); // destructor - virtual C4MCNode *clone(C4MCNode *pToNode) { return new C4MCNode(pToNode, *this, true); } + virtual C4MCNode *clone(C4MCParser* pParser, C4MCNode *pToNode) { return new C4MCNode(pParser, pToNode, *this, true); } void Clear(); // clear all child nodes void Reg2Owner(C4MCNode *pOwner); // register into list @@ -201,9 +202,9 @@ class C4MCOverlay : public C4MCNode { public: C4MCOverlay(C4MCNode *pOwner=NULL); // constructor - C4MCOverlay(C4MCNode *pOwner, C4MCOverlay &rTemplate, bool fClone); // construct of template + C4MCOverlay(C4MCParser* pParser, C4MCNode *pOwner, C4MCOverlay &rTemplate, bool fClone); // construct of template - C4MCNode *clone(C4MCNode *pToNode) { return new C4MCOverlay(pToNode, *this, true); } + C4MCNode *clone(C4MCParser* pParser, C4MCNode *pToNode) { return new C4MCOverlay(pParser, pToNode, *this, true); } protected: void Default(); // set default values for default presets @@ -254,9 +255,9 @@ class C4MCPoint : public C4MCNode { public: C4MCPoint(C4MCNode *pOwner=NULL); // constructor - C4MCPoint(C4MCNode *pOwner, C4MCPoint &rTemplate, bool fClone); // construct of template + C4MCPoint(C4MCParser* pParser, C4MCNode *pOwner, C4MCPoint &rTemplate, bool fClone); // construct of template - C4MCNode *clone(C4MCNode *pToNode) { return new C4MCPoint(pToNode, *this, true); } + C4MCNode *clone(C4MCParser* pParser, C4MCNode *pToNode) { return new C4MCPoint(pParser, pToNode, *this, true); } protected: void Default(); // set default values for default presets @@ -280,9 +281,9 @@ class C4MCMap : public C4MCOverlay { public: C4MCMap(C4MCNode *pOwner=NULL); // constructor - C4MCMap(C4MCNode *pOwner, C4MCMap &rTemplate, bool fClone); // construct of template + C4MCMap(C4MCParser* pParser, C4MCNode *pOwner, C4MCMap &rTemplate, bool fClone); // construct of template - C4MCNode *clone(C4MCNode *pToNode) { return new C4MCMap(pToNode, *this, true); } + C4MCNode *clone(C4MCParser* pParser, C4MCNode *pToNode) { return new C4MCMap(pParser, pToNode, *this, true); } protected: void Default(); // set default values for default presets