예제 #1
0
    CreatureAI* selectAI(Creature *creature)
    {
        // Allow scripting AI for normal creatures and not controlled pets (guardians and mini-pets)
        if ((!creature->IsPet() || !((Pet*)creature)->isControlled()) && !creature->isCharmed())
            if (CreatureAI* scriptedAI = sScriptMgr.GetCreatureAI(creature))
                return scriptedAI;

        CreatureAIRegistry &ai_registry(CreatureAIRepository::Instance());

        const CreatureAICreator *ai_factory = NULL;

        std::string ainame=creature->GetAIName();

        // select by NPC flags _first_ - otherwise EventAI might be choosen for pets/totems
        // excplicit check for isControlled() and owner type to allow guardian, mini-pets and pets controlled by NPCs to be scripted by EventAI
        Unit *owner=NULL;
        if ((creature->IsPet() && ((Pet*)creature)->isControlled() &&
            ((owner=creature->GetOwner()) && owner->GetTypeId()==TYPEID_PLAYER)) || (creature->isCharmed() && !creature->IsVehicle()))
            ai_factory = ai_registry.GetRegistryItem("PetAI");
        else if (creature->IsTotem())
            ai_factory = ai_registry.GetRegistryItem("TotemAI");

        // select by script name
        if (!ai_factory && !ainame.empty())
            ai_factory = ai_registry.GetRegistryItem( ainame.c_str() );

        if (!ai_factory && creature->isGuard() )
            ai_factory = ai_registry.GetRegistryItem("GuardAI");

        // FG: civilians must never attack if not attacked by player
        if (!ai_factory && creature->IsCivilian())
            ai_factory = ai_registry.GetRegistryItem("ReactorAI");

        // select by permit check
        if (!ai_factory)
        {
            int best_val = PERMIT_BASE_NO;
            typedef CreatureAIRegistry::RegistryMapType RMT;
            RMT const &l = ai_registry.GetRegisteredItems();
            for( RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter)
            {
                const CreatureAICreator *factory = iter->second;
                const SelectableAI *p = dynamic_cast<const SelectableAI *>(factory);
                MANGOS_ASSERT( p != NULL );
                int val = p->Permit(creature);
                if( val > best_val )
                {
                    best_val = val;
                    ai_factory = p;
                }
            }
        }

        // select NullCreatureAI if not another cases
        ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key();

        DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str() );
        return ( ai_factory == NULL ? new NullCreatureAI(creature) : ai_factory->Create(creature) );
    }
예제 #2
0
    CreatureAI* selectAI(Creature *creature)
    {
        // Allow scripting AI for normal creatures and not controlled pets (guardians and mini-pets)
        if((!creature->isPet() || !((Pet*)creature)->isControlled()) && !creature->isCharmed())
            if(CreatureAI* scriptedAI = Script->GetAI(creature))
                return scriptedAI;

        CreatureAIRegistry &ai_registry(CreatureAIRepository::Instance());
        assert( creature->GetCreatureInfo() != NULL );
        CreatureInfo const *cinfo=creature->GetCreatureInfo();

        const CreatureAICreator *ai_factory = NULL;

        std::string ainame=cinfo->AIName;

        // select by script name
        if( !ainame.empty())
            ai_factory = ai_registry.GetRegistryItem( ainame.c_str() );

        // select by NPC flags
        if(!ai_factory)
        {
            if( creature->isGuard() )
                ai_factory = ai_registry.GetRegistryItem("GuardAI"); 
            else if(creature->isPet() || creature->isCharmed())
                ai_factory = ai_registry.GetRegistryItem("PetAI");
            else if(creature->isTotem())
                ai_factory = ai_registry.GetRegistryItem("TotemAI");
        }

        // select by permit check
        if(!ai_factory)
        {
            int best_val = -1;
            typedef CreatureAIRegistry::RegistryMapType RMT;
            RMT const &l = ai_registry.GetRegisteredItems();
            for( RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter)
            {
                const CreatureAICreator *factory = iter->second;
                const SelectableAI *p = dynamic_cast<const SelectableAI *>(factory);
                assert( p != NULL );
                int val = p->Permit(creature);
                if( val > best_val )
                {
                    best_val = val;
                    ai_factory = p;
                }
            }
        }

        // select NullCreatureAI if not another cases
        ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key();

        DEBUG_LOG("Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str() );
        return ( ai_factory == NULL ? new NullCreatureAI : ai_factory->Create(creature) );
    }
    CreatureAI* selectAI(Creature* creature)
    {
        if (CreatureAI* scriptedAI = sScriptMgr.GetCreatureAI(creature))
        {
            // charmed creature may have some script even if its not supposed to be that way (ex: Eye of Acherus)
            // Allow scripting AI for normal creatures and not controlled pets (guardians and mini-pets)
            if (creature->isCharmed() || !(creature->IsPet() && static_cast<Pet*>(creature)->isControlled()))
                return scriptedAI;
        }

        CreatureAIRegistry& ai_registry(CreatureAIRepository::Instance());

        const CreatureAICreator* ai_factory = nullptr;

        std::string ainame = creature->GetAIName();

        // select by NPC flags
        if (creature->IsPet())
        {
            if (static_cast<Pet*>(creature)->isControlled())
                ai_factory = ai_registry.GetRegistryItem("PetAI");
            else                            // For guardians and creature pets in general
                ai_factory = ai_registry.GetRegistryItem("GuardianAI");
        }
        else if (creature->IsTotem())
            ai_factory = ai_registry.GetRegistryItem("TotemAI");
        else if (!ainame.empty())           // select by script name
            ai_factory = ai_registry.GetRegistryItem(ainame.c_str());
        else if (creature->IsGuard())
            ai_factory = ai_registry.GetRegistryItem("GuardAI");
        else                                // select by permit check
        {
            int best_val = PERMIT_BASE_NO;
            typedef CreatureAIRegistry::RegistryMapType RMT;
            RMT const& l = ai_registry.GetRegisteredItems();
            for (RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter)
            {
                const CreatureAICreator* factory = iter->second;
                const SelectableAI* p = dynamic_cast<const SelectableAI*>(factory);
                MANGOS_ASSERT(p != nullptr);
                int val = p->Permit(creature);
                if (val > best_val)
                {
                    best_val = val;
                    ai_factory = p;
                }
            }
        }

        // select NullCreatureAI if not another cases
        ainame = (ai_factory == nullptr) ? "NullCreatureAI" : ai_factory->key();

        DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str());
        return (ai_factory == nullptr ? new NullCreatureAI(creature) : ai_factory->Create(creature));
    }
	GameObjectAI* SelectGameObjectAI(GameObject *go)
	{
		const GameObjectAICreator *ai_factory = NULL;
		GameObjectAIRegistry& ai_registry(*GameObjectAIRepository::instance());

		ai_factory = ai_registry.GetRegistryItem(go->GetAIName());

		//future goAI types go here
		std::string ainame = (ai_factory == NULL || go->GetScriptId()) ? "NullGameObjectAI" : ai_factory->key();

		//sLog->outDebug(LOG_FILTER_TSCR, "GameObject %u used AI is %s.", go->GetGUIDLow(), ainame.c_str()); Not ready to use just yet.
		sLog->outStaticDebug("GameObject %u used AI is %s.", go->GetGUIDLow(), ainame.c_str());
		return (ai_factory == NULL ? new NullGameObjectAI(go) : ai_factory->Create(go));
	}
    CreatureAI* GetSpecificAI(Unit* unit, std::string const& ainame)
    {
        // little hack to not have to change all AI to use Unit instead of Creature
        Creature* creature = unit->GetTypeId() == TYPEID_UNIT ? static_cast<Creature*>(unit) : nullptr;

        CreatureAIRegistry& ai_registry(CreatureAIRepository::Instance());
        const CreatureAICreator* ai_factory = ai_registry.GetRegistryItem(ainame);
        if (creature)
            return  ai_factory->Create(creature);
        else if (ainame == "PetAI")
            return (new PetAI(unit));

        sLog.outError("FactorySelector::GetSpecificAI> Cannot get %s AI for %s", ainame.c_str(), unit->GetObjectGuid().GetString().c_str());
        MANGOS_ASSERT(false);
        return nullptr;
    }
예제 #6
0
    GameObjectAI* SelectGameObjectAI(GameObject* go)
    {
        const GameObjectAICreator* ai_factory = NULL;
        GameObjectAIRegistry& ai_registry(GameObjectAIRepository::Instance());

        if (GameObjectAI* scriptedAI = sScriptMgr.GetGameObjectAI(go))
            return scriptedAI;

        ai_factory = ai_registry.GetRegistryItem(go->GetAIName());

        std::string ainame = (ai_factory == NULL) ? "NullGameObjectAI" : ai_factory->key();

        sLog.outDebug("GameObject %u used AI is %s.", go->GetGUIDLow(), ainame.c_str());

        return (ai_factory == NULL ? new NullGameObjectAI(go) : ai_factory->Create(go));
    }
예제 #7
0
GameObjectAI* SelectGameObjectAI(GameObject* go)
{
    const GameObjectAICreator* ai_factory = NULL;
    GameObjectAIRegistry& ai_registry(GameObjectAIRepository::Instance());

    // AIname in db
    std::string GobAiName = go->GetAIName();
    if (!GobAiName.empty())
        ai_factory = ai_registry.GetRegistryItem(GobAiName.c_str());

    //future goAI types go here

    std::string ainame = (ai_factory == NULL) ? "NullGameObjectAI" : ai_factory->key();

    DEBUG_LOG("GameObject %u used AI is %s.", go->GetGUIDLow(), ainame.c_str());

    return (ai_factory == NULL ? new NullGameObjectAI(go) : ai_factory->Create(go));
}
예제 #8
0
    GameObjectAI* SelectGameObjectAI(GameObject* go)
    {
        const GameObjectAICreator* ai_factory = NULL;
        GameObjectAIRegistry& ai_registry(*GameObjectAIRepository::instance());

        // scriptname in db
        if (GameObjectAI* scriptedAI = sScriptMgr->GetGameObjectAI(go))
            return scriptedAI;

        ai_factory = ai_registry.GetRegistryItem(go->GetAIName());

        //future goAI types go here

        std::string ainame = (ai_factory == NULL || go->GetScriptId()) ? "NullGameObjectAI" : ai_factory->key();

        TC_LOG_DEBUG("scripts", "GameObject %u used AI is %s.", go->GetGUIDLow(), ainame.c_str());

        return (ai_factory == NULL ? new NullGameObjectAI(go) : ai_factory->Create(go));
    }
예제 #9
0
    GameObjectAI* SelectGameObjectAI(GameObject* go)
    {
        const GameObjectAICreator* ai_factory = NULL;
        GameObjectAIRegistry& ai_registry(*GameObjectAIRepository::instance());

        if (GameObjectAI* scriptedAI = sScriptMgr->GetGameObjectAI(go))
            return scriptedAI;

        ai_factory = ai_registry.GetRegistryItem(go->GetAIName());

        //future goAI types go here

        // xinef: unused
        //std::string ainame = (ai_factory == NULL || go->GetScriptId()) ? "NullGameObjectAI" : ai_factory->key();

        ;//sLog->outDebug(LOG_FILTER_TSCR, "GameObject %u used AI is %s.", go->GetGUIDLow(), ainame.c_str());

        return (ai_factory == NULL ? new NullGameObjectAI(go) : ai_factory->Create(go));
    }
예제 #10
0
    CreatureAI* selectAI(Creature *creature)
    {
        const CreatureAICreator *ai_factory = NULL;
        CreatureAIRegistry& ai_registry(*CreatureAIRepository::instance());

        if (creature->isPet())
            ai_factory = ai_registry.GetRegistryItem("PetAI");

        //scriptname in db
        if (!ai_factory)
            if (CreatureAI * scriptedAI = sScriptMgr->GetCreatureAI(creature))
                return scriptedAI;

        // AIname in db
        std::string ainame = creature->GetAIName();
        if (!ai_factory && !ainame.empty())
            ai_factory = ai_registry.GetRegistryItem(ainame.c_str());

        // select by NPC flags
        if (!ai_factory)
        {
            if (creature->IsVehicle())
                ai_factory = ai_registry.GetRegistryItem("VehicleAI");
            else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN) && ((Guardian*) creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER)
                ai_factory = ai_registry.GetRegistryItem("PetAI");
            else if (creature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK))
                ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
            else if (creature->isGuard())
                ai_factory = ai_registry.GetRegistryItem("GuardAI");
            else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
                ai_factory = ai_registry.GetRegistryItem("PetAI");
            else if (creature->isTotem())
                ai_factory = ai_registry.GetRegistryItem("TotemAI");
            else if (creature->isTrigger())
            {
                if (creature->m_spells[0])
                    ai_factory = ai_registry.GetRegistryItem("TriggerAI");
                else
                    ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
            }
            else if (creature->GetCreatureType() == CREATURE_TYPE_CRITTER && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
                ai_factory = ai_registry.GetRegistryItem("CritterAI");
        }

        // select by permit check
        if (!ai_factory)
        {
            int best_val = -1;
            typedef CreatureAIRegistry::RegistryMapType RMT;
            RMT const &l = ai_registry.GetRegisteredItems();
            for (RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter)
            {
                const CreatureAICreator *factory = iter->second;
                const SelectableAI *p = dynamic_cast<const SelectableAI *>(factory);
                ASSERT(p != NULL);
                int val = p->Permit(creature);
                if (val > best_val)
                {
                    best_val = val;
                    ai_factory = p;
                }
            }
        }

        // select NullCreatureAI if not another cases
        ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key();

        //sLog->outDebug(LOG_FILTER_TSCR, "Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str()); Not ready to use just yet.
        sLog->outStaticDebug("Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str());
        return (ai_factory == NULL ? new NullCreatureAI(creature) : ai_factory->Create(creature));
    }
예제 #11
0
    CreatureAI* selectAI(Creature* creature)
    {
        const CreatureAICreator* ai_factory = NULL;
        CreatureAIRegistry& ai_registry(*CreatureAIRepository::instance());

        if (creature->IsPet())
            ai_factory = ai_registry.GetRegistryItem("PetAI");

        //scriptname in db
        if (!ai_factory)
            if (CreatureAI* scriptedAI = sScriptMgr->GetCreatureAI(creature))
                return scriptedAI;

        // AIname in db
        std::string ainame=creature->GetAIName();
        if (!ai_factory && !ainame.empty())
            ai_factory = ai_registry.GetRegistryItem(ainame);

        // select by NPC flags
        if (!ai_factory)
        {
            if (creature->IsVehicle())
                ai_factory = ai_registry.GetRegistryItem("VehicleAI");
            else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN) && ((Guardian*)creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER)
                ai_factory = ai_registry.GetRegistryItem("PetAI");
            else if (creature->HasFlag(UNIT_FIELD_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK))
                ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
            else if (creature->IsGuard())
                ai_factory = ai_registry.GetRegistryItem("GuardAI");
            else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
                ai_factory = ai_registry.GetRegistryItem("PetAI");
            else if (creature->IsTotem())
                ai_factory = ai_registry.GetRegistryItem("TotemAI");
            else if (creature->IsTrigger())
            {
                if (creature->m_spells[0])
                    ai_factory = ai_registry.GetRegistryItem("TriggerAI");
                else
                    ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
            }
            else if (creature->IsCritter() && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
                ai_factory = ai_registry.GetRegistryItem("CritterAI");
        }

        // select by permit check
        if (!ai_factory)
        {
            int best_val = -1;
            typedef CreatureAIRegistry::RegistryMapType RMT;
            RMT const& l = ai_registry.GetRegisteredItems();
            for (RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter)
            {
                const CreatureAICreator* factory = iter->second;
                const SelectableAI* p = dynamic_cast<const SelectableAI*>(factory);
                ASSERT(p);
                int val = p->Permit(creature);
                if (val > best_val)
                {
                    best_val = val;
                    ai_factory = p;
                }
            }
        }

        // select NullCreatureAI if not another cases
        ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key();

        TC_LOG_DEBUG("scripts", "Creature %s (Entry: %u GUID: %u DB GUID: %u) is using AI type: %s.", creature->GetName().c_str(), creature->GetEntry(), creature->GetGUIDLow(), creature->GetDBTableGUIDLow(), ainame.c_str());
        return (ai_factory == NULL ? new NullCreatureAI(creature) : ai_factory->Create(creature));
    }
예제 #12
0
    CreatureAI* selectAI(Creature* creature)
    {
        const CreatureAICreator* ai_factory = NULL;
        CreatureAIRegistry& ai_registry(*CreatureAIRepository::instance());

        // xinef: if we have controlable guardian, define petai for players as they can steer him, otherwise db / normal ai
        // xinef: dont remember why i changed this qq commented out as may break some quests
        if (creature->IsPet()/* || (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN) && ((Guardian*)creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER)*/)
            ai_factory = ai_registry.GetRegistryItem("PetAI");

        //scriptname in db
        if (!ai_factory)
            if (CreatureAI* scriptedAI = sScriptMgr->GetCreatureAI(creature))
                return scriptedAI;

        // AIname in db
        std::string ainame=creature->GetAIName();
        if (!ai_factory && !ainame.empty())
            ai_factory = ai_registry.GetRegistryItem(ainame);

        // select by NPC flags
        if (!ai_factory)
        {
            if (creature->IsVehicle())
                ai_factory = ai_registry.GetRegistryItem("VehicleAI");
            else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN) && ((Guardian*)creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER)
                ai_factory = ai_registry.GetRegistryItem("PetAI");
            else if (creature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK))
                ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
            else if (creature->IsGuard())
                ai_factory = ai_registry.GetRegistryItem("GuardAI");
            else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
                ai_factory = ai_registry.GetRegistryItem("PetAI");
            else if (creature->IsTotem())
                ai_factory = ai_registry.GetRegistryItem("TotemAI");
            else if (creature->IsTrigger())
            {
                if (creature->m_spells[0])
                    ai_factory = ai_registry.GetRegistryItem("TriggerAI");
                else
                    ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
            }
            else if (creature->IsCritter() && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
                ai_factory = ai_registry.GetRegistryItem("CritterAI");
        }

        // select by permit check
        if (!ai_factory)
        {
            int best_val = -1;
            typedef CreatureAIRegistry::RegistryMapType RMT;
            RMT const& l = ai_registry.GetRegisteredItems();
            for (RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter)
            {
                const CreatureAICreator* factory = iter->second;
                const SelectableAI* p = dynamic_cast<const SelectableAI*>(factory);
                ASSERT(p);
                int val = p->Permit(creature);
                if (val > best_val)
                {
                    best_val = val;
                    ai_factory = p;
                }
            }
        }

        // select NullCreatureAI if not another cases
        // xinef: unused
        // ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key();

        ;//sLog->outDebug(LOG_FILTER_TSCR, "Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str());
        return (ai_factory == NULL ? new NullCreatureAI(creature) : ai_factory->Create(creature));
    }
예제 #13
0
    CreatureAI* selectAI(Creature *creature)
    {
        const CreatureAICreator *ai_factory = NULL;
        CreatureAIRegistry &ai_registry(CreatureAIRepository::Instance());

        if(creature->isPet())
            ai_factory = ai_registry.GetRegistryItem("PetAI");

        //scriptname in db
        if(!ai_factory)
            if(CreatureAI* scriptedAI = Script->GetAI(creature))
                return scriptedAI;

        // AIname in db
        std::string ainame=creature->GetAIName();
        if(!ai_factory && !ainame.empty())
            ai_factory = ai_registry.GetRegistryItem( ainame.c_str() );

        // select by NPC flags
        if(!ai_factory)
        {
            if(creature->HasSummonMask(SUMMON_MASK_CONTROLABLE_GUARDIAN) && ((Guardian*)creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER)
                ai_factory = ai_registry.GetRegistryItem("PetAI");
            else if(creature->isVehicle() || creature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK))
                ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
            else if(creature->isGuard())
                ai_factory = ai_registry.GetRegistryItem("GuardAI");
            else if(creature->HasSummonMask(SUMMON_MASK_CONTROLABLE_GUARDIAN))
                ai_factory = ai_registry.GetRegistryItem("PetAI");
            else if(creature->isTotem())
                ai_factory = ai_registry.GetRegistryItem("TotemAI");
            else if(creature->isTrigger())
            {
                if(creature->m_spells[0])
                    ai_factory = ai_registry.GetRegistryItem("TriggerAI");
                else
                    ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
            }
            else if(creature->GetCreatureType() == CREATURE_TYPE_CRITTER && !creature->HasSummonMask(SUMMON_MASK_GUARDIAN))
                ai_factory = ai_registry.GetRegistryItem("CritterAI");
        }

        if(!ai_factory)
        {
            for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
            {
                if(creature->m_spells[i])
                {
                    ai_factory = ai_registry.GetRegistryItem("SpellAI");
                    break;
                }
            }
        }

        // select by permit check
        if(!ai_factory)
        {
            int best_val = -1;
            typedef CreatureAIRegistry::RegistryMapType RMT;
            RMT const &l = ai_registry.GetRegisteredItems();
            for( RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter)
            {
                const CreatureAICreator *factory = iter->second;
                const SelectableAI *p = dynamic_cast<const SelectableAI *>(factory);
                assert( p != NULL );
                int val = p->Permit(creature);
                if( val > best_val )
                {
                    best_val = val;
                    ai_factory = p;
                }
            }
        }

        // select NullCreatureAI if not another cases
        ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key();

        DEBUG_LOG("Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str() );
        return ( ai_factory == NULL ? new NullCreatureAI(creature) : ai_factory->Create(creature) );
    }
예제 #14
0
CreatureAI* selectAI(Creature *creature)
{
    const CreatureAICreator *ai_factory = NULL;
    CreatureAIRegistry &ai_registry(CreatureAIRepository::Instance());

    if(creature->isPet())
        ai_factory = ai_registry.GetRegistryItem("PetAI");

    //scriptname in db
    // Allow scripting AI for normal creatures and not controlled pets (guardians and mini-pets)
    if((!creature->isPet() || !((Pet*)creature)->isControlled()) && !creature->isCharmed())
        if(CreatureAI* scriptedAI = Script->GetAI(creature))
            return scriptedAI;

    // AIname in db
    std::string ainame=creature->GetAIName();
    if(!ai_factory && !ainame.empty())
        ai_factory = ai_registry.GetRegistryItem( ainame.c_str() );

    // select by NPC flags
    if(!ai_factory)
    {
        if(creature->isGuard() && creature->GetOwner() && creature->GetOwner()->GetTypeId() == TYPEID_PLAYER)
            ai_factory = ai_registry.GetRegistryItem("PetAI");
        else if(creature->isGuard())
            ai_factory = ai_registry.GetRegistryItem("GuardAI");
        else if(creature->isPet() || (creature->isCharmed() && !creature->isPossessed()))
            ai_factory = ai_registry.GetRegistryItem("PetAI");
        else if(creature->isTotem())
            ai_factory = ai_registry.GetRegistryItem("TotemAI");
        else if(creature->isTrigger())
        {
            if(creature->m_spells[0])
                ai_factory = ai_registry.GetRegistryItem("TriggerAI");
            else
                ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
        }
        else if(creature->GetCreatureType() == CREATURE_TYPE_CRITTER)
            ai_factory = ai_registry.GetRegistryItem("CritterAI");
    }

    if(!ai_factory)
    {
        for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
        {
            if(creature->m_spells[i])
            {
                ai_factory = ai_registry.GetRegistryItem("CombatAI");
                break;
            }
        }
    }

    // select by permit check
    if(!ai_factory)
    {
        int best_val = -1;
        typedef CreatureAIRegistry::RegistryMapType RMT;
        RMT const &l = ai_registry.GetRegisteredItems();
        for( RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter)
        {
            const CreatureAICreator *factory = iter->second;
            const SelectableAI *p = dynamic_cast<const SelectableAI *>(factory);
            assert( p != NULL );
            int val = p->Permit(creature);
            if( val > best_val )
            {
                best_val = val;
                ai_factory = p;
            }
        }
    }

    // select NullCreatureAI if not another cases
    ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key();

    DEBUG_LOG("Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str() );
    return ( ai_factory == NULL ? new NullCreatureAI(creature) : ai_factory->Create(creature) );
}