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; } }
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; } }