void AttackTask::onUpdate() { CGroup *group = firstGroup(); if (group->isMicroing() && group->isIdle()) { targetAlt = -1; // for sure group->micro(false); } if (isMoving) { /* Keep tracking the target */ pos = ai->cbc->GetUnitPos(target); float3 gpos = group->pos(); float dist = gpos.distance2D(pos); float range = group->getRange(); /* See if we can attack our target already */ if (dist <= range) { bool canAttack = true; /* // for ground units prevent shooting across hill... if ((group->cats&AIR).none()) { // FIXME: improve dist = ai->pathfinder->getPathLength(*group, pos); canAttack = (dist <= range * 1.1f); } */ if (canAttack) { if ((group->cats&BUILDER).any()) group->reclaim(target); else group->attack(target); isMoving = false; ai->pathfinder->remove(*group); group->micro(true); } } } /* See if we can attack a target we found on our path */ if (!(group->isMicroing() || urgent())) { if ((group->cats&BUILDER).any()) resourceScan(); // builders should not be too aggressive else enemyScan(targetAlt); } }
void AssistTask::onUpdate() { CGroup *group = firstGroup(); if (group->isMicroing() && group->isIdle()) { targetAlt = -1; // for sure group->micro(false); } if (!assisting) { if (isMoving) { /* Keep tracking the target */ pos = assist->pos; float3 gpos = group->pos(); float dist = gpos.distance2D(pos); float range = group->getRange(); if (dist <= range) { bool canAssist = true; /* // for ground units prevent assisting across hill... if ((group->cats&AIR).none()) { dist = ai->pathfinder->getPathLength(*group, pos); canAssist = (dist <= range * 1.1f); } */ if (canAssist) { isMoving = false; ai->pathfinder->remove(*group); } } } if (!isMoving) { group->assist(*assist); group->micro(true); assisting = true; } } if (!group->isMicroing()) { if ((group->cats&BUILDER).any()) resourceScan(); // builders should not be too aggressive else if ((group->cats&AIR).none()) { enemyScan(targetAlt); } } }
void MergeTask::onUpdate() { /* See which groups can be merged already */ std::list<CGroup*>::iterator it; for (it = groups.begin(); it != groups.end(); ++it) { CGroup *g = *it; if (g->isMicroing()) continue; if (pos.distance2D(g->pos()) < range) { mergable[g->key] = g; g->micro(true); } } /* We have at least two groups, now we can merge */ if (mergable.size() >= 2) { std::vector<int> keys; std::map<int, CGroup*>::iterator it; // get keys because while merging "mergable" is reducing... for (it = mergable.begin(); it != mergable.end(); ++it) { keys.push_back(it->first); } for (int i = 0; i < keys.size(); i++) { int key = keys[i]; if (key != masterGroup->key) { CGroup *g = mergable[key]; LOG_II("MergeTask::update merging " << (*g) << " with " << (*masterGroup)) // NOTE: group being merged is automatically removed masterGroup->merge(*g); } } assert(mergable.size() == 1); mergable.clear(); masterGroup->micro(false); } // if only one (or none) group remains, merging is no longer possible, // remove the task, unreg groups... if (groups.size() <= 1) ATask::remove(); }