Esempio n. 1
0
bool AssistTask::onValidate() {
    if (targetAlt >= 0) {
        if (ai->cbc->IsUnitCloaked(targetAlt)) {
            firstGroup()->stop();
        }
    }

    return true;
}
Esempio n. 2
0
bool AttackTask::onValidate() {
	CGroup *group = firstGroup();

	if (targetAlt >= 0) {
		if (ai->cbc->IsUnitCloaked(targetAlt) || !group->canAttack(targetAlt)) {
			group->stop();
		}
	}

	const UnitDef *eud = ai->cbc->GetUnitDef(target);
	if (eud == NULL)
		return false;

	if (!isMoving) {
		if (ai->cbc->IsUnitCloaked(target))
			return false;
		return true;
	}

	if (!group->canAttack(target))
		return false;

	// don't chase scout groups too long if they are out of base...
	bool scoutGroup = (group->cats&SCOUTER).any();
	if (!scoutGroup && lifeTime() > 20.0f) {
		const unitCategory ecats = UC(eud->id);
		if ((ecats&SCOUTER).any() && !ai->defensematrix->isPosInBounds(pos))
			return false;
	}

	float targetDistance = pos.distance2D(group->pos());
	if (targetDistance > 1000.0f)
		return true; // too far to panic

	if (ai->cbc->IsUnitCloaked(target))
		return false;

	bool isBaseThreat = ai->defensematrix->isPosInBounds(pos);

	// if there is no threat to our base then prevent useless attack for groups
	// which are not too cheap
	if (!isBaseThreat && (group->costMetal / group->units.size()) >= 100.0f) {
		float threatRange;
		if (scoutGroup)
			threatRange = 300.0f;
		else
			threatRange = 0.0f;

		if (group->getThreat(pos, threatRange) > group->strength)
			return false;
	}

	return true;
}
Esempio n. 3
0
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);
	}
}
Esempio n. 4
0
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);
        }
    }
}
Esempio n. 5
0
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;
	}
}
Esempio n. 6
0
void AttackTask::toStream(std::ostream& out) const {
	out << "AttackTask(" << key << ") target(" << enemy << ") ";
	CGroup *group = firstGroup();
	if (group)
		out << (*group);
}