bool World::createDynamicNPC(const std::string &name, TYPE_OF_RACE_ID type, const position &pos, /*CCharacter::face_to dir,*/ Character::sex_type sex, const std::string &scriptname) {
    try {

        try {
            NPC *newNPC = new NPC(DYNNPC_BASE, name, type, pos, (Character::face_to)4/*dir*/, false, sex, {});

            // add npc to npc list
            Npc.insert(newNPC);

            try {
                // try to load the script
                std::shared_ptr<LuaNPCScript> script(new LuaNPCScript(scriptname, newNPC));
                newNPC->setScript(script);
            } catch (ScriptException &e) {
                Logger::error(LogFacility::Script) << "World::createDynamicNPC: Error while loading dynamic NPC script: " << scriptname << ": " << e.what() << Log::end;
            }
        } catch (FieldNotFound &) {
            Logger::error(LogFacility::Script) << "World::createDynamicNPC: No space available for dynamic NPC: " << name << " near " << pos << Log::end;
        }

        return true;
    } catch (...) {
        Logger::error(LogFacility::Script) << "World::createDynamicNPC: Unknown error while loading dynamic NPC: " << name << Log::end;
        return false;
    }
}
Example #2
0
void NPCTable::reload() {
    try {
        Database::SelectQuery query;
        query.addColumn("npc", "npc_id");
        query.addColumn("npc", "npc_type");
        query.addColumn("npc", "npc_posx");
        query.addColumn("npc", "npc_posy");
        query.addColumn("npc", "npc_posz");
        query.addColumn("npc", "npc_name");
        query.addColumn("npc", "npc_faceto");
        query.addColumn("npc", "npc_is_healer");
        query.addColumn("npc", "npc_script");
        query.addColumn("npc", "npc_sex");
        query.addColumn("npc", "npc_hair");
        query.addColumn("npc", "npc_beard");
        query.addColumn("npc", "npc_hairred");
        query.addColumn("npc", "npc_hairgreen");
        query.addColumn("npc", "npc_hairblue");
        query.addColumn("npc", "npc_skinred");
        query.addColumn("npc", "npc_skingreen");
        query.addColumn("npc", "npc_skinblue");
        query.addServerTable("npc");
        query.addOrderBy("npc", "npc_id", Database::SelectQuery::ASC);

        Database::Result results = query.execute();

        if (!results.empty()) {
            auto questNodes = QuestNodeTable::getInstance().getNpcNodes();
            auto questItr = questNodes.first;
            auto questEnd = questNodes.second;

            for (const auto &row : results) {
                NPC *newNPC = nullptr;
                TYPE_OF_CHARACTER_ID npcID = 0;
                std::string npcName;

                try {
                    npcID = row["npc_id"].as<TYPE_OF_CHARACTER_ID>();

                    const position pos(
                        row["npc_posx"].as<int16_t>(),
                        row["npc_posy"].as<int16_t>(),
                        row["npc_posz"].as<int16_t>()
                    );

                    npcName = row["npc_name"].as<std::string>();

                    Character::appearance appearance;
                    appearance.hairtype = uint8_t(row["npc_hair"].as<int16_t>());
                    appearance.beardtype = uint8_t(row["npc_hair"].as<int16_t>());
                    appearance.hair = {
                        uint8_t(row["npc_hairred"].as<int16_t>()),
                        uint8_t(row["npc_hairgreen"].as<int16_t>()),
                        uint8_t(row["npc_hairblue"].as<int16_t>())
                    };
                    appearance.skin = {
                        (uint8_t)(row["npc_skinred"].as<int16_t>()),
                        (uint8_t)(row["npc_skingreen"].as<int16_t>()),
                        (uint8_t)(row["npc_skinblue"].as<int16_t>())
                    };

                    newNPC = new NPC(
                        npcID, npcName,
                        row["npc_type"].as<TYPE_OF_RACE_ID>(),
                        pos,
                        Character::face_to(row["npc_faceto"].as<uint32_t>()),
                        row["npc_is_healer"].as<bool>(),
                        Character::sex_type(row["npc_sex"].as<uint32_t>()),
                        appearance);

                    // add npc to npc list
                    _world->Npc.insert(newNPC);

                    // set field to occupied
                    Field *tempf;

                    if (_world->GetPToCFieldAt(tempf, pos)) {
                        tempf->setChar();
                    }

                    if (!row["npc_script"].is_null()) {
                        const std::string scriptname = row["npc_script"].as<std::string>();

                        try {
                            std::shared_ptr<LuaNPCScript> script(new LuaNPCScript(scriptname, newNPC));

                            while (questItr != questEnd && questItr->first == npcID) {
                                script->addQuestScript(questItr->second.entrypoint, questItr->second.script);
                                ++questItr;
                            }

                            newNPC->setScript(script);
                        } catch (ScriptException &e) {
                            Logger::error(LogFacility::Script) << "Error while loading npc script: " << scriptname << ": " << e.what() << Log::end;
                        }
                    }

                    newNPC = nullptr;
                } catch (NoSpace &s) {
                    Logger::error(LogFacility::Other) << "No space available for NPC " << npcName << "(" << npcID << "): " << s.what() << Log::end;
                }

                delete newNPC;
            }

        }

        m_dataOK = true;
    } catch (...) {
        Logger::error(LogFacility::Other) << "Error while loading NPCs" << Log::end;
        m_dataOK = false;
    }
}