bool MergeTask::reelectMasterGroup() { if (groups.size() <= 1) return false; bool reelect = true; if (masterGroup && !isRetreating) { float threat = masterGroup->getThreat(pos, masterGroup->radius()); // if threat is 2x smaller than group strength then do nothing if (threat <= EPS || (masterGroup->strength / threat) > 2.0f) reelect = false; } if (reelect) { float minThreat = std::numeric_limits<float>::max(); float maxDistance = std::numeric_limits<float>::min(); CGroup *bestGroup = NULL; std::list<CGroup*>::iterator it; for (it = groups.begin(); it != groups.end(); ++it) { CGroup *g = *it; float3 gpos = g->pos(); float threat = g->getThreat(gpos, g->radius()); float distance = ai->defensematrix->distance2D(gpos); if (distance > maxDistance) maxDistance = distance; if (threat < minThreat) { bestGroup = g; minThreat = threat; isRetreating = (distance + EPS) < maxDistance; } } if (bestGroup && (masterGroup == NULL || masterGroup->key != bestGroup->key)) { masterGroup = bestGroup; pos = bestGroup->pos(true); for (it = groups.begin(); it != groups.end(); ++it) { CGroup *g = *it; ai->pathfinder->remove(*g); if (!ai->pathfinder->addGroup(*g)) return false; } } } return (masterGroup != NULL); }
MergeTask::MergeTask(AIClasses *_ai, std::list<CGroup*>& groups): ATask(_ai) { t = TASK_MERGE; isRetreating = false; range = 0.0f; masterGroup = NULL; std::list<CGroup*>::iterator it; for (it = groups.begin(); it != groups.end(); ++it) { CGroup *group = *it; addGroup(*group); range += group->radius(); } unitCategory cats = firstGroup()->cats; if ((cats&AIR).any() && (cats&ASSAULT).none()) { // FIXME: prefer no hardcoding range = 1000.0f; } else { range = range + groups.size() * FOOTPRINT2REAL; } }