Merge pull request #334 from TES3MP/master

Add master commits up to 11 Nov 2017
new-script-api
David Cernat 7 years ago committed by GitHub
commit 700e4d032e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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())
MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Return, 0); {
if (!SDL_IsTextInputActive())
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">
<Property key="Caption" value="#{sMaxSale}"/> <Widget type="AutoSizedButton" skin="MW_Button" name="MaxSaleButton">
</Widget> <Property key="Caption" value="#{sMaxSale}"/>
</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…
Cancel
Save