diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b372e40b..e4706ccd9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ include (OpenMWMacros) # Version set (OPENMW_VERSION_MAJOR 0) -set (OPENMW_VERSION_MINOR 13) +set (OPENMW_VERSION_MINOR 14) set (OPENMW_VERSION_RELEASE 0) set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}") @@ -27,6 +27,11 @@ configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_ option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE) option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE) +# Apps and tools +option(BUILD_ESMTOOL "build ESM inspector" ON) +option(BUILD_LAUNCHER "build Launcher" ON) +option(BUILD_MWINIIMPORTER "build MWiniImporter" ON) + # Sound source selection option(USE_FFMPEG "use ffmpeg for sound" OFF) option(USE_AUDIERE "use audiere for sound" OFF) @@ -117,10 +122,11 @@ set(OENGINE_BULLET ${LIBDIR}/openengine/bullet/physic.hpp ${LIBDIR}/openengine/bullet/BulletShapeLoader.cpp ${LIBDIR}/openengine/bullet/BulletShapeLoader.h - ${LIBDIR}/openengine/bullet/pmove.h - ${LIBDIR}/openengine/bullet/pmove.cpp - ${LIBDIR}/openengine/bullet/trace.h - ${LIBDIR}/openengine/bullet/trace.cpp + ${LIBDIR}/openengine/bullet/pmove.cpp + ${LIBDIR}/openengine/bullet/pmove.h + ${LIBDIR}/openengine/bullet/trace.cpp + ${LIBDIR}/openengine/bullet/trace.h + ) set(OENGINE_ALL ${OENGINE_OGRE} ${OENGINE_GUI} ${OENGINE_BULLET}) @@ -208,16 +214,16 @@ include_directories("." link_directories(${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR}) -if(APPLE) +if (APPLE) # List used Ogre plugins - SET(USED_OGRE_PLUGINS "RenderSystem_GL" - "Plugin_OctreeSceneManager" - "Plugin_CgProgramManager" - "Plugin_ParticleFX") -endif(APPLE) + SET(USED_OGRE_PLUGINS ${OGRE_RenderSystem_GL_LIBRARY_REL} + ${OGRE_Plugin_OctreeSceneManager_LIBRARY_REL} + ${OGRE_Plugin_CgProgramManager_LIBRARY_REL} + ${OGRE_Plugin_ParticleFX_LIBRARY_REL}) +endif (APPLE) -add_subdirectory( files/) -add_subdirectory( files/mygui ) +add_subdirectory(files/) +add_subdirectory(files/mygui) # Specify build paths @@ -248,37 +254,42 @@ endif (WIN32) if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.linux "${OpenMW_BINARY_DIR}/plugins.cfg") + + configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop + "${OpenMW_BINARY_DIR}/openmw.desktop") endif() if (APPLE) + if (${OGRE_PLUGIN_DIR_REL}}) + set(OGRE_PLUGINS_REL_FOUND TRUE) + endif () + + if (${OGRE_PLUGIN_DIR_DBG}) + set(OGRE_PLUGINS_DBG_FOUND TRUE) + endif () + + if (${OGRE_PLUGINS_REL_FOUND}) + set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL}) + else () + set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_DBG}) + endif () + + set(OGRE_PLUGIN_DIR "${OGRE_PLUGIN_DIR}/") + configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.mac "${OpenMW_BINARY_DIR}/plugins.cfg") + set(OGRE_PLUGIN_DIR_2 ${OGRE_PLUGIN_DIR}) + set(OGRE_PLUGIN_DIR "") + configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.mac + "${OpenMW_BINARY_DIR}/plugins.cfg.install") + set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_2}) + configure_file(${OpenMW_SOURCE_DIR}/files/mac/Info.plist "${APP_BUNDLE_DIR}/Contents/Info.plist") configure_file(${OpenMW_SOURCE_DIR}/files/mac/openmw.icns "${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY) - - # prepare plugins - if (${CMAKE_BUILD_TYPE} MATCHES "Release") - set(OPENMW_RELEASE_BUILD 1) - endif() - if (${CMAKE_BUILD_TYPE} MATCHES "RelWithDebugInfo") - set(OPENMW_RELEASE_BUILD 1) - endif() - - if (${OPENMW_RELEASE_BUILD}) - set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL}) - else() - set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_DBG}) - endif() - - foreach(plugin ${USED_OGRE_PLUGINS}) - configure_file("${OGRE_PLUGIN_DIR}/${plugin}.dylib" - "${APP_BUNDLE_DIR}/Contents/Plugins/${plugin}.dylib" - COPYONLY) - endforeach() endif (APPLE) @@ -311,7 +322,7 @@ if(DPKG_PROGRAM) endif() #Install icon and desktop file - INSTALL(FILES "${OpenMW_SOURCE_DIR}/files/openmw.desktop" DESTINATION "share/applications/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") + INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.desktop" DESTINATION "share/applications/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "share/pixmaps/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw") #Install global configuration files @@ -356,7 +367,7 @@ if(WIN32) INSTALL(FILES ${files} DESTINATION ".") INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg") INSTALL(FILES - "${OpenMW_SOURCE_DIR}/readme.txt" + "${OpenMW_SOURCE_DIR}/readme.txt" "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION ".") INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION ".") @@ -417,17 +428,14 @@ add_subdirectory (components) # Apps and tools add_subdirectory( apps/openmw ) -option(BUILD_ESMTOOL "build ESM inspector" ON) if (BUILD_ESMTOOL) add_subdirectory( apps/esmtool ) endif() -option(BUILD_LAUNCHER "build Launcher inspector" ON) if (BUILD_LAUNCHER) add_subdirectory( apps/launcher ) endif() -option(BUILD_MWINIIMPORTER "build MWiniImporter inspector" ON) if (BUILD_MWINIIMPORTER) add_subdirectory( apps/mwiniimporter ) endif() @@ -519,10 +527,12 @@ if (APPLE) install(DIRECTORY "${APP_BUNDLE_DIR}" USE_SOURCE_PERMISSIONS DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) install(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) - - install(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) + install(FILES "${OpenMW_BINARY_DIR}/plugins.cfg.install" RENAME "plugins.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) install(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) + install(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) + install(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) + set(CPACK_GENERATOR "DragNDrop") set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION}) set(CPACK_PACKAGE_VERSION_MAJOR ${OPENMW_VERSION_MAJOR}) @@ -531,22 +541,25 @@ if (APPLE) set(APPS "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}") set(PLUGINS "") + set(ABSOLUTE_PLUGINS "") - # Scan Plugins dir for *.dylibs - set(PLUGIN_SEARCH_ROOT "${APP_BUNDLE_DIR}/Contents/Plugins") - file(GLOB_RECURSE ALL_PLUGINS "${PLUGIN_SEARCH_ROOT}/*.dylib") + foreach (PLUGIN ${USED_OGRE_PLUGINS}) + get_filename_component(PLUGIN_ABS ${PLUGIN} REALPATH) + set(ABSOLUTE_PLUGINS ${PLUGIN_ABS} ${ABSOLUTE_PLUGINS}) + endforeach () set(PLUGIN_INSTALL_BASE "\${CMAKE_INSTALL_PREFIX}/${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}/Contents/Plugins") - foreach(PLUGIN ${ALL_PLUGINS}) - string(REPLACE "${PLUGIN_SEARCH_ROOT}/" "" PLUGIN_RELATIVE "${PLUGIN}") + install(FILES ${ABSOLUTE_PLUGINS} DESTINATION "${INSTALL_SUBDIR}/${APP_BUNDLE_NAME}/Contents/Plugins" COMPONENT Runtime) + foreach (PLUGIN ${ABSOLUTE_PLUGINS}) + get_filename_component(PLUGIN_RELATIVE ${PLUGIN} NAME) set(PLUGINS ${PLUGINS} "${PLUGIN_INSTALL_BASE}/${PLUGIN_RELATIVE}") - endforeach() + endforeach () #For now, search unresolved dependencies only in default system paths, so if you put unresolveable (i.e. with @executable_path in id name) lib or framework somewhere else, it would fail set(DIRS "") # Overriding item resolving during installation, it needed if - # some library already has be "fixed up", i.e. its id name contains @executable_path, + # some library already has been "fixed up", i.e. its id name contains @executable_path, # but library is not embedded in bundle. For example, it's Ogre.framework from Ogre SDK. # Current implementation of GetPrerequsities/BundleUtilities doesn't handle that case. # @@ -564,17 +577,22 @@ if (APPLE) if (item MATCHES \"Frameworks\") # if it is a framework # get last segment of path get_filename_component(fname \"\${item}\" NAME_WE) - find_library(ri NAMES \${fname} PATHS \${exepath} \${dirs} /Library/Frameworks) + find_library(ri NAMES \${fname} PATHS \${exepath} \${dirs} \${CMAKE_SYSTEM_FRAMEWORK_PATH}) if (ri) - message(STATUS \"found \${ri} for \${item}\") string(REGEX REPLACE \"^.*/Frameworks/.*\\\\.framework\" \"\" item_part \${item}) set(ri \"\${ri}\${item_part}\") set(\${resolved_item_var} \${ri} PARENT_SCOPE) set(\${resolved_var} 1 PARENT_SCOPE) - set(OPENMW_RESOLVED_ITEMS \${_OPENMW_RESOLVED_ITEMS} \${ri}) endif() else() # code path for standard (non-framework) libs (ogre & qt pugins) + get_filename_component(fname \"\${item}\" NAME_WE) + string(REGEX REPLACE \"^lib\" \"\" fname \${fname}) + find_library(ri NAMES \${fname} PATHS \${exepath} \${dirs} /usr/lib /usr/local/lib) + if (ri) + set(\${resolved_item_var} \${ri} PARENT_SCOPE) + set(\${resolved_var} 1 PARENT_SCOPE) + endif () endif() endif() endfunction(gp_resolve_item_override) @@ -584,10 +602,5 @@ if (APPLE) include(BundleUtilities) fixup_bundle(\"${APPS}\" \"${PLUGINS}\" \"${DIRS}\") " COMPONENT Runtime) - -include(CPack) - -set(CMAKE_EXE_LINKER_FLAGS "-arch i386") -set(CMAKE_CXX_FLAGS "-arch i386") - + include(CPack) endif (APPLE) diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index 1fbc11c63..672a2b60a 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -89,7 +89,7 @@ namespace MWClass static const int sMapping[size][2] = { - { ESM::Clothing::Shirt, MWWorld::InventoryStore::Slot_Cuirass }, + { ESM::Clothing::Shirt, MWWorld::InventoryStore::Slot_Shirt }, { ESM::Clothing::Belt, MWWorld::InventoryStore::Slot_Belt }, { ESM::Clothing::Robe, MWWorld::InventoryStore::Slot_Robe }, { ESM::Clothing::Pants, MWWorld::InventoryStore::Slot_Pants }, diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index a5feba4b5..f6a8d0dbe 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -53,32 +53,40 @@ namespace MWClass // NPC stats if (!ref->base->faction.empty()) { - // TODO research how initial rank is stored. The information in loadnpc.hpp are at - // best very unclear. - data->mNpcStats.mFactionRank[ref->base->faction] = 0; + if(ref->base->npdt52.gold != -10) + { + data->mNpcStats.mFactionRank[ref->base->faction] = (int)ref->base->npdt52.rank; + } + else + { + data->mNpcStats.mFactionRank[ref->base->faction] = (int)ref->base->npdt12.rank; + } } - for (int i=0; i<27; ++i) - data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[i]); + if(ref->base->npdt52.gold != -10) + { + for (int i=0; i<27; ++i) + data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[i]); - for (std::vector::const_iterator iter (ref->base->spells.list.begin()); - iter!=ref->base->spells.list.end(); ++iter) - data->mCreatureStats.mSpells.add (*iter); + // creature stats + data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength); + data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence); + data->mCreatureStats.mAttributes[2].set (ref->base->npdt52.willpower); + data->mCreatureStats.mAttributes[3].set (ref->base->npdt52.agility); + data->mCreatureStats.mAttributes[4].set (ref->base->npdt52.speed); + data->mCreatureStats.mAttributes[5].set (ref->base->npdt52.endurance); + data->mCreatureStats.mAttributes[6].set (ref->base->npdt52.personality); + data->mCreatureStats.mAttributes[7].set (ref->base->npdt52.luck); + data->mCreatureStats.mDynamic[0].set (ref->base->npdt52.health); + data->mCreatureStats.mDynamic[1].set (ref->base->npdt52.mana); + data->mCreatureStats.mDynamic[2].set (ref->base->npdt52.fatigue); - // creature stats - data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength); - data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence); - data->mCreatureStats.mAttributes[2].set (ref->base->npdt52.willpower); - data->mCreatureStats.mAttributes[3].set (ref->base->npdt52.agility); - data->mCreatureStats.mAttributes[4].set (ref->base->npdt52.speed); - data->mCreatureStats.mAttributes[5].set (ref->base->npdt52.endurance); - data->mCreatureStats.mAttributes[6].set (ref->base->npdt52.personality); - data->mCreatureStats.mAttributes[7].set (ref->base->npdt52.luck); - data->mCreatureStats.mDynamic[0].set (ref->base->npdt52.health); - data->mCreatureStats.mDynamic[1].set (ref->base->npdt52.mana); - data->mCreatureStats.mDynamic[2].set (ref->base->npdt52.fatigue); - - data->mCreatureStats.mLevel = ref->base->npdt52.level; + data->mCreatureStats.mLevel = ref->base->npdt52.level; + } + else + { + //TODO: do something with npdt12 maybe:p + } // \todo add initial container content @@ -97,7 +105,10 @@ namespace MWClass void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { - renderingInterface.getActors().insertNPC(ptr); + + + renderingInterface.getActors().insertNPC(ptr, getInventoryStore(ptr)); + } void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const @@ -286,7 +297,7 @@ namespace MWClass void Npc::registerSelf() { boost::shared_ptr instance (new Npc); - + std::cout << "class npc:" << typeid (ESM::NPC).name(); registerClass (typeid (ESM::NPC).name(), instance); } } diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp index b06605cc2..90f0c0231 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanager.cpp @@ -39,6 +39,9 @@ #include "../mwscript/interpretercontext.hpp" #include +#include "../mwclass/npc.hpp" +#include "../mwmechanics/npcstats.hpp" + namespace { std::string toLower (const std::string& name) @@ -109,16 +112,15 @@ namespace switch (world.getGlobalVariableType (name)) { case 's': - - return selectCompare (comp, value, world.getGlobalVariable (name).mShort); + return selectCompare (comp, world.getGlobalVariable (name).mShort, value); case 'l': - return selectCompare (comp, value, world.getGlobalVariable (name).mLong); + return selectCompare (comp, world.getGlobalVariable (name).mLong, value); case 'f': - return selectCompare (comp, value, world.getGlobalVariable (name).mFloat); + return selectCompare (comp, world.getGlobalVariable (name).mFloat, value); case ' ': @@ -178,7 +180,17 @@ namespace MWDialogue break; case 46://Same faction - if(!selectCompare(comp,0,select.i)) return false; + { + MWMechanics::NpcStats PCstats = MWWorld::Class::get(mEnvironment.mWorld->getPlayer().getPlayer()).getNpcStats(mEnvironment.mWorld->getPlayer().getPlayer()); + MWMechanics::NpcStats NPCstats = MWWorld::Class::get(actor).getNpcStats(actor); + int sameFaction = 0; + if(!NPCstats.mFactionRank.empty()) + { + std::string NPCFaction = NPCstats.mFactionRank.begin()->first; + if(PCstats.mFactionRank.find(NPCFaction) != PCstats.mFactionRank.end()) sameFaction = 1; + } + if(!selectCompare(comp,sameFaction,select.i)) return false; + } break; case 48://Detected @@ -190,7 +202,6 @@ namespace MWDialogue break; case 50://choice - if(choice) { if(!selectCompare(comp,mChoice,select.i)) return false; @@ -270,7 +281,7 @@ namespace MWDialogue { case '1': // function - return true; // TODO implement functions + return true; // Done elsewhere. case '2': // global @@ -444,9 +455,6 @@ namespace MWDialogue if (toLower (info.actor)!=MWWorld::Class::get (actor).getId (actor)) return false; - //PC Faction - if(!info.pcFaction.empty()) return false; - //NPC race if (!info.race.empty()) { @@ -474,26 +482,37 @@ namespace MWDialogue //NPC faction if (!info.npcFaction.empty()) { - ESMS::LiveCellRef *cellRef = actor.get(); - - if (!cellRef) - return false; - - if (toLower (info.npcFaction)!=toLower (cellRef->base->faction)) - return false; - - //check NPC rank - if(cellRef->base->npdt52.gold != -10) + //MWWorld::Class npcClass = MWWorld::Class::get(actor); + MWMechanics::NpcStats stats = MWWorld::Class::get(actor).getNpcStats(actor); + std::map::iterator it = stats.mFactionRank.find(info.npcFaction); + if(it!=stats.mFactionRank.end()) { - if(cellRef->base->npdt52.rank < info.data.rank) return false; + //check rank + if(it->second < (int)info.data.rank) return false; } else { - if(cellRef->base->npdt12.rank < info.data.rank) return false; + //not in the faction + return false; } } // TODO check player faction + if(!info.pcFaction.empty()) + { + MWMechanics::NpcStats stats = MWWorld::Class::get(mEnvironment.mWorld->getPlayer().getPlayer()).getNpcStats(mEnvironment.mWorld->getPlayer().getPlayer()); + std::map::iterator it = stats.mFactionRank.find(info.pcFaction); + if(it!=stats.mFactionRank.end()) + { + //check rank + if(it->second < (int)info.data.PCrank) return false; + } + else + { + //not in the faction + return false; + } + } //check gender ESMS::LiveCellRef* npc = actor.get(); @@ -658,6 +677,7 @@ namespace MWDialogue void DialogueManager::executeScript(std::string script) { + std::cout << script; std::vector code; if(compile(script,code)) { @@ -799,4 +819,19 @@ namespace MWDialogue mChoiceMap[question] = choice; mIsInChoice = true; } + + std::string DialogueManager::getFaction() + { + std::string factionID(""); + MWMechanics::NpcStats stats = MWWorld::Class::get(mActor).getNpcStats(mActor); + if(stats.mFactionRank.empty()) + { + std::cout << "No faction for this actor!"; + } + else + { + factionID = stats.mFactionRank.begin()->first; + } + return factionID; + } } diff --git a/apps/openmw/mwdialogue/dialoguemanager.hpp b/apps/openmw/mwdialogue/dialoguemanager.hpp index 260d8e339..d0380fa71 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.hpp +++ b/apps/openmw/mwdialogue/dialoguemanager.hpp @@ -63,6 +63,9 @@ namespace MWDialogue void askQuestion(std::string question,int choice); + ///get the faction of the actor you are talking with + std::string getFaction(); + //calbacks for the GUI void keywordSelected(std::string keyword); void goodbyeSelected(); diff --git a/apps/openmw/mwgui/layouts.cpp b/apps/openmw/mwgui/layouts.cpp index 6d8aa901b..21302d7c1 100644 --- a/apps/openmw/mwgui/layouts.cpp +++ b/apps/openmw/mwgui/layouts.cpp @@ -67,17 +67,8 @@ HUD::HUD(int width, int height, int fpsLevel) getWidget(crosshair, "Crosshair"); - if ( fpsLevel == 2 ){ - getWidget(fpsbox, "FPSBoxAdv"); - fpsbox->setVisible(true); - getWidget(fpscounter, "FPSCounterAdv"); - }else if ( fpsLevel == 1 ){ - getWidget(fpsbox, "FPSBox"); - fpsbox->setVisible(true); - getWidget(fpscounter, "FPSCounter"); - }else{ - getWidget(fpscounter, "FPSCounter"); - } + setFpsLevel(fpsLevel); + getWidget(trianglecounter, "TriangleCounter"); getWidget(batchcounter, "BatchCounter"); @@ -95,6 +86,28 @@ HUD::HUD(int width, int height, int fpsLevel) LocalMapBase::init(minimap, this); } +void HUD::setFpsLevel(int level) +{ + MyGUI::Widget* fps; + getWidget(fps, "FPSBoxAdv"); + fps->setVisible(false); + getWidget(fps, "FPSBox"); + fps->setVisible(false); + + if (level == 2) + { + getWidget(fpsbox, "FPSBoxAdv"); + fpsbox->setVisible(true); + getWidget(fpscounter, "FPSCounterAdv"); + } + else if (level == 1) + { + getWidget(fpsbox, "FPSBox"); + fpsbox->setVisible(true); + getWidget(fpscounter, "FPSCounter"); + } +} + void HUD::setFPS(float fps) { fpscounter->setCaption(boost::lexical_cast((int)fps)); diff --git a/apps/openmw/mwgui/layouts.hpp b/apps/openmw/mwgui/layouts.hpp index 0614708cf..19d96d2ef 100644 --- a/apps/openmw/mwgui/layouts.hpp +++ b/apps/openmw/mwgui/layouts.hpp @@ -78,6 +78,7 @@ namespace MWGui void setPlayerPos(const float x, const float y); void setBottomLeftVisibility(bool hmsVisible, bool weapVisible, bool spellVisible); void setBottomRightVisibility(bool effectBoxVisible, bool minimapVisible); + void setFpsLevel(const int level); MyGUI::ProgressPtr health, magicka, stamina; MyGUI::Widget *weapBox, *spellBox; diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index 13b6fab31..34d62ba08 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -15,6 +15,8 @@ #include "journalwindow.hpp" #include "charactercreation.hpp" +#include + #include #include #include @@ -472,3 +474,11 @@ void WindowManager::toggleFogOfWar() map->toggleFogOfWar(); hud->toggleFogOfWar(); } + +int WindowManager::toggleFps() +{ + showFPSLevel = (showFPSLevel+1)%3; + hud->setFpsLevel(showFPSLevel); + Settings::Manager::setInt("fps", "HUD", showFPSLevel); + return showFPSLevel; +} diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index f1db11731..2b53560ba 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -158,7 +158,10 @@ namespace MWGui void setPlayerDir(const float x, const float y); ///< set player view direction in map space void toggleFogOfWar(); - + + int toggleFps(); + ///< toggle fps display @return resulting fps level + void setInteriorMapTexture(const int x, const int y); ///< set the index of the map texture that should be used (for interiors) diff --git a/apps/openmw/mwinput/inputmanager.cpp b/apps/openmw/mwinput/inputmanager.cpp index c6841ae43..37eadc887 100644 --- a/apps/openmw/mwinput/inputmanager.cpp +++ b/apps/openmw/mwinput/inputmanager.cpp @@ -69,6 +69,8 @@ namespace MWInput A_ToggleWeapon, A_ToggleSpell, + A_ToggleFps, // Toggle FPS display (this is temporary) + A_LAST // Marker for the last item }; @@ -89,6 +91,11 @@ namespace MWInput /* InputImpl Methods */ + void toggleFps() + { + windows.toggleFps(); + } + void toggleSpell() { DrawState state = player.getDrawState(); @@ -236,6 +243,8 @@ namespace MWInput "Draw Weapon"); disp->funcs.bind(A_ToggleSpell,boost::bind(&InputImpl::toggleSpell,this), "Ready hands"); + disp->funcs.bind(A_ToggleFps, boost::bind(&InputImpl::toggleFps, this), + "Toggle FPS display"); // Add the exit listener ogre.getRoot()->addFrameListener(&exit); @@ -282,6 +291,7 @@ namespace MWInput disp->bind(A_ToggleWalk, KC_C); disp->bind(A_ToggleWeapon,KC_F); disp->bind(A_ToggleSpell,KC_R); + disp->bind(A_ToggleFps, KC_F10); // Key bindings for polled keys // NOTE: These keys are constantly being polled. Only add keys that must be checked each frame. diff --git a/apps/openmw/mwmechanics/drawstate.hpp b/apps/openmw/mwmechanics/drawstate.hpp index ded25f8d5..772086d90 100644 --- a/apps/openmw/mwmechanics/drawstate.hpp +++ b/apps/openmw/mwmechanics/drawstate.hpp @@ -1,6 +1,8 @@ #ifndef GAME_MWMECHANICS_DRAWSTATE_H #define GAME_MWMECHANICS_DRAWSTATE_H +#undef DrawState + enum DrawState { DrawState_Weapon = 0, diff --git a/apps/openmw/mwrender/actors.cpp b/apps/openmw/mwrender/actors.cpp index 6eb4a182b..5034e72b3 100644 --- a/apps/openmw/mwrender/actors.cpp +++ b/apps/openmw/mwrender/actors.cpp @@ -20,10 +20,10 @@ Actors::~Actors(){ void Actors::setMwRoot(Ogre::SceneNode* root){ mMwRoot = root; } -void Actors::insertNPC(const MWWorld::Ptr& ptr){ +void Actors::insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv){ insertBegin(ptr, true, true); - NpcAnimation* anim = new MWRender::NpcAnimation(ptr, mEnvironment, mRend); + NpcAnimation* anim = new MWRender::NpcAnimation(ptr, mEnvironment, mRend, inv); mAllActors[ptr] = anim; } diff --git a/apps/openmw/mwrender/actors.hpp b/apps/openmw/mwrender/actors.hpp index d49c6e0f8..66c98c541 100644 --- a/apps/openmw/mwrender/actors.hpp +++ b/apps/openmw/mwrender/actors.hpp @@ -34,7 +34,7 @@ namespace MWRender{ void setMwRoot(Ogre::SceneNode* root); void insertBegin (const MWWorld::Ptr& ptr, bool enabled, bool static_); void insertCreature (const MWWorld::Ptr& ptr); - void insertNPC(const MWWorld::Ptr& ptr); + void insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv); bool deleteObject (const MWWorld::Ptr& ptr); ///< \return found? diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index fb710443b..5755418e2 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -9,7 +9,6 @@ namespace MWRender{ , mRend(_rend) , mEnvironment(_env) , vecRotPos() - , shapeparts() , time(0.0f) , startTime(0.0f) , stopTime(0.0f) @@ -19,7 +18,6 @@ namespace MWRender{ , shapeNumber(0) , shapeIndexI() , shapes(NULL) - , entityparts() , transformations(NULL) , textmappings(NULL) , base(NULL) @@ -305,8 +303,8 @@ namespace MWRender{ for(; boneSequenceIter != boneSequence.end(); boneSequenceIter++) { - if(creaturemodel->getSkeleton()->hasBone(*boneSequenceIter)){ - Ogre::Bone *bonePtr = creaturemodel->getSkeleton()->getBone(*boneSequenceIter); + if(skel->hasBone(*boneSequenceIter)){ + Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter); // Computes C = B + AxC*scale transmult = transmult + rotmult * bonePtr->getPosition(); rotmult = rotmult * bonePtr->getOrientation(); @@ -430,14 +428,7 @@ namespace MWRender{ //base->_updateAnimation(); //base->_notifyMoved(); - for(unsigned int i = 0; i < entityparts.size(); i++){ - //Ogre::SkeletonInstance* skel = entityparts[i]->getSkeleton(); - - //Ogre::Bone* b = skel->getRootBone(); - //b->setOrientation(Ogre::Real(.3),Ogre::Real(.3),Ogre::Real(.3), Ogre::Real(.3));//This is a trick - - //entityparts[i]->getAllAnimationStates()->_notifyDirty(); - } + std::vector::iterator iter; diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 7692c7128..98f0e7487 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -31,7 +31,7 @@ class Animation{ - std::vector* > shapeparts; //All the NiTriShape data that we need for animating an npc + float time; float startTime; @@ -48,7 +48,7 @@ class Animation{ //Ogre::SkeletonInstance* skel; std::vector* shapes; //All the NiTriShapeData for a creature - std::vector entityparts; + std::vector* transformations; diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 9de5705e3..751a07548 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -3,6 +3,7 @@ #include "renderconst.hpp" + using namespace Ogre; using namespace NifOgre; namespace MWRender{ @@ -11,9 +12,49 @@ NpcAnimation::~NpcAnimation(){ } -NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend): Animation(_env,_rend){ +NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv): Animation(_env,_rend), mStateID(-1), inv(_inv), timeToChange(0), + robe(inv.end()), helmet(inv.end()), shirt(inv.end()), + cuirass(inv.end()), greaves(inv.end()), + leftpauldron(inv.end()), rightpauldron(inv.end()), + boots(inv.end()), + leftglove(inv.end()), rightglove(inv.end()), skirtiter(inv.end()), + pants(inv.end()), + lclavicle(0), + rclavicle(0), + rupperArm(0), + lupperArm(0), + rUpperLeg(0), + lUpperLeg(0), + lForearm(0), + rForearm(0), + lWrist(0), + rWrist(0), + rKnee(0), + lKnee(0), + neck(0), + rAnkle(0), + lAnkle(0), + groin(0), + lfoot(0), + rfoot(0) + { ESMS::LiveCellRef *ref = ptr.get(); + Ogre::Entity* blank = 0; + std::vector* blankshape = 0; + zero = std::make_pair(blank, blankshape); + chest = std::make_pair(blank, blankshape); + tail = std::make_pair(blank, blankshape); + lFreeFoot = std::make_pair(blank, blankshape); + rFreeFoot = std::make_pair(blank, blankshape); + rhand = std::make_pair(blank, blankshape); + lhand = std::make_pair(blank, blankshape); + skirt = std::make_pair(blank, blankshape); + for (int init = 0; init < 27; init++){ + partslots[init] = -1; //each slot is empty + partpriorities[init] = 0; + } + //Part selection on last character of the file string // " Tri Chest @@ -35,16 +76,22 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O std::string hairID = ref->base->hair; std::string headID = ref->base->head; - std::string npcName = ref->base->name; + headModel = "meshes\\" + + mEnvironment.mWorld->getStore().bodyParts.find(headID)->model; + + hairModel = "meshes\\" + + mEnvironment.mWorld->getStore().bodyParts.find(hairID)->model; + npcName = ref->base->name; + //ESMStore::Races r = const ESM::Race* race = mEnvironment.mWorld->getStore().races.find(ref->base->race); - std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); + bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); char secondtolast = bodyRaceID.at(bodyRaceID.length() - 2); - bool female = tolower(secondtolast) == 'f'; + isFemale = tolower(secondtolast) == 'f'; std::transform(bodyRaceID.begin(), bodyRaceID.end(), bodyRaceID.begin(), ::tolower); - bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_"; + isBeast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_"; /*std::cout << "Race: " << ref->base->race ; if(female){ @@ -57,7 +104,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O std::string smodel = "meshes\\base_anim.nif"; - if(beast) + if(isBeast) smodel = "meshes\\base_animkna.nif"; insert = ptr.getRefData().getBaseNode(); @@ -66,6 +113,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O NifOgre::NIFLoader::load(smodel); base = mRend.getScene()->createEntity(smodel); + base->setVisibilityFlags(RV_Actors); bool transparent = false; for (unsigned int i=0; igetNumSubEntities(); ++i) @@ -87,6 +135,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O } base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); + base->setSkipAnimationStateUpdate(true); //Magical line of code, this makes the bones //stay in the same place when we skipanim, or open a gui window @@ -105,168 +154,413 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O textmappings = NIFLoader::getSingletonPtr()->getTextIndices(smodel); insert->attachObject(base); - if(female) + + if(isFemale) insert->scale(race->data.height.female, race->data.height.female, race->data.height.female); else insert->scale(race->data.height.male, race->data.height.male, race->data.height.male); - std::string headModel = "meshes\\" + - mEnvironment.mWorld->getStore().bodyParts.find(headID)->model; + std::cout << "Inv" << inv.getStateId() << "\n"; + updateParts(); - std::string hairModel = "meshes\\" + - mEnvironment.mWorld->getStore().bodyParts.find(hairID)->model; - const ESM::BodyPart *chest = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "chest"); - const ESM::BodyPart *upperleg = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper leg"); - const ESM::BodyPart *groin = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "groin"); - const ESM::BodyPart *arml = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper arm"); //We need two - const ESM::BodyPart *neck = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "neck"); - const ESM::BodyPart *knee = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "knee"); - const ESM::BodyPart *ankle = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "ankle"); - const ESM::BodyPart *foot = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "foot"); - const ESM::BodyPart *feet = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "feet"); - const ESM::BodyPart *tail = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "tail"); - const ESM::BodyPart *wristl = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "wrist"); //We need two - const ESM::BodyPart *forearml = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "forearm"); //We need two - const ESM::BodyPart *handl = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hand"); //We need two - const ESM::BodyPart *hair = mEnvironment.mWorld->getStore().bodyParts.search(hairID); - const ESM::BodyPart *head = mEnvironment.mWorld->getStore().bodyParts.search(headID); - if(bodyRaceID == "b_n_argonian_f_") - forearml = mEnvironment.mWorld->getStore().bodyParts.search ("b_n_argonian_m_forearm"); //We need two - if(!handl) - handl = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hands"); - //const ESM::BodyPart* claviclel = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "clavicle"); - //const ESM::BodyPart* clavicler = claviclel; - const ESM::BodyPart* handr = handl; - const ESM::BodyPart* forearmr = forearml; - const ESM::BodyPart* wristr = wristl; - const ESM::BodyPart* armr = arml; +} + +void NpcAnimation::updateParts(){ + + bool apparelChanged = false; - if(upperleg){ - insertBoundedPart("meshes\\" + upperleg->model + "*|", "Left Upper Leg"); - insertBoundedPart("meshes\\" + upperleg->model, "Right Upper Leg"); - + //inv.getSlot(MWWorld::InventoryStore::Slot_Robe); + if(robe != inv.getSlot(MWWorld::InventoryStore::Slot_Robe)){ + //A robe was added or removed + removePartGroup(MWWorld::InventoryStore::Slot_Robe); + robe = inv.getSlot(MWWorld::InventoryStore::Slot_Robe); + apparelChanged = true; } - if(foot){ - if(bodyRaceID.compare("b_n_khajiit_m_") == 0) - { - feet = foot; - } - else - { - insertBoundedPart("meshes\\" + foot->model, "Right Foot"); - insertBoundedPart("meshes\\" + foot->model + "*|", "Left Foot"); - } + if(skirtiter != inv.getSlot(MWWorld::InventoryStore::Slot_Skirt)){ + //A robe was added or removed + removePartGroup(MWWorld::InventoryStore::Slot_Skirt); + skirtiter = inv.getSlot(MWWorld::InventoryStore::Slot_Skirt); + apparelChanged = true; } - if(groin){ - insertBoundedPart("meshes\\" + groin->model, "Groin"); - } - if(knee) - { - insertBoundedPart("meshes\\" + knee->model + "*|", "Left Knee"); //e - insertBoundedPart("meshes\\" + knee->model, "Right Knee"); //e + if(helmet != inv.getSlot(MWWorld::InventoryStore::Slot_Helmet)){ + apparelChanged = true; + helmet = inv.getSlot(MWWorld::InventoryStore::Slot_Helmet); + removePartGroup(MWWorld::InventoryStore::Slot_Helmet); - } - if(ankle){ - - insertBoundedPart("meshes\\" + ankle->model + "*|", "Left Ankle"); //Ogre::Quaternion(Ogre::Radian(3.14 / 4), Ogre::Vector3(1, 0, 0)),blank); //1,0,0, blank); - insertBoundedPart("meshes\\" + ankle->model, "Right Ankle"); - } - if (armr){ - insertBoundedPart("meshes\\" + armr->model, "Right Upper Arm"); - } - if(arml){ - insertBoundedPart("meshes\\" + arml->model + "*|", "Left Upper Arm"); - } - - if (forearmr) - { - insertBoundedPart("meshes\\" + forearmr->model, "Right Forearm"); - } - if(forearml) - insertBoundedPart("meshes\\" + forearml->model + "*|", "Left Forearm"); - - if (wristr) - { - insertBoundedPart("meshes\\" + wristr->model, "Right Wrist"); - } - - if(wristl) - insertBoundedPart("meshes\\" + wristl->model + "*|", "Left Wrist"); - - - - - - /*if(claviclel) - insertBoundedPart("meshes\\" + claviclel->model + "*|", "Left Clavicle", base); - if(clavicler) - insertBoundedPart("meshes\\" + clavicler->model , "Right Clavicle", base);*/ - - if(neck) - { - insertBoundedPart("meshes\\" + neck->model, "Neck"); - } - if(head) - insertBoundedPart("meshes\\" + head->model, "Head"); - if(hair) - insertBoundedPart("meshes\\" + hair->model, "Head"); - - if (chest){ - insertFreePart("meshes\\" + chest->model, ">\"", insert); - - - } - if (handr){ - insertFreePart("meshes\\" + handr->model , ">?", insert); - - } - if (handl){ - insertFreePart("meshes\\" + handl->model, ">>", insert); - - } - if(tail){ - insertFreePart("meshes\\" + tail->model, ">*", insert); } - if(feet){ - std::string num = getUniqueID(feet->model); - insertFreePart("meshes\\" + feet->model,"><", insert); - insertFreePart("meshes\\" + feet->model,">:", insert); + if(cuirass != inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass)){ + cuirass = inv.getSlot(MWWorld::InventoryStore::Slot_Cuirass); + removePartGroup(MWWorld::InventoryStore::Slot_Cuirass); + apparelChanged = true; + } - //originalpos = insert->_getWorldAABB().getCenter(); - //originalscenenode = insert->getPosition(); + if(greaves != inv.getSlot(MWWorld::InventoryStore::Slot_Greaves)){ + greaves = inv.getSlot(MWWorld::InventoryStore::Slot_Greaves); + removePartGroup(MWWorld::InventoryStore::Slot_Greaves); + apparelChanged = true; + } + if(leftpauldron != inv.getSlot(MWWorld::InventoryStore::Slot_LeftPauldron)){ + leftpauldron = inv.getSlot(MWWorld::InventoryStore::Slot_LeftPauldron); + removePartGroup(MWWorld::InventoryStore::Slot_LeftPauldron); + apparelChanged = true; + + } + if(rightpauldron != inv.getSlot(MWWorld::InventoryStore::Slot_RightPauldron)){ + rightpauldron = inv.getSlot(MWWorld::InventoryStore::Slot_RightPauldron); + removePartGroup(MWWorld::InventoryStore::Slot_RightPauldron); + apparelChanged = true; + + } + if(!isBeast && boots != inv.getSlot(MWWorld::InventoryStore::Slot_Boots)){ + boots = inv.getSlot(MWWorld::InventoryStore::Slot_Boots); + removePartGroup(MWWorld::InventoryStore::Slot_Boots); + apparelChanged = true; + + } + if(leftglove != inv.getSlot(MWWorld::InventoryStore::Slot_LeftGauntlet)){ + leftglove = inv.getSlot(MWWorld::InventoryStore::Slot_LeftGauntlet); + removePartGroup(MWWorld::InventoryStore::Slot_LeftGauntlet); + apparelChanged = true; + + } + if(rightglove != inv.getSlot(MWWorld::InventoryStore::Slot_RightGauntlet)){ + rightglove = inv.getSlot(MWWorld::InventoryStore::Slot_RightGauntlet); + removePartGroup(MWWorld::InventoryStore::Slot_RightGauntlet); + apparelChanged = true; + + } + if(shirt != inv.getSlot(MWWorld::InventoryStore::Slot_Shirt)){ + shirt = inv.getSlot(MWWorld::InventoryStore::Slot_Shirt); + removePartGroup(MWWorld::InventoryStore::Slot_Shirt); + apparelChanged = true; + + } + if(pants != inv.getSlot(MWWorld::InventoryStore::Slot_Pants)){ + pants = inv.getSlot(MWWorld::InventoryStore::Slot_Pants); + removePartGroup(MWWorld::InventoryStore::Slot_Pants); + apparelChanged = true; + + } + + if(apparelChanged){ + + if(robe != inv.end()) + { + MWWorld::Ptr ptr = *robe; + + const ESM::Clothing *clothes = (ptr.get())->base; + std::vector parts = clothes->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_Robe, 5, parts); + reserveIndividualPart(ESM::PRT_Groin, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_Skirt, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_RLeg, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_LLeg, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_RUpperarm, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_LUpperarm, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_RKnee, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_LKnee, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_RForearm, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_LForearm, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_RPauldron, MWWorld::InventoryStore::Slot_Robe, 5); + reserveIndividualPart(ESM::PRT_LPauldron, MWWorld::InventoryStore::Slot_Robe, 5); + } + if(skirtiter != inv.end()) + { + MWWorld::Ptr ptr = *skirtiter; + + const ESM::Clothing *clothes = (ptr.get())->base; + std::vector parts = clothes->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_Skirt, 4, parts); + reserveIndividualPart(ESM::PRT_Groin, MWWorld::InventoryStore::Slot_Skirt, 4); + reserveIndividualPart(ESM::PRT_RLeg, MWWorld::InventoryStore::Slot_Skirt, 4); + reserveIndividualPart(ESM::PRT_LLeg, MWWorld::InventoryStore::Slot_Skirt, 4); + } + + if(helmet != inv.end()){ + removeIndividualPart(ESM::PRT_Hair); + const ESM::Armor *armor = (helmet->get())->base; + std::vector parts = armor->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_Helmet, 3, parts); + + } + if(cuirass != inv.end()){ + const ESM::Armor *armor = (cuirass->get())->base; + std::vector parts = armor->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_Cuirass, 3, parts); + + } + if(greaves != inv.end()){ + const ESM::Armor *armor = (greaves->get())->base; + std::vector parts = armor->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_Greaves, 3, parts); + + } + + if(leftpauldron != inv.end()){ + const ESM::Armor *armor = (leftpauldron->get())->base; + std::vector parts = armor->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_LeftPauldron, 3, parts); + + } + if(rightpauldron != inv.end()){ + const ESM::Armor *armor = (rightpauldron->get())->base; + std::vector parts = armor->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_RightPauldron, 3, parts); + + } + if(!isBeast && boots != inv.end()){ + if(boots->getTypeName() == typeid(ESM::Clothing).name()){ + const ESM::Clothing *clothes = (boots->get())->base; + std::vector parts = clothes->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_Boots, 2, parts); + } + else if(boots->getTypeName() == typeid(ESM::Armor).name()) + { + const ESM::Armor *armor = (boots->get())->base; + std::vector parts = armor->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_Boots, 3, parts); + } + + } + if(leftglove != inv.end()){ + if(leftglove->getTypeName() == typeid(ESM::Clothing).name()){ + const ESM::Clothing *clothes = (leftglove->get())->base; + std::vector parts = clothes->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_LeftGauntlet, 2, parts); + } + else + { + const ESM::Armor *armor = (leftglove->get())->base; + std::vector parts = armor->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_LeftGauntlet, 3, parts); + } + + } + if(rightglove != inv.end()){ + if(rightglove->getTypeName() == typeid(ESM::Clothing).name()){ + const ESM::Clothing *clothes = (rightglove->get())->base; + std::vector parts = clothes->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_RightGauntlet, 2, parts); + } + else + { + const ESM::Armor *armor = (rightglove->get())->base; + std::vector parts = armor->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_RightGauntlet, 3, parts); + } + + } + + if(shirt != inv.end()){ + const ESM::Clothing *clothes = (shirt->get())->base; + std::vector parts = clothes->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_Shirt, 2, parts); + } + if(pants != inv.end()){ + const ESM::Clothing *clothes = (pants->get())->base; + std::vector parts = clothes->parts.parts; + addPartGroup(MWWorld::InventoryStore::Slot_Pants, 2, parts); + } + } + + if(partpriorities[ESM::PRT_Head] < 1){ + addOrReplaceIndividualPart(ESM::PRT_Head, -1,1,headModel); + } + if(partpriorities[ESM::PRT_Hair] < 1 && partpriorities[ESM::PRT_Head] <= 1){ + addOrReplaceIndividualPart(ESM::PRT_Hair, -1,1,hairModel); + } + if(partpriorities[ESM::PRT_Neck] < 1){ + const ESM::BodyPart *neckPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "neck"); + if(neckPart) + addOrReplaceIndividualPart(ESM::PRT_Neck, -1,1,"meshes\\" + neckPart->model); + } + if(partpriorities[ESM::PRT_Cuirass] < 1){ + const ESM::BodyPart *chestPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "chest"); + if(chestPart) + addOrReplaceIndividualPart(ESM::PRT_Cuirass, -1,1,"meshes\\" + chestPart->model); + } + + if(partpriorities[ESM::PRT_Groin] < 1){ + const ESM::BodyPart *groinPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "groin"); + if(groinPart) + addOrReplaceIndividualPart(ESM::PRT_Groin, -1,1,"meshes\\" + groinPart->model); + } + if(partpriorities[ESM::PRT_RHand] < 1){ + const ESM::BodyPart *handPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hand"); + if(!handPart) + handPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hands"); + if(handPart) + addOrReplaceIndividualPart(ESM::PRT_RHand, -1,1,"meshes\\" + handPart->model); + } + if(partpriorities[ESM::PRT_LHand] < 1){ + const ESM::BodyPart *handPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hand"); + if(!handPart) + handPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hands"); + if(handPart) + addOrReplaceIndividualPart(ESM::PRT_LHand, -1,1,"meshes\\" + handPart->model); + } + + if(partpriorities[ESM::PRT_RWrist] < 1){ + const ESM::BodyPart *wristPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "wrist"); + if(wristPart) + addOrReplaceIndividualPart(ESM::PRT_RWrist, -1,1,"meshes\\" + wristPart->model); + } + if(partpriorities[ESM::PRT_LWrist] < 1){ + const ESM::BodyPart *wristPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "wrist"); + if(wristPart) + addOrReplaceIndividualPart(ESM::PRT_LWrist, -1,1,"meshes\\" + wristPart->model); + } + if(partpriorities[ESM::PRT_RForearm] < 1){ + const ESM::BodyPart *forearmPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "forearm"); + if(bodyRaceID == "b_n_argonian_f_") + forearmPart = mEnvironment.mWorld->getStore().bodyParts.search ("b_n_argonian_m_forearm"); + if(forearmPart) + addOrReplaceIndividualPart(ESM::PRT_RForearm, -1,1,"meshes\\" + forearmPart->model); + } + if(partpriorities[ESM::PRT_LForearm] < 1){ + const ESM::BodyPart *forearmPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "forearm"); + if(bodyRaceID == "b_n_argonian_f_") + forearmPart = mEnvironment.mWorld->getStore().bodyParts.search ("b_n_argonian_m_forearm"); + if(forearmPart) + addOrReplaceIndividualPart(ESM::PRT_LForearm, -1,1,"meshes\\" + forearmPart->model); + } + if(partpriorities[ESM::PRT_RUpperarm] < 1){ + const ESM::BodyPart *armPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper arm"); + if(armPart) + addOrReplaceIndividualPart(ESM::PRT_RUpperarm, -1,1,"meshes\\" + armPart->model); + } + if(partpriorities[ESM::PRT_LUpperarm] < 1){ + const ESM::BodyPart *armPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper arm"); + if(armPart) + addOrReplaceIndividualPart(ESM::PRT_LUpperarm, -1,1,"meshes\\" + armPart->model); + } + if(partpriorities[ESM::PRT_RFoot] < 1){ + const ESM::BodyPart *footPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "foot"); + if(isBeast && !footPart) + footPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "feet"); + if(footPart) + addOrReplaceIndividualPart(ESM::PRT_RFoot, -1,1,"meshes\\" + footPart->model); + } + if(partpriorities[ESM::PRT_LFoot] < 1){ + const ESM::BodyPart *footPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "foot"); + if(isBeast && !footPart) + footPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "feet"); + if(footPart) + addOrReplaceIndividualPart(ESM::PRT_LFoot, -1,1,"meshes\\" + footPart->model); + } + if(partpriorities[ESM::PRT_RAnkle] < 1){ + const ESM::BodyPart *anklePart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "ankle"); + if(anklePart) + addOrReplaceIndividualPart(ESM::PRT_RAnkle, -1,1,"meshes\\" + anklePart->model); + } + if(partpriorities[ESM::PRT_LAnkle] < 1){ + const ESM::BodyPart *anklePart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "ankle"); + if(anklePart) + addOrReplaceIndividualPart(ESM::PRT_LAnkle, -1,1,"meshes\\" + anklePart->model); + } + if(partpriorities[ESM::PRT_RKnee] < 1){ + const ESM::BodyPart *kneePart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "knee"); + if(kneePart) + addOrReplaceIndividualPart(ESM::PRT_RKnee, -1,1,"meshes\\" + kneePart->model); + } + if(partpriorities[ESM::PRT_LKnee] < 1){ + const ESM::BodyPart *kneePart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "knee"); + if(kneePart) + addOrReplaceIndividualPart(ESM::PRT_LKnee, -1,1,"meshes\\" + kneePart->model); + } + if(partpriorities[ESM::PRT_RLeg] < 1){ + const ESM::BodyPart *legPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper leg"); + if(legPart) + addOrReplaceIndividualPart(ESM::PRT_RLeg, -1,1,"meshes\\" + legPart->model); + } + if(partpriorities[ESM::PRT_LLeg] < 1){ + const ESM::BodyPart *legPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper leg"); + if(legPart) + addOrReplaceIndividualPart(ESM::PRT_LLeg, -1,1,"meshes\\" + legPart->model); + } + if(partpriorities[ESM::PRT_Tail] < 1){ + const ESM::BodyPart *tailPart = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "tail"); + if(tailPart) + addOrReplaceIndividualPart(ESM::PRT_Tail, -1,1,"meshes\\" + tailPart->model); + } + + + + + + + + } Ogre::Entity* NpcAnimation::insertBoundedPart(const std::string &mesh, std::string bonename){ - + NIFLoader::load(mesh); - Entity* ent = mRend.getScene()->createEntity(mesh); + Ogre::Entity* part = mRend.getScene()->createEntity(mesh); + part->setVisibilityFlags(RV_Actors); - base->attachObjectToBone(bonename, ent); - return ent; + base->attachObjectToBone(bonename, part); + return part; } -void NpcAnimation::insertFreePart(const std::string &mesh, const std::string suffix, Ogre::SceneNode* insert){ - std::string meshNumbered = mesh + getUniqueID(mesh + suffix) + suffix; - NIFLoader::load(meshNumbered); - - Ogre::Entity* ent = mRend.getScene()->createEntity(meshNumbered); - - - - - insert->attachObject(ent); - entityparts.push_back(ent); - shapes = ((NIFLoader::getSingletonPtr())->getShapes(mesh + "0000" + suffix)); - if(shapes){ - shapeparts.push_back(shapes); - handleShapes(shapes, ent, base->getSkeleton()); +void NpcAnimation::insertFootPart(int type, const std::string &mesh){ + std::string meshAndSuffix = mesh; + if(type == ESM::PRT_LFoot) + meshAndSuffix += "*|"; + NIFLoader::load(meshAndSuffix); + Ogre::Entity* part = mRend.getScene()->createEntity(meshAndSuffix); + std::vector* shape = ((NIFLoader::getSingletonPtr())->getShapes(meshAndSuffix)); + if(shape == 0){ + if(type == ESM::PRT_LFoot){ + base->attachObjectToBone("Left Foot", part); + lfoot = part; + } + else if (type == ESM::PRT_RFoot){ + base->attachObjectToBone("Right Foot", part); + rfoot = part; + } + } + else{ + if(type == ESM::PRT_LFoot) + lFreeFoot = insertFreePart(mesh, "::"); + else if (type == ESM::PRT_RFoot) + rFreeFoot = insertFreePart(mesh, ":<"); } + +} +std::pair*> NpcAnimation::insertFreePart(const std::string &mesh, const std::string suffix){ + + std::string meshNumbered = mesh + getUniqueID(mesh + suffix) + suffix; + NIFLoader::load(meshNumbered); + + Ogre::Entity* part = mRend.getScene()->createEntity(meshNumbered); + part->setVisibilityFlags(RV_Actors); + + insert->attachObject(part); + + std::vector* shape = ((NIFLoader::getSingletonPtr())->getShapes(mesh + "0000" + suffix)); + if(shape){ + handleShapes(shape, part, base->getSkeleton()); + } + std::pair*> pair = std::make_pair(part, shape); + return pair; } + + void NpcAnimation::runAnimation(float timepassed){ - + + if(timeToChange > .2){ + + timeToChange = 0; + + updateParts(); + } + + timeToChange += timepassed; + //1. Add the amount of time passed to time //2. Handle the animation transforms dependent on time @@ -284,23 +578,285 @@ void NpcAnimation::runAnimation(float timepassed){ time = startTime + (time - stopTime); } - handleAnimationTransforms(); + handleAnimationTransforms(); + - std::vector*>::iterator shapepartsiter = shapeparts.begin(); - std::vector::iterator entitypartsiter = entityparts.begin(); - while(shapepartsiter != shapeparts.end()) - { vecRotPos.clear(); - std::vector* shapes = *shapepartsiter; - Ogre::Entity* theentity = *entitypartsiter; - handleShapes(shapes, theentity, base->getSkeleton()); - shapepartsiter++; - entitypartsiter++; + if(lFreeFoot.first) + handleShapes(lFreeFoot.second, lFreeFoot.first, base->getSkeleton()); + if(rFreeFoot.first) + handleShapes(rFreeFoot.second, rFreeFoot.first, base->getSkeleton()); + + if(chest.first) + handleShapes(chest.second, chest.first, base->getSkeleton()); + if(tail.first) + handleShapes(tail.second, tail.first, base->getSkeleton()); + if(skirt.first){ + handleShapes(skirt.second, skirt.first, base->getSkeleton()); + } + if(lhand.first) + handleShapes(lhand.second, lhand.first, base->getSkeleton()); + if(rhand.first) + handleShapes(rhand.second, rhand.first, base->getSkeleton()); + +} +} + +void NpcAnimation::removeIndividualPart(int type){ + partpriorities[type] = 0; + partslots[type] = -1; + + if(type == ESM::PRT_Head && head){ //0 + base->detachObjectFromBone(head); + head = 0; } - + else if(type == ESM::PRT_Hair && hair){//1 + base->detachObjectFromBone(hair); + hair = 0; + } + else if(type == ESM::PRT_Neck && neck){//2 + base->detachObjectFromBone(neck); + neck = 0; + } + else if(type == ESM::PRT_Cuirass && chest.first){//3 + insert->detachObject(chest.first); + chest = zero; + } + else if(type == ESM::PRT_Groin && groin){//4 + base->detachObjectFromBone(groin); + groin = 0; + } + else if(type == ESM::PRT_Skirt && skirt.first){//5 + insert->detachObject(skirt.first); + skirt = zero; + } + else if(type == ESM::PRT_RHand && rhand.first){//6 + insert->detachObject(rhand.first); + rhand = zero; + } + else if(type == ESM::PRT_LHand && lhand.first){//7 + insert->detachObject(lhand.first); + lhand = zero; + } + else if(type == ESM::PRT_RWrist && rWrist){//8 + base->detachObjectFromBone(rWrist); + rWrist = 0; + } + else if(type == ESM::PRT_LWrist && lWrist){//9 + base->detachObjectFromBone(lWrist); + lWrist = 0; + } + else if(type == ESM::PRT_Shield){//10 + + } + else if(type == ESM::PRT_RForearm && rForearm){//11 + base->detachObjectFromBone(rForearm); + rForearm = 0; + } + else if(type == ESM::PRT_LForearm && lForearm){//12 + base->detachObjectFromBone(lForearm); + lForearm = 0; + } + else if(type == ESM::PRT_RUpperarm && rupperArm){//13 + base->detachObjectFromBone(rupperArm); + rupperArm = 0; + } + else if(type == ESM::PRT_LUpperarm && lupperArm){//14 + base->detachObjectFromBone(lupperArm); + lupperArm = 0; + } + else if(type == ESM::PRT_RFoot){ //15 + if(rfoot){ + base->detachObjectFromBone(rfoot); + rfoot = 0; + } + else if(rFreeFoot.first){ + insert->detachObject(rFreeFoot.first); + rFreeFoot = zero; + } + } + else if(type == ESM::PRT_LFoot){ //16 + if(lfoot){ + base->detachObjectFromBone(lfoot); + lfoot = 0; + } + else if(lFreeFoot.first){ + insert->detachObject(lFreeFoot.first); + lFreeFoot = zero; + } + } + else if(type == ESM::PRT_RAnkle && rAnkle){ //17 + base->detachObjectFromBone(rAnkle); + rAnkle = 0; + } + else if(type == ESM::PRT_LAnkle && lAnkle){ //18 + base->detachObjectFromBone(lAnkle); + lAnkle = 0; + } + else if(type == ESM::PRT_RKnee && rKnee){ //19 + base->detachObjectFromBone(rKnee); + rKnee = 0; + } + else if(type == ESM::PRT_LKnee && lKnee){ //20 + base->detachObjectFromBone(lKnee); + lKnee = 0; + } + else if(type == ESM::PRT_RLeg && rUpperLeg){ //21 + base->detachObjectFromBone(rUpperLeg); + rUpperLeg = 0; + } + else if(type == ESM::PRT_LLeg && lUpperLeg){ //22 + base->detachObjectFromBone(lUpperLeg); + lUpperLeg = 0; + } + else if(type == ESM::PRT_RPauldron && rclavicle){ //23 + base->detachObjectFromBone(rclavicle); + rclavicle = 0; + } + else if(type == ESM::PRT_LPauldron && lclavicle){ //24 + base->detachObjectFromBone(lclavicle); + lclavicle = 0; + } + else if(type == ESM::PRT_Weapon){ //25 + + } + else if(type == ESM::PRT_Tail && tail.first){ //26 + insert->detachObject(tail.first); + tail = zero; + } + + + + } -} + void NpcAnimation::reserveIndividualPart(int type, int group, int priority){ + if(priority > partpriorities[type]){ + removeIndividualPart(type); + partpriorities[type] = priority; + partslots[type] = group; + } + } + + void NpcAnimation::removePartGroup(int group){ + for(int i = 0; i < 27; i++){ + if(partslots[i] == group){ + removeIndividualPart(i); + } + } + } + bool NpcAnimation::addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh){ + if(priority > partpriorities[type]){ + removeIndividualPart(type); + partslots[type] = group; + partpriorities[type] = priority; + switch(type){ + case ESM::PRT_Head: //0 + head = insertBoundedPart(mesh, "Head"); + break; + case ESM::PRT_Hair: //1 + hair = insertBoundedPart(mesh, "Head"); + break; + case ESM::PRT_Neck: //2 + neck = insertBoundedPart(mesh, "Neck"); + break; + case ESM::PRT_Cuirass: //3 + chest = insertFreePart(mesh, ":\""); + break; + case ESM::PRT_Groin: //4 + groin = insertBoundedPart(mesh, "Groin"); + break; + case ESM::PRT_Skirt: //5 + skirt = insertFreePart(mesh, ":|"); + break; + case ESM::PRT_RHand: //6 + rhand = insertFreePart(mesh, ":?"); + break; + case ESM::PRT_LHand: //7 + lhand = insertFreePart(mesh, ":>"); + break; + case ESM::PRT_RWrist: //8 + rWrist = insertBoundedPart(mesh, "Right Wrist"); + break; + case ESM::PRT_LWrist: //9 + lWrist = insertBoundedPart(mesh + "*|", "Left Wrist"); + break; + case ESM::PRT_Shield: //10 + break; + case ESM::PRT_RForearm: //11 + rForearm = insertBoundedPart(mesh, "Right Forearm"); + break; + case ESM::PRT_LForearm: //12 + lForearm = insertBoundedPart(mesh + "*|", "Left Forearm"); + break; + case ESM::PRT_RUpperarm: //13 + rupperArm = insertBoundedPart(mesh, "Right Upper Arm"); + break; + case ESM::PRT_LUpperarm: //14 + lupperArm = insertBoundedPart(mesh + "*|", "Left Upper Arm"); + break; + case ESM::PRT_RFoot: //15 + insertFootPart(type, mesh); + break; + case ESM::PRT_LFoot: //16 + insertFootPart(type, mesh); + break; + case ESM::PRT_RAnkle: //17 + rAnkle = insertBoundedPart(mesh , "Right Ankle"); + break; + case ESM::PRT_LAnkle: //18 + lAnkle = insertBoundedPart(mesh + "*|", "Left Ankle"); + break; + case ESM::PRT_RKnee: //19 + rKnee = insertBoundedPart(mesh , "Right Knee"); + break; + case ESM::PRT_LKnee: //20 + lKnee = insertBoundedPart(mesh + "*|", "Left Knee"); + break; + case ESM::PRT_RLeg: //21 + rUpperLeg = insertBoundedPart(mesh, "Right Upper Leg"); + break; + case ESM::PRT_LLeg: //22 + lUpperLeg = insertBoundedPart(mesh + "*|", "Left Upper Leg"); + break; + case ESM::PRT_RPauldron: //23 + rclavicle = insertBoundedPart(mesh , "Right Clavicle"); + break; + case ESM::PRT_LPauldron: //24 + lclavicle = insertBoundedPart(mesh + "*|", "Left Clavicle"); + break; + case ESM::PRT_Weapon: //25 + break; + case ESM::PRT_Tail: //26 + tail = insertFreePart(mesh, ":*"); + break; + + + } + return true; + } + return false; + } + + void NpcAnimation::addPartGroup(int group, int priority, std::vector& parts){ + for(std::size_t i = 0; i < parts.size(); i++) + { + ESM::PartReference part = parts[i]; + + const ESM::BodyPart *bodypart = 0; + + if(isFemale) + bodypart = mEnvironment.mWorld->getStore().bodyParts.search (part.female); + if(!bodypart) + bodypart = mEnvironment.mWorld->getStore().bodyParts.search (part.male); + if(bodypart){ + addOrReplaceIndividualPart(part.part, group,priority,"meshes\\" + bodypart->model); + } + else + reserveIndividualPart(part.part, group, priority); + + } + } } diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index e2071957c..352b54bec 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -6,24 +6,96 @@ #include #include #include +#include #include "../mwworld/refdata.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/environment.hpp" #include "components/nifogre/ogre_nif_loader.hpp" +#include "../mwworld/inventorystore.hpp" +#include "../mwclass/npc.hpp" +#include "../mwworld/containerstore.hpp" +#include "components/esm/loadarmo.hpp" namespace MWRender{ class NpcAnimation: public Animation{ +private: + MWWorld::InventoryStore& inv; + int mStateID; + //Free Parts + std::pair*> chest; + std::pair*> skirt; + std::pair*> lhand; + std::pair*> rhand; + std::pair*> tail; + std::pair*> lFreeFoot; + std::pair*> rFreeFoot; + + int partslots[27]; //Each part slot is taken by clothing, armor, or is empty + int partpriorities[27]; + std::pair*> zero; + + + + //Bounded Parts + Ogre::Entity* lclavicle; + Ogre::Entity* rclavicle; + Ogre::Entity* rupperArm; + Ogre::Entity* lupperArm; + Ogre::Entity* rUpperLeg; + Ogre::Entity* lUpperLeg; + Ogre::Entity* lForearm; + Ogre::Entity* rForearm; + Ogre::Entity* lWrist; + Ogre::Entity* rWrist; + Ogre::Entity* rKnee; + Ogre::Entity* lKnee; + Ogre::Entity* neck; + Ogre::Entity* rAnkle; + Ogre::Entity* lAnkle; + Ogre::Entity* groin; + Ogre::Entity* lfoot; + Ogre::Entity* rfoot; + Ogre::Entity* hair; + Ogre::Entity* head; - + Ogre::SceneNode* insert; + bool isBeast; + bool isFemale; + std::string headModel; + std::string hairModel; + std::string npcName; + std::string bodyRaceID; + float timeToChange; + MWWorld::ContainerStoreIterator robe; + MWWorld::ContainerStoreIterator helmet; + MWWorld::ContainerStoreIterator shirt; + MWWorld::ContainerStoreIterator cuirass; + MWWorld::ContainerStoreIterator greaves; + MWWorld::ContainerStoreIterator leftpauldron; + MWWorld::ContainerStoreIterator rightpauldron; + MWWorld::ContainerStoreIterator boots; + MWWorld::ContainerStoreIterator pants; + MWWorld::ContainerStoreIterator leftglove; + MWWorld::ContainerStoreIterator rightglove; + MWWorld::ContainerStoreIterator skirtiter; public: - NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend); + NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); virtual ~NpcAnimation(); Ogre::Entity* insertBoundedPart(const std::string &mesh, std::string bonename); - void insertFreePart(const std::string &mesh, const std::string suffix, Ogre::SceneNode* insert); + std::pair*> insertFreePart(const std::string &mesh, const std::string suffix); + void insertFootPart(int type, const std::string &mesh); virtual void runAnimation(float timepassed); + void updateParts(); + void removeIndividualPart(int type); + void reserveIndividualPart(int type, int group, int priority); + + bool addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh); + void removePartGroup(int group); + void addPartGroup(int group, int priority, std::vector& parts); + }; } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index ee60407b2..c1462807f 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -56,6 +56,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); if (caps->getNumMultiRenderTargets() < 2) Settings::Manager::setBool("shader", "Water", false); + if (!caps->isShaderProfileSupported("fp40") && !caps->isShaderProfileSupported("ps_4_0")) + Settings::Manager::setBool("enabled", "Shadows", false); // note that the order is important here if (useMRT()) @@ -108,7 +110,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const RenderingManager::~RenderingManager () { - //TODO: destroy mSun? delete mPlayer; delete mSkyManager; delete mDebugging; @@ -481,11 +482,13 @@ void RenderingManager::preCellChange(MWWorld::Ptr::CellStore* cell) void RenderingManager::disableLights() { mObjects.disableLights(); + sunDisable(); } void RenderingManager::enableLights() { mObjects.enableLights(); + sunEnable(); } const bool RenderingManager::useMRT() diff --git a/apps/openmw/mwrender/terrainmaterial.cpp b/apps/openmw/mwrender/terrainmaterial.cpp index 57bea5388..9785ec903 100644 --- a/apps/openmw/mwrender/terrainmaterial.cpp +++ b/apps/openmw/mwrender/terrainmaterial.cpp @@ -39,6 +39,8 @@ THE SOFTWARE. #include #include "renderingmanager.hpp" +#undef far + namespace Ogre { //--------------------------------------------------------------------- @@ -538,7 +540,6 @@ namespace Ogre params->setNamedAutoConstant("viewProjMatrix", GpuProgramParameters::ACT_VIEWPROJ_MATRIX); params->setNamedAutoConstant("lodMorph", GpuProgramParameters::ACT_CUSTOM, Terrain::LOD_MORPH_CUSTOM_PARAM); - params->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS); if (prof->isShadowingEnabled(tt, terrain)) { @@ -574,7 +575,7 @@ namespace Ogre { params->setNamedAutoConstant("lightPosObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i); params->setNamedAutoConstant("lightDiffuseColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i); - if (prof->getNumberOfLightsSupported() > 1) + if (i > 0) params->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i); //params->setNamedAutoConstant("lightSpecularColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, i); } @@ -584,6 +585,7 @@ namespace Ogre params->setNamedAutoConstant("eyePosObjSpace", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE); params->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR); + params->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS); if (prof->isShadowingEnabled(tt, terrain)) { @@ -811,11 +813,11 @@ namespace Ogre outStream << "out float4 oPos : POSITION,\n" - "out float4 oPosObj : COLOR \n"; + "out float4 oPosObj : TEXCOORD0 \n"; - uint texCoordSet = 0; + uint texCoordSet = 1; outStream << - ", out float4 oUVMisc : TEXCOORD" << texCoordSet++ <<" // xy = uv, z = camDepth\n"; + ", out float4 oUVMisc : COLOR0 // xy = uv, z = camDepth\n"; // layer UV's premultiplied, packed as xy/zw uint numUVSets = numLayers / 2; @@ -835,14 +837,6 @@ namespace Ogre outStream << ", out float2 lodInfo : TEXCOORD" << texCoordSet++ << "\n"; } - bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; - if (fog) - { - outStream << - ", uniform float4 fogParams\n"; - //", out float fogVal : COLOR\n"; - } - if (prof->isShadowingEnabled(tt, terrain)) { texCoordSet = generateVpDynamicShadowsParams(texCoordSet, prof, terrain, tt, outStream); @@ -938,11 +932,11 @@ namespace Ogre outStream << "void main_fp(\n" - "float4 position : COLOR,\n"; + "float4 position : TEXCOORD0,\n"; - uint texCoordSet = 0; + uint texCoordSet = 1; outStream << - "float4 uvMisc : TEXCOORD" << texCoordSet++ << ",\n"; + "float4 uvMisc : COLOR0,\n"; // UV's premultiplied, packed as xy/zw uint maxLayers = prof->getMaxLayers(terrain); @@ -969,8 +963,8 @@ namespace Ogre if (fog) { outStream << + "uniform float4 fogParams, \n" "uniform float3 fogColour, \n"; - //"float fogVal : COLOR,\n"; } uint currentSamplerIdx = 0; @@ -989,7 +983,7 @@ namespace Ogre //"uniform float3 lightSpecularColour"<getNumberOfLightsSupported() > 1) + if (i > 0) outStream << "uniform float4 lightAttenuation"<getNumberOfLightsSupported() > 1) + if (i > 0) outStream << // pre-multiply light color with attenuation factor "d = length( lightDir"<getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; - if (fog) - { - if (terrain->getSceneManager()->getFogMode() == FOG_LINEAR) - { - outStream << - " float fogVal = saturate((oPos.z - fogParams.y) * fogParams.w);\n"; - } - else - { - outStream << - " float fogVal = saturate(1 / (exp(oPos.z * fogParams.x)));\n"; - } - outStream << - " oPosObj.w = fogVal; \n"; - } + " oPosObj.w = oPos.z;\n"; if (prof->isShadowingEnabled(tt, terrain)) generateVpDynamicShadows(prof, terrain, tt, outStream); @@ -1339,7 +1315,13 @@ namespace Ogre // diffuse lighting for (int i=0; igetNumberOfLightsSupported(); ++i) + { + // shadows only for first light (directional) + if (i==0) outStream << " outputCol.rgb += litRes"<isLayerSpecularMappingEnabled()) @@ -1367,6 +1349,16 @@ namespace Ogre bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; if (fog) { + if (terrain->getSceneManager()->getFogMode() == FOG_LINEAR) + { + outStream << + " float fogVal = saturate((position.w - fogParams.y) * fogParams.w);\n"; + } + else + { + outStream << + " float fogVal = saturate(1 / (exp(position.w * fogParams.x)));\n"; + } outStream << " outputCol.rgb = lerp(outputCol.rgb, fogColour, fogVal);\n"; } @@ -1374,7 +1366,7 @@ namespace Ogre outStream << " oColor = outputCol;\n"; if (MWRender::RenderingManager::useMRT()) outStream << - " oColor1 = float4(uvMisc.z / far, 0, 0, 1); \n"; + " oColor1 = float4(position.w / far, 0, 0, 1); \n"; outStream << "}\n"; @@ -1583,7 +1575,7 @@ namespace Ogre { uint numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); outStream << - " float camDepth = uvMisc.z;\n"; + " float camDepth = position.w;\n"; if (prof->getReceiveDynamicShadowsDepth()) { @@ -1627,8 +1619,8 @@ namespace Ogre outStream << " float fadeRange = shadowFar_fadeStart.x - shadowFar_fadeStart.y; \n" - " float fade = 1-((uvMisc.z - shadowFar_fadeStart.y) / fadeRange); \n" - " rtshadow = (uvMisc.z > shadowFar_fadeStart.x) ? 1 : ((uvMisc.z > shadowFar_fadeStart.y) ? 1-((1-rtshadow)*fade) : rtshadow); \n" + " float fade = 1-((position.w - shadowFar_fadeStart.y) / fadeRange); \n" + " rtshadow = (position.w > shadowFar_fadeStart.x) ? 1 : ((position.w > shadowFar_fadeStart.y) ? 1-((1-rtshadow)*fade) : rtshadow); \n" " rtshadow = (1-(1-rtshadow)*0.6); \n" // make the shadow a little less intensive " shadow = min(shadow, rtshadow);\n"; diff --git a/apps/openmw/mwscript/dialogueextensions.cpp b/apps/openmw/mwscript/dialogueextensions.cpp index 0cca028e2..fec539d3e 100644 --- a/apps/openmw/mwscript/dialogueextensions.cpp +++ b/apps/openmw/mwscript/dialogueextensions.cpp @@ -11,6 +11,7 @@ #include "../mwdialogue/dialoguemanager.hpp" #include "interpretercontext.hpp" +#include "ref.hpp" namespace MWScript { @@ -115,12 +116,27 @@ namespace MWScript } }; + template + class OpForceGreeting : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + context.getEnvironment().mDialogueManager->startDialogue (ptr); + } + }; const int opcodeJournal = 0x2000133; const int opcodeSetJournalIndex = 0x2000134; const int opcodeGetJournalIndex = 0x2000135; const int opcodeAddTopic = 0x200013a; const int opcodeChoice = 0x2000a; + const int opcodeForceGreeting = 0x200014f; + const int opcodeForceGreetingExplicit = 0x2000150; void registerExtensions (Compiler::Extensions& extensions) { @@ -129,6 +145,9 @@ namespace MWScript extensions.registerFunction ("getjournalindex", 'l', "c", opcodeGetJournalIndex); extensions.registerInstruction ("addtopic", "S" , opcodeAddTopic); extensions.registerInstruction ("choice", "/SlSlSlSlSlSlSlSlSlSlSlSlSlSlSlSl", opcodeChoice); + extensions.registerInstruction("forcegreeting","",opcodeForceGreeting); + extensions.registerInstruction("forcegreeting","",opcodeForceGreeting, + opcodeForceGreetingExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -138,6 +157,8 @@ namespace MWScript interpreter.installSegment5 (opcodeGetJournalIndex, new OpGetJournalIndex); interpreter.installSegment5 (opcodeAddTopic, new OpAddTopic); interpreter.installSegment3 (opcodeChoice,new OpChoice); + interpreter.installSegment5 (opcodeForceGreeting, new OpForceGreeting); + interpreter.installSegment5 (opcodeForceGreetingExplicit, new OpForceGreeting); } } diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 1317794fa..58960aac4 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -24,7 +24,12 @@ op 0x20007: PlayAnim, explicit reference op 0x20008: LoopAnim op 0x20009: LoopAnim, explicit reference op 0x2000a: Choice -opcodes 0x2000b-0x3ffff unused +op 0x2000b: PCRaiseRank +op 0x2000c: PCLowerRank +op 0x2000d: PCJoinFaction +op 0x2000e: PCGetRank implicit +op 0x2000f: PCGetRank explicit +opcodes 0x20010-0x3ffff unused Segment 4: (not implemented yet) @@ -135,4 +140,8 @@ op 0x2000149: RemoveSpell op 0x200014a: RemoveSpell, explicit reference op 0x200014b: GetSpell op 0x200014c: GetSpell, explicit reference -opcodes 0x200014d-0x3ffffff unused +op 0x200014d: ModDisposition +op 0x200014e: ModDisposition, explicit reference +op 0x200014f: ForceGreeting +op 0x2000150: ForceGreeting, explicit reference +opcodes 0x2000151-0x3ffffff unused diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 011b8b010..239f8d768 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -8,6 +8,8 @@ #include #include "../mwworld/class.hpp" +#include "../mwworld/environment.hpp" +#include "../mwworld/player.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/npcstats.hpp" @@ -15,6 +17,8 @@ #include "interpretercontext.hpp" #include "ref.hpp" +#include "../mwdialogue/dialoguemanager.hpp" + namespace MWScript { namespace Stats @@ -319,6 +323,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { + MWWorld::Ptr ptr = R()(runtime); std::string id = runtime.getStringLiteral (runtime[0].mInteger); @@ -339,6 +344,160 @@ namespace MWScript } }; + class OpPCJoinFaction : public Interpreter::Opcode1 + { + public: + + virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + { + std::string factionID = ""; + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + if(arg0==0) + { + factionID = context.getEnvironment().mDialogueManager->getFaction(); + } + else + { + factionID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + } + if(factionID != "") + { + MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); + if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) == MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) + { + MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = 0; + } + } + } + }; + + class OpPCRaiseRank : public Interpreter::Opcode1 + { + public: + + virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + { + std::string factionID = ""; + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + if(arg0==0) + { + factionID = context.getEnvironment().mDialogueManager->getFaction(); + } + else + { + factionID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + } + if(factionID != "") + { + MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); + if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) == MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) + { + MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = 0; + } + else + { + MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] +1; + } + } + } + }; + + class OpPCLowerRank : public Interpreter::Opcode1 + { + public: + + virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + { + std::string factionID = ""; + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + if(arg0==0) + { + factionID = context.getEnvironment().mDialogueManager->getFaction(); + } + else + { + factionID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + } + if(factionID != "") + { + MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); + if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) != MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) + { + MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] = MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID] -1; + } + } + } + }; + + template + class OpGetPCRank : public Interpreter::Opcode1 + { + public: + + virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) + { + MWWorld::Ptr ptr = R()(runtime); + + std::string factionID = ""; + if(arg0 >0) + { + factionID = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + } + else + { + if(MWWorld::Class::get(ptr).getNpcStats(ptr).mFactionRank.empty()) + { + //throw exception? + } + else + { + factionID = MWWorld::Class::get(ptr).getNpcStats(ptr).mFactionRank.begin()->first; + } + } + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + MWWorld::Ptr player = context.getEnvironment().mWorld->getPlayer().getPlayer(); + if(factionID!="") + { + if(MWWorld::Class::get(player).getNpcStats(player).mFactionRank.find(factionID) != MWWorld::Class::get(player).getNpcStats(player).mFactionRank.end()) + { + runtime.push(MWWorld::Class::get(player).getNpcStats(player).mFactionRank[factionID]); + } + else + { + runtime.push(-1); + } + } + else + { + runtime.push(-1); + } + } + }; + + template + class OpModDisposition : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + +// Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); + + /// \todo modify disposition towards the player + } + }; + const int numberOfAttributes = 8; const int opcodeGetAttribute = 0x2000027; @@ -377,6 +536,14 @@ namespace MWScript const int opcodeGetSpell = 0x200014b; const int opcodeGetSpellExplicit = 0x200014c; + const int opcodePCRaiseRank = 0x2000b; + const int opcodePCLowerRank = 0x2000c; + const int opcodePCJoinFaction = 0x2000d; + const int opcodeGetPCRank = 0x2000e; + const int opcodeGetPCRankExplicit = 0x2000f; + const int opcodeModDisposition = 0x200014d; + const int opcodeModDispositionExplicit = 0x200014e; + void registerExtensions (Compiler::Extensions& extensions) { static const char *attributes[numberOfAttributes] = @@ -452,6 +619,13 @@ namespace MWScript extensions.registerInstruction ("removespell", "c", opcodeRemoveSpell, opcodeRemoveSpellExplicit); extensions.registerFunction ("getspell", 'l', "c", opcodeGetSpell, opcodeGetSpellExplicit); + + extensions.registerInstruction("pcraiserank","/S",opcodePCRaiseRank); + extensions.registerInstruction("pclowerrank","/S",opcodePCLowerRank); + extensions.registerInstruction("pcjoinfaction","/S",opcodePCJoinFaction); + extensions.registerInstruction("moddisposition","l",opcodeModDisposition, + opcodeModDispositionExplicit); + extensions.registerFunction("getpcrank",'l',"/S",opcodeGetPCRank,opcodeGetPCRankExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -515,6 +689,14 @@ namespace MWScript new OpRemoveSpell); interpreter.installSegment5 (opcodeGetSpell, new OpGetSpell); interpreter.installSegment5 (opcodeGetSpellExplicit, new OpGetSpell); + + interpreter.installSegment3(opcodePCRaiseRank,new OpPCRaiseRank); + interpreter.installSegment3(opcodePCLowerRank,new OpPCLowerRank); + interpreter.installSegment3(opcodePCJoinFaction,new OpPCJoinFaction); + interpreter.installSegment5(opcodeModDisposition,new OpModDisposition); + interpreter.installSegment5(opcodeModDispositionExplicit,new OpModDisposition); + interpreter.installSegment3(opcodeGetPCRank,new OpGetPCRank); + interpreter.installSegment3(opcodeGetPCRankExplicit,new OpGetPCRank); } } } diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 650418201..230f7d69a 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -72,7 +72,7 @@ void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& ite /// \todo restack item previously in this slot (if required) /// \todo unstack item pointed to by iterator if required) - + mSlots[slot] = iterator; flagAsModified(); diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 16d19f65f..80cb3284b 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -21,11 +21,13 @@ namespace MWWorld PhysicsSystem::PhysicsSystem(OEngine::Render::OgreRenderer &_rend) : mRender(_rend), mEngine(0), mFreeFly (true) { - playerphysics = new playerMove; + + playerphysics = new playerMove; // Create physics. shapeLoader is deleted by the physic engine NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader(); mEngine = new OEngine::Physic::PhysicEngine(shapeLoader); - playerphysics->mEngine = mEngine; + playerphysics->mEngine = mEngine; + } PhysicsSystem::~PhysicsSystem() @@ -65,6 +67,13 @@ namespace MWWorld return mEngine->rayTest2(from,to); } + void PhysicsSystem::setCurrentWater(bool hasWater, int waterHeight){ + playerphysics->hasWater = hasWater; + if(hasWater){ + playerphysics->waterHeight = waterHeight; + } + + } btVector3 PhysicsSystem::getRayPoint(float extent) { @@ -102,10 +111,12 @@ namespace MWWorld act->setWalkDirection(btVector3(0,0,0)); } playerMove::playercmd& pm_ref = playerphysics->cmd; + + pm_ref.rightmove = 0; + pm_ref.forwardmove = 0; + pm_ref.upmove = 0; + - pm_ref.rightmove = 0; - pm_ref.forwardmove = 0; - pm_ref.upmove = 0; //playerphysics->ps.move_type = PM_NOCLIP; for (std::vector >::const_iterator iter (actors.begin()); iter!=actors.end(); ++iter) @@ -123,19 +134,22 @@ namespace MWWorld Ogre::Quaternion pitchQuat = pitchNode->getOrientation(); Ogre::Quaternion both = yawQuat * pitchQuat; - playerphysics->ps.viewangles.x = 0; + playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees(); playerphysics->ps.viewangles.z = 0; - playerphysics->ps.viewangles.y = both.getYaw().valueDegrees() *-1 + 90; - //playerphysics->ps.viewangles.z = both.getPitch().valueDegrees(); + playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90; + + if(mFreeFly) { Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y); + pm_ref.rightmove = -dir1.x; pm_ref.forwardmove = dir1.z; pm_ref.upmove = dir1.y; + //std::cout << "Current angle" << yawQuat.getYaw().valueDegrees() - 90<< "\n"; @@ -157,13 +171,15 @@ namespace MWWorld dir = 0.025*(quat*dir1); } - Pmove(playerphysics); + //set the walk direction act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y)); } mEngine->stepSimulation(duration); Pmove(playerphysics); + + std::vector< std::pair > response; for(std::map::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++) { @@ -178,6 +194,8 @@ namespace MWWorld //coord = Ogre::Vector3(coord.x, coord.z, coord.y); //x, z, -y } + + response.push_back(std::pair(it->first, coord)); } @@ -261,6 +279,7 @@ namespace MWWorld { if(playerphysics->ps.move_type==PM_NOCLIP) playerphysics->ps.move_type=PM_NORMAL; + else playerphysics->ps.move_type=PM_NOCLIP; for(std::map::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++) diff --git a/apps/openmw/mwworld/physicssystem.hpp b/apps/openmw/mwworld/physicssystem.hpp index d8e7e125a..cb559f000 100644 --- a/apps/openmw/mwworld/physicssystem.hpp +++ b/apps/openmw/mwworld/physicssystem.hpp @@ -55,12 +55,15 @@ namespace MWWorld void insertActorPhysics(const MWWorld::Ptr&, std::string model); OEngine::Physic::PhysicEngine* getEngine(); + + void setCurrentWater(bool hasWater, int waterHeight); private: OEngine::Render::OgreRenderer &mRender; OEngine::Physic::PhysicEngine* mEngine; bool mFreeFly; - playerMove* playerphysics; + playerMove* playerphysics; + PhysicsSystem (const PhysicsSystem&); PhysicsSystem& operator= (const PhysicsSystem&); diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index ed72a4589..b3af5dd52 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -110,4 +110,5 @@ namespace MWWorld MWWorld::Ptr ptr = getPlayer(); return MWWorld::Class::get(ptr).getNpcStats(ptr).mDrawState; } + } diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 83d379cf6..2f34ded95 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -134,6 +134,8 @@ namespace MWWorld void Scene::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position, bool adjustPlayerPos) { + bool hasWater = cell->cell->data.flags & cell->cell->HasWater; + mPhysics->setCurrentWater(hasWater, cell->cell->water); if (adjustPlayerPos) mWorld->getPlayer().setPos (position.pos[0], position.pos[1], position.pos[2]); diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index f9c6b2fa0..fb0480171 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -27,6 +27,9 @@ const float WeatherGlobals::mSunriseDuration = 2; const float WeatherGlobals::mSunsetDuration = 2; const float WeatherGlobals::mWeatherUpdateTime = 20.f; + +// morrowind sets these per-weather, but since they are only used by 'thunderstorm' +// weather setting anyway, we can just as well set them globally const float WeatherGlobals::mThunderFrequency = .4; const float WeatherGlobals::mThunderThreshold = 0.6; const float WeatherGlobals::mThunderSoundDelay = 0.25; diff --git a/cmake/FindFreetype.cmake b/cmake/FindFreetype.cmake new file mode 100644 index 000000000..fc36d548e --- /dev/null +++ b/cmake/FindFreetype.cmake @@ -0,0 +1,69 @@ +#------------------------------------------------------------------- +# This file is part of the CMake build system for OGRE +# (Object-oriented Graphics Rendering Engine) +# For the latest info, see http://www.ogre3d.org/ +# +# The contents of this file are placed in the public domain. Feel +# free to make use of it in any way you like. +#------------------------------------------------------------------- + +# - Try to find FreeType +# Once done, this will define +# +# FREETYPE_FOUND - system has FreeType +# FREETYPE_INCLUDE_DIRS - the FreeType include directories +# FREETYPE_LIBRARIES - link these to use FreeType + +include(FindPkgMacros) +findpkg_begin(FREETYPE) + +# Get path, convert backslashes as ${ENV_${var}} +getenv_path(FREETYPE_HOME) + +# construct search paths +set(FREETYPE_PREFIX_PATH ${FREETYPE_HOME} ${ENV_FREETYPE_HOME}) +create_search_paths(FREETYPE) +# redo search if prefix path changed +clear_if_changed(FREETYPE_PREFIX_PATH + FREETYPE_LIBRARY_FWK + FREETYPE_LIBRARY_REL + FREETYPE_LIBRARY_DBG + FREETYPE_INCLUDE_DIR +) + +set(FREETYPE_LIBRARY_NAMES freetype2311 freetype239 freetype238 freetype235 freetype219 freetype) +get_debug_names(FREETYPE_LIBRARY_NAMES) + +use_pkgconfig(FREETYPE_PKGC freetype2) + +# prefer static library over framework +set(CMAKE_FIND_FRAMEWORK "LAST") + +message(STATUS "CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}") +findpkg_framework(FREETYPE) +message(STATUS "CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}") + +find_path(FREETYPE_INCLUDE_DIR NAMES freetype/freetype.h HINTS ${FREETYPE_INC_SEARCH_PATH} ${FREETYPE_PKGC_INCLUDE_DIRS} PATH_SUFFIXES freetype2) +find_path(FREETYPE_FT2BUILD_INCLUDE_DIR NAMES ft2build.h HINTS ${FREETYPE_INC_SEARCH_PATH} ${FREETYPE_PKGC_INCLUDE_DIRS}) + +if (SYMBIAN) +set(ORIGINAL_CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH}) +set(CMAKE_PREFIX_PATH ${CMAKE_SYSYEM_OUT_DIR}) +message(STATUS "Lib will be searched in Symbian out dir: ${CMAKE_SYSYEM_OUT_DIR}") +endif (SYMBIAN) +find_library(FREETYPE_LIBRARY_REL NAMES ${FREETYPE_LIBRARY_NAMES} HINTS ${FREETYPE_LIB_SEARCH_PATH} ${FREETYPE_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" release relwithdebinfo minsizerel) +find_library(FREETYPE_LIBRARY_DBG NAMES ${FREETYPE_LIBRARY_NAMES_DBG} HINTS ${FREETYPE_LIB_SEARCH_PATH} ${FREETYPE_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" debug) +if (SYMBIAN) +set(CMAKE_PREFIX_PATH ${ORIGINAL_CMAKE_PREFIX_PATH}) +endif (SYMBIAN) + +make_library_set(FREETYPE_LIBRARY) + +findpkg_finish(FREETYPE) +mark_as_advanced(FREETYPE_FT2BUILD_INCLUDE_DIR) +if (NOT FREETYPE_FT2BUILD_INCLUDE_DIR STREQUAL FREETYPE_INCLUDE_DIR) + set(FREETYPE_INCLUDE_DIRS ${FREETYPE_INCLUDE_DIRS} ${FREETYPE_FT2BUILD_INCLUDE_DIR}) +endif () + +# Reset framework finding +set(CMAKE_FIND_FRAMEWORK "FIRST") diff --git a/cmake/FindMyGUI.cmake b/cmake/FindMyGUI.cmake index 6731d584c..c79ee5998 100644 --- a/cmake/FindMyGUI.cmake +++ b/cmake/FindMyGUI.cmake @@ -82,37 +82,49 @@ findpkg_finish ( "MYGUI" ) ELSE (WIN32) #Unix CMAKE_MINIMUM_REQUIRED(VERSION 2.4.7 FATAL_ERROR) FIND_PACKAGE(PkgConfig) - IF(MYGUI_STATIC) - PKG_SEARCH_MODULE(MYGUI MYGUIStatic MyGUIStatic) - IF (MYGUI_INCLUDE_DIRS) - SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS}) - SET(MYGUI_LIB_DIR ${MYGUI_LIBDIR}) - SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") - SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") - ELSE (MYGUI_INCLUDE_DIRS) - FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) - FIND_LIBRARY(MYGUI_LIBRARIES myguistatic PATHS /usr/lib /usr/local/lib) - SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") - SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) - STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") - STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") - ENDIF (MYGUI_INCLUDE_DIRS) - ELSE(MYGUI_STATIC) - PKG_SEARCH_MODULE(MYGUI MYGUI MyGUI) - IF (MYGUI_INCLUDE_DIRS) - SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS}) - SET(MYGUI_LIB_DIR ${MYGUI_LIBDIR}) - SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") - SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") - ELSE (MYGUI_INCLUDE_DIRS) - FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) - FIND_LIBRARY(MYGUI_LIBRARIES mygui PATHS /usr/lib /usr/local/lib) - SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") - SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) - STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") - STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") - ENDIF (MYGUI_INCLUDE_DIRS) - ENDIF(MYGUI_STATIC) + IF(MYGUI_STATIC) + # don't use pkgconfig on OS X, find freetype & append it's libs to resulting MYGUI_LIBRARIES + IF (NOT APPLE) + PKG_SEARCH_MODULE(MYGUI MYGUIStatic MyGUIStatic) + IF (MYGUI_INCLUDE_DIRS) + SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS}) + SET(MYGUI_LIB_DIR ${MYGUI_LIBDIR}) + SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") + SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") + ELSE (MYGUI_INCLUDE_DIRS) + FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) + FIND_LIBRARY(MYGUI_LIBRARIES myguistatic PATHS /usr/lib /usr/local/lib) + SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") + SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) + STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") + STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") + ENDIF (MYGUI_INCLUDE_DIRS) + ELSE (NOT APPLE) + SET(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${MYGUI_DEPENDENCIES_DIR} ${OGRE_DEPENDENCIES_DIR}) + FIND_PACKAGE(freetype) + FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) + FIND_LIBRARY(MYGUI_LIBRARIES MyGUIEngineStatic PATHS /usr/lib /usr/local/lib) + SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") + SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) + STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") + STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") + ENDIF (NOT APPLE) + ELSE(MYGUI_STATIC) + PKG_SEARCH_MODULE(MYGUI MYGUI MyGUI) + IF (MYGUI_INCLUDE_DIRS) + SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS}) + SET(MYGUI_LIB_DIR ${MYGUI_LIBDIR}) + SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") + SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") + ELSE (MYGUI_INCLUDE_DIRS) + FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI) + FIND_LIBRARY(MYGUI_LIBRARIES mygui PATHS /usr/lib /usr/local/lib) + SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform") + SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES}) + STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}") + STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}") + ENDIF (MYGUI_INCLUDE_DIRS) + ENDIF(MYGUI_STATIC) ENDIF (WIN32) #Do some preparation @@ -120,17 +132,23 @@ SEPARATE_ARGUMENTS(MYGUI_INCLUDE_DIRS) SEPARATE_ARGUMENTS(MYGUI_LIBRARIES) SEPARATE_ARGUMENTS(MYGUI_PLATFORM_LIBRARIES) +SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} ${FREETYPE_LIBRARIES}) + SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS} CACHE PATH "") SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "") SET(MYGUI_PLATFORM_LIBRARIES ${MYGUI_PLATFORM_LIBRARIES} CACHE STRING "") SET(MYGUI_LIB_DIR ${MYGUI_LIB_DIR} CACHE PATH "") -IF (MYGUI_INCLUDE_DIRS AND MYGUI_LIBRARIES) +IF (NOT APPLE OR NOT MYGUI_STATIC) # we need explicit freetype libs only on OS X for static build, for other cases just make it TRUE + SET(FREETYPE_LIBRARIES TRUE) +ENDIF (NOT APPLE OR NOT MYGUI_STATIC) + +IF (MYGUI_INCLUDE_DIRS AND MYGUI_LIBRARIES AND FREETYPE_LIBRARIES) SET(MYGUI_FOUND TRUE) -ENDIF (MYGUI_INCLUDE_DIRS AND MYGUI_LIBRARIES) +ENDIF (MYGUI_INCLUDE_DIRS AND MYGUI_LIBRARIES AND FREETYPE_LIBRARIES) IF (MYGUI_FOUND) -MARK_AS_ADVANCED(MYGUI_LIB_DIR) + MARK_AS_ADVANCED(MYGUI_LIB_DIR) IF (NOT MYGUI_FIND_QUIETLY) MESSAGE(STATUS " libraries : ${MYGUI_LIBRARIES} from ${MYGUI_LIB_DIR}") MESSAGE(STATUS " includes : ${MYGUI_INCLUDE_DIRS}") diff --git a/components/bsa/bsa_archive.cpp b/components/bsa/bsa_archive.cpp index 0e3563b26..fa197d960 100644 --- a/components/bsa/bsa_archive.cpp +++ b/components/bsa/bsa_archive.cpp @@ -79,7 +79,7 @@ class DirArchive: public Ogre::FileSystemArchive { passed = filename.substr(0, filename.length() - 2); } - if(filename.at(filename.length() - 2) == '>') + if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':') passed = filename.substr(0, filename.length() - 6); copy = passed; } @@ -232,7 +232,7 @@ public: { passed = filename.substr(0, filename.length() - 2); } - if(filename.at(filename.length() - 2) == '>') + if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':') passed = filename.substr(0, filename.length() - 6); // Open the file StreamPtr strm = narc->getFile(passed.c_str()); @@ -254,7 +254,7 @@ bool exists(const String& filename) { { passed = filename.substr(0, filename.length() - 2); } - if(filename.at(filename.length() - 2) == '>') + if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':') passed = filename.substr(0, filename.length() - 6); return arc.exists(passed.c_str()); diff --git a/components/esm/loadarmo.cpp b/components/esm/loadarmo.cpp index ddc25e176..8b559b10f 100644 --- a/components/esm/loadarmo.cpp +++ b/components/esm/loadarmo.cpp @@ -11,6 +11,7 @@ void PartReferenceList::load(ESMReader &esm) esm.getHT(pr.part); // The INDX byte pr.male = esm.getHNOString("BNAM"); pr.female = esm.getHNOString("CNAM"); + parts.push_back(pr); } } diff --git a/components/esm/loadclot.cpp b/components/esm/loadclot.cpp index 1d6c9d4a1..16fd0598c 100644 --- a/components/esm/loadclot.cpp +++ b/components/esm/loadclot.cpp @@ -13,6 +13,7 @@ void Clothing::load(ESMReader &esm) icon = esm.getHNOString("ITEX"); parts.load(esm); + enchant = esm.getHNOString("ENAM"); } diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index ab6a708c0..05d35b85f 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -1211,6 +1211,7 @@ void NIFLoader::loadResource(Resource *resource) char suffix = name.at(name.length() - 2); bool addAnim = true; bool hasAnim = false; + bool linkSkeleton = true; //bool baddin = false; bNiTri = true; if(name == "meshes\\base_anim.nif" || name == "meshes\\base_animkna.nif") @@ -1241,6 +1242,17 @@ void NIFLoader::loadResource(Resource *resource) addAnim = false; } + else if(suffix == ':') + { + //baddin = true; + linkSkeleton = false; + bNiTri = true; + std::string sub = name.substr(name.length() - 6, 4); + + if(sub.compare("0000") != 0) + addAnim = false; + + } switch(name.at(name.length() - 1)) { @@ -1379,7 +1391,7 @@ void NIFLoader::loadResource(Resource *resource) } //Don't link on npc parts to eliminate redundant skeletons //Will have to be changed later slightly for robes/skirts - if(triname == "") + if(linkSkeleton) mesh->_notifySkeleton(mSkel); } } diff --git a/files/openmw.desktop b/files/openmw.desktop index 8643d4b13..234f660c6 100644 --- a/files/openmw.desktop +++ b/files/openmw.desktop @@ -1,5 +1,5 @@ [Desktop Entry] -Version=0.11 +Version=${OPENMW_VERSION} Type=Application Name=OpenMW Launcher GenericName=Role Playing Game diff --git a/files/plugins.cfg.mac b/files/plugins.cfg.mac index 0c16bddaf..322070832 100644 --- a/files/plugins.cfg.mac +++ b/files/plugins.cfg.mac @@ -1,12 +1,12 @@ # Defines plugins to load # Define plugin folder -PluginFolder= +PluginFolder=${OGRE_PLUGIN_DIR} # Define plugins -Plugin=RenderSystem_GL.dylib -Plugin=Plugin_ParticleFX.dylib -Plugin=Plugin_OctreeSceneManager.dylib -Plugin=Plugin_CgProgramManager +Plugin=RenderSystem_GL.1.8.0 +Plugin=Plugin_ParticleFX.1.8.0 +Plugin=Plugin_OctreeSceneManager.1.8.0 +Plugin=Plugin_CgProgramManager.1.8.0 diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 4d2d46fca..553a82e49 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -93,7 +93,7 @@ rtt size = 512 reflect terrain = true reflect statics = false reflect small statics = false -reflect actors = true +reflect actors = false reflect misc = false # Enable underwater effect. It is not resource intensive, so only disable it if you have problems. diff --git a/libs/openengine/.gitmodules b/libs/openengine/.gitmodules new file mode 100644 index 000000000..0a9a9121f --- /dev/null +++ b/libs/openengine/.gitmodules @@ -0,0 +1,3 @@ +[submodule "mangle"] + path = mangle + url = git://github.com/korslund/mangle diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 2968a2f8c..a17498176 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -164,8 +164,9 @@ namespace Physic // The actual physics solver solver = new btSequentialImpulseConstraintSolver; + //btOverlappingPairCache* pairCache = new btSortedOverlappingPairCache(); + pairCache = new btSortedOverlappingPairCache(); - //pairCache = new btSortedOverlappingPairCache(); //pairCache->setInternalGhostPairCallback( new btGhostPairCallback() ); broadphase = new btDbvtBroadphase(); @@ -253,7 +254,7 @@ namespace Physic delete collisionConfiguration; delete dispatcher; delete broadphase; - //delete pairCache; + delete pairCache; delete mShapeLoader; } diff --git a/libs/openengine/bullet/pmove.cpp b/libs/openengine/bullet/pmove.cpp index dcb2e9f9b..db78049cd 100644 --- a/libs/openengine/bullet/pmove.cpp +++ b/libs/openengine/bullet/pmove.cpp @@ -632,6 +632,8 @@ float PM_CmdScale(playerMove::playercmd* const cmd) total = sqrtf( (const float)(cmd->forwardmove * cmd->forwardmove + cmd->rightmove * cmd->rightmove + cmd->upmove * cmd->upmove) ); scale = (float)pm->ps.speed * max / ( 127.0f * total ); + if(pm->ps.move_type == PM_NOCLIP) + scale *= 2; return scale; } @@ -1125,7 +1127,7 @@ void AngleVectors( const Ogre::Vector3& angles, Ogre::Vector3* const forward, Og { right->x = (-1 * sr * sp * cy + -1 * cr * -sy); right->y = (-1 * sr * sp * sy + -1 * cr * cy); - right->z = 0.0f;//-1 * sp * cp; + right->z = 0; } if (up) { @@ -1713,11 +1715,11 @@ void PM_SetWaterLevel( playerMove* const pm ) point[1] = pm->ps->origin[1]; point[2] = pm->ps->origin[2] + MINS_Z + 1; */ point.x = pm->ps.origin.x; - point.y = pm->ps.origin.y + MINS_Z + 1; - point.z = pm->ps.origin.z; + point.y = pm->ps.origin.y; + point.z = pm->ps.origin.z + MINS_Z + 1; //cont = pm->pointcontents( point, pm->ps->clientNum ); - bool checkWater = (pml.hasWater && pml.waterHeight > point.y); + bool checkWater = (pml.hasWater && pml.waterHeight > point.z); //if ( cont & MASK_WATER ) if ( checkWater) { @@ -1727,14 +1729,14 @@ void PM_SetWaterLevel( playerMove* const pm ) pm->ps.watertype = CONTENTS_WATER;//cont; pm->ps.waterlevel = WL_ANKLE; //point[2] = pm->ps->origin[2] + MINS_Z + sample1; - point.y = pm->ps.origin.y + MINS_Z + sample1; + point.z = pm->ps.origin.z + MINS_Z + sample1; //cont = pm->pointcontents (point, pm->ps->clientNum ); //if ( cont & MASK_WATER ) if (checkWater) { pm->ps.waterlevel = WL_WAIST; //point[2] = pm->ps->origin[2] + MINS_Z + sample2; - point.y = pm->ps.origin.y + MINS_Z + sample2; + point.z = pm->ps.origin.z + MINS_Z + sample2; //cont = pm->pointcontents (point, pm->ps->clientNum ); //if ( cont & MASK_WATER ) if (checkWater ) diff --git a/libs/openengine/bullet/pmove.h b/libs/openengine/bullet/pmove.h index 30572a92a..304572b02 100644 --- a/libs/openengine/bullet/pmove.h +++ b/libs/openengine/bullet/pmove.h @@ -55,7 +55,7 @@ static const Ogre::Vector3 halfExtents(14.64f * 2, 14.24f * 2, 33.25f * 2); #define CONTENTS_FOG 64 static const float pm_accelerate = 10.0f; static const float pm_stopspeed = 100.0f; -static const float pm_friction = 6.0f; +static const float pm_friction = 12.0f; static const float pm_flightfriction = 3.0f; static const float pm_waterfriction = 1.0f; static const float pm_airaccelerate = 1.0f; @@ -90,7 +90,7 @@ struct playerMove { struct playerStruct { - playerStruct() : gravity(800.0f), speed(320.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0) + playerStruct() : gravity(800.0f), speed(480.0f), pmove_framecount(20), groundEntityNum(ENTITYNUM_NONE), commandTime(40), move_type(PM_NOCLIP), pm_time(0) { origin = Ogre::Vector3(733.164f,900.0f, 839.432f); velocity = Ogre::Vector3(0.0f, 0.0f, 0.0f); diff --git a/libs/openengine/gui/manager.cpp b/libs/openengine/gui/manager.cpp index 2d84ac804..1bf8ec325 100644 --- a/libs/openengine/gui/manager.cpp +++ b/libs/openengine/gui/manager.cpp @@ -18,7 +18,6 @@ void MyGUIManager::setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool // manager before the main gui system itself, otherwise the main // object will get the chance to spit out a few messages before we // can able to disable it. - /// \todo - can't avoid this with MyGUI 3.2? std::string theLogFile = std::string(MYGUI_PLATFORM_LOG_FILENAME); if(!logDir.empty()) @@ -26,9 +25,9 @@ void MyGUIManager::setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool // Set up OGRE platform. We might make this more generic later. mPlatform = new OgrePlatform(); + LogManager::getInstance().setSTDOutputEnabled(logging); mPlatform->initialise(wnd, mgr, "General", theLogFile); - LogManager::getInstance().setSTDOutputEnabled(logging); // Create GUI mGui = new Gui(); diff --git a/readme.txt b/readme.txt index e1c24ab52..52c4e11a2 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ OpenMW: A reimplementation of The Elder Scrolls III: Morrowind OpenMW is an attempt at recreating the engine for the popular role-playing game Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work. -Version: 0.13.0 +Version: 0.14.0 License: GPL (see GPL3.txt for more information) Website: http://www.openmw.org @@ -64,8 +64,6 @@ Allowed options: --start arg (=Beshara) set initial cell --master arg master file(s) --plugin arg plugin file(s) - --fps [=arg(=1)] (=0) fps counter detail (0 = off, 1 = fps counter - , 2 = full detail) --anim-verbose [=arg(=1)] (=0) output animation indices files --debug [=arg(=1)] (=0) debug mode --nosound [=arg(=1)] (=0) disable all sounds @@ -90,6 +88,7 @@ Allowed options: win1252 - Western European (Latin) alphabet, used by default --report-focus [=arg(=1)] (=0) write name of focussed object to cout + --fallback arg fallback values CREDITS @@ -134,6 +133,36 @@ Thanks to Kevin Ryan for kindly providing us with the icon used for the Data Fil CHANGELOG +0.14.0 + +Bug #1: Meshes rendered with wrong orientation +Bug #6/Task #220: Picking up small objects doesn't always work +Bug #127: tcg doesn't work +Bug #178: Compablity problems with Ogre 1.8.0 RC 1 +Bug #211: Wireframe mode (toggleWireframe command) should not apply to Console & other UI +Bug #227: Terrain crashes when moving away from predefined cells +Bug #229: On OS X Launcher cannot launch game if path to binary contains spaces +Bug #235: TGA texture loading problem +Bug #246: wireframe mode does not work in water +Feature #8/#232: Water Rendering +Feature #13: Terrain Rendering +Feature #37: Render Path Grid +Feature #66: Factions +Feature #77: Local Map +Feature #78: Compass/Mini-Map +Feature #97: Render Clothing/Armour +Feature #121: Window Pinning +Feature #205: Auto equip +Feature #217: Contiainer should track changes to its content +Feature #221: NPC Dialogue Window Enhancements +Feature #233: Game settings manager +Feature #240: Spell List and selected spell (no GUI yet) +Feature #243: Draw State +Task #113: Morrowind.ini Importer +Task #215: Refactor the sound code +Task #216: Update MyGUI + + 0.13.0 Bug #145: Fixed sound problems after cell change