1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-09-16 09:26:28 +02:00

Fixed use-after-free crash with quests registration in RMG.

* code taken from PR #200
This commit is contained in:
AlexVinS
2016-09-08 14:24:28 +03:00
parent 78a560767b
commit 6dc47a2de0
4 changed files with 26 additions and 26 deletions

View File

@@ -556,16 +556,9 @@ void CMap::eraseArtifactInstance(CArtifactInstance * art)
artInstances[art->id.getNum()].dellNull();
}
void CMap::addQuest(CGObjectInstance * quest)
{
auto q = dynamic_cast<IQuestObject *>(quest);
q->quest->qid = quests.size();
quests.push_back(q->quest);
}
void CMap::addNewObject(CGObjectInstance * obj)
{
if(obj->id != ObjectInstanceID(objects.size()))
if(obj->id != ObjectInstanceID(objects.size()))
throw std::runtime_error("Invalid object instance id");
if(obj->instanceName == "")
@@ -573,19 +566,33 @@ void CMap::addNewObject(CGObjectInstance * obj)
auto it = instanceNames.find(obj->instanceName);
if(it != instanceNames.end())
throw std::runtime_error("Object instance name duplicated:"+obj->instanceName);
throw std::runtime_error("Object instance name duplicated: "+obj->instanceName);
objects.push_back(obj);
instanceNames[obj->instanceName] = obj;
addBlockVisTiles(obj);
objects.push_back(obj);
instanceNames[obj->instanceName] = obj;
addBlockVisTiles(obj);
if(obj->ID == Obj::TOWN)
//todo: make this virtual method of CGObjectInstance
switch (obj->ID)
{
case Obj::TOWN:
towns.push_back(static_cast<CGTownInstance *>(obj));
}
if(obj->ID == Obj::HERO)
{
break;
case Obj::HERO:
heroesOnMap.push_back(static_cast<CGHeroInstance*>(obj));
break;
case Obj::SEER_HUT:
case Obj::QUEST_GUARD:
case Obj::BORDERGUARD:
case Obj::BORDER_GATE:
{
auto q = dynamic_cast<IQuestObject *>(obj);
q->quest->qid = quests.size();
quests.push_back(q->quest);
}
break;
default:
break;
}
}

View File

@@ -313,7 +313,7 @@ public:
void addNewArtifactInstance(CArtifactInstance * art);
void eraseArtifactInstance(CArtifactInstance * art);
void addQuest(CGObjectInstance * quest);
void addNewObject(CGObjectInstance * obj);
/// Gets object of specified type on requested position

View File

@@ -1112,7 +1112,6 @@ void CMapLoaderH3M::readObjects()
case Obj::SEER_HUT:
{
nobj = readSeerHut();
map->addQuest(nobj);
break;
}
case Obj::WITCH_HUT:
@@ -1363,7 +1362,6 @@ void CMapLoaderH3M::readObjects()
case Obj::QUEST_GUARD:
{
auto guard = new CGQuestGuard();
map->addQuest(guard);
readQuest(guard);
nobj = guard;
break;
@@ -1400,13 +1398,11 @@ void CMapLoaderH3M::readObjects()
case Obj::BORDERGUARD:
{
nobj = new CGBorderGuard();
map->addQuest(nobj);
break;
}
case Obj::BORDER_GATE:
{
nobj = new CGBorderGate();
map->addQuest (nobj);
break;
}
case Obj::PYRAMID: //Pyramid of WoG object

View File

@@ -451,7 +451,7 @@ void CRmgTemplateZone::createBorder(CMapGenerator* gen)
if (gen->isPossible(nearbyPos))
gen->setOccupied(nearbyPos, ETileType::BLOCKED);
});
edge = true;
edge = true;
}
});
}
@@ -2328,7 +2328,7 @@ ObjectInfo CRmgTemplateZone::getRandomObject(CMapGenerator* gen, CTreasurePileIn
continue;
total += oi.probability;
thresholds.push_back (std::make_pair (total, &oi));
}
}
@@ -2760,7 +2760,6 @@ void CRmgTemplateZone::addAllPossibleObjects(CMapGenerator* gen)
obj->quest->isCustomFirst = obj->quest->isCustomNext = obj->quest->isCustomComplete = false;
gen->banQuestArt(artid);
gen->map->addQuest(obj);
this->questArtZone->possibleObjects.push_back (generateArtInfo(artid));
@@ -2799,7 +2798,6 @@ void CRmgTemplateZone::addAllPossibleObjects(CMapGenerator* gen)
obj->quest->isCustomFirst = obj->quest->isCustomNext = obj->quest->isCustomComplete = false;
gen->banQuestArt(artid);
gen->map->addQuest(obj);
this->questArtZone->possibleObjects.push_back(generateArtInfo(artid));
@@ -2823,7 +2821,6 @@ void CRmgTemplateZone::addAllPossibleObjects(CMapGenerator* gen)
obj->quest->isCustomFirst = obj->quest->isCustomNext = obj->quest->isCustomComplete = false;
gen->banQuestArt(artid);
gen->map->addQuest(obj);
this->questArtZone->possibleObjects.push_back(generateArtInfo(artid));