Exemple #1
0
bool UnitBase::isInAttackRange(const ObjectBase* pObject) const {
	int checkRange;
    switch(attackMode) {
        case GUARD: {
            checkRange = getWeaponRange();
        } break;

        case AREAGUARD: {
            checkRange = getAreaGuardRange() + getWeaponRange() + 1;
        } break;

        case AMBUSH: {
            checkRange = getViewRange() + 1;
        } break;

        case HUNT: {
            return true;
        } break;

        case STOP:
        default: {
            return false;
        } break;
    }

    if(getItemID() == Unit_Sandworm) {
        checkRange = getViewRange() + 1;
    }

    return (blockDistance(guardPoint*TILESIZE + Coord(TILESIZE/2, TILESIZE/2), pObject->getCenterPoint()) <= checkRange*TILESIZE);
}
Exemple #2
0
	virtual void calculate(const float dt) {
		if (!_reaction.tick(dt))
			return;
		
		float range = getWeaponRange(_object);
		//LOG_DEBUG(("range = %g", range));

		_state.fire = false;

		const Object * result = NULL;
		float dist = -1;
		
		std::set<const Object *> objects;
		enumerate_objects(objects, range, &ai::Targets->troops );
		for(std::set<const Object *>::const_iterator i = objects.begin(); i != objects.end(); ++i) {
			const Object *target = *i;
			if (has_same_owner(target) || target->ai_disabled() || target->pierceable || target->impassability == 0 || target->hp <= 0)
				continue;
			
			v2<float> dpos = get_relative_position(target);
			if (check_distance(get_center_position(), target->get_center_position(), get_z(), true)) {
				if (result == NULL || dpos.quick_length() < dist) {
					result = target;
					dist = dpos.quick_length();
				}
			}
		}
		
		if (result != NULL) {
			_state.fire = true;
			_direction = get_relative_position(result);
			_direction.normalize();
			//set_direction(_direction.get_direction(get_directions_number()) - 1);
		}
	}
Exemple #3
0
bool UnitBase::isInWeaponRange(const ObjectBase* object) const {
    if(object == NULL) {
        return false;
    }

    Coord targetLocation = target.getObjPointer()->getClosestPoint(location);

    return (blockDistance(location, targetLocation) <= getWeaponRange());
}
Exemple #4
0
void Cannon::calculate(const float dt) {
	if (!_reaction.tick(dt))
		return;
	
	static float range = getWeaponRange("cannon-bullet");
	v2<float> pos, vel;
	if (get_nearest(_variants.has("trainophobic")? ai::Targets->infantry_and_train: ai::Targets->infantry, range, pos, vel, true)) {
		pos.normalize();
		set_direction(pos.get_direction(get_directions_number()) - 1);
		_direction = pos;
		_state.fire = true;
	} else _state.fire = false;
}
Exemple #5
0
	void calculate(const float dt) {
		if (!_reaction.tick(dt)) 
			return;
		
		if (_parent == NULL)
			throw_ex(("turret is only operable attached to shilka "));

		if (_parent->disable_ai && PlayerManager->get_slot_by_id(_parent->get_id()) == NULL) {
			Object::calculate(dt);
			return;
		}
					
		v2<float> pos, vel;
		std::set<const Object *> objects;
		_parent->enumerate_objects(objects, getWeaponRange("shilka-bullet"), &ai::Targets->troops);

		int dirs = get_directions_number();
		//int parent_dir = _parent->get_direction();
		//(_parent->get_direction() - _parent->get_directions_number() / 2) * get_directions_number() / _parent->get_directions_number();

		const Object *target = NULL;
		v2<float> target_pos;
		for(std::set<const Object *>::iterator i = objects.begin(); i != objects.end(); ++i) {
			const Object *o = *i;
			if (o->get_id() == _parent->get_id() || o->impassability == 0 || o->hp <= 0 ||
				PIERCEABLE_PAIR(_parent, o) || !ZBox::sameBox(_parent->get_z(), o->get_z()) || _parent->has_same_owner(o) ||
				o->has_effect("invulnerability")
				)
				continue;
			
			pos = get_relative_position(o);
			if (target == NULL || pos.quick_length() < target_pos.quick_length()) {
				target = o;
				target_pos = pos;
			}
			//LOG_DEBUG(("%s <- dir: %d, parent_dir: %d (%g, %g)", o->animation.c_str(), dir, parent_dir, pos.x, pos.y));
		}
		
		target_pos.normalize();
		int dir = target_pos.get_direction(dirs) - 1;

		if (target == NULL || dir < 0) {
			Object::calculate(dt);
			return;
		}

		_direction = target_pos;		
		set_direction(dir);
	}
Exemple #6
0
void UnitBase::engageTarget() {

    if(target && (target.getObjPointer() == NULL)) {
        // the target does not exist anymore
        releaseTarget();
        return;
    }

    if(target && (target.getObjPointer()->isActive() == false)) {
        // the target changed its state to inactive
        releaseTarget();
        return;
    }

    if(target && !targetFriendly && !canAttack(target.getObjPointer())) {
        // the (non-friendly) target cannot be attacked anymore
        releaseTarget();
        return;
    }

    if(target && !targetFriendly && !forced && !isInAttackRange(target.getObjPointer())) {
        // the (non-friendly) target left the attack mode range (and we were not forced to attack it)
        releaseTarget();
        return;
    }

    if(target) {
        // we have a target unit or structure

        Coord targetLocation = target.getObjPointer()->getClosestPoint(location);

        if(destination != targetLocation) {
            // the location of the target has moved
            // => recalculate path
            clearPath();
        }

        targetDistance = blockDistance(location, targetLocation);

        Sint8 newTargetAngle = lround(8.0f/256.0f*destinationAngle(location, targetLocation));
        if(newTargetAngle == 8) {
            newTargetAngle = 0;
        }

        if(bFollow) {
            // we are following someone
            setDestination(targetLocation);
            return;
        }

        if(targetDistance > getWeaponRange()) {
            // we are not in attack range
            // => follow the target
            setDestination(targetLocation);
            return;
        }

        // we are in attack range

        if(targetFriendly && !forced) {
            // the target is friendly and we only attack these if were forced to do so
            return;
        }

        if(goingToRepairYard) {
            // we are going to the repair yard
            // => we do not need to change the destination
            targetAngle = INVALID;
        } else if(attackMode == CAPTURE) {
            // we want to capture the target building
            setDestination(targetLocation);
            targetAngle = INVALID;
        } else if(isTracked() && target.getObjPointer()->isInfantry() && currentGameMap->tileExists(targetLocation) && !currentGameMap->getTile(targetLocation)->isMountain() && forced) {
            // we squash the infantry unit because we are forced to
            setDestination(targetLocation);
            targetAngle = INVALID;
        } else {
            // we decide to fire on the target thus we can stop moving
            setDestination(location);
            targetAngle = newTargetAngle;
        }

        if(getCurrentAttackAngle() == newTargetAngle) {
            attack();
        }

    } else if(attackPos) {
        // we attack a position

        targetDistance = blockDistance(location, attackPos);

        Sint8 newTargetAngle = lround(8.0f/256.0f*destinationAngle(location, attackPos));
        if(newTargetAngle == 8) {
            newTargetAngle = 0;
        }

        if(targetDistance <= getWeaponRange()) {
            // we are in weapon range thus we can stop moving
            setDestination(location);
            targetAngle = newTargetAngle;

            if(getCurrentAttackAngle() == newTargetAngle) {
                attack();
            }
        } else {
            targetAngle = INVALID;
        }
    }
}