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(); 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) 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"); throw std::runtime_error("Invalid object instance id");
if(obj->instanceName == "") if(obj->instanceName == "")
@@ -573,19 +566,33 @@ void CMap::addNewObject(CGObjectInstance * obj)
auto it = instanceNames.find(obj->instanceName); auto it = instanceNames.find(obj->instanceName);
if(it != instanceNames.end()) 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); objects.push_back(obj);
instanceNames[obj->instanceName] = obj; instanceNames[obj->instanceName] = obj;
addBlockVisTiles(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)); towns.push_back(static_cast<CGTownInstance *>(obj));
} break;
if(obj->ID == Obj::HERO) case Obj::HERO:
{
heroesOnMap.push_back(static_cast<CGHeroInstance*>(obj)); 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 addNewArtifactInstance(CArtifactInstance * art);
void eraseArtifactInstance(CArtifactInstance * art); void eraseArtifactInstance(CArtifactInstance * art);
void addQuest(CGObjectInstance * quest);
void addNewObject(CGObjectInstance * obj); void addNewObject(CGObjectInstance * obj);
/// Gets object of specified type on requested position /// Gets object of specified type on requested position

View File

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

View File

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