예제 #1
0
void WaypointManager::Load()
{
    Cleanup();

    uint32 total_paths = 0;
    uint32 total_nodes = 0;
    uint32 total_behaviors = 0;

    QueryResult *result = WorldDatabase.Query("SELECT id, COUNT(point) FROM creature_movement GROUP BY id");
    if(result)
    {
        total_paths = result->GetRowCount();
        barGoLink bar( total_paths );
        do
        {
            Field *fields = result->Fetch();
            uint32 id    = fields[0].GetUInt32();
            uint32 count = fields[1].GetUInt32();
            m_pathMap[id].resize(count);

            total_nodes += count;
            bar.step();
        } while( result->NextRow() );
        delete result;
    }

    result = WorldDatabase.Query("SELECT position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id, point FROM creature_movement");
    if(result)
    {
        barGoLink bar( result->GetRowCount() );
        do
        {
            Field *fields = result->Fetch();
            uint32 point        = fields[15].GetUInt32();
            uint32 id           = fields[14].GetUInt32();

            WaypointPath &path  = m_pathMap[id];
            // the cleanup queries make sure the following is true
            assert(point >= 1 && point <= path.size());
            WaypointNode &node  = path[point-1];

            node.x              = fields[0].GetFloat();
            node.y              = fields[1].GetFloat();
            node.z              = fields[2].GetFloat();
            node.orientation    = fields[3].GetFloat();
            node.delay          = fields[6].GetUInt16();

            // prevent using invalid coordinates
            if(!MaNGOS::IsValidMapCoord(node.x, node.y, node.z, node.orientation))
            {
                QueryResult *result1 = WorldDatabase.PQuery("SELECT id, map FROM creature WHERE guid = '%u'", id);
                if(result1)
                    sLog.outErrorDb("ERROR: Creature (guidlow %d, entry %d) have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
                        id, result1->Fetch()[0].GetUInt32(), point, node.x, node.y);
                else
                    sLog.outErrorDb("ERROR: Waypoint path %d, have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
                        id, point, node.x, node.y);

                MaNGOS::NormalizeMapCoord(node.x);
                MaNGOS::NormalizeMapCoord(node.y);
                if(result1)
                {
                    node.z = MapManager::Instance ().GetBaseMap(result1->Fetch()[1].GetUInt32())->GetHeight(node.x, node.y, node.z);
                    delete result1;
                }
                WorldDatabase.PExecute("UPDATE creature_movement SET position_x = '%f', position_y = '%f', position_z = '%f' WHERE id = '%u' AND point = '%u'", node.x, node.y, node.z, id, point);
            }

            WaypointBehavior be;
            be.model1           = fields[4].GetUInt32();
            be.model2           = fields[5].GetUInt32();
            be.emote            = fields[7].GetUInt32();
            be.spell            = fields[8].GetUInt32();

            for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
            {
                be.textid[i]        = fields[9+i].GetUInt32();
                if(be.textid[i])
                {
                    if (be.textid[i] < MIN_DB_SCRIPT_STRING_ID || be.textid[i] >= MAX_DB_SCRIPT_STRING_ID)
                    {
                        sLog.outErrorDb( "Table `db_script_string` not have string id  %u", be.textid[i]);
                        continue;
                    }
                }
            }

            // save memory by not storing empty behaviors
            if(!be.isEmpty())
            {
                node.behavior   = new WaypointBehavior(be);
                ++total_behaviors;
            }
            else
                node.behavior   = NULL;
            bar.step();
        } while( result->NextRow() );
        delete result;
    }
    sLog.outString( ">> Loaded %u paths, %u nodes and %u behaviors", total_paths, total_nodes, total_behaviors);
}
예제 #2
0
void WaypointManager::Load()
{
    Cleanup();

    uint32 total_paths = 0;
    uint32 total_nodes = 0;
    uint32 total_behaviors = 0;

    std::set<uint32> movementScriptSet;

    for (ScriptMapMap::const_iterator itr = sCreatureMovementScripts.second.begin(); itr != sCreatureMovementScripts.second.end(); ++itr)
        movementScriptSet.insert(itr->first);

    // creature_movement
    QueryResult* result = WorldDatabase.Query("SELECT id, COUNT(point) FROM creature_movement GROUP BY id");

    if (!result)
    {
        BarGoLink bar(1);
        bar.step();
        sLog.outString();
        sLog.outString(">> Loaded 0 paths. DB table `creature_movement` is empty.");
    }
    else
    {
        total_paths = (uint32)result->GetRowCount();
        BarGoLink bar(total_paths);

        do
        {
            bar.step();
            Field* fields   = result->Fetch();

            uint32 id       = fields[0].GetUInt32();
            uint32 count    = fields[1].GetUInt32();

            m_pathMap[id].resize(count);
            total_nodes += count;
        }
        while (result->NextRow());

        sLog.outString();
        sLog.outString(">> Paths loaded");

        delete result;

        //                                   0   1      2           3           4           5         6
        result = WorldDatabase.Query("SELECT id, point, position_x, position_y, position_z, waittime, script_id,"
                                     //   7        8        9        10       11       12     13     14           15      16
                                     "textid1, textid2, textid3, textid4, textid5, emote, spell, orientation, model1, model2 FROM creature_movement");

        BarGoLink barRow((int)result->GetRowCount());

        // error after load, we check if creature guid corresponding to the path id has proper MovementType
        std::set<uint32> creatureNoMoveType;

        do
        {
            barRow.step();
            Field* fields = result->Fetch();
            uint32 id           = fields[0].GetUInt32();
            uint32 point        = fields[1].GetUInt32();

            const CreatureData* cData = sObjectMgr.GetCreatureData(id);

            if (!cData)
            {
                sLog.outErrorDb("Table creature_movement contain path for creature guid %u, but this creature guid does not exist. Skipping.", id);
                continue;
            }

            if (cData->movementType != WAYPOINT_MOTION_TYPE)
                creatureNoMoveType.insert(id);

            WaypointPath& path  = m_pathMap[id];

            // the cleanup queries make sure the following is true
            MANGOS_ASSERT(point >= 1 && point <= path.size());

            WaypointNode& node  = path[point-1];

            node.x              = fields[2].GetFloat();
            node.y              = fields[3].GetFloat();
            node.z              = fields[4].GetFloat();
            node.orientation    = fields[14].GetFloat();
            node.delay          = fields[5].GetUInt32();
            node.script_id      = fields[6].GetUInt32();

            // prevent using invalid coordinates
            if (!MaNGOS::IsValidMapCoord(node.x, node.y, node.z, node.orientation))
            {
                QueryResult* result1 = WorldDatabase.PQuery("SELECT id, map FROM creature WHERE guid = '%u'", id);
                if (result1)
                    sLog.outErrorDb("Creature (guidlow %d, entry %d) have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
                                    id, result1->Fetch()[0].GetUInt32(), point, node.x, node.y);
                else
                    sLog.outErrorDb("Waypoint path %d, have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
                                    id, point, node.x, node.y);

                MaNGOS::NormalizeMapCoord(node.x);
                MaNGOS::NormalizeMapCoord(node.y);

                if (result1)
                {
                    node.z = sTerrainMgr.LoadTerrain(result1->Fetch()[1].GetUInt32())->GetHeightStatic(node.x, node.y, node.z);
                    delete result1;
                }

                WorldDatabase.PExecute("UPDATE creature_movement SET position_x = '%f', position_y = '%f', position_z = '%f' WHERE id = '%u' AND point = '%u'", node.x, node.y, node.z, id, point);
            }

            if (node.script_id)
            {
                if (sCreatureMovementScripts.second.find(node.script_id) == sCreatureMovementScripts.second.end())
                {
                    sLog.outErrorDb("Table creature_movement for id %u, point %u have script_id %u that does not exist in `dbscripts_on_creature_movement`, ignoring", id, point, node.script_id);
                    continue;
                }

                movementScriptSet.erase(node.script_id);
            }

            // WaypointBehavior can be dropped in time. Script_id added may 2010 and can handle all the below behavior.

            WaypointBehavior be;
            be.model1           = fields[15].GetUInt32();
            be.model2           = fields[16].GetUInt32();
            be.emote            = fields[12].GetUInt32();
            be.spell            = fields[13].GetUInt32();

            for (int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
            {
                be.textid[i]    = fields[7 + i].GetInt32();

                if (be.textid[i])
                {
                    if (be.textid[i] < MIN_DB_SCRIPT_STRING_ID || be.textid[i] >= MAX_DB_SCRIPT_STRING_ID)
                    {
                        sLog.outErrorDb("Table `creature_movement` Id %u, point %u has textid%u has value %d out of range. Must be in %u-%u", id, point, i + 1, be.textid[i], MIN_DB_SCRIPT_STRING_ID, MAX_DB_SCRIPT_STRING_ID - 1);
                        be.textid[i] = 0;
                    }
                }
            }

            if (be.spell && ! sSpellStore.LookupEntry(be.spell))
            {
                sLog.outErrorDb("Table creature_movement references unknown spellid %u. Skipping id %u with point %u.", be.spell, id, point);
                be.spell = 0;
            }

            if (be.emote)
            {
                if (!sEmotesStore.LookupEntry(be.emote))
                    sLog.outErrorDb("Waypoint path %u (Point %u) are using emote %u, but emote does not exist.", id, point, be.emote);
            }

            // save memory by not storing empty behaviors
            if (!be.isEmpty())
            {
                node.behavior = new WaypointBehavior(be);
                ++total_behaviors;
            }
            else
                node.behavior = NULL;
        }
        while (result->NextRow());

        if (!creatureNoMoveType.empty())
        {
            for (std::set<uint32>::const_iterator itr = creatureNoMoveType.begin(); itr != creatureNoMoveType.end(); ++itr)
            {
                const CreatureData* cData = sObjectMgr.GetCreatureData(*itr);
                const CreatureInfo* cInfo = ObjectMgr::GetCreatureTemplate(cData->id);

                sLog.outErrorDb("Table creature_movement has waypoint for creature guid %u (entry %u), but MovementType is not WAYPOINT_MOTION_TYPE(2). Creature will not use this path.", *itr, cData->id);

                if (cInfo->MovementType == WAYPOINT_MOTION_TYPE)
                    sLog.outErrorDb("    creature_template for this entry has MovementType WAYPOINT_MOTION_TYPE(2), did you intend to use creature_movement_template ?");
            }
        }

        sLog.outString();
        sLog.outString(">> Waypoints and behaviors loaded");
        sLog.outString();
        sLog.outString(">>> Loaded %u paths, %u nodes and %u behaviors", total_paths, total_nodes, total_behaviors);

        delete result;
    }

    // creature_movement_template
    result = WorldDatabase.Query("SELECT entry, COUNT(point) FROM creature_movement_template GROUP BY entry");

    if (!result)
    {
        BarGoLink bar(1);
        bar.step();
        sLog.outString();
        sLog.outString(">> Loaded 0 path templates. DB table `creature_movement_template` is empty.");
    }
    else
    {
        total_nodes = 0;
        total_behaviors = 0;
        total_paths = (uint32)result->GetRowCount();
        BarGoLink barRow(total_paths);

        do
        {
            barRow.step();
            Field* fields = result->Fetch();

            uint32 entry    = fields[0].GetUInt32();
            uint32 count    = fields[1].GetUInt32();

            m_pathTemplateMap[entry].resize(count);
            total_nodes += count;
        }
        while (result->NextRow());

        delete result;

        sLog.outString();
        sLog.outString(">> Path templates loaded");

        //                                   0      1      2           3           4           5         6
        result = WorldDatabase.Query("SELECT entry, point, position_x, position_y, position_z, waittime, script_id,"
                                     //   7        8        9        10       11       12     13     14           15      16
                                     "textid1, textid2, textid3, textid4, textid5, emote, spell, orientation, model1, model2 FROM creature_movement_template");

        BarGoLink bar(result->GetRowCount());

        do
        {
            bar.step();
            Field* fields = result->Fetch();

            uint32 entry        = fields[0].GetUInt32();
            uint32 point        = fields[1].GetUInt32();

            const CreatureInfo* cInfo = ObjectMgr::GetCreatureTemplate(entry);

            if (!cInfo)
            {
                sLog.outErrorDb("Table creature_movement_template references unknown creature template %u. Skipping.", entry);
                continue;
            }

            WaypointPath& path  = m_pathTemplateMap[entry];

            // the cleanup queries make sure the following is true
            MANGOS_ASSERT(point >= 1 && point <= path.size());

            WaypointNode& node  = path[point-1];

            node.x              = fields[2].GetFloat();
            node.y              = fields[3].GetFloat();
            node.z              = fields[4].GetFloat();
            node.orientation    = fields[14].GetFloat();
            node.delay          = fields[5].GetUInt32();
            node.script_id      = fields[6].GetUInt32();

            // prevent using invalid coordinates
            if (!MaNGOS::IsValidMapCoord(node.x, node.y, node.z, node.orientation))
            {
                sLog.outErrorDb("Table creature_movement_template for entry %u (point %u) are using invalid coordinates position_x: %f, position_y: %f)",
                                entry, point, node.x, node.y);

                MaNGOS::NormalizeMapCoord(node.x);
                MaNGOS::NormalizeMapCoord(node.y);

                sLog.outErrorDb("Table creature_movement_template for entry %u (point %u) are auto corrected to normalized position_x=%f, position_y=%f",
                                entry, point, node.x, node.y);

                WorldDatabase.PExecute("UPDATE creature_movement_template SET position_x = '%f', position_y = '%f' WHERE entry = %u AND point = %u", node.x, node.y, entry, point);
            }

            if (node.script_id)
            {
                if (sCreatureMovementScripts.second.find(node.script_id) == sCreatureMovementScripts.second.end())
                {
                    sLog.outErrorDb("Table creature_movement_template for entry %u, point %u have script_id %u that does not exist in `dbscripts_on_creature_movement`, ignoring", entry, point, node.script_id);
                    continue;
                }

                movementScriptSet.erase(node.script_id);
            }

            WaypointBehavior be;
            be.model1           = fields[15].GetUInt32();
            be.model2           = fields[16].GetUInt32();
            be.emote            = fields[12].GetUInt32();
            be.spell            = fields[13].GetUInt32();

            for (int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
            {
                be.textid[i]    = fields[7+i].GetUInt32();

                if (be.textid[i])
                {
                    if (be.textid[i] < MIN_DB_SCRIPT_STRING_ID || be.textid[i] >= MAX_DB_SCRIPT_STRING_ID)
                    {
                        sLog.outErrorDb("Table `creature_movement_template` Entry %u, point %u has textid%u has value %d out of range. Must be in %u-%u", entry, point, i + 1, be.textid[i], MIN_DB_SCRIPT_STRING_ID, MAX_DB_SCRIPT_STRING_ID - 1);
                        be.textid[i] = 0;
                    }
                }
            }

            if (be.spell && ! sSpellStore.LookupEntry(be.spell))
            {
                sLog.outErrorDb("Table creature_movement_template references unknown spellid %u. Skipping id %u with point %u.", be.spell, entry, point);
                be.spell = 0;
            }

            if (be.emote)
            {
                if (!sEmotesStore.LookupEntry(be.emote))
                    sLog.outErrorDb("Waypoint template path %u (point %u) are using emote %u, but emote does not exist.", entry, point, be.emote);
            }

            // save memory by not storing empty behaviors
            if (!be.isEmpty())
            {
                node.behavior   = new WaypointBehavior(be);
                ++total_behaviors;
            }
            else
                node.behavior   = NULL;
        }
        while (result->NextRow());

        delete result;

        sLog.outString();
        sLog.outString(">> Waypoint templates loaded");
        sLog.outString();
        sLog.outString(">>> Loaded %u path templates with %u nodes and %u behaviors", total_paths, total_nodes, total_behaviors);
    }

    if (!movementScriptSet.empty())
    {
        for (std::set<uint32>::const_iterator itr = movementScriptSet.begin(); itr != movementScriptSet.end(); ++itr)
            sLog.outErrorDb("Table `dbscripts_on_creature_movement` contain unused script, id %u.", *itr);
    }
}
예제 #3
0
void WaypointManager::Load()
{
    Cleanup();

    uint32 total_paths = 0;
    uint32 total_nodes = 0;
    uint32 total_behaviors = 0;

    QueryResult *result = WorldDatabase.Query("SELECT id, COUNT(point) FROM creature_movement GROUP BY id");

    if(!result)
    {
        barGoLink bar(1);
        bar.step();
        sLog.outString();
        sLog.outString( ">> Loaded 0 paths. DB table `creature_movement` is empty." );
        return;
    } else {
        total_paths = result->GetRowCount();
        barGoLink bar( total_paths );
        do
        {
            bar.step();
            Field *fields = result->Fetch();
            uint32 id    = fields[0].GetUInt32();
            uint32 count = fields[1].GetUInt32();
            m_pathMap[id].resize(count);
            total_nodes += count;
        } while( result->NextRow() );
        delete result;

        sLog.outString();
        sLog.outString( ">> Paths loaded" );
    }

    //                                   0           1           2           3            4       5
    result = WorldDatabase.Query("SELECT position_x, position_y, position_z, orientation, model1, model2,"
    //   6         7      8      9        10       11       12       13       14  15
        "waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id, point FROM creature_movement");

    barGoLink bar( result->GetRowCount() );
    do
    {
        bar.step();
        Field *fields = result->Fetch();
        uint32 point        = fields[15].GetUInt32();
        uint32 id           = fields[14].GetUInt32();
        if (!sObjectMgr.GetCreatureData(id))
        {
            sLog.outErrorDb("Table creature_movement references unknown creature %u. Deleted.", id);
			WorldDatabase.PExecute("DELETE FROM creature_movement where id=%u",id);
            continue;
        }

        WaypointPath &path  = m_pathMap[id];
        // the cleanup queries make sure the following is true
        ASSERT(point >= 1 && point <= path.size());
        WaypointNode &node  = path[point-1];

        node.x              = fields[0].GetFloat();
        node.y              = fields[1].GetFloat();
        node.z              = fields[2].GetFloat();
        node.orientation    = fields[3].GetFloat();
        node.delay          = fields[6].GetUInt32();

        // prevent using invalid coordinates
        if(!MaNGOS::IsValidMapCoord(node.x, node.y, node.z, node.orientation))
        {
            QueryResult *result1 = WorldDatabase.PQuery("SELECT id, map FROM creature WHERE guid = '%u'", id);
            if(result1)
                sLog.outErrorDb("Creature (guidlow %d, entry %d) have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
                    id, result1->Fetch()[0].GetUInt32(), point, node.x, node.y);
            else
                sLog.outErrorDb("Waypoint path %d, have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
                    id, point, node.x, node.y);

            MaNGOS::NormalizeMapCoord(node.x);
            MaNGOS::NormalizeMapCoord(node.y);
            if(result1)
            {
                node.z = MapManager::Instance ().CreateBaseMap(result1->Fetch()[1].GetUInt32())->GetHeight(node.x, node.y, node.z);
                delete result1;
            }
            WorldDatabase.PExecute("UPDATE creature_movement SET position_x = '%f', position_y = '%f', position_z = '%f' WHERE id = '%u' AND point = '%u'", node.x, node.y, node.z, id, point);
        }
        WaypointBehavior be;
        be.model1           = fields[4].GetUInt32();
        be.model2           = fields[5].GetUInt32();
        be.emote            = fields[7].GetUInt32();
        be.spell            = fields[8].GetUInt32();
        for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
        {
            be.textid[i]        = fields[9+i].GetUInt32();
            if(be.textid[i])
            {
                if (be.textid[i] < MIN_DB_SCRIPT_STRING_ID || be.textid[i] >= MAX_DB_SCRIPT_STRING_ID)
                {
                    sLog.outErrorDb( "Table `db_script_string` not have string id  %u", be.textid[i]);
                    continue;
                }
            }
        }

        if (be.spell && ! sSpellStore.LookupEntry(be.spell))
        {
            sLog.outErrorDb("Table creature_movement references unknown spellid %u. Skipping id %u with point %u.", be.spell, id, point);
            be.spell = 0;
        }

        if (be.emote)
        {
            if (!sEmotesStore.LookupEntry(be.emote))
                sLog.outErrorDb("Waypoint path %u (Point %u) are using emote %u, but emote does not exist.",id, point, be.emote);
        }

        // save memory by not storing empty behaviors
        if(!be.isEmpty())
        {
            node.behavior   = new WaypointBehavior(be);
            ++total_behaviors;
        }
        else
            node.behavior   = NULL;
    } while( result->NextRow() );
    delete result;

    sLog.outString();
    sLog.outString( ">> Waypoints and behaviors loaded" );
    sLog.outString();
    sLog.outString( ">>> Loaded %u paths, %u nodes and %u behaviors", total_paths, total_nodes, total_behaviors);
}