Example #1
0
void AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor, bool cancelOther)
{
    if (actor == getPlayer())
        throw std::runtime_error("Can't add AI packages to player");

    // Stop combat when a non-combat AI package is added
    if (isActualAiPackage(package.getTypeId()))
        stopCombat();

    // We should return a wandering actor back after combat, casting or pursuit.
    // The same thing for actors without AI packages.
    // Also there is no point to stack return packages.
    int currentTypeId = getTypeId();
    int newTypeId = package.getTypeId();
    if (currentTypeId <= MWMechanics::AiPackage::TypeIdWander
        && !hasPackage(MWMechanics::AiPackage::TypeIdInternalTravel)
        && (newTypeId <= MWMechanics::AiPackage::TypeIdCombat
        || newTypeId == MWMechanics::AiPackage::TypeIdPursue
        || newTypeId == MWMechanics::AiPackage::TypeIdCast))
    {
        osg::Vec3f dest;
        if (currentTypeId == MWMechanics::AiPackage::TypeIdWander)
        {
            AiPackage* activePackage = getActivePackage();
            dest = activePackage->getDestination(actor);
        }
        else
        {
            dest = actor.getRefData().getPosition().asVec3();
        }

        MWMechanics::AiTravel travelPackage(dest.x(), dest.y(), dest.z(), true);
        stack(travelPackage, actor, false);
    }

    // remove previous packages if required
    if (cancelOther && package.shouldCancelPreviousAi())
    {
        for(std::list<AiPackage *>::iterator it = mPackages.begin(); it != mPackages.end();)
        {
            if((*it)->canCancel())
            {
                delete *it;
                it = mPackages.erase(it);
            }
            else
                ++it;
        }
        mRepeat=false;
    }

    // insert new package in correct place depending on priority
    for(std::list<AiPackage *>::iterator it = mPackages.begin(); it != mPackages.end(); ++it)
    {
        // We should keep current AiCast package, if we try to add a new one.
        if ((*it)->getTypeId() == MWMechanics::AiPackage::TypeIdCast &&
            package.getTypeId() == MWMechanics::AiPackage::TypeIdCast)
        {
            continue;
        }

        if((*it)->getPriority() <= package.getPriority())
        {
            mPackages.insert(it,package.clone());
            return;
        }
    }

    mPackages.push_back (package.clone());

    // Make sure that temporary storage is empty
    if (cancelOther)
    {
        mAiState.moveIn(new AiCombatStorage());
        mAiState.moveIn(new AiFollowStorage());
        mAiState.moveIn(new AiWanderStorage());
    }
}