mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-03 02:09:41 +00:00
Merge branch 'master' of https://github.com/zinnschlag/openmw
Conflicts: apps/openmw/main.cpp
This commit is contained in:
commit
19e5978a01
29 changed files with 208 additions and 143 deletions
|
@ -989,8 +989,7 @@ void Record<ESM::NPC>::print()
|
|||
std::cout << " Faction: " << mData.mFaction << std::endl;
|
||||
std::cout << " Flags: " << npcFlags(mData.mFlags) << std::endl;
|
||||
|
||||
// Seriously?
|
||||
if (mData.mNpdt52.mGold == -10)
|
||||
if (mData.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
|
||||
{
|
||||
std::cout << " Level: " << mData.mNpdt12.mLevel << std::endl;
|
||||
std::cout << " Reputation: " << (int)mData.mNpdt12.mReputation << std::endl;
|
||||
|
@ -1022,7 +1021,7 @@ void Record<ESM::NPC>::print()
|
|||
std::cout << " Luck: " << (int)mData.mNpdt52.mLuck << std::endl;
|
||||
|
||||
std::cout << " Skills:" << std::endl;
|
||||
for (int i = 0; i != 27; i++)
|
||||
for (int i = 0; i != ESM::Skill::Length; i++)
|
||||
std::cout << " " << skillLabel(i) << ": "
|
||||
<< (int)((unsigned char)mData.mNpdt52.mSkills[i]) << std::endl;
|
||||
|
||||
|
|
|
@ -24,7 +24,12 @@ namespace EsmTool
|
|||
bool mPrintPlain;
|
||||
|
||||
public:
|
||||
RecordBase () { mPrintPlain = false; }
|
||||
RecordBase ()
|
||||
: mFlags(0)
|
||||
, mPrintPlain(false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~RecordBase() {}
|
||||
|
||||
const std::string &getId() const {
|
||||
|
|
|
@ -75,14 +75,8 @@ void Launcher::DataFilesPage::saveSettings(const QString &profile)
|
|||
mLauncherSettings.setValue(QString("Profiles/currentprofile"), ui.profilesComboBox->currentText());
|
||||
|
||||
foreach(const ContentSelectorModel::EsmFile *item, items) {
|
||||
|
||||
if (item->gameFiles().size() == 0) {
|
||||
mLauncherSettings.setMultiValue(QString("Profiles/") + profileName, item->fileName());
|
||||
mGameSettings.setMultiValue(QString("content"), item->fileName());
|
||||
} else {
|
||||
mLauncherSettings.setMultiValue(QString("Profiles/") + profileName, item->fileName());
|
||||
mGameSettings.setMultiValue(QString("content"), item->fileName());
|
||||
}
|
||||
mLauncherSettings.setMultiValue(QString("Profiles/") + profileName, item->fileName());
|
||||
mGameSettings.setMultiValue(QString("content"), item->fileName());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,8 +7,6 @@ namespace CSMFilter
|
|||
{
|
||||
class AndNode : public NAryNode
|
||||
{
|
||||
bool mAnd;
|
||||
|
||||
public:
|
||||
|
||||
AndNode (const std::vector<boost::shared_ptr<Node> >& nodes);
|
||||
|
|
|
@ -7,8 +7,6 @@ namespace CSMFilter
|
|||
{
|
||||
class OrNode : public NAryNode
|
||||
{
|
||||
bool mAnd;
|
||||
|
||||
public:
|
||||
|
||||
OrNode (const std::vector<boost::shared_ptr<Node> >& nodes);
|
||||
|
|
|
@ -61,11 +61,11 @@ namespace CSMFilter
|
|||
bool isString() const;
|
||||
};
|
||||
|
||||
Token::Token (Type type) : mType (type) {}
|
||||
Token::Token (Type type) : mType (type), mNumber(0.0) {}
|
||||
|
||||
Token::Token (Type type, const std::string& string) : mType (type), mString (string) {}
|
||||
Token::Token (Type type, const std::string& string) : mType (type), mString (string), mNumber(0.0) {}
|
||||
|
||||
Token::Token (const std::string& string) : mType (Type_String), mString (string) {}
|
||||
Token::Token (const std::string& string) : mType (Type_String), mString (string), mNumber(0.0) {}
|
||||
|
||||
Token::Token (double number) : mType (Type_Number), mNumber (number) {}
|
||||
|
||||
|
@ -614,4 +614,4 @@ boost::shared_ptr<CSMFilter::Node> CSMFilter::Parser::getFilter() const
|
|||
throw std::logic_error ("No filter available");
|
||||
|
||||
return mFilter;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,11 @@ namespace CSMSettings
|
|||
inline QStringPair *getValuePair() { return mValuePair; }
|
||||
|
||||
/// set value range (spinbox / integer use)
|
||||
inline void setValuePair (QStringPair valuePair) { mValuePair = new QStringPair(valuePair); }
|
||||
inline void setValuePair (QStringPair valuePair)
|
||||
{
|
||||
delete mValuePair;
|
||||
mValuePair = new QStringPair(valuePair);
|
||||
}
|
||||
|
||||
inline bool isMultivalue () { return mIsMultiValue; }
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager)
|
|||
manager.add (CSMWorld::UniversalId::Type_Topics,
|
||||
new CSVDoc::SubViewFactoryWithCreator<TableSubView, TopicCreatorFactory>);
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_Journal,
|
||||
manager.add (CSMWorld::UniversalId::Type_Journals,
|
||||
new CSVDoc::SubViewFactoryWithCreator<TableSubView, JournalCreatorFactory>);
|
||||
|
||||
manager.add (CSMWorld::UniversalId::Type_TopicInfos,
|
||||
|
|
|
@ -281,9 +281,11 @@ int main(int argc, char**argv)
|
|||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX || OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
||||
if (isatty(fileno(stdin)) || !SDL_WasInit(SDL_INIT_VIDEO))
|
||||
std::cerr << "\nERROR: " << e.what() << std::endl;
|
||||
else
|
||||
#endif
|
||||
SDL_ShowSimpleMessageBox(0, "OpenMW: Fatal error", e.what(), NULL);
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -199,7 +199,7 @@ namespace MWClass
|
|||
else
|
||||
{
|
||||
MWMechanics::DynamicStat<float> fatigue(getCreatureStats(ptr).getFatigue());
|
||||
fatigue.setCurrent(fatigue.getCurrent() - damage);
|
||||
fatigue.setCurrent(fatigue.getCurrent() - damage, true);
|
||||
getCreatureStats(ptr).setFatigue(fatigue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,6 @@ namespace
|
|||
bool male = (npc->mFlags & ESM::NPC::Female) == 0;
|
||||
|
||||
int level = creatureStats.getLevel();
|
||||
|
||||
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||
{
|
||||
const ESM::Race::MaleFemale& attribute = race->mData.mAttributeValues[i];
|
||||
|
@ -85,7 +84,7 @@ namespace
|
|||
}
|
||||
|
||||
// skill bonus
|
||||
for (int attribute=0; attribute<ESM::Attribute::Length; ++attribute)
|
||||
for (int attribute=0; attribute < ESM::Attribute::Length; ++attribute)
|
||||
{
|
||||
float modifierSum = 0;
|
||||
|
||||
|
@ -131,6 +130,89 @@ namespace
|
|||
|
||||
creatureStats.setHealth(static_cast<int> (0.5 * (strength + endurance)) + multiplier * (creatureStats.getLevel() - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief autoCalculateSkills
|
||||
*
|
||||
* Skills are calculated with following formulae ( http://www.uesp.net/wiki/Morrowind:NPCs#Skills ):
|
||||
*
|
||||
* Skills: (Level - 1) × (Majority Multiplier + Specialization Multiplier)
|
||||
*
|
||||
* The Majority Multiplier is 1.0 for a Major or Minor Skill, or 0.1 for a Miscellaneous Skill.
|
||||
*
|
||||
* The Specialization Multiplier is 0.5 for a Skill in the same Specialization as the class,
|
||||
* zero for other Skills.
|
||||
*
|
||||
* and by adding class, race, specialization bonus.
|
||||
*/
|
||||
void autoCalculateSkills(const ESM::NPC* npc, MWMechanics::NpcStats& npcStats)
|
||||
{
|
||||
const ESM::Class *class_ =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find(npc->mClass);
|
||||
|
||||
unsigned int level = npcStats.getLevel();
|
||||
|
||||
const ESM::Race *race = MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(npc->mRace);
|
||||
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
int bonus = (i==0) ? 10 : 25;
|
||||
|
||||
for (int i2 = 0; i2 < 5; ++i2)
|
||||
{
|
||||
int index = class_->mData.mSkills[i2][i];
|
||||
if (index >= 0 && index < ESM::Skill::Length)
|
||||
{
|
||||
npcStats.getSkill(index).setBase (npcStats.getSkill(index).getBase() + bonus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int skillIndex = 0; skillIndex < ESM::Skill::Length; ++skillIndex)
|
||||
{
|
||||
float majorMultiplier = 0.1f;
|
||||
float specMultiplier = 0.0f;
|
||||
|
||||
int raceBonus = 0;
|
||||
int specBonus = 0;
|
||||
|
||||
for (int raceSkillIndex = 0; raceSkillIndex < 7; ++raceSkillIndex)
|
||||
{
|
||||
if (race->mData.mBonus[raceSkillIndex].mSkill == skillIndex)
|
||||
{
|
||||
raceBonus = race->mData.mBonus[raceSkillIndex].mBonus;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int k = 0; k < 5; ++k)
|
||||
{
|
||||
// is this a minor or major skill?
|
||||
if ((class_->mData.mSkills[k][0] == skillIndex) || (class_->mData.mSkills[k][1] == skillIndex))
|
||||
{
|
||||
majorMultiplier = 1.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// is this skill in the same Specialization as the class?
|
||||
const ESM::Skill* skill = MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find(skillIndex);
|
||||
if (skill->mData.mSpecialization == class_->mData.mSpecialization)
|
||||
{
|
||||
specMultiplier = 0.5f;
|
||||
specBonus = 5;
|
||||
}
|
||||
|
||||
npcStats.getSkill(skillIndex).setBase(
|
||||
std::min(
|
||||
npcStats.getSkill(skillIndex).getBase()
|
||||
+ 5
|
||||
+ raceBonus
|
||||
+ specBonus
|
||||
+ static_cast<int>((level-1) * (majorMultiplier + specMultiplier)), 100.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWClass
|
||||
|
@ -173,7 +255,7 @@ namespace MWClass
|
|||
{
|
||||
std::string faction = ref->mBase->mFaction;
|
||||
Misc::StringUtils::toLower(faction);
|
||||
if(ref->mBase->mNpdt52.mGold != -10)
|
||||
if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
|
||||
{
|
||||
data->mNpcStats.getFactionRanks()[faction] = (int)ref->mBase->mNpdt52.mRank;
|
||||
}
|
||||
|
@ -185,11 +267,11 @@ namespace MWClass
|
|||
|
||||
// creature stats
|
||||
int gold=0;
|
||||
if(ref->mBase->mNpdt52.mGold != -10)
|
||||
if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
|
||||
{
|
||||
gold = ref->mBase->mNpdt52.mGold;
|
||||
|
||||
for (int i=0; i<27; ++i)
|
||||
for (unsigned int i=0; i< ESM::Skill::Length; ++i)
|
||||
data->mNpcStats.getSkill (i).setBase (ref->mBase->mNpdt52.mSkills[i]);
|
||||
|
||||
data->mNpcStats.getAttribute(0).set (ref->mBase->mNpdt52.mStrength);
|
||||
|
@ -220,6 +302,7 @@ namespace MWClass
|
|||
data->mNpcStats.setReputation(ref->mBase->mNpdt12.mReputation);
|
||||
|
||||
autoCalculateAttributes(ref->mBase, data->mNpcStats);
|
||||
autoCalculateSkills(ref->mBase, data->mNpcStats);
|
||||
}
|
||||
|
||||
data->mNpcStats.getAiSequence().fill(ref->mBase->mAiPackage);
|
||||
|
@ -586,7 +669,7 @@ namespace MWClass
|
|||
else
|
||||
{
|
||||
MWMechanics::DynamicStat<float> fatigue(getCreatureStats(ptr).getFatigue());
|
||||
fatigue.setCurrent(fatigue.getCurrent() - damage);
|
||||
fatigue.setCurrent(fatigue.getCurrent() - damage, true);
|
||||
getCreatureStats(ptr).setFatigue(fatigue);
|
||||
}
|
||||
}
|
||||
|
@ -628,6 +711,8 @@ namespace MWClass
|
|||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionOpen(ptr, true));
|
||||
if(get(actor).getStance(actor, MWWorld::Class::Sneak))
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionOpen(ptr)); // stealing
|
||||
if(get(ptr).getCreatureStats(ptr).isHostile())
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::FailedAction("#{sActorInCombat}"));
|
||||
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionTalk(ptr));
|
||||
}
|
||||
|
||||
|
|
|
@ -174,38 +174,32 @@ namespace MWGui
|
|||
|
||||
void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<float>& value)
|
||||
{
|
||||
static const char *ids[] =
|
||||
{
|
||||
"HBar", "MBar", "FBar", 0
|
||||
};
|
||||
int current = std::max(0, static_cast<int>(value.getCurrent()));
|
||||
int modified = static_cast<int>(value.getModified());
|
||||
|
||||
for (int i=0; ids[i]; ++i)
|
||||
if (ids[i]==id)
|
||||
{
|
||||
MyGUI::Widget* w;
|
||||
std::string valStr = boost::lexical_cast<std::string>(value.getCurrent()) + "/" + boost::lexical_cast<std::string>(value.getModified());
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
mHealth->setProgressRange (value.getModified());
|
||||
mHealth->setProgressPosition (value.getCurrent());
|
||||
getWidget(w, "HealthFrame");
|
||||
w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
|
||||
break;
|
||||
case 1:
|
||||
mMagicka->setProgressRange (value.getModified());
|
||||
mMagicka->setProgressPosition (value.getCurrent());
|
||||
getWidget(w, "MagickaFrame");
|
||||
w->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
|
||||
break;
|
||||
case 2:
|
||||
mStamina->setProgressRange (value.getModified());
|
||||
mStamina->setProgressPosition (value.getCurrent());
|
||||
getWidget(w, "FatigueFrame");
|
||||
w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
MyGUI::Widget* w;
|
||||
std::string valStr = boost::lexical_cast<std::string>(current) + "/" + boost::lexical_cast<std::string>(modified);
|
||||
if (id == "HBar")
|
||||
{
|
||||
mHealth->setProgressRange(modified);
|
||||
mHealth->setProgressPosition(current);
|
||||
getWidget(w, "HealthFrame");
|
||||
w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
|
||||
}
|
||||
else if (id == "MBar")
|
||||
{
|
||||
mMagicka->setProgressRange (modified);
|
||||
mMagicka->setProgressPosition (current);
|
||||
getWidget(w, "MagickaFrame");
|
||||
w->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
|
||||
}
|
||||
else if (id == "FBar")
|
||||
{
|
||||
mStamina->setProgressRange (modified);
|
||||
mStamina->setProgressPosition (current);
|
||||
getWidget(w, "FatigueFrame");
|
||||
w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
|
||||
}
|
||||
}
|
||||
|
||||
void HUD::setDrowningTimeLeft(float time)
|
||||
|
|
|
@ -134,38 +134,28 @@ namespace MWGui
|
|||
|
||||
void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value)
|
||||
{
|
||||
static const char *ids[] =
|
||||
{
|
||||
"HBar", "MBar", "FBar",
|
||||
0
|
||||
};
|
||||
int current = std::max(0, static_cast<int>(value.getCurrent()));
|
||||
int modified = static_cast<int>(value.getModified());
|
||||
|
||||
for (int i=0; ids[i]; ++i)
|
||||
{
|
||||
if (ids[i]==id)
|
||||
{
|
||||
std::string id (ids[i]);
|
||||
setBar (id, id + "T", static_cast<int>(value.getCurrent()), static_cast<int>(value.getModified()));
|
||||
setBar (id, id + "T", current, modified);
|
||||
|
||||
// health, magicka, fatigue tooltip
|
||||
MyGUI::Widget* w;
|
||||
std::string valStr = boost::lexical_cast<std::string>(int(value.getCurrent())) + "/" + boost::lexical_cast<std::string>(int(value.getModified()));
|
||||
if (i==0)
|
||||
{
|
||||
getWidget(w, "Health");
|
||||
w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
|
||||
}
|
||||
else if (i==1)
|
||||
{
|
||||
getWidget(w, "Magicka");
|
||||
w->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
|
||||
}
|
||||
else if (i==2)
|
||||
{
|
||||
getWidget(w, "Fatigue");
|
||||
w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
|
||||
}
|
||||
}
|
||||
// health, magicka, fatigue tooltip
|
||||
MyGUI::Widget* w;
|
||||
std::string valStr = boost::lexical_cast<std::string>(current) + "/" + boost::lexical_cast<std::string>(modified);
|
||||
if (id == "HBar")
|
||||
{
|
||||
getWidget(w, "Health");
|
||||
w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
|
||||
}
|
||||
else if (id == "MBar")
|
||||
{
|
||||
getWidget(w, "Magicka");
|
||||
w->setUserString("Caption_HealthDescription", "#{sIntDesc}\n" + valStr);
|
||||
}
|
||||
else if (id == "FBar")
|
||||
{
|
||||
getWidget(w, "Fatigue");
|
||||
w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -420,8 +410,6 @@ namespace MWGui
|
|||
}
|
||||
mSkillWidgets.clear();
|
||||
|
||||
mSkillView->setViewOffset (MyGUI::IntPoint(0,0));
|
||||
|
||||
const int valueSize = 40;
|
||||
MyGUI::IntCoord coord1(10, 0, mSkillView->getWidth() - (10 + valueSize) - 24, 18);
|
||||
MyGUI::IntCoord coord2(coord1.left + coord1.width, coord1.top, valueSize, coord1.height);
|
||||
|
|
|
@ -112,9 +112,6 @@ namespace MWGui
|
|||
, mPlayerMinorSkills()
|
||||
, mPlayerMajorSkills()
|
||||
, mPlayerSkillValues()
|
||||
, mPlayerHealth()
|
||||
, mPlayerMagicka()
|
||||
, mPlayerFatigue()
|
||||
, mGui(NULL)
|
||||
, mGuiModes()
|
||||
, mCursorManager(NULL)
|
||||
|
@ -590,32 +587,8 @@ namespace MWGui
|
|||
mStatsWindow->setValue (id, value);
|
||||
mHud->setValue (id, value);
|
||||
mCharGen->setValue(id, value);
|
||||
if (id == "HBar")
|
||||
{
|
||||
mPlayerHealth = value;
|
||||
}
|
||||
else if (id == "MBar")
|
||||
{
|
||||
mPlayerMagicka = value;
|
||||
}
|
||||
else if (id == "FBar")
|
||||
{
|
||||
mPlayerFatigue = value;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
MWMechanics::DynamicStat<int> WindowManager::getValue(const std::string& id)
|
||||
{
|
||||
if(id == "HBar")
|
||||
return mPlayerHealth;
|
||||
else if (id == "MBar")
|
||||
return mPlayerMagicka;
|
||||
else if (id == "FBar")
|
||||
return mPlayerFatigue;
|
||||
}
|
||||
#endif
|
||||
|
||||
void WindowManager::setValue (const std::string& id, const std::string& value)
|
||||
{
|
||||
mStatsWindow->setValue (id, value);
|
||||
|
|
|
@ -346,8 +346,6 @@ namespace MWGui
|
|||
std::map<int, MWMechanics::Stat<int> > mPlayerAttributes;
|
||||
SkillList mPlayerMajorSkills, mPlayerMinorSkills;
|
||||
std::map<int, MWMechanics::Stat<float> > mPlayerSkillValues;
|
||||
MWMechanics::DynamicStat<float> mPlayerHealth, mPlayerMagicka, mPlayerFatigue;
|
||||
|
||||
|
||||
MyGUI::Gui *mGui; // Gui
|
||||
std::vector<GuiMode> mGuiModes;
|
||||
|
|
|
@ -37,6 +37,7 @@ MWMechanics::AiSequence& MWMechanics::AiSequence::operator= (const AiSequence& s
|
|||
{
|
||||
clear();
|
||||
copy (sequence);
|
||||
mDone = sequence.mDone;
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
|
|
@ -1112,7 +1112,7 @@ void CharacterController::resurrect()
|
|||
|
||||
if(mAnimation)
|
||||
mAnimation->disable(mCurrentDeath);
|
||||
mCurrentDeath.empty();
|
||||
mCurrentDeath.clear();
|
||||
mDeathState = CharState_None;
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ void MWMechanics::NpcStats::setMovementFlag (Flag flag, bool state)
|
|||
|
||||
const MWMechanics::Stat<float>& MWMechanics::NpcStats::getSkill (int index) const
|
||||
{
|
||||
if (index<0 || index>=27)
|
||||
if (index<0 || index>=ESM::Skill::Length)
|
||||
throw std::runtime_error ("skill index out of range");
|
||||
|
||||
return (!mIsWerewolf ? mSkill[index] : mWerewolfSkill[index]);
|
||||
|
@ -94,7 +94,7 @@ const MWMechanics::Stat<float>& MWMechanics::NpcStats::getSkill (int index) cons
|
|||
|
||||
MWMechanics::Stat<float>& MWMechanics::NpcStats::getSkill (int index)
|
||||
{
|
||||
if (index<0 || index>=27)
|
||||
if (index<0 || index>=ESM::Skill::Length)
|
||||
throw std::runtime_error ("skill index out of range");
|
||||
|
||||
return (!mIsWerewolf ? mSkill[index] : mWerewolfSkill[index]);
|
||||
|
|
|
@ -162,14 +162,26 @@ namespace MWMechanics
|
|||
setCurrent (getCurrent()+diff);
|
||||
}
|
||||
|
||||
void setCurrent (const T& value)
|
||||
void setCurrent (const T& value, bool allowDecreaseBelowZero = false)
|
||||
{
|
||||
mCurrent = value;
|
||||
if (value > mCurrent)
|
||||
{
|
||||
// increase
|
||||
mCurrent = value;
|
||||
|
||||
if (mCurrent<0)
|
||||
if (mCurrent > getModified())
|
||||
mCurrent = getModified();
|
||||
}
|
||||
else if (value > 0 || allowDecreaseBelowZero)
|
||||
{
|
||||
// allowed decrease
|
||||
mCurrent = value;
|
||||
}
|
||||
else if (mCurrent > 0)
|
||||
{
|
||||
// capped decrease
|
||||
mCurrent = 0;
|
||||
else if (mCurrent>getModified())
|
||||
mCurrent = getModified();
|
||||
}
|
||||
}
|
||||
|
||||
void setModifier (const T& modifier)
|
||||
|
|
|
@ -209,6 +209,7 @@ namespace MWScript
|
|||
.getDynamic (mIndex));
|
||||
|
||||
stat.setModified (value, 0);
|
||||
stat.setCurrent(value);
|
||||
|
||||
MWWorld::Class::get (ptr).getCreatureStats (ptr).setDynamic (mIndex, stat);
|
||||
}
|
||||
|
|
|
@ -473,7 +473,7 @@ void WeatherManager::update(float duration)
|
|||
{
|
||||
// pick a random sound
|
||||
int sound = rand() % 4;
|
||||
std::string* soundName;
|
||||
std::string* soundName = NULL;
|
||||
if (sound == 0) soundName = &mThunderSoundID0;
|
||||
else if (sound == 1) soundName = &mThunderSoundID1;
|
||||
else if (sound == 2) soundName = &mThunderSoundID2;
|
||||
|
|
|
@ -214,7 +214,7 @@ namespace MWWorld
|
|||
: mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0),
|
||||
mSky (true), mCells (mStore, mEsm),
|
||||
mActivationDistanceOverride (mActivationDistanceOverride),
|
||||
mFallback(fallbackMap), mPlayIntro(0), mTeleportEnabled(true),
|
||||
mFallback(fallbackMap), mPlayIntro(0), mTeleportEnabled(true), mLevitationEnabled(false),
|
||||
mFacedDistance(FLT_MAX), mGodMode(false)
|
||||
{
|
||||
mPhysics = new PhysicsSystem(renderer);
|
||||
|
|
|
@ -160,10 +160,10 @@ void Land::loadData(int flags)
|
|||
}
|
||||
mEsm->restoreContext(mContext);
|
||||
|
||||
memset(mLandData->mNormals, 0, LAND_NUM_VERTS * 3);
|
||||
memset(mLandData->mNormals, 0, sizeof(mLandData->mNormals));
|
||||
|
||||
if (mEsm->isNextSub("VNML")) {
|
||||
condLoad(actual, DATA_VNML, mLandData->mNormals, sizeof(VNML));
|
||||
condLoad(actual, DATA_VNML, mLandData->mNormals, sizeof(mLandData->mNormals));
|
||||
}
|
||||
|
||||
if (mEsm->isNextSub("VHGT")) {
|
||||
|
|
|
@ -72,13 +72,13 @@ struct Land
|
|||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef signed char VNML[LAND_NUM_VERTS * 3];
|
||||
typedef signed char VNML;
|
||||
|
||||
struct LandData
|
||||
{
|
||||
float mHeightOffset;
|
||||
float mHeights[LAND_NUM_VERTS];
|
||||
VNML mNormals;
|
||||
VNML mNormals[LAND_NUM_VERTS * 3];
|
||||
uint16_t mTextures[LAND_NUM_TEXTURES];
|
||||
|
||||
bool mUsingColours;
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace ESM
|
|||
|
||||
void NPC::load(ESMReader &esm)
|
||||
{
|
||||
mNpdt52.mGold = -10;
|
||||
//mNpdt52.mGold = -10;
|
||||
|
||||
mPersistent = esm.getRecordFlags() & 0x0400;
|
||||
|
||||
|
@ -29,12 +29,12 @@ void NPC::load(ESMReader &esm)
|
|||
esm.getSubHeader();
|
||||
if (esm.getSubSize() == 52)
|
||||
{
|
||||
mNpdtType = 52;
|
||||
mNpdtType = NPC_DEFAULT;
|
||||
esm.getExact(&mNpdt52, 52);
|
||||
}
|
||||
else if (esm.getSubSize() == 12)
|
||||
{
|
||||
mNpdtType = 12;
|
||||
mNpdtType = NPC_WITH_AUTOCALCULATED_STATS;
|
||||
esm.getExact(&mNpdt12, 12);
|
||||
}
|
||||
else
|
||||
|
@ -76,9 +76,9 @@ void NPC::save(ESMWriter &esm) const
|
|||
esm.writeHNCString("KNAM", mHair);
|
||||
esm.writeHNOCString("SCRI", mScript);
|
||||
|
||||
if (mNpdtType == 52)
|
||||
if (mNpdtType == NPC_DEFAULT)
|
||||
esm.writeHNT("NPDT", mNpdt52, 52);
|
||||
else if (mNpdtType == 12)
|
||||
else if (mNpdtType == NPC_WITH_AUTOCALCULATED_STATS)
|
||||
esm.writeHNT("NPDT", mNpdt12, 12);
|
||||
|
||||
esm.writeHNT("FLAG", mFlags);
|
||||
|
@ -114,7 +114,7 @@ void NPC::save(ESMWriter &esm) const
|
|||
mNpdt52.mLevel = 0;
|
||||
mNpdt52.mStrength = mNpdt52.mIntelligence = mNpdt52.mWillpower = mNpdt52.mAgility =
|
||||
mNpdt52.mSpeed = mNpdt52.mEndurance = mNpdt52.mPersonality = mNpdt52.mLuck = 0;
|
||||
for (int i=0; i<27; ++i) mNpdt52.mSkills[i] = 0;
|
||||
for (int i=0; i< Skill::Length; ++i) mNpdt52.mSkills[i] = 0;
|
||||
mNpdt52.mReputation = 0;
|
||||
mNpdt52.mHealth = mNpdt52.mMana = mNpdt52.mFatigue = 0;
|
||||
mNpdt52.mDisposition = 0;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "loadcont.hpp"
|
||||
#include "aipackage.hpp"
|
||||
#include "spelllist.hpp"
|
||||
#include "loadskil.hpp"
|
||||
|
||||
namespace ESM {
|
||||
|
||||
|
@ -58,6 +59,12 @@ struct NPC
|
|||
Metal = 0x0800 // Metal blood effect (golden?)
|
||||
};
|
||||
|
||||
enum NpcType
|
||||
{
|
||||
NPC_WITH_AUTOCALCULATED_STATS = 12,
|
||||
NPC_DEFAULT = 52
|
||||
};
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
|
||||
|
@ -73,7 +80,7 @@ struct NPC
|
|||
mPersonality,
|
||||
mLuck;
|
||||
|
||||
char mSkills[27];
|
||||
char mSkills[Skill::Length];
|
||||
char mReputation;
|
||||
short mHealth, mMana, mFatigue;
|
||||
char mDisposition, mFactionID, mRank;
|
||||
|
|
|
@ -27,6 +27,7 @@ public:
|
|||
Ogre::String doGet(const void *target) const
|
||||
{
|
||||
assert(false && "Unimplemented");
|
||||
return "";
|
||||
}
|
||||
void doSet(void *target, const Ogre::String &val)
|
||||
{
|
||||
|
@ -41,6 +42,7 @@ public:
|
|||
Ogre::String doGet(const void *target) const
|
||||
{
|
||||
assert(false && "Unimplemented");
|
||||
return "";
|
||||
}
|
||||
void doSet(void *target, const Ogre::String &val)
|
||||
{
|
||||
|
@ -563,6 +565,7 @@ public:
|
|||
Ogre::String doGet(const void *target) const
|
||||
{
|
||||
assert(false && "Unimplemented");
|
||||
return "";
|
||||
}
|
||||
void doSet(void *target, const Ogre::String &val)
|
||||
{
|
||||
|
@ -577,6 +580,7 @@ public:
|
|||
Ogre::String doGet(const void *target) const
|
||||
{
|
||||
assert(false && "Unimplemented");
|
||||
return "";
|
||||
}
|
||||
void doSet(void *target, const Ogre::String &val)
|
||||
{
|
||||
|
|
2
extern/oics/tinyxml.h
vendored
2
extern/oics/tinyxml.h
vendored
|
@ -349,7 +349,7 @@ protected:
|
|||
{
|
||||
//strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe),
|
||||
// and the null terminator isn't needed
|
||||
for( int i=0; p[i] && i<*length; ++i ) {
|
||||
for( int i=0; i<*length && p[i]; ++i ) {
|
||||
_value[i] = p[i];
|
||||
}
|
||||
return p + (*length);
|
||||
|
|
|
@ -819,6 +819,8 @@ namespace BtOgre {
|
|||
*/
|
||||
|
||||
DynamicRenderable::DynamicRenderable()
|
||||
: mVertexBufferCapacity(0)
|
||||
, mIndexBufferCapacity(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue