mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 19:19:56 +00:00
Merge pull request #333 from OpenMW/master
Add OpenMW commits up to 11 Nov 2017
This commit is contained in:
commit
01db219de4
10 changed files with 76 additions and 35 deletions
|
@ -188,6 +188,8 @@ namespace MWInput
|
||||||
|
|
||||||
void InputManager::handleGuiArrowKey(int action)
|
void InputManager::handleGuiArrowKey(int action)
|
||||||
{
|
{
|
||||||
|
if (SDL_IsTextInputActive())
|
||||||
|
return;
|
||||||
MyGUI::KeyCode key;
|
MyGUI::KeyCode key;
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
|
@ -1159,7 +1161,10 @@ namespace MWInput
|
||||||
void InputManager::activate()
|
void InputManager::activate()
|
||||||
{
|
{
|
||||||
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
|
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||||
|
{
|
||||||
|
if (!SDL_IsTextInputActive())
|
||||||
MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Return, 0);
|
MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Return, 0);
|
||||||
|
}
|
||||||
else if (mControlSwitch["playercontrols"])
|
else if (mControlSwitch["playercontrols"])
|
||||||
mPlayer->activate();
|
mPlayer->activate();
|
||||||
}
|
}
|
||||||
|
|
|
@ -536,7 +536,7 @@ namespace MWRender
|
||||||
return mKeyframes->mTextKeys;
|
return mKeyframes->mTextKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animation::addAnimSource(const std::string &model)
|
void Animation::addAnimSource(const std::string &model, const std::string& baseModel)
|
||||||
{
|
{
|
||||||
std::string kfname = model;
|
std::string kfname = model;
|
||||||
Misc::StringUtils::lowerCaseInPlace(kfname);
|
Misc::StringUtils::lowerCaseInPlace(kfname);
|
||||||
|
@ -565,7 +565,7 @@ namespace MWRender
|
||||||
NodeMap::const_iterator found = nodeMap.find(bonename);
|
NodeMap::const_iterator found = nodeMap.find(bonename);
|
||||||
if (found == nodeMap.end())
|
if (found == nodeMap.end())
|
||||||
{
|
{
|
||||||
std::cerr << "Warning: addAnimSource: can't find bone '" + bonename << "' in " << model << " (referenced by " << kfname << ")" << std::endl;
|
std::cerr << "Warning: addAnimSource: can't find bone '" + bonename << "' in " << baseModel << " (referenced by " << kfname << ")" << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1668,7 +1668,7 @@ namespace MWRender
|
||||||
{
|
{
|
||||||
setObjectRoot(model, false, false, false);
|
setObjectRoot(model, false, false, false);
|
||||||
if (animated)
|
if (animated)
|
||||||
addAnimSource(model);
|
addAnimSource(model, model);
|
||||||
|
|
||||||
if (!ptr.getClass().getEnchantment(ptr).empty())
|
if (!ptr.getClass().getEnchantment(ptr).empty())
|
||||||
addGlow(mObjectRoot, getEnchantmentColor(ptr));
|
addGlow(mObjectRoot, getEnchantmentColor(ptr));
|
||||||
|
|
|
@ -309,11 +309,12 @@ protected:
|
||||||
*/
|
*/
|
||||||
void setObjectRoot(const std::string &model, bool forceskeleton, bool baseonly, bool isCreature);
|
void setObjectRoot(const std::string &model, bool forceskeleton, bool baseonly, bool isCreature);
|
||||||
|
|
||||||
/** Adds the keyframe controllers in the specified model as a new animation source. Note that the .nif
|
/** Adds the keyframe controllers in the specified model as a new animation source.
|
||||||
* file extension will be replaced with .kf.
|
|
||||||
* @note Later added animation sources have the highest priority when it comes to finding a particular animation.
|
* @note Later added animation sources have the highest priority when it comes to finding a particular animation.
|
||||||
|
* @param model The file to add the keyframes for. Note that the .nif file extension will be replaced with .kf.
|
||||||
|
* @param baseModel The filename of the mObjectRoot, only used for error messages.
|
||||||
*/
|
*/
|
||||||
void addAnimSource(const std::string &model);
|
void addAnimSource(const std::string &model, const std::string& baseModel);
|
||||||
|
|
||||||
/** Adds an additional light to the given node using the specified ESM record. */
|
/** Adds an additional light to the given node using the specified ESM record. */
|
||||||
void addExtraLight(osg::ref_ptr<osg::Group> parent, const ESM::Light *light);
|
void addExtraLight(osg::ref_ptr<osg::Group> parent, const ESM::Light *light);
|
||||||
|
|
|
@ -33,8 +33,8 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr,
|
||||||
setObjectRoot(model, false, false, true);
|
setObjectRoot(model, false, false, true);
|
||||||
|
|
||||||
if((ref->mBase->mFlags&ESM::Creature::Bipedal))
|
if((ref->mBase->mFlags&ESM::Creature::Bipedal))
|
||||||
addAnimSource("meshes\\xbase_anim.nif");
|
addAnimSource("meshes\\xbase_anim.nif", model);
|
||||||
addAnimSource(model);
|
addAnimSource(model, model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,8 +51,8 @@ CreatureWeaponAnimation::CreatureWeaponAnimation(const MWWorld::Ptr &ptr, const
|
||||||
setObjectRoot(model, true, false, true);
|
setObjectRoot(model, true, false, true);
|
||||||
|
|
||||||
if((ref->mBase->mFlags&ESM::Creature::Bipedal))
|
if((ref->mBase->mFlags&ESM::Creature::Bipedal))
|
||||||
addAnimSource("meshes\\xbase_anim.nif");
|
addAnimSource("meshes\\xbase_anim.nif", model);
|
||||||
addAnimSource(model);
|
addAnimSource(model, model);
|
||||||
|
|
||||||
mPtr.getClass().getInventoryStore(mPtr).setInvListener(this, mPtr);
|
mPtr.getClass().getInventoryStore(mPtr).setInvListener(this, mPtr);
|
||||||
|
|
||||||
|
|
|
@ -482,25 +482,25 @@ void NpcAnimation::updateNpcBase()
|
||||||
{
|
{
|
||||||
const std::string base = "meshes\\xbase_anim.nif";
|
const std::string base = "meshes\\xbase_anim.nif";
|
||||||
if (smodel != base)
|
if (smodel != base)
|
||||||
addAnimSource(base);
|
addAnimSource(base, smodel);
|
||||||
|
|
||||||
addAnimSource(smodel);
|
addAnimSource(smodel, smodel);
|
||||||
|
|
||||||
if(!isWerewolf)
|
if(!isWerewolf)
|
||||||
{
|
{
|
||||||
if(mNpc->mModel.length() > 0)
|
if(mNpc->mModel.length() > 0)
|
||||||
addAnimSource(Misc::ResourceHelpers::correctActorModelPath("meshes\\" + mNpc->mModel, mResourceSystem->getVFS()));
|
addAnimSource(Misc::ResourceHelpers::correctActorModelPath("meshes\\" + mNpc->mModel, mResourceSystem->getVFS()), smodel);
|
||||||
if(Misc::StringUtils::lowerCase(mNpc->mRace).find("argonian") != std::string::npos)
|
if(Misc::StringUtils::lowerCase(mNpc->mRace).find("argonian") != std::string::npos)
|
||||||
addAnimSource("meshes\\xargonian_swimkna.nif");
|
addAnimSource("meshes\\xargonian_swimkna.nif", smodel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const std::string base = "meshes\\xbase_anim.1st.nif";
|
const std::string base = "meshes\\xbase_anim.1st.nif";
|
||||||
if (smodel != base)
|
if (smodel != base)
|
||||||
addAnimSource(base);
|
addAnimSource(base, smodel);
|
||||||
|
|
||||||
addAnimSource(smodel);
|
addAnimSource(smodel, smodel);
|
||||||
|
|
||||||
mObjectRoot->setNodeMask(Mask_FirstPerson);
|
mObjectRoot->setNodeMask(Mask_FirstPerson);
|
||||||
mObjectRoot->addCullCallback(new OverrideFieldOfViewCallback(mFirstPersonFieldOfView));
|
mObjectRoot->addCullCallback(new OverrideFieldOfViewCallback(mFirstPersonFieldOfView));
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "escape.hpp"
|
#include "escape.hpp"
|
||||||
|
|
||||||
#include <boost/algorithm/string/replace.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
namespace Files
|
namespace Files
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,7 @@ namespace Files
|
||||||
const int escape_hash_filter::sEscapeIdentifier = 'a';
|
const int escape_hash_filter::sEscapeIdentifier = 'a';
|
||||||
const int escape_hash_filter::sHashIdentifier = 'h';
|
const int escape_hash_filter::sHashIdentifier = 'h';
|
||||||
|
|
||||||
escape_hash_filter::escape_hash_filter() : mNext(), mPrevious(), mSeenNonWhitespace(false), mFinishLine(false)
|
escape_hash_filter::escape_hash_filter() : mSeenNonWhitespace(false), mFinishLine(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,8 +26,14 @@ namespace Files
|
||||||
|
|
||||||
std::string EscapeHashString::processString(const std::string & str)
|
std::string EscapeHashString::processString(const std::string & str)
|
||||||
{
|
{
|
||||||
std::string temp = boost::replace_all_copy<std::string>(str, std::string() + (char)escape_hash_filter::sEscape + (char)escape_hash_filter::sHashIdentifier, "#");
|
std::string temp = str;
|
||||||
boost::replace_all(temp, std::string() + (char)escape_hash_filter::sEscape + (char)escape_hash_filter::sEscapeIdentifier, std::string((char)escape_hash_filter::sEscape, 1));
|
|
||||||
|
static const char hash[] = { escape_hash_filter::sEscape, escape_hash_filter::sHashIdentifier };
|
||||||
|
Misc::StringUtils::replaceAll(temp, hash, "#", 2, 1);
|
||||||
|
|
||||||
|
static const char escape[] = { escape_hash_filter::sEscape, escape_hash_filter::sEscapeIdentifier };
|
||||||
|
Misc::StringUtils::replaceAll(temp, escape, "@", 2, 1);
|
||||||
|
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@ namespace Files
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::queue<int> mNext;
|
std::queue<int> mNext;
|
||||||
int mPrevious;
|
|
||||||
|
|
||||||
bool mSeenNonWhitespace;
|
bool mSeenNonWhitespace;
|
||||||
bool mFinishLine;
|
bool mFinishLine;
|
||||||
|
@ -42,11 +41,9 @@ namespace Files
|
||||||
if (mNext.empty())
|
if (mNext.empty())
|
||||||
{
|
{
|
||||||
int character = boost::iostreams::get(src);
|
int character = boost::iostreams::get(src);
|
||||||
bool record = true;
|
|
||||||
if (character == boost::iostreams::WOULD_BLOCK)
|
if (character == boost::iostreams::WOULD_BLOCK)
|
||||||
{
|
{
|
||||||
mNext.push(character);
|
mNext.push(character);
|
||||||
record = false;
|
|
||||||
}
|
}
|
||||||
else if (character == EOF)
|
else if (character == EOF)
|
||||||
{
|
{
|
||||||
|
@ -78,7 +75,7 @@ namespace Files
|
||||||
mFinishLine = true;
|
mFinishLine = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mPrevious == sEscape)
|
else if (character == sEscape)
|
||||||
{
|
{
|
||||||
mNext.push(sEscape);
|
mNext.push(sEscape);
|
||||||
mNext.push(sEscapeIdentifier);
|
mNext.push(sEscapeIdentifier);
|
||||||
|
@ -89,8 +86,6 @@ namespace Files
|
||||||
}
|
}
|
||||||
if (!mSeenNonWhitespace && !isspace(character))
|
if (!mSeenNonWhitespace && !isspace(character))
|
||||||
mSeenNonWhitespace = true;
|
mSeenNonWhitespace = true;
|
||||||
if (record)
|
|
||||||
mPrevious = character;
|
|
||||||
}
|
}
|
||||||
int retval = mNext.front();
|
int retval = mNext.front();
|
||||||
mNext.pop();
|
mNext.pop();
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define MISC_STRINGOPS_H
|
#define MISC_STRINGOPS_H
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
@ -138,6 +139,35 @@ public:
|
||||||
|
|
||||||
return notFound;
|
return notFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Replaces all occurrences of a string in another string.
|
||||||
|
*
|
||||||
|
* @param str The string to operate on.
|
||||||
|
* @param what The string to replace.
|
||||||
|
* @param with The replacement string.
|
||||||
|
* @param whatLen The length of the string to replace.
|
||||||
|
* @param withLen The length of the replacement string.
|
||||||
|
*
|
||||||
|
* @return A reference to the string passed in @p str.
|
||||||
|
*/
|
||||||
|
static std::string &replaceAll(std::string &str, const char *what, const char *with,
|
||||||
|
std::size_t whatLen=std::string::npos, std::size_t withLen=std::string::npos)
|
||||||
|
{
|
||||||
|
if (whatLen == std::string::npos)
|
||||||
|
whatLen = strlen(what);
|
||||||
|
|
||||||
|
if (withLen == std::string::npos)
|
||||||
|
withLen = strlen(with);
|
||||||
|
|
||||||
|
std::size_t found;
|
||||||
|
std::size_t offset = 0;
|
||||||
|
while((found = str.find(what, offset, whatLen)) != std::string::npos)
|
||||||
|
{
|
||||||
|
str.replace(found, whatLen, with, withLen);
|
||||||
|
offset = found + withLen;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -432,13 +432,18 @@ namespace Resource
|
||||||
|
|
||||||
bool canOptimize(const std::string& filename)
|
bool canOptimize(const std::string& filename)
|
||||||
{
|
{
|
||||||
// xmesh.nif can not be optimized because there are keyframes added in post
|
|
||||||
size_t slashpos = filename.find_last_of("\\/");
|
size_t slashpos = filename.find_last_of("\\/");
|
||||||
if (slashpos != std::string::npos && slashpos+1 < filename.size())
|
if (slashpos != std::string::npos && slashpos+1 < filename.size())
|
||||||
{
|
{
|
||||||
std::string basename = filename.substr(slashpos+1);
|
std::string basename = filename.substr(slashpos+1);
|
||||||
|
// xmesh.nif can not be optimized because there are keyframes added in post
|
||||||
if (!basename.empty() && basename[0] == 'x')
|
if (!basename.empty() && basename[0] == 'x')
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// NPC skeleton files can not be optimized because of keyframes added in post
|
||||||
|
// (most of them are usually named like 'xbase_anim.nif' anyway, but not all of them :( )
|
||||||
|
if (basename.compare(0, 9, "base_anim") == 0 || basename.compare(0, 4, "skin") == 0)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For spell VFX, DummyXX nodes must remain intact. Not adding those to reservedNames to avoid being overly cautious - instead, decide on filename
|
// For spell VFX, DummyXX nodes must remain intact. Not adding those to reservedNames to avoid being overly cautious - instead, decide on filename
|
||||||
|
|
|
@ -53,18 +53,17 @@
|
||||||
<Property key="TextAlign" value="Center"/>
|
<Property key="TextAlign" value="Center"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
<Widget type="AutoSizedButton" skin="MW_Button" position="0 60 60 24" name="MaxSaleButton" align="Left Top">
|
<Widget type="HBox" position="0 60 566 24" align="Left Bottom HStretch">
|
||||||
|
<Widget type="AutoSizedButton" skin="MW_Button" name="MaxSaleButton">
|
||||||
<Property key="Caption" value="#{sMaxSale}"/>
|
<Property key="Caption" value="#{sMaxSale}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
<Widget type="HBox" position="0 60 566 24" align="Right Bottom">
|
|
||||||
<Widget type="Widget">
|
<Widget type="Widget">
|
||||||
<UserString key="HStretch" value="true"/>
|
<UserString key="HStretch" value="true"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
<Widget type="AutoSizedButton" skin="MW_Button" name="OfferButton" align="Right Top">
|
<Widget type="AutoSizedButton" skin="MW_Button" name="OfferButton">
|
||||||
<Property key="Caption" value="#{sBarterDialog8}"/>
|
<Property key="Caption" value="#{sBarterDialog8}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
<Widget type="AutoSizedButton" skin="MW_Button" name="CancelButton" align="Right Top">
|
<Widget type="AutoSizedButton" skin="MW_Button" name="CancelButton">
|
||||||
<Property key="Caption" value="#{sCancel}"/>
|
<Property key="Caption" value="#{sCancel}"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
Loading…
Reference in a new issue