forked from Mirrors/openclonk
map creator: don't crash when using a template within itself (#534)
parent
28e2bdbb92
commit
2d3a4981bf
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue